
    epjzt                       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 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)d:d+Z*d;d<d/Z+d0 Z,d=d2Z-d>d5Z. G d6 d7e          Z/d?d9Z0d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)
get_secret)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.configr0   
isinstancedictget	Exceptionloggerdebug)r0   cfgsectionexcs       E/home/thesage/.hermes/hermes-agent/plugins/image_gen/krea/__init__.py_load_krea_configr=   x   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)
r3   strstripr   osenvironr5   r=   r4   DEFAULT_MODEL)r>   env_overrider9   krea_cfg	candidatevaluetops          r<   _resolve_modelrO      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                 :   	 ddl m}  ddlm} n3# t          $ r&}t
                              d|           Y d}~dS d}~ww xY wt          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_KEYr1   rC   z*Managed Krea gateway resolution failed: %s)tools.managed_tool_gatewayrR   tools.tool_backend_helpersrS   r6   r7   r8   r	   )rR   rS   r;   s      r<   _resolve_managed_krea_gatewayrW      s    KKKKKK>>>>>>>   FLLLttttt .!! //+*F*F t++F333   A3GGGttttts(    
?:?
A* *
B4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_readyFrC   )rU   r[   r6   rX   rZ   s    r<   _managed_krea_gateway_readyr\      s    LLLLLLL   uu11&99:::   uus   	 
3 
A ArM   rE   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``).rC   
creativityNr   )r3   rE   rF   lower_VALID_CREATIVITYr=   r5   r4   )rM   vr9   rK   	cfg_values        r<   _resolve_creativityrc      s    % KKMM!!!!!H


C",SWWV__d"C"CKswwvH.84.H.HR\***dI)S!! )ioo&7&7&=&=&?&?CT&T&T  &&(((8rP   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-   rE   c                    dS )NrC    selfs    r<   namezKreaImageGenProvider.name       vrP   c                    dS )NKrearg   rh   s    r<   display_namez!KreaImageGenProvider.display_name   rk   rP   rX   c                V    t          t          d                    pt                      S )NrT   )rX   r	   r\   rh   s    r<   is_availablez!KreaImageGenProvider.is_available   s&     J~..//P3N3P3PPrP   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   rg   ).0model_idmetas      r<   
<listcomp>z4KreaImageGenProvider.list_models.<locals>.<listcomp>   sU     	
 	
 	
 $ 	?g!+.g 	
 	
 	
rP   )r   itemsrh   s    r<   list_modelsz KreaImageGenProvider.list_models   s-    	
 	
 #*--//	
 	
 	
 		
rP   r?   c                    t           S N)rI   rh   s    r<   default_modelz"KreaImageGenProvider.default_model   s    rP   r.   c                    dddddddgdS )	Nrm   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.rT   zKrea API keyz'https://www.krea.ai/settings/api-tokens)keyprompturl)rj   badgetagenv_varsrg   rh   s    r<   get_setup_schemaz%KreaImageGenProvider.get_setup_schema   s7     Q *,D 	
 
 	
rP   c                    ddgddS )Ntextimage
   )
