+
    lHàjTÐ  ã                   óº  a € R™ tz0 t R t^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIHtHtHtHtHtHt ^ RIHtHt ^ RIHtHtHt ^ RIH t  ]PB                  ! ]"4      t#Rt$Rt%]	PL                  ! R	4      t'R
t(Rt)Rt*Rt+Rt,Rt-^t.Rt/Rt0]	PL                  ! R4      t1]	PL                  ! R]	Pd                  4      t3]	PL                  ! R]	Pd                  4      t4Ršt5R›R R llt6R R lt7R›R R llt8R R lt9R R lt:R  R! lt;R" R# lt< ! R$ R%]4      t=R& R' lt>R( R) lt?R* R+ lt@R, R- ltAR. R/ ltBR0 R1 ltCR2 R3 ltDR4 R5 ltER6 R7 ltFR8 R9 ltGR: R; ltHR< R= ltIR> R? ltJR@ RA ltKRB RC ltLRD RE ltMRF RG ltNRœRI RJ lltORK RL ltPRM RN ltQRœRO RP lltRRQ RR ltSRœRS RT lltTRœRU RV lltURœRW RX lltVRY RZ ltWR[ R\ ltXR�R] R^ lltYR_ R` ltZRa Rb lt[Rct\Rd Re lt]Rf t^/ t_] ^ k ]PÀ                  ! 4       ta]PÄ                  ! ]7RgRh^ Ri4      tc/ td] ^k / te] ^k ]f! 4       tg] ^k RžRj Rk llthRl Rm ltiRn Ro ltjRp Rq ltkRr Rs ltlRt Ru ltmR]-RRH3Rv Rw lltnRxtoRytpRztqR{trR|tsR} R~ lttR R€ ltuR�R‚Rƒ]o]s,           R„,           R…R†R‡RˆR‰R†RŠRƒR‹/RŒR†RŠRƒR�/RŽR†R�R�]-RƒR‘]- R’]/ R“2//R”R‰.//tv^ R•IwHxtx ]xPò                  ! R‚R]vR– ]G]uR—R˜7       R# )Ÿz»Use the Browser Use CLI 3.0 (https://browser-use.com) for browser automation

When browser.backend is "browser-use", the model gets ``browser_exec`` tool
instead of default browser tools
N)ÚPath)ÚAnyÚCallableÚDictÚListÚ
NamedTupleÚOptional)Úget_hermes_homeÚhermes_home_key)Ú
daemon_envÚdaemon_identityÚnamespace_harness_dirs)Úis_truthy_valueúbrowser-useÚoffz ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$Ú_HERMES_BU_PRIVATE_BROWSERÚ_HERMES_BU_BOT_DESKTOP_BROWSERÚ _HERMES_BU_REAL_PROFILE_FALLBACKÚ_HERMES_BU_LOCAL_FALLBACKaù  # hermes: pin this named session to its own tab (once per daemon process)
def _hermes_ensure_own_tab():
    import os as _os, tempfile as _tf
    _name = _os.environ.get("BU_NAME", "default")
    try:
        # Key the marker by the daemon's pid so a daemon restart (which
        # re-attaches to the first shared page) re-pins automatically,
        # while agent-driven tab switches mid-session are left alone.
        from browser_harness import _ipc as _bipc
        _dpid = _bipc.pid_path(_name).read_text().strip() or "0"
    except Exception:
        _dpid = "0"
    _uid = _os.getuid() if hasattr(_os, "getuid") else 0
    _marker = _os.path.join(
        _tf.gettempdir(), "hermes-bu-owntab-%s-%s-%s" % (_uid, _name, _dpid)
    )
    if _os.path.exists(_marker):
        return
    try:
        # Force a fresh target: new_tab() would REUSE a blank current tab,
        # which is exactly the tab a sibling daemon may also hold.
        _tid = cdp("Target.createTarget", url="about:blank").get("targetId")
        if _tid:
            switch_tab(_tid)
    except Exception:
        pass  # best-effort: worst case is pre-fix behavior
    try:
        open(_marker, "w").close()
    except OSError:
        pass
_hermes_ensure_own_tab()
del _hermes_ensure_own_tab
i,  i  i   z[^A-Za-z0-9._-]+z4((?:[A-Za-z]:[\\/]|/)[^\s\"']+?\.(?:png|jpe?g|webp))zhttps?://[^\s'\"\\)]+Ú c                ób   € V ^8„  d   QhR\         . \        3,          R\        R\        R\        /# )é   ÚfnÚdefaultÚ
log_prefixÚreturn)r   r   Ústr)Úformats   "Ú:/home/ubuntu/.hermes/hermes-agent/tools/browser_use_cli.pyÚ__annotate__r   b   s1   € ÷ ñ Œx˜œC˜Õ ð ¬3ð ¼Cð Ìñ ó    c                ó€   €  V ! 4       #   \          d*   pT'       d   \        P                  RY#4        Rp?T# Rp?ii ; i)zT``fn()``, or ``default`` on any exception (debug-logged when ``log_prefix`` is set).z%s: %sN)Ú	ExceptionÚloggerÚdebug)r   r   r   Úes   &&& r   Ú_quietr&   b   s5   € ð2Ù‹tˆøÜô 2ßÜ�L‰L˜ :Ô1ûØ€Nûð2ús   ‚	 ‰=”8¸=c          
      óT   € V ^8„  d   QhR\         R\         R\        R\         R\        /# )r   ÚmoduleÚnamer   r   r   )r   r   )r   s   "r   r   r   l   s6   € ÷ añ a”sð a¤#ð a´ð aÄð aÌñ ar    c                ó(   a a€ \        V V3R lW#4      # )z•Call ``module.name()`` resolved at call time (tests stub the module / patch the
attribute); on any failure log ``log_prefix`` and return ``default``.c                  óN   <€ \        \        P                  ! S 4      S4      ! 4       # ©N)ÚgetattrÚ	importlibÚimport_module)r(   r)   s   €€r   Ú<lambda>Ú_lazy_call.<locals>.<lambda>o   s   ø€ œ'¤)×"9Ò"9¸&Ó"AÀ4ÔHÔJr    )r&   )r(   r)   r   r   s   ff&&r   Ú
_lazy_callr2   l   s   ù€ ô ÕJÈGÓ`Ð`r    c                ó0   € V ^8„  d   QhR\         R\        /# )r   Úcontextr   )r   Úbool)r   s   "r   r   r   r   s   € ÷ tñ tœSð t¬$ñ tr    c                 ó$   € \        R RRRV  24      # )ztools.browser_camofoxÚis_camofox_modeFzCamofox activity check failed©r2   )r4   s   &r   Ú_camofox_activer9   r   s   € ÜÐ-Ð/@À%ÐKhÐipÐhqÐIrÓsÐsr    c                ó$   € V ^8„  d   QhR\         /# ©r   r   ©r5   )r   s   "r   r   r   v   s   € ÷ tñ t¤ñ tr    c                  ó   € \        R RRR4      # )ztools.browser_tool_cloudÚ_use_real_profileFz"real-profile consent lookup failedr8   © r    r   Ú_real_profile_consentedr@   v   s   € ÜÐ0Ð2EÀuÐNrÓsÐsr    c                ó4   € V ^8„  d   QhR\         R\        RR/# )r   ÚenvÚcdpr   N©Údictr   )r   s   "r   r   r   z   s&   € ÷ Xñ X”dð X¤ð X¨ñ Xr    c                óF   € YVP                  R4      '       d   R&   R# R&   R# )uM   Export a CDP endpoint under the BU_CDP_* contract (http(s) â†’ URL, else WS).Ú
BU_CDP_URLÚ	BU_CDP_WSN)zhttp://zhttps://)Ú
startswith)rB   rC   s   &&r   Ú_set_cdp_envrJ   z   s   € àTW˜Ÿ™Ð'>×?Ò?ˆÓQÀ[ÓQr    c                ó0   € V ^8„  d   QhR\         R\        /# )r   rB   r   ©rE   r5   )r   s   "r   r   r      s   € ÷ ?ñ ?”dð ?œtñ ?r    c                 óh   € \        V P                  R 4      ;'       g    V P                  R4      4      # )rH   rG   )r5   Úget)rB   s   &r   Ú_has_cdp_envrO      s'   € Ü�—‘˜Ó$×=Ð=¨¯©°Ó(=Ó>Ð>r    c                ó¾   € V ^8„  d   QhR\         R\        \        .\        3,          R\        R\        \        .\        3,          R\        R\
        \        ,          /# )r   rB   Úget_session_infoÚ	cache_keyÚfail_msgÚ
no_cdp_msgr   )rE   r   r   r   r"   r   )r   s   "r   r   r   ƒ   sW   € ÷ 
ñ 
œTð 
´X¼s¸eÄS¸jÕ5Ið 
ÔVYð 
Ü"*¬I¨;¼Ð+;Õ"<ð
ÜJMð
ÜRZÔ[^ÕR_ñ
r    c                óÚ   €  \        V! V4      ;'       g    / P                  R4      ;'       g    R4      pT'       g   T# \        Y4       R#   \         d   pT! T4      u Rp?# Rp?ii ; i)z_Export the CDP endpoint from ``get_session_info(cache_key)``; error string on failure / no CDP.Úcdp_urlr   N)r   rN   r"   rJ   )rB   rQ   rR   rS   rT   rC   r%   s   &&&&&  r   Ú_export_session_cdprW   ƒ   sd   € ðÜÑ# IÓ.×4Ð4°"×9Ñ9¸)ÓD×JÐJÈÓKˆ÷ ØÐÜ�ÔÙøô ô Ù˜‹{Õûðús'   ‚A –A ¯A ÁA*ÁA%ÁA*Á%A*c                   ó0   a € ] tR t^�t o RtV 3R ltRtV tR# )Ú_CodeUrlVerdictzRWhat one pass over a code blob's URL literals decided (see ``_code_url_verdict``).c                óB   <€ V ^8„  d   Qh/ S[ S[,          ;R&   S[;R&   # )r   ÚblockedÚlocal_sidecar©r   r   r5   )r   Ú__classdict__s   "€r   r   Ú_CodeUrlVerdict.__annotate__�   s#   ø‡ ‚ ñ ‘c�]Ññ ñ Ñò	 r    r?   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__)r^   s   @r   rY   rY   �   s   ø‡ € Ù\÷ ƒ r    rY   c                ó0   € V ^8„  d   QhR\         R\        /# )r   Úcoder   )r   rY   )r   s   "r   r   r   —   s   € ÷ 0ñ 0œCð 0¤Oñ 0r    c                ó   € ^ RI HpHp Rp\        P	                  T ;'       g    R4       FF  pV! V4      pT;'       g    TpV! WER7      pV'       g   K*  \        VP                  RR4      V4      u # 	  \        RV4      # )aQ  One pass over the code's URL literals: the blocking error, if any, and whether the call must run on
the hybrid LOCAL sidecar. Each URL's routing predicate is evaluated ONCE and feeds both answers: it
resolves DNS unmemoised, so a rebinding host evaluated twice could relax the private-address floor and
still route to the cloud provider.)Ú_hybrid_routes_locallyÚevaluate_url_safetyFr   )Ú
auto_localÚerrorzBlocked: unsafe URLN)Útools.browser_toolrk   rl   Ú_URL_REÚfindallrY   rN   )ri   rk   rl   r\   ÚurlÚroutes_localÚerrs   &      r   Ú_code_url_verdictru   —   st   € ÷
 OØ€MÜ�‰˜tŸz˜z rÖ*ˆÙ-¨cÓ2ˆØ%×5Ð5¨ˆÙ! #Ô?ˆß‰3Ü" 3§7¡7¨7Ð4IÓ#JÈMÓZÒZñ +ô ˜4 Ó/Ð/r    c                ó$   € V ^8„  d   QhR\         /# r;   ©rE   )r   s   "r   r   r   §   s   € ÷ ñ œdñ r    c                  ó  € ^ RI Hp  V ! 4       pVP                  RR4       \        4       pV'       d   W!R&   MVP                  RR4       \	        VP                  RR4      4      VR&   VP                  RR4       \        V\        4       4       V# )	é    )Ú_build_browser_envÚ
