Ë
    âß²jÿF  ã                  ó¤  — U d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	m
Z
mZ ddlmZmZmZmZ  ej"                  e«      ZdZdZdZd	Z eh d
£«      ZdddddddddœZdZdZed e edd«      «      ddgg d¢ddgdddd d!œd"œ	gZd#e d$<   d0d%„Z!d1d&„Z"d2d3d'„Z#d4d(„Z$d5d)„Z%d6d*„Z&d7d+„Z'	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d8d,„Z( G d-„ d.e«      Z)d9d/„Z*y):uÆ  OpenRouter video generation backend.

OpenRouter fronts every major video model (Veo, Sora, Kling, Seedance, Wan, Hailuo, Grok
Imagine, FLUX Video, â€¦) behind one asynchronous API: ``POST /api/v1/videos`` â†’ poll
``GET /api/v1/videos/{id}`` â†’ download ``GET /api/v1/videos/{id}/content`` with the
bearer key. The catalog and each model's limits come live from ``GET /api/v1/videos/models``
(public, no key), so new releases are selectable without a patch and a retired model drops
out on its own. ``capabilities()`` reflects the *selected* model so the dynamic
``video_generate`` schema advertises only what that model honours.

Docs: https://openrouter.ai/docs/guides/overview/multimodal/video-generation
é    )ÚannotationsN)ÚAnyÚDictÚListÚOptionalÚTuple)ÚVideoGenProviderÚerror_responseÚsave_url_videoÚsuccess_responsezminimax/hailuo-3-maxzhttps://openrouter.ai/api/v1g     Àr@ç      $@>   ÚfailedÚexpiredÚcanceledÚ	cancelledÚ	completedià  i  iÐ  i   i8  i   i   ip  )Ú480pÚ540pÚ720pÚ768pÚ1080pÚ1KÚ2KÚ4K)	ú16:9ú9:16ú1:1ú4:3ú3:4z3:2z2:3ú21:9z9:21é   zMiniMax: Hailuo 3 Maxé   é   r   r   )r    r   r   r   r   r   Úfirst_frameÚ
last_frameFz0.05z0.08)Úduration_seconds_480pÚduration_seconds_768p)	ÚidÚnameÚsupported_durationsÚsupported_resolutionsÚsupported_aspect_ratiosÚsupported_frame_imagesÚgenerate_audioÚseedÚpricing_skusúList[Dict[str, Any]]Ú_FALLBACK_CATALOGc                óŒ  — t        | t        «      syg }| j                  «       D ]Z  \  }}	 t        |«      }|j                  d«      r|j                  |«       Œ5|j                  d«      sŒG|j                  |dz  «       Œ\ |syt        |«      t        |«      }}||k(  rd|d›d�S d|d›d|d›d�S # t        t
        f$ r Y Œžw xY w)	uÏ   Compact per-second price from ``pricing_skus`` (``$0.10/s`` or ``$0.05â€“0.28/s``); ``""`` when the
    SKU shape is token- or megapixel-priced (Seedance, FLUX upscale) â€” a wrong number is worse than none.Ú Úduration_seconds)Úcents_per_second_outputÚcents_per_video_output_secondéd   ú$z.2fz/su   â€“)
