
    `gjE                    H   U d Z ddlm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mZmZmZmZmZ ddlmZmZmZmZmZmZ  ej<                  e      Z dd	d
ddddddZ!de"d<   dZ#ddddddddZ$ddhZ%dZ&d$dZ'd%dZ(d&dZ)d'd Z* G d! d"e      Z+d(d#Z,y))a  xAI image generation backend.

Exposes xAI's ``grok-imagine-image`` model as an
:class:`ImageGenProvider` implementation.

Features:
- Text-to-image generation
- Multiple aspect ratios (1:1, 16:9, 9:16, etc.)
- Multiple resolutions (1K, 2K)
- Base64 output saved to cache

Selection precedence (first hit wins):
1. ``XAI_IMAGE_MODEL`` env var
2. ``image_gen.xai.model`` in ``config.yaml``
3. :data:`DEFAULT_MODEL`
    )annotationsN)Path)AnyDictListOptionalTuple)DEFAULT_ASPECT_RATIOImageGenProvidererror_responsenormalize_reference_imagesresolve_aspect_ratiosave_b64_imagesave_url_imagesuccess_response)build_xai_storage_optionshermes_xai_user_agent"maybe_mark_xai_storage_notice_seenread_xai_imagine_storage_configresolve_xai_http_credentialsxai_storage_notice_textzGrok Imagine Imagez~5-10szFast, high-quality)displayspeed	strengthszGrok Imagine Image (Quality)z~10-20sz9Higher fidelity / detail; slower than the standard model.)grok-imagine-imagegrok-imagine-image-qualityzDict[str, Dict[str, Any]]_MODELSr   z16:91:1z9:164:33:43:22:3)	landscapesquareportraitr   r    r!   r"   1k2kc                 .   	 ddl m}   |        }t        |t              r|j	                  d      nd}t        |t              r|j	                  d      nd}t        |t              r|S i S # t
        $ r"}t        j                  d|       i cY d}~S d}~ww xY w)z(Read ``image_gen.xai`` from config.yaml.r   )load_config	image_genNxaiz'Could not load image_gen.xai config: %s)hermes_cli.configr)   
isinstancedictget	Exceptionloggerdebug)r)   cfgsectionxai_sectionexcs        Q/root/.hermes/venv/lib/python3.12/site-packages/plugins/image_gen/xai/__init__.py_load_xai_configr8   Y   s{    	1m*4S$*?#''+&T,6w,Egkk%(4(d;{CC >D	s$   A$A) 'A) )	B2B	BBc                 2   t         j                  j                  d      } | r| t        v r| t        |    fS t	               }t        |j                  d      t              r|j                  d      nd}|r|t        v r|t        |   fS t        t        t           fS )z:Decide which model to use and return ``(model_id, meta)``.XAI_IMAGE_MODELmodelN)osenvironr/   r   r8   r-   strDEFAULT_MODEL)env_overrider3   	candidates      r7   _resolve_modelrB   g   s    ::>>"34L/W\222

C$.swww/?$E 4IY')'),,,'-000    c                     t               } t        | j                  d      t              r| j                  d      nd}|r
|t        v r|S t
        S )zGet configured resolution.
resolutionN)r8   r-   r/   r>   _XAI_RESOLUTIONSDEFAULT_RESOLUTION)r3   ress     r7   _resolve_resolutionrI   u   sB    

C#-cggl.CS#I#'',
tC
s&&
rC   c                   | j                         } | j                         }|j                  d      r| ddS ddl}ddl}ddlm}  ||        t        |j                  j                  |       d      5 }|j                         }ddd       |j                  j                  |       d   j                  d	      xs d
j                         }|dk(  rd}|j                        j                  d      }d| d| ddS # 1 sw Y   zxY w)zBuild the xAI ``image`` field for an edit request.

    xAI's ``/v1/images/edits`` accepts a public HTTPS URL or a base64 data URI.
    Local file paths are read and encoded into a ``data:`` URI.
    zhttp://zhttps://zdata:	image_url)urltyper   N)raise_if_read_blockedrb   .pngjpgjpegzutf-8zdata:image/z;base64,)striplower
startswithbase64r<   agent.file_safetyrO   openpath
expanduserreadsplitextlstrip	b64encodedecode)	sourcerW   rY   _osrO   fhrawextb64s	            r7   _xai_image_fieldri   ~   s     \\^FLLNE89{33 8&!	chh!!&)4	0 Bggi88V$Q'..s3<u
C
C
EC
e|


3

&
&w
/C XcU3[II s   2C<<D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
efddd		 	 	 	 	 	 	 	 	 	 	 dd
Zy)XAIImageGenProviderz#xAI ``grok-imagine-image`` backend.c                     y)Nr+    selfs    r7   namezXAIImageGenProvider.name   s    rC   c                     y)Nz
xAI (Grok)rm   rn   s    r7   display_namez XAIImageGenProvider.display_name   s    rC   c                J    t               }t        |j                  d            S )Napi_key)r   boolr/   )ro   credss     r7   is_availablez XAIImageGenProvider.is_available   s    ,.EIIi())rC   c                    t         j                         D cg c]<  \  }}||j                  d|      |j                  dd      |j                  dd      d> c}}S c c}}w )Nr   r    r   )idr   r   r   )r   itemsr/   )ro   model_idmetas      r7   list_modelszXAIImageGenProvider.list_models   s_     #*--/
 $ 88Ix8'2.!XXk26	
 	
 
s   AAc                @    t        d      }d}|r|d| z  }dd|g ddS )Nr*   zVgrok-imagine-image - text-to-image & image editing; uses xAI Grok OAuth or XAI_API_KEYz. zxAI Grok Imagine (image)paidxai_grok)rp   badgetagenv_vars
post_setup)r   )ro   storage_noticer   s      r7   get_setup_schemaz$XAIImageGenProvider.get_setup_schema   sH    
 1=( 	 R'((C.$
 	
rC   c                    ddgdddS )Ntextimage      )
modalitiesmax_reference_imagesmax_source_imagesrm   rn   s    r7   capabilitiesz XAIImageGenProvider.capabilities   s     "7+$%!"
 	
rC   N)rL   reference_image_urlsc          	     ^   t               }t        |j                  d      xs d      j                         }t        |j                  d      xs d      j                         xs d}|st	        dd||      S t               \  }	}
t        |      }t        j                  |d      }t               }|t        v r|nt        }g }t        |t              r/|j                         r|j                  |j                                t        |      }|r|j                  |       t        |      d	kD  rt	        d
d|d||      S t!        |      D ]  \  }}|dk(  r|r|j                         |k(  rdnd}|j#                         }|j%                  d      rFt'        |      j)                         }|j+                         rpt	        | dd|d||      c S  t-        |      }|rdnd}d| dt/               d}t        |j                  d      xs d      j                         j1                  d      }t3        ddd      }t5        d      }t7        d      }|rDd}	 |D cg c]  }t9        |       }}||d#} t        |      d$k(  r	|d   | d<   n|| d%<   | d&}!|}	n|	|||d'} | d(}!||| d)<   	 t=        j>                  |!|| d*+      }"|"jA                          	 |"jI                         }%|%j                  d9g       }&|&st	        d:d;||	||      S |&d   }'|'j                  d<      }(|'j                  d=      })t        |'tT              r|'j                  d>      nd"}*t        |*tT              r|*ni }*t        |*j                  d?      t              r|*j                  d?      nd"}+|+r|+},nO|(r	 tW        |(d@|	 A      }-t        |-      },n0|)r	 tY        |)d@|	 A      }-t        |-      },nt	        dDd;d|	||      S dEt-        |dF         i}.|s||.dG<   |r||.dH<   |+r|+|.d?<   |*rdID ]  }/|/|*v s|*|/   |.|/<    |%j                  dJ      r|%dJ   |.dJ<   t]        |,|	||d||.K      S c c}w # t:        $ r}t	        d | d!||||      cY d"}~S d"}~ww xY w# t<        jB                  $ r}|jD                  }"|"|"jF                  nd}#	 |"jI                         j                  d,i       j                  d-|"jJ                  d"d.       }$n+# t:        $ r |"|"jJ                  d"d. n
t        |      }$Y nw xY wtL        jO                  d/|#|$       t	        d0|# d1|$ d2||	||      cY d"}~S d"}~wt<        jP                  $ r t	        d3d4||	||      cY S t<        jR                  $ r}t	        d5| d6||	||      cY d"}~S d"}~ww xY w# t:        $ r}t	        d7| d8||	||      cY d"}~S d"}~ww xY w# t:        $ r}t	        dB| d!d|	||      cY d"}~S d"}~ww xY w# t:        $ r$}tL        j[                  dC|)|       |)},Y d"}~9d"}~ww xY w)La  Generate an image (text-to-image) or edit a source image (image-to-image).

        Routing: when ``image_url`` is provided, POST to ``/v1/images/edits``
        with the source image; otherwise POST to ``/v1/images/generations``.
        Per xAI docs, editing uses the ``grok-imagine-image-quality`` model and
        a JSON body (the OpenAI SDK's multipart ``images.edit()`` is NOT
        supported by xAI).
        rt   ry   providerr+   zSNo xAI credentials found. Configure xAI OAuth in `hermes model` or set XAI_API_KEY.missing_api_key)error
error_typer   aspect_ratior   r   z2xAI image editing supports at most 3 source imagestoo_many_referencesr   )r   r   r   r;   promptr   r   rL   r   rK   zc must be a public HTTPS URL or data URI (e.g. the `image`/`public_url` from a prior Imagine result)invalid_image_urlr   r   zBearer zapplication/json)AuthorizationzContent-Typez
User-Agentbase_urlzhttps://api.x.ai/v1/r*   zhermes-xai-imagerS   )filename_prefix	extensionz)Could not load source image for editing: io_errorN)r;   r   rQ   imagesz/images/edits)r;   r   r   rE   z/images/generationsstorage_optionsx   )headersjsontimeoutr   messagei,  zxAI image gen failed (%d): %szxAI image generation failed (z): 	api_errorz%xAI image generation timed out (120s)r   zxAI connection error: connection_errorzxAI returned invalid JSON: invalid_responsedatazxAI returned no image dataempty_responseb64_jsonrM   file_output
public_urlxai_)prefixzCould not save image to cache: zDxAI image URL %s could not be cached (%s); falling back to bare URL.z/xAI response contained neither b64_json nor URLstorage_enabledenabledrE   r   )filename
expires_atpublic_url_expires_atpublic_url_errorstorage_errorusage)r   r;   r   r   r   modalityextra)/r   r>   r/   rV   r   rB   r   _XAI_ASPECT_RATIOSrI   rF   rG   r-   appendr   extendlen	enumeraterW   rX   r   r]   is_fileru   r   rstripr   r   r   ri   r0   requestspostraise_for_status	HTTPErrorresponsestatus_coder   r   r1   r   TimeoutConnectionErrorr.   r   r   warningr   )0ro   r   r   rL   r   kwargsrv   rt   provider_namer|   r}   aspectxai_arrE   xai_ressource_imagesrefsindexrc   fieldrW   r\   is_editr   r   r   r   r   storage_cfg
edit_modelimage_fieldsr6   payloadendpoint_urlr   statuserr_msgresultr   firstrh   rM   r   r   	image_ref
saved_pathr   keys0                                                   r7   generatezXAIImageGenProvider.generate   s	   " -.eii	*0b1779EIIj1:U;AACLu!k,&)	  ()$%l3#''6(*
 *.> >*DV#%i%)//*;  !23)*>?  &}!!J0&2#  '}5 	ME6#(A:)	@QU[@[KawELLNE##$DEF|..0||~)$g &Z Z $7!.:%%+
 
	" }%%76  'wi0./1
 uyy,E0EFLLNUUVYZ3.

 <KH5kB 6J
GTUV 0 8UU $ 'G < A%#/? $0!&Z}5L!H "  &%	G 'Z':;L&)8G%&)	}}	H %%'H
	]]_F zz&"%!2+&#  Qii
#ii2<UD2Ieii.t%/T%Bk6@Q]A^`c6d[__\2jn
"I
+C$xj8IJ
 JI
,+C$xj8IJ
  
O	!G+#  tK	$:;!
 ")E,&4E"#",E, 2 +%!,S!1E#J2 ::g#G_E'N
 	
Y  V %EcUK)*$!!' L !! 	||H-5-AX))qFT"--/--gr:>>y(--X\Y\J]^ T191E(---3s8TLL8&'J!5fXS	J&&#   	!=$&#  '' 	!.se4-&# 	  	!3C59-&# 	F  %;C5A)""!!' (   Z
  	 s   Q Q,Q +)R V+ "W W? Q 	R "Q;5R ;R V(U3=S10U1%TUT0U	V('V(8V(
V#V(#V(+	W4WWW	W<W71W<7W<?	X,X''X,returnr>   )r   ru   )r   zList[Dict[str, Any]]r   Dict[str, Any])r   r>   r   r>   rL   zOptional[str]r   zOptional[List[str]]r   r   r   r   )__name__
__module____qualname____doc__propertyrp   rr   rw   r~   r   r   r
   r   rm   rC   r7   rk   rk      s    -   *	

(
 1N

 $(48N
N
 N

 !N
 2N
 N
 
N
rC   rk   c                6    | j                  t                      y)z3Register this provider with the image gen registry.N)register_image_gen_providerrk   )ctxs    r7   registerr     s    ##$7$9:rC   r   )r   zTuple[str, Dict[str, Any]]r   )rc   r>   r   zDict[str, str])r   r   r   None)-r   
__future__r   loggingr<   pathlibr   typingr   r   r   r   r	   r   agent.image_gen_providerr
   r   r   r   r   r   r   r   tools.xai_httpr   r   r   r   r   r   	getLoggerr   r1   r   __annotations__r?   r   rF   rG   r8   rB   rI   ri   rk   r   rm   rC   r7   <module>r      s   " #  	  3 3 	 	 	  
		8	$ () 2P#&	"  %   $<  1JBE
* E
Z
;rC   