Ë
    ãß²jÓ  ã                  óü   — d Z ddlmZ ddlZddlZddlmZmZmZm	Z	m
Z
  ej                  e«      Zdd„Zdd„Zdd„Zdddddd	œ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd
„Zdd„Zddddddœ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zy)u„  Registry-level browser extension router.

Agent-side half of browser-extension-control: decides, per ``browser_*`` handler
invocation, whether an attached extension controller (via
:mod:`gateway.browser_control_broker`) or the legacy backend executes it.

Routing contract (see ``tests/tools/test_browser_extension_router.py``):
- Feature off â‡’ legacy, broker never touched, ``fallback()`` called exactly once.
- No server-bound identity â‡’ legacy.
- Bound identity â‡’ authoritative extension lane; missing/ambiguous scope,
  disconnect, or capability mismatch fail closed (never jump to another browser).
- Selected controller â‡’ authoritative; its errors propagate, legacy never retried.
- ``args`` is never mutated.

:func:`routed_browser_handler` resolves the flag and broker lazily on every call
so importing this module never pulls in the gateway and config changes apply
without restart.
é    )ÚannotationsN)ÚAnyÚCallableÚDictÚOptionalÚTuplec                 ó8   ‡ — ddl mŠ  t        ˆ fd„dD «       «      S )zF(session_id, principal_id, transport_family) from the session context.r   ©Úget_session_envc              3  ó8   •K  — | ]  } ‰|d «      xs d–— Œ y­w)Ú N© )Ú.0Úkeyr   s     €úC/home/ubuntu/.hermes/hermes-agent/tools/browser_extension_router.pyú	<genexpr>z"_bound_identity.<locals>.<genexpr>!   s(   øè ø€ ò àñ 	˜˜RÓ Ò( DÓ(ñùs   ƒ)ÚHERMES_SESSION_IDÚ HERMES_BROWSER_CONTROL_PRINCIPALÚ'HERMES_BROWSER_CONTROL_TRANSPORT_FAMILY)Úgateway.session_contextr   Útupler
   s   @r   Ú_bound_identityr      s"   ø€ å7äó ð?ôó ð ó    c                ó   — ddl m}  || «      S )Nr   )ÚControllerUnavailable)Úgateway.browser_control_brokerr   )Úmessager   s     r   Ú_controller_unavailabler   (   s   € ÝDá  Ó)Ð)r   c                ó  — 	 ddl m}m}  |«       syt        «       x\  }}}}t	        |«      sy |«       }|j                  |||¬«      }|duxr |j                  || «      duS # t        $ r t        j                  d| d¬«       Y yw xY w)	zÜWhether this request owns one exact controller capable of ``action``.
    Runs during tool-schema assembly inside the request's session context;
    consults the process-local broker directly and fails closed on any gap.r   ©Úbrowser_control_enabledÚget_browser_control_brokerF)Ú
session_idÚprincipal_idÚtransport_familyNz2browser extension availability check failed for %sT)Úexc_info)
r   r!   r"   r   ÚallÚscope_for_sessionÚselectÚ	ExceptionÚloggerÚdebug)	Úactionr!   r"   r#   r$   r%   ÚidentityÚbrokerÚscopes	            r   Úextension_controller_availabler1   .   s˜   € ðßfá&Ô(ØÜ@OÓ@QÐQÑ2ˆ
�LÐ"2°XÜ�8Œ}ØÙ+Ó-ˆØ×(Ñ(°JÈ\Ðl|Ð(Ó}ˆØ˜DÐ ÒM V§]¡]°5¸&Ó%AÈÐ%MÐMøÜò Ü�‰ÐIÈ6Ð\`ˆÔaÙðús   ‚A# ’A# ®4A# Á#!BÂBr   )r#   Útask_idr$   r%   Útool_call_idc               óô  — |r:t        |xs d«      j                  «       rt        |xs d«      j                  «       s |«       S t        ||||¬«      }
 |j                  d
i |
¤Ž}|€5t	        |dd«      }t        |«      r |d
i |
¤Žs |«       S t        d| › �«      ‚|j                  || «      €t        d| › �«      ‚|j                  || ||	¬«      }t        |t         «      r|S t        j                  |d¬	«      S )a{  Route one browser action through the extension-control broker.

    ``broker`` exposes ``scope_for_session(**identity)``, ``select(scope, cap)``
    and ``dispatch(scope, *, action, arguments, tool_call_id)``. ``fallback`` is
    called exactly once when the feature is off or no server-bound identity
    exists; once a controller is selected its result/exception is final.
    r   )r#   r2   r$   r%   NÚlane_registeredz)bound browser controller unavailable for z(bound browser controller cannot execute )r-   Ú	argumentsr3   F)Úensure_asciir   )ÚstrÚstripÚdictr(   ÚgetattrÚcallabler   r)   ÚdispatchÚ