Ú
isinstanceÚdictÚitemsÚfloatÚ	TypeErrorÚ
ValueErrorÚ
startswithÚappendÚminÚmax)ÚskusÚ
per_secondÚkeyÚvalueÚamountÚloÚhis          úJ/home/ubuntu/.hermes/hermes-agent/plugins/video_gen/openrouter/__init__.pyÚ_price_labelrL   -   sÙ   € ô �dœDÔ!ØØ €JØ—j‘j“lò ,‰
ˆˆUð	Ü˜5“\ˆFð �>‰>Ð,Ô-Ø×Ñ˜fÕ%Ø�^‰^ÐXÕYØ×Ñ˜f s™lÕ+ð,ñ ØÜ�‹_œc *›oˆ€BØ 2šXˆQˆr�#ˆh�bˆ>ÐD¨Q¨r°#¨h°c¸"¸S¸ÀÐ+DÐDøô œ:Ð&ò 	Ùð	ús   «B1Â1CÃCc                ó–   — 	 t        | «      j                  d«      \  }}t        |«      t        |«      z  S # t        t        f$ r Y y w xY w)Nú:)ÚstrÚsplitr=   r?   ÚZeroDivisionError)rG   ÚwÚhs      rK   Ú_ratiorT   B   sJ   € ðÜ�5‹z×Ñ Ó$‰ˆˆ1Ü�Q‹xœ% ›(Ñ"Ð"øÜÔ)Ð*ò Ùðús   ‚36 ¶AÁAc           
     óZ  ‡ — |r‰ |v r‰ S |�||j                  t        ‰ «      «      }|€|d   S t        |«      D ��cg c]0  \  }}t        |«      |v sŒt        |t        |«         |z
  «      ||f‘Œ2 }}}|rt	        |«      d   S |d   S dt        ‰ «      v rat        ‰ «      }|€|d   S t        |«      D ��cg c]$  \  }}t        |«      x}€Œt        ||z
  «      ||f‘Œ& }}}|rt	        |«      d   S |d   S 	 t	        |ˆ fd„¬«      S c c}}w c c}}w # t        t        f$ r |d   cY S w xY w)zàClosest supported value (durations by distance, resolutions by pixel height, aspect ratios by
    numeric ratio); the request is otherwise a guaranteed 400 because the tool always sends a default
    resolution/aspect ratio.r   é   rN   c                óH   •— t        t        | «      t        ‰«      z
  «      | fS ©N)ÚabsÚint)ÚsrG   s    €rK   ú<lambda>z_nearest.<locals>.<lambda>]   s   ø€ ¬S´°Q³¼#¸e»*Ñ1DÓ-EÀqÐ,I€ ó    )rF   )ÚgetrO   Ú	enumeraterY   rB   rT   r>   r?   )rG   Ú	supportedÚheightÚtargetÚir[   ÚscoredÚrs   `       rK   Ú_nearestrf   J   sO  ø€ ñ ˜ Ñ*ØˆØÐØ—‘œC ›JÓ'ˆØˆ>Ø˜Q‘<ÐÜCLÈYÓCW×l¹4¸1¸aÔ[^Ð_`Ó[aÐekÒ[k”3�vœc !›f‘~¨Ñ.Ó/°°AÒ6ÐlˆÑlÙ!'Œs�6‹{˜1‰~Ð9¨Y°q©\Ð9Ø
Œc�%‹jÑÜ˜“ˆØˆ>Ø˜Q‘<ÐÜ6?À	Ó6J×k©d¨a°ÔTZÐ[\ÓT]È~ÈqÑNj”3�q˜6‘z“? A qÒ)ÐkˆÑkÙ!'Œs�6‹{˜1‰~Ð9¨Y°q©\Ð9ðÜ�9Ó"IÔJÐJùó mùó løô ”zÐ"ò Ø˜‰|Òðús)   »DÁDÂ5DÃDÃ7D ÄD*Ä)D*c                ó6   — t        | j                  d«      «      S )z¤Text/image-to-video models declare durations; edit, upscale and avatar models (video/audio input)
    do not and are outside the unified ``video_generate`` surface.r*   )Úboolr^   )Úentrys    rK   Ú_is_generativerj   b   s   € ô �—	‘	Ð/Ó0Ó1Ð1r]   c                óò  — | j                  d«      xs g D �cg c]$  }t        |t        t        f«      sŒt        |«      ‘Œ& }}| j                  d«      rddgndgt	        | j                  d«      xs t
        «      t	        | j                  d«      xs t        «      |rt        |«      nd|rt        |«      ndt        | j                  d	«      «      d
