§
    øžyjm  ã                  ól   — d Z ddlmZ ddlmZmZmZmZ ddlm	Z	 dd„Z
dd
„Zdd„Z G d„ d¦  «        ZdS )u°  Shared FAL.ai SDK plumbing.

Holds the stateless atoms that every FAL-backed tool needs:

* :func:`import_fal_client` â€” lazy import + ``lazy_deps`` integration so
  ``fal_client`` isn't pulled at cold start (it added ~64 ms per CLI
  invocation when imported eagerly).
* :class:`_ManagedFalSyncClient` â€” wrapper that drives a Nous-managed
  fal-queue gateway through the standard ``fal_client.SyncClient``
  primitives.
* :func:`_normalize_fal_queue_url_format`, :func:`_extract_http_status`
  â€” small helpers used by both the managed client wrapper and
  ``_submit_fal_request``.

Stateful pieces (cache globals, ``_managed_fal_client*`` selectors,
``_submit_fal_request``) intentionally stay on
:mod:`tools.image_generation_tool`. That module is the patch target for
existing test suites (``tests/tools/test_image_generation.py``,
``tests/tools/test_managed_media_gateways.py``) and for the
``plugins/image_gen/fal/`` plugin's ``_it`` indirection â€” moving the
caches here would silently defeat ``monkeypatch.setattr(image_tool,
"_managed_fal_client", None)`` because the lookups would go against
``fal_common``'s namespace instead. See the per-rule walkthrough at
issue #26241 for details.
é    )Úannotations)ÚAnyÚDictÚOptionalÚUnion)Ú	urlencodeÚreturnr   c                 óª   — 	 ddl m}   | dd¬¦  «         n9# t          $ r Y n-t          $ r!}t          t	          |¦  «        ¦  «        ‚d}~ww xY wddl}|S )uª  Import ``fal_client`` (via ``lazy_deps`` when available) and return
    the module reference.

    Callers are responsible for caching the result on their own module
    global â€” keeping per-module globals lets tests monkey-patch the
    target module's ``fal_client`` attribute and have the patched value
    stick for that module's call sites.

    Raises :class:`ImportError` if the package is genuinely unavailable.
    r   )Úensurez	image.falF)ÚpromptN)Útools.lazy_depsr   ÚImportErrorÚ	ExceptionÚstrÚ
fal_client)Ú_lazy_ensureÚexcr   s      ú6/home/ragecks/.hermes/hermes-agent/tools/fal_common.pyÚimport_fal_clientr   !   s�   € ð$Ø:Ð:Ð:Ð:Ð:Ð:Øˆ�[¨Ð/Ñ/Ô/Ð/Ð/øÝð ð ð ØˆÝð $ð $ð $Ý�#˜c™(œ(Ñ#Ô#Ð#øøøøð$øøøàÐÐÐØÐs   ‚ –
A¢	A«AÁAÚqueue_run_originr   c                óš   — t          | pd¦  «                             ¦   «                              d¦  «        }|st          d¦  «        ‚|› d�S )NÚ ú/z$Managed FAL queue origin is required)r   ÚstripÚrstripÚ
ValueError)r   Únormalized_origins     r   Ú_normalize_fal_queue_url_formatr   7   sW   € ÝÐ,Ð2°Ñ3Ô3×9Ò9Ñ;Ô;×BÒBÀ3ÑGÔGÐØð AÝÐ?Ñ@Ô@Ð@ØÐ"Ð"Ð"Ð"ó    r   ÚBaseExceptionúOptional[int]c                óÌ   — t          | dd¦  «        }|�(t          |dd¦  «        }t          |t          ¦  «        r|S t          | dd¦  «        }t          |t          ¦  «        r|S dS )uð   Return an HTTP status code from httpx/fal exceptions, else None.

    Defensive across exception shapes â€” httpx.HTTPStatusError exposes
    ``.response.status_code`` while fal_client wrappers may expose
    ``.status_code`` directly.
    ÚresponseNÚstatus_code)ÚgetattrÚ
isinstanceÚint)r   r#   Ústatuss      r   Ú_extract_http_statusr)   >   sp   € õ �s˜J¨Ñ-Ô-€HØÐÝ˜ =°$Ñ7Ô7ˆÝ�f�cÑ"Ô"ð 	ØˆMÝ�S˜-¨Ñ.Ô.€FÝ�&�#ÑÔð ØˆØˆ4r   c                  ó2   — e Zd ZdZdd„Zdd	d	d	d	d	d
œdd„Zd	S )Ú_ManagedFalSyncClientas  Small per-instance wrapper around ``fal_client.SyncClient`` for
    managed queue hosts.

    The wrapper carries its own ``fal_client`` module reference instead
    of reaching into a module global, so callers stay in control of
    which module's ``fal_client`` is in scope (matters for the test
    patches that swap the legacy module's ``fal_client`` attribute).
    r   r   Úkeyr   r   c               ó¨  — t          |dd ¦  «        }|€t          d¦  «        ‚t          |dd ¦  «        }|€t          d¦  «        ‚t          |¦  «        | _         ||¬¦  «        | _        t          | j        dd ¦  «        | _        t          |dd ¦  «        | _        t          |dd ¦  «        | _        t          |d	d ¦  «        | _        t          |d
d ¦  «        | _	        t          |dd ¦  «        | _
        t          |dd ¦  «        | _        | j        €t          d¦  «        ‚| j        �| j        €t          d¦  «        ‚| j        €t          d¦  «        ‚d S )NÚ
