
    (Gj\t                    |   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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ddddddZded<   dZddddZdZd Zh d!Z d"Z!d#Z"d$Z#d%Z$ e%h d&          Z&h d'Z'd9d*Z(d:d;d.Z)d/ Z*d<d1Z+d=d4Z, G d5 d6e          Z-d>d8Z.dS )?u  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normalize_reference_images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)largezKrea 2 Medium Turboz~8-15su:   Fastest Krea 2 — medium quality at lower latency / cost.z$$0.015 (text) / $0.0175 (style refs)zmedium-turbo)krea-2-mediumzkrea-2-largezkrea-2-medium-turbozDict[str, Dict[str, Any]]_MODELSr   z16:91:1z9:16)	landscapesquareportrait1Kg333333?>   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       E/home/rurouni/.hermes/hermes-agent/plugins/image_gen/krea/__init__.py_load_krea_configr<   w   s    111111kmm*4S$*?*?I#''+&&&T$Wd33;ww;   :C@@@						s   AA 
B!B=BBexplicitOptional[str]Tuple[str, Dict[str, Any]]c                .   t          | t                    rN|                                 t          v r3|                                 t          |                                          fS 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 )u  Decide which model to use and return ``(model_id, meta)``.

    Precedence: explicit caller override (e.g. managed-mode routing or a direct
    ``model`` kwarg) → ``KREA_IMAGE_MODEL`` env → ``image_gen.krea.model`` →
    ``image_gen.model`` → :data:`DEFAULT_MODEL`.
    KREA_IMAGE_MODELkreaNmodel)