t        | j                  d«      «      d
t        dœ
S c c}w )Nr*   r-   ÚtextÚimager,   r+   é   é   r.   Fr/   ©
Ú
modalitiesÚaspect_ratiosÚresolutionsÚmax_durationÚmin_durationÚsupports_audioÚsupports_negative_promptÚsupports_seedÚsupports_upscaleÚmax_reference_images)r^   r:   rZ   r=   ÚlistÚ_ALL_ASPECT_RATIOSÚ_RESOLUTION_HEIGHTrC   rB   rh   Ú_MAX_REFERENCE_IMAGES)ri   ÚdÚ	durationss      rK   Ú_entry_capabilitiesr�   h   sÖ   € Ø!&§¡Ð+@Ó!AÒ!GÀRÖg˜AÌ:ÐVWÔZ]Ô_dÐYeÕKf”�Q•Ðg€IÐgà+0¯9©9Ð5MÔ+N�v˜wÑ'ÐU[ÐT\Ü˜eŸi™iÐ(AÓBÒXÔFXÓYÜ˜EŸI™IÐ&=Ó>ÒTÔBTÓUÙ*3œ˜Iœ¸Ñ_hÌSÐQZÌ^ÐnoÜ˜uŸy™yÐ)9Ó:Ó;ÐY^Ü˜eŸi™i¨Ó/Ó0ÀeÜ 5ñð ùò hs
   ˜C4´C4c                ó   — dd| idœS )NÚ	image_urlÚurl)Útyperƒ   © )r„   s    rK   Ú_image_partr‡   u   s   € Ø¨u°c¨lÑ;Ð;r]   c                ój   — | j                  «       }|j                  d«      xs |j                  d«      S )z¬OpenRouter fetches the frame itself, so it needs a public HTTPS URL or an inline ``data:image/`` URL
    (what the sandbox confinement chokepoint hands us for local files).zhttps://zdata:image/)Úlowerr@   )rG   Úlowereds     rK   Ú_acceptable_image_refr‹   y   s0   € ð �k‰k‹m€GØ×Ñ˜jÓ)ÒN¨W×-?Ñ-?ÀÓ-NÐNr]   c       	   
     óR  — ||dœ}
|r+t        |t        | j                  d«      xs g «      «      |
d<   |r0t        |t        | j                  d«      xs g «      t        «      |
d<   |r=t	        t        t	        |«      t        | j                  d«      xs g «      «      «      |
d<   |ri t        |«      ¥dd	i¥g|
d
<   |r#|dt         D �cg c]  }t        |«      ‘Œ c}|
d<   |�| j                  d«      rt        |«      |
d<   |	�| j                  d«      rt	        |	«      |
d<   |
S c c}w )uÅ   Unified inputs â†’ OpenRouter body, clamped to the model's live limits; unsupported toggles are dropped
    rather than sent (the API 400s on ``seed``/``generate_audio`` for models that lack them).)ÚmodelÚpromptr,   Úaspect_ratior+   Ú
