
    jO                    N   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ZddlmZmZmZmZmZmZ  ej        e          ZdZddd	d
dddddddddZded<   dZddddZdZh dZdZdZdZ dZ! e"h d           Z#h d!Z$d/d$Z%d0d&Z&d1d*Z' G d+ d,e          Z(d2d.Z)dS )3u  Krea image generation backend.

Exposes Krea's `Krea 2` foundation image model family — Krea 2 Medium and
Krea 2 Large — as an :class:`ImageGenProvider` implementation.

Krea's API is asynchronous: the generate endpoint returns a ``job_id``
that you poll at ``GET /jobs/{job_id}``. This provider hides that
roundtrip behind the synchronous ``generate()`` contract: submit, poll
every 2s with light backoff, materialise the result URL to local cache,
return the success/error dict like every other backend.

Selection precedence (first hit wins):

1. ``KREA_IMAGE_MODEL`` env var (escape hatch for scripts / tests)
2. ``image_gen.krea.model`` in ``config.yaml``
3. ``image_gen.model`` in ``config.yaml`` (when it's one of our IDs)
4. :data:`DEFAULT_MODEL` — ``krea-2-medium`` (Krea's "start here" recommendation)

Docs: https://docs.krea.ai/developers/krea-2/overview
API:  https://docs.krea.ai/api-reference/krea/krea-2-large
    )annotationsN)AnyDictListOptionalTuple)DEFAULT_ASPECT_RATIOImageGenProvidererror_responseresolve_aspect_ratiosave_url_imagesuccess_responsezhttps://api.krea.aizKrea 2 Mediumz~15-25szCIllustration, anime, painting, expressive styles. Faster + cheaper.z9$0.030 (text) / $0.035 (style refs) / $0.040 (moodboards)medium)displayspeed	strengthspricepathzKrea 2 Largez~25-60szIPhotorealism, raw textured looks (motion blur, grain), expressive styles.z9$0.060 (text) / $0.065 (style refs) / $0.070 (moodboards)large)krea-2-mediumzkrea-2-largezDict[str, Dict[str, Any]]_MODELSr   z16:91:1z9:16)	landscapesquareportrait1K>   lowrawhighr   g       @g      @g?g     f@>                   >   failed	cancelled	completedreturnDict[str, Any]c                    	 ddl m}   |             }t          |t                    r|                    d          nd}t          |t                    r|ni S # t
          $ r'}t                              d|           i cY d}~S d}~ww xY w)zMRead ``image_gen.krea`` (with fallthrough to ``image_gen``) from config.yaml.r   )load_config	image_genNz#Could not load image_gen config: %s)hermes_cli.configr.   
isinstancedictget	Exceptionloggerdebug)r.   cfgsectionexcs       >/usr/local/lib/hermes-agent/plugins/image_gen/krea/__init__.py_load_krea_configr;   i   s    111111kmm*4S$*?*?I#''+&&&T$Wd33;ww;   :C@@@						s   AA 
B!B=BBTuple[str, Dict[str, Any]]c                 h   t           j                            d          } | r| t          v r| t          |          fS t	                      }t          |                    d          t                    r|                    d          ni }d}t          |t                    r5|                    d          }t          |t                    r|t          v r|}|5|                    d          }t          |t                    r|t          v r|}||t          |         fS t          t          t                   fS )z:Decide which model to use and return ``(model_id, meta)``.KREA_IMAGE_MODELkreaNmodel)	osenvironr3   r   r;   r1   r2   strDEFAULT_MODEL)env_overrider7   krea_cfg	candidatevaluetops         r:   _resolve_modelrJ   v   s   :>>"455L 3//W\222


