+
    kHàjJ  ã                  ó¾  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIHtHtH	t	H
t
Ht ^ RIHtHtHtHt ]P"                  ! ]4      tRtRtRtRt]! 0 R@m4      tR	R
RRRRRRRRRRRRRR/tRAt^tR]RRR]! ]! ^^4      4      RRR	.R. RBORR R!.R"R#R$R#R%R&R'R(R)//	.tR*] R+&   R, R- lt!R. R/ lt"RCR0 R1 llt#R2 R3 lt$R4 R5 lt%R6 R7 lt&R8 R9 lt'R: R; lt( ! R< R=]4      t)R> R? lt*R# )DuÆ  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@ç      $@Ú480pià  Ú540pi  Ú720piÐ  Ú768pi   Ú1080pi8  Ú1Ki   Ú2Ki   Ú4Kip  ÚidÚnamezMiniMax: Hailuo 3 MaxÚsupported_durationsÚsupported_resolutionsÚsupported_aspect_ratiosÚsupported_frame_imagesÚfirst_frameÚ
last_frameÚgenerate_audioFÚseedÚpricing_skusÚduration_seconds_480pz0.05Úduration_seconds_768pz0.08úlist[dict[str, Any]]Ú_FALLBACK_CATALOGc               ó    € V ^8„  d   QhRRRR/# )é   Úskusr   ÚreturnÚstr© )Úformats   "ÚJ/home/ubuntu/.hermes/hermes-agent/plugins/video_gen/openrouter/__init__.pyÚ__annotate__r,   ,   s   € ÷ Eñ E�sð E˜sñ Eó    c                óÔ  € \        V \        4      '       g   R# . pV P                  4        Fl  w  r# \        V4      pTP                  R4      '       d   TP                  T4       K;  TP                  R4      '       g   KT  TP                  T^d,          4       Kn  	  V'       g   R# \        V4      \        V4      reWV8X  d   RVR R2# RVR RVR R2#   \        \
        3 d     K»  i ; i)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Ú$z.2fz/su   â€“)Úcents_per_second_outputÚcents_per_video_output_second)
Ú
isinstanceÚdictÚitemsÚfloatÚ	TypeErrorÚ
ValueErrorÚ
startswithÚappendÚminÚmax)r&   Ú
per_secondÚkeyÚvalueÚamountÚloÚhis   &      r+   Ú_price_labelrD   ,   s×   € ô �dœD×!Ò!ÙØ €JØ—j‘j–l‰
ˆð	Ü˜5“\ˆFð �>‰>Ð,×-Ò-Ø×Ñ˜fÖ%Ø�^‰^ÐX×YÔYØ×Ñ˜f s�lÖ+ñ #÷ ÙÜ�‹_œc *›oˆØœXˆQˆr�#ˆh�bˆ>ÐD¨Q¨r°#¨h°c¸"¸S¸ÀÐ+DÐDøô œ:Ð&ô 	Úð	ús   ±CÃC'Ã&C'c               ó    € V ^8„  d   QhRRRR/# )r%   r@   r   r'   zOptional[float]r)   )r*   s   "r+   r,   r,   A   s   € ÷ ñ �#ð ˜/ñ r-   c                ó¢   €  \        V 4      P                  R 4      w  r\        V4      \        V4      ,          #   \        \        3 d     R# i ; i)Ú:N)r(   Úsplitr7   r9   ÚZeroDivisionError)r@   ÚwÚhs   &  r+   Ú_ratiorL   A   sH   € ðÜ�5‹z×Ñ Ó$‰ˆÜ�Q‹xœ% ›(Õ"Ð"øÜÔ)Ð*ô Úðús   ‚69 ¹AÁAc               ó(   € V ^8„  d   QhRRRRRRRR/# )r%   r@   r   Ú	supportedz	list[Any]ÚheightzOptional[dict[str, int]]r'   r)   )r*   s   "r+   r,   r,   I   s*   € ÷ ñ �Cð  Ið Ð7Oð Ð[^ñ r-   c           
     óø  a € V'       d   S V9   d   S # Ve�   VP                  \        S 4      4      pVf
   V^ ,          # \        V4       UUu. uF;  w  rE\        V4      V9   g   K  \        V\        V4      ,          V,
          4      WE3NK=  	  pppV'       d   \	        V4      ^,          # V^ ,          # R\        S 4      9   d|   \        S 4      pVf
   V^ ,          # \        V4       UUu. uF)  w  rE\        V4      ;pf   K  \        Ws,
          4      WE3NK+  	  pppV'       d   \	        V4      ^,          # V^ ,          #  \	        VV 3R lR7      # u uppi u uppi   \        \        3 d    T^ ,          u # i ; i)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.rG   c                óP   <€ \        \        V 4      \        S4      ,
          4      V 3# ©N)ÚabsÚint)Úsr@   s   &€r+   Ú<lambda>Ú_nearest.<locals>.<lambda>\   s   ø€ ¬S´°Q³¼#¸e»*Õ1DÓ-EÀqÑ,Ir-   )r?   )Úgetr(   Ú	enumeraterS   r<   rL   r8   r9   )r@   rN   rO   ÚtargetÚirU   ÚscoredÚrs   f&&     r+   Ú_nearestr^   I   sN  ø€ ÷ ˜ Ô*ØˆØÒØ—‘œC ›JÓ'ˆØŠ>Ø˜Q•<ÐÜCLÈYÔCWÔlÑCW¹4¸1Ô[^Ð_`Ó[aÐekÑ[kÔ6”3�vœc !›f•~¨Õ.Ó/°Ó6ÑCWˆÑlß!'Œs�6‹{˜1�~Ð9¨Y°q­\Ð9Ø