resolutionr*   ÚdurationÚ
frame_typer$   Úframe_imagesNÚinput_referencesr.   r/   )rf   r{   r^   r}   rZ   r‡   r~   rh   )ri   r�   rŽ   rƒ   Úreference_image_urlsr‘   r�   r�   Úaudior/   ÚpayloadÚus               rK   Ú_build_payloadr™   €   s&  € ð ).¸Ñ@€GÙÜ"*¨<¼¸e¿i¹iÐHaÓ>bÒ>hÐfhÓ9iÓ"jˆ�ÑÙÜ (¨´T¸%¿)¹)ÐD[Ó:\Ò:bÐ`bÓ5cÔewÓ xˆ�ÑÙÜ!¤(¬3¨x«=¼$¸u¿y¹yÐI^Ó?_Ò?eÐceÓ:fÓ"gÓhˆ�
ÑÙØ#Z¤k°)Ó&<Ð#Z¸lÈMÑ#ZÐ"[ˆ�ÑÙØ?SÐTjÔUjÐ?kÖ&l¸!¤{°1¥~Ò&lˆÐ"Ñ#ØÐ˜UŸY™YÐ'7Ô8Ü$(¨£KˆÐ Ñ!ØÐ˜EŸI™I fÔ-Ü˜d›)ˆ�‰Ø€Nùò 'ms   ÃD$c            
      óè   — e Zd ZdZdZdZdZdZdZdd„Z	dd„Z
dd	„Zdd
„Zdd„Zdd„Zd d„Zd!d„Zdd„Zd d„Zd"d„Zd#d„Zd#d„Zd$d„Zd%d„Zddddddddddœ		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d&d„Zy)'ÚOpenRouterVideoGenProviderzUEvery generative model on OpenRouter's video API, catalog and limits discovered live.Ú
openrouterÚ
OpenRouterr   g      Œ@g      N@c                ó   — d | _         y rX   )Ú_catalog_cache©Úselfs    rK   Ú__init__z#OpenRouterVideoGenProvider.__init__¡   s
   € ØLPˆÕr]   c                ó^   — t         j                  j                  dd«      j                  «       S )NÚOPENROUTER_API_KEYr4   )ÚosÚenvironr^   Ústripr    s    rK   Ú_api_keyz#OpenRouterVideoGenProvider._api_key¥   s!   € Ü�z‰z�~‰~Ð2°BÓ7×=Ñ=Ó?Ð?r]   c                óŒ   — t         j                  j                  dd«      j                  «       xs t        j                  d«      S )NÚOPENROUTER_BASE_URLr4   ú/)r¥   r¦   r^   r§   ÚDEFAULT_BASE_URLÚrstripr    s    rK   Ú	_base_urlz$OpenRouterVideoGenProvider._base_url¨   s3   € Ü—
‘
—‘Ð4°bÓ9×?Ñ?ÓAÒUÔEU×]Ñ]Ð^aÓbÐbr]   c                ó2   — d| j                  «       › �ddddœS )NzBearer zapplication/jsonz,https://github.com/NousResearch/hermes-agentzHermes Agent)ÚAuthorizationzContent-TypezHTTP-RefererzX-Title)r¨   r    s    rK   Ú_headersz#OpenRouterVideoGenProvider._headers«   s(   € Ø#*¨4¯=©=«?Ð*;Ð!<ÐN`Ø NÐ[iñkð 	kr]   c                ó*   — dd l }|j                  «       S )Nr   )ÚrequestsÚSession)r¡   r³   s     rK   Ú_sessionz#OpenRouterVideoGenProvider._session¯   s   € ÛØ×ÑÓ!Ð!r]   c                ó4   — t        | j                  «       «      S rX   )rh   r¨   r    s    rK   Úis_availablez'OpenRouterVideoGenProvider.is_available³   s   € Ü�D—M‘M“OÓ$Ð$r]   c                ó~  — | j                   r:t        j                  «       | j                   d   z
  t        k  r| j                   d   S g }	 ddl}|j                  | j                  «       › d�t        ¬«      }|j                  «        |j                  «       j                  d«      }t        |t        «      r|ng D �cg c]'  }t        |t        «      sŒ|j                  d«      sŒ&|‘Œ) }}|st         S |t        j                  «       f| _         |S c c}w # t        $ r }t        j                  d|«       Y d}~ŒNd}~ww xY w)	zaLive ``/videos/models`` entries (public endpoint), cached per TTL; the snapshot when unreachable.ro   r   Nz/videos/models)ÚtimeoutÚdatar(   z(OpenRouter video catalog unavailable: %s)rŸ   ÚtimeÚ	monotonicÚ_CATALOG_TTL_Sr³   r^   r®   Ú_CATALOG_TIMEOUT_SÚraise_for_statusÚjsonr:   r{   r;   Ú	ExceptionÚloggerÚdebugr2   )r¡   Úentriesr³   Úresponserº   ÚeÚexcs          rK   Ú_catalogz#OpenRouterVideoGenProvider._catalog·   s  € à×Ò¤4§>¡>Ó#3°d×6IÑ6IÈ!Ñ6LÑ#LÌ~Ò#]Ø×&Ñ& qÑ)Ð)Ø(*ˆð	JÛØ—|‘| t§~¡~Ó'7Ð&8¸Ð$GÔQc�|ÓdˆHØ×%Ñ%Ô'Ø—=‘=“?×&Ñ& vÓ.ˆDÜ+5°d¼DÔ+A¡4ÀrÖr˜QÌjÐYZÔ\`ÕNaÐfg×fkÑfkÐlpÕfq’qÐrˆGÐrñ Ü$Ð$Ø&¬¯©Ó(8Ð9ˆÔØˆùò søÜò 	JÜ�L‰LÐCÀS×IÑIûð	Jús7   Á
