Ë
    áß²j—  ã                  ó|  — U d Z ddlm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mZ ddlmZ ddlmZ  ej"                  e«      ZdZd	ed
<   dZ G d„ de«      Zd#d„Zd$d„Zdddœd%d„ZddddddœZddddœ	 	 	 	 	 	 	 	 	 d&d„Zdddœ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d'd„Zdd d d ed!œ	 	 	 	 	 	 	 	 	 	 	 	 	 d(d"„ZddlZddl Z ddl!Z!y))a„  Image generation provider ABC.

Providers register via ``PluginContext.register_image_gen_provider()`` (from
``<repo>/plugins/image_gen/<name>/`` or ``~/.hermes/plugins/image_gen/<name>/``);
the one selected by ``image_gen.provider`` services every ``image_generate`` call.
One tool covers text-to-image and editing: ``image_url`` / ``reference_image_urls``
route to the provider's edit endpoint, otherwise text-to-image. Mirrors
``agent/video_gen_provider.py``. Response dicts come from :func:`success_response`
/ :func:`error_response` (``success, image, model, prompt, aspect_ratio, modality,
provider`` + ``error, error_type`` on failure).
é    )ÚannotationsN)ÚPath)ÚAnyÚDictÚListÚOptionalÚTuple)Úprovider_media)ÚCatalogProviderBase)Ú	landscapeÚsquareÚportraitzTuple[str, ...]ÚVALID_ASPECT_RATIOSr   c                  ó`   — e Zd ZdZdd„Zej                  efdddœ	 	 	 	 	 	 	 	 	 	 	 dd„«       Zy)ÚImageGenProviderzÊAbstract base class for an image generation backend. Subclasses implement
    :attr:`name` and :meth:`generate`; ``list_models`` entries may add
    ``speed`` / ``strengths`` / ``price`` for the picker.c                ó   — dgddœS )zü``modalities`` (``"text"`` and/or ``"image"``) and ``max_reference_images``.
        Surfaced in the dynamic tool schema so the model knows when ``image_url`` is
        honored; the text-only default keeps non-overriding providers backward compatible.Útextr   )Ú
modalitiesÚmax_reference_images© )Úselfs    ú=/home/ubuntu/.hermes/hermes-agent/agent/image_gen_provider.pyÚcapabilitieszImageGenProvider.capabilities#   s   € ð  &˜hÀÑBÐBó    N)Ú	image_urlÚreference_image_urlsc                ó   — y)a«  Generate an image, or edit ``image_url`` (``reference_image_urls`` are extra
        style/composition refs, clamped to ``max_reference_images``); any source image
        routes to the edit endpoint. Return :func:`success_response` / :func:`error_response`.
        Unknown ``kwargs`` MUST be ignored (forward compat); ``upscale`` (bool) is a
        post-generation high-res pass, reported as ``upscaled: True`` in ``extra``.Nr   )r   ÚpromptÚaspect_ratior   r   Úkwargss         r   ÚgeneratezImageGenProvider.generate)   s   � r   )ÚreturnúDict[str, Any])r   Ústrr   r$   r   úOptional[str]r   úOptional[List[str]]r    r   r"   r#   )	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚabcÚabstractmethodÚDEFAULT_ASPECT_RATIOr!   r   r   r   r   r      s|   „ ñ=óCð 	×Ñð 1ðWð
 $(Ø48ñWàðWð ðWð
 !ðWð 2ðWð ðWð 
òWó ñWr   r   c                ó‚   — t        | t        «      r| j                  «       j                  «       nd}|t        v r|S t
        S )z“Clamp to :data:`VALID_ASPECT_RATIOS`; invalid values coerce to landscape so
    the tool surface forgives agent mistakes instead of rejecting them.Ú )Ú
isinstancer$   ÚstripÚlowerr   r-   )ÚvalueÚvs     r   Úresolve_aspect_ratior5   :   s7   € ô ",¨E´3Ô!7ˆ�‰‹×ÑÔ¸R€AØÔ(Ñ(ˆ1ÐBÔ.BÐBr   c                óè   — t        | t        «      r| g} t        | t        t        f«      sy| D �cg c]4  }t        |t        «      sŒ|j	                  «       sŒ%|j	                  «       ‘Œ6 c}xs dS c c}w )z“Coerce a str or list into a clean list of non-blank strings; ``None`` when
    nothing usable remains so providers treat "no refs" as one sentinel.N)r0   r$   ÚlistÚtupler1   )r3   Úitems     r   Únormalize_reference_imagesr:   A   sW   € ô �%œÔØ�ˆÜ�eœd¤E˜]Ô+ØØ%*ÖU˜T¬j¸¼sÕ.CÈÏ
É
ÍˆD�J‰J�LÒUÒ]ÐY]Ð]ùÒUs   ¯A/ÁA/ÁA/ÚimageÚpng©ÚprefixÚ	extensionc               ó4   — t        j                  d| ||¬«      S )zNDecode base64 image data into ``$HERMES_HOME/cache/images/``; return the path.Úimagesr=   )r
   Úsave_b64)Úb64_datar>   r?   s      r   Úsave_b64_imagerD   K   s   € ä×"Ñ" 8¨X¸fÐPYÔZÐZr   ÚjpgÚwebpÚgif)z	image/pngz
image/jpegz	image/jpgz
image/webpz	image/gifg      N@i  �)r>   ÚtimeoutÚ	max_bytesc               óJ   — t        j                  d| |||dt        dddd¬«      S )z­Download an (often ephemeral) image URL into ``$HERMES_HOME/cache/images/``. Raises on
    network / HTTP / oversize / empty errors so callers can fall back to the bare URL.rA   i   )r<   rE   ÚjpegrF   rG   r<   ÚImagez3Image at {url} returned 0 bytes; refusing to cache.)	r>   rH   rI   Ú
chunk_sizeÚcontent_typesÚurl_extensionsÚdefault_extensionÚlabelÚempty_error)r
   Úsave_urlÚ_URL_IMAGE_CONTENT_TYPES)Úurlr>   rH   rI   s       r   Úsave_url_imagerV   U   s4   € ô
 ×"Ñ"Ø�#˜f¨gÀØÔ,DØ<ÐPUØÐ#Xô	ð r   r   )ÚmodalityÚextrac                óv   — d| |||||dœ}|xs i j                  «       D ]  \  }}	|j                  ||	«       Œ |S )zPUniform success dict; ``extra`` keys are added without overriding standard ones.T)Úsuccessr;   Úmodelr   r   rW   Úprovider)ÚitemsÚ
setdefault)
r;   r[   r   r   r\   rW   rX   ÚpayloadÚkr4   s
             r   Úsuccess_responsera   b   sR   € ð  %°%À6Ø$°(Èñ€Gð ’˜"×#Ñ#Ó%ò !‰ˆˆ1Ø×Ñ˜1˜aÕ ð!à€Nr   Úprovider_errorr/   )Ú
error_typer\   r[   r   r   c           	     ó   — dd| |||||dœS )z$Build a uniform error response dict.FN)rZ   r;   Úerrorrc   r[   r   r   r\   r   )re   rc   r\   r[   r   r   s         r   Úerror_responserf   v   s!   € ð  4°%ÀzØ &¸,ÐT\ñð r   )r3   r%   r"   r$   )r3   r   r"   r&   )rC   r$   r>   r$   r?   r$   r"   r   )
rU   r$   r>   r$   rH   ÚfloatrI   Úintr"   r   )r;   r$   r[   r$   r   r$   r   r$   r\   r$   rW   r$   rX   zOptional[Dict[str, Any]]r"   r#   )re   r$   rc   r$   r\   r$   r[   r$   r   r$   r   r$   r"   r#   )"r*   Ú
__future__r   r+   ÚloggingÚpathlibr   Útypingr   r   r   r   r	   Úagentr
   Úagent.provider_baser   Ú	getLoggerr'   Úloggerr   Ú__annotations__r-   r   r5   r:   rD   rT   rV   ra   rf   Úbase64ÚdatetimeÚuuidr   r   r   ú<module>ru      s  ðò
õ #ã 
Û Ý ß 3Õ 3å  Ý 3à	ˆ×	Ñ	˜8Ó	$€ð (KÐ �_Ó JØ"Ð ôWÐ*ô Wó8Có^ð 4;ÈUõ [ð  e¸%ÈvÐdiñÐ ð  '¸ÐP`ñ
Ø	ð
Øð
Ø16ð
ØJMð
à	ó
ð( Ø&*ñàðð ðð ð	ð
 ðð ðð ðð $ðð óð. 'ØØØØ,ñàðð ðð ð	ð
 ðð ðð ðð óó( Û Ü r   