1010class LumaIO :
1111 LUMA_REF = "LUMA_REF"
1212 LUMA_CONCEPTS = "LUMA_CONCEPTS"
13+ LUMA_RAY32_KEYFRAME = "LUMA_RAY32_KEYFRAME"
1314
1415
1516class LumaReference :
@@ -20,13 +21,14 @@ def __init__(self, image: torch.Tensor, weight: float):
2021 def create_api_model (self , download_url : str ):
2122 return LumaImageRef (url = download_url , weight = self .weight )
2223
24+
2325class LumaReferenceChain :
24- def __init__ (self , first_ref : LumaReference = None ):
26+ def __init__ (self , first_ref : LumaReference = None ):
2527 self .refs : list [LumaReference ] = []
2628 if first_ref :
2729 self .refs .append (first_ref )
2830
29- def add (self , luma_ref : LumaReference = None ):
31+ def add (self , luma_ref : LumaReference = None ):
3032 self .refs .append (luma_ref )
3133
3234 def create_api_model (self , download_urls : list [str ], max_refs = 4 ):
@@ -124,7 +126,7 @@ def get_luma_concepts(include_none=False):
124126 "pull_out" ,
125127 "aerial" ,
126128 "crane_up" ,
127- "eye_level"
129+ "eye_level" ,
128130 ]
129131
130132
@@ -162,8 +164,8 @@ class LumaVideoModelOutputDuration(str, Enum):
162164
163165
164166class LumaGenerationType (str , Enum ):
165- video = ' video'
166- image = ' image'
167+ video = " video"
168+ image = " image"
167169
168170
169171class LumaState (str , Enum ):
@@ -174,86 +176,109 @@ class LumaState(str, Enum):
174176
175177
176178class LumaAssets (BaseModel ):
177- video : Optional [str ] = Field (None , description = ' The URL of the video' )
178- image : Optional [str ] = Field (None , description = ' The URL of the image' )
179- progress_video : Optional [str ] = Field (None , description = ' The URL of the progress video' )
179+ video : Optional [str ] = Field (None , description = " The URL of the video" )
180+ image : Optional [str ] = Field (None , description = " The URL of the image" )
181+ progress_video : Optional [str ] = Field (None , description = " The URL of the progress video" )
180182
181183
182184class LumaImageRef (BaseModel ):
183185 """Used for image gen"""
184- url : str = Field (..., description = 'The URL of the image reference' )
185- weight : confloat (ge = 0.0 , le = 1.0 ) = Field (..., description = 'The weight of the image reference' )
186+
187+ url : str = Field (..., description = "The URL of the image reference" )
188+ weight : confloat (ge = 0.0 , le = 1.0 ) = Field (..., description = "The weight of the image reference" )
186189
187190
188191class LumaImageReference (BaseModel ):
189192 """Used for video gen"""
190- type : Optional [str ] = Field ('image' , description = 'Input type, defaults to image' )
191- url : str = Field (..., description = 'The URL of the image' )
193+
194+ type : Optional [str ] = Field ("image" , description = "Input type, defaults to image" )
195+ url : str = Field (..., description = "The URL of the image" )
192196
193197
194198class LumaModifyImageRef (BaseModel ):
195- url : str = Field (..., description = ' The URL of the image reference' )
196- weight : confloat (ge = 0.0 , le = 1.0 ) = Field (..., description = ' The weight of the image reference' )
199+ url : str = Field (..., description = " The URL of the image reference" )
200+ weight : confloat (ge = 0.0 , le = 1.0 ) = Field (..., description = " The weight of the image reference" )
197201
198202
199203class LumaCharacterRef (BaseModel ):
200- identity0 : LumaImageIdentity = Field (..., description = ' The image identity object' )
204+ identity0 : LumaImageIdentity = Field (..., description = " The image identity object" )
201205
202206
203207class LumaImageIdentity (BaseModel ):
204- images : list [str ] = Field (..., description = ' The URLs of the image identity' )
208+ images : list [str ] = Field (..., description = " The URLs of the image identity" )
205209
206210
207211class LumaGenerationReference (BaseModel ):
208- type : str = Field (' generation' , description = ' Input type, defaults to generation' )
209- id : str = Field (..., description = ' The ID of the generation' )
212+ type : str = Field (" generation" , description = " Input type, defaults to generation" )
213+ id : str = Field (..., description = " The ID of the generation" )
210214
211215
212216class LumaKeyframes (BaseModel ):
213- frame0 : Optional [Union [LumaImageReference , LumaGenerationReference ]] = Field (None , description = '' )
214- frame1 : Optional [Union [LumaImageReference , LumaGenerationReference ]] = Field (None , description = '' )
217+ frame0 : Optional [Union [LumaImageReference , LumaGenerationReference ]] = Field (None , description = "" )
218+ frame1 : Optional [Union [LumaImageReference , LumaGenerationReference ]] = Field (None , description = "" )
215219
216220
217221class LumaConceptObject (BaseModel ):
218- key : str = Field (..., description = ' Camera Concept name' )
222+ key : str = Field (..., description = " Camera Concept name" )
219223
220224
221225class LumaImageGenerationRequest (BaseModel ):
222- prompt : str = Field (..., description = ' The prompt of the generation' )
223- model : LumaImageModel = Field (LumaImageModel .photon_1 , description = ' The image model used for the generation' )
224- aspect_ratio : Optional [LumaAspectRatio ] = Field (LumaAspectRatio .ratio_16_9 , description = 'The aspect ratio of the generation' )
225- image_ref : Optional [list [LumaImageRef ]] = Field (None , description = ' List of image reference objects' )
226- style_ref : Optional [list [LumaImageRef ]] = Field (None , description = ' List of style reference objects' )
227- character_ref : Optional [LumaCharacterRef ] = Field (None , description = ' The image identity object' )
228- modify_image_ref : Optional [LumaModifyImageRef ] = Field (None , description = ' The modify image reference object' )
226+ prompt : str = Field (..., description = " The prompt of the generation" )
227+ model : LumaImageModel = Field (LumaImageModel .photon_1 , description = " The image model used for the generation" )
228+ aspect_ratio : Optional [LumaAspectRatio ] = Field (LumaAspectRatio .ratio_16_9 )
229+ image_ref : Optional [list [LumaImageRef ]] = Field (None , description = " List of image reference objects" )
230+ style_ref : Optional [list [LumaImageRef ]] = Field (None , description = " List of style reference objects" )
231+ character_ref : Optional [LumaCharacterRef ] = Field (None , description = " The image identity object" )
232+ modify_image_ref : Optional [LumaModifyImageRef ] = Field (None , description = " The modify image reference object" )
229233
230234
231235class LumaGenerationRequest (BaseModel ):
232- prompt : str = Field (..., description = ' The prompt of the generation' )
233- model : LumaVideoModel = Field (LumaVideoModel .ray_2 , description = ' The video model used for the generation' )
234- duration : Optional [LumaVideoModelOutputDuration ] = Field (None , description = ' The duration of the generation' )
235- aspect_ratio : Optional [LumaAspectRatio ] = Field (None , description = ' The aspect ratio of the generation' )
236- resolution : Optional [LumaVideoOutputResolution ] = Field (None , description = ' The resolution of the generation' )
237- loop : Optional [bool ] = Field (None , description = ' Whether to loop the video' )
238- keyframes : Optional [LumaKeyframes ] = Field (None , description = ' The keyframes of the generation' )
239- concepts : Optional [list [LumaConceptObject ]] = Field (None , description = ' Camera Concepts to apply to generation' )
236+ prompt : str = Field (..., description = " The prompt of the generation" )
237+ model : LumaVideoModel = Field (LumaVideoModel .ray_2 , description = " The video model used for the generation" )
238+ duration : Optional [LumaVideoModelOutputDuration ] = Field (None , description = " The duration of the generation" )
239+ aspect_ratio : Optional [LumaAspectRatio ] = Field (None , description = " The aspect ratio of the generation" )
240+ resolution : Optional [LumaVideoOutputResolution ] = Field (None , description = " The resolution of the generation" )
241+ loop : Optional [bool ] = Field (None , description = " Whether to loop the video" )
242+ keyframes : Optional [LumaKeyframes ] = Field (None , description = " The keyframes of the generation" )
243+ concepts : Optional [list [LumaConceptObject ]] = Field (None , description = " Camera Concepts to apply to generation" )
240244
241245
242246class LumaGeneration (BaseModel ):
243- id : str = Field (..., description = ' The ID of the generation' )
244- generation_type : LumaGenerationType = Field (..., description = ' Generation type, image or video' )
245- state : LumaState = Field (..., description = ' The state of the generation' )
246- failure_reason : Optional [str ] = Field (None , description = ' The reason for the state of the generation' )
247- created_at : str = Field (..., description = ' The date and time when the generation was created' )
248- assets : Optional [LumaAssets ] = Field (None , description = ' The assets of the generation' )
249- model : str = Field (..., description = ' The model used for the generation' )
250- request : Union [LumaGenerationRequest , LumaImageGenerationRequest ] = Field (..., description = "The request used for the generation" )
247+ id : str = Field (..., description = " The ID of the generation" )
248+ generation_type : LumaGenerationType = Field (..., description = " Generation type, image or video" )
249+ state : LumaState = Field (..., description = " The state of the generation" )
250+ failure_reason : Optional [str ] = Field (None , description = " The reason for the state of the generation" )
251+ created_at : str = Field (..., description = " The date and time when the generation was created" )
252+ assets : Optional [LumaAssets ] = Field (None , description = " The assets of the generation" )
253+ model : str = Field (..., description = " The model used for the generation" )
254+ request : Union [LumaGenerationRequest , LumaImageGenerationRequest ] = Field (...)
251255
252256
253257class Luma2ImageRef (BaseModel ):
254258 url : str | None = None
255259 data : str | None = None
256260 media_type : str | None = None
261+ generation_id : str | None = Field (None , description = "reference a prior generation (extend / source reuse)" )
262+
263+
264+ class Luma2VideoEdit (BaseModel ):
265+ """Edit controls for Ray 3.2 ``video_edit`` generations."""
266+
267+ auto_controls : bool | None = Field (None , description = "derive a conditioning schedule from the source (recommended)" )
268+ strength : str | None = Field (None , description = "'adhere_1' .. 'reimagine_3'; constrained by IO.Combo" )
269+
270+
271+ class Luma2VideoOptions (BaseModel ):
272+ """Ray 3.2 ``video`` output settings (text / image / keyframe / edit / extend)."""
273+
274+ resolution : str | None = Field (None , description = "360p | 540p | 720p | 1080p" )
275+ duration : str | None = Field (None , description = "5s | 10s" )
276+ loop : bool | None = Field (None )
277+ start_frame : Luma2ImageRef | None = Field (None )
278+ end_frame : Luma2ImageRef | None = Field (None )
279+ keyframes : list [Luma2ImageRef ] | None = Field (None )
280+ keyframe_indexes : list [int ] | None = Field (None )
281+ edit : Luma2VideoEdit | None = Field (None )
257282
258283
259284class Luma2GenerationRequest (BaseModel ):
@@ -266,6 +291,7 @@ class Luma2GenerationRequest(BaseModel):
266291 web_search : bool | None = None
267292 image_ref : list [Luma2ImageRef ] | None = None
268293 source : Luma2ImageRef | None = None
294+ video : Luma2VideoOptions | None = Field (None )
269295
270296
271297class Luma2Generation (BaseModel ):
@@ -277,3 +303,31 @@ class Luma2Generation(BaseModel):
277303 output : list [LumaImageReference ] | None = None
278304 failure_reason : str | None = None
279305 failure_code : str | None = None
306+
307+
308+ # --- Ray 3.2 multi-keyframe chain ---
309+
310+ LUMA_KEYFRAME_MODE_FRACTION = "fraction" # value in [0.0, 1.0] of the output video duration
311+ LUMA_KEYFRAME_MODE_SECONDS = "seconds" # absolute time, in seconds, from the start of the output
312+
313+
314+ class LumaRay32KeyframeItem :
315+ """One guide image anchored at a position on the Ray 3.2 output timeline."""
316+
317+ def __init__ (self , image : torch .Tensor , mode : str , value : float ):
318+ self .image = image
319+ self .mode = mode # LUMA_KEYFRAME_MODE_FRACTION | LUMA_KEYFRAME_MODE_SECONDS
320+ self .value = value
321+
322+
323+ class LumaRay32KeyframeChain :
324+ def __init__ (self ):
325+ self .items : list [LumaRay32KeyframeItem ] = []
326+
327+ def add (self , item : LumaRay32KeyframeItem ) -> None :
328+ self .items .append (item )
329+
330+ def clone (self ) -> "LumaRay32KeyframeChain" :
331+ c = LumaRay32KeyframeChain ()
332+ c .items = list (self .items )
333+ return c
0 commit comments