C",SWWV__d"C"CKswwvH#I(D!! W%%eS!! 	ew&6&6Igggc3 	C7NNI'),,,'-000    rH   Optional[str]rC   c                T   t          | t                    r1|                                                                 }|t          v r|S t                      }t          |                    d          t                    r|                    d          ni }t          |t                    r|                    d          nd}t          |t                    rS|                                                                t          v r&|                                                                S dS )zGCoerce ``creativity`` kwarg to a valid Krea value (default ``medium``).r?   
creativityNr   )r1   rC   striplower_VALID_CREATIVITYr;   r3   r2   )rH   vr7   rF   	cfg_values        r:   _resolve_creativityrT      s    % KKMM!!!!!H


C",SWWV__d"C"CKswwvH.84.H.HR\***dI)S!! )ioo&7&7&=&=&?&?CT&T&T  &&(((8rK   c                  n    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ZdS )KreaImageGenProviderz@Krea ``Krea 2`` foundation image model backend (Medium + Large).r+   rC   c                    dS )Nr?    selfs    r:   namezKreaImageGenProvider.name       vrK   c                    dS )NKrearX   rY   s    r:   display_namez!KreaImageGenProvider.display_name   r\   rK   boolc                Z    t          t          j                            d                    S )NKREA_API_KEY)r`   rA   rB   r3   rY   s    r:   is_availablez!KreaImageGenProvider.is_available   s    BJNN>22333rK   List[Dict[str, Any]]c                H    d t                                           D             S )Nc                T    g | ]%\  }}||d          |d         |d         |d         d&S )r   r   r   r   )idr   r   r   r   rX   ).0model_idmetas      r:   
<listcomp>z4KreaImageGenProvider.list_models.<locals>.<listcomp>   sU     	
 	
 	
 $ 	?g!+.g 	
 	
 	
rK   )r   itemsrY   s    r:   list_modelsz KreaImageGenProvider.list_models   s-    	
 	
 #*--//	
 	
 	
 		
rK   rL   c                    t           S )N)rD   rY   s    r:   default_modelz"KreaImageGenProvider.default_model   s    rK   r,   c                    dddddddgdS )	Nr^   paidu_   Krea 2 foundation model — Medium ($0.03) + Large ($0.06). Strong style transfer + moodboards.rb   zKrea API keyz'https://www.krea.ai/settings/api-tokens)keyprompturl)r[   badgetagenv_varsrX   rY   s    r:   get_setup_schemaz%KreaImageGenProvider.get_setup_schema   s4    t *,D 	
 
 	
rK   rs   aspect_ratiokwargsr   c           	        |pd                                 }t          |          }t                              |d          }|st	          ddd|          S t
          j                            d          }|st	          dd	d|          S t                      \  }}t          |                    d
                    }	||t          |	d}
