
    `gj\t                    r   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'd0d(Z(d1d2d)Z)d* Z*d3d+Z+d4d,Z, G d- d.e      Z-d5d/Z.y)6u  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	completedc                     	 ddl m}   |        }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)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       R/root/.hermes/venv/lib/python3.12/site-packages/plugins/image_gen/krea/__init__.py_load_krea_configr:   w   sb    1m*4S$*?#''+&T$Wd3w;; :C@	s$   AA A 	A1A,&A1,A1c                   t        | t              r=| j                         t        v r'| j                         t        | j                            fS t        j
                  j                  d      }|r|t        v r|t        |   fS t               }t        |j                  d      t              r|j                  d      ni }d}t        |t              r+|j                  d      }t        |t              r
|t        v r|}|+|j                  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)
r0   strstripr   osenvironr2   r:   r1   DEFAULT_MODEL)explicitenv_overrider6   krea_cfg	candidatevaluetops          r9   _resolve_modelrJ      s    (C X^^%5%@~~)9!:::::>>"45L/W\222

C",SWWV_d"CswwvH#I(D!W%eS!ew&6Igggc3C7NI'),,,'-000    c                 .   	 ddl m}  ddlm} t        j                  j                  d      r	 |d      sy	  | d      S # t        $ r }t
        j                  d|       Y d}~yd}~ww xY w# t        $ r }t
        j                  d	|       Y d}~y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_KEYr.   r=   z*Managed Krea gateway resolution failed: %s)
tools.managed_tool_gatewayrM   tools.tool_backend_helpersrN   r3   r4   r5   rA   rB   r2   )rM   rN   r8   s      r9   _resolve_managed_krea_gatewayrR      s    K>
 
zz~~n%ok.J+F33  FL  A3Gs,   ? A+ 	A(A##A(+	B4BBc                 p    	 ddl m}  	 t         | d            S # t        $ r Y yw xY w# t        $ r Y yw xY w)z<Cheap, offline-friendly probe for managed Krea availability.r   is_managed_tool_gateway_readyFr=   )rP   rU   r3   boolrT   s    r9   _managed_krea_gateway_readyrW      sG    L1&9::    s    ) 	&&	55c                   t        | t              r(| j                         j                         }|t        v r|S t               }t        |j                  d      t              r|j                  d      ni }t        |t              r|j                  d      nd}t        |t              rB|j                         j                         t        v r|j                         j                         S y)zGCoerce ``creativity`` kwarg to a valid Krea value (default ``medium``).r=   
creativityNr   )r0   r?   r@   lower_VALID_CREATIVITYr:   r2   r1   )rH   vr6   rF   	cfg_values        r9   _resolve_creativityr^      s    %KKM!!!H

C",SWWV_d"CswwvH.84.H\*dI)S!ioo&7&=&=&?CT&T &&((rK   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y	)KreaImageGenProviderz@Krea ``Krea 2`` foundation image model backend (Medium + Large).c                     y)Nr=    selfs    r9   namezKreaImageGenProvider.name       rK   c                     y)NKrearb   rc   s    r9   display_namez!KreaImageGenProvider.display_name   rf   rK   c                j    t        t        j                  j                  d            xs
 t	               S )NrO   )rV   rA   rB   r2   rW   rc   s    r9   is_availablez!KreaImageGenProvider.is_available   s%     BJJNN>23T7R7TTrK   c           
         t         j                         D cg c]  \  }}||d   |d   |d   |d   d c}}S c c}}w )Nr   r   r   r   )idr   r   r   r   )r   items)rd   model_idmetas      r9   list_modelsz KreaImageGenProvider.list_models   sR     #*--/	
 $ 	?g!+.g	
 		
 	
s   :c                    t         S N)rC   rc   s    r9   default_modelz"KreaImageGenProvider.default_model   s    rK   c                    dddddddgdS )	Nrh   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.rO   zKrea API keyz'https://www.krea.ai/settings/api-tokens)keyprompturl)re   badgetagenv_varsrb   rc   s    r9   get_setup_schemaz%KreaImageGenProvider.get_setup_schema   s-     Q *,D	
 	
rK   c                    ddgddS )Ntextimage
   )
modalitiesmax_reference_imagesrb   rc   s    r9   capabilitiesz!KreaImageGenProvider.capabilities  s      &w/LLrK   N)	image_urlreference_image_urlsc               r   |xs dj                         }t        |      }t        j                  |d      }g }t	        |t
              r/|j                         r|j                  |j                                t        |      xs g D ]  }	|j                  |	        |j                  d      }
t	        |
t              r\|
D ]W  }	t	        |	t
              r1|	j                         s$|j                  |	j                                D|	sG|j                  |	       Y t               }g }|D ]9  }t	        |t
              r||v r|j                  |       |j                  |       ; |d d }|rdnd}|st        ddd	|
      S t               }|(|j                  j                  d      }|j                  }n6t         }t"        j$                  j                  d      }|st        ddd	|
      S t'        |j                  d            \  }}t)        |j                  d            }|t	        |j                  d      t              r"|j                  d      rt        ddd	|||      S t	        |j                  d      t              r"|j                  d      rt        ddd	|||      S ||t*        |d}|j                  d      }t	        |t,              r||d<   |j                  d      }t	        |t              r|r||d<   |rHg }|D ]<  }	t	        |	t
              r|j                  |	t.        d       ,|j                  |	       > ||d<   |j                  d      }t	        |t              r
|r|d d |d<   d| ddd}| t        t1        j2                               |d<   | d |d!    }	 t5        j6                  |||d"#      }|j9                          	 |jA                         }#|#j                  d<      }$t	        |$t
              r|$st        d=d;d	|||      S | d>|$ }%d| dd?}&tP        }'tS        jT                         tV        z   }(d })	 tS        jX                  |'       t[        |'t\        z  t^              }'	 t5        j                  |%|&d"@      }*|*j9                          	 |*jA                         }+t	        |+tB              r|+j                  dI      nd },t	        |,t
              r|,})|,td        v rngt	        |+tB              r|+j                  dJ      rnEtS        jT                         |(k\  r,t        dK|$ dLt-        tV               dM|)xs dN dOd7d	|||      S t	        |+tB              st        dPd;d	|||      S |)dQk(  r`t	        |+j                  dR      tB              r$|+j                  dR      xs i j                  d%      nd }-t        dK|$ dS|-xs dT d4d	|||      S |)dUk(  rt        dK|$ dVdUd	|||      S |+j                  dR      }.t	        |.tB              st        dWdXd	|||      S d }/|.j                  dY      }0t	        |0t              r<|0r:|0D ]5  }1t	        |1t
              s|1j                         s%|1j                         }/ n |/A|.j                  dZ      }2t	        |2t
              r |2j                         r|2j                         }/|/t        d[dXd	|||      S 	 tg        |/d\| ]      }3t        |3      }4|t*        ||$d_}5t	        |+j                  dJ      t
              r|+dJ   |5dJ<   ti        |4|||d	||5`      S # t4        j:                  $ rV}|j<                  }||j>                  nd$}	 ||jA                         ni } t	        | j                  d%      tB              r!| j                  d%i       j                  d&      n#| j                  d&      xs | j                  d'      xs ||jD                  d d( n
t        |      }!n+# tF        $ r ||jD                  d d( n
t        |      }!Y nw xY wtH        jK                  d)||!       |=d*|cxk  rd+k  r2n n/|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        jL                  $ r t        d6d7d	|||      cY S t4        jN                  $ r}t        d8| d9d	|||      cY d }~S d }~ww xY w# tF        $ r}t        d:| d;d	|||      cY d }~S d }~ww xY w# t4        j:                  $ ry}|j<                  }||j>                  nd$}tH        jK                  dA||$       |t`        vstS        jT                         |(k\  rt        dB| dC|$ d4d	|||      cY d }~S Y d }~ed }~wt4        jL                  t4        jN                  f$ rU}tH        jc                  dD|$|       tS        jT                         |(k\  rt        dE|$ dF| d7d	|||      cY d }~S Y d }~d }~ww xY w# tF        $ rR}tH        jc                  dG|$|       tS        jT                         |(k\  rt        dH| d;d	|||      cY d }~S Y d }~9d }~ww xY w# tF        $ r$}tH        jc                  d^|/|       |/}4Y d }~d }~ww xY w)aN r   image_style_referencesr   r   r   z1Prompt is required and must be a non-empty stringinvalid_argumentr=   )error
error_typeprovideraspect_ratio/rO   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_requiredr>   rY   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   r>   rx   r   
moodboardszzManaged Krea (Nous Subscription) does not support moodboards. Set KREA_API_KEY to use Krea directly, or omit `moodboards`.)rx   r   
resolutionrY   seed)ry   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   )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urlsry   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   rY   r   )r   r>   rx   r   r   modalityextra)5r@   r   _ASPECT_MAPr2   r0   r?   appendr   listsetaddr   rR   gateway_originrstripnous_user_tokenBASE_URLrA   rB   rJ   r^   DEFAULT_RESOLUTIONint!_DEFAULT_STYLE_REFERENCE_STRENGTHuuiduuid4requestspostraise_for_status	HTTPErrorresponsestatus_coder   r1   r   r3   r4   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   )6rd   rx   r   r   r   kwargsaspectkrea_ar
style_refsreflegacy_refsseendedupedrr   managedbase_url
auth_tokenro   rp   rY   payloadr   r   normalized_refsr   r   
submit_urlr   r8   respr   bodyerr_msghintsubmit_bodyr   job_urlpoll_headersintervaldeadlinelast_status	poll_respjob
status_strerrr   result_image_urlr   rG   single
saved_path	image_refr   s6                                                         r9   generatezKreaImageGenProvider.generate  sp    ,B%%'%l3//&%0 !#
i%)//*;ioo/0./CDJ 	#Cc"	#jj!9:k4(" +c3'yy{"))#))+6%%c*+ E 	A!S!9NN1	 Sb\
(7f!I-#	  01--44S9H 00JH7J%,  /#!'  (

7(;<$(L)AB
 &**X.5&**X:N%6  6#"!!'  &**\2D9fjj>V%-  6#"!!'  #,$	#
 zz&!dC "GFOH%fd# &GH *,O! 0c3'#** #1RS $**3/0 1@G,-ZZ-
j$'J$.rNGL!  'zl3.=

 
 ,/tzz|+<G'( !z!=d6l^L
H	}}	H %%'F
	"--/K *&#&f!;-#  JfVH-&zl3=
 *>>#&;;%)JJx 8m35GHH"$LL,PRS	**,Dnn& /9d.C*J*c*(!11 #t$)@~~8+%#F8+D4566F{G_V_F``ac  )#"!!'
 
