@@ -25,6 +25,8 @@ import type {
2525 TextToSpeechParams ,
2626 TextToVideoParams ,
2727 ImageToVideoParams ,
28+ ReferenceToVideoInputs ,
29+ ReferenceToVideoParams ,
2830 TextToMusicParams ,
2931 EncodedAudioResult
3032} from "./types.js" ;
@@ -79,6 +81,7 @@ export class PythonProvider extends BaseProvider {
7981 private _secrets : Record < string , string > ;
8082 private _supportsStreamingTTS = true ;
8183 private _supportsEncodedTTS = true ;
84+ private _workerCapabilities = new Set < string > ( ) ;
8285
8386 constructor (
8487 providerId : string ,
@@ -99,19 +102,26 @@ export class PythonProvider extends BaseProvider {
99102 this . _bridge = bridge ;
100103 this . _pythonProviderId = providerIdOrOptions ;
101104 this . _secrets = secrets ;
105+ this . referenceToVideo = BaseProvider . prototype . referenceToVideo ;
102106 return ;
103107 }
104108
105109 const { _id, _bridge, _bridgeProviderId, _capabilities, ...rawSecrets } =
106110 providerIdOrOptions ;
107111 super ( _id ) ;
112+ const wrappedReferenceToVideo = this . referenceToVideo ;
108113 this . _bridge = _bridge ;
109114 this . _pythonProviderId = _bridgeProviderId ?? _id ;
115+ this . referenceToVideo = BaseProvider . prototype . referenceToVideo ;
110116 if ( Array . isArray ( _capabilities ) ) {
117+ this . _workerCapabilities = new Set ( _capabilities . map ( String ) ) ;
111118 this . _supportsStreamingTTS = _capabilities . includes ( "text_to_speech" ) ;
112119 this . _supportsEncodedTTS = _capabilities . includes (
113120 "text_to_speech_encoded"
114121 ) ;
122+ if ( this . _workerCapabilities . has ( "reference_to_video" ) ) {
123+ this . referenceToVideo = wrappedReferenceToVideo ;
124+ }
115125 }
116126 this . _secrets = Object . fromEntries (
117127 Object . entries ( rawSecrets ) . filter (
@@ -187,10 +197,25 @@ export class PythonProvider extends BaseProvider {
187197 // The public provider id may be an alias (notably `huggingface-local`) so
188198 // selections route back through this bridge adapter instead of colliding
189199 // with a built-in remote provider that uses the worker's original id.
190- return models . map ( ( model ) => ( {
191- ...model ,
192- provider : this . provider
193- } ) ) ;
200+ return models . map ( ( model ) => {
201+ const supportedTasks = Array . isArray ( model . supportedTasks )
202+ ? model . supportedTasks . map ( String )
203+ : Array . isArray ( model . supported_tasks )
204+ ? model . supported_tasks . map ( String )
205+ : undefined ;
206+ const normalizedModel : Record < string , unknown > = {
207+ ...model ,
208+ provider : this . provider
209+ } ;
210+ if ( modelType === "video" && supportedTasks ) {
211+ normalizedModel . supportedTasks = this . _workerCapabilities . has (
212+ "reference_to_video"
213+ )
214+ ? supportedTasks
215+ : supportedTasks . filter ( ( task ) => task !== "reference_to_video" ) ;
216+ }
217+ return normalizedModel ;
218+ } ) ;
194219 }
195220
196221 // ── Chat completion ───────────────────────────────────────────────
@@ -327,6 +352,47 @@ export class PythonProvider extends BaseProvider {
327352 ) ;
328353 }
329354
355+ async referenceToVideo (
356+ inputs : ReferenceToVideoInputs ,
357+ params : ReferenceToVideoParams
358+ ) : Promise < Uint8Array > {
359+ if ( ! this . _workerCapabilities . has ( "reference_to_video" ) ) {
360+ throw new Error ( "Python worker does not support reference_to_video" ) ;
361+ }
362+ if (
363+ Array . isArray ( params . model . supportedTasks ) &&
364+ ! params . model . supportedTasks . includes ( "reference_to_video" )
365+ ) {
366+ throw new Error (
367+ `Video model ${ params . model . id } does not support reference_to_video`
368+ ) ;
369+ }
370+ if ( ! Array . isArray ( params . model . supportedTasks ) ) {
371+ const models = await this . _getModels ( "video" ) ;
372+ const model = models . find (
373+ ( candidate ) =>
374+ isRecord ( candidate ) && String ( candidate . id ?? "" ) === params . model . id
375+ ) ;
376+ if (
377+ ! isRecord ( model ) ||
378+ ! Array . isArray ( model . supportedTasks ) ||
379+ ! model . supportedTasks . includes ( "reference_to_video" )
380+ ) {
381+ throw new Error (
382+ `Video model ${ params . model . id } does not support reference_to_video`
383+ ) ;
384+ }
385+ }
386+ const { signal, ...wireParams } = params ;
387+ return this . _bridge . providerReferenceToVideo (
388+ this . _pythonProviderId ,
389+ inputs ,
390+ { ...wireParams , model : params . model . id } ,
391+ this . _secrets ,
392+ signal
393+ ) ;
394+ }
395+
330396 async * textToSpeech (
331397 args : TextToSpeechParams
332398 ) : AsyncGenerator < StreamingAudioChunk > {
0 commit comments