
    PL
j:                    >   U d Z ddlmZ ddl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ZddlmZmZmZ  ej        e          ZdZdZdZd	Zd
ZdZdZh dZdd
hZdZdddddddgdiZde d<   d8dZ!d9dZ"d:d Z#d;d#Z$d<d)Z%d=d/Z&d>d3Z' G d4 d5e          Z(d?d7Z)dS )@u[  xAI Grok-Imagine video generation backend.

Surface: text-to-video and image-to-video (animate an input image)
through xAI's ``/videos/generations`` endpoint. Edit and extend are not
exposed in this unified surface — xAI is the only backend that supports
them and the inconsistency would force per-backend prose in the agent's
tool description.

Originally salvaged from PR #10600 by @Jaaneek; reshaped into the
:class:`VideoGenProvider` plugin interface and trimmed to the
generate-only surface.

Authentication: xAI Grok OAuth tokens (preferred — billed against the
user's SuperGrok subscription) or ``XAI_API_KEY``. Both routes are
resolved through ``tools.xai_http.resolve_xai_http_credentials`` so a
single login covers chat + TTS + image gen + video gen + transcription.
Output is an HTTPS URL from xAI's CDN; the gateway downloads and
delivers it.
    )annotationsN)AnyDictListOptionalTuple)VideoGenProvidererror_responsesuccess_responsezhttps://api.x.ai/v1zgrok-imagine-video   16:9720p      >   1:12:33:23:44:39:16r   480p   zGrok Imagine Videoz~60-240szMText-to-video + image-to-video; up to 7 reference images for style/character.z!see https://docs.x.ai/docs/modelstextimage)displayspeed	strengthsprice
modalitieszDict[str, Dict[str, Any]]_MODELSreturnTuple[str, str]c                    	 ddl m}   |             pi }n4# t          $ r'}t                              d|           i }Y d}~nd}~ww xY wt          |                    d          pt          j        dd                    	                                }t          |                    d          pt          j        d	          pt                    	                                                    d
          }||fS )u/  Return ``(api_key, base_url)`` from the shared xAI credential resolver.

    Order: runtime provider (xai-oauth pool entry) → singleton ``auth.json``
    OAuth tokens → ``XAI_API_KEY`` env var. ``api_key`` is empty when no
    credential source is available; callers must check before using it.
    r   )resolve_xai_http_credentialsz"xAI credential resolver failed: %sNapi_keyXAI_API_KEY base_urlXAI_BASE_URL/)tools.xai_httpr$   	ExceptionloggerdebugstrgetosgetenvstripDEFAULT_XAI_BASE_URLrstrip)r$   credsexcr%   r(   s        B/home/kuhnn/.hermes/hermes-agent/plugins/video_gen/xai/__init__.py_resolve_xai_credentialsr9   I   s   ??????,,..4"   93??? %))I&&F")M2*F*FGGMMOOG		* 	 9^$$	   eggffSkk	 
 Hs    
AAAr/   c                 F    	 ddl m}   |             S # t          $ r Y dS w xY w)Nr   hermes_xai_user_agentzhermes-agent/video_gen)r+   r<   r,   r;   s    r8   _xai_user_agentr=   a   sL    (888888$$&&& ( ( ('''(s    
  r%   Dict[str, str]c                ,    d|  dt                      dS )NzBearer zapplication/json)AuthorizationzContent-Typez
User-Agent)r=   )r%   s    r8   _xai_headersrA   j   s(    ,7,,*%''      reference_image_urlsOptional[List[str]]c                z    g }| pg D ]1}|pd                                 }|r|                    d|i           2|pd S )Nr'   url)r3   append)rC   refsrF   
normalizeds       r8   _normalize_reference_imagesrJ   r   sZ    D#)r - -iR&&((
 	-KK
+,,,<4rB   durationOptional[int]has_reference_imagesboolintc                P    | | nt           }|dk     rd}|dk    rd}|r|dk    rd}|S )N      
   )DEFAULT_DURATION)rK   rM   values      r8   _clamp_durationrV   {   sG     ,HH2BEqyyrzz 

LrB   clienthttpx.AsyncClientpayloadDict[str, Any]r(   c          	     L  K   |                      | di t          |          dt          t          j                              i|d           d{V }|                                 |                                }|                    d          }|st          d          |S )up   POST to /videos/generations — xAI's only public endpoint for our
    text-to-video and image-to-video surface.z/videos/generationszx-idempotency-key<   )headersjsontimeoutN