modalitiesmax_reference_imagesrg   rh   s    r<   capabilitiesz!KreaImageGenProvider.capabilities  s      &w/LLLrP   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#          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          t/          j                              |d<   | d |d!          }	 t3          j        |||d"#          }|                                 n# t2          j        $ r~}|j        }||j        nd$}	 ||                                ni } t	          |                     d%          t@                    r)|                     d%i                               d&          n)|                     d&          p|                     d'          p||j!        d d(         nt          |          }!n0# tD          $ r# ||j!        d d(         nt          |          }!Y nw xY wtF          $                    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t2          j%        $ r t          d6d7d	|||          cY S t2          j&        $ r"}t          d8| d9d	|||          cY d }~S d }~ww xY w	 |                                }#n/# tD          $ 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?}&tN          }'tQ          j)                    tT          z   }(d })	 tQ          j+        |'           tY          |'tZ          z  t\                    }'	 t3          j        |%|&d"A          }*|*                                 n# t2          j        $ rx}|j        }||j        nd$}tF          $                    dB||$           |t^          vstQ          j)                    |(k    r t          dC| dD|$ d4d	|||          cY d }~S Y d }~d }~wt2          j%        t2          j&        f$ r^}tF          0                    dE|$|           tQ          j)                    |(k    r t          dF|$ dG| d7d	|||          cY d }~S Y d }~Yd }~ww xY w	 |*                                }+nh# tD          $ r[}tF          0                    dH|$|           tQ          j)                    |(k    rt          dI| d;d	|||          cY d }~S Y d }~d }~ww xY wt	          |+t@                    r|+                    dJ          nd },t	          |,t
                    r|,})|,tb          v rnwt	          |+t@                    r|+                    dK          rnLtQ          j)                    |(k    r3t          dL|$ dMt+          tT                     dN|)pdO dPd7d	|||          S t	          |+t@                    st          dQd;d	|||          S |)dRk    rqt	          |+                    dS          t@                    r*|+                    dS          pi                     d%          nd }-t          dL|$ dT|-pdU d4d	|||          S |)dVk    rt          dL|$ dWdVd	|||          S |+                    dS          }.t	          |.t@                    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 	 te          |/d]| ^          }3t          |3          }4n5# tD          $ r(}tF          0                    d_|/|           |/}4Y d }~nd }~ww xY w|t(          ||$d`}5t	          |+                    dK          t
                    r|+dK         |5dK<   tg          |4|||d	||5a          S )bN r   image_style_referencesr   r   r   z1Prompt is required and must be a non-empty stringinvalid_argumentrC   )error
error_typeproviderr   /rT   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_requiredrD   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   rD   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   rD   r   r   r   modalityextra)4rF   r   _ASPECT_MAPr5   r3   rE   appendr   listsetaddr   rW   gateway_originrstripnous_user_tokenBASE_URLr	   rO   rc   DEFAULT_RESOLUTIONint!_DEFAULT_STYLE_REFERENCE_STRENGTHuuiduuid4requestspostraise_for_status	HTTPErrorresponsestatus_coder   r4   r   r6   r7   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   )6ri   r   r   r   r   r   aspectkrea_ar
style_refsreflegacy_refsseendedupedrr   managedbase_url
auth_tokenrv   rw   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   rL   single
saved_path	image_refr   s6                                                         r<   generatezKreaImageGenProvider.generate  s5    ,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#N33J %,  /#!'    (

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   Y"X	#B3UX	*VX	VAX	#Y")X	Y"	'Y"2Y" YY"Y"&Y; ;
Z'Z"Z'"Z'+]> >a<A(` 5a< a<Aa7+a<7a< b 
c:A
c5)c:5c:o 
o4o//o4)r-   rE   r-   rX   )r-   rq   )r-   r?   r-   r.   )r   rE   r   rE   r   r?   r   r   r   r   r-   r.   )__name__
__module____qualname____doc__propertyrj   rn   rp   rz   r}   r   r   r
   r   rg   rP   r<   re   re      s        JJ   X    XQ Q Q Q

 

 

 

   
 
 
 
M M M M 1I

 $(48I
 I
 I
 I
 I
 I
 I
 I
rP   re   Nonec                H    |                      t                                 dS )uG   Plugin entry point — wire ``KreaImageGenProvider`` into the registry.N)register_image_gen_providerre   )ctxs    r<   registerr    s#    ##$8$:$:;;;;;rP   r   r|   )r>   r?   r-   r@   r   )rM   r?   r-   rE   )r-   r  )1r  
__future__r   loggingrG   r   r   typingr   r   r   r   r   r   agent.secret_scoper	   agent.image_gen_providerr
   r   r   r   r   r   r   	getLoggerr   r7   r   r   __annotations__rI   r   r   r   r`   r   r   r   r   	frozensetr   r   r=   rO   rW   r\   rc   re   r  rg   rP   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< < < < < <rP   