§
    øžyj³P  ã                  ó  — 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 ddl	m
Z
mZmZ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ZeefZd	d
ddœZdZdZd+d„Zd,d„Z d-d„Z!d.d„Z"d/d"„Z# G d#„ d$e¦  «        Z$d0d&„Z%d1d*„Z&dS )2u�  OpenRouter-compatible image generation backend (OpenRouter + Nous Portal).

Both OpenRouter and the Nous Portal inference endpoint speak the same
OpenAI-style ``/chat/completions`` image-generation protocol: send
``modalities: ["image", "text"]`` with an image-output model (e.g.
``google/gemini-3-pro-image``), pass reference images as ``image_url``
content parts for grounding, and read the generated images back from
``choices[0].message.images[].image_url.url`` (a ``data:image/...;base64`` URI).

Nous Portal proxies OpenRouter, so one implementation services both â€” we only
swap the resolved ``(base_url, api_key)``. Credentials are resolved through the
agent's existing :func:`~hermes_cli.runtime_provider.resolve_runtime_provider`,
which already understands OpenRouter's key pool and the Nous OAuth device-code
token, so this plugin never reinvents auth.

Reference grounding is the reason pet sprite generation cares about this
backend: each animation row must stay the same character as the chosen base
frame, which only works on models that accept image input. Gemini Flash Image
("nano-banana") does, so both providers advertise image-to-image support.
é    )ÚannotationsN)ÚPath)ÚAnyÚDictÚListÚOptional)ÚDEFAULT_ASPECT_RATIOÚImageGenProviderÚerror_responseÚresolve_aspect_ratioÚsave_b64_imageÚsave_url_imageÚsuccess_responsezopenai/gpt-5.4-image-2zgoogle/gemini-3-pro-imageú1:1z16:9z9:16)ÚsquareÚ	landscapeÚportraité   g     Àr@Ú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)zDRead the ``image_gen`` section from config.yaml (``{}`` on failure).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       úK/home/ragecks/.hermes/hermes-agent/plugins/image_gen/openrouter/__init__.pyÚ_load_image_gen_configr%   J   s¥   € ðØ1Ð1Ð1Ð1Ð1Ð1àˆk‰mŒmˆÝ*4°S½$Ñ*?Ô*?ÐI�#—'’'˜+Ñ&Ô&Ð&ÀTˆÝ$ W­dÑ3Ô3Ð;ˆwˆw¸Ð;øÝð ð ð Ý�ŠÐ:¸CÑ@Ô@Ð@Øˆ	ˆ	ˆ	ˆ	ˆ	ˆ	øøøøðøøøs   ‚AA Á
BÁ!BÁ=BÂBÚrefÚstrúOptional[str]c                óò  — t          | pd¦  «                             ¦   «         } | sdS |                      d¦  «        r| S t          | ¦  «        }ddlm}  || ¦  «         	 |                     ¦   «         }n4# t          $ r'}t           	                    d| |¦  «         Y d}~dS d}~ww xY wt          j        |j        ¦  «        d         pd}t          j        |¦  «                             d¦  «        }d	|› d
|› �S )a4  Turn a reference (local path or http URL) into an ``image_url`` value.

    Remote URLs pass through unchanged; local files are inlined as base64 data
    URIs so the request is self-contained (the provider endpoint can't reach a
    path on our disk). Returns ``None`` when the reference can't be read.
    Ú N)zhttp://zhttps://údata:r   )Úraise_if_read_blockedz%could not read reference image %s: %sz	image/pngÚasciir+   z;base64,)r'   ÚstripÚ
startswithr   Úagent.file_safetyr,   Ú
read_bytesÚOSErrorr   r    Ú	mimetypesÚ
guess_typeÚnameÚbase64Ú	b64encodeÚdecode)r&   Úpathr,   Úrawr#   ÚmimeÚencodeds          r$   Ú_to_image_url_partr=   W   s  € õ ˆcˆi�R‰.Œ.×
Ò
Ñ
 Ô
 €CØð ØˆtØ