|                    d          }t          |t                    r||
d<   |                    d          }t          |t                    r|r||
d<   |                    d          }t          |t                    r|r|d d         |
d<   |                    d          }t          |t                    r|r|d d         |
d<   d| ddd}t           d|d          }	 t          j        |||
d          }|                                 n# t          j        $ r8}|j        }||j        nd}	 ||                                ni }t          |                    d          t*                    r)|                    di                               d          n)|                    d          p|                    d          p||j        d d         nt/          |          }n0# t0          $ r# ||j        d d         nt/          |          }Y nw xY wt2                              d||           t	          d | d!| d"d|||#          cY d }~S d }~wt          j        $ r t	          d$d%d|||#          cY S t          j        $ r"}t	          d&| d'd|||#          cY d }~S d }~ww xY w	 |                                }n/# t0          $ r"}t	          d(| d)d|||#          cY d }~S d }~ww xY w|                    d*          }t          |t.                    r|st	          d+d)d|||#          S t           d,| }d| dd-}t:          }t=          j                    t@          z   }d }	 t=          j!        |           tE          |tF          z  tH                    }	 t          j        ||d/          }|                                 n# t          j        $ rx}|j        }||j        nd}t2                              d0||           |tJ          vst=          j                    |k    r t	          d1| d2| d"d|||#          cY d }~S Y d }~d }~wt          j        t          j        f$ r^}t2          &                    d3||           t=          j                    |k    r t	          d4| d5| d%d|||#          cY d }~S Y d }~Yd }~ww xY w	 |                                }nh# t0          $ r[}t2          &                    d6||           t=          j                    |k    rt	          d7| d)d|||#          cY d }~S Y d }~d }~ww xY wt          |t*                    r|                    d8          nd } t          | t.                    r| }| tN          v rnwt          |t*                    r|                    d9          rnLt=          j                    |k    r3t	          d:| d;t          t@                     d<|pd= d>d%d|||#          S t          |t*                    st	          d?d)d|||#          S |d@k    rqt          |                    dA          t*                    r*|                    dA          pi                     d          nd }!t	          d:| dB|!pdC d"d|||#          S |dDk    rt	          d:| dEdDd|||#          S |                    dA          }"t          |"t*                    st	          dFdGd|||#          S d }#|"                    dH          }$t          |$t                    rF|$rD|$D ]A}%t          |%t.                    r*|%                                 r|%                                 }# nB|#R|"                    dI          }&t          |&t.                    r(|&                                 r|&                                 }#|#t	          dJdGd|||#          S 	 tQ          |#dK| L          }'t/          |'          }(n5# t0          $ r(}t2          &                    dM|#|           |#}(Y d }~nd }~ww xY w|t          |	|dN})t          |                    d9          t.                    r|d9         |)d9<   tS          |(|||d|)O          S )PN r   z1Prompt is required and must be a non-empty stringinvalid_argumentr?   )error
error_typeproviderry   rb   u   KREA_API_KEY not set. Run `hermes tools` → Image Generation → Krea to configure, or get a key at https://www.krea.ai/settings/api-tokens.auth_requiredrN   )rs   ry   
resolutionrN   seedstylesimage_style_references
   
moodboards   zBearer zapplication/jsonz!Hermes-Agent/1.0 (krea-image-gen))AuthorizationzContent-Type
User-Agentz/generate/image/krea/krea-2/r      )headersjsontimeoutr   r~   messagedetaili,  zKrea submit failed (%d): %szKrea image generation failed (z): 	api_error)r~   r   r   r@   rs   ry   zKrea submit timed out (30s)r   zKrea connection error: connection_errorz&Krea returned invalid JSON on submit: invalid_responsejob_idz#Krea submit response missing job_idz/jobs/)r   r   T)r   r   z Krea poll failed (%d) for job %szKrea poll failed (z
) for job z(Krea poll transient error for job %s: %szKrea poll timed out for job z: z.Krea poll returned invalid JSON for job %s: %sz!Krea poll returned invalid JSON: statuscompleted_atz	Krea job z did not complete within zs (last status: unknown)zKrea returned non-dict job bodyr(   resultz	 failed: zunknown errorr)   z was cancelledz)Krea job completed but result was missingempty_responseurlsrt   z"Krea result contained no image URLkrea_)prefixzEKrea image URL %s could not be cached (%s); falling back to bare URL.)krea_aspect_ratior   rN   r   )imager@   rs   ry   r   extra)*rO   r   _ASPECT_MAPr3   r   rA   rB   rJ   rT   DEFAULT_RESOLUTIONr1   intlistBASE_URLrequestspostraise_for_status	HTTPErrorresponsestatus_coder   r2   textrC   r4   r5   r~   TimeoutConnectionError_POLL_INITIAL_INTERVALtime	monotonic_POLL_TIMEOUT_SECONDSsleepmin_POLL_BACKOFF_POLL_MAX_INTERVAL_RETRYABLE_POLL_STATUSESwarning_TERMINAL_STATESr   r   )*rZ   rs   ry   rz   aspectkrea_arapi_keyri   rj   rN   payloadr   r   r   r   r   
submit_urlr   r9   respr   bodyerr_msgsubmit_bodyr   job_urlpoll_headersintervaldeadlinelast_status	poll_respjob
status_strerrr   	image_urlr   rG   single
saved_path	image_refr   s*                                             r:   generatezKreaImageGenProvider.generate   sp    ,B%%''%l33//&%00 	!I-#	    *..00 
	!? +#	 	 	 	 ())$(L)A)ABB
 #,$	#
 #
 zz&!!dC   	#"GFOH%%fd## 	' 	' &GH!',D!E!E,d33 	L8N 	L0Fss0KG,-ZZ--