Œc�%‹jÔÜ˜“ˆØŠ>Ø˜Q•<ÐÜ6?À	Ô6JÔkÑ6J©d¨aÔTZÐ[\ÓT]È~ÈqÔ)”3�q•z“? AÓ)Ñ6JˆÑkß!'Œs�6‹{˜1�~Ð9¨Y°q­\Ð9ðÜ�9Ô"IÔJÐJùó mùó løô ”zÐ"ô Ø˜�|Òðús*   ÁEÁ%(EÃ)EÄEÄ?E ÅE9Å8E9c               ó    € V ^8„  d   QhRRRR/# )r%   Úentryúdict[str, Any]r'   Úboolr)   )r*   s   "r+   r,   r,   a   s   € ÷ 2ñ 2˜.ð 2¨Tñ 2r-   c                ó6   € \        V P                  R4      4      # )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   )rb   rX   )r`   s   &r+   Ú_is_generativerd   a   s   € ô �—	‘	Ð/Ó0Ó1Ð1r-   c               ó    € V ^8„  d   QhRRRR/# )r%   r`   ra   r'   r)   )r*   s   "r+   r,   r,   g   s   € ÷ 
ñ 
˜~ð 
°.ñ 
r-   c                ó^  € V P                  R 4      ;'       g    .  Uu. uF,  p\        V\        \        34      '       g   K!  \        V4      NK.  	  ppRV P                  R4      '       d   RR.MR.R\	        V P                  R4      ;'       g    \
        4      R\	        V P                  R4      ;'       g    \        4      R	V'       d   \        V4      M^R
