
    jh j`C                       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ZddlZddl	m
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e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gddddddgdgddZ%de&d <   dGd#Z'dHd%Z(dId(Z)dJd*Z*dKd-Z+dLd3Z,dMd8Z-dNd>Z.dOdBZ/ G dC dDe          Z0dPdFZ1dS )Qui  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 or X Premium+ 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)Path)AnyDictListOptionalTuple)VideoGenProvidererror_responsesuccess_responsezhttps://api.x.ai/v1grok-imagine-videogrok-imagine-video-1.5-preview   16:9720p      >   1:12:33:23:44:39:16r   480p   zGrok Imagine Videoz~60-240sz.Text-to-video; legacy image-to-video fallback.z:see https://docs.x.ai/developers/models/grok-imagine-videotextimage)displayspeed	strengthsprice
modalitieszGrok Imagine Video 1.5 Previewz Latest xAI image-to-video model.zFsee https://docs.x.ai/developers/models/grok-imagine-video-1.5-previewz!grok-imagine-video-1.5-2026-05-30)r   r   r    r!   r"   aliases)r   r   z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        C/home/ubuntu/.hermes/hermes-agent/plugins/video_gen/xai/__init__.py_resolve_xai_credentialsr=   V   s   ??????,,..4"   93??? %))I&&F")M2*F*FGGMMOOG		* 	 9^$$	   eggffSkk	 
 Hs    
AAAr3   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@   r0   r?   s    r<   _xai_user_agentrA   n   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)rA   )r)   s    r<   _xai_headersrE   w   s(    ,7,,*%''      valuec                   | pd                                 }|sdS |                                }|                    d          r|S t          |                                          }|                                s|S t          j        |j                  d         pd}|                    d          s|S t          j
        |                                                              d          }d| d| S )	z7Return a URL/data URI accepted by xAI for image inputs.r+   )zhttp://zhttps://zdata:image/r   zapplication/octet-streamzimage/asciizdata:z;base64,)r7   lower
startswithr   
expanduseris_file	mimetypes
guess_typenamebase64	b64encode
read_bytesdecode)rG   refrJ   pathmimeencodeds         r<   _image_ref_to_xai_urlrY      s    ;B



C rIIKKE>?? 
99!!D<<>> 
	**1-K1KD??8$$ 
t001188AAG*4*****rF   reference_image_urlsOptional[List[str]]c                l    g }| pg D ]*}t          |          }|r|                    d|i           +|pd S )Nurl)rY   append)rZ   refsr]   
normalizeds       r<   _normalize_reference_imagesra      sR    D#)r - -*3//
 	-KK
+,,,<4rF   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)rb   rd   rG   s      r<   _clamp_durationrl      sG     ,HH2BEqyyrzz 

LrF   modelOptional[str]modalityexplicit_modelc                   | pd                                 }|r|r|S |dk    rt          S |t          k    rt          S |pt          S )a3  Select xAI's text/video model without treating config as a prompt override.

    ``grok-imagine-video-1.5-preview`` currently rejects text-only video
    generation, but it is the desired image-to-video backend. Explicit tool
    ``model=`` still wins for users who intentionally request another model.
    r+   r   )r7   DEFAULT_IMAGE_TO_VIDEO_MODELDEFAULT_TEXT_TO_VIDEO_MODEL)rm   ro   rp   	requesteds       r<   _resolve_model_for_modalityru      s]     "##%%I ) 7++000**333rF   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)	postrE   r3   uuiduuid4raise_for_statusr}   r4   RuntimeError)rv   rx   r)   r,   responsebodyr   s          r<   _submitr      s       [[(((Q<((Q*=s4:<<?P?PQQ	 !        H ==??D,''J LJKKKrF   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)r   r   >   errorfailedexpired	cancelledr~   )r4   rE   r   r}   rJ   asynciosleep)
rv   r   r)   r,   r   r   elapsedlast_statusr   r   s
             r<   _pollr      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ArF   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%   r3   c                    dS )Nxai selfs    r<   rP   zXAIVideoGenProvider.name       urF   c                    dS )NxAIr   r   s    r<   display_namez XAIVideoGenProvider.display_name  r   rF   re   c                B    t                      \  }}t          |          S N)r=   re   )r   r)   _s      r<   is_availablez XAIVideoGenProvider.is_available  s    -//
G}}rF   List[Dict[str, Any]]c                H    d t                                           D             S )Nc                     g | ]\  }}d |i|S )idr   ).0midmetas      r<   
<listcomp>z3XAIVideoGenProvider.list_models.<locals>.<listcomp>
  s&    EEE	Ts#d#EEErF   )r$   itemsr   s    r<   list_modelszXAIVideoGenProvider.list_models	  s    EEW]]__EEEErF   rn   c                    t           S r   )DEFAULT_MODELr   s    r<   default_modelz!XAIVideoGenProvider.default_model  s    rF   ry   c                    dddg ddS )NzxAI Grok Imaginepaidz{grok-imagine-video for text-to-video; grok-imagine-video-1.5-preview for image-to-video; uses xAI Grok OAuth or XAI_API_KEYxai_grok)rP   badgetagenv_vars
post_setupr   r   s    r<   get_setup_schemaz$XAIVideoGenProvider.get_setup_schema  s%     ' Q$
 
 	
rF   c           	     n    ddgt          t                    t          t                    ddddt          dS )Nr   r   ri   rh   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    r<   capabilitiesz XAIVideoGenProvider.capabilities  s@    !7+#$788!"344#(-$8	
 	
 		
rF   N)	rm   	image_urlrZ   rb   aspect_ratio
resolutionnegative_promptaudioseedpromptrm   r   rZ   r[   rb   rc   r   r   r   r   Optional[bool]r   kwargsr   c       	           	 t          j                    }	 |                    |                     ||t	          |                    d                    |||||                    |                                 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_model_override_explicit)r   rm   rp   r   rZ   rb   r   r   z$xAI video gen unexpected failure: %sT)exc_infozxAI video generation failed: 	api_errorr   )r   
error_typeproviderrm   r   r   )r   new_event_looprun_until_complete_generate_asyncre   r4   closer0   r1   warningr   r   )r   r   rm   r   rZ   rb   r   r   r   r   r   r   loopr;   s                 r<   generatezXAIVideoGenProvider.generate*  s   	)++D..t/C/C!#'

3M(N(N#O#O')=%!-) 0D 	0 	0 	 	 



 		 		 		NNA3QUNVVV!;c;;&,})        		s5   B AA: %B :BB 
C#;CC#C#rp   c          
       K   t                      \  }	}
|	st          ddd|          S |pd                                }t          |pd          pd }|pt                                          }|pt
                                                                          }|rdnd}t          |||          }|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
          }|||||d}|rd|i|d<   |r||d<   t          j                    4 d {V }	 t#          |||	|
           d {V }n|# t          j        $ rj}d}	 |j        j        d d         }n# t*          $ r Y nw xY wt          d|j        j         d|p| dd||          cY d }~cd d d           d {V  S d }~ww xY wt/          |||	|
t0          t2                     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          }|s)t          dd d|                    d!          p||          S ||d"}|                    d#          r|d#         |d#<   t7          ||                    d!          p|||||                    d$          p|d|%          S |d&k    rt          d't0           d(d&d||          S |                    d)i           pi                     d*          p|                    d*          pd+| d,}t          |d-| d||          S ).NzNo xAI credentials found. Sign in via `hermes auth add xai-oauth` (SuperGrok / Premium+) or set XAI_API_KEY from https://console.x.ai/.auth_requiredr   )r   r   r   r   r+   r   r   )ro   rp   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)rd   )rm   r   rb   r   r   r]   reference_images)r)   r,   i  zxAI submit failed (z): r   )r   r   r   rm   r   )r)   r,   r   r   r   r   r   videoz2xAI video generation completed without a video URLempty_responserm   )r   r   usagerb   )r   rm   r   ro   r   rb   r   extrar~   z-Timed out waiting for video generation after sr   messagez(xAI video generation ended with status ''xai_)r=   r   r7   rY   DEFAULT_ASPECT_RATIODEFAULT_RESOLUTIONrJ   ru   ra   lenr   rl   re   r   r   httpxAsyncClientr   HTTPStatusErrorr   r   r0   status_coder   DEFAULT_TIMEOUT_SECONDSDEFAULT_POLL_INTERVAL_SECONDSr4   r   )r   r   rm   rp   r   rZ   rb   r   r   r)   r,   image_url_normnormalized_aspect_rationormalized_resolutionmodality_usedresolved_modelr_   clamped_durationrx   rv   r   r;   detailpoll_resultr   r   r   r]   r   r   s                                 r<   r   z#XAIVideoGenProvider._generate_asyncS  s+      566 		!- +v    ,B%%''.yB??G4#/#G3G"N"N"P"P!+!A/A H H J J P P R R#1=v4")
 
 
  	!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! $(3/#
 #
  	7 %~6GG 	/*.G&'$&& 	 	 	 	 	 	 	&#*GWx$ $ $      

 (    \.tt4FF    D%\0H\\V]WZ\\*"(!       	 	 	 	 	 	 	 	 	 	 	 	 	 	
 !&
( 7;	! ! !      K'	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	4 X&6"VHHW%%+E))E""C %N/"((7++=~!    )3% %E xx   /!%gg#hhw''9>&4:..B2B	 	 	 	 Y!`F]```$$    XXgr""(b--i88 Dxx	""DC&CCC 	
 &f 
 
 
 	
sf   I!F.-I!.H'=H" GH"
G"H"!G""(H"
H'I!"H''(I!!
I+.I+r%   r3   )r%   re   )r%   r   )r%   rn   )r%   ry   )r   r3   rm   rn   r   rn   rZ   r[   rb   rc   r   r3   r   r3   r   rn   r   r   r   rc   r   r   r%   ry   )r   r3   rm   rn   rp   re   r   rn   rZ   r[   rb   rc   r   r3   r   r3   r%   ry   )__name__
__module____qualname____doc__propertyrP   r   r   r   r   r   r   r   r   r   r   r   rF   r<   r   r      s       JJ   X    X   F F F F   
 
 
 


 

 

 

   $#'48"&0,)- $"' ' ' ' ' 'R[
 [
 [
 [
 [
 [
rF   r   Nonec                H    |                      t                                 dS )uF   Plugin entry point — wire ``XAIVideoGenProvider`` into the registry.N)register_video_gen_providerr   )ctxs    r<   registerr    s#    ##$7$9$9:::::rF   )r%   r&   r   )r)   r3   r%   rB   )rG   r3   r%   r3   )rZ   r[   )rb   rc   rd   re   r%   rf   )rm   rn   ro   r3   rp   re   r%   r3   )
rv   rw   rx   ry   r)   r3   r,   r3   r%   r3   )rv   rw   r   r3   r)   r3   r,   r3   r   rf   r   rf   r%   ry   )r%   r  )2r  
__future__r   r   rQ   loggingrN   r5   r   pathlibr   typingr   r   r   r   r	   r   agent.video_gen_providerr
   r   r   	getLoggerr   r1   r8   rs   rr   r   rk   r   r   r   r   r   r   r   r$   __annotations__r=   rA   rE   rY   ra   rl   ru   r   r   r   r  r   rF   r<   <module>r     s    ( # " " " " "        				        3 3 3 3 3 3 3 3 3 3 3 3 3 3           
	8	$	$ - 2 ? +     ! III V$  
 (EMw'  47Yi78' '& &    0   0( ( ( (   + + + +*      4 4 4 4,   .B B B BJt
 t
 t
 t
 t
* t
 t
 t
x; ; ; ; ; ;rF   