j$'' 	3J 	3$.rrNGL! 1w00.=
 
 !LLd6lLL
.	}	  H %%''''! 	 	 	<D)-)9T%%qFL&*&6tyy{{{B "$((7"3"3T::CDHHWb))--i888),,B0B0BI *.)9dioos3xx	 
  L L L-1-=$)DSD//3s88LLL6HHH!KvKK'KK&#          	 	 	!3$#      ' 	 	 	!555-#        	
	"--//KK 	 	 	!DsDD-#        	 **&#&& 	f 	!;-#    --V--0w00=
 
 *>##&;;%)O	Jx   8m35GHHH"$L,PRSSS	**,,,,%   |-1-=))1?PPP
 !999T^=M=MQY=Y=Y)M6MMVMM#.!'&%%+         $h&>?   I6SVWWW>##x//)LVLLsLL#,!'&%%+         nn&&   OQWY\]]]>##x//)G#GG#5!'&%%+          /9d.C.CM***J*c** (!111 #t$$ )@)@ ~8++%cF c c455c cGRG_V_c c c  )#"!!'
 
 
 
KO	d #t$$ 	!7-#    (""<FswwxGXGXZ^<_<_i3778$$*//888eiC!K&KK33I/KK&#    +%%!8&888&#    ""&$'' 	!A+#    $(	zz&!!dD!! 	d 	!  	i-- )//2C2C  ) 1 1IEZZ&&F&#&& +6<<>> +"LLNN	!:+#   
	('	:L(:L:LMMMJ JII  	" 	" 	"NNW  
 "IIIIII	" "),$	!
 !
 cggn--s33 	8$'$7E.!
 
 
 	
s   7,G% %N5L(B3J<;L(<*K)&L((K))9L("N('NNM<6N<NN 
O$O;OO5+R" "V 1A(T$V $V AVV V $V9 9
XA
XXXc& &
d0ddN)r+   rC   )r+   r`   )r+   rd   )r+   rL   r+   r,   )rs   rC   ry   rC   rz   r   r+   r,   )__name__
__module____qualname____doc__propertyr[   r_   rc   rm   ro   rx   r	   r   rX   rK   r:   rV   rV      s        JJ   X    X4 4 4 4

 

 

 

   
 
 
 
* 1J
 J
 J
 J
 J
 J
 J
rK   rV   Nonec                H    |                      t                                 dS )uG   Plugin entry point — wire ``KreaImageGenProvider`` into the registry.N)register_image_gen_providerrV   )ctxs    r:   registerr   "  s#    ##$8$:$:;;;;;rK   r   )r+   r<   )rH   rL   r+   rC   )r+   r   )*r   
__future__r   loggingrA   r   typingr   r   r   r   r   r   agent.image_gen_providerr	   r
   r   r   r   r   	getLoggerr   r5   r   r   __annotations__rD   r   r   rQ   r   r   r   r   	frozensetr   r   r;   rJ   rT   rV   r   rX   rK   r:   <module>r      s7    , # " " " " "  				  3 3 3 3 3 3 3 3 3 3 3 3 3 3                 
	8	$	$ !
 #ZL  "`L & &    "  
     544 
     %9%M%M%MNN 777 
 
 
 
1 1 1 10   &y
 y
 y
 y
 y
+ y
 y
 y
B< < < < < <rK   