r2   strstripr   osenvironr4   r<   r3   DEFAULT_MODEL)r=   env_overrider8   krea_cfg	candidatevaluetops          r;   _resolve_modelrN      s`    (C   ;X^^%5%5%@%@~~)9)9!::::>>"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    c                 Z   	 ddl m}  ddlm} n3# t          $ r&}t
                              d|           Y d}~dS d}~ww xY wt          j        	                    d          r |d          sdS 	  | d          S # t          $ r&}t
                              d	|           Y d}~dS d}~ww xY w)
u  Return managed Krea gateway config when the user is on the managed path.

    Mirrors ``_resolve_managed_fal_gateway`` in ``tools/image_generation_tool.py``:
    the Nous-hosted Krea gateway wins when it is resolvable AND either no direct
    ``KREA_API_KEY`` is configured or the user explicitly opted into the gateway
    for ``image_gen``. Returns ``None`` (direct/BYO path) otherwise, and never
    raises — plugin discovery and availability scans must stay robust.
    r   )resolve_managed_tool_gateway)prefers_gatewayz/Managed Krea gateway resolution unavailable: %sNKREA_API_KEYr0   rB   z*Managed Krea gateway resolution failed: %s)
tools.managed_tool_gatewayrQ   tools.tool_backend_helpersrR   r5   r6   r7   rF   rG   r4   )rQ   rR   r:   s      r;   _resolve_managed_krea_gatewayrV      s    KKKKKK>>>>>>>   FLLLttttt 
z~~n%% ook.J.J t++F333   A3GGGttttts(    
?:?/
A: :
B*B%%B*boolc                     	 ddl m}  n# t          $ r Y dS w xY w	 t           | d                    S # t          $ r Y dS w xY w)z<Cheap, offline-friendly probe for managed Krea availability.r   is_managed_tool_gateway_readyFrB   )rT   rZ   r5   rW   rY   s    r;   _managed_krea_gateway_readyr[      s    LLLLLLL   uu11&99:::   uus   	 
3 
A ArL   rD   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``).rB   
creativityNr   )r2   rD   rE   lower_VALID_CREATIVITYr<   r4   r3   )rL   vr8   rJ   	cfg_values        r;   _resolve_creativityrb      s    % KKMM!!!!!H


C",SWWV__d"C"CKswwvH.84.H.HR\***dI)S!! )ioo&7&7&=&=&?&?CT&T&T  &&(((8rO   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efdddddZdS )KreaImageGenProviderz@Krea ``Krea 2`` foundation image model backend (Medium + Large).r,   rD   c                    dS )NrB    selfs    r;   namezKreaImageGenProvider.name       vrO   c                    dS )NKrearf   rg   s    r;   display_namez!KreaImageGenProvider.display_name   rj   rO   rW   c                v    t          t          j                            d                    pt	                      S )NrS   )rW   rF   rG   r4   r[   rg   s    r;   is_availablez!KreaImageGenProvider.is_available   s,     BJNN>2233T7R7T7TTrO   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   rf   ).0model_idmetas      r;   
<listcomp>z4KreaImageGenProvider.list_models.<locals>.<listcomp>   sU     	
 	
 	
 $ 	?g!+.g 	
 	
 	
rO   )r   itemsrg   s    r;   list_modelsz KreaImageGenProvider.list_models   s-    	
 	
 #*--//	
 	
 	
 		
rO   r>   c                    t           S N)rH   rg   s    r;   default_modelz"KreaImageGenProvider.default_model   s    rO   r-   c                    dddddddgdS )	Nrl   paidu   Krea 2 foundation model — Medium ($0.03), Large ($0.06), Medium Turbo ($0.015). Style transfer, moodboards, reference-guided generation. Direct key or managed Nous Subscription gateway.rS   zKrea API keyz'https://www.krea.ai/settings/api-tokens)keyprompturl)ri   badgetagenv_varsrf   rg   s    r;   get_setup_schemaz%KreaImageGenProvider.get_setup_schema   s7     Q *,D 	
 
 	
rO   c                    ddgddS )Ntextimage
   )
modalitiesmax_reference_imagesrf   rg   s    r;   capabilitiesz!KreaImageGenProvider.capabilities  s      &w/LLLrO   N)	image_urlreference_image_urlsr   aspect_ratior   r   Optional[List[str]]kwargsr   c                  |pd                                 }t          |          }t                              |d          }g }t	          |t
                    r;|                                 r'|                    |                                            t          |          pg D ]}	|                    |	           |                    d          }
t	          |
t                    rm|
D ]j}	t	          |	t
                    r<|	                                 r'|                    |	                                            S|	r|                    |	           kt                      }g }|D ]F}t	          |t
                    r||v r|
                    |           |                    |           G|d d         }|rdnd}|st          ddd	|
          S t                      }|"|j                            d          }|j        }n;t           }t"          j                            d          }|st          ddd	|
          S t'          |                    d                    \  }}t)          |                    d                    }|t	          |                    d          t                    r*|                    d          rt          ddd	|||          S t	          |                    d          t                    r*|                    d          rt          ddd	|||          S ||t*          |d}|                    d          }t	          |t,                    r||d<   |                    d          }t	          |t                    r|r||d<   |rTg }|D ]J}	t	          |	t
                    r|                    |	t.          d           5|                    |	           K||d<   |                    d          }t	          |t                    r|r|d d         |d<   d| ddd}|#t          t1          j                              |d<   | d |d!          }	 t5          j        |||d"#          }|                                 n# t4          j        $ r~}|j        }||j        nd$}	 ||                                 ni } t	          |                     d%          tB                    r)|                     d%i                               d&          n)|                     d&          p|                     d'          p||j"        d d(         nt          |          }!n0# tF          $ r# ||j"        d d(         nt          |          }!Y nw xY wtH          %                    d)||!           |Dd*|cxk    rd+k     r7n n4|d,k    rd-nd.| d/}"t          d0| d1| d2|! d3|" d4d	|||          cY d }~S t          d5| d2|! d4d	|||          cY d }~S d }~wt4          j&        $ r t          d6d7d	|||          cY S t4          j'        $ r"}t          d8| d9d	|||          cY d }~S d }~ww xY w	 |                                 }#n/# tF          $ 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 | d>|$ }%d| dd?}&tP          }'tS          j*                    tV          z   }(d })	 tS          j,        |'           t[          |'t\          z  t^                    }'	 t5          j        |%|&d"A          }*|*                                 n# t4          j        $ rx}|j        }||j        nd$}tH          %                    dB||$           |t`          vstS          j*                    |(k    r t          dC| dD|$ d4d	|||          cY d }~S Y d }~d }~wt4          j&        t4          j'        f$ r^}tH          1                    dE|$|           tS          j*                    |(k    r t          dF|$ dG| d7d	|||          cY d }~S Y d }~Yd }~ww xY w	 |*                                 }+nh# tF          $ r[}tH          1                    dH|$|           tS          j*                    |(k    rt          dI| d;d	|||          cY d }~S Y d }~d }~ww xY wt	          |+tB                    r|+                    dJ          nd },t	          |,t
                    r|,})|,td          v rnwt	          |+tB                    r|+                    dK          rnLtS          j*                    |(k    r3t          dL|$ dMt-          tV                     dN|)pdO dPd7d	|||          S t	          |+tB                    st          dQd;d	|||          S |)dRk    rqt	          |+                    dS          tB                    r*|+                    dS          pi                     d%          nd }-t          dL|$ dT|-pdU d4d	|||          S |)dVk    rt          dL|$ dWdVd	|||          S |+                    dS          }.t	          |.tB                    st          dXdYd	|||          S d }/|.                    dZ          }0t	          |0t                    rF|0rD|0D ]A}1t	          |1t
                    r*|1                                 r|1                                 }/ nB|/R|.                    d[          }2t	          |2t
                    r(|2                                 r|2                                 }/|/t          d\dYd	|||          S 	 tg          |/d]| ^          }3t          |3          }4n5# tF          $ r(}tH          1                    d_|/|           |/}4Y d }~nd }~ww xY w|t*          ||$d`}5t	          |+                    dK          t
                    r|+dK         |5dK<   ti          |4|||d	||5a          S )bN r   image_style_referencesr   r   r   z1Prompt is required and must be a non-empty stringinvalid_argumentrB   )error