‡~‚~Ð6Ñ7Ô7ð Øˆ
Ý�‰9Œ9€Dà7Ð7Ð7Ð7Ð7Ð7àÐ˜#ÑÔÐðØ�oŠoÑÔˆˆøÝð ð ð Ý�ŠÐ<¸cÀ3ÑGÔGÐGØˆtˆtˆtˆtˆtøøøøðøøøõ Ô ¤	Ñ*Ô*¨1Ô-Ð<°€DÝÔ˜sÑ#Ô#×*Ò*¨7Ñ3Ô3€GØ*�4Ð*Ð* Ð*Ð*Ð*s   Á A5 Á5
B&Á?B!Â!B&Úpayloadú	List[str]c                óÒ  — g }t          | t          ¦  «        r|                      d¦  «        nd}t          |t          ¦  «        s|S |D �]}t          |t          ¦  «        r|                     d¦  «        nd}t          |t          ¦  «        r|                     d¦  «        nd}t          |t          ¦  «        sŒq|D ]©}t          |t          ¦  «        sŒ|                     d¦  «        }t          |t          ¦  «        r|                     d¦  «        nd}t          |t          ¦  «        r;|                     ¦   «         r'|                     |                     ¦   «         ¦  «         Œª�Œ|S )zÀPull generated image URLs from a chat-completions response.

    OpenRouter returns generated images under
    ``choices[0].message.images[].image_url.url`` (typically a base64 data URI).
    ÚchoicesNÚmessageÚimagesÚ	image_urlÚurl)r   r   r   Úlistr'   r.   Úappend)	r>   ÚoutrA   ÚchoicerB   rC   ÚimagerD   rE   s	            r$   Ú_extract_imagesrK   r   sU  € ð €CÝ(2°7½DÑ(AÔ(AÐKˆg�kŠk˜)Ñ$Ô$Ð$Àt€GÝ�g�tÑ$Ô$ð Øˆ
Øð (ñ (ˆÝ+5°f½dÑ+CÔ+CÐM�&—*’*˜YÑ'Ô'Ð'ÈˆÝ*4°W½dÑ*CÔ*CÐM�—’˜XÑ&Ô&Ð&ÈˆÝ˜&¥$Ñ'Ô'ð 	ØØð 	(ð 	(ˆEÝ˜e¥TÑ*Ô*ð ØØŸ	š	 +Ñ.Ô.ˆIÝ*4°YÅÑ*EÔ*EÐO�)—-’- Ñ&Ô&Ð&È4ˆCÝ˜#�sÑ#Ô#ð (¨¯	ª	©¬ð (Ø—
’
˜3Ÿ9š9™;œ;Ñ'Ô'Ð'øñ	(ð €Jó    ÚdisplayÚmodel_idÚenv_varÚstatusÚintÚerr_msgc                óÖ   ‡— |                      d¦  «        sdS |pd                     ¦   «         Š|dv pt          ˆfd„dD ¦   «         ¦  «        }|sdS | › d|› d|› d	| › d
|› dt          › d�S )uÅ  A targeted hint when an access-gated OpenAI image model can't be reached.

    Some OpenAI image models on OpenRouter need account enablement / BYOK, so the
    failure isn't a missing key (the key is valid) â€” the *model* is unreachable.
    The generic "check your key" message is misleading there, so we detect that
    case and point the user at the real fix. Returns one actionable line, or
    ``None`` when this isn't the access-gated case.
    zopenai/Nr*   )i’  i“  i”  c              3  ó    •K  — | ]}|‰v V — Œ	d S ©N© )Ú.0ÚsÚlows     €r$   ú	<genexpr>z%_access_error_hint.<locals>.<genexpr>™   s8   øè è € ð -ð -ØˆˆSˆð-ð -ð -ð -ð -ð -rL   )zno endpointsz