K d #t$!7-#  ("<FswwxGXZ^<_3778$*//8eiC!!&33I/2JK&#  +%!!&8&#  "&$'!A+#  +/zz&!dD!d! 	i-)//2C'0'8$ #ZZ&F&#&6<<>#)<<> #!:+# 
	('(85
ASTJ JI "),$	!
 cggn-s3$'$7E.!
 	
e !! .	<<D)-)9T%%qFL&*&6tyy{B "$((7"3T: HHWb)--i8),B0BI *.)9diios3x	 
  L-1-=$))DS/3s8LLL6H
 "sf':s': } S "( ,? ?	  &CH: N!!'G9Btf>  +#"!!'
 
 "6vhc'K&#   	!3$#  '' 	!/u5-# 	  	!>seD-# 	P %% ||-1-=))1?P
 !99T^^=MQY=Y) 26(*VHM#.!'&%%+  $$h&>&>? I6SVW>>#x/) <VHBseL#,!'&%%+    OQWY\]>>#x/) A#G#5!'&%%+  `  	)NNW 
 )I	)s   ()\; c< 6(d& h+ j	 ;c9b ,B`b %`+(b *`++Ab >c9b c9 'c9	c9c4.c94c9<	d#dd#d#&h(9A(f-!h(-&h(Ah#h(#h(+	j4Aj5jj		j6j11j6)returnr?   r   rV   )r   zList[Dict[str, Any]])r   Optional[str]r   Dict[str, Any])rx   r?   r   r?   r   r   r   zOptional[List[str]]r   r   r   r   )__name__
__module____qualname____doc__propertyre   ri   rk   rq   rt   r}   r   r	   r   rb   rK   r9   r`   r`      s    J   U


M 1I

 $(48I
I
 I

 !I
 2I
 I
 
I
rK   r`   c                6    | j                  t                      y)uG   Plugin entry point — wire ``KreaImageGenProvider`` into the registry.N)register_image_gen_providerr`   )ctxs    r9   registerr     s    ##$8$:;rK   r   rs   )rD   r   r   zTuple[str, Dict[str, Any]]r   )rH   r   r   r?   )r   None)/r   
__future__r   loggingrA   r   r   typingr   r   r   r   r   r   agent.image_gen_providerr	   r
   r   r   r   r   r   	getLoggerr   r4   r   r   __annotations__rC   r   r   r   r[   r   r   r   r   	frozensetr   r   r:   rJ   rR   rW   r^   r`   r   rb   rK   r9   <module>r	     s,  , #  	   3 3    
		8	$ !
 #ZL "`L )Q7&	" 0  
   
 %( ! 5 
     %%MN 7 
1@4	&@
+ @
P<rK   