error_typeproviderr   /rS   u   KREA_API_KEY not set. Run `hermes tools` → Image Generation → Krea to configure, get a key at https://www.krea.ai/settings/api-tokens, or sign in to a Nous account with the managed Krea gateway enabled (`hermes setup`).auth_requiredrC   r]   styleszManaged Krea (Nous Subscription) does not support trained styles (LoRAs). Set KREA_API_KEY to use Krea directly, or omit `styles`.unsupported_argument)r   r   r   rC   r   r   
moodboardszzManaged Krea (Nous Subscription) does not support moodboards. Set KREA_API_KEY to use Krea directly, or omit `moodboards`.)r   r   
resolutionr]   seed)r   strength   zBearer zapplication/jsonz!Hermes-Agent/1.0 (krea-image-gen))AuthorizationzContent-Type
User-Agentzx-idempotency-keyz/generate/image/krea/krea-2/r      )headersjsontimeoutr   r   messagedetaili,  zKrea submit failed (%d): %si  r(   r'   u<   Krea's shared-key concurrency cap was hit — retry shortly.zModel 'u   ' may not be enabled/priced on the Nous Portal's Krea gateway. Set KREA_API_KEY to use Krea directly, or pick a different model via `hermes tools` → Image Generation.z)Nous Subscription Krea gateway rejected 'z' (HTTP z): z. 	api_errorzKrea image generation failed (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urlsr   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   r]   r   )r   rC   r   r   r   modalityextra)5rE   r   _ASPECT_MAPr4   r2   rD   appendr   listsetaddr   rV   gateway_originrstripnous_user_tokenBASE_URLrF   rG   rN   rb   DEFAULT_RESOLUTIONint!_DEFAULT_STYLE_REFERENCE_STRENGTHuuiduuid4requestspostraise_for_status	HTTPErrorresponsestatus_coder   r3   r   r5   r6   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   )6rh   r   r   r   r   r   aspectkrea_ar
style_refsreflegacy_refsseendedupedrr   managedbase_url
auth_tokenru   rv   r]   payloadr   r   normalized_refsr   r   
submit_urlr   r:   respr   bodyerr_msghintsubmit_bodyr   job_urlpoll_headersintervaldeadlinelast_status	poll_respjob
status_strerrr   result_image_urlr   rK   single
saved_path	image_refr   s6                                                         r;   generatezKreaImageGenProvider.generate  s;    ,B%%''%l33//&%00 !#
i%% 	1)//*;*; 	1ioo//000./CDDJ 	# 	#Cc""""jj!9::k4(( 	+" + +c3'' +yy{{ 7"))#))++666 +%%c*** EE 	 	A!S!! 99NN1SbS\
(477f 	!I-#	    011-44S99H 0JJH77J %,  /#!'    (

7(;(;<<$(L)A)ABB
 &**X..55 &**X:N:N %6  6#"!!'    &**\22D99 fjj>V>V %-  6#"!!'    #,$	#
 #
 zz&!!dC   	#"GFOH%%fd## 	' 	' &GH 	@ *,O! 0 0c3'' 0#** #1RSS    $**3////0?G,-ZZ--
j$'' 	3J 	3$.rrNGL! 4z33.=
 

 
 ,/tz||+<+<G'( !LLd6lLL
H	}	  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
 "sf':':':':s':':':':': }} SR?( ? ? ?	  &>H > >!'> >,3> >7;> >  +#"!!'
 
 
 
 
 
 
 
 
 "KvKK'KK&#          	 	 	!3$#      ' 	 	 	!555-#        	
	"--//KK 	 	 	!DsDD-#        	 **&#&& 	f 	!;-#    --V--3z33=
 
 *>##&;;%)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 '0'8'8$E#ZZ&&F&#&& 26<<>> 2#)<<>> #!:+#   
	('(8ASASASTTTJ JII  	) 	) 	)NNW   
 )IIIIII	) "),$	!
 !
 cggn--s33 	8$'$7E.!
 
 
 	