PYTHONHOMENÚ
PYTHONPATHÚPATHr   ÚANONYMIZED_TELEMETRYÚfalse)	ro   rz   ÚpopÚ_harness_site_dirÚ_floor_subprocess_pathrN   Ú
setdefaultr   Ú_served_profile_tag)rz   rB   Úsite_dirs      r   Ú_base_subprocess_envr†   §   sy   € Ý5Ù
Ó
€Cð
 ‡G�GˆL˜$ÔÜ Ó"€HßØ$ˆLÒà�‰�˜dÔ#Ü(¨¯©°¸Ó)<Ó=€Cˆ�KØ‡N�NÐ)¨7Ô3Ü˜3Ô 3Ó 5Ô6Ø€Jr    c                ó0   € V ^8„  d   QhR\         R\         /# )r   Úpathr   ©r   )r   s   "r   r   r   º   s   € ÷ kñ k¤ð k¬ñ kr    c           
     ó^  € \         P                  R8X  d   V # \        P                  ! \        4      ;_uu_ 4        ^ RIHp T! T ;'       g    R4      uuRRR4       #   + '       g   i     M; iT ;'       g    RP                  \         P                  4       Uu. uF  q"'       g   K  TNK  	  Mu upi pp\         P                  P                  T\         Uu. uF=  qD\        T4      9  g   K  \         P                  P                  T4      '       g   K;  TNK?  	  Mu upi up,           4      # )zÑKeep system commands reachable from profile workers with a minimal PATH.