request_idz-xAI video response did not include request_id)	postrA   r/   uuiduuid4raise_for_statusr^   r0   RuntimeError)rW   rY   r%   r(   responsebodyr`   s          r8   _submitrh      s       [[(((Q<((Q*=s4:<<?P?PQQ	 !        H ==??D,''J LJKKKrB   r`   timeout_secondspoll_intervalc                 K   d}d}||k     r|                      | d| t          |          d           d {V }|                                 |                                }	|	                     d          pd                                }|dk    rd|	d	S |d
v r||	d	S t          j        |           d {V  ||z  }||k     dd|id	S )Ng        queuedz/videos/   )r]   r_   statusr'   done)rn   rg   >   errorfailedexpired	cancelledr_   )r0   rA   rd   r^   lowerasynciosleep)
rW   r`   r%   r(   ri   rj   elapsedlast_statusrf   rg   s
             r8   _pollry      s6      GK
O
#
#---- )) $ 
 
 
 
 
 
 
 

 	!!###}}xx))/R6688&  $d333EEE)4888mM*********= ! O
#
#$  (K)@AAArB   c            
          e Zd ZdZed"d            Zed"d            Zd#dZd$d	Zd%dZ	d&dZ
d&dZddddeedddd	d'd Zd(d!ZdS ))XAIVideoGenProviderz@xAI grok-imagine-video backend (text-to-video + image-to-video).r!   r/   c                    dS )Nxai selfs    r8   namezXAIVideoGenProvider.name       urB   c                    dS )NxAIr~   r   s    r8   display_namez XAIVideoGenProvider.display_name   r   rB   rN   c                B    t                      \  }}t          |          S N)r9   rN   )r   r%   _s      r8   is_availablez XAIVideoGenProvider.is_available   s    -//
G}}rB   List[Dict[str, Any]]c                H    d t                                           D             S )Nc                     g | ]\  }}d |i|S )idr~   ).0midmetas      r8   
<listcomp>z3XAIVideoGenProvider.list_models.<locals>.<listcomp>   s&    EEE	Ts#d#EEErB   )r    itemsr   s    r8   list_modelszXAIVideoGenProvider.list_models   s    EEW]]__EEEErB   Optional[str]c                    t           S r   )DEFAULT_MODELr   s    r8   default_modelz!XAIVideoGenProvider.default_model   s    rB   rZ   c                    dddg ddS )NzxAI Grok ImaginepaiduY   grok-imagine-video — text-to-video & image-to-video; uses xAI Grok OAuth or XAI_API_KEYxai_grok)r   badgetagenv_vars
post_setupr~   r   s    r8   get_setup_schemaz$XAIVideoGenProvider.get_setup_schema   s"     'n$
 
 	
rB   c           	     n    ddgt          t                    t          t                    ddddt          dS )Nr   r   rR   rQ   F)r   aspect_ratiosresolutionsmax_durationmin_durationsupports_audiosupports_negative_promptmax_reference_images)sortedVALID_ASPECT_RATIOSVALID_RESOLUTIONSMAX_REFERENCE_IMAGESr   s    r8   capabilitiesz XAIVideoGenProvider.capabilities   s@    !7+#$788!"344#(-$8	
 	
 		
rB   N)	model	image_urlrC   rK   aspect_ratio
resolutionnegative_promptaudioseedpromptr   r   rC   rD   rK   rL   r   r   r   r   Optional[bool]r   kwargsr   c       	           	 t          j                    }	 |                    |                     |||||||                    |                                 S # |                                 w xY w# t
          $ rF}t                              d|d           t          d| dd|pt          ||          cY d }~S d }~ww xY w)	N)r   r   r   rC   rK   r   r   z$xAI video gen unexpected failure: %sT)exc_infozxAI video generation failed: 	api_errorr}   )rp   
error_typeproviderr   r   r   )
ru   new_event_looprun_until_complete_generate_asynccloser,   r-   warningr
   r   )r   r   r   r   rC   rK   r   r   r   r   r   r   loopr7   s                 r8   generatezXAIVideoGenProvider.generate   s   	)++D..t/C/C!')=%!-) 0D 0 0   



 		 		 		NNA3QUNVVV!;c;;&,})        		s4   A2 .A A2 A//A2 2
C<;B=7C=Cc          
       K   t                      \  }}	|st          ddd|          S |pd                                }|pd                                pd }
|pt                                          }|pt                                                                          }|
rdnd}|st          dd	d|          S t          |          }|r4t          |          t          k    rt          d
t           ddd|          S |
r|rt          ddd|          S t          |t          |                    }|t          vrt          }|t          vrt          }|pt          ||||d}|
rd|
i|d<   |r||d<   t          j                    4 d {V }	 t!          ||||	           d {V }n# t          j        $ rq}d}	 |j        j        d d         }n# t(          $ r Y nw xY wt          d|j        j         d|p| dd|pt          |          cY d }~cd d d           d {V  S d }~ww xY wt-          ||||	t.          t0                     d {V }d d d           d {V  n# 1 d {V swxY w Y   |d         }|d         }|dk    r|                    d          pi }|                    d          }|s0t          ddd|                    d           p|pt          |          S ||d!}|                    d"          r|d"         |d"<   t5          ||                    d           p|pt          ||||                    d#          p|d|$          S |d%k    r$t          d&t.           d'd%d|pt          |          S |                    d(i           pi                     d)          p|                    d)          pd*| d+}t          |d,| d|pt          |          S )-NzNo xAI credentials found. Sign in via `hermes auth add xai-oauth` (SuperGrok subscription) or set XAI_API_KEY from https://console.x.ai/.auth_requiredr}   )rp   r   r   r   r'   r   r   zMprompt is required for xAI video generation (text-to-video or image-to-video)missing_promptz&reference_image_urls supports at most z images on xAItoo_many_referencesz<image_url and reference_image_urls cannot be combined on xAIconflicting_inputs)rM   )r   r   rK   r   r   rF   reference_images)r%   r(   i  zxAI submit failed (z): r   )rp   r   r   r   r   )r%   r(   ri   rj   rn   rg   ro   videoz2xAI video generation completed without a video URLempty_responser   )r`   r   usagerK   )r   r   r   modalityr   rK   r   extrar_   z-Timed out waiting for video generation after srp   messagez(xAI video generation ended with status ''xai_)r9   r
   r3   DEFAULT_ASPECT_RATIODEFAULT_RESOLUTIONrt   rJ   lenr   rV   rN   r   r   r   httpxAsyncClientrh   HTTPStatusErrorrf   r   r,   status_codery   DEFAULT_TIMEOUT_SECONDSDEFAULT_POLL_INTERVAL_SECONDSr0   r   )r   r   r   r   rC   rK   r   r   r%   r(   image_url_normnormalized_aspect_rationormalized_resolutionmodality_usedrH   clamped_durationrY   rW   r`   r7   detailpoll_resultrn   rg   r   rF   r   r   s                               r8   r   z#XAIVideoGenProvider._generate_async  s.      566 		!- +v    ,B%%''#/r0022:d#/#G3G"N"N"P"P!+!A/A H H J J P P R R#1=v 	!8 ,v    ++?@@ 	CII 444!c?Sccc0v   
  	d 	!T/v    +8$t**UUU"*===&:# (999$6! +m(3/#
 #
  	7 %~6GG 	/*.G&'$&& 	 	 	 	 	 	 	&#*GWx$ $ $      

 (    \.tt4FF    D%\0H\\V]WZ\\*"0=!       	 	 	 	 	 	 	 	 	 	 	 	 	 	
 !&
( 7;	! ! !      K'	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	4 X&6"VHHW%%+E))E""C %N/"((7++EuE!    )3% %E xx   /!%gg#hhw''A5AM&4:..B2B	 	 	 	 Y!`F]```$,}    XXgr""(b--i88 Dxx	""DC&CCC 	
 &f(=
 
 
 	
sf   I"F('I"(H(7H#:GH#
GH#G/H#H(I"#H(((I""
I,/I,r!   r/   )r!   rN   )r!   r   )r!   r   )r!   rZ   )r   r/   r   r   r   r   rC   rD   rK   rL   r   r/   r   r/   r   r   r   r   r   rL   r   r   r!   rZ   )r   r/   r   r   r   r   rC   rD   rK   rL   r   r/   r   r/   r!   rZ   )__name__
__module____qualname____doc__propertyr   r   r   r   r   r   r   r   r   r   r   r~   rB   r8   r{   r{      s       JJ   X    X   F F F F   
 
 
 


 

 

 

   $#'48"&0,)- $"& & & & & &PU
 U
 U
 U
 U
 U
rB   r{   Nonec                H    |                      t                                 dS )uF   Plugin entry point — wire ``XAIVideoGenProvider`` into the registry.N)register_video_gen_providerr{   )ctxs    r8   registerr     s#    ##$7$9$9:::::rB   )r!   r"   r   )r%   r/   r!   r>   )rC   rD   )rK   rL   rM   rN   r!   rO   )
rW   rX   rY   rZ   r%   r/   r(   r/   r!   r/   )rW   rX   r`   r/   r%   r/   r(   r/   ri   rO   rj   rO   r!   rZ   )r!   r   )*r   
__future__r   ru   loggingr1   rb   typingr   r   r   r   r   r   agent.video_gen_providerr	   r
   r   	getLoggerr   r-   r4   r   rT   r   r   r   r   r   r   r   r    __annotations__r9   r=   rA   rJ   rV   rh   ry   r{   r   r~   rB   r8   <module>r      s.    ( # " " " " "   				  3 3 3 3 3 3 3 3 3 3 3 3 3 3           
	8	$	$ - $     ! III V$   'd4w' &        0( ( ( (            .B B B BJm
 m
 m
 m
 m
* m
 m
 m
j; ; ; ; ; ;rB   