SyncClientz>fal_client.SyncClient is required for managed FAL gateway modeÚclientz:fal_client.client is required for managed FAL gateway mode)r,   Ú_clientÚ_maybe_retry_requestÚ_raise_for_statusÚSyncRequestHandleÚadd_hint_headerÚadd_priority_headerÚadd_timeout_headerzFfal_client.SyncClient._client is required for managed FAL gateway modezKfal_client.client request helpers are required for managed FAL gateway modezLfal_client.client.SyncRequestHandle is required for managed FAL gateway mode)r%   ÚRuntimeErrorr   Ú_queue_url_formatÚ_sync_clientÚ_http_clientr1   r2   Ú_request_handle_classÚ_add_hint_headerÚ_add_priority_headerÚ_add_timeout_header)Úselfr   r,   r   Úsync_client_classÚclient_modules         r   Ú__init__z_ManagedFalSyncClient.__init__Z   sg  € Ý# J°¸dÑCÔCÐØÐ$ÝÐ_Ñ`Ô`Ð`å 
¨H°dÑ;Ô;ˆØÐ ÝÐ[Ñ\Ô\Ð\å!@ÐAQÑ!RÔ!RˆÔØ-Ð-°#Ð6Ñ6Ô6ˆÔÝ# DÔ$5°yÀ$ÑGÔGˆÔÝ$+¨MÐ;QÐSWÑ$XÔ$XˆÔ!Ý!(¨Ð8KÈTÑ!RÔ!RˆÔÝ%,¨]Ð<OÐQUÑ%VÔ%VˆÔ"Ý '¨Ð7HÈ$Ñ OÔ OˆÔÝ$+¨MÐ;PÐRVÑ$WÔ$WˆÔ!Ý#*¨=Ð:NÐPTÑ#UÔ#UˆÔ àÔÐ$ÝÐgÑhÔhÐhØÔ$Ð,°Ô0FÐ0NÝÐlÑmÔmÐmØÔ%Ð-ÝÐmÑnÔnÐnð .Ð-r   r   N)ÚpathÚhintÚwebhook_urlÚpriorityÚheadersÚstart_timeoutÚapplicationÚ	argumentsúDict[str, Any]rC   rD   úOptional[str]rE   rF   rG   úOptional[Dict[str, str]]rH   úOptional[Union[int, float]]c               óÂ  — | j         |z   }	|r|	d|                     d¦  «        z   z  }	|�|	dt          d|i¦  «        z   z  }	t          |pi ¦  «        }
|�| j        �|                      ||
¦  «         |�,| j        €t          d¦  «        ‚|                      ||
¦  «         |�,| j        €t          d¦  «        ‚|                      ||
¦  «         |                      | j	        d|	|t          | j        dd¦  «        |
¬	¦  «        }|                      |¦  «         |                     ¦   «         }|                      |d
         |d         |d         |d         | j	        ¬¦  «        S )Nr   ú?Úfal_webhookzGfal_client.client.add_priority_header is required for priority requestszEfal_client.client.add_timeout_header is required for timeout requestsÚPOSTÚdefault_timeoutg      ^@)ÚjsonÚtimeoutrG   Ú
request_idÚresponse_urlÚ
status_urlÚ
cancel_url)rV   rW   rX   rY   r/   )r8   Úlstripr   Údictr<   r=   r7   r>   r1   r:   r%   r9   r2   rT   r;   )r?   rI   rJ   rC   rD   rE   rF   rG   rH   ÚurlÚrequest_headersr#   Údatas                r   Úsubmitz_ManagedFalSyncClient.submitt   s˜  € ð Ô$ {Ñ2ˆØð 	*Ø�3˜Ÿš SÑ)Ô)Ñ)Ñ)ˆCØÐ"Ø�3� M°;Ð#?Ñ@Ô@Ñ@Ñ@ˆCå˜w˜}¨"Ñ-Ô-ˆØÐ Ô 5Ð AØ×!Ò! $¨Ñ8Ô8Ð8ØÐØÔ(Ð0Ý"Ð#lÑmÔmÐmØ×%Ò% h°Ñ@Ô@Ð@ØÐ$ØÔ'Ð/Ý"Ð#jÑkÔkÐkØ×$Ò$ ]°OÑDÔDÐDà×,Ò,ØÔØØØÝ˜DÔ-Ð/@À%ÑHÔHØ#ð -ñ 
ô 
ˆð 	×Ò˜xÑ(Ô(Ð(à�}Š}‰ŒˆØ×)Ò)Ø˜LÔ)Ø˜nÔ-Ø˜LÔ)Ø˜LÔ)ØÔ$ð *ñ 
ô 
ð 	
r   )r   r   r,   r   r   r   )rI   r   rJ   rK   rC   r   rD   rL   rE   rL   rF   r   rG   rM   rH   rN   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__rB   r_   © r   r   r+   r+   P   sh   € € € € € ðð ðoð oð oð oð> Ø"Ø%)ØØ,0Ø59ð/
ð /
ð /
ð /
ð /
ð /
ð /
ð /
r   r+   N)r	   r   )r   r   r	   r   )r   r    r	   r!   )rc   Ú
__future__r   Útypingr   r   r   r   Úurllib.parser   r   r   r)   r+   rd   r   r   ú<module>rh      sÑ   ððð ð4 #Ð "Ð "Ð "Ð "Ð "à -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ø "Ð "Ð "Ð "Ð "Ð "ðð ð ð ð,#ð #ð #ð #ðð ð ð ð$S
ð S
ð S
ð S
ð S
ñ S
ô S
ð S
ð S
ð S
r   