Browser subprocesses may launch shell helpers; version-manager-only paths
omit /usr/bin. Reuse the shared browser PATH floor on POSIX.
Únt)Ú_merge_browser_pathr   N)Úosr)   Ú
contextlibÚsuppressr"   Útools.browser_tool_installrŒ   ÚsplitÚpathsepÚjoinÚ_FHS_BIN_DIRSÚsetrˆ   Úisdir)rˆ   rŒ   ÚpÚpartsÚds   &    r   r‚   r‚   º   sÂ   € ô 
‡w�w�$„ØˆÜ	×	Ò	œY×	'Õ	'ÝBÙ" 4§: :¨2Ó.÷ 
(×	'×	'Ò	'úð Ÿ˜ ×*Ñ*¬2¯:©:Ô6Ó<Ñ6�1»!�QˆQÒ6ùÒ<€EÐ<Ü�:‰:�?‰?˜5­}Ó#i©}¨!ÌÈUËÑ@S¤AÔXZ×X_ÑX_×XeÑXeÐfg×Xh§A Aª}ùÔ#iÕiÓjÐjs)   ºAÁA-	Â	B0Â)B0ÃD
Ã/"D
ÄD
c                ó$   € V ^8„  d   QhR\         /# r;   rw   )r   s   "r   r   r   É   s   € ÷ ñ œ4ñ r    c                 óÈ   €  ^ RI Hp Hp V ! V! 4       R/ R7      p\        V\        4      '       d   V# / #   \
         d#   p\        P                  RT4       / u Rp?# Rp?ii ; i)z=Return the ``browser:`` config section, or {} on any failure.)Úcfg_getÚread_raw_configÚbrowser©r   z)Could not read browser config section: %sN)Úhermes_cli.configrœ   r�   Ú
isinstancerE   r"   r#   r$   )rœ   r�   Úcfgr%   s       r   Ú_read_browser_cfgr£   É   sV   € ðß>Ù‘oÓ'¨¸BÔ?ˆÜ  ¤d×+Ò+ˆsÐ3°Ð3øÜô Ü�‰Ð@À!ÔDØ�	ûðús   ‚/4 ²4 ´A!¿AÁA!ÁA!c                ó0   € V ^8„  d   QhR\         R\        /# ©r   Úbrowser_cfgr   rL   )r   s   "r   r   r   Ô   s   € ÷ añ aœdð a¤tñ ar    c                ó  € \        V P                  R4      RR7      '       d   R#  ^ RIHp \        T P                  R4      ;'       g    R4      P                  4       P                  4       T8H  #   \         d     R# i ; i)uO  True when the browser section selects the Nous Tool Gateway â€” by the current ``hermes tools``
picker row (``cloud_provider: nous``) or the pre-picker ``use_gateway: true`` flag. Reading only
the legacy flag missed every picker-configured gateway, and the direct-API branch it fell into
holds no credentials in managed mode (#108310).Úuse_gatewayFrŸ   T)ÚNOUS_MANAGED_PROVIDERÚcloud_providerr   )r   rN   Útools.tool_backend_helpersr©   r"   r   ÚstripÚlower)r¦   r©   s   & r   Ú_use_gatewayr®   Ô   sp   € ô
 �{—‘ }Ó5¸u×EÓEÙðÝDô ˆ{�‰Ð/Ó0×6Ð6°BÓ7×=Ñ=Ó?×EÑEÓGÐK`Ñ`Ð`øô ô Úðús   ¦A/ Á/A>Á=A>c                ó$   € V ^8„  d   QhR\         /# r;   r‰   )r   s   "r   r   r   â   s   € ÷ sñ sœSñ sr    c                 óÞ   € \        4       P                  R4      p \        V \        4      '       d   V RJ d   \        # R# \        T ;'       g    R4      P                  4       P                  4       # )u—   Configured browser backend key ("" = unset â†’ default). YAML 1.1 parses an
unquoted ``off`` as False â€” that must mean BACKEND_DISABLED, not "unset".ÚbackendFr   )r£   rN   r¡   r5   ÚBACKEND_DISABLEDr   r¬   r­   )Úraws    r   Úget_browser_backendr´   â   s\   € ô Ó
×
!Ñ
! )Ó
,€CÜ9CÀCÌ×9NÒ9N  u£ÔÐr°"ÐrÔTWÐX[×XaÐXaÐ_aÓTb×ThÑThÓTj×TpÑTpÓTrÐrr    c                ó(   € V ^8„  d   QhR\         RR/# )r   Úenabledr   Nr<   )r   s   "r   r   r   é   s   € ÷  ñ  ¤$ð  ¨4ñ  r    c                óœ   € ^ RI HpHp ^ RIHp V! 4       pV '       d   \
        M\        VP                  R/ 4      R&   V! V4       V! 4        R# )zÎ``/browser use [off]`` on every surface: persist ``browser.backend`` for the current profile and drop
cached tool availability. A live agent keeps its tools (prompt cache); the next one built gets the swap.)Úload_configÚsave_config)Úinvalidate_check_fn_cacherž   r±   N)r    r¸   r¹   Útools.registryrº   Ú_BACKEND_KEYr²   rƒ   )r¶   r¸   r¹   rº   Úconfigs   &    r   Úset_browser_use_moder¾   é   s;   € ÷ ;Ý8Ù‹]€FßBIµ,ÔO_€F×Ñ�i Ó$ YÑ/Ù�ÔÙÖr    c                ó0   € V ^8„  d   QhR\         R\        /# r¥   rL   )r   s   "r   r   r   ô   s   € ÷ 	&ñ 	&´Dð 	&¼Tñ 	&r    c                óJ  € \        V \        4      '       d   V P                  R4      '       d   R# \        V P                  R4      ;'       g    R4      P	                  4       P                  4       pVR9  g#   \        V 4      '       g   \        R4      '       d   R# \        4       # )zæTrue for pre-CLI direct-API Browser Use cloud configs. An explicit backend or
a non-Browser-Use cloud_provider wins; Camofox is selected via env var, not
cloud_provider, so a Camofox user with a stray BROWSER_USE_API_KEY keeps it.r±   Frª   r   z during migration>   r   r   )	r¡   rE   rN   r   r¬   r­   r®   r9   Ú_browser_use_api_key_set)r¦   Úproviders   & r   Ú"is_legacy_browser_use_cloud_configrÃ   ô   sz   € ô �k¤4×(Ò(¨K¯O©O¸I×,FÒ,FÙÜ�;—?‘?Ð#3Ó4×:Ð:¸Ó;×AÑAÓC×IÑIÓK€HØÐ*Ô*¬l¸;×.GÒ.GÌ?Ð[n×KoÒKoÙÜ#Ó%Ð%r    c                ó$   € V ^8„  d   QhR\         /# r;   r<   )r   s   "r   r   r      s   € ÷ 7ñ 7¤$ñ 7r    c                 ó2   € ^ RI Hp  \        V ! RR4      4      # )z³BROWSER_USE_API_KEY for the served profile: the only credential Hermes autospawns BU cloud with.
Profile-scoped so a multiplexed secondary never inherits the default's cloud mode.©Ú
get_secretÚBROWSER_USE_API_KEYr   )Úagent.secret_scoperÇ   r5   rÆ   s    r   rÁ   rÁ      s   € õ .Ü‘
Ð0°"Ó5Ó6Ð6r    c                ó$   € V ^8„  d   QhR\         /# r;   r<   )r   s   "r   r   r     s   € ÷ Hñ H¤ñ Hr    c                 óª   € \        4       '       d   R# \        4       p V '       d
   V \        8H  # \        \	        4       4      ;'       g    \        4       RJ# )ar  True when the Browser Use CLI replaces the built-in browser stack. Browser Use mode is the DEFAULT:
unset ``browser.backend`` ("") enables it whenever browser-harness is importable (a core dependency);
``browser.backend: off`` keeps the built-in browser_* tools. Camofox always falls back to the built-in
tools (Firefox, custom HTTP API, no CDP surface for the harness).FN)r9   r´   r¼   rÃ   r£   Ú	_find_cli)r±   s    r   Úis_browser_use_cli_moderÍ     sZ   € ô
 ×ÒÙÜ!Ó#€Gß&-ˆ7”lÑ"ð  HÔ4VÔWhÓWjÓ4k÷  5Gð  5GÔoxÓozð  CGð  pGð  Hr    c                ó:   € V ^8„  d   QhR\         \        ,          /# r;   ©r   r   )r   s   "r   r   r     s   € ÷ ñ ¤(¬3¥-ñ r    c                 ó(  €  \        4       '       g   \        4       '       g   \        4       e   R# \        \	        4       4      R,          R,          p \
        P
                  ! 4       p\        P                  ! \        4      ;_uu_ 4        ^ WP                  4       P                  ,
          u;8:  d   R8  d   M M RRR4       R# RRR4       \        P                  ! \        4      ;_uu_ 4        V P                  P                  RRR7       V P                  4        \        P                  ! WV34       RRR4       R#   + '       g   i     L‚; i  + '       g   i     R# ; i  \          d"   p\"        P%                  RT4        Rp?R# Rp?ii ; i)	z­One-line notice when ``browser.backend`` is unset but the CLI is not runnable, so
the session fell back to the built-in tools. Rate-limited to once per 24h via a stamp file.NÚcachez.browser_use_default_noticeT©ÚparentsÚexist_okuÂ   browser-harness is missing from Hermes's Python environment â€” using the built-in browser tools. Run `hermes update` to re-sync it, or set `browser.backend: off` in config.yaml to silence this.z'browser-use downgrade notice failed: %si€Q )r´   r9   rÌ   r   r	   ÚtimerŽ   r�   ÚOSErrorÚstatÚst_mtimeÚparentÚmkdirÚtouchr�   Úutimer"   r#   r$   )ÚstampÚnowr%   s      r   Údefault_downgrade_noticerß     s  € ðÜ× Ò ¤O×$5Ò$5¼»Ò9PÙÜ”_Ó&Ó'¨'Õ1Ð4QÕQˆÜ�iŠi‹kˆÜ× Ò ¤×)Õ)Ø�CŸ*™*›,×/Ñ/Õ/Ö;°)×;Ø÷ *×)Ñ)ô × Ò ¤×)Õ)Ø�L‰L×Ñ t°dÐÔ;Ø�K‰KŒMÜ�HŠH�U #˜JÔ'÷ *ñs÷ *×)ú÷ *Ö)ñsûäô Ü�‰Ð>ÀÔBÝûðúsZ   ‚,E% °AE% Â2D>Â:E% Ã*E% Ã.AEÄ4E% Ä>E	Å	E% ÅE"	ÅE% Å"E% Å%FÅ0FÆFc                ó:   € V ^8„  d   QhR\         \        ,          /# r;   rÏ   )r   s   "r   r   r   (  s   € ÷ :ñ :œ8¤C�=ñ :r    c                 óð   € \         P                  P                  R4      p V e   V P                  '       g   R# \	        \        V P                  4      P                  4       P                  P                  4      # )zLThe site dir Hermes's interpreter imports ``browser_harness`` from, or None.Úbrowser_harnessN)r.   ÚutilÚ	find_specÚoriginr   r   ÚresolverÙ   )Úspecs    r   r�   r�   (  sP   € ä�>‰>×#Ñ#Ð$5Ó6€DØ‚|˜4Ÿ;Ÿ;˜;ÙÜŒt�D—K‘KÓ ×(Ñ(Ó*×1Ñ1×8Ñ8Ó9Ð9r    c                óP   € V ^8„  d   QhR\         \        \        ,          ,          /# r;   )r   Úlistr   )r   s   "r   r   r   0  s   € ÷ 9ñ 9”8œD¤�IÕ&ñ 9r    c                 óD   € \        4       f   R# \        P                  RR.# )z¬The Browser Use CLI's engine (browser-harness) is a core dependency of Hermes's own venv,
so every install, the Desktop bundle included, runs it on the current interpreter.Nz-mzbrowser_harness.run)r�   ÚsysÚ
executabler?   r    r   rÌ   rÌ   0  s"   € ô ÓÒ"ÙÜ�N‰N˜DÐ"7Ð8Ð8r    c                ó\   € V ^8„  d   QhR\         \        ,          R\         \        ,          /# )r   Útask_idr   rÏ   )r   s   "r   r   r   8  s"   € ÷ ñ œH¤S�Mð ¬h´s­mñ r    c                óè  € \         P                  P                  R4      '       d   \         P                  R,          #  \        P	                  R\        T ;'       g    R4      4      R,          ;'       g    Rp\        \        4       4      R,          R,          R,          V,          pVP                  RRR	7       \        V4      #   \         d"   p\        P                  R
T4        Rp?R# Rp?ii ; i)zCStable per-task scratch dir that persists across browser_exec callsÚBH_AGENT_WORKSPACEÚ_r   :NéP   NrÑ   r   Ú	workspaceTrÒ   z&browser_exec workspace unavailable: %sN)r�   ÚenvironrN   Ú_TASK_ID_SAFE_REÚsubr   r   r	   rÚ   r"   r#   r$   )rî   Úsaferˆ   r%   s   &   r   Ú_workspace_dirrø   8  sµ   € ä	‡z�z‡~�~Ð*×+Ò+Ü�z‰zÐ.Õ/Ð/ðÜ×#Ñ# C¬¨W×-AÐ-A¸	Ó)BÓCÀCÕH×UÐUÈIˆÜ”OÓ%Ó&¨Õ0°=Õ@À;ÕNÐQUÕUˆØ�
‰
˜4¨$ˆ
Ô/Ü�4‹yÐøÜô Ü�‰Ð=¸qÔAÝûðús$   ¾C ÁC Á5AC ÃC1ÃC,Ã,C1c                óR   € V ^8„  d   QhR\         R\        R\        \         ,          /# )r   ÚstdoutÚsincer   )r   Úfloatr   )r   s   "r   r   r   F  s%   € ÷ 	ñ 	œSð 	¬ð 	´8¼Cµ=ñ 	r    c                ó6  € \        \        P                  T ;'       g    R4      4       FZ  p \        P                  P                  V4      '       d2   \        P                  P                  V4      V^,
          8¼  d   Vu # KZ  K\  	  R#   \         d     Kn  i ; i)zjLast screenshot path printed during this exec that exists and was written after
the exec started, or None.r   N)ÚreversedÚ_IMAGE_PATH_RErq   r�   rˆ   ÚisfileÚgetmtimerÖ   )rú   rû   rˆ   s   && r   Ú_find_screenshotr  F  s}   € ô œ×/Ñ/°·°¸"Ó=Ö>ˆð	Ü�w‰w�~‰~˜d×#Ò#¬¯©×(8Ñ(8¸Ó(>À%È!Å)Ô(KØ’ñ )LÑ#ñ ?ñ øô ô 	Úð	ús   ­AB	Â	BÂBc          	      ó–   € V ^8„  d   QhR\         \        \        3,          R\        R\        \         \        \        3,          ,          /# )r   Úresultrˆ   r   )rE   r   r   r   )r   s   "r   r   r   R  s9   € ÷ ñ ¤d¬3´¨8¥nð ¼Cð ÄHÌTÔRUÔWZÐRZÍ^ÕD\ñ r    c                óL  €  ^ RI HpHpHp ^ RIHp V! 4       '       g   R# V! \        V4      RV! 4       VRR7      p\        P                  ! V RR7      pVR	,           pR
RRVRRVRR/RRRRV/RRRRV//./#   \         d"   p	\        P                  RT	4        Rp	?	R# Rp	?	ii ; i)z?Build a multimodal tool result attaching path for vision models)Ú_EMBED_MAX_DIMENSIONÚ_resize_image_for_visionÚ#_should_use_native_vision_fast_path)Úresolve_embed_target_bytesNz	image/pngT)Ú	mime_typeÚmax_base64_bytesÚmax_dimensionÚ
force_jpegF)Úensure_asciiuS   

The screenshot from this call is attached â€” inspect it with your native vision.Ú_multimodalÚtext_summaryÚmetaÚscreenshot_pathÚnative_visionÚcontentÚtypeÚtextÚ	image_urlrr   z:Native screenshot attach failed (falling back to text): %s)Útools.vision_toolsr  r  r  Ú!tools.vision_tools_history_budgetr	  r   ÚjsonÚdumpsr"   r#   r$   )
r  rˆ   r  r  r  r	  Údata_urlr  Úattachedr%   s
   &&        r   Ú_native_screenshot_resultr  R  sÍ   € ð÷	gñ 	gåPÙ2×4Ò4Ùñ ,¬D°«JÀ+Ù=WÓ=YØ:NÐ[_ôaˆô �zŠz˜&¨uÔ5ˆØÐqÕqˆØ˜t ^°T¸6ÐDUÐW[Ð]lÐnrÐCsØ˜V V¨V°XÐ>ÀÈÐVaÐdiÐksÐctÐ@uÐvðxð 	xøäô Ü�‰ÐQÐSTÔUÝûðús   ‚A7 ¡AA7 Á7B#ÂBÂB#c                ó$   € V ^8„  d   QhR\         /# r;   r‰   )r   s   "r   r   r   h  s   € ÷ Kñ KœSñ Kr    c                 ó6   € ^ RI Hp Hp V ! 4       f   R# V! 4       # )u   ``""`` outside a served-profile scope (every legacy key stays byte-identical); under a
multiplexed turn, the routed profile's home key â€” one profile's browser must never be handed
to another that happens to use the same session name or task id (#110032).©Úget_hermes_home_overrider
   r   )Úhermes_constantsr"  r
   r!  s     r   r„   r„   h  s   € ÷ KÙ)Ó+Ò3ˆ2ÐJ¹Ó9JÐJr    Fc                ó^   € V ^8„  d   QhR\         \        ,          R\        R\        R\        /# )r   rî   Úsession_nameÚsidecarr   r]   )r   s   "r   r   r   p  s.   € ÷ /ñ /¤¬¥ð /¼Sð /ÔPTð /Ôadñ /r    c                óˆ   € V'       d   RV 2MT ;'       g    Rp\        4       pV'       d   V RV 2MTpV'       d   V R2# T# )zùSession-cache key for a backend browser: named sessions get their own; served profiles get their own.
``sidecar`` appends the hybrid ``::local`` suffix, which makes ``_get_session_info`` build local Chromium
even when a cloud provider is configured.z	bu-named-zbrowser-exec-defaultÚ@z::local)r„   )rî   r%  r&  ÚkeyÚtags   &&&  r   Ú_backend_cache_keyr+  p  sK   € ÷ )5ˆI�l�^Ñ
$¸7×;\Ð;\ÐF\€CÜ
Ó
€CßˆSˆE��3�%‰. S€Cß%ˆcˆU�'ˆ?Ð.¨3Ð.r    c                ó0   € V ^8„  d   QhR\         R\         /# )r   r)   r   r‰   )r   s   "r   r   r   z  s   € ÷ .ñ .œsð .¤sñ .r    c                ó.   € RT ;'       g    R 2R,          # )a  BU_NAME of the harness daemon serving the hybrid local sidecar. The daemon reads BU_CDP_* once at
spawn and outlives the call, so sharing the cloud route's daemon would relay a private URL to the
cloud browser it is already attached to. User session names cannot start with ``_``.Ú_local_r   :Né@   Nr?   )r)   s   &r   Ú_sidecar_daemon_namer0  z  s   € ð �T×&Ð&˜YÐ'Ð(¨Õ-Ð-r    c                ó4   € V ^8„  d   QhR\         R\        RR/# )r   rB   r)  r   NrD   )r   s   "r   r   r   �  s!   € ÷ >ñ >¤4ð >¬cð >°dñ >r    c                ób   € ^ RI Hp V! V4      pV'       d   V P                  \        V4       R# R# )z£The session layer decides real profile vs fresh browser once per key; carry its note (if it fell
back) so the result reports the browser this call actually drives.)Úreal_profile_noteN)Útools.browser_tool_sessionr3  rƒ   Ú_REAL_PROFILE_FALLBACK_SENTINEL)rB   r)  r3  Únotes   &&  r   Ú_export_real_profile_noter7  �  s(   € õ =Ù˜SÓ!€DßØ�‰Ô6¸Ö=ñ r    c                ó€   € V ^8„  d   QhR\         R\        \        ,          R\        R\        R\        \        ,          /# ©r   rB   rî   r%  r&  r   ©rE   r   r   r5   )r   s   "r   r   r   Š  s9   € ÷ ñ ¤ð ´¼µð ÌSð Ü%)ðÜ6>¼sµmñr    c           	     ó(  €  ^ RI Hp ^ RIHp V! 4       '       g   R#  \        Y\        YT4      R R4      pTf)   RT \        &   RT \        &   \        T \        YT4      4       T#   \         d"   p\
        P                  RT4        Rp?R# Rp?ii ; i)a   Point the harness at a Hermes-spawned ``lightpanda serve`` (``browser.engine: lightpanda`` and
nothing of higher precedence claimed the session). Each cache key gets its own process via the
legacy ``_get_session_info()`` (cache, reaper, atexit): private browser, own-tab preamble skipped.©Ú_get_session_info)Ú_using_lightpanda_engineNz browser engine lookup failed: %sc                 ó   € R V  R2# )z!Lightpanda could not be started: un    Set browser.engine to auto to use local Chrome, or switch backends via `hermes tools` â†’ Browser Automation.r?   )r%   s   &r   r0   Ú)_resolve_lightpanda_cdp.<locals>.<lambda>™  s   € Ð6°q°cð :hñ hr    z\Lightpanda session returned no CDP endpoint. Set browser.engine to auto to use local Chrome.Ú1)r4  r=  Ú&tools.browser_tool_lightpanda_fallbackr>  r"   r#   r$   rW   r+  Ú_PRIVATE_BROWSER_SENTINELÚ_BOT_DESKTOP_BROWSER_SENTINELr7  )rB   rî   r%  r&  r=  r>  r%   rt   s   &&&&    r   Ú_resolve_lightpanda_cdprE  Š  s™   € ð
Ý@ÝSÙ'×)Ò)Ùð *ô
 ØÔ 2°7È'Ó Rñ	iàfó	€Cð ‚{Ø),ˆÔ%Ñ&Ø-0ˆÔ)Ñ*Ü! #Ô'9¸'ÐQXÓ'YÔZØ€Jøô ô Ü�‰Ð7¸Ô;Ýûðús   ‚A% Á%BÁ0BÂBc                ó0   € V ^8„  d   QhR\         R\         /# )r   rC   r   r‰   )r   s   "r   r   r   ¤  s   € ÷ ñ œCð ¤Cñ r    c                óÒ  €  ^ RI Hp V! 4       '       g   V # ^ RIHpHp ^ RIHpHp ^ RIH	p V! V 4      pVP                  R9  g   VP                  '       g   V # VP                  RR7      pVf   V # VP                  W‡P                  VP                  V4      R7      p	V! VP                  R	V	 2R
7      4      #   \          d#   p
\"        P%                  RT
4       T u Rp
?
# Rp
?
ii ; i)aŒ  A CDP endpoint agent-browser reported from INSIDE the terminal backend's sandbox is that sandbox's
loopback: unreachable from this host (Docker bridge / ssh remote). The harness, the vault supervisor
and ``browser_exec`` all connect from here, so forward the port over the sandbox's exec stream and hand
them the local end. Chromium's DevTools accepts any loopback ``Host`` header, port included.)Ú_browser_in_sandbox)ÚurlsplitÚ
urlunsplit)ÚruntimeÚsandbox_host)ÚstreamsT)ÚcreateN)Úuserz
127.0.0.1:)Únetlocz#sandbox CDP forward unavailable: %s)z	127.0.0.1Ú	localhost)r4  rH  Úurllib.parserI  rJ  Útools.bot_desktoprK  rL  Útools.environmentsrM  ÚhostnameÚportÚ_sandbox_envÚforward_portÚ	_user_forÚ_replacer"   r#   r$   )rC   rH  rI  rJ  Ú_bd_runtimerL  rM  r˜   ÚsandboxÚlocalr%   s   &          r   Ú_reach_sandbox_cdpr^  ¤  sÇ   € ð
ÝBÙ"×$Ò$ØˆJß5ßJÝ.Ù˜“ˆØ�>‰>Ð!;Ô;À5Ç:Ç:À:ØˆJØ×*Ñ*°$Ð*Ó7ˆØŠ?ØˆJØ×$Ñ$ W¯j©j¸|×?UÑ?UÐV]Ó?^Ð$Ó_ˆÙ˜%Ÿ.™.°*¸U¸GÐ0D˜.ÓEÓFÐFøÜô Ü�‰Ð:¸AÔ>Ø�
ûðús;   ‚B9 •B9 —A B9 ÁB9 ÁB9 Á2AB9 Â9C&ÃC!ÃC&Ã!C&c                ó€   € V ^8„  d   QhR\         R\        \        ,          R\        R\        R\        \        ,          /# r9  r:  )r   s   "r   r   r   ½  s:   € ÷ ñ ¤tð ´h¼sµmð ÔSVð Ü+/ðÜ<DÄS½Mñr    c           	     ól  €  ^ RI Hp ^ RIHp T! \        YT4      RR.T! RR7      R	7      pT;'       g    / P                  R
4      '       dH   \        T;'       g    / P                  R4      ;'       g    / P                  R4      ;'       g    R4      MRpT'       g*   RT;'       g    / P                  R4      ;'       g    R R2# \        T4      p\        Y4       RT \        &   RT \        &   \        T \        YT4      4       R#   \         d"   p\
        P                  RT4        Rp?R# Rp?ii ; i)u´  Point the harness at Hermes' packaged Chromium, launched through agent-browser for this cache key â€”
the same browser the built-in tools drive. Left alone, the harness discovers the user's INSTALLED
Chrome on its default profile, which needs the chrome://inspect toggle + an Allow popup per run and
is blocked outright on Chrome >=136; on a headless box it just reports ``chrome-not-running``.
``get cdp-url`` runs through ``_run_browser_command`` (legacy cache, inactivity reaper, atexit, Chromium
preflight/auto-install) on EVERY call: it launches the browser cold, follows a relaunch, and refreshes
the agent-browser daemon's idle timer, which never sees the harness's direct CDP traffic.)Ú_run_browser_command)Ú_get_open_command_timeoutz+managed chromium resolution unavailable: %sNrN   zcdp-urlT)Ú
first_open©ÚtimeoutÚsuccessÚdataÚcdpUrlr   z(The local browser could not be started: rn   z&agent-browser returned no CDP endpointuW    Run `hermes tools` â†’ Browser Automation to (re)install Chromium, or switch backends.rA  )r4  ra  ro   rb  r"   r#   r$   r+  rN   r   r^  rJ   rC  rD  r7  )	rB   rî   r%  r&  ra  rb  r%   ÚresrC   s	   &&&&     r   Ú_resolve_managed_chromium_cdprj  ½  s  € ðÝCÝ@ñ Ô1°'ÈÓQÐSXÐ[dÐZeÙ'@ÈDÔ'QôS€CàGJÇyÀyÈbÇoÁoÐV_×F`ÒF`Œ#�—	�	�r�‰˜vÓ&×,Ð,¨"×1Ñ1°(Ó;×AÐA¸rÔ
BÐfh€CßØ:¸C¿I¸IÀ2¿?¹?È7Ó;S×;Ð;ÐWð  ;Að Aið ið 	jä
˜SÓ
!€CÜ�ÔØ%(€CÔ!Ñ"Ø),€CÔ%Ñ&Ü˜cÔ#5°gÈWÓ#UÔVÙøô ô Ü�‰ÐBÀAÔFÝûðús   ‚D ÄD3ÄD.Ä.D3c                ó€   € V ^8„  d   QhR\         R\        \        ,          R\        R\        R\        \        ,          /# r9  r:  )r   s   "r   r   r   Ú  s@   € ÷ Nñ N¤4ð N´(¼3µ-ð NÌsð NÜ'+ðNÜ8@Ä½ñNr    c                óh   € \        WW#4      pV'       g   \        V 4      '       d   V# \        WW#4      # )zvLocal engine (no provider / override, or the hybrid sidecar): ``browser.engine: lightpanda`` or the
packaged Chromium.)rE  rO   rj  )rB   rî   r%  r&  rt   s   &&&& r   Ú_resolve_local_engine_cdprm  Ú  s/   € ô " #°Ó
F€Cß
Œl˜3×ÒØˆ
Ü(¨°|ÓMÐMr    c                ó€   € V ^8„  d   QhR\         R\        \        ,          R\        R\        R\        \        ,          /# )r   rB   rî   r%  Úforce_local_sidecarr   r:  )r   s   "r   r   r   ä  s@   € ÷ Hñ Hœdð H¬X´c­]ð HÌ#ð HÜ.2ðHÜ?GÌ½}ñHr    c           	     ó   aaa€ \        V 4      '       d   R#  ^ RIHp ^ RIHo ^ RIHp \        TR4      pT'       d   \        Y4       R# T'       d   \        YTRR7      # \        TRR	4      pTf   \        YT4      # \        \        TR
R4      ;'       g    R4      P                  4       P!                  4       p	T	\"        8X  d5   \%        \'        4       4      '       g   \)        4       '       d   RT \*        &   R# \-        T4      P.                  o/ oR TT3R llp
\1        Y
\3        Y4      T3R lRS R24      pT'       dJ   SP5                  R4      '       d3   \        P7                  RSSP5                  R4      4       \9        YT4      # Tf   T'       d
   RT \*        &   T#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)u±  Point the harness at the configured backend's CDP endpoint; error string on failure.

Precedence: (1) ``BU_CDP_WS``/``BU_CDP_URL`` already in env (operator override); (2) ``BROWSER_CDP_URL``
env / ``browser.cdp_url`` (``/browser connect``); (3) a cloud provider via the legacy ``_get_session_info()``
so browser_exec shares the SAME session machinery (per-task cache, expiry, reaper, atexit);
(4) the local engine â€” ``browser.engine: lightpanda`` or Hermes' packaged Chromium via agent-browser
(never the harness's own discovery of the user's installed Chrome); (5) BU direct-API configs WITH
``BROWSER_USE_API_KEY`` â†’ None (checked before (3)): the CLI reaches BU cloud natively (BU_AUTOSPAWN); a
keyless ``browser-use`` provider (managed-gateway autodetect, or a selection missing its key) takes (3).
``session_name`` (BU_NAME) keys the session cache so each name gets its OWN browser â€” what makes named
sessions concurrent-safe.

``force_local_sidecar`` skips step (3): the call runs on the local engine under the ``::local`` cache
key (hybrid routing; see ``_hybrid_routes_locally``). It sits BELOW the two operator overrides, and the
sidecar verdict never fires while a CDP override is set.N©Ú_get_cloud_providerr<  )Ú_get_cdp_overridez/browser_tool backend resolution unavailable: %sr   T)r&  zCloud provider lookup failedr)   rA  c                ó0   € V ^8„  d   QhR\         R\        /# )r   r)  r   ©r   rE   )r   s   "r   r   Ú*_resolve_backend_cdp.<locals>.__annotate__  s   € ÷ ñ œ3ð ¤4ñ r    c                 óJ   <€ SP                  S! V 4      ;'       g    / 4       S# r,   )Úupdate)r)  r=  Úsessions   &€€r   Ú_session_infoÚ+_resolve_backend_cdp.<locals>._session_info  s"   ø€ Ø�‰Ñ(¨Ó-×3Ð3°Ô4Øˆr    c                 ó   <€ R S RV  R2# )úCloud browser provider z failed to provide a session: u^   . Fix the provider configuration or switch backends via `hermes tools` â†’ Browser Automation.r?   )r%   Úprovider_names   &€r   r0   Ú&_resolve_backend_cdp.<locals>.<lambda>  s    ø€ Ð,¨]¨OÐ;YÐZ[ÐY\ð ]rñ rr    r}  zw returned no CDP endpoint, so Browser Use mode cannot drive it. Switch to the built-in browser tools for this provider.Úfallback_from_cloudzCbrowser_exec: %s failed (%s); using local Chromium for this sessionÚfallback_reason)rO   Útools.browser_tool_cloudrr  r4  r=  Útools.browser_tool_cdprs  r"   r#   r$   r&   rJ   rm  r   r-   r¬   r­   r¼   r®   r£   rÁ   rC  r  r`   rW   r+  rN   Úwarningrj  )rB   rî   r%  ro  rr  rs  r%   ÚoverriderÂ   Úprovider_keyrz  rt   r=  r~  ry  s   &&&&        @@@r   Ú_resolve_backend_cdpr‡  ä  s�  ú€ ô" �C×ÒÙðÝ@Ý@Ý<ô Ð'¨Ó,€HßÜ�SÔ#ÙßÜ(¨°|ÈTÔRÐRÜÐ)¨4Ð1OÓP€HØÒÜ(¨°|ÓDÐDô ”w˜x¨°Ó4×:Ð:¸Ó;×AÑAÓC×IÑIÓK€LØ”|Ô#¬LÔ9JÓ9L×,MÒ,MÔRj×RlÒRlØ),ˆÔ%Ñ&Ùä˜“N×+Ñ+€MØ€G÷ñ ô ØÔ.¨wÓEô	sà
! - ð 1Sð 	Só	€C÷ ˆw�{‰{Ð0×1Ò1ô 	�‰Ð\Ø$ g§k¡kÐ2CÓ&Dô	Fä,¨S¸<ÓHÐHð ‚{—|Ø),ˆÔ%Ñ&Ø€Jøôc ô Ü�‰ÐFÈÔJÝûðús   ˜F! Æ!GÆ,GÇGc                óR   € V ^8„  d   QhR\         R\        R\        \        ,          /# )r   rB   Úforce_localr   )rE   r5   r   r   )r   s   "r   r   r   /  s%   € ÷ ñ ¤4ð ´dð ¼xÌ½}ñ r    c                óØ  € \        4       '       d   \        V 4      '       d   R#  ^ RIHp ^ RIHp ^ RIHp \        TR4      '       d   R# T'       g2   \        T\        4       4      f   \        \        4       4      '       d   R# T! 4       w  rgT'       d   T'       g   \        Y4       RT \         &   T;'       g    R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)uQ  Point the harness at the user's real-profile copy-browser (a SNAPSHOT of their default Chromium
profile, hermes_cli.browser_connect) when consented. Two ways in: the effective backend is already local
(no provider, CDP override, or legacy BU cloud config) â†’ silent upgrade; or ``force_local`` (consent-gated
``local`` arg) â†’ the user's browser even under a cloud backend. Operator overrides (BU_CDP_* env,
/browser connect, ``browser.cdp_url``) own the session either way. A launch error is returned;
``_route_backend`` then falls back to the normal backend and reports it, never silently.N)Ú_get_cdp_override_rawrq  )Ú_real_profile_cdpz/real-profile backend resolution unavailable: %sr   rA  )r@   rO   rƒ  r‹  r‚  rr  Útools.browser_tool_real_profilerŒ  r"   r#   r$   r&   ÚobjectrÃ   r£   rJ   rD  )rB   r‰  r‹  rr  rŒ  r%   rC   rt   s   &&      r   Ú_resolve_real_profile_cdpr�  /  s³   € ô #×$Ò$¬°S×(9Ò(9ÙðÝ@Ý@ÝEô Ð# R×(Ò(Ù÷ œFÐ#6¼»ÓAÒMÜAÔBSÓBU×VÒVÙÙ Ó"�H€Cß
—3Ü�SÔØ-0ˆÔ)Ñ*Ø�;ˆ;�$Ðøô ô Ü�‰ÐFÈÔJÝûðús   ¥B= Â=C)ÃC$Ã$C)c                óJ   € V ^8„  d   QhR\         R\        \        ,          RR/# )r   rB   rî   r   N)rE   r   r   )r   s   "r   r   r   M  s*   € ÷ Xñ X¤$ð X´¼#µð XÀ4ñ Xr    c                óD  € V P                  R4      ;'       g    V P                  R4      pV'       g   R#  ^ RIHp ^ RIHpHp V! 4       w  rgTP                  T;'       g    RV! V4      WgR7       R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)	a)  Attach the per-task CDP supervisor to the browser this exec drives so ``browser_vault`` fill has
a secret-capable WebSocket (never argv) into the SAME browser. Only CDP-routed backends expose an
endpoint; BU direct-cloud (BU_AUTOSPAWN) does not, and the vault tools report ``supervisor_required``.rH   rG   N)ÚSUPERVISOR_REGISTRY)Ú_get_dialog_policy_configÚ_resolve_cdp_overrider   )rî   rV   Údialog_policyÚdialog_timeout_sz:browser_exec: CDP supervisor attach failed (non-fatal): %s)
rN   Útools.browser_supervisorr’  rƒ  r“  r”  Úget_or_startr"   r#   r$   )	rB   rî   rC   r’  r“  r”  ÚpolicyÚ	timeout_sÚexcs	   &&       r   Ú_attach_vault_supervisorrœ  M  s�   € ð �'‰'�+Ó
×
7Ð
7 #§'¡'¨,Ó"7€CßÙðXÝ@ß[Ù5Ó7ÑˆØ×(Ñ(°×1EÐ1E¸IÑOdÐehÓOiØ7=ð 	)ö 	[øäô XÜ�‰ÐQÐSV×WÒWûðXús   ¶*A3 Á!A3 Á3BÁ>BÂBc                ó˜   € V ^8„  d   QhR\         R\        R\        \        ,          R\        R\        R\        R\        \        ,          /# )r   rB   ry  rî   r]  ro  Úreal_profiler   )rE   r   r   r5   )r   s   "r   r   r   ^  sS   € ÷ Iñ Iœð I¤sð I´X¼cµ]ð IÌ4ð IÜ(,ðIÜDHðIÜT\Ô]`ÕTañIr    c                óB  € V'       d   \        WR7      MRpV'       d$   \        V 4      '       g   \        4       '       g   R# V'       dJ   \        V 4      '       g9   V'       g	   V'       g)   V'       d   ^ RIHp V! V4      V \
        &   RV \        &   Rp\        WVVR7      # )a9  Resolve where the harness connects; returns an error string or None. Real-profile consent runs