no allowedznot a valid modelzdata policyz can't reach image model 'z' (u)   ) â€” enable OpenAI image access in your z account, or set Ú=ú.)r/   ÚlowerÚanyÚ_FALLBACK_MODEL)rM   rN   rO   rP   rR   ÚgatedrY   s         @r$   Ú_access_error_hintra   ‹   sè   ø€ ð ×Ò˜yÑ)Ô)ð ØˆtØˆ=�b×
Ò
Ñ
!Ô
!€CØ�oÐ%ð ­ð -ð -ð -ð -Ø\ð-ñ -ô -ñ *ô *€Eð ð Øˆtàð 	Wð 	W¨hð 	Wð 	W¸6ð 	Wð 	WØ 'ð	Wð 	WØ:Að	Wð 	WÝDSð	Wð 	Wð 	WðrL   Úmodelsú	list[str]c                ó¾   — g }t          ¦   «         }| D ]I}|pd                     ¦   «         }|r||v rŒ|                     |¦  «         |                     |¦  «         ŒJ|S )Nr*   )Úsetr.   ÚaddrG   )rb   rH   ÚseenÚmodelÚms        r$   Ú_dedupe_modelsrj   ¤   sl   € Ø€CÝ‘U”U€DØð ð ˆØˆ[�b×ÒÑ!Ô!ˆØð 	�A˜�I�IØØ�Š�‰ŒˆØ�
Š
�1‰ŒˆˆØ€JrL   c                  ó¢   — e Zd ZdZd&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d(d„Zd,d-d„Zd,d.d„Zefdddœd/d%„ZdS )0ÚOpenRouterCompatImageProvidera  Image generation over an OpenRouter-compatible chat-completions endpoint.

    Instantiated once per backend (OpenRouter, Nous Portal). The two differ only
    in which runtime provider supplies ``(base_url, api_key)`` and in the config
    namespace used for the model override.
    Úprovider_namer'   Údisplay_nameÚruntime_nameÚ
config_keyÚmodel_env_varÚsetup_schemar   r   ÚNonec               óZ   — || _         || _        || _        || _        || _        || _        d S rU   )Ú_nameÚ_displayÚ_runtime_nameÚ_config_keyÚ_model_env_varÚ_setup_schema)Úselfrm   rn   ro   rp   rq   rr   s          r$   Ú__init__z&OpenRouterCompatImageProvider.__init__¸   s8   € ð #ˆŒ
Ø$ˆŒØ)ˆÔØ%ˆÔØ+ˆÔØ)ˆÔÐÐrL   c                ó   — | j         S rU   )ru   ©r{   s    r$   r5   z"OpenRouterCompatImageProvider.nameÉ   s
   € àŒzÐrL   c                ó   — | j         S rU   )rv   r~   s    r$   rn   z*OpenRouterCompatImageProvider.display_nameÍ   s
   € àŒ}ÐrL   c                ó0   — ddl m}  || j        ¬¦  «        S )z@Resolve ``(base_url, api_key)`` via the shared runtime resolver.r   )Úresolve_runtime_provider)Ú	requested)Úhermes_cli.runtime_providerr�   rw   )r{   r�   s     r$   Ú_resolve_runtimez.OpenRouterCompatImageProvider._resolve_runtimeÑ   s+   € àHÐHÐHÐHÐHÐHà'Ð'°$Ô2DÐEÑEÔEÐErL   Úboolc                ó&  — 	 |                       ¦   «         }n9# t          $ r,}t                               d| j        |¦  «         Y d }~dS d }~ww xY wt          t          |                     d¦  «        pd¦  «                             ¦   «         ¦  «        S )Nz %s runtime resolution failed: %sFÚapi_keyr*   )	r„   r   r   r    ru   r…   r'   r   r.   )r{   Úruntimer#   s      r$   Úis_availablez*OpenRouterCompatImageProvider.is_available×   s”   € ð	Ø×+Ò+Ñ-Ô-ˆGˆGøÝð 	ð 	ð 	Ý�LŠLÐ;¸T¼ZÈÑMÔMÐMØ�5�5�5�5�5øøøøð	øøøõ •C˜Ÿš IÑ.Ô.Ð4°"Ñ5Ô5×;Ò;Ñ=Ô=Ñ>Ô>Ð>s   ‚ —