s   ",R Y2 X3B3U'&X'*VXVAX3Y29XY2'Y2Y2Y-'Y2-Y26Z 
Z7Z2,Z72Z7!+^ bA(`bb.Ab;bbb% %
d
/A
d9d
d
.o 
po??p)r,   rD   r,   rW   )r,   rp   )r,   r>   r,   r-   )r   rD   r   rD   r   r>   r   r   r   r   r,   r-   )__name__
__module____qualname____doc__propertyri   rm   ro   ry   r|   r   r   r	   r   rf   rO   r;   rd   rd      s        JJ   X    XU U U U

 

 

 

   
 
 
 
M M M M 1I

 $(48I
 I
 I
 I
 I
 I
 I
 I
rO   rd   Nonec                H    |                      t                                 dS )uG   Plugin entry point — wire ``KreaImageGenProvider`` into the registry.N)register_image_gen_providerrd   )ctxs    r;   registerr    s#    ##$8$:$:;;;;;rO   r   r{   )r=   r>   r,   r?   r   )rL   r>   r,   rD   )r,   r  )/r  
__future__r   loggingrF   r   r   typingr   r   r   r   r   r   agent.image_gen_providerr	   r
   r   r   r   r   r   	getLoggerr   r6   r   r   __annotations__rH   r   r   r   r_   r   r   r   r   	frozensetr   r   r<   rN   rV   r[   rb   rd   r  rf   rO   r;   <module>r     s    , # " " " " "  				   3 3 3 3 3 3 3 3 3 3 3 3 3 3                   
	8	$	$ !
 #ZL  "`L  )Q7 & &    0  
    
 %( ! 544 
     %9%M%M%MNN 777 
 
 
 
1 1 1 1 1@  4	 	 	 	   &@
 @
 @
 @
 @
+ @
 @
 @
P< < < < < <rO   