BEFORE provider resolution so a hit short-circuits the cloud path via the BU_CDP_* env contract. Named
sessions compose with the backend: BU_NAME namespaces the harness daemon (IPC socket, log, pid) and on
provider backends additionally keys its own cloud browser.

``force_local_sidecar`` (a call carrying a private URL) declines the cloud provider for the hybrid local
sidecar; unlike ``local`` (the consent-gated real-profile browser) it never touches the user's profile.)r‰  Nu°   local=true was requested but browser.use_real_profile is off. Enable it in config.yaml (browser.use_real_profile: true) or the desktop Settings â†’ Browser section, then retry.)Úreal_profile_fallback_noterA  T)r%  ro  )r�  rO   r@   r�  r   r5  Ú_LOCAL_FALLBACK_SENTINELr‡  )rB   ry  rî   r]  ro  rž  Úrp_errr   s   &&&&&&  r   Ú_route_backendr£  ^  s‚   € ÷ COÔ& sÕ>ÐTX€Fç”\ #×&Ò&Ô/F×/HÒ/Hñl÷
 ”\ #×&Ò&¯F¿,ßÝRÙ3MÈfÓ3UˆCÔ/Ñ0Ø(+ˆÔ$Ñ%Ø"ÐÜ ¸7Ø4GôIð Ir    c                ó$   € V ^8„  d   QhR\         /# r;   rw   )r   s   "r   r   r   {  s   € ÷ 