V'       d   \        V4      M^R\        V P                  R4      4      RRR\        V P                  R4      4      RRR\        /
# u upi )r   Ú
modalitiesr   ÚtextÚimageÚaspect_ratiosr   Úresolutionsr   Úmax_durationÚmin_durationÚsupports_audior   Úsupports_negative_promptFÚsupports_seedr   Úsupports_upscaleÚmax_reference_images)rX   r4   rT   r7   ÚlistÚ_ALL_ASPECT_RATIOSÚ_RESOLUTION_HEIGHTr=   r<   rb   Ú_MAX_REFERENCE_IMAGES)r`   ÚdÚ	durationss   &  r+   Ú_entry_capabilitiesry   g   s  € Ø!&§¡Ð+@Ó!A×!GÐ!GÀRÐ!GÓgÑ!G˜AÌ:ÐVWÔZ]Ô_dÐYe×Kf””�Q–Ñ!G€IÐgà¨5¯9©9Ð5M×+NÒ+N�v˜wÑ'ÐU[ÐT\Øœ˜eŸi™iÐ(AÓB×XÐXÔFXÓYØ”t˜EŸI™IÐ&=Ó>×TÐTÔBTÓUØ¯)œ˜Iœ¸¸^×_hÌSÐQZÌ^ÐnoØœ$˜uŸy™yÐ)9Ó:Ó;Ð=WÐY^Øœ˜eŸi™i¨Ó/Ó0Ð2DÀeØÔ 5ðð ùò hs   žD*ÁD*c               ó    € V ^8„  d   QhRRRR/# )r%   Úurlr(   r'   ra   r)   )r*   s   "r+   r,   r,   t   s   € ÷ <ñ <�Sð <˜^ñ <r-   c                ó   € R RRRV //# )ÚtypeÚ	image_urlr{   r)   )r{   s   &r+   Ú_image_partr   t   s   € Ø�K ¨u°c¨lÐ;Ð;r-   c               ó    € V ^8„  d   QhRRRR/# )r%   r@   r(   r'   rb   r)   )r*   s   "r+   r,   r,   x   s   € ÷ Oñ O ð O¨ñ Or-   c                óv   € V P                  4       pVP                  R4      ;'       g    VP                  R4      # )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:   )r@   Úlowereds   & r+   Ú_acceptable_image_refr„   x   s3   € ð �k‰k‹m€GØ×Ñ˜jÓ)×NÐN¨W×-?Ñ-?ÀÓ-NÐNr-   c               óD   € V ^8„  d   QhRRRRRRRRRR	R
RRRRRRRRRRR/# )r%   r`   ra   Úmodelr(   Úpromptr~   úOptional[str]Úreference_image_urlsúOptional[list[str]]ÚdurationúOptional[int]Úaspect_ratioÚ
resolutionÚaudioúOptional[bool]r   r'   r)   )r*   s   "r+   r,   r,      sf   € ÷ ñ ØðØ%(ðØ25ðØBOðØgzðàðà+.ðà<?ðàHVðà^kðð ñr-   c       	   
     óØ  € RVRV/p
V'       d2   \        T\        V P                  R4      ;'       g    . 4      4      V
R&   V'       d7   \        T\        V P                  R4      ;'       g    . 4      \        4      V
R&   V'       dD   \	        \        \	        V4      \        V P                  R4      ;'       g    . 4      4      4      V
R&   V'       d   / \        V4      CR	R
/C.V
R&   V'       d&   VR\          Uu. uF  p\        V4      NK  	  upV
R&   Ve&   V P                  R4      '       d   \        V4      V
R&   V	e&   V P                  R4      '       d   \	        V	4      V
R&   V
# u upi )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).r†   r‡   r   r�   r   rŽ   r   r‹   Ú
frame_typer   Úframe_imagesNÚinput_referencesr   r   )r^   rs   rX   ru   rT   r   rv   rb   )r`   r†   r‡   r~   r‰   r‹   r�   rŽ   r�   r   ÚpayloadÚus   &$$$$$$$$$  r+   Ú_build_payloadr—      s?  € ð  '¨¨x¸Ð@€GßÜ"*¨<¼¸e¿i¹iÐHaÓ>b×>hÐ>hÐfhÓ9iÓ"jˆ�ÑßÜ (¨´T¸%¿)¹)ÐD[Ó:\×:bÐ:bÐ`bÓ5cÔewÓ xˆ�ÑßÜ!¤(¬3¨x«=¼$¸u¿y¹yÐI^Ó?_×?eÐ?eÐceÓ:fÓ"gÓhˆ�
ÑßØ#Z¤k°)Ó&<Ð#Z¸lÈMÑ#ZÐ"[ˆ�ÑßØ?SÐTjÔUjÑ?kÓ&lÑ?k¸!¤{°1¦~Ñ?kÑ&lˆÐ"Ñ#ØÒ˜UŸY™YÐ'7×8Ò8Ü$(¨£KˆÐ Ñ!ØÒ˜EŸI™I f×-Ò-Ü˜d›)ˆ�‰Ø€Nùò 'ms   Ã9E'c                  ó
  € ] tR t^—tRtRtRtRtRtRt	R R lt
R	 R
 ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R  ltR! R" ltR#R$R%R$R&R$R'R$R(R)R*R+R,R$R-R$R.R$/	R/ R0 lltR1tR$# )2ÚOpenRouterVideoGenProviderzUEvery generative model on OpenRouter's video API, catalog and limits discovered live.Ú
openrouterÚ
OpenRouterr   g      Œ@g      N@c               ó   € V ^8„  d   QhRR/# ©r%   r'   ÚNoner)   )r*   s   "r+   r,   Ú'OpenRouterVideoGenProvider.__annotate__    s   € ÷ Qñ Q˜$ñ Qr-   c                	ó   € R V n         R # rR   ©Ú_catalog_cache©Úselfs   &r+   Ú__init__Ú#OpenRouterVideoGenProvider.__init__    s
   € ØLPˆÖr-   c               ó   € V ^8„  d   QhRR/# )r%   r'   ztuple[str, str]r)   )r*   s   "r+   r,   rŸ   ¤   s   € ÷ ^ñ ^˜oñ ^r-   c                ó"  € ^ RI Hp V! RR7      p\        VP                  R4      ;'       g    R4      P	                  4       \        VP                  R4      ;'       g    R4      P	                  4       ;'       g    \
        P                  R4      3# )zÆ``(api_key, base_url)`` from the runtime resolver chat uses, so a pooled or OAuth credential counts