isinstanceÚjsonÚdumps)r-   ÚargsÚfallbackr/   Úenabledr#   r2   r$   r%   r3   r.   r0   Ú
lane_boundÚresults                 r   Úroute_browser_toolrF   B   s  € ñ œ#˜lÒ0¨bÓ1×7Ñ7Ô9ÄÐEUÒE[ÐY[ÓA\×AbÑAbÔAdÙ‹zÐä˜z°7ÈÐhxÔy€HØ$ˆF×$Ñ$Ñ0 xÑ0€EØ€}ô ˜VÐ%6¸Ó=ˆ
Ü�JÔ©
Ñ(>°XÒ(>Ù“:ÐÜ%Ð(QÐRXÐQYÐ&ZÓ[Ð[à‡}�}�U˜FÓ#Ð+Ü%Ð(PÐQWÐPXÐ&YÓZÐZð
 �_‰_˜U¨6¸TÐP\ˆ_Ó]€FÜ ¬Ô,ˆ6ÐX´$·*±*¸VÐRWÔ2XÐXr   c                 óV   — 	 ddl m}  | j                  «       xs dS # t        $ r Y yw xY w)zEActive tool_call_id bound by the agent executor, or ``""`` when none.r   ©Ú_approval_tool_call_idr   )Útools.approval_contextrI   Úgetr*   rH   s    r   Úcurrent_tool_call_idrL   f   s0   € ðÝAà%×)Ñ)Ó+Ò1¨rÐ1øÜò Ùðús   ‚ œ	(§()r2   r#   r$   r%   r3   c               óL  — 	 ddl m}m}	  |«       s |«       S 	 t        «       \  }}}t        | || |	«       d|xs |||xs ||xs ||€t        «       ¬«
      S |¬«
      S # t        $ r'}
t        j                  d|
«        |«       cY d}
~
S d}
~
ww xY w# t        $ r	 dx}x}}Y Œ{w xY w)u�   Lazy registry-handler route wrapper for ``browser_*`` tools.
    Feature off (or gateway unimportable) â‡’ the legacy handler runs unchanged.r   r    z?browser extension router unavailable (%s); using legacy backendNT)rB   r/   rC   r#   r2   r$   r%   r3   )	r   r!   r"   r*   r+   r,   r   rF   rL   )r-   rA   rB   r2   r#   r$   r%   r3   r!   r"   ÚexcÚenv_sessionÚenv_principalÚenv_transports                 r   Úrouted_browser_handlerrR   p   sÍ   € ðßfñ #Ô$Ù‹zÐð;Ü4CÓ4EÑ1ˆ�] Mô Ø�˜xÑ0JÓ0LÐVZØÒ, °gÈLÒLiÐ\iØ)Ò:¨]Ø/;Ð/CÔ)Ó+ô	ð ð JVô	ð øô ò Ü�‰ÐVÐX[Ô\Ù‹zÕûðûô ò ;Ø6:Ð:ˆÐ:�m¢mð;ús.   ‚A ™B Á	BÁ'B	ÂBÂ	BÂB#Â"B#)Úreturnz2Tuple[Optional[str], Optional[str], Optional[str]])r   r8   rS   r*   )r-   r8   rS   Úbool)r-   r8   rA   úDict[str, Any]rB   úCallable[[], Any]r/   r   rC   rT   r#   úOptional[str]r2   rW   r$   rW   r%   rW   r3   rW   rS   r   )rS   r8   )r-   r8   rA   rU   rB   rV   r2   rW   r#   rW   r$   rW   r%   rW   r3   rW   rS   r   )Ú__doc__Ú
__future__r   r?   ÚloggingÚtypingr   r   r   r   r   Ú	getLoggerÚ__name__r+   r   r   r1   rF   rL   rR   r   r   r   ú<module>r^      s&  ðñõ& #ã Û ß 7Õ 7à	ˆ×	Ñ	˜8Ó	$€óó*óð, !%¸tÐcgØ&*È"ñ!YØð!YØ%ð!YØ4Eð!YØORð!YØ]að!Yàð!Yà/<ð!YàS`ð!Yð $ð!Yð ;Hð!Yð 	ó	!YóHð aeØ $ÀDØ&*È$ñØðØ%ðØ4EðØP]ðàðà4Aðð $ðð ;Hðð 	ô	r   