A1D Â;DÃDÃ#DÃ'D ÄD Ä	D<ÄD7Ä7D<c                óJ   ‡— t        ˆfd„| j                  «       D «       i «      S )u¬   Catalog row for *model_id*; ``{}`` for an unknown id (request passes through unclamped so a
        brand-new model works before our cache refreshes â€” the API validates).c              3  óL   •K  — | ]  }|j                  d «      ‰k(  sŒ|–— Œ y­w)r(   N)r^   )Ú.0rÆ   Úmodel_ids     €rK   ú	<genexpr>z4OpenRouterVideoGenProvider._entry.<locals>.<genexpr>Ì   s    øè ø€ ÒK˜1°1·5±5¸³;À(Ó3J”QÑKùs   ƒ$�$)ÚnextrÈ   )r¡   rÌ   s    `rK   Ú_entryz!OpenRouterVideoGenProvider._entryÉ   s   ø€ ô ÓK §¡£ÔKÈRÓPÐPr]   c                óú   — 	 ddl m}m}  | |«       dd«      }t        |t        «      r |j                  «       r|j                  «       S t        S # t        $ r"}t        j                  d|«       d }Y d }~Œ\d }~ww xY w)Nr   )Úcfg_getÚload_configÚ	video_genr�   z"Could not read video_gen.model: %s)
Úhermes_cli.configrÑ   rÒ   rÁ   rÂ   rÃ   r:   rO   r§   ÚDEFAULT_MODEL)r¡   rÑ   rÒ   rG   rÇ   s        rK   Ú_configured_modelz,OpenRouterVideoGenProvider._configured_modelÎ   sd   € ð	ß>Ù™K›M¨;¸Ó@ˆEô !+¨5´#Ô 6¸5¿;¹;¼=ˆu�{‰{‹}Ð[ÌmÐ[øô ò 	Ü�L‰LÐ=¸sÔCØ�Eûð	ús   ‚A Á	A:ÁA5Á5A:c                ó¢  — g }| j                  «       D ]¹  }t        |«      sŒt        |«      }|d   › d|d   › d�dj                  |d   «      g}||d   rdgng z  }|d	|d
   v rdgng z  }|j	                  |d   |j                  d«      xs |d   dj                  |«      t        |j                  d«      «      |d
   |d   |d   dœ«       Œ» |S )Nru   Ú-rt   r[   r«   rs   rv   r–   rm   rq   Úi2vr(   r)   z, r0   )r(   ÚdisplayÚ	strengthsÚpricerq   ru   rt   )rÈ   rj   r�   ÚjoinrA   r^   rL   )r¡   Úrowsri   ÚcapsÚextrass        rK   Úlist_modelsz&OpenRouterVideoGenProvider.list_models×   s  € ØˆØ—]‘]“_ò 		fˆEÜ! %Ô(ØÜ& uÓ-ˆDØ˜nÑ-Ð.¨a°°^Ñ0DÐ/EÀQÐGÈÏÉÐRVÐWdÑReÓIfÐgˆFØ 4Ð(8Ò#9�w‘i¸rÑAˆFØ ¨D°Ñ,>Ñ!>�u‘gÀBÑFˆFØ�K‰K˜u T™{°u·y±yÀÓ7HÒ7WÈEÐRVÉKÐfj×foÑfoÐpvÓfwÜ".¨u¯y©y¸Ó/HÓ"IÐY]Ð^jÑYkØ)-¨nÑ)=ÈtÐTbÑOcñeõ fð		fð ˆr]   c                ó   — t         S rX   )rÕ   r    s    rK   Údefault_modelz(OpenRouterVideoGenProvider.default_modelå   s   € ÜÐr]   c                ó´   — | j                  | j                  «       «      }|rt        |«      S ddgt        t        «      t        t
        «      ddddddt        dœ
S )zÉThe selected model's live surface; the API-wide union when the id is unknown or the catalog is down.
        ``supports_seed``/``supports_audio`` are per-model (Veo/Wan/Seedance: yes; Hailuo/Grok: no).rl   rm   rn   ro   TFrp   )rÏ   rÖ   r�   r{   r|   r}   r~   )r¡   ri   s     rK   Úcapabilitiesz'OpenRouterVideoGenProvider.capabilitiesè   sa   € ð —‘˜D×2Ñ2Ó4Ó5ˆÙÜ& uÓ-Ð-Ø% wÐ/Ä$ÔGYÓBZÜ#Ô$6Ó7ÈÐ]^Ø"&ÀEÐ\`Ø$)ÔCXñZð 	Zr]   c                ó   — dddddddœgdœS )	Nr�   Úpaidu¬   Veo 3.1, Sora 2 Pro, Kling 3, Seedance 2, Wan 3, Hailuo 3, Grok Imagine & more â€” live catalog; text-to-video, image-to-video & reference-to-video; uses OPENROUTER_API_KEYr¤   zOpenRouter API keyz#https://openrouter.ai/settings/keys)rF   rŽ   r„   )r)   ÚbadgeÚtagÚenv_varsr†   r    s    rK   Úget_setup_schemaz+OpenRouterVideoGenProvider.get_setup_schemaó   s2   € Ø$¨vðeà%9ÐEYð  cHñ  Ið  JñKð 	Kr]   c                óÄ  — t        j                  «       | j                  z   }| j                  «       › d|› �}d}	 |t        j                  «       z
  }|dk  r(t	        d|› dt        | j                  «      › d|› d�«      ‚|j                  || j                  «       t        dt        | j                  |«      «      ¬	«      }|j                  «        |j                  «       }t        |j                  d
«      xs d«      j                  «       xs d}|t        v r|S t        j                   t        | j"                  t        d|t        j                  «       z
  «      «      «       �Œ()Nú/videos/Úunknownr   z
video job z did not finish within zs (last status=ú)gü©ñÒMbP?)Úheadersr¹   Ústatusr4   g        )r»   r¼   Ú_poll_deadline_sr®   ÚTimeoutErrorrZ   r^   r±   rC   rB   Ú_request_timeout_sr¿   rÀ   rO   r‰   Ú_TERMINAL_STATUSESÚsleepÚ_poll_interval_s)	r¡   ÚsessionÚjob_idÚdeadliner„   Úlast_statusÚ	remainingrÅ   r—   s	            rK   Ú_pollz OpenRouterVideoGenProvider._pollú   sE  € Ü—>‘>Ó# d×&;Ñ&;Ñ;ˆØ—‘Ó!Ð" (¨6¨(Ð3ˆØˆØØ ¤4§>¡>Ó#3Ñ3ˆIØ˜AŠ~Ü" Z°¨xÐ7NÌsÐSW×ShÑShÓOiÐNjÐjyð  {Fð  zGð  GHð  $Ió  Jð  JØ—{‘{ 3°·±³ÌÈUÔTWÐX\×XoÑXoÐqzÓT{ÓI|�{Ó}ˆHØ×%Ñ%Ô'Ø—m‘m“oˆGÜ˜gŸk™k¨(Ó3Ò9°rÓ:×@Ñ@ÓBÒOÀiˆKØÔ0Ñ0Ø�Ü�J‰J”s˜4×0Ñ0´#°c¸8ÄdÇnÁnÓFVÑ;VÓ2WÓXÔYñ r]   c           	     óx   — t        t        | j                  «       › d|› d�d| j                  «       dd¬«      «      S )Nrí   z/contentrœ   T)Úprefixrð   Úrequire_video_content_typeÚtrusted_origin)rO   r   r®   r±   )r¡   rù   s     rK   Ú_save_completed_videoz0OpenRouterVideoGenProvider._save_completed_video
  sA   € ô ”> T§^¡^Ó%5Ð$6°h¸v¸hÀhÐ"OÐXdØ*.¯-©-«/ÐVZØ15ô7ó 8ð 	8r]   Nr   r   )	r�   rƒ   r•   r‘   r�   r�   Únegative_promptr–   r/   c       	        ó¢  ‡ ‡‡‡— ~~‰xs dj                  «       Š|xs dj                  «       xs ‰ j                  «       Šd&ˆˆˆˆ fd„}‰s	 |dd«      S ‰ j                  «       s	 |dd«      S |xs dj                  «       xs d }|xs g D �cg c]4  }t        |t        «      sŒ|j                  «       sŒ%|j                  «       ‘Œ6 }}|r|gng |z   D ]  }t        |«      rŒ |dd«      c S  ‰ j                  ‰«      }t        |‰‰|||‰||	|
¬	«
      }‰ j                  «       }	 |j                  ‰ j                  «       › d
�‰ j                  «       |‰ j                  ¬«      }|j                  dk\  rŒd}	 t	        |j                  «       j                  d«      xs i j                  d«      xs d«      } |d|j                  › d|xs |j"                  d d › �d«      t%        |dd «      }t'        |«      r |«        S S t	        |j                  «       j                  d«      xs d«      j                  «       }|s) |dd«      t%        |dd «      }t'        |«      r |«        S S ‰ j)                  ||«      }t	        |j                  d«      xs d«      j+                  «       }|dk7  rH |t	        |j                  d«      xs d|›�«      d«      t%        |dd «      }t'        |«      r |«        S S ‰ j-                  |«      }	 t%        |dd «      }t'        |«      r |«        	 |j                  d«      }t        |t2        «      r|ni }d|i|j                  d«      �d|d   ini ¥}t5        |‰‰|rd nd!t	        |j                  d"«      xs d«      t7        |j                  d#«      xs d$«      ‰ j8                  |¬%«      S c c}w # t         $ r d}Y �Œw xY w# t         $ rM}t.        j1                  dd¬«        |d|› �d«      cY d }~t%        |dd «      }t'        |«      r |«        S S d }~ww xY w# t%        |dd «      }t'        |«      r |«        w w xY w)'Nr4   Úerrorc                ó:   •— t        | |‰j                  ‰‰‰¬«      S )N)r  Ú
error_typeÚproviderr�   rŽ   r�   )r
   r)   )r  r  r�   rÌ   rŽ   r¡   s     €€€€rK   Úfailz1OpenRouterVideoGenProvider.generate.<locals>.fail  s#   ø€ Ü!¨¸*ÈtÏyÉyÐ`hÐqwØ/;ô=ð =r]   zprompt is requiredÚinvalid_requestzOPENROUTER_API_KEY is not setÚmissing_credentialsz[image inputs must be public HTTPS URLs or data:image/ URLs (OpenRouter fetches them itself))	r�   rŽ   rƒ   r•   r‘   r�   r�   r–   r/   z/videos)rð   rÀ   r¹   i�  Úmessagez&OpenRouter rejected the request (HTTP z): i,  Ú	api_errorÚcloser(   z3OpenRouter submit response did not contain a job idrñ   r   zvideo job ended with status=Ú
job_failedz"OpenRouter video generation failedT)Úexc_infoz$OpenRouter video generation failed: Úusagerù   Úcostrm   rl   r�   r‘   r   )Úvideor�   rŽ   Úmodalityr�   r‘   r  Úextra)r  rO   r  rO   ÚreturnúDict[str, Any])r§   rÖ   r¨   r:   rO   r‹   rÏ   r™   rµ   Úpostr®   r±   rô   Ústatus_coderÀ   r^   rÁ   rl   ÚgetattrÚcallablerý   r‰   r  rÂ   rÃ   r;   r   rZ   r)   )r¡   rŽ   r�   rƒ   r•   r‘   r�   r�   r  r–   r/   Úkwargsr	  re   ÚrefsÚrefri   r—   rø   Ú	submittedÚdetailr  rù   Újobrñ   Ú
video_pathrÇ   Ú	raw_usager  r  rÌ   s   ``    `                       @rK   Úgeneratez#OpenRouterVideoGenProvider.generate  sY  û€ ð ˜VØ’,˜B×%Ñ%Ó'ˆØ’K˜R×&Ñ&Ó(ÒD¨D×,BÑ,BÓ,Dˆ÷	=ð 	=ñ ÙÐ,Ð.?Ó@Ð@Ø�}‰}ŒÙÐ7Ð9NÓOÐOØ’_ "×+Ñ+Ó-Ò5°ˆ	Ø$8Ò$>¸BÖd˜aÄ:ÈaÔQTÕCUÐZ[×ZaÑZaÕZc�—‘•	ÐdˆÐdÙ#,�Y‘K°"¸Ñ<ò 	/ˆCÜ(¨Õ-ÙÐyØ-ó/ò /ð	/ð
 —‘˜HÓ%ˆÜ  ¨h¸vÐQZÐquØ*2ÀÐZdÐlqÐx|ô~ˆà—-‘-“/ˆð	ØŸ™¨¯©Ó(8Ð'9¸Ð%AÈ4Ï=É=Ë?ÐahØ-1×-DÑ-Dð %ó FˆIà×$Ñ$¨Ò+Ø�ð Ü  )§.¡.Ó"2×"6Ñ"6°wÓ"?Ò"EÀ2×!JÑ!JÈ9Ó!UÒ![ÐY[Ó\�Fñ ÐDÀY×EZÑEZÐD[Ð[^Ð_eÒ_}Ðir×iwÑiwÐx|Ðy|Ði}Ð^~ÐØ'ó)ô ˜G W¨dÓ3ˆEÜ˜ŒÙ•ð ô ˜Ÿ™Ó)×-Ñ-¨dÓ3Ò9°rÓ:×@Ñ@ÓBˆFÙÙÐQÐS^Ó_ô ˜G W¨dÓ3ˆEÜ˜ŒÙ•ð ð —*‘*˜W fÓ-ˆCÜ˜Ÿ™ Ó*Ò0¨bÓ1×7Ñ7Ó9ˆFØ˜Ò$ÙœC §¡¨Ó 0Ò ]Ð6RÐSYÐR\Ð4]Ó^Ð`lÓmô ˜G W¨dÓ3ˆEÜ˜ŒÙ•ð ð ×3Ñ3°FÓ;‰Jô
 ˜G W¨dÓ3ˆEÜ˜ŒÙ•à—G‘G˜GÓ$ˆ	Ü-7¸	Ä4Ô-H¡	ÈbˆØ!)¨6Ð xÐQV×QZÑQZÐ[aÓQbÐQn°v¸uÀV¹}Ñ6MÐtvÐ xˆÜØ H°VÑQZÁgÐ`fÜ˜WŸ[™[¨Ó8Ò>¸BÓ?Ì#ÈgÏkÉkÐZdÓNeÒNjÐijÓJkØ—Y‘Y eô-ð 	-ùòQ eøô" !ò  Ø“Fð ûô ò 	SÜ�L‰LÐ=ÈˆLÔMÙÐ>¸s¸eÐDÀkÓRÔRä˜G W¨dÓ3ˆEÜ˜ŒÙ•ð ûð	Sûô ˜G W¨dÓ3ˆEÜ˜ŒÙ•ð ús{   ÂN<Â$N<Â5N<Ä%AO Å5?O Æ4)O Ç>AO É#A*O Ë.O ÏOÏO ÏOÏO Ï	P)Ï"P$Ï>P)Ï?P, Ð$P)Ð)P, Ð,"Q©r  ÚNone)r  rO   )r  zDict[str, str])r  r   )r  rh   )r  r1   )rÌ   rO   r  r  )r  úOptional[str])r  r  )rø   r   rù   rO   r  r  )rù   rO   r  rO   )rŽ   rO   r�   r'  rƒ   r'  r•   úOptional[List[str]]r‘   úOptional[int]r�   rO   r�   rO   r  r'  r–   úOptional[bool]r/   r)  r  r   r  r  )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r)   Údisplay_namer÷   rò   rô   r¢   r¨   r®   r±   rµ   r·   rÈ   rÏ   rÖ   rá   rã   rå   rë   rý   r  r$  r†   r]   rK   r›   r›   ˜   s  „ Ù_à€DØ€LØÐØÐØÐóQó@ócókó"ó%óó$Qó
\óóó	ZóKóZó 8ð 6:ÐVZØ48ÐTXØ"°fÐ_cØ $¸Dñ	>-Øð>-Ø%2ð>-ØFSð>-à1ð>-àDQð>-ð ð>-ð 14ð>-ð P]ð>-ð ð	>-ð -:ð	>-ð MPð	>-ð
 
ô>-r]   r›   c                ó6   — | j                  t        «       «       y)uM   Plugin entry point â€” wire ``OpenRouterVideoGenProvider`` into the registry.N)Úregister_video_gen_providerr›   )Úctxs    rK   Úregisterr3  S  s   € à×#Ñ#Ô$>Ó$@ÕAr]   )rD   r   r  rO   )rG   r   r  zOptional[float]rX   )rG   r   r`   z	List[Any]ra   zOptional[Dict[str, int]]r  r   )ri   r  r  rh   )ri   r  r  r  )r„   rO   r  r  )rG   rO   r  rh   )ri   r  r�   rO   rŽ   rO   rƒ   r'  r•   r(  r‘   r)  r�   rO   r�   rO   r–   r*  r/   r)  r  r  r%  )+r.  Ú
__future__r   Úloggingr¥   r»   Útypingr   r   r   r   r   Úagent.video_gen_providerr	   r
   r   r   Ú	getLoggerr+  rÂ   rÕ   r¬   r½   r¾   Ú	frozensetrõ   r}   r|   r~   r{   Úranger2   Ú__annotations__rL   rT   rf   rj   r�   r‡   r‹   r™   r›   r3  r†   r]   rK   ú<module>r<     sm  ðòõ #ã Û 	Û ß 3Õ 3ç gÓ gà	ˆ×	Ñ	˜8Ó	$€à&€Ø1Ð Ø€ØÐ ÙÒZÓ[Ð ð "¨3¸ÀSÐSWÐ_cÐkoÐw{Ñ|Ð ØXÐ ØÐ ð Ð"9ÑRVÑW\Ð]^Ð`bÓWcÓRdØ% vÐ.ÒKxØ -¨|Ð<ÐPUÐ_dØ/5ÐPVÑWñYð+Ð Ð'ó óEó*ôó02ó
ó<óOðØðØ%(ðØ25ðØBOðØgzðàðà+.ðà<?ðàHVðà^kðð óô0x-Ð!1ô x-ôvBr]   