and a multiplexed profile never spends the launch profile's ``os.environ`` key; raises on failure.)Úresolve_runtime_providerrš   )Ú	requestedÚapi_keyr/   Úbase_urlÚ/)Úhermes_cli.runtime_providerr©   r(   rX   ÚstripÚDEFAULT_BASE_URLÚrstrip)r¤   r©   Úruntimes   &  r+   Ú_credentialsÚ'OpenRouterVideoGenProvider._credentials¤   sw   € õ 	Iá*°\ÔBˆÜ�G—K‘K 	Ó*×0Ð0¨bÓ1×7Ñ7Ó9Ü�W—[‘[ Ó,×2Ð2°Ó3×9Ñ9Ó;×OÐOÔ?O×WÑWÐX[Ó\ð^ð 	^r-   c               ó    € V ^8„  d   QhRRRR/# )r%   r«   r(   r'   údict[str, str]r)   )r*   s   "r+   r,   rŸ   ­   s   € ÷ kñ k ð k¨ñ kr-   c                	ó   € R RV 2RRRRRR/# )ÚAuthorizationzBearer zContent-Typezapplication/jsonzHTTP-Refererz,https://github.com/NousResearch/hermes-agentzX-TitlezHermes Agentr)   )r¤   r«   s   &&r+   Ú_headersÚ#OpenRouterVideoGenProvider._headers­   s+   € Ø 7¨7¨)Ð!4°nÐFXØÐ NÐPYÐ[iðkð 	kr-   c               ó   € V ^8„  d   QhRR/# )r%   r'   r   r)   )r*   s   "r+   r,   rŸ   ±   s   € ÷ "ñ "˜#ñ "r-   c                	ó*   € ^ RI pVP                  4       # )é    N)ÚrequestsÚSession)r¤   r¾   s   & r+   Ú_sessionÚ#OpenRouterVideoGenProvider._session±   s   € ÛØ×ÑÓ!Ð!r-   c               ó   € V ^8„  d   QhRR/# )r%   r'   rb   r)   )r*   s   "r+   r,   rŸ   µ   s   € ÷ ñ ˜dñ r-   c                	ó¢   €  \        V P                  4       ^ ,          4      #   \         d"   p\        P	                  RT4        Rp?R# Rp?ii ; i)r½   z1OpenRouter video credential resolution failed: %sNF)rb   r³   Ú	ExceptionÚloggerÚdebug)r¤   Úexcs   & r+   Úis_availableÚ'OpenRouterVideoGenProvider.is_availableµ   sB   € ð	Ü˜×)Ñ)Ó+¨AÕ.Ó/Ð/øÜô 	Ü�L‰LÐLÈcÔRÝûð	ús   ‚" ¢A­A	Á	Ac               ó   € V ^8„  d   QhRR/# ©r%   r'   r"   r)   )r*   s   "r+   r,   rŸ   ½   s   € ÷ ñ Ð.ñ r-   c                óô  € V P                   '       dJ   \        P                  ! 4       V P                   ^,          ,
          \        8  d   V P                   ^ ,          # . p ^ RIpVP                  V P                  4       ^,           R2\        R7      pVP                  4        VP                  4       P                  R4      p\        V\        4      '       d   TM.  Uu. uF6  p\        V\        4      '       g   K  VP                  R4      '       g   K4  VNK8  	  ppV'       g   \         # V\        P                  ! 4       3V n         V# u upi   \         d!   p\        P                  RT4        Rp?LWRp?ii ; i)zaLive ``/videos/models`` entries (public endpoint), cached per TTL; the snapshot when unreachable.Nz/videos/models)ÚtimeoutÚdatar   z(OpenRouter video catalog unavailable: %s)r¢   ÚtimeÚ	monotonicÚ_CATALOG_TTL_Sr¾   rX   r³   Ú_CATALOG_TIMEOUT_SÚraise_for_statusÚjsonr4   rs   r5   rÄ   rÅ   rÆ   r#   )r¤   Úentriesr¾   ÚresponserÎ   ÚerÇ   s   &      r+   Ú_catalogÚ#OpenRouterVideoGenProvider._catalog½   s)  € à××Ð¤4§>¢>Ó#3°d×6IÑ6IÈ!Õ6LÕ#LÌ~Ô#]Ø×&Ñ& qÕ)Ð)Ø(*ˆð	JÛØ—|‘| t×'8Ñ'8Ó':¸1Õ'=Ð&>¸nÐ$MÔWi�|ÓjˆHØ×%Ñ%Ô'Ø—=‘=“?×&Ñ& vÓ.ˆDÜ+5°d¼D×+AÒ+A¡4ÀrÐ#IÓrÑ#I˜QÌjÐYZÔ\`×Na”qÐfg×fkÑfkÐlp×fq—q�qÑ#IˆGÐr÷ Ü$Ð$Ø&¬¯ªÓ(8Ð9ˆÔØˆùò søÜô 	JÜ�L‰LÐCÀS×IÑIûð	Jús7   ÁA>E ÃEÃ:EÄEÄE ÅE ÅE7ÅE2Å2E7c               ó    € V ^8„  d   QhRRRR/# )r%   Úmodel_idr(   r'   ra   r)   )r*   s   "r+   r,   rŸ   Ï   s   € ÷ Qñ Q˜sð Q ~ñ Qr-   c                óL   a€ \        V3R lV P                  4        4       / 4      # )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  óV   <"  € T F  qP                  R 4      S8X  g   K  Vx € K   	  R# 5i)r   N)rX   )Ú.0r×   rÛ   s   & €r+   Ú	<genexpr>Ú4OpenRouterVideoGenProvider._entry.<locals>.<genexpr>Ò   s    øé € ÐK¡˜1·5±5¸³;À(Ñ3J—Q’Q£ùs   ƒ)Ÿ
))ÚnextrØ   )r¤   rÛ   s   &fr+   Ú_entryÚ!OpenRouterVideoGenProvider._entryÏ   s   ø€ ô ÔK §¡¤ÓKÈRÓPÐPr-   c               ó   € V ^8„  d   QhRR/# )r%   r'   r(   r)   )r*   s   "r+   r,   rŸ   Ô   s   € ÷ \ñ \ 3ñ \r-   c                	ó  €  ^ RI HpHp V! V! 4       RR4      p\        V\        4      '       d'   VP                  4       '       d   VP                  4       # \        #   \         d#   p\        P                  RT4       Rp Rp?LjRp?ii ; i)r½   )Úcfg_getÚload_configÚ	video_genr†   z"Could not read video_gen.model: %sN)
Úhermes_cli.configræ   rç   rÄ   rÅ   rÆ   r4   r(   r¯   ÚDEFAULT_MODEL)r¤   ræ   rç   r@   rÇ   s   &    r+   Ú_configured_modelÚ,OpenRouterVideoGenProvider._configured_modelÔ   si   € ð	ß>Ù™K›M¨;¸Ó@ˆEô !+¨5´#× 6Ò 6¸5¿;¹;¿=º=ˆu�{‰{‹}Ð[ÌmÐ[øô ô 	Ü�L‰LÐ=¸sÔCØ�Eûð	ús   ‚A ÁBÁ&BÂBc               ó   € V ^8„  d   QhRR/# rË   r)   )r*   s   "r+   r,   rŸ   Ý   s   € ÷ ñ Ð1ñ r-   c                	ó@  € . pV P                  4        EF  p\        V4      '       g   K  \        V4      pVR ,           RVR,           R2RP                  VR,          4      .pYCR,          '       d   R.M. ,          pTRVR	,          9   d   R
.M. ,          pTP	                  RVR,          RVP                  R4      ;'       g
    VR,          RRP                  V4      R\        VP                  R4      4      R	VR	,          R VR ,          RVR,          /4       EK	  	  V# )rm   Ú-rl   rU   r­   rk   rn   r�   ri   rg   Úi2vr   Údisplayr   Ú	strengthsz, Úpricer   )rØ   rd   ry   Újoinr;   rX   rD   )r¤   Úrowsr`   ÚcapsÚextrass   &    r+   Úlist_modelsÚ&OpenRouterVideoGenProvider.list_modelsÝ   s  € ØˆØ—]‘]—_ˆEÜ! %×(Ò(ÙÜ& uÓ-ˆDØ˜nÕ-Ð.¨a°°^Õ0DÐ/EÀQÐGÈÏÉÐRVÐWdÕReÓIfÐgˆFØÐ(8×#9Ô#9�w‘i¸rÕAˆFØ ¨D°Õ,>Ô!>�u‘gÀBÕFˆFØ�K‰K˜˜u T�{¨I°u·y±yÀÓ7H×7WÐ7WÈEÐRVÍKÐYdÐfj×foÑfoÐpvÓfwØ ¤,¨u¯y©y¸Ó/HÓ"IÈ<ÐY]Ð^jÕYkØ'¨¨nÕ)=¸~ÈtÐTbÕOcðe÷ fñ %ð ˆr-   c               ó   € V ^8„  d   QhRR/# )r%   r'   rˆ   r)   )r*   s   "r+   r,   rŸ   ë   s   € ÷ ñ ˜}ñ r-   c                	ó   € \         # rR   )rê   r£   s   &r+   Údefault_modelÚ(OpenRouterVideoGenProvider.default_modelë   s   € ÜÐr-   c               ó   € V ^8„  d   QhRR/# ©r%   r'   ra   r)   )r*   s   "r+   r,   rŸ   î   s   € ÷ 	Zñ 	Z˜nñ 	Zr-   c                óÒ   € V P                  V P                  4       4      pV'       d   \        V4      # RRR.R\        \        4      R\        \
        4      R^R^RR	R