tñ 
tœTñ 
tr    c                 óZ   € R R lp \         P                  R8X  d   \        V / R4      # RR/# )a  Popen kwargs starting the CLI in its own process group (a new session on POSIX) so a
timeout can take down every process that inherited the capture pipes, not just the CLI
child. Windows also hides the console the .cmd shim would flash (as browser_tool does).c                ó$   € V ^8„  d   QhR\         /# r;   rw   )r   s   "r   r   Ú)_group_popen_kwargs.<locals>.__annotate__  s   € ÷ #ñ #”Dñ #r    c                  óÈ   € ^ RI Hp  \        P                  ! 4       pV;P                  \        P
                  ,          un        RV ! 4       \        \        R^ 4      ,          RV/# )ry   ©Úwindows_hide_flagsÚcreationflagsÚCREATE_NEW_PROCESS_GROUPÚstartupinfo)Úhermes_cli._subprocess_compatrª  Ú
subprocessÚSTARTUPINFOÚdwFlagsÚSTARTF_USESHOWWINDOWr-   )rª  Úsis     r   Ú_flagsÚ#_group_popen_kwargs.<locals>._flags  sO   € ÝDÜ×#Ò#Ó%ˆØ
�
Š
”j×5Ñ5Õ5�
ØÑ!3Ó!5¼Ä
ÐLfÐhiÓ8jÕ!jØ˜rð#ð 	#r    r‹   zWindows hide-flags unavailableÚstart_new_sessionT)r�   r)   r&   )r´  s    r   Ú_group_popen_kwargsr·  {  s1   € õ#ô DFÇ7Á7ÈdÄ?Œ6�&˜"Ð>Ó?ÐsÐYlÐnrÐXsÐsr    c                ó0   € V ^8„  d   QhR\         R\        /# )r   rš  r   )r   Úint)r   s   "r   r   r   ˆ  s   € ÷ "ñ "œcð "¤cñ "r    c                 óŒ   €  \        \        \        \        V 4      \        4      4      #   \
        \        3 d
    \        u # i ; ir,   )ÚmaxÚ_MIN_TIMEOUT_SÚminr¹  Ú_MAX_TIMEOUT_SÚ	TypeErrorÚ