A¡!AÁAc                ó   — ddgt           dœS )NÚtextrJ   )Ú
modalitiesÚmax_reference_images)Ú_MAX_REFERENCE_IMAGESr~   s    r$   Úcapabilitiesz*OpenRouterCompatImageProvider.capabilitiesß   s   € ð " 7Ð+Ý$9ð
ð 
ð 	
rL   úList[Dict[str, Any]]c                ó.   — t           dddœt          dddœgS )NzOpenAI GPT-5.4 Image 2z=Highest fidelity; best prompt adherence; slower on OpenRouter)ÚidrM   Ú	strengthszGemini 3 Pro Imagez2Fast, reliable fallback with good layout adherence)ÚDEFAULT_MODELr_   r~   s    r$   Úlist_modelsz)OpenRouterCompatImageProvider.list_modelsç   s6   € õ $Ø3Ø\ðð õ &Ø/ØQðð ð
ð 	
rL   r(   c                ó*   — |                       ¦   «         S rU   )Ú_resolve_modelr~   s    r$   Údefault_modelz+OpenRouterCompatImageProvider.default_modelõ   s   € Ø×"Ò"Ñ$Ô$Ð$rL   c                ó*   — t          | j        ¦  «        S rU   )r   rz   r~   s    r$   Úget_setup_schemaz.OpenRouterCompatImageProvider.get_setup_schemaø   s   € Ý�DÔ&Ñ'Ô'Ð'rL   NÚexplicitc                ó8   — |                       |¦  «        d         S )z=Pick the image model (first of :meth:`_resolve_model_chain`).r   )Ú_resolve_model_chain)r{   r›   s     r$   r—   z,OpenRouterCompatImageProvider._resolve_modelû   s   € à×(Ò(¨Ñ2Ô2°1Ô5Ð5rL   rc   c                ó\  — t          |t          ¦  «        r)|                     ¦   «         r|                     ¦   «         gS t          j                             | j        d¦  «                             ¦   «         }|r|gS t          ¦   «         }t          |                     | j        ¦  «        t          ¦  «        r|                     | j        ¦  «        ni }t          |t          ¦  «        rS|                     d¦  «        }t          |t          ¦  «        r)|                     ¦   «         r|                     ¦   «         gS |                     d¦  «        }t          |t          ¦  «        r)|                     ¦   «         r|                     ¦   «         gS t          t          t          ¦  «        ¦  «        S )uæ  Ordered model attempts for this request.

        Precedence: explicit caller override (the ``model`` kwarg) â†’ the
        provider's ``*_IMAGE_MODEL`` env override â†’ scoped
        ``image_gen.<provider>.model`` â†’ top-level ``image_gen.model`` (written
        by ``hermes tools``) â†’ the quality-first default chain.

        Any explicit user/model selection means "use this exact model", so no
        fallback. Only the bare default chain carries a Gemini fallback.
        r*   rh   )r   r'   r.   ÚosÚenvironr   ry   r%   rx   r   rj   rF   Ú_DEFAULT_MODEL_CHAIN)r{   r›   Úenv_overrider!   ÚscopedÚvalueÚtops          r$   r�   z2OpenRouterCompatImageProvider._resolve_model_chainÿ   s_  € õ �h¥Ñ$Ô$ð 	&¨¯ªÑ)9Ô)9ð 	&Ø—N’NÑ$Ô$Ð%Ð%Ý”z—~’~ dÔ&9¸2Ñ>Ô>×DÒDÑFÔFˆØð 	"Ø �>Ð!Ý$Ñ&Ô&ˆÝ.8¸¿ºÀÔAQÑ9RÔ9RÕTXÑ.YÔ.YÐa�—’˜Ô)Ñ*Ô*Ð*Ð_aˆÝ�f�dÑ#Ô#ð 	'Ø—J’J˜wÑ'Ô'ˆEÝ˜%¥Ñ%Ô%ð '¨%¯+ª+©-¬-ð 'ØŸš™œ�Ð&Ø�gŠg�gÑÔˆÝ�c�3ÑÔð 	! C§I¢I¡K¤Kð 	!Ø—I’I‘K”K�=Ð Ý�dÕ#7Ñ8Ô8Ñ9Ô9Ð9rL   )rD   Úreference_image_urlsÚpromptÚaspect_ratiorD   r¦   úOptional[List[str]]Úkwargsr   c          
     ó   — dd l }	 |                      ¦   «         }n:# t          $ r-}t          d| j        › d|› �d| j        |¬¦  «        cY d }~S d }~ww xY wt          |                     d¦  «        pd¦  «                             ¦   «         }	t          |                     d¦  «        pd¦  «                             ¦   «          	                    d	¦  «        }