RRR	RRR\        /
# )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).rg   rh   ri   rj   rk   rl   rm   rn   Tro   Frp   rq   rr   )râ   rë   ry   rs   rt   ru   rv   )r¤   r`   s   & r+   ÚcapabilitiesÚ'OpenRouterVideoGenProvider.capabilitiesî   sw   € ð —‘˜D×2Ñ2Ó4Ó5ˆßÜ& uÓ-Ð-Ø˜v wÐ/°Ä$ÔGYÓBZØœtÔ$6Ó7¸ÈÈ^Ð]^Ø  $Ð(BÀEÈ?Ð\`Ø" EÐ+AÔCXðZð 	Zr-   c               ó   € V ^8„  d   QhRR/# rÿ   r)   )r*   s   "r+   r,   rŸ   ù   s   € ÷ Kñ K .ñ Kr-   c                	ó$   € R RRRRRRRRR	R
RR/./# )r   r›   ÚbadgeÚpaidÚtagu¬   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_KEYÚenv_varsr?   ÚOPENROUTER_API_KEYr‡   zOpenRouter API keyr{   z#https://openrouter.ai/settings/keysr)   r£   s   &r+   Úget_setup_schemaÚ+OpenRouterVideoGenProvider.get_setup_schemaù   sC   € Ø˜ g¨vØð eà˜eÐ%9¸8ÐEYÐ[`ð  cHð  Ið  JðKð 	Kr-   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r%   Úsessionr   Újob_idr(   r¬   Úheadersr¶   r'   ra   r)   )r*   s   "r+   r,   rŸ      s7   € ÷ Zñ Z˜Sð Z¨#ð Z¸ð ZÀ~ð ZÐZhñ Zr-   c                	óÎ  € \         P                  ! 4       V P                  ,           pV R V 2pRp V\         P                  ! 4       ,
          pV^ 8:  d)   \        RV R\	        V P                  4       RV R24      hVP                  Wd\        R\        V P                  V4      4      R7      p	V	P                  4        V	P                  4       p
\        V
P                  R4      ;'       g    R	4      P                  4       ;'       g    RpV\        9   d   V
# \         P                  ! \        V P                  \        R
V\         P                  ! 4       ,
          4      4      4       EK7  )ú/videos/Úunknownz
video job z did not finish within zs (last status=Ú)gü©ñÒMbP?)r  rÍ   Ústatusr/   g        )rÏ   rÐ   Ú_poll_deadline_sÚTimeoutErrorrT   rX   r=   r<   Ú_request_timeout_srÓ   rÔ   r(   r‚   Ú_TERMINAL_STATUSESÚsleepÚ_poll_interval_s)r¤   r  r  r¬   r  Údeadliner{   Úlast_statusÚ	remainingrÖ   r•   s   &&&&&      r+   Ú_pollÚ OpenRouterVideoGenProvider._poll   s5  € Ü—>’>Ó# d×&;Ñ&;Õ;ˆØ�
˜( 6 (Ð+ˆØˆØØ ¤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ÌCÐPT×PgÑPgÐirÓLsÓAt�{ÓuˆHØ×%Ñ%Ô'Ø—m‘m“oˆGÜ˜gŸk™k¨(Ó3×9Ð9°rÓ:×@Ñ@ÓB×OÐOÀiˆKØÔ0Ô0Ø�Ü�JŠJ”s˜4×0Ñ0´#°c¸8ÄdÇnÂnÓFVÕ;VÓ2WÓX×Yr-   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r%   r  r(   r¬   r  r¶   r'   r)   )r*   s   "r+   r,   rŸ     s)   € ÷ 8ñ 8¨Cð 8¸3ð 8Èð 8Ð\_ñ 8r-   c           
     	ó@   € \        \        V R V R2RVRRR7      4      # )r  z/contentrš   T)Úprefixr  Úrequire_video_content_typeÚtrusted_origin)r(   r
   )r¤   r  r¬   r  s   &&&&r+   Ú_save_completed_videoÚ0OpenRouterVideoGenProvider._save_completed_video  s2   € ô ”> X J¨h°v°h¸hÐ"GÐP\Ø*1ÈdØ15ô7ó 8ð 	8r-   r†   Nr~   r‰   r‹   r�   ú16:9rŽ   r   Únegative_promptr�   r   c               óH   € V ^8„  d   QhRRRRRRRRRR	R
RRRRRRRRR	RRRR/# )r%   r‡   r(   r†   rˆ   r~   r‰   rŠ   r‹   rŒ   r�   rŽ   r(  r�   r�   r   Úkwargsr   r'   ra   r)   )r*   s   "r+   r,   rŸ     sŒ   € ÷ E-ñ E-ØðE-Ø%2ðE-ØFSðE-à1ðE-àDQðE-ð ðE-ð 14ðE-ð P]ðE-ð ð	E-ð -:ð	E-ð MPð	E-ð
 
ñE-r-   c       	        	ó~
  a aaa!€ ??S;'       g    R P                  4       oT;'       g    R P                  4       ;'       g    S P                  4       o!R VV!VV 3R llpS'       g
   V! RR4      #  S P                  4       w  rÞT'       g
   T! RR4      # S P	                  T4      pT;'       g    R P                  4       ;'       g    RpT;'       g    .  Uu. uFC  p\        T\        4      '       g   K  TP                  4       '       g   K3  TP                  4       NKE  	  ppT'       d   T.M. T,            F  p\        T4      '       d   K  T! R	R4      u # 	  S P                  S!4      p\        TS!STTTSYyT
R
7
      pS P                  4       p TP                  T R2TTS P                  R7      pTP                  R8¼  d©   R p \        TP                  4       P                  R4      ;'       g    / P                  R4      ;'       g    R 4      pT! RTP                   RT;'       g    TP                   R,           2R4      \#        TRR4      p\%        T4      '       d	   T! 4        # # \        TP                  4       P                  R4      ;'       g    R 4      P                  4       pT'       g0   T! RR4      \#        TRR4      p\%        T4      '       d	   T! 4        # # S P'                  TTTT4      p\        TP                  R4      ;'       g    R 4      P)                  4       pTR8w  dV   T! \        TP                  R4      ;'       g    RT: 24      R4      \#        TRR4      p\%        T4      '       d	   T! 4        # # S P+                  TTT4      p \#        TRR4      p\%        T4      '       d   T! 4        TP                  R4      p\        T\0        4      '       d   TM/ pR T/TP                  R!4      e   R!TR!,          /M/ Cp \3        TS!ST'       d   R"MR#\        TP                  R$4      ;'       g    R 4      \5        TP                  R%4      ;'       g    ^ 4      S P6                  T R&7      #   \         d   pT! RT 2R4      u Rp?# Rp?ii ; iu upi   \         d    R p ELŸi ; i  \         dT   p\,        P/                  RRR7       T! RT 2R4      u Rp?\#        TRR4      p\%        T4      '       d	   T! 4        # # Rp?ii ; i  \#        TRR4      p\%        T4      '       d	   T! 4        i i ; i)'r/   c               ó$   € V ^8„  d   QhRRRRRR/# )r%   Úerrorr(   Ú
error_typer'   ra   r)   )r*   s   "r+   r,   Ú9OpenRouterVideoGenProvider.generate.<locals>.__annotate__"  s!   € ÷ 	=ñ 	=˜ð 	=¨ð 	=°ñ 	=r-   c           	     ó8   <€ \        WSP                  SSSR 7      # ))r-  r.  Úproviderr†   r‡   r�   )r	   r   )r-  r.  r�   rÛ   r‡   r¤   s   &&€€€€r+   ÚfailÚ1OpenRouterVideoGenProvider.generate.<locals>.fail"  s!   ø€ Ü!¨ÈtÏyÉyÐ`hÐqwØ/;ô=ð =r-   zprompt is requiredÚinvalid_requestz*Could not resolve OpenRouter credentials: Úmissing_credentialsNzTNo OpenRouter credential: set OPENROUTER_API_KEY or run `hermes auth add openrouter`z[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�  r-  Úmessagez&OpenRouter rejected the request (HTTP z): :Ni,  NÚ	api_errorÚcloser   z3OpenRouter submit response did not contain a job idr  Ú	completedzvideo job ended with status=Ú
job_failedz"OpenRouter video generation failedT)Úexc_infoz$OpenRouter video generation failed: Úusager  Úcostri   rh   r�   r‹   )Úvideor†   r‡   Úmodalityr�   r‹   r1  Úextra)r¯   rë   r³   rÄ   r¹   r4   r(   r„   râ   r—   rÀ   Úpostr  Ústatus_coderÔ   rX   rh   ÚgetattrÚcallabler  r‚   r%  rÅ   rÆ   r5   r   rT   r   )"r¤   r‡   r†   r~   r‰   r‹   r�   rŽ   r(  r�   r   r*  r2  r«   r¬   rÇ   r  r]   ÚrefsÚrefr`   r•   r  Ú	submittedÚdetailr8  r  Újobr  Ú
video_pathÚ	raw_usager<  r@  rÛ   s"   ff$$$$d$$$$,                     @r+   ÚgenerateÚ#OpenRouterVideoGenProvider.generate  sÞ  û€ ð ˜VØ—,�,˜B×%Ñ%Ó'ˆØ—K�K˜R×&Ñ&Ó(×DÐD¨D×,BÑ,BÓ,Dˆ÷	=ó 	=÷ ÙÐ,Ð.?Ó@Ð@ð	cØ $× 1Ñ 1Ó 3ÑˆG÷ ÙÐnØ-ó/ð /ð —-‘- Ó(ˆØ—_�_ "×+Ñ+Ó-×5Ð5°ˆ	Ø$8×$>Ð$>¸BÐ$>ÓdÑ$>˜aÄ:ÈaÔQT×CU”	ÐZ[×ZaÑZa×Zc”	�—‘–	Ñ$>ˆÐdß#,�Y‘K°"¸×<Ð<ˆCÜ(¨×-Ô-ÙÐyØ-ó/ò /ñ =ð
 —‘˜HÓ%ˆÜ  ¨h¸vÐQZÐquØ*2ÀÐZdÐx|ô~ˆà—-‘-“/ˆð	ØŸ™¨ z°Ð%9À7ÐQXØ-1×-DÑ-Dð %ó FˆIà×$Ñ$¨Ô+Ø�ð Ü  )§.¡.Ó"2×"6Ñ"6°wÓ"?×"EÐ"EÀ2×!JÑ!JÈ9Ó!U×![Ð![ÐY[Ó\�Fñ ÐDÀY×EZÑEZÐD[Ð[^Ð_e×_}Ð_}Ðir×iwÑiwÐx|Õi}Ð^~ÐØ'ó)ô ˜G W¨dÓ3ˆEÜ˜�ŠÙ•ð ô ˜Ÿ™Ó)×-Ñ-¨dÓ3×9Ð9°rÓ:×@Ñ@ÓBˆFßÙÐQÐS^Ó_ô ˜G W¨dÓ3ˆEÜ˜�ŠÙ•ð ð —*‘*˜W f¨h¸Ó@ˆCÜ˜Ÿ™ Ó*×0Ð0¨bÓ1×7Ñ7Ó9ˆFØ˜Ô$ÙœC §¡¨Ó 0× ]Ð ]Ð6RÐSYÑR\Ð4]Ó^Ð`lÓmô ˜G W¨dÓ3ˆEÜ˜�ŠÙ•ð ð ×3Ñ3°F¸HÀgÓN‰Jô
 ˜G W¨dÓ3ˆEÜ˜�ŠÙ”à—G‘G˜GÓ$ˆ	Ü-7¸	Ä4×-HÒ-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ÐNjÐijÓJkØ—Y‘Y eô-ð 	-øôa ô 	cÙÐDÀSÀEÐJÐLaÓbÕbûð	cüò 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À   Á1Q6 ÃRÃ4RÄRÆ5R3 Ç*R Ç0R È	R ÈR3 È)R3 É**R3 ÊR3 Ê2R3 Ë!0R3 Ì:R3 ÍR3 ÎR3 Ñ6RÒRÒRÒRÒR0Ò,R3 Ò/R0Ò0R3 Ò3TÒ>"TÓ TÓ!T ÔTÔT Ô(T<r¡   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   Údisplay_namer  r  r  r¥   r³   r¹   rÀ   rÈ   rØ   râ   rë   rø   rü   r  r
  r  r%  rL  Ú__static_attributes__r)   r-   r+   r™   r™   —   sÙ   † Ù_à€DØ€LØÐØÐØÐõQõ^õkõ"õõõ$Qõ
\õõõ	ZõKõZõ 8ðE-Ø59ðE-ØVZðE-à48ðE-àTXðE-ð #ðE-ð 7=ðE-ð `dðE-ð !%ð	E-ð =A÷	E-ó E-r-   r™   c               ó   € V ^8„  d   QhRR/# r�   r)   )r*   s   "r+   r,   r,   `  s   € ÷ Bñ B�Tñ Br-   c                ó8   € V P                  \        4       4       R# )uM   Plugin entry point â€” wire ``OpenRouterVideoGenProvider`` into the registry.N)Úregister_video_gen_providerr™   )Úctxs   &r+   ÚregisterrY  `  s   € à×#Ñ#Ô$>Ó$@ÖAr-   >   ÚfailedÚexpiredÚcanceledÚ	cancelledr9  )	r'  ú9:16ú1:1ú4:3ú3:4z3:2z2:3ú21:9z9:21)rb  r'  r`  r_  ra  r^  rR   )+Ú__conditional_annotations__rR  Ú
__future__r   ÚloggingrÏ   Útypingr   r   r   r   r   Úagent.video_gen_providerr   r	   r
   r   Ú	getLoggerrN  rÅ   rê   r°   rÑ   rÒ   Ú	frozensetr  ru   rt   rv   rs   Úranger#   Ú__annotations__rD   rL   r^   rd   ry   r   r„   r—   r™   rY  )rc  s   @r+   Ú<module>rl     s>  øðôõ #ã Û ß 3Õ 3ç gÓ gà	×	Ò	˜8Ó	$€à&€Ø1Ð Ø€ØÐ ÙÒZÓ[Ð ð ˜c 6¨3°¸¸VÀSÈ'ÐSWÐY]Ð_cÐeiÐkoÐquÐw{Ð|Ð ØXÐ ØÐ ð 
ˆ=˜&Ð"9Ð;PÑRVÑW\Ð]^Ð`bÓWcÓRdØ˜v vÐ.Ð0IÒKxØ ¨|Ð<Ð>NÐPUÐW]Ð_dØÐ-¨vÐ7NÐPVÐWðYð+Ð Ð'ó õEõ*÷õ02õ
õ<õOõô0F-Ð!1ô F-÷RBr-   