ValueErrorÚ_DEFAULT_TIMEOUT_S)rš  s   &r   Ú_clamp_timeoutrÂ  ˆ  s9   € ð"Ü”>¤3¤s¨9£~´~Ó#FÓGÐGøÜ”zÐ"ô "Ü!Ò!ð"ús   ‚&) ©AÁAg      $@c                ó   € V ^8„  d   QhRR/# ©r   r   Nr?   )r   s   "r   r   r   ”  s   € ÷ ,ñ , Tñ ,r    c                óV  € \         P                  R8X  d�   ^ RIHp \        P
                  ! \        \        P                  4      ;_uu_ 4        \        P                  ! RRRR\        V P                  4      .\        P                  RRRR	^
R
V! 4       R7	       RRR4       R# \        P
                  ! \        \        4      ;_uu_ 4        \         P                  ! V P                  \         P"                  4       RRR4       R#   + '       g   i     R# ; i  + '       g   i     R# ; i)uµ   SIGKILL the CLI's whole process group (POSIX; ``start_new_session`` made pgid == pid) or,
on Windows, its process tree via ``taskkill /T /F`` â€” the only group-wide kill it offers.r‹   r©  Útaskkillz/Tz/Fz/PIDTúutf-8ÚreplaceF)ÚstdinÚcapture_outputr  ÚencodingÚerrorsre  Úcheckr«  N)r�   r)   r®  rª  rŽ   r�   rÖ   r¯  ÚSubprocessErrorÚrunr   ÚpidÚDEVNULLÚProcessLookupErrorÚPermissionErrorÚkillpgÚsignalÚSIGKILL)Úprocrª  s   & r   Ú_kill_cli_process_grouprØ  ”  sÃ   € ô 
‡w�w�$„ÝDÜ× Ò ¤¬*×*DÑ*D×EÕEÜ�NŠN˜J¨¨d°F¼CÀÇÁ»MÐJÔR\×RdÑRdØ*.°TÀGÐT]ÐgiØ!&Ñ6HÓ6JõL÷ Fñ 	Ü	×	Ò	Ô/´×	AÕ	AÜ
�	Š	�$—(‘(œFŸN™NÔ+÷ 
BÑ	A÷ FÖEñ 	úß	A×	AÐ	Aús   ÁADÃ	0DÄD	ÄD(	c                ó"  € \         P                  ! V 3R\         P                  R\         P                  R\         P                  RRRRRR	R
V/\        4       B p VP	                  WR7      w  rV\         P                  ! YP                  YV4      #   \         P
                   dl    \        T4       \        P                  ! \         P
                  4      ;_uu_ 4        TP	                  \        R7       RRR4       h   + '       g   i     h ; ii ; i)u´  Run the CLI in its own process group and kill the whole group on timeout.

``subprocess.run`` only kills the direct child on ``TimeoutExpired``; a grandchild that
inherited the stdout/stderr pipes (browser_harness daemon / Chrome helper) is orphaned
still holding them, and on Windows ``run()``'s unbounded post-kill ``communicate()`` then
blocks on pipe EOF forever â€” so the tool call, plus its activity heartbeat, wedges (#106244).
rÉ  rú   Ústderrr  TrË  rÇ  rÌ  rÈ  rB   )Úinputre  rd  N)r¯  ÚPopenÚPIPEr·  ÚcommunicateÚTimeoutExpiredrØ  rŽ   r�   Ú_POST_KILL_DRAIN_SÚCompletedProcessÚ
returncode)Úcmdri   rB   re  r×  rú   rÚ  s   &&&&   r   Ú_run_cli_killing_process_grouprä  ¢  sõ   € ô ×ÒØñÜ—?‘?ðÜ+5¯?©?ðÜCMÇ?Á?ðàðà#ðà,5ðà;>ðäBUÓBWñ€DðØ×)Ñ)°Ð)ÓF‰ˆô ×&Ò& s¯O©O¸VÓLÐLøô ×$Ñ$ô Ü Ô%Ü× Ò ¤×!:Ñ!:×;Õ;Ø×ÑÔ%7ÐÔ8÷ <à÷ <Ö;àúð	ús%   ÁB ÂADÃC:Ã1	DÃ:D
Ä	Dztools.browser_tool_cdpÚlive_cdp_generationz!live CDP generation lookup failedc                ó>   € V ^8„  d   QhR\         \        ,          RR/# )r   Úhome_keyr   NrÏ   )r   s   "r   r   r   Å  s   € ÷ ñ ¤8¬C¥=ð ¸Dñ r    c                óþ   a € \         ;_uu_ 4        \        V 3R l\        P                  4        4       4      pV F  p\        P	                  VR4       K  	  RRR4       \        X4       R#   + '       g   i     L; i)zÌStop every harness daemon this process drove (only ``home_key``'s when given), through the
harness's own identity-checked ``--reload``; the next browser_exec respawns one on the endpoint
it resolves then.c              3   óB   <"  € T F  w  rSR V39   g   K  Vx € K  	  R # 5ir,   r?   )Ú.0r)  Úhomerç  s   &  €r   Ú	<genexpr>Ú'stop_harness_daemons.<locals>.<genexpr>Ê  s%   øé € ÐbÑ.E¡ ÈÐVZÐ\`ÐUaÑIaŸšÓ.Eùs   ƒ•
N)Ú_driven_daemons_lockÚsortedÚ_driven_daemonsÚitemsr€   Ú_reload_daemons)rç  Údaemonsr)  s   f  r   Ústop_harness_daemonsrô  Å  sV   ø€ ÷ 
Ö	ÜÔb¬o×.CÑ.CÔ.EÓbÓbˆÛˆCÜ×Ñ  TÖ*ñ ÷ 
ô �GÖ÷	 
×	ús   �AA,Á,A<	c                ó   € V ^8„  d   QhRR/# rÄ  r?   )r   s   "r   r   r   Ð  s   € ÷ `ñ ` ñ `r    c                 ó:  € V '       d   \        4       MR pV'       g   R # \        4       pV  FX  p\        P                  ! \        \
        P                  4      ;_uu_ 4        \        . VORNR\        W#4      ^4       R R R 4       KZ  	  R #   + '       g   i     Ko  ; i)Nz--reloadr   )	rÌ   r†   rŽ   r�   rÖ   r¯  rÎ  rä  r   )ró  rã  rB   Údaemons   &   r   rò  rò  Ð  sp   € ß Œ)Œ+ d€CßÙÜ
Ó
 €CÛˆÜ× Ò ¤¬*×*DÑ*D×EÕEÜ*Ð+=¨SÐ+=°*Ð+=¸rÄ:ÈcÓCZÐ\^Ô_÷ FÑEó ßE×EÐEús   ÁB	Â	Bc                óº   € V ^8„  d   QhR\         R\        R\        \        ,          R\        R\        R\        R\        \        \        ,          \        3,          /# ©r   rB   ry  rî   r]  r\   Ú	route_keyr   )rE   r   r   r5   Útuple)r   s   "r   r   r   Ú  s[   € ÷ 
Uñ 
U”Tð 
U¤Cð 
U´(¼3µ-ð 
UÌð 
UÔ]að 
UÜð
UÜ#(¬´#­¼Ð)<Õ#=ñ
Ur    c           	     óè   € \        WW#VV\        9  R7      pV P                  \        R4      pV'       d   \        P	                  WW4       Yd;'       g     \        V P                  \        R4      4      3# )zü``_route_backend`` for one browser_exec call; returns ``(error, runs on the local sidecar)``.
A real-profile fallback is remembered per route: the route keeps its fresh browser and the note
waits until a result carries it (``_take_real_profile_note``).)ro  rž  N)r£  Ú_real_profile_fallbackr€   r5  rƒ   r5   r¡  )rB   ry  rî   r]  r\   rú  Ú	route_errr6  s   &&&&&&  r   Ú_route_execrÿ  Ú  sc   € ô
 ˜s¨WÐQ^Ø,5Ô=SÑ,SôU€Ià�7‰7Ô2°DÓ9€DßÜ×)Ñ)¨)Ô:Ø×TÐT¤t¨C¯G©GÔ4LÈdÓ,SÓ'TÐTÐTr    c                óÎ   € V ^8„  d   QhR\         R\        R\        \        ,          R\        R\        R\        R\        \         \        \        ,          \        \
        3,          /# rù  )rE   r   r   r5   rû  r¹  )r   s   "r   r   r   ç  sZ   € ÷ 
2ñ 
2œTð 
2¬Cð 
2¼(Ä3½-ð 
2ÔPTð 
2Ü'+ð
2Ü8;ð
2Ü@EÄdÌHÔUXÍMÔ[_ÔadÐFdÕ@eñ
2r    c           	     ó¬   € \        ^4       F@  p\        V 4      p\        4       p\        WqW#WE4      w  ršV	'       g   \        4       V8X  g   K@   M	  XX	X
X3# )zÈ``_route_exec`` on a copy of ``env`` -> ``(routed env, error, sidecar, generation)``, re-routed (at
most 3 tries) when /browser connect published meanwhile; ``_reload_if_republished`` covers dispatch.)ÚrangerE   Ú_live_generationrÿ  )rB   ry  rî   r]  r\   rú  Ú_attemptÚroutedÚ
generationrþ  r&  s   &&&&&&     r   Ú_route_exec_currentr  ç  sV   € ô ˜!–HˆÜ�c“ˆÜ%Ó'ˆ
Ü(¨¸'È-ÓcÑˆ	ßÔ(Ó*¨jÖ8Ùñ ð �9˜g zÐ1Ð1r    c                ó4   € V ^8„  d   QhR\         R\        RR/# )r   rB   r  r   N)rE   r¹  )r   s   "r   r   r   ô  s!   € ÷ ñ ¤ð ´#ð ¸$ñ r    c                óÖ   € \        4       V8X  d   R# \        V 4      p\        ;_uu_ 4        \        P	                  VR4       RRR4       \        V.4       R#   + '       g   i     L; i)z`Stop this call's daemon if the profile published a new endpoint while it spawned on the old one.N)r  r   rî  rð  r€   rò  )rB   r  r÷  s   && r   Ú_reload_if_republishedr
  ô  sH   € äÓ˜ZÔ'ÙÜ˜SÓ!€Fß	Ö	Ü×Ñ˜F DÔ)÷ 
ä�V�HÖ÷ 
×	ús   «AÁA(	c                ó0   € V ^8„  d   QhR\         R\        /# )r   rú  r   ru  )r   s   "r   r   r   þ  s   € ÷ Kñ K¤sð K¬tñ Kr    c                óz   € V \         9  g   V \        9   d   / # \        P                  V 4       R\         V ,          /# )z[The fallback note for the first result this route returns after falling back, then nothing.Úreal_profile_unavailable)rý  Ú_real_profile_note_deliveredÚadd)rú  s   &r   Ú_take_real_profile_noter  þ  s7   € àÔ.Ô.°)Ô?[Ô2[Øˆ	Ü ×$Ñ$ YÔ/Ø&Ô(>¸yÕ(IÐJÐJr    c          
      ój   € V ^8„  d   QhR\         R\         R\        R\        \         ,          R\        /# )r   ri   ry  rš  rî   r]  )r   r¹  r   r5   )r   s   "r   r   r     s<   € ÷ kñ k”sð k¤Sð k¼#ð kÜ"¤3�-ðkÜ7;ñkr    c           
     óÔ  a aaaaa€ ^ RI Hp ^ RIHoHp S '       d   S P                  4       '       g	   S! R4      # \        S 4      pVP                  '       d   S! VP                  4      # \        SV4      p\        P                  S 4      '       d   VP                  M\        P                  VR4      p	\        4       oS'       g	   S! R4      # \        4       oV'       d.   \         P#                  V4      '       g   S! RV: R24      # VSR&   \%        SVS\'        V4      W˜4      w  or©pV
'       d	   S! V
4      # V	'       d   \)        V4      SR&   V	\        V&   \'        SP+                  \,        R	4      4      pSP+                  \.        R	4      pV'       d   V'       g   \0        S ,           o \3        S4      pV'       d   VSR
&   RS9  d   \5        \7        4       4      '       d   RSR&   \9        V4      o\:        P:                  ! 4       pR VV VVVV3R llpV'       d   ^ RIHp V! RRR//V4      pMV! 4       p\A        SV4       RV9  d   RV9   d
   VR,          # V! V4      # VR,          pRVPB                  ^ 8H  RVPB                  RV! VPD                  RR7      /pV'       d   VVR&   V'       d   VVR&   VPG                  \I        V4      4       T! VPJ                  ;'       g    RP                  4       RR7      p\M        V4      \N        8”  d   VR	\N         R,           pV'       d   VVR&   \Q        VPD                  V4      pV'       d   VVR&   \S        VV4      pVe   V# V! V4      # )zBRun Python code through the browser-use CLI, and return its output)Úredact_sensitive_text)Ú
tool_errorÚtool_resultz~No code provided. Pass Python that uses the pre-imported helpers, e.g. new_tab("https://example.com") then print(page_info()).Fz_browser-harness is missing from Hermes's Python environment. Run `hermes update` to re-sync it.zInvalid session name zA: use 1-64 letters, digits, dashes, or underscores (e.g. 'r7k2').ÚBU_NAMENrð   ÚBU_AUTOSPAWNrA  c                óF   € V ^8„  d   QhR\         \        \        3,          /# r;   )rE   r   r   )r   s   "r   r   Ú"browser_exec.<locals>.__annotate__>  s   € ÷ Zñ Z”dœ3¤˜8•nñ Zr    c            	      ój  <€ \        SS4       \        ;_uu_ 4        \        S4      p \        4       \        V &   R R R 4        R\        SSSS4      /#   + '       g   i     L!; i  \        P                   d    RS! RS R\         R24      /u # \         d   pRS! RT 24      /u R p?# R p?ii ; i)Nr×  Úerror_resultz!browser-use exec timed out after zGs. The daemon may still be working; retry with a larger timeout_s (max u‚   ), or split the work into several calls that append to workspace files â€” anything already written to the workspace is preserved.z"Failed to launch browser-use CLI: )
rœ  rî  r   r
   rð  rä  r¯  rß  r¾  rÖ   )r÷  r%   rã  ri   rB   rî   re  r  s     €€€€€€r   ÚdispatchÚbrowser_exec.<locals>.dispatch>  sÅ   ø€ Ü   gÔ.ß!Ö!Ü$ SÓ)ˆFÜ&5Ó&7ŒO˜FÑ#÷ "ð		ZØÔ:¸3ÀÀcÈ7ÓSÐTÐT÷	 "×!ûô
 ×(Ñ(ô 	Ø"¡JØ3°G°9ð =0Ü0>Ð/?ð @hðhó%ð ò ô
 ô 	ZØ"¡JÐ1SÐTUÐSVÐ/WÓ$XÐYÕYûð	Zús5   œAÁA% ÁA"	Á%*B2ÂB2ÂB2ÂB-Â'B2Â-B2)Ú
run_fencedÚfeaturesr]  Tr×  r  rf  Ú	exit_codeÚoutput)Úforceró   ry  r   u   
â€¦ (stderr truncated)rÚ  r  )*Úagent.redactr  r»   r  r  r¬   ru   r[   r+  rp   Úsearchr\   Ú_exec_route_is_sidecarrN   rÌ   r†   Ú_SESSION_REÚmatchr  r5   r0  r€   rD  rC  Ú_OWN_TAB_PREAMBLErø   rÃ   r£   rÂ  rÕ   r4  r  r
  râ  rú   rx  r  rÚ  ÚlenÚ_STDERR_CAP_CHARSr  r  )ri   ry  rš  rî   r]  r  r  Úverdictrú  r\   rþ  r  Úbot_desktop_browserÚprivate_browserró   Ústartedr  r  Ú
dispatchedr×  r  rÚ  Ú
screenshotÚnativerã  rB   re  r  s   f&&f&                   @@@@r   Úbrowser_execr2    s  ý€ õ 3ß6ß�t—z‘z—|’|Ùð  ]ó  ^ð  	^ô   Ó%€GØ‡‡€Ù˜'Ÿ/™/Ó*Ð*ô # 7¨GÓ4€IÜ-4¯^©^¸D×-AÒ-A�G×)Ò)ÔG]×GaÑGaÐbkÐmrÓGs€Mä
‹+€CßÙð ?ó @ð 	@ô Ó
 €CßÜ× Ñ  ×)Ò)ÙÐ 5°g±[ð AFð Fó Gð Gà ˆˆI‰Ü0CØˆW�gœt E›{¨Mó1FÑ-€Cˆ :çÙ˜)Ó$Ð$ßÜ-¨gÓ6ˆˆI‰Ø(5Ô˜9Ñ%Ü˜sŸw™wÔ'DÀdÓKÓLÐð —g‘gÔ7¸Ó>€Oß—Ü  4Õ'ˆä˜wÓ'€IßØ$-ˆÐ Ñ!ð ˜SÔ Ô%GÔHYÓH[×%\Ò%\Ø!ˆˆNÑä˜YÓ'€GÜ�iŠi‹k€G÷Zõ Z÷  Ý9Ù ¨g°t¨_Ð =¸xÓH‰
á“Zˆ
Ü˜3 
Ô+Ø�ZÔØ˜ZÔ'Ø˜nÕ-Ð-Ù˜:Ó&Ð&Ø�fÕ€Dð
 	�4—?‘? aÑ'Ø�T—_‘_ØÑ'¨¯©¸4Ô@ð€F÷
 Ø'ˆˆ{ÑßØ#ˆˆyÑØ
‡M�MÔ)¨)Ó4Ô5Ù" D§K¡K×$5Ð$5°2×#<Ñ#<Ó#>ÀdÔK€FÜ
ˆ6ƒ{Ô&Ô&ØÐ*Ô*Ð+Ð.HÕHˆßØ!ˆˆxÑÜ! $§+¡+¨wÓ7€JßØ$.ˆÐ Ñ!Ü*¨6°:Ó>ˆØÒØˆMÙ�vÓÐr    u|  Drive a real web browser via the Browser Use CLI: `code` runs as full Python (stdlib available) with pre-imported browser helpers; stdout comes back in the result. Start `code` with a one-line comment describing the step for the user in plain language, max 60 chars (e.g. `# Searching Amazon for paper towels`) â€” the UI shows it as the step label.

STATE: the browser session and workspace persist across calls; Python variables do NOT (fresh interpreter each call). The workspace dir is $BH_AGENT_WORKSPACE (also `workspace` in every result); functions defined in agent_helpers.py there are auto-imported into every call. For multi-item tasks ('all N products / every entry'), append each batch to a JSON/CSV file in the workspace, then read it back and aggregate in code â€” dedupe/count/sort with Python, not in your head â€” and verify the collected count against what was asked before answering.

Batch each sub-procedure (navigate, wait, extract, act) into one call â€” do not spend a call per action â€” but for long extractions prefer several medium calls that append to workspace files over one giant call, so progress survives timeouts.u   Screenshots are attached to your context automatically: when the exec output contains a capture_screenshot() path, the image arrives with this tool's result and you inspect it directly with your own vision â€” never send browser screenshots to a separate vision tool.u   Your model cannot view images, so work text-first: page_info() for state, js() for reading/extracting DOM text, fill_input(selector, text) for inputs, and js("document.querySelector('â€¦').click()") for clicks â€” skip the screenshot-driven workflow described below.u   The local engine is Lightpanda (no graphical renderer, one page per session): capture_screenshot() is unavailable, so work text-first; navigate with new_tab(url) exactly once, then goto_url(url) for every later navigation â€” a second new_tab() fails with TargetAlreadyLoaded.uÖ  

HELPERS (pre-imported): new_tab(url) opens/navigates (use for the FIRST navigation), goto_url(url) navigates the current tab, wait_for_load() after navigation, page_info() summarizes the current page state, js(expr) evaluates a JS expression and returns its value (js('document.title'); wrap function bodies as js('(() => {...})()') â€” a bare '() => {...}' returns the function itself, uncalled), fill_input(selector, text) types into inputs, click_at_xy(x, y) clicks viewport coordinates, capture_screenshot() saves and prints a screenshot path, cdp('Domain.method', **kwargs) is raw CDP â€” cdp('Accessibility.getFullAXTree')['nodes'] lists every element's role/name/backendDOMNodeId (filter in Python before printing; it is thousands of nodes), then cdp('DOM.getBoxModel', backendNodeId=n) gives click coordinates. ensure_real_tab() recovers from a stale/internal tab. Login walls: never guess credentials; see the vault note below if present, otherwise stop and ask the user.c                ó$   € V ^8„  d   QhR\         /# r;   r‰   )r   s   "r   r   r   ª  s   € ÷ Lñ LœSñ Lr    c                 óÖ   € \        RRRR4      ^ ,          '       d   \        \        ,           \        ,           # \        RRRR4      p \        V '       d   \        ,           # \        ,           # )	zCHeader tailored to whether the active model can see images nativelyz&tools.browser_tool_lightpanda_fallbackÚlightpanda_engine_statusFr   z$lightpanda engine status unavailableztools.vision_toolsr  )Fr   )r2   Ú_HEADER_BASEÚ_HEADER_TEXT_ONLYÚ_HEADER_LIGHTPANDAÚ_HEADER_VISION)Úvisions    r   Ú_description_headerr;  ª  s_   € äÐ:Ð<VÐXcØ8ó:Ø:;÷=ô =äÔ/Õ/Ô2DÕDÐDÜÐ,Ð.SÐUZÐ\^Ó_€FÜ¯Vœ>ÕKÐKÔ9JÕKÐKr    c                ó$   € V ^8„  d   QhR\         /# r;   rw   )r   s   "r   r   r   ³  s   € ÷ ñ ¤4ñ r    c                  óÐ   € R \        4       \        ,           /p \        4       '       d?   \        \        R,          R,          4      pRRRRR R/VR&   / \        R,          CRV/CV R&   V # )	ÚdescriptionÚ
parametersÚ
propertiesr  Úbooleanr   Fu3  Drive the user's own local browser (a Hermes-managed copy of their real default-Chromium profile, logins/cookies included) instead of the configured cloud browser backend. Use when the user asks to act as themselves â€” their accounts, their sessions. No-op when the backend is already local. Default false.r]  )r;  Ú_HELPERS_DIGESTr@   rE   ÚBROWSER_EXEC_SCHEMA)Ú	overridesÚpropss     r   Ú_dynamic_schema_overridesrF  ³  sx   € Ø$Ô&9Ó&;¼oÕ&MÐN€Iô × Ò ÜÔ(¨Õ6°|ÕDÓEˆà�I˜y¨%Øð pð
ˆˆg‰ð #]Ô%8¸Õ%FÐ"\ÈÐV[Ñ"\ˆ	�,ÑØÐr    r)   r2  r>  ur   

(The browser-use CLI is not installed yet. Install it with `hermes tools` (Browser Automation â†’ Browser Use).)r?  r  rŽ  r@  ri   ÚstringziPython code to execute using the pre-imported browser helpers. Use print(...) for any data you need back.ry  uÌ   Named isolated browser session â€” its own daemon and (on cloud backends) own browser, so concurrent tasks don't share tabs. Reuse the same name on every related call; omit for the shared default session.rš  Úintegerr   z4Max seconds to wait for the code to finish (default z, max z).Úrequired)Úregistryc                 óî   € \        V P                  R R4      V P                  RR4      ;'       g    RV P                  R\        4      VP                  R4      \        V P                  RR4      4      R7      # )ri   r   ry  rš  rî   r]  F)ri   ry  rš  rî   r]  )r2  rN   rÁ  r5   )ÚargsÚkws   &,r   r0   r0   à  sY   € œ|Ø�X‰X�f˜bÓ!¨4¯8©8°I¸rÓ+B×+HÐ+HÀbØ—(‘(˜;Ô(:Ó;ÀRÇVÁVÈIÓEVÜ�4—8‘8˜G UÓ+Ó,õ r    u   ðŸŒ�)r)   ÚtoolsetÚschemaÚhandlerÚcheck_fnÚdynamic_schema_overridesÚemojic                ó8  € V ^8„  d   Qh/ ^ \         9   d(   \        \        \        R3,          \        3,          ;R&   ^\         9   d   \        \        \        3,          ;R&   ^\         9   d   \        \        \        3,          ;R&   ^\         9   d
   \
        ;R&   # )r   .rð  r%  rý  r  )Ú__conditional_annotations__rE   rû  r   r5   r•   )r   s   "r   r   r      s~   € ÷ ñ ÷r 1Ò 0””eœC ˜H•o¤sÐ*Õ+Ñ 0ñs÷| -Ò ,œœS¤$˜Y�Ñ ,ñ}÷@ ,Ò +œœS¤#˜X�Ñ +ñA÷B *Ò )œcÑ )òCr    )z/usr/local/sbinz/usr/local/binz	/usr/sbinz/usr/binz/sbinz/bin)r   )r   F)FTr,   ){rU  rd   rŽ   Ú	functoolsr.   Úimportlib.utilr  Úloggingr�   ÚrerÕ  r¯  rë   Ú	threadingrÕ   Úpathlibr   Útypingr   r   r   r   r   r   r#  r	   r
   Útools.browser_harness_dirsr   r   r   Úutilsr   Ú	getLoggerr`   r#   r¼   r²   Úcompiler&  rC  rD  r5  r¡  r(  rÁ  r¼  r¾  r*  rõ   Ú
IGNORECASErÿ   rp   r”   r&   r2   r9   r@   rJ   rO   rW   rY   ru   r†   r‚   r£   r®   r´   r¾   rÃ   rÁ   rÍ   rß   r�   rÌ   rø   r  r  r„   r+  r0  r7  rE  r^  rj  rm  r‡  r�  rœ  r£  r·  rÂ  rà  rØ  rä  rð  ÚLockrî  Úpartialr  r%  rý  r•   r  rô  rò  rÿ  r  r
  r  r2  r6  r9  r7  r8  rB  r;  rF  rC  r»   rJ  Úregisterr   )rU  s   @r   Ú<module>re     s}  øðöó Û Û Û Û Û Û 	Û 	Û Û Û 
Û Û Ý ß B× Bç =ß ZÑ ZÝ !à	×	Ò	˜8Ó	$€à€ØÐ ð �jŠjÐ<Ó=€ð 9Ð ð !AÐ à"DÐ à6Ð ð!Ð ðF Ð Ø€Ø€ØÐ à—:’:Ð1Ó2Ð à—’ÐSÐUW×UbÑUbÓc€à
�*Š*Ð-¨r¯}©}Ó
=€Ø_€÷õa÷tõtõXõ
?õ
ô�jô õ0õ õ&kõõaõsõ õ	&õ7õHõõ,:õ9õõ	õõ,K÷/õ.õ>÷õ4÷2÷:N÷HõVõ<X÷"Iõ:
tõ"ð Ð õ,òMð0 /1€Ó 0Ø —~’~Ó'Ð Ø×$Ò$ ZÐ1IÐK`ÐbcØ%HóJÐ ð +-Ð Ó ,à)+Ð Ó +Ù$'£EÐ Ó )÷õ`õ
Uõ
2õõKð ,.Ð@RØ*.¸e÷kð^5ð ð"Yð ðxð ðTð ð	Yð õLõð& ˆNà�L ?Õ2ð MõMàØ�ØØ�V˜X }ð  7bð  cØ˜ ¨-ð  :Hð  IØ˜& )¨YÐ8JØ'Ð+_Ð`rÐ_sÐsyð  {Ið  zJð  JLð  *MðNð
ð 	�V�Hð	ðÐ õ* $à × Ò Ø	ØØñð
 %Ø6Ø
÷r    