|	r|
s)t          d
| j        › d| j        › d�d| j        |¬¦  «        S |  
                    |                     d¦  «        ¦  «        }t          |¦  «        }t                               |d¦  «        }g }|                     d¦  «        pg D ]$}|                     t          |¦  «        ¦  «         Œ%|r"|                     t          |¦  «        ¦  «         |pg D ]$}|                     t          |¦  «        ¦  «         Œ%d|dœg}|d t          …         D ]-}t          |¦  «        }|r|                     dd|idœ¦  «         Œ.d|	› �ddddœ}d }t!          |¦  «        D �]ä\  }}|ddgd|dœgd|idœ}|t#          |¦  «        dz
  k    }	 |                     |
› d �||t&          ¬!¦  «        }|                     ¦   «          �n÷# |j        $ �r=}|j        }|�|j        nd}	 |                     ¦   «                              d"i ¦  «                             d#|j        d d$…         ¦  «        }n0# t          $ r# |�|j        d d$…         nt          |¦  «        }Y nw xY wt4                               d%| j        |||¦  «         t9          | j        || j        ||¦  «        }|r3|s1t4                               d&| j        |||dz            ¦  «         Y d }~�Œpt          |p| j        › d'|› d(|› �|rd)nd*| j        |||¬+¦  «        }|cY d }~c S d }~w|j        $ rl |s.t4                               d,| j        |||dz            ¦  «         Y �Œãt          | j        › d-tA          t&          ¦  «        › d.�d/| j        |||¬+¦  «        cY c S |j!        $ r0}t          | j        › d0|› �d1| j        |||¬+¦  «        cY d }~c S d }~ww xY w	 |                     ¦   «         }n=# t          $ r0}t          | j        › d2|› �d3| j        |||¬+¦  «        cY d }~c S d }~ww xY wtE          |¦  «        }|sV|s-t4                               d4| j        |||dz            ¦  «         �Œít          | j        › d5|› d6�d7| j        |||¬+¦  «        c S |d         }	 | #                    d8¦  «        r<d9|v r| $                    d9d¦  «        d         nd} tK          | | j        › d:�¬;¦  «        }!ntM          || j        › d:�¬;¦  «        }!n6# t          $ r)}t          d<|› �d=| j        |||¬+¦  «        cY d }~c S d }~ww xY wtO          t          |!¦  «        |||| j        ¬>¦  «        c S |p+t          | j        › d?�d*| j        |r|d@         nd||¬+¦  «        S )ANr   zCould not resolve z credentials: Úmissing_api_key)ÚerrorÚ
error_typeÚproviderr¨   r‡   r*   Úbase_urlú/zNo z credentials found. Configure u(    in `hermes tools` â†’ Image Generation.rh   r   Úreference_imagesr‹   )Útyper‹   rD   rE   )r³   rD   zBearer zapplication/jsonz,https://github.com/NousResearch/hermes-agentzHermes Agent)ÚAuthorizationzContent-TypezHTTP-RefererzX-TitlerJ   Úuser)ÚroleÚcontentr¨   )rh   rŒ   ÚmessagesÚimage_configé   z/chat/completions)ÚheadersÚjsonÚtimeoutr­   rB   i,  z"%s image gen failed (%d) on %s: %sz2%s model %s unavailable; retrying with fallback %sz image generation failed (z): Úmodel_accessÚ	api_error)r­   r®   r¯   rh   r§   r¨   z0%s model %s timed out; retrying with fallback %sz image generation timed out (zs)r½   z connection error: Úconnection_errorz returned invalid JSON: Úinvalid_responsez8%s model %s returned no image; retrying with fallback %sz& returned no image. Ensure the model 'z' supports image output.Úempty_responser+   Ú,Ú_gen)Úprefixz Could not save generated image: Úio_error)rJ   rh   r§   r¨   r¯   z; image generation failed after trying all candidate models.éÿÿÿÿ)(Úrequestsr„   r   r   rv   ru   r'   r   r.   Úrstripr�   r   Ú_ASPECT_RATIOSrG   rŽ   r=   Ú	enumerateÚlenÚpostÚ_REQUEST_TIMEOUTÚraise_for_statusÚ	HTTPErrorÚresponseÚstatus_coder¼   r‹   r   r­   ra   ry   ÚinfoÚTimeoutrQ   ÚConnectionErrorrK   r/   Úsplitr   r   r   )"r{   r§   r¨   rD   r¦   rª   rÈ   rˆ   r#   r‡   r°   Úmodel_chainÚaspectÚ	or_aspectÚ
referencesr&   r·   Úpartr»   Ú
last_errorÚirN   r>   Úis_lastrÑ   ÚresprP   rR   ÚhintÚresultrC   ÚfirstÚb64Ú
saved_paths"                                     r$   Úgeneratez&OpenRouterCompatImageProvider.generate  s	  € ð 	ˆˆˆð	Ø×+Ò+Ñ-Ô-ˆGˆGøÝð 	ð 	ð 	Ý!ØM¨4¬=ÐMÐMÈÐMÐMØ,ØœØ)ð	ñ ô ð ð ð ð ð ð øøøøð	øøøõ �g—k’k )Ñ,Ô,Ð2°Ñ3Ô3×9Ò9Ñ;Ô;ˆÝ�w—{’{ :Ñ.Ô.Ð4°"Ñ5Ô5×;Ò;Ñ=Ô=×DÒDÀSÑIÔIˆØð 		˜hð 		Ý!ðY˜$œ-ð Yð YØ!%¤ðYð Yð Yð -ØœØ)ðñ ô ð ð ×/Ò/°·
²
¸7Ñ0CÔ0CÑDÔDˆÝ% lÑ3Ô3ˆÝ"×&Ò& v¨uÑ5Ô5ˆ	ð
 !#ˆ
Ø—:’:Ð0Ñ1Ô1Ð7°Rð 	(ð 	(ˆCØ×Ò�c #™hœhÑ'Ô'Ð'Ð'Øð 	.Ø×Ò�c )™nœnÑ-Ô-Ð-Ø'Ð-¨2ð 	(ð 	(ˆCØ×Ò�c #™hœhÑ'Ô'Ð'Ð'à28À&Ð)IÐ)IÐ(JˆØÐ4Õ4Ð4Ô5ð 	Rð 	RˆCÝ% cÑ*Ô*ˆDØð RØ—’¨À5È$À-ÐPÐPÑQÔQÐQøð 1 wÐ0Ð0Ø.àJØ%ð
ð 
ˆð 04ˆ
Ý$ [Ñ1Ô1ð A	ñ A	‰KˆAˆxà!Ø&¨Ð/Ø&,¸ÐAÐAÐBØ!/°Ð ;ð	'ð 'ˆGð �3˜{Ñ+Ô+¨aÑ/Ò/ˆGð<Ø#Ÿ=š=ØÐ2Ð2Ð2Ø#Ø Ý,ð	 )ñ ô �ð ×)Ò)Ñ+Ô+Ð+Ñ+øØÔ%ð "ñ "ð "Ø”|�Ø-1Ð-=˜Ô)Ð)À1�ðPØ"Ÿiši™kœkŸošo¨g°rÑ:Ô:×>Ò>¸yÈ$Ì)ÐTXÐUXÐTXÌ/ÑZÔZ�G�GøÝ ð Pð Pð PØ15Ð1A˜dœi¨¨¨œo˜oÅsÈ3ÁxÄx�G�G�GðPøøøå—’ÐAÀ4Ä:ÈvÐW_ÐahÑiÔiÐiÝ)¨$¬-¸À4ÔCVÐX^Ð`gÑhÔh�Øð  ð Ý—K’KØLØœ
Ø Ø# A¨¡EÔ*ñ	ô ð ð �H�H�H‘HÝ+ØÐb T¤]Ð"bÐ"bÈfÐ"bÐ"bÐY`Ð"bÐ"bØ15ÐF˜~˜~¸;Ø!œZØ"Ø!Ø!'ðñ ô �
ð "Ð!Ð!Ð!Ð!Ð!Ð!Ð!Ð!øøøøØÔ#ð ð ð Øð Ý—K’KØJØœ
Ø Ø# A¨¡EÔ*ñ	ô ð ð ‘HÝ%Ø!œ]ð 2ð 2ÝÕ,Ñ-Ô-ð2ð 2ð 2à(Ø!œZØ"Ø!Ø!'ðñ ô ð ð ð ð ð ð Ô+ð ð ð Ý%Ø!œ]ÐDÐD¸sÐDÐDØ1Ø!œZØ"Ø!Ø!'ðñ ô ð ð ð ð ð ð ð ð øøøøðøøøð
Ø!Ÿš™œ��øÝð ð ð Ý%Ø!œ]ÐIÐIÀCÐIÐIØ1Ø!œZØ"Ø!Ø!'ðñ ô ð ð ð ð ð ð ð ð øøøøðøøøõ % VÑ,Ô,ˆFØð Øð Ý—K’KØRØœ
Ø Ø# A¨¡EÔ*ñ	ô ð ñ õ &àœ=ð ?ð ?Ø$ð?ð ?ð ?ð  0Ø!œZØ"Ø!Ø!'ð
ñ 
ô 
ð 
ð 
ð 
ð ˜1”IˆEðØ×#Ò# GÑ,Ô,ð SØ47¸5°L°L˜%Ÿ+š+ c¨1Ñ-Ô-¨aÔ0Ð0Àb�CÝ!/°¸t¼zÐ<OÐ<OÐ<OÐ!PÑ!PÔ!P�J�Jå!/°ÀÄÐ>QÐ>QÐ>QÐ!RÑ!RÔ!R�JøøÝð ð ð Ý%ØB¸SÐBÐBØ)Ø!œZØ"Ø!Ø!'ðñ ô ð ð ð ð ð ð ð ð øøøøðøøøõ $Ý˜*‘o”oØØØ#Øœðñ ô ð ð ð ð ð 
�^Ø”]Ð_Ð_Ð_Ø"Ø”ZØ%0Ð8�+˜b”/�/°bØØð
ñ 
ô 
ð 	
s¿   † ›
A¥"AÁAÁAÉ(5JÊRÊ*O"Ê=A	LÌO"Ì*L4Ì1O"Ì3L4Ì4A2O"Î,.O"ÏRÏ":RÐ7RÑ	RÑ##RÒRÒRÒR,Ò,
S&Ò6#S!ÓS&Ó!S&ÕA*W×
W7×W2×*W7×2W7)rm   r'   rn   r'   ro   r'   rp   r'   rq   r'   rr   r   r   rs   )r   r'   ©r   r   )r   r…   )r   r�   )r   r(   rU   )r›   r(   r   r'   )r›   r(   r   rc   )r§   r'   r¨   r'   rD   r(   r¦   r©   rª   r   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r|   Úpropertyr5   rn   r„   r‰   r�   r•   r˜   rš   r—   r�   r	   rå   rV   rL   r$   rl   rl   °   sY  € € € € € ðð ð*ð *ð *ð *ð" ðð ð ñ „Xðð ðð ð ñ „XððFð Fð Fð Fð?ð ?ð ?ð ?ð
ð 
ð 
ð 
ð
ð 
ð 
ð 
ð%ð %ð %ð %ð(ð (ð (ð (ð6ð 6ð 6ð 6ð 6ð:ð :ð :ð :ð :ð< 1ðH
ð
 $(Ø48ðH
ð H
ð H
ð H
ð H
ð H
ð H
ð H
rL   rl   ú#List[OpenRouterCompatImageProvider]c                 óv   — t          ddddddddddd	d
œgdœ¬¦  «        t          ddddddddg ddœ¬¦  «        gS )NÚ
openrouterÚ
OpenRouterÚOPENROUTER_IMAGE_MODELzOpenRouter (image)ÚpaidzAGemini Flash Image & more via OpenRouter; uses OPENROUTER_API_KEYÚOPENROUTER_API_KEYzOpenRouter API keyzhttps://openrouter.ai/keys)Úkeyr§   rE   )r5   ÚbadgeÚtagÚenv_vars)rm   rn   ro   rp   rq   rr   ÚnouszNous PortalÚNOUS_IMAGE_MODELzNous Portal (image)ÚsubscriptionzGReference-grounded image generation via Nous Portal (OpenRouter-backed)T)r5   rô   rõ   rö   Úrequires_nous_auth)rl   rV   rL   r$   Ú_build_providersrû   å  s–   € å%Ø&Ø%Ø%Ø#Ø2à,ØØZð  4Ø"6Ø;ðð ðð	ð ð	
ñ 	
ô 	
õ& 	&Ø Ø&ØØØ,à-Ø'Ø`ØØ&*ðð ð	
ñ 	
ô 	
ð)"ð "rL   Úctxr   rs   c                óR   — t          ¦   «         D ]}|                      |¦  «         ŒdS )z:Register the OpenRouter + Nous Portal image gen providers.N)rû   Úregister_image_gen_provider)rü   r¯   s     r$   Úregisterrÿ     s8   € å$Ñ&Ô&ð 2ð 2ˆØ×'Ò'¨Ñ1Ô1Ð1Ð1ð2ð 2rL   ræ   )r&   r'   r   r(   )r>   r   r   r?   )rM   r'   rN   r'   rO   r'   rP   rQ   rR   r'   r   r(   )rb   rc   r   rc   )r   rì   )rü   r   r   rs   )'rê   Ú
__future__r   r6   Úloggingr3   rŸ   Úpathlibr   Útypingr   r   r   r   Úagent.image_gen_providerr	   r
   r   r   r   r   r   Ú	getLoggerrç   r   r”   r_   r¡   rÊ   rŽ   rÎ   r%   r=   rK   ra   rj   rl   rû   rÿ   rV   rL   r$   ú<module>r     s÷  ððð ð* #Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø Ð Ð Ð Ø 	€	€	€	Ø Ð Ð Ð Ð Ð Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð 
ˆÔ	˜8Ñ	$Ô	$€ð )€Ø-€Ø% Ð7Ð ð
 ØØðð €ð Ð ð
 Ð ð
ð 
ð 
ð 
ð+ð +ð +ð +ð6ð ð ð ð2ð ð ð ð2	ð 	ð 	ð 	ðr
ð r
ð r
ð r
ð r
Ð$4ñ r
ô r
ð r
ðj	#ð #ð #ð #ðL2ð 2ð 2ð 2ð 2ð 2rL   