Ë
    ãß²jtÜ  ã                  ó4  — U 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ZddlZddl	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 ddlmZ ddlmZmZmZmZmZmZ ddlmZmZmZmZm Z   ejB                  e"«      Z#da$d�d	„Z% e&h d
£«       e&h d£«       e&h d£«       e&h d£«       e&h d£«       e&ddh«       e&h d£«       e&h d£«       e&ddh«      h	Z'dddddddddœZ(dD � cg c]  }  e
jR                  | e
jT                  «      ‘Œ! c} Z+dŽd„Z,d�d„Z-d�d„Z. ej^                  «       Z0da1de2d<   i Z3de2d<   i Z4d e2d!<   i Z5d"e2d#<   i Z6d$e2d%<    ej^                  «       Z7 e8«       Z9d&e2d'<    ej^                  «       Z:i Z;d(e2d)<   d*Z<d‘d+„Z=d’d“d,„Z>d”d-„Z?d•d.„Z@d–d/„ZAd—d0„ZBd˜d1„ZCd™d2„ZDd•d3„ZEdšd›d4„ZFdœd5„ZGej�                  d�d6„«       ZId�d7„ZJdd8œd�d9„ZK G d:„ d;e«      ZLdžd<„ZMd�d=„ZNdŸd>„ZOd d?„ZPd d@„ZQd¡dA„ZRdB„ ZSdC„ ZTd’dD„ZUdE„ ZVd¢dF„ZW edGdHdIdIdJ„ f¬K«      ZX eeXdLdL¬M«      ZY eYeReW¬N«       eY eeRd*¬O«      eW¬N«       eY eeRdP¬Q«      eW¬N«       eY eeRdR¬Q«      eW¬N«       eYeSdS„ ¬N«       eYeTdT„ ¬N«       eYdU„ dV„ ¬N«       eYdW„ dX„ ¬N«       eYdY„ «       eXdZ„ dLd[„ ¬\«       eXeU«       eXd]„ «       eX eeVd^¬_«      «       eX eeVd`¬_«      «      daœZZdbe2dc<    e&dd„ eZj·                  «       D «       «      Z\dedededededfdfdgdgdhdhdiœZ]d’d£dj„Z^d¤dk„Z_d¥dl„Z`d¤dm„Zad¦dn„ZbdoZcdpZddqZedrxZfZgd§ds„Zhd¨dt„Zid©du„Zjdªd«dv„Zkd¬dw„Zldx„ Zmdy„ Znd­dz„Zod®d{„Zpd’d¯d|„Zqd°d}„Zrecdf	 	 	 d±d~„Zs	 d’	 	 	 d²d„Ztd³d´d€„Zu	 	 	 	 dµd�„Zvd¶d‚„Zwd¶dƒ„Zxd„Zyeyfd·d…„Zzd¨d†„Z{d¸d‡„Z|dˆZ}ddddd‰œ	 	 	 	 	 	 	 d¹dŠ„Z~d¨d‹„ZdºdŒ„Z€ddl�Z�yc c} w )»ak  `computer_use` tool entry point: any-model desktop control (macOS/Windows/Linux) via cua-driver.
Return contract: text-only results are a JSON string; captures / `capture_after=True` return
``{"_multimodal": True, "content": [text, image_url], "text_summary": <fallback>}`` (run_agent.py /
the Anthropic adapter turn it into provider-specific image tool content).é    )ÚannotationsN)Ú
namedtuple)Úpartial)ÚSimpleNamespace)ÚAnyÚCallableÚDictÚListÚOptionalÚTuple)ÚActionResultÚCaptureResultÚComputerUseBackendÚ	UIElementÚimage_dimensions_from_bytesc                ó   — | a y ©N)Ú_approval_callback)Úcbs    ú</home/ubuntu/.hermes/hermes-agent/tools/computer_use/tool.pyÚset_approval_callbackr   #   s   € àÑó    >   ÚcmdÚshiftÚ	backspace>   r   Úoptionr   >   Úqr   Úctrl>   r   r   r   >   r   r   r   r   ÚwinÚl>   r   Údeleter   >   Údelr   r   r   Úf4r   r   )ÚcommandÚcontrolÚaltu   âŒ˜u   âŒ¥ÚwindowsÚsuperÚmeta)zcurl\s+[^|]*\|\s*bashzcurl\s+[^|]*\|\s*shzwget\s+[^|]*\|\s*bashz\bsudo\s+rm\s+-[rf]z\brm\s+-rf\s+/\s*$z:\s*\(\)\s*\{\s*:\|:\s*&\s*\}c                ó\   — t        d„ d„ t        j                  d| «      D «       D «       «      S )Nc              3  óN   K  — | ]  }|sŒt         j                  ||«      –— Œ y ­wr   )Ú_KEY_ALIASESÚget)Ú.0Úps     r   ú	<genexpr>z#_canon_key_combo.<locals>.<genexpr>8   s    è ø€ Òv°Òtu”\×%Ñ% a¨×+Ñvùs   ‚%Š%c              3  óX   K  — | ]"  }|j                  «       j                  «       –— Œ$ y ­wr   )ÚstripÚlower)r.   r   s     r   r0   z#_canon_key_combo.<locals>.<genexpr>8   s   è ø€ Ò5pÈA°a·g±g³i·o±o×6GÑ5pùs   ‚(*z\s*[+\-]\s*)Ú	frozensetÚreÚsplit)Úkeyss    r   Ú_canon_key_combor8   6   s)   € äÑvÑ5pÔQS×QYÑQYÐZhÐjnÓQoÔ5pÔvÓvÐvr   c                ó€  ‡— | dk(  r6t        ˆfd„t        D «       d«      x}rt        j                  d|›�ddœ«      S | dk(  r@t        ˆfd„t        D «       d«      x}	 �$t        j                  d	t        |«      › �d
dœ«      S ‰j                  d«      r,‰j                  d«      dk7  rt        j                  dddœ«      S y)zNJSON error for hard-blocked input, else None. Runs BEFORE the approval prompt.Útypec              3  óz   •K  — | ]2  }|j                  ‰j                  d d«      «      sŒ%|j                  –— Œ4 y­w)ÚtextÚ N)Úsearchr-   Úpattern)r.   r/   Úargss     €r   r0   z!_reject_unsafe.<locals>.<genexpr><   s3   øè ø€ Ò)v¸ÐWX×W_ÑW_Ð`d×`hÑ`hÐioÐqsÓ`tÕWu¨!¯)­)Ñ)vùs   ƒ&;ª;Nzblocked pattern in type text: z:Dangerous shell patterns cannot be typed via computer_use.©ÚerrorÚhintÚkeyc           	   3  óv   •K  — | ]0  }|j                  t        ‰j                  d d«      «      «      r|–— Œ2 y­w)r7   r=   N)Úissubsetr8   r-   )r.   Úbr@   s     €r   r0   z!_reject_unsafe.<locals>.<genexpr>?   s9   øè ø€ ò -d°1Ø01·
±
Ô;KÈDÏHÉHÐU[Ð]_ÓL`Ó;aÔ0bô ./ñ -dùs   ƒ69zblocked key combo: z.Destructive system shortcuts are hard-blocked.Úbring_to_frontÚdelivery_modeÚ
foregroundz2bring_to_front requires delivery_mode='foreground'Ú"bring_to_front_requires_foreground)rB   Úcode)ÚnextÚ_BLOCKED_TYPE_PATTERNSÚjsonÚdumpsÚ_BLOCKED_KEY_COMBOSÚsortedr-   )Úactionr@   ÚpatÚblockeds    `  r   Ú_reject_unsaferV   :   sê   ø€ à�Ò¤DÓ)vÔ=SÔ)vÐx|Ó$}Ð}˜SÐ}Ü�z‰zÐ&DÀSÀGÐ$LØ#_ñaó bð 	bà�‚¤tó -dÔ8Kô -dØeió(kð k˜GØswðxä�z‰zÐ&9¼&À»/Ð9JÐ$Kð  VFñ  Gó  Hð  	HØ‡x�xÐ Ô! d§h¡h¨Ó&?À<Ò&OÜ�z‰zÐ$XØ#GñIó Jð 	Jàr   c                ó¼   — t        | dd«      }|xs dj                  «       j                  «       |j                  «       j                  «       }}|r
|r||v s||v rdS |S )zÝCurrent sticky-target app when it provably differs from *requested_app*: both known and neither a substring
    of the other ('Google-chrome' vs 'chrome'). Unknown target -> None (fail open; the verify ladder catches it).Ú	_last_appNr=   )Úgetattrr2   r3   )ÚbackendÚrequested_appÚlast_appÚcurrentÚwanteds        r   Ú_input_target_mismatchr_   G   sb   € ô �w ¨TÓ2€HØ’~ 2×,Ñ,Ó.×4Ñ4Ó6¸×8KÑ8KÓ8M×8SÑ8SÓ8UˆV€GÙ¡f°¸'Ñ0AÀWÐPVÑEVˆ4ÐdÐ\dÐdr   zOptional[ComputerUseBackend]Ú_backendzDict[str, ComputerUseBackend]Ú	_backendszDict[str, threading.RLock]Ú_backend_call_lockszDict[str, str]Ú_backend_permission_modesz Dict[Tuple[str, str, str], bool]Ú_AUX_VISION_ROUTE_CACHEÚsetÚ_escalation_warnedzDict[str, Dict[str, Any]]Ú_last_screenshot_stateé   c                ón  — t         5  t        j                  | «      }|�u|j                  d«      |k(  ra|j                  d«      |k(  rMt        |j                  dd«      «      t        k  r+t        |j                  dd«      «      dz   |d<   	 ddd«       y||ddœt        | <   	 ddd«       y	# 1 sw Y   yxY w)
aQ  True when this capture should be delivered WITHOUT its image: the previous frame for this session had identical
    bytes for the same target and the omission streak is below _SCREENSHOT_DEDUP_MAX_STREAK. Any miss (new pixels,
    new target, streak exhausted, first capture) resets the stored state to this digest so the image goes out.NÚdigestÚtargetÚstreakr   é   T)rj   rk   rl   F)Ú_screenshot_dedup_lockrg   r-   ÚintÚ_SCREENSHOT_DEDUP_MAX_STREAK)Ú
session_idrj   rk   Ústates       r   Ú_screenshot_dedup_checkrs   i   s¯   € ô 
 ñ Ü&×*Ñ*¨:Ó6ˆØÐ %§)¡)¨HÓ"5¸Ò"?ÀEÇIÁIÈhÓDWÐ[aÒDaÜ˜Ÿ	™	 (¨AÓ.Ó/Ô2NÒNÜ! %§)¡)¨H°aÓ"8Ó9¸AÑ=ˆE�(‰OØ÷ð ð 9?È&Ð\]Ñ-^Ô˜zÑ*Ø÷÷ ñ ús   ‡BB+ÂB+Â+B4c                ó”   — t         5  | €t        j                  «        nt        j                  | d«       ddd«       y# 1 sw Y   yxY w)z5Forget dedup state (all sessions, or one scoped key).N)rn   rg   ÚclearÚpop©rq   s    r   Ú_reset_screenshot_deduprx   v   s<   € ä	ñ 9ØÐÜ"×(Ñ(Õ*ä"×&Ñ& z°4Ô8÷	9÷ 9ñ 9ús	   ‡.>¾Ac                ó,   — t        t        | «      «       y)zÆCompaction boundary hook (mirrors ``reset_file_dedup``): the summary may have dropped the frame an
    "unchanged" note would point at, so the next capture of this session must deliver pixels again.N)rx   Ú_scoped_sidrw   s    r   Úreset_screenshot_dedupr{   ~   s   € ô œK¨
Ó3Õ4r   c                ó  — d}t        j                  t        «      5  ddlm}  |«       }ddd«       t        j                  t        «      5  ddlm} ddlm}  || «      st         |d¬«      x}«      rf ||«      r^t        5  t        | xs d«      x}t        v}t        j                  |«       ddd«       rt        j                  d	||«       	 ddd«       y
ddd«       |S # 1 sw Y   Œ»xY w# 1 sw Y   ŒBxY w# 1 sw Y   |S xY w)aÂ  Map Hermes's approval bypass onto Cua's immutable mode; fails closed. Both identity namespaces are consulted
    (DB ``session_id`` and gateway ``session_key`` contextvar) or a gateway ``/yolo`` would be invisible here.
    Warns once per session that ``-z``/``--yolo`` swapped the driver onto a private ``unrestricted`` daemon, dropping
    the configured ceiling: deliberate (``unrestricted`` is not a config value) but easy to trigger by accident.Ústandardr   )Ú_cua_configured_permission_modeN)Ú%is_approval_bypass_active_for_session)Úget_current_session_keyr=   )Údefaultaj  computer_use: approval bypass (--yolo / -z) escalated the cua-driver permission mode from the configured '%s' to 'unrestricted' for this session. Runtime approval prompts are disabled and the driver's residual ceilings no longer apply. Drop the bypass flag to keep '%s', or declare a version-3 computer_use.capability_manifest to keep a ceiling on bypassed runs.Úunrestricted)Ú
contextlibÚsuppressÚ	ExceptionÚtools.computer_use.cua_backendr~   Útools.approvalr   Útools.approval_contextr€   ÚboolÚ_approval_lockÚstrrf   ÚaddÚloggerÚwarning)rq   Ú
configuredr~   r   r€   rD   Úwarns          r   Ú_cua_permission_moder‘   ƒ   s  € ð €JÜ	×	Ñ	œYÓ	'ñ 7ÝRÙ4Ó6ˆ
÷7ô 
×	Ñ	œYÓ	'ñ "ÝHÝBÙ0°Ô<ÜÑ3¸BÔ?Ð?�SÔ@ÑEjÐknÔEoÜñ ,Ü" :Ò#3°Ó4Ð4˜Ô=OÐO�Ü"×&Ñ& sÔ+÷,ñ Ü—‘ðeð gqÐr|ô	~ð
 "÷"÷ "ð "ð Ð÷%7ð 7ú÷,ð ,ú÷"ð Ðús/   œC$Á7C<Â-C0Â/"C<Ã$C-Ã0C9	Ã5C<Ã<Dc                ó¾   — t         j                  j                  dd«      j                  «       }|dv rddlm}  || ¬«      S |dk7  rt        d|›�«      ‚t        «       S )	NÚHERMES_COMPUTER_USE_BACKENDÚcua>   ú
cua-driverr=   r”   r   )ÚCuaDriverBackend)Úpermission_modeÚnoopz$Unknown HERMES_COMPUTER_USE_BACKEND=)ÚosÚenvironr-   r3   r†   r–   ÚRuntimeErrorÚ_NoopBackend)r—   Úbackend_namer–   s      r   Ú_new_backendrž   Ÿ   s[   € Ü—:‘:—>‘>Ð"?ÀÓG×MÑMÓO€LØÐ0Ñ0ÝCÙ°Ô@Ð@Ø�vÒÜÐAÀ,ÐAQÐRÓSÐSÜ‹>Ðr   c                ó€   — ||ct         | <   t        | <   t        j                  «       t        | <   | dk(  r|a|S t
        a|S )zŠRecord a backend in the session caches (the empty session also mirrors it onto the ``_backend`` hook).
    Caller holds ``_backend_lock``.r=   )ra   rc   Ú	threadingÚRLockrb   r`   )ÚsidrZ   r—   s      r   Ú_install_backendr£   ¨   sH   € ð 6=¸oÐ2„Iˆc�NÔ-¨cÑ2Ü(Ÿ™Ó0Ô˜ÑØ š)ˆw€HØ€Nô *2€HØ€Nr   c                óÌ   — t         j                  | d«       t        j                  | d«      t        j                  | d«      }}| dk(  r|€t        n|}t        |u rdnt        a||fS )zÀRemove one session's cache entries, plus the ``_backend`` injection hook when it aliases the empty session
    (older callers/tests may populate only the hook). Caller holds ``_backend_lock``.Nr=   )rc   rv   ra   rb   r`   )r¢   rZ   Ú	call_locks      r   Ú_detach_lockedr¦   ±   sb   € ô ×!Ñ! # tÔ,Ü"Ÿ™ s¨DÓ1Ô3F×3JÑ3JÈ3ÐPTÓ3UˆY€GØ
ˆb‚yØ%˜o•(°7ˆÜ# wÑ.‘4´HˆØ�IÐÐr   c                ó¼   — 	 |�|nt        j                  «       5  | j                  «        ddd«       y# 1 sw Y   yxY w# t        $ r} ||«       Y d}~yd}~ww xY w)zÊStop under the session call lock (if any) so an in-flight action finishes first. Never called under
    ``_backend_lock`` (unrelated sessions stay free). ``on_error`` absorbs the failure (never raises).N)rƒ   ÚnullcontextÚstopr…   )rZ   r¥   Úon_errorÚes       r   Ú_stop_backendr¬   ¼   sP   € ðØ#Ð/‰Y´Z×5KÑ5KÓ5Mñ 	Ø�L‰LŒN÷	÷ 	ñ 	ûäò Ù��‰ûðús.   ‚A  š4«A  ´=¹A  ½A  Á 	AÁ	AÁAc                óZ   — ddl m}m} t        | xs d«      } |«       €|S |› d |«       › �S )uŽ  Cache key for one Hermes session's backend. Outside a served-profile scope it is the bare id
    (legacy keys byte-identical); under a multiplexed turn the routed profile's home key is appended
    so two profiles that share a session id (or a DISPLAY) never share one cua-driver (#110032).
    Every cache path â€” lookup, install, release â€” goes through this, so release finds what lookup made.r   )Úget_hermes_home_overrideÚhermes_home_keyr=   ú@)Úhermes_constantsr®   r¯   r‹   )rq   r®   r¯   r¢   s       r   rz   rz   Å   s9   € ÷
 KÜ
ˆjÒ˜BÓ
€CÙ*Ó,Ð4ˆ3ÐV¸S¸EÀÁ?ÓCTÐBUÐ:VÐVr   c                óÞ  — t        | xs d«      t        | «      }}	 t        5  t        |«      }|dk(  rt        �|t
        vrt        |t        |«       t
        j                  |«      x}€1t        |«      }|j                  «        t        |||«      cd d d «       S t        j                  |d«      |k(  r|cd d d «       S t        |«      \  }}d d d «       t        d„ «       ŒÇ# 1 sw Y   ŒxY w)Nr=   r}   c                 ó   — y r   © ©r«   s    r   ú<lambda>z_get_backend.<locals>.<lambda>Þ   ó   � r   )r‹   rz   Ú_backend_lockr‘   r`   ra   r£   r-   rž   Ústartrc   r¦   r¬   )rq   Úbare_sidr¢   r—   ÚcachedrZ   Ú_Ú
stale_locks           r   Ú_get_backendr¾   Î   sâ   € Ü˜
Ò( bÓ)¬;°zÓ+Bˆc€HØ
Üñ 	0ä2°8Ó<ˆOØ�bŠyœXÐ1°cÄÑ6JÜ  ¤h°Ô@Ü#Ÿ-™-¨Ó,Ð,�Ð5Ü& Ó7�Ø—‘”Ü'¨¨W°oÓF÷	0ñ 	0ô )×,Ñ,¨S°*Ó=ÀÒPØ÷	0ñ 	0ô +¨3Ó/‰MˆAˆz÷	0ô 	�f˜j©.Ô9ð ÷	0ð 	0ús   ¢A.C#ÂC#Â>C#Ã#C,c                óª   ‡— t        | «      Št        ‰«       t        5  t        ‰«      \  }}ddd«       €yt	        |ˆfd„«       y# 1 sw Y   ŒxY w)aN  Release one session-owned backend (lifecycle seam for hosts/plugins); idempotent, True iff one was released.
    Cache entries are removed BEFORE stopping so new lookups cannot retain the stale target/ref namespace. Approval
    grants are not touched here: they live in the shared store and die with ``tools.approval.clear_session``.NFc                ó4   •— t         j                  d‰d¬«      S )Nz2computer_use backend release failed for session %sT)Úexc_info©r�   Údebug)r«   r¢   s    €r   r¶   z.release_computer_use_session.<locals>.<lambda>ë   s   ø€ œFŸL™LÐ)]Ð_bÐmq˜LÓr€ r   T)rz   rx   r¸   r¦   r¬   )rq   rZ   r¥   r¢   s      @r   Úrelease_computer_use_sessionrÄ   à   sY   ø€ ô �jÓ
!€CÜ˜CÔ Ü	ñ 1Ü+¨CÓ0Ñˆ�÷1à€ØÜ�'˜9Ûrôtà÷1ð 1ús   žA	Á	Ac            
     óp  — t         5  t        j                  «       D � �ci c]&  \  } }t        |«      |t        j                  | «      f“Œ( }} }t        �8|j                  t        t        «      t        t        j                  d«      f«       dat        j                  «       t        j                  «       t        j                  «       f ddd«       t        5  t        j                  «        ddd«       j                  «       D ]  \  }}t        ||d„ «       Œ yc c}} w # 1 sw Y   ŒYxY w# 1 sw Y   ŒBxY w)a_  Stop all cached backends so cua-driver subprocesses don't outlive us. atexit only, no signal handlers: a
    ``SystemExit`` from a prompt_toolkit key binding corrupts its coroutine state and makes the process unkillable.
    Never raises. Drops the global lock before stop(): teardown budgets 5s and must not block spawns.

    Each session backend holds a long-lived ``cua-driver`` subprocess, so without this a driver can survive
    the Hermes process that spawned it (#28152 item 3). #69903 kept the orphan from burning a core by
    disabling the cursor overlay; the process itself still lingered.
    Nr=   c                ó.   — t         j                  d| «      S )Nz%cua-driver atexit teardown failed: %srÂ   rµ   s    r   r¶   z*_shutdown_backend_atexit.<locals>.<lambda>  s   € ´F·L±LÐAhÐjkÓ4l€ r   )r¸   ra   ÚitemsÚidrb   r-   r`   Ú
setdefaultru   rc   rŠ   rf   Úvaluesr¬   )r¢   rG   ÚuniquerZ   r¥   s        r   Ú_shutdown_backend_atexitrÌ   î   s  € ô 
ñ ZÜIRÏÉÓIZ×[¹v¸sÀA”"�Q“%˜!Ô0×4Ñ4°SÓ9Ð:Ñ:Ð[ˆÑ[ÜÐØ×Ñœb¤›l¬XÔ7J×7NÑ7NÈrÓ7RÐ,SÔTØˆÜ�‰ÓÔ.×4Ñ4Ó6Ô8Q×8WÑ8WÓ8YÑY÷Zô 
ñ #Ü× Ñ Ô"÷#à$Ÿm™m›oò nÑˆ�Ü�g˜yÑ*lÕmñnùó \÷Zð Zú÷#ð #ús)   ‡D Ÿ+DÁ
A>D ÃD,ÄD Ä D)Ä,D5c                 óT   — t        «        t        j                  «        t        «        y r   )rÌ   rd   ru   rx   r´   r   r   Úreset_backend_for_testsrÎ     s   € ÜÔÜ×!Ñ!Ô#ÜÕr   ©Úresultc               ó   ‡ ‡‡— ˆ ˆˆfd„}|S )Nc           
     óâ   •— | j                   j                  ‰i t        j                  ‰«      ¥t        t	        ‰|«      «      ¥|¥x}f«       t        ‰«      r ‰|«      S ‰€t        d‰¬«      S ‰S )NT©ÚokrS   )ÚcallsÚappendÚdictÚfromkeysÚzipÚcallabler   )ÚselfÚposÚkwÚcallÚnameÚparamsrÐ   s       €€€r   Úmethodz_noop_stub.<locals>.method  sp   ø€ Ø�
‰
×Ñ˜4Ð)b¬D¯M©M¸&Ó,AÐ)bÄTÌ#ÈfÐVYÓJZÓE[Ð)bÐ_aÐ)bÐ!b ÐcÔdÜ'¨Ô/‰v�d‹|ÐuÐ[aÐ[i´\ÀTÐRVÔ5WÐuÐouÐur   r´   )rß   rÐ   rà   rá   s   ``` r   Ú
_noop_stubrâ   	  s   ú€ övð €Mr   c                  óò   — e Zd ZdZdd„Zd„ xZZdd„Z eddddd	d
„ ¬«      Z	 ed«       ed«       ed«      cZ
ZZ edd«       edd«       eddd«      cZZZ edg ¬«       edg ¬«      cZZ eddd«      Zy)rœ   zkTest/CI stub (HERMES_COMPUTER_USE_BACKEND=noop). Records ``(name, kwargs)`` calls; returns trivial results.c                ó   — g | _         y r   )rÕ   ©rÛ   s    r   Ú__init__z_NoopBackend.__init__  s   € Èr ¥
r   c                 ó   — y r   r´   rå   s    r   r¶   z_NoopBackend.<lambda>  r·   r   c                 ó   — y)NTr´   rå   s    r   Úis_availablez_NoopBackend.is_available  s   € ¨4r   ÚcaptureÚmodeÚappÚpidÚ	window_idc           	     óB   — t        | d   xs dddd g | d   xs dd¬«      S )Nrë   Úsomi   i   rì   r=   )rë   ÚwidthÚheightÚpng_b64Úelementsrì   Úwindow_title)r   )rÝ   s    r   r¶   z_NoopBackend.<lambda>  s5   € ÔYfØ�‰ZÒ ˜5¨°SÀ$ÐQSÐY[Ð\aÑYbÒYhÐfhÐwyôZ{€ r   rÏ   ÚclickÚdragÚscrollr:   r<   rD   r7   Ú	set_valueÚvalueÚelementÚ	list_appsÚlist_windowsÚ	focus_appÚraise_windowN©ÚreturnÚNone©r  r‰   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ræ   r¹   r©   ré   râ   rê   rö   r÷   rø   Ú	type_textrD   rù   rü   rý   rþ   r´   r   r   rœ   rœ     s¬   „ ÙuãQÙ$Ð$€EˆDÛ/á˜ F¨E°5¸+ñ O{ô |€Gá$ WÓ-©z¸&Ó/AÁ:ÈhÓCWÐ€Eˆ4�Ù *¨6°6Ó :¹JÀuÈfÓ<UÑWaÐbmÐovð  yBó  XCÐ€Iˆs�IÙ(¨¸RÔ@Á*È^ÐdfÔBgÐ€Iˆ|Ù˜;¨¨~Ó>�Ir   rœ   c                ó¨  — | j                  d«      xs dj                  «       j                  «       }|st        j                  ddi«      S t        |j                  d«      xs d«      }t        || «      x}�|S |t        v rt        |   j                  r|gng | j                  d«      s|dk(  r| j                  d	«      rdgng z   }|D ]  }t        || «      x}€Œ|c S  	 t        |¬
«      }	 t        5  t        j                  |t        j                   «       «      }	ddd«       	5  t#        ||| |xs d¬
«      cddd«       S # t        $ r%}t        j                  d|› �ddœ«      cY d}~S d}~ww xY w# 1 sw Y   ŒYxY w# 1 sw Y   yxY w# t        $ r<}t$        j'                  d|«       t        j                  d|› d|› �i«      cY d}~S d}~ww xY w)uE  Main entry point (tools.registry): a JSON string (text-only) or a dict marked `_multimodal`. Order: hard
    blocks (_reject_unsafe) -> approval scopes (destructive action, then 'bring_to_front' â€” persistent focus is a
    separate visible side effect with its own scope) -> backend -> dispatch under the session call lock.rS   r=   rB   zmissing `action`rq   NrH   rþ   rÿ   rw   z"computer_use backend unavailable: z›If the cua-driver binary is missing, run `hermes computer-use install`. If a Python dependency is missing, the error above shows the exact install command.rA   zcomputer_use %s failedz	 failed: )r-   r2   r3   rO   rP   r‹   rV   Ú_ACTIONSÚdestructiveÚ_request_approvalr¾   r…   r¸   rb   rÉ   r    r¡   Ú	_dispatchr�   Ú	exception)
r@   ÚkwargsrS   rq   ÚerrÚscopesÚscoperZ   r«   r¥   s
             r   Úhandle_computer_user     sá  € ð �h‰h�xÓ Ò& B×-Ñ-Ó/×5Ñ5Ó7€FÙÜ�z‰z˜7Ð$6Ð7Ó8Ð8Ü�V—Z‘Z Ó-Ò3°Ó4€JÜ˜f dÓ+Ð+ˆÐ8Øˆ
Ø ¤HÑ,´¸&Ñ1A×1MÒ1Mˆv‰hÐSUØ"Ÿh™hÐ'7Ô8¸VÀ{Ò=RÐW[×W_ÑW_Ð`nÔWoÐ	ÑÐvxñz€Fàò ˆÜ$ U¨DÓ1Ð1ˆCÑ>ØŠJðð{Ü¨*Ô5ˆð
>Üñ 	VÜ+×6Ñ6°zÄ9Ç?Á?ÓCTÓUˆI÷	Vàñ 	SÜ˜W f¨d¸zÒ?QÈTÔR÷	Sñ 	Søô ò {Ü�z‰zÐ&HÈÈÐ$Lð$yñzó {õ 	{ûð{ú÷
	Vð 	Vú÷	Sð 	Sûäò >Ü×ÑÐ1°6Ô:Ü�z‰z˜7 v h¨i¸°sÐ$;Ð<Ó=Õ=ûð>úsr   Ã E Ã-F Ã3)E4Ä
F Ä&F Ä9	F Å	E1ÅE,Å&E1Å,E1Å4E=Å9F Æ F	ÆF Æ	F Æ	GÆ1GÇGÇGc                ó&  — ddl m} |j                  d«      dk(  rdnd}d| › d�} |d| › d	|› �|d
t        | |«      › �t        d| › d�ddddd| › d�¬«
      }|j                  d«      ryt        j                  |j                  d«      xs d| dœ«      S )aÁ  None if approved, else a JSON error string. The decision (yolo bypass, session/permanent grants, CLI prompt,
    gateway pending, cron/unattended policy, fail-closed with nobody to ask) is ``tools.approval``'s shared gate,
    so a computer_use grant is one store entry like any terminal pattern. Scope key ``cua:<action>:<mode>``:
    foreground delivery is a visible focus change, so a background ``session`` grant must NOT cover it (#67052).
    r   )Ú_run_approval_gaterI   rJ   Ú
backgroundzAllow computer_use to perform `z`?zcua:ú:zcomputer_use: zcomputer_use `z` requires approvalzdesktop actionsz=Find an alternative approach that avoids driving the desktop.z:computer_use action in non-interactive non-gateway contextTzBLOCKED: computer_use `zP` requires approval but no interactive user or gateway is present to approve it.)
Úpattern_keyÚdescriptionÚdisplay_targetÚapproval_callbackÚsubjectÚnounÚadviceÚautoapprove_log_prefixÚfail_closed_when_no_humanÚno_human_block_messageÚapprovedNÚmessagezdenied by user)rB   rS   )r‡   r  r-   Ú_summarize_actionr   rO   rP   )rS   r@   r  rë   r  rÐ   s         r   r  r  >  sÀ   € õ 2àŸ8™8 OÓ4¸ÒD‰<È,€DØ3°F°8¸2Ð>€KÙØ˜6˜( ! D 6Ð*¸Ø'Ô(9¸&À$Ó(GÐ'HÐIÔ]oØ   Ð(;Ð<ÐCTØNØ[Ø"&Ø"9¸&¸ð BDð !Dô	€Fð ‡z�z�*ÔØÜ�:‰: §
¡
¨9Ó 5Ò IÐ9IÐU[Ñ\Ó]Ð]r   c                ó’   — |j                  d«      dk(  rdnd}t        j                  | t        d «      «      j                  | ||«      S )NrI   rJ   u;    [FOREGROUND â€” briefly raises the window / changes focus]r=   )r-   r
  Ú_ActionSpecÚ	summarize)rS   r@   Úfgs      r   r$  r$  V  sB   € ØJNÏ(É(ÐSbÓJcÐgsÒJsÑ	FÐy{€BÜ�<‰<˜¤¨DÓ 1Ó2×<Ñ<¸VÀTÈ2ÓNÐNr   c                ór   — | j                  d«      x}r|d   �t        |d   |d   ¬«      S t        dd¬«      S )zVClick semantics: a coordinate only counts when its x is set (a bare y is not a point).Ú
coordinater   Nrm   ©ÚxÚy©r-   r×   ©r@   Úcoords     r   Ú_xyr1  ]  sE   € à59·X±X¸lÓ5KÐ,K¨EÐ,KÐQVÐWXÑQYÐQeŒ4�%˜‘(˜e A™hÔ'ÐÔkoÐrvÐz~ÔkÐr   c                ó€   — | j                  d«      xs d}t        |r
|d   �|d   nd|r|d   �
|d   ¬«      S d¬«      S )ud   Scroll semantics: axes are independent â€” ``coordinate=[null, 100]`` scrolls at y=100 with x unset.r*  ©NNr   Nrm   r+  r.  r/  s     r   Ú
_scroll_xyr4  a  sX   € à�H‰H�\Ó"Ò2 l€EÜ™e¨¨a©Ð(<�%˜’(À$Ù#¨¨a©Ð(<�%˜‘(ôHð HØBFôHð Hr   c           	     ó¶   —  | j                   dd|j                  d«      it        |«      ¤|xs |j                  d«      xs d||j                  d«      dœ¤|¤ŽS )Nrû   ÚbuttonÚleftÚ	modifiers)r6  Úclick_countr8  r´   )rö   r-   r1  )rZ   rS   r@   r6  ÚcountÚdeliverys         r   Ú	_do_clickr<  g  sk   € Øˆ7�=‰=ñ Y §¡¨)Ó!4ð Y¼¸D»	ð YÈ&ÒJpÐTX×T\ÑT\Ð]eÓTfÒJpÐjpØ%*°d·h±h¸{Ó6KòYØOWñYð Yr   c                ó   — |j                  d«      |j                  d«      }}|j                  d«      �|j                  d«      €|r|st        j                  ddi«      S  | j                  d|j                  d«      |j                  d«      |rt	        |«      nd |rt	        |«      nd |j                  dd«      |j                  d	«      d
œ|¤ŽS )NÚfrom_coordinateÚto_coordinateÚfrom_elementÚ
to_elementrB   zFdrag requires from_coordinate/to_coordinate or from_element/to_elementr6  r7  r8  )r@  rA  Úfrom_xyÚto_xyr6  r8  r´   )r-   rO   rP   r÷   Útuple)rZ   rS   r@   r;  ÚsrcÚdsts         r   Ú_do_dragrG  k  sÁ   € Ø�x‰xÐ)Ó*¨D¯H©H°_Ó,Eˆ€CØ�‰�Ó Ð(¨D¯H©H°\Ó,BÐ,JÑUXÑ]`Ü�z‰z˜7Ð$lÐmÓnÐnØˆ7�<‰<ð h T§X¡X¨nÓ%=È$Ï(É(ÐS_ÓJ`Ù.1¤ c¤
°tÑQTÄ5ÈÄ:ÐZ^Ø#Ÿx™x¨°&Ó9ÀTÇXÁXÈkÓEZñhà^fñhð hr   c           
     óÚ   —  | j                   d|j                  dd«      t        |j                  dd«      «      |j                  d«      dœt        |«      ¤d|j                  d«      i¤|¤ŽS )	NÚ	directionÚdownÚamounté   rû   )rI  rK  rû   r8  r´   )rø   r-   ro   r4  ©rZ   rS   r@   r;  s       r   Ú
_do_scrollrN  s  sv   € Øˆ7�>‰>ð x D§H¡H¨[¸&Ó$AÌ#ÈdÏhÉhÐW_ÐabÓNcÓJdØ"&§(¡(¨9Ó"5ñxÜ9CÀDÓ9IñxØUY×U]ÑU]Ð^iÓUjñxØnvñxð xr   c                ó&  — t        |j                  dd«      «      x}dvrt        j                  dd|›d�i«      S t	         | j
                  d||j                  d«      dœd	D �ci c]  }|j                  |«      €Œ|||   “Œ c}¤Ž|¬
«      S c c}w )Nrë   rð   >   Úaxrð   ÚvisionrB   z	bad mode z; use som|vision|axrì   )rë   rì   ©rí   rî   rw   r´   )r‹   r-   rO   rP   Ú_capture_responserê   )rZ   rS   r@   rq   r¼   rë   Úks          r   Ú_do_capturerU  w  sŸ   € Ü�D—H‘H˜V UÓ+Ó,Ð,ˆÐ5LÑLÜ�z‰z˜7 i°¨xÐ7JÐ$KÐLÓMÐMä˜_˜WŸ_™_ð v°$¸D¿H¹HÀU»Oñ vØDXÖ/t¸qÐ\`×\dÑ\dÐefÓ\gÑ\s°°4¸±7±
Ò/tñvà(2ô4ð 4ùÚ/ts   Á$BÁ;Bc                óh   — t        j                  | t        | |«      «       x}dt        |«      i«      S )Nr:  )rO   rP   rY   Úlen)rZ   rS   r@   rD   r¼   rÇ   s         r   Ú_do_listingrX    s1   € Ü�:‰:�sÐ&>¤g¨g°vÓ&>Ó&@Ð@˜UÀ7ÌCÐPUËJÐWÓXÐXr   c                óŒ   — |j                  d«      �d|d   › �n#|j                  d«      rdt        |d   «      › �nd}| › |› |› �S )Nrû   z
 element #r*  z at r=   )r-   rD  )rS   r@   r(  Úwheres       r   Ú_summarize_clickr[  ‚  sZ   € Ø/3¯x©x¸	Ó/BÐ/Nˆz˜$˜y™/Ð*Ñ+Ø8<¿¹ÀÔ8N�Dœ˜t LÑ1Ó2Ð3Ñ4ÐTVð 
àˆX�e�W˜R˜DÐ!Ð!r   r&  z#handler input destructive summarizeFc                ó   — | |z   S r   r´   ©Úar@   r(  s      r   r¶   r¶   ‹  s
   € ÀQÈÁV€ r   )ÚdefaultsT)Úinputr  )r'  )r:  Úright)r6  Úmiddlec                óž   — d|j                  d«      xs |j                  d«      › d|j                  d«      xs |j                  d«      › |› �S )Nzdrag r@  r>  u    â†’ rA  r?  ©r-   r]  s      r   r¶   r¶   “  sZ   € ¸eÀDÇHÁHÈ^ÓD\ÒD{Ð`d×`hÑ`hÐizÓ`{ÐC|ð  }BØ@DÇÁÈÓ@VÒ@sÐZ^×ZbÑZbÐcrÓZsÐ?tÐuwÐtxð=z€ r   c                óV   — d|j                  dd«      › d|j                  dd«      › |› �S )Nzscroll rI  ú?z xrK  rL  rd  r]  s      r   r¶   r¶   •  sE   € ÀÈÏÉÐR]Ð_bÓIcÐHdÐdfÐgk×goÑgoÐpxÐz{Óg|Ðf}ð  Að  ~Bð  @C€ r   c                óH   —  | j                   |j                  dd«      fi |¤ŽS )Nr<   r=   )r  r-   rM  s       r   r¶   r¶   –  s'   € Ð=N¸W×=NÑ=NÈtÏxÉxÐX^Ð`bÓOcÑ=pÐgoÑ=p€ r   c                óˆ   — d|j                  dd«      d d ›�t        |j                  dd«      «      dkD  rdz   |z   S dz   |z   S )Nztype r<   r=   é<   z...)r-   rW  r]  s      r   r¶   r¶   —  sx   € °5¸¿¹À&È"Ó9MÈcÈrÐ9RÐ8UÐ1VÔcfÐgk×goÑgoÐpvÐxzÓg{Óc|ð  @Bò  dBÐZ_ñ  2Kð  NPñ  2P€ ð  HJñ  2Kð  NPñ  2P€ r   c                óH   —  | j                   |j                  dd«      fi |¤ŽS )Nr7   r=   )rD   r-   rM  s       r   r¶   r¶   ˜  s$   € ¸K¸G¿K¹KÈÏÉÐQWÐY[ÓH\Ñ<iÐ`hÑ<i€ r   c                ó0   — d|j                  dd«      ›|› �S )Nzkey r7   r=   rd  r]  s      r   r¶   r¶   ™  s   € °$°t·x±xÀÈÓ7KÐ6NÈrÈdÐ0S€ r   c                ó®   — |j                  d«      €t        j                  ddi«      S | j                  t	        |d   «      |j                  d«      ¬«      S )Nrú   rB   zset_value requires `value`rû   )rú   rû   )r-   rO   rP   rù   r‹   ©rZ   rS   r@   r¼   s       r   r¶   r¶   š  sQ   € Ø?C¿x¹xÈÓ?PÐ?XŒ�
‰
�GÐ9Ð:Ó;ð à×Ñ¤S¨¨g©Ó%7ÀÇÁÈ)ÓATÐÓUð r   c                ó®   — |j                  d«      st        j                  ddi«      S | j                  |d   t	        |j                  d«      «      ¬«      S )Nrì   rB   zfocus_app requires `app`rÿ   )rÿ   )r-   rO   rP   rþ   r‰   rm  s       r   r¶   r¶   �  sM   € ØAEÇÁÈ%ÄŒ�
‰
�GÐ7Ð8Ó9ð à×Ñ˜t E™{¼¸d¿h¹hÀ~Ó>VÓ9WÐÓXð r   c                ó\   — d|j                  dd«      ›�|j                  d«      rdz   S dz   S )Nzfocus rì   r=   rÿ   z (raise)rd  r]  s      r   r¶   r¶      s5   € ¨¨t¯x©x¸¸rÓ/BÐ.EÐ&FÐX\×X`ÑX`ÐaoÔXpÈ*Ñ&y€ ÐvxÑ&y€ r   )r  r'  c           
     óh   — t        | j                  t        |j                  dd«      «      «      «      S )NÚsecondsç      ð?)Ú_text_responseÚwaitÚfloatr-   rm  s       r   r¶   r¶   ¢  s*   € ¼>È'Ï,É,ÔW\Ð]a×]eÑ]eÐfoÐqtÓ]uÓWvÓJwÓ;x€ r   Úapps©rD   r'   )rö   Údouble_clickÚright_clickÚmiddle_clickr÷   rø   r:   rD   rù   rþ   rê   rt  rü   rý   zDict[str, _ActionSpec]r
  c              #  ó@   K  — | ]  \  }}|j                   sŒ|–— Œ y ­wr   )r`  )r.   r^  Úss      r   r0   r0   §  s   è ø€ ÒE¡  A¸Q¿W»Wœ1ÑEùs   ‚—rD   r:   rê   rö   )ÚhotkeyÚ	press_keyÚkeypressÚ	key_comboÚshortcutr  Ú
input_textÚ
screenshotÚget_window_stateÚ
left_clickÚmouse_clickc                óú  — t         j                  |«      }|€Jt        j                  dd|›�t        j                  t        |«      «      x}rd|›d�z   i«      S dz   i«      S |j                  r�t        |j                  d«      x}t
        «      r`|j                  «       rPt        | |«      x}�Bt        j                  d|d|› d	|›d
|j                  «       ›d|j                  «       ›d�dœ«      S  |j                  | ||f|j                  d«      t        |j                  d«      «      dœ|j                  ri nd|i¤Ž}t        |t
        t        f«      r|S t        | |t        |j                  d«      «      |¬«      S )NrB   zunknown action u    â€” did you mean z)? See the action enum in the tool schema.r=   rì   FÚinput_target_mismatchz  would go to the current target z, not ub    â€” input actions always hit the sticky target from the last capture/focus_app. Call capture(app=z!) or focus_app first, then retry.)rÔ   rS   rL   rB   rI   rH   )rI   rH   rq   Úcapture_afterrw   )r
  r-   rO   rP   Ú_ACTION_SUGGESTIONSr‹   r`  Ú
isinstancer2   r_   Úhandlerr‰   r×   Ú_maybe_follow_capture)	rZ   rS   r@   rq   ÚspecrC   r[   ÚmismatchÚress	            r   r  r  ¯  sÀ  € Ü�<‰<˜Ó€DØ€|Ü�z‰z˜7 o°f°ZÐ$@ÜM`×MdÑMdÔehÐioÓepÓMqÐEqÀTÐEqð GYÐY]ÐX`ð  aJð  EKñ %|ð }ó ~ð 	~Øxzñ%|ð }ó ~ð 	~ð 	�
Š
”z°4·8±8¸E³?Ð"B -ÄCÔHÈ]×M`ÑM`ÔMbÜ3°G¸]ÓKÐK�ÐXÜ�z‰z °&ÐBYØˆhÐ6°x°lÀ&È×I\ÑI\ÓI^ÐHað b à -× 3Ñ 3Ó 5Ð8Ð8Yð[ñ]ó ^ð 	^ð ˆ$�,‰,�w ¨ð ~¸D¿H¹HÀ_Ó<UÜ&*¨4¯8©8Ð4DÓ+EÓ&Fñ~ØQU×Q[ÒQ[É2ÐbnÐpzÐa{ñ~€Cä˜S¤3¬ +Ô.ˆ3ð `Ô4IÈ'ÐSVÔX\Ð]a×]eÑ]eÐfuÓ]vÓXwØT^ô5`ð `r   c                óF  — | j                   dk(  s| j                  du rddiS | j                   dk(  rdddœS | j                   d	k(  s| j                  r| j                  �Add
it	        | j
                  t        «      rd| j
                  j                  d«      ini ¥ddi¥S dddœS )z�Next ladder step from semantic evidence, in precedence order. Escalation is advisory: it never overrides
    a confirmed effect nor licenses repeating input.Ú	confirmedTÚdecisionÚdoneÚunverifiableÚverify_fresh_stateuš   Input was delivered but not confirmed. Re-capture and check the result BEFORE any retry â€” do not repeat the input on an escalation recommendation alone.)r“  rC   Úsuspected_noopÚescalateÚrecommendedrC   u'  The input likely did not land. Climb one rung following `recommended`: 'px' â†’ re-issue by coordinate; 'foreground' (or a failed pixel click) â†’ re-issue with delivery_mode='foreground' (separate approval). Do not predict the rung from the app being Electron/Chromium â€” react to this signal.zYTransport succeeded but the effect is unproven. Re-capture and confirm before continuing.)ÚeffectÚverifiedrÔ   rL   r‹  Ú
escalationr×   r-   ©r�  s    r   Ú_classify_action_resultrž  Ä  sÇ   € ð ‡z�z�[Ò  C§L¡L°DÑ$8Ø˜FÐ#Ð#Ø
‡z�z�^Ò#Ø0ð <mñ oð 	oà
‡z�zÐ%Ò%¨S¯VªV°s·x±xÐ7KØ˜Jð gÜ.8¸¿¹ÌÔ.Nð -:¸3¿>¹>×;MÑ;MÈmÓ;\Ñ+]ØTVðgØY_ðeñgð 	gð
 -Øoñqð qr   c                 ó\   — | j                  «       D ��ci c]  \  }}|sŒ	||“Œ c}}S c c}}w r   )rÇ   )ÚfieldsrT  Úvs      r   Ú_presentr¢  Õ  s&   € Ø#Ÿ\™\›^×1‘T�Q˜ªqˆAˆq‰DÓ1Ð1ùÓ1s   ”
(Ÿ(c                óî   — | j                   | j                  dœt        | j                  ¬«      ¥dD �ci c]  }t	        | |«      x}�||“Œ c}¥t        | j
                  ¬«      ¥dt        | «      i¥S c c}w )NrÓ   )r#  )r›  rš  rœ  ÚpathÚdegradedrI   rL   )r)   Úverdict)rÔ   rS   r¢  r#  rY   r)   rž  )r�  rT  r¡  s      r   Ú_action_payloadr§  Ø  s‚   € ð —&‘& C§J¡Jñ 5´(À3Ç;Á;Ô2Oð 5Ønö 6˜Ü  Q›Ð'�1Ð4ð �!‰tò 6ð5ä9AÀsÇxÁxÔ9Pð5ð Ô.¨sÓ3ñ5ð 5ùò6s   ³A2c                ó>   — t        j                  t        | «      «      S r   )rO   rP   r§  r�  s    r   rs  rs  à  s   € Ü�:‰:”o cÓ*Ó+Ð+r   éd   é   éx   é   c                ó˜   — | j                   xs# | j                  xs dj                  d«      rdnd}||j                  «       dk(  rdfS dfS )Nr=   z/9j/z
image/jpegz	image/pngú.jpgz.png)Úimage_mime_typeró   Ú
startswithr3   )ÚcapÚmimes     r   Ú_capture_image_formatr³  í  sN   € ð ×ÑÒk°C·K±KÒ4EÀ2×3QÑ3QÐRXÔ3Y¡<Ð_j€DØ˜DŸJ™J›L¨LÒ8�&ÐEÐE¸fÐEÐEr   c                óŽ   — t        j                  t        t        «      5  t	        d„ | D «       «      cd d d «       S # 1 sw Y   yxY w)Nc              3  ó8   K  — | ]  }t        |«      d k(  –— Œ y­w)r   N)ro   )r.   r¡  s     r   r0   z"_bounds_unknown.<locals>.<genexpr>÷  s   è ø€ Ò/ 1”3�q“6˜Q•;Ñ/ùs   ‚F)rƒ   r„   Ú	TypeErrorÚ
ValueErrorÚall)Úboundss    r   Ú_bounds_unknownrº  ó  s:   € ô 
×	Ñ	œY¬
Ó	3ñ 0ÜÑ/¨Ô/Ó/÷0÷ 0ñ 0àús	   Ÿ;»Ac                ó
  — | j                   | j                  | j                  d t         t	        | j
                  «      rd nt        | j
                  «      | j                  dœt        | j                  «      t        kD  rddi¥S i ¥S )N©ÚindexÚroleÚlabelr¹  rì   Úlabel_truncatedT)	r½  r¾  r¿  Ú_MAX_ELEMENT_LABEL_CHARSrº  r¹  Úlistrì   rW  rµ   s    r   Ú_element_to_dictrÃ  ú  sy   € à—W‘W a§f¡f°q·w±wÐ?XÔ@XÐ7YÜ-¨a¯h©hÔ7‘d¼TÀ!Ç(Á(»^ÐTU×TYÑTYñ^ä,/°·±«LÔ;SÒ,SÐ! 4Ð(ð^ð ^àY[ð^ð ^r   c                ó”  — | d | D �cg c]Ž  }d|j                   › d|j                  › d|j                  j                  t	        d«      d«      d d ›d�t        |j                  «      rdnd|j                  › �z   |j                  rd|j                  › d�nd	z   ‘Œ� }}|t        | «      |kD  rd
t        | «      |z
  › d�gz   S g z   S c c}w )Nz  #Ú é
   ri  z)@ bounds-unknown (click by element index)z@ z [ú]r=   z  ... +z( more (call capture with app= to narrow))	r½  r¾  r¿  ÚreplaceÚchrrº  r¹  rì   rW  )rô   Ú	max_linesr«   Úouts       r   Ú_format_elementsrÌ     sù   € ð 8@À
ÀÐ7KöMà23ð �—‘�	˜˜1Ÿ6™6˜( ! A§G¡G§O¡O´C¸³G¸SÓ$AÀ#À2Ð$FÐ#IÈÐKÜ=LÈQÏXÉXÔ=VÑ9Ð^`Ðab×aiÑaiÐ`jÐ\kñmà Ÿušu��1—5‘5�'˜‰m¨"ó.ð M€Cð Mð ÔehÐiqÓerÐu~Òe~�WœS ›]¨YÑ6Ð7Ð7_Ð`Ðañ  Hð  Hð  EGñ  Hð  HùòMs   ˆBCc           	     ó€  — | r
|dk  s|dk  rydx}}| D ]V  }	 |j                   \  }}}}	t        |t	        |«      t	        |«      z   «      t        |t	        |«      t	        |	«      z   «      }}ŒX ||dz  k  r	||dz  k  ryd|› d|› d|› d|› d�	}
t        t        ||z  ||z  «      d«      |
fS # t        t        f$ r Y Œ¨w xY w)	aœ  (scale, note) when element bounds live in a different coordinate space than the screenshot, else (None, None).
    On HiDPI displays AX bounds are native while the screenshot is downscaled, so coordinate= clicks read off the
    screenshot miss by the scale factor. 5% slack: window chrome can hang a few px past the captured frame without
    implying a different space. Scale heuristic: larger axis ratio wins.r   r3  gÍÌÌÌÌÌð?z=element bounds are in native desktop coordinates (extend to ~r,  z), NOT screenshot pixels (u‡   ). coordinate= clicks expect the native space â€” derive click points from element bounds, or scale screenshot positions up accordinglyrh   )r¹  r¶  r·  Úmaxro   Úround)rô   Úimage_widthÚimage_heightÚmax_xÚmax_yr«   r,  r-  ÚwÚhÚnotes              r   Ú_bounds_hintsr×    s  € ñ
 �{ aÒ'¨<¸1Ò+<ØØÐ€EˆEØò Pˆð	ØŸ™‰JˆAˆq�!�Qô ˜5¤# a£&¬3¨q«6¡/Ó2´C¸¼sÀ1»vÌÈAË¹Ó4Oˆu‰ðPð �˜dÑ"Ò" u°¸tÑ0CÒ'CØØKÈEÈ7ÐRSÐTYÐSZð [&Ø&1 ]°!°L°>ð Bnðn€Dô ”�U˜[Ñ(¨%°,Ñ*>Ó?ÀÓCÀTÐIÐIøô œ:Ð&ò 	Ùð	ús   ˜B+Â+B=Â<B=c                ó"   — t        | ||«      d   S )Nr   ©r×  ©rô   rÐ  rÑ  s      r   r¶   r¶     s   € ¼MÈ(ÐT_ÐamÓ<nÐopÑ<q€ r   c                ó"   — t        | ||«      d   S ©Nrm   rÙ  rÚ  s      r   r¶   r¶     s   € ÄÈxÐYdÐfrÓAsÐtuÑAv€ r   c                ó   — | j                   d| d}}t        j                  t        «      5  | j                  r*t        t        j                  | j                  d¬«      «      nd}ddd«       |xs | j                  | j                  f\  }}t        |||«      \  }}t        | j                   «      t        |«      kD  xs t        d„ |D «       «      }t        |«      xr t        |«      t        k  }	t        | j                  «      xr | j                   dk7  xr |	 }
t        | j                   «      | j"                  cxk\  xr dkD  nc }t%        | |t        | j                   «      ||t        | j                   «      t        |«      z
  |||r| j"                  nd|rt'        | «      nd|
rt)        | «      nd|	r||
¬«      S d|
¬«      S # 1 sw Y   �ŒaxY w)z§One capture's derived facts, computed once for every response branch: ``visible`` is the capped element list,
    ``dims_omitted`` an image below the provider minimum.NF©Úvalidatec              3  óT   K  — | ]   }t        |j                  «      t        kD  –— Œ" y ­wr   )rW  r¿  rÁ  )r.   r«   s     r   r0   z _capture_view.<locals>.<genexpr>'  s   è ø€ Ò9sÐfg¼#¸a¿g¹g»,ÔIaÕ:aÑ9sùs   ‚&(rP  r   )r±  ÚvisibleÚtotalrñ   rò   Ú	truncatedÚbounds_scaleÚbounds_noteÚ	ax_cappedÚelements_fileÚscreenshot_pathÚdims_omittedÚ	has_image)rô   rƒ   r„   r…   ró   r   Úbase64Ú	b64decoderñ   rò   r×  rW  Úanyr‰   ÚminÚ_MIN_PROVIDER_IMAGE_DIMENSIONrë   Úax_max_elementsr   Ú_spill_elements_to_fileÚ_persist_capture_image)r±  Úmax_elementsrá  Údimsrñ   rò   ÚscalerÖ  Úlost_detailÚ	too_smallrê  ræ  s               r   Ú_capture_viewrø    s›  € ð —L‘L  ,Ð/°ˆT€GÜ	×	Ñ	œYÓ	'ñ sØ]`×]hÒ]hÔ*¬6×+;Ñ+;¸C¿K¹KÐRWÔ+XÔYÐnrˆ÷sàÒ3˜SŸY™Y¨¯
©
Ð3�M€Eˆ6Ü ¨°Ó7�K€Eˆ4ä�c—l‘lÓ#¤c¨'£lÑ2Òs´cÑ9sÐkrÔ9sÓ6s€KÜ�T“
ÒHœs 4›yÔ+HÑH€IÜ�S—[‘[Ó!ÒH c§h¡h°$Ñ&6ÒH¸y¸=€Iô �C—L‘LÓ! S×%8Ñ%8Ö<¸1Ô<€IÜ˜s¨G¼3¸s¿|¹|Ó;LÐTYÐbhÜ%(¨¯©Ó%6¼¸W»Ñ%EÐTYÐgkÙ<E S×%8Ò%8È1ÙITÔ)@ÀÔ)EÐZ^ÙJSÔ+AÀ#Ô+FÐY]Ù09¨ÈyôZð Zð
 @DÈyôZð Z÷sñ sús   «9GÇGc           
     ó�  — | j                   xr8 | j                   | j                  rd| j                  › d| j                  › d�ndz   | j                  xr d| j                  › �| j                  j                  | j
                  xr  | j                  rdnd› d| j
                  › d�| j                  xr d	| j                  › d
�f}d| j                  j                  › d| j                  › d| j                  › �| j                  j                  rd| j                  j                  › �ndz   | j                  j                  rd| j                  j                  ›�ndz   | j                  › d�gd„ |D «       ¢t        | j                  «      ¢| j                  r3d| j                  d   › d| j                  d   › dt         › dt         › d�	g¢S g ¢S )zšHuman-readable capture summary; line ORDER is contract. Lists only what `elements` surfaces, otherwise the
    summary names indices the model can't find.z; estimated scale ~zx (screenshot position x u    â‰ˆ native coordinate)r=   zshareable screenshot saved to zfull z.element tree with untruncated labels saved to uX    â€” read_file/search_files it if you need dropped label text or elements beyond the capzaccessibility walk capped at z elements; pass app= to narrowzcapture mode=rÅ  r,  z app=z window=z interactable element(s):c              3  ó.   K  — | ]  }|sŒd |› d�–— Œ y­w)z  (ú)Nr´   )r.   rÖ  s     r   r0   z)_capture_summary_lines.<locals>.<genexpr>E  s   è ø€ Ò	2˜DªTˆC�ˆv�QŒ-Ñ	2ùs   ‚Šz  (screenshot omitted: r   rm   z is below the z provider minimum))rå  rä  rè  r±  rÖ  rç  ræ  rë   rñ   rò   rì   rõ   râ  rÌ  rá  ré  rï  )r¡  Únotess     r   Ú_capture_summary_linesrý  4  så  € ð 	
�‰ò 	q˜!Ÿ-™-ØYZ×YgÒYgð .AÀÇÁÐ@PÐPiØ./¯n©nÐ-=Ð=Tñ,VØmoñqà	×ÑÒRÐ >¸q×?PÑ?PÐ>QÐRØ	�‰�
‰
Ø	�‰ò 	@ a§k¢k¡°wÐ?ð @)Ø)*¯©Ð(9ð :?ð?ð 	
�‰ÒeÐ8¸¿¹¸ÐEcÐdð	€Eð ˜Ÿ™Ÿ
™
�| 1 Q§W¡W I¨Q¨q¯x©x¨jÐ9Ø"#§%¡%§)¢)ˆU�1—5‘5—9‘9�+Ñ°ñ	5Ø]^×]bÑ]b×]oÒ]o¸(À1Ç5Á5×CUÑCUÐBXÑ8YÐuwñ	yà�7‰7ˆ)Ð,Ð-ðñ 
3 EÔ	2ð	ô
 
˜!Ÿ)™)Ó	$ðð ef×drÒdrð % Q§^¡^°AÑ%6Ð$7°q¸¿¹ÈÑ9JÐ8KÈ>Ü+Ð,¨AÔ.KÐ-LÐL^ð`ð aðð ð y{ðð r   c                ó¸  — t        j                  | j                  j                  | j                  | j
                  | j                  j                  | j                  j                  | j                  D �cg c]  }t        |«      ‘Œ c}| j                  |dœ|xs i ¥t        | j                  | j                  | j                  | j                  ¬«      ¥«      S c c}w )z¦JSON text payload shared by the AX, vision-unavailable and aux-vision branches. Key order is contract:
    fixed fields, ``extra`` branch markers, then set optionals.)rë   rñ   rò   rì   rõ   rô   Útotal_elementsÚsummary)Útruncated_elementsrç  rè  rä  )rO   rP   r±  rë   rñ   rò   rì   rõ   rá  rÃ  râ  r¢  rã  rç  rè  rä  )r¡  r   Úextrar«   s       r   Ú_text_capture_payloadr  K  sª   € ô �:‰:Ø—‘—
‘
 Q§W¡W¸¿¹ÈÏÉÏÉÐde×diÑdi×dvÑdvØ23·)±)Ö<¨QÔ% aÕ(Ò<ÐPQ×PWÑPWÐdkñð Š;�Bðô  a§k¡kÀÇÁÐbc×bsÑbsØ !§¡ô0ð	ó ð ùâ<s   Á3Cc                óÜ   — t        j                  t        | j                  xs d«      dz   j	                  d«      | j
                  xs dj	                  dd«      z   «      j                  «       S )Nr=   r  úutf-8ÚasciiÚignore)ÚhashlibÚsha256r‹   r¯  Úencoderó   Ú	hexdigest©r±  s    r   Ú_capture_digestr  V  s]   € Ü�>‰>œ3˜s×2Ñ2Ò8°bÓ9¸CÑ?×GÑGÈÓPØ Ÿ[™[Ò.¨B×6Ñ6°wÀÓIñJó KßKTÉ9Ë;ðWr   c           	     óè  — t        | |«      }t        |«      }dj                  |«      d }}|j                  rg|ret	        t        |«      t        | «      t        | j                  xs d«      t        | j                  xs d«      f«      r|j                  d«       ddi}nù|j                  rít        «       s‘dd|dœdd	d
t        | «      d   › d| j                  › �idœg|| j                  |j                  |j                   |j"                  | j$                  dœt'        |j(                  |j*                  |j,                  ¬«      ¥dœS t/        | ||j0                  |j2                  |j*                  |j(                  ¬«      }|�|S |j                  d«       ddi}|j2                  r5|j                  dt5        |j0                  «      › d|j"                  › d�«       t7        |dj                  |«      |«      S )NÚ
r=   uá     (screen unchanged since the previous capture â€” image omitted to save context; the previous capture's screenshot/analysis still shows the current state. Element indices below are fresh and remain the preferred way to act.)Úscreen_unchangedTr<   )r:   r<   Ú	image_urlÚurlzdata:r   z;base64,)r:   r  )rë   rñ   rò   rô   Ú	png_bytes)rè  rç  rä  )Ú_multimodalÚcontentÚtext_summaryr)   ©Úvisible_elementsr  rç  rè  u£     (vision unavailable: the auxiliary vision model could not be reached; screenshot omitted. Element-index actions still work â€” drive via the element list above.)Úvision_unavailablez  (response truncated to z of ui    elements; the full tree is in elements_file â€” read_file/search_files it, or pass app= to narrow scope))rø  rý  Újoinrê  rs   rz   r  r‹   rì   rõ   rÖ   Ú _should_route_through_aux_visionr³  ró   rë   rñ   rò   râ  Úpng_bytes_lenr¢  rè  rç  rä  Ú!_route_capture_through_aux_visionrá  rã  rW  r  )r±  ró  rq   r¡  Úlinesr   r  Úrouteds           r   rS  rS  Z  s  € ä�c˜<Ó(€AÜ" 1Ó%€EØ—Y‘Y˜uÓ% tˆU€GØ‡{‚{‘zÔ&=Ü˜
Ó#¤_°SÓ%9¼CÀÇÁÂÈ2Ó<NÔPSÐTW×TdÑTdÒTjÐhjÓPkÐ;lô'nð 	�‰ð =ô 	>ð $ TÐ*‰Ø	
�Šô 0Ô1à#Ø%+°WÑ=Ø%0ÀÈÔOdÐehÓOiÐjkÑOlÐNmÐmuÐvy÷  wBñ  wBð  vCð  HDð  @Eñ  FðGà 'Ø!$§¡°A·G±GÀqÇxÁxÐ]^×]dÑ]dÐsv÷  tEñ  tEñ DÜ#°A×4EÑ4EÐUV×UdÑUdÐst÷  tBñ  tBô  CðDñð ô 3Ø�¨1¯9©9ÈÏÉØŸ/™/¸1×;LÑ;LôNˆð ÐØˆMð 	�‰ð hô 	ià% tÐ,ˆØ‡{‚{Ø�‰Ð0´°Q·Y±Y³Ð0@ÀÀQÇWÁWÀIð Nbð bô 	cä   D§I¡I¨eÓ$4°eÓ<Ð<r   c           
     ó´  — |r|j                   st        |«      S 	 dD �ci c]#  }|t        | dd «      xs i j                  |«      “Œ% }} | j                  ddt        «       id |j                  «       vr|ndt        | dd «      i¤Ž}t        ||¬«      t        |«      }	}t        |t        «      rD|j                  d«      r3t        j                  |	«      d	z   |d
   z   x|d   d   d<   |d
<   |	|d<   |S t        j                  i t        j                   |«      ¥|	¥«      S c c}w # t        $ r+}t        j                  d|«       t        |«      cY d }~S d }~ww xY w)NrR  Ú_last_targetrë   rì   rX   zfollow-up capture failed: %srw   r  z

r  r  r   r<   Úaction_resultr´   )rÔ   rs  rY   r-   rê   Ú_capture_after_moderÊ   r…   r�   rŽ   rS  r§  r‹  r×   rO   rP   Úloads)
rZ   r�  Ú
do_capturerq   rT  Úexactr±  r«   ÚrespÚpayloads
             r   r�  r�  †  se  € ñ ˜SŸVšVÜ˜cÓ"Ð"ð#ð ThÖhÈa�”W˜W n°dÓ;ÒA¸r×FÑFÀqÓIÑIÐhˆÐhØˆg�o‰oñ pÔ#6Ó#8ð pÀdÐRW×R^ÑR^ÓR`ÑF`¹UØBGÌÐQXÐZeÐgkÓIlÐAmñpˆô
 & c°jÔAÄ?ÐSVÓCWˆ'€DÜ�$œÔ $§(¡(¨=Ô"9ä<@¿J¹JÀwÓ<OÐRXÑ<XÐ[_Ð`nÑ[oÑ<oÐoˆˆY‰˜Ñ˜6Ñ" T¨.Ñ%9Ø 'ˆˆ_ÑØˆÜ�:‰:Ð5œŸ™ DÓ)Ð5¨WÐ5Ó6Ð6ùò iøô ò #Ü�‰Ð5°qÔ9Ü˜cÓ"Õ"ûð#ús.   ›D# Ÿ(DÁ?D# ÄD# Ä#	EÄ, EÅEÅEc           	     ób  — ddl m}  || |«      }|j                  dd¬«       t        j                  t
        «      5  |rt        |j                  |«      d„ ¬«      ng }|dt        dt        |«      |dz
  z
  «       D ]  }|j                  d¬	«       Œ 	 ddd«       ||z  S # 1 sw Y   ||z  S xY w)
zµPath for a new file under ``$HERMES_HOME/<subdir>`` (dir created). With ``pattern``/``cap``, first unlinks the
    oldest matching files so at most ``cap - 1`` remain (best-effort).r   )Úget_hermes_dirT)ÚparentsÚexist_okc                ó6   — | j                  «       j                  S r   )ÚstatÚst_mtime©r/   s    r   r¶   z_cache_file.<locals>.<lambda>¤  s   € ¸a¿f¹f»h×>OÑ>O€ r   rw  Nrm   )Ú
missing_ok)r±   r*  Úmkdirrƒ   r„   r…   rR   ÚglobrÎ  rW  Úunlink)	ÚsubdirÚlegacyrß   r?   r±  r*  Ú	cache_dirÚfilesÚstales	            r   Ú_cache_filer:  �  s¯   € õ 0Ù˜v vÓ.€IØ‡O�O˜D¨4€OÔ0Ü	×	Ñ	œYÓ	'ñ *ÙT[”�y—~‘~ gÓ.Ñ4OÕPÐacˆØÐ;œS ¤C¨£J°#¸±'Ñ$:Ó;Ð<ò 	*ˆEØ�L‰L DˆLÕ)ñ	*÷*ð �tÑÐ÷	*ð �tÑÐús   ¼AB!Â!B.c           	     ó¢   — 	  |t        |||||«      x}«       t        |«      S # t        $ r!}t        j	                  d| |«       Y d}~yd}~ww xY w)u»   Bounded cache write via ``write(path)``; the path, or None on any failure â€” an unwritable cache must never
    break control (a capture keeps working without its spill/screenshot copy).zcomputer_use: %s failed: %sN)r:  r‹   r…   r�   rÃ   )	Úwhatr5  r6  rß   r?   r±  Úwriter¤  Úexcs	            r   Ú_write_cache_filer?  ©  sO   € ðÙ”k &¨&°$¸ÀÓEÐEˆdÔFÜ�4‹yÐøÜò Ü�‰Ð2°D¸#Ô>Üûðús   ‚!$ ¤	A­A	Á	Ac           
     óª   ‡ — ‰ j                   rEt        ddddt        j                  «       j                  › t        ‰ «      d   › �dt        ˆ fd„«      S dS )	ziCopy of the capture in Hermes' media cache so attachment surfaces can deliver it (None without an image).zscreenshot persistencezcache/imagesÚimage_cacheÚcomputer_use_rm   zcomputer_use_*.*c                ód   •— | j                  t        j                  ‰j                  d¬«      «      S )NFrÞ  )Úwrite_bytesrë  rì  ró   )r/   r±  s    €r   r¶   z(_persist_capture_image.<locals>.<lambda>¸  s%   ø€ ¸!¿-¹-Ì×HXÑHXÐY\×YdÑYdÐotÔHuÓ:v€ r   N)ró   r?  ÚuuidÚuuid4Úhexr³  Ú_MAX_CAPTURE_FILESr  s   `r   rò  rò  ´  sm   ø€ ð
 
�Šô Ø  .°-À=ÔQU×Q[ÑQ[ÓQ]×QaÑQaÐPbÔcxÐy|Óc}Ð~ñ  dAð  cBð  BCØÔ.Ó0vóð ð ðr   c                óŒ  ‡— | j                   | j                  t        | j                  «      | j                  D �cg c]E  }|j                  |j
                  |j                  t        |j                  «      |j                   dœ‘ŒG c}dœŠt        ddddt        j                  «       j                  › d�dt        ˆfd	„«      S c c}w )
us   FULL element tree (untruncated labels) in a cache file â€” the read_file/search_files escape hatch for capped text.r¼  )rì   rõ   rÿ  rô   zelement spillzcache/computer_useÚcomputer_use_cacheÚ	elements_z.jsonzelements_*.jsonc                óV   •— | j                  t        j                  ‰dd¬«      d¬«      S )NFrm   )Úensure_asciiÚindentr  )Úencoding)Ú
write_textrO   rP   )r/   r(  s    €r   r¶   z)_spill_elements_to_file.<locals>.<lambda>Â  s$   ø€  q§|¡|´D·J±J¸wÐUZÐcdÔ4eÐpw |Ó'x€ r   )rì   rõ   rW  rô   r½  r¾  r¿  rÂ  r¹  r?  rE  rF  rG  Ú_MAX_SPILL_FILES)r±  r«   r(  s     @r   rñ  rñ  »  s²   ø€ à—g‘g¨s×/?Ñ/?ÔSVÐWZ×WcÑWcÓSdà%(§\¡\ö3Ø !ð '(§g¡g°q·v±vÈÏÉÔ[_Ð`a×`hÑ`hÓ[iÐrs×rwÑrwÓxò 3ñ4€Gô ˜_Ð.BÐDXÐ\eÔfj×fpÑfpÓfr×fvÑfvÐewÐw|ÐZ}Ø.Ô0@Ûxózð zùò3s   ºA
C
i°  c                ó$  — 	 ddl m} ddlm} |j	                   || «      «      }t        |j                  «      |k  r| dfS |j                   |«       c\  }}}|j                  ||f«       |j                  \  }	}
|j                  ||dk(  rdnd¬«       |	r||	z  nd	|
r||
z  nd	}}|d
›|d
›k(  rd|d
›d�n
d|d
›d|d
›d�}|j                  «       d|› d|› d|	› d|
› d|› �
fS # t        $ r$}t        j                  d|«       | dfcY d}~S d}~ww xY w)a$  Downscale encoded image bytes so the longest side is <= max_dim -> ``(bytes, scale_note)``. note is None when
    unchanged (fits, or Pillow unavailable/failed), else it tells the vision model the factor so reported
    coordinates map back to the real screen instead of being silently wrong.r   )ÚBytesIO)ÚImageNr®  ÚJPEGÚPNG)Úformatrr  z.2fz'multiply any coordinates you report by z  to map back to the real screen.z)multiply any x coordinates you report by z and any y coordinates by zScreenshot downscaled from r,  z to z for vision; z*computer_use: vision downscale skipped: %s)ÚiorS  ÚPILrT  ÚopenrÎ  ÚsizeÚ	thumbnailÚsaveÚgetvaluer…   r�   rÃ   )ÚrawÚextÚmax_dimrS  rT  ÚimgÚorig_wÚorig_hrË  Únew_wÚnew_hÚfxÚfyÚfactor_clauser>  s                  r   Ú_shrink_capture_for_visionrj  È  s]  € ðÝÝØ�j‰j™ ›Ó&ˆÜˆs�x‰x‹=˜GÒ#Ø˜�9ÐØ #§¡©'«)ÐÑˆ�˜#Ø�‰�w Ð(Ô)Ø—x‘x‰ˆˆuØ�‰� s¨f¢}™V¸%ˆÔ@Ù$)�&˜5’.¨sÉ°f¸u²nÐSVˆBˆØrtÐuxÐqyð  BDð  EHð  AIò  pJÐBÀ2ÀcÀ(ÐJjÑkØ IÈ"ÈSÈÐQkÐlnÐorÐksð  tTð  Uð 	à�|‰|‹~Ð!<¸V¸HÀAÀfÀXÈTÐRWÐQXÐXYÐZ_ÐY`Ð`mÐn{Ðm|Ð}Ð}Ð}øÜò Ü�‰ÐAÀ3ÔGØ�DˆyÕûðús$   ‚>C" ÁB C" Ã"	DÃ+D
ÄDÄ
Dc                 óz  — d} 	 ddl m}m} ddlm} ddlm} ddlm} d}  |«       xs d |«       xs d}}t        j                   |«       t        |«      t        |«      fx}«      x}	�|	S d
} t         ||| |«       «      «      xt        |<   }
|
S # t        $ r!}t        j                  d| |«       Y d	}~yd	}~ww xY w)zÃTrue when ``_capture_response`` should hand the PNG to aux vision. Any failure returns False (fail open) so a
    broken config never silently drops the screenshot for vision-capable main models.Úimportr   )Ú_read_main_modelÚ_read_main_provider©Úload_config)r¯   )Ú"should_route_capture_to_aux_visionzconfig readr=   Nr“  z.computer_use: aux-vision routing %s failed: %sF)Úagent.auxiliary_clientrm  rn  Úhermes_cli.configrp  r±   r¯   Ú!tools.computer_use.vision_routingrq  rd   r-   r‹   r‰   r…   r�   rÃ   )Ústagerm  rn  rp  r¯   rq  ÚproviderÚmodelrD   r»   r“  r>  s               r   r  r  Þ  sÂ   € ð €EðßPÝ1Ý4ÝXØˆÙ-Ó/Ò5°2Ñ7GÓ7IÒ7OÈR�%ˆÜ-×1Ñ1¹/Ó:KÌSÐQYË]Ô\_Ð`eÓ\fÐ9gÐ2g°#ÓhÐhˆFÐuØˆMØˆÜ26Ñ7YÐZbÐdiÑkvÓkxÓ7yÓ2zÐzÔ Ñ$ xØˆøÜò Ü�‰ÐEÀuÈcÔRÜûðús   „A&B Á+$B Â	B:ÂB5Â5B:c                 ó.  — t        j                  t        «      5  ddlm}  t         | «       xs i j                  d«      xs i j                  dd«      xs d«      }|j                  «       j                  «       x}dv r|ndcddd«       S # 1 sw Y   yxY w)zDMode for ``capture_after`` follow-ups. Default ``som`` (screenshot).r   ro  Úcomputer_useÚcapture_after_moderð   >   rP  rð   rQ  N)	rƒ   r„   r…   rs  rp  r‹   r-   r2   r3   )rp  rë   s     r   r#  r#  ò  s‰   € ä	×	Ñ	œYÓ	'ñ \Ý1Ü‘[“]Ò( b×-Ñ-¨nÓ=ÒCÀ×HÑHÐI]Ð_dÓeÒnÐinÓoˆØ $§
¡
£× 2Ñ 2Ó 4Ð4˜Ð9PÑP‰tÐV[÷\÷ \ñ \ð ús   šA'BÂBak  Describe what is visible in this desktop application screenshot in concise but specific terms. Mention the app name and window title if visible, the overall layout, any labelled buttons, menus or text fields, and any prominent text content the user would need to know about. Do not invent details that are not actually visible.

AX/SOM index for cross-reference:
r  c               ó(  — | j                   syd\  }}	 ddlm} ddlm}	 d}t        j                  | j                   d¬«      }
d}t        | «      d	   }t        d
ddt        j                  «       j                  › |› �«      }t        |
|«      \  }
}|j                  |
«       t        |z   |rd|› �ndz   } | |	t        |«      |«      «      }	 |�@t)        j*                  t         «      5  t-        j.                  t        |«      «       ddd«       t1        |t        «      r|j3                  «       nd}t)        j*                  t4        t6        j8                  «      5  t7        j:                  |«      }t1        |t<        «      r,t        |j?                  d«      xs d«      j3                  «       nd}ddd«       |sytA        | |€| jB                  n|tE        | jB                  «      | jF                  | jH                  |||d¬«	      }tK        |||ddœ«      S # t         $ r‰}|rt"        j%                  d||«       nt"        j'                  d|«       Y d}~|�Mt)        j*                  t         «      5  t-        j.                  t        |«      «       ddd«       y# 1 sw Y   yxY wyd}~ww xY w# 1 sw Y   �Œ¡xY w# |�Mt)        j*                  t         «      5  t-        j.                  t        |«      «       ddd«       w # 1 sw Y   w xY ww xY w# 1 sw Y   �Œ\xY w)zÏPre-analyse the capture via ``vision_analyze_tool`` (temp file under ``$HERMES_HOME/cache/vision/``) and merge
    the description with the AX/SOM summary into one text payload. JSON, or None on any failure.N)zaux-vision import failedNr   )Ú
_run_async)Úvision_analyze_toolzfailed to decode capture base64FrÞ  rm   zcache/visionÚtemp_vision_imagesrB  z

Note: r=   zcomputer_use: %s: %szacomputer_use: auxiliary.vision pre-analysis failed (%s); returning to caller without aux analysisÚanalysis)	r±  rá  râ  rñ   rò   rã  rç  rè  rä  zauxiliary.vision)Úvision_analysisÚvision_analysis_routed_via)&ró   Úmodel_toolsr|  Útools.vision_toolsr}  rë  rì  r³  r:  rE  rF  rG  rj  rD  Ú_VISION_PROMPTr‹   r…   r�   rÃ   rŽ   rƒ   r„   r™   r4  r‹  r2   r¶  rO   ÚJSONDecodeErrorr$  r×   r-   r   rô   rW  rñ   rò   r  )r±  r   r  r  rç  rè  ÚproblemÚtemp_image_pathr|  r}  r_  r`  Ú
scale_noteÚpromptÚresult_jsonr>  Úanalysis_textÚparsedÚviews                      r   r  r  ÿ  s»  € ð
 �;Š;ØØ?Ñ€Gˆ_ð0Ý*Ý:Ø3ˆÜ×Ñ˜sŸ{™{°UÔ;ˆØˆÜ# CÓ(¨Ñ+ˆÜ% nÐ6JÈmÔ\`×\fÑ\fÓ\h×\lÑ\lÐ[mÐnqÐmrÐLsÓtˆÜ4°S¸#Ó>‰ˆˆZØ×#Ñ# CÔ(Ü 'Ñ)É*¨z¸*¸Ñ-FÐZ\Ñ]ˆÙ Ñ!4´S¸Ó5IÈ6Ó!RÓS‰ð Ð&Ü×$Ñ$¤YÓ/ñ 0Ü—	‘	œ#˜oÓ.Ô/÷0ô ,6°kÄ3Ô+G�K×%Ñ%Ô'ÈR€MÜ	×	Ñ	œY¬×(<Ñ(<Ó	=ñ fÜ—‘˜MÓ*ˆÜEOÐPVÔX\ÔE]œ˜FŸJ™J zÓ2Ò8°bÓ9×?Ñ?ÔAÐceˆ÷fñ Øô ˜sÐ<LÐ<T¨C¯LªLÐZjÜ!$ S§\¡\Ó!2¸#¿)¹)ÈCÏJÉJÐbtØ)6ÈÐfjôl€Dô !  wÀMØOañ1có dð døô/ ò ÙÜ�L‰LÐ/°¸#Õ>ä�N‰Nð FØGJôLãàÐ&Ü×$Ñ$¤YÓ/ñ 0Ü—	‘	œ#˜oÓ.Ô/÷0÷ 0ñ 0úð 'ûðú÷0ñ 0ûð Ð&Ü×$Ñ$¤YÓ/ñ 0Ü—	‘	œ#˜oÓ.Ô/÷0÷ 0ñ 0úð 'ú÷
fñ fúsg   ”B8H Ã(J&ÅALÈ	J#È0JÉ
J3 É)JÊJÊJ#Ê#J3 Ê&J0Ê3LËK7Ë.	LË7L Ë<LÌLc                 óB   — t         j                  dvryddlm}   | «       S )zmmacOS/Windows/Linux + cua-driver binary (or env override). `hermes computer-use doctor` names blocked checks.)ÚdarwinÚwin32ÚlinuxFr   ©Úcua_driver_binary_available)ÚsysÚplatformÚ%tools.computer_use.cua_backend_driverr“  r’  s    r   Úcheck_computer_use_requirementsr—  .  s   € ä
‡|�|Ð7Ñ7ØÝQÙ&Ó(Ð(r   c                 ó   — ddl m}  | S )Nr   ©ÚCOMPUTER_USE_SCHEMA)Útools.computer_use.schemarš  r™  s    r   Úget_computer_use_schemarœ  5  s   € Ý=ØÐr   r   )r7   r‹   r  r4   )rS   r‹   r@   úDict[str, Any]r  úOptional[str])r[   r‹   r  rž  )rq   r‹   rj   r‹   rk   úTuple[str, str]r  r‰   r   )rq   rž  r  r  )rq   r‹   r  r  )rq   r‹   r  r‹   )r—   r‹   r  r   )r¢   r‹   rZ   r   r—   r‹   r  r   )r¢   r‹   r  z>Tuple[Optional[ComputerUseBackend], Optional[threading.RLock]])rZ   r   r¥   zOptional[threading.RLock]rª   zCallable[[Exception], None]r  r  )r=   )rq   r‹   r  r   )rq   r‹   r  r‰   )rß   r‹   rà   r‹   rÐ   r   )r@   r�  r  r   )rS   r‹   r@   r�  r  r‹   )r@   r�  r  r�  rÜ  )rS   r‹   r@   r�  r(  r‹   r  r‹   )
rZ   r   rS   r‹   r@   r�  rq   rž  r  r   )r�  r   r  r�  )r   r   r  r�  )r�  r   r  r‹   )r±  r   r  rŸ  r  )r«   r   r  r�  )é(   )rô   úList[UIElement]rÊ  ro   r  ú	List[str])rô   r¡  rÐ  ro   rÑ  ro   r  z%Tuple[Optional[float], Optional[str]])r±  r   ró  ro   r  r   )r¡  r   r  r¢  )r¡  r   r   r‹   r  zOptional[Dict[str, Any]]r  r‹   )r±  r   r  r‹   )r±  r   ró  ro   rq   rž  r  r   )
rZ   r   r�  r   r%  r‰   rq   rž  r  r   )r=   r   )
r5  r‹   r6  r‹   rß   r‹   r?   r‹   r±  ro   )r<  r‹   r5  r‹   r6  r‹   rß   r‹   r?   r‹   r±  ro   r=  zCallable[[Any], None]r  rž  )r±  r   r  rž  )r_  Úbytesr`  r‹   ra  ro   r  ztuple[bytes, Optional[str]])r  r‹   )r±  r   r   r‹   r  zOptional[List[UIElement]]r  ro   rç  rž  rè  rž  r  rž  )r  r�  )‚r  Ú
__future__r   Úatexitrë  rƒ   r  rO   Úloggingr™   r5   r”  r    rE  Úcollectionsr   Ú	functoolsr   Útypesr   Útypingr   r   r	   r
   r   r   Útools.computer_use.backendr   r   r   r   r   Ú	getLoggerr  r�   r   r   r4   rQ   r,   ÚcompileÚ
IGNORECASErN   r8   rV   r_   ÚLockr¸   r`   Ú__annotations__ra   rb   rc   rd   rŠ   re   rf   rn   rg   rp   rs   rx   r{   r‘   rž   r£   r¦   r¬   rz   r¾   rÄ   ÚregisterrÌ   rÎ   râ   rœ   r  r  r$  r1  r4  r<  rG  rN  rU  rX  r[  r&  Ú_inputr
  rÇ   Ú_INPUT_ACTIONSrŠ  r  rž  r¢  r§  rs  Ú_DEFAULT_MAX_ELEMENTSrï  rÁ  rQ  rH  r³  rº  rÃ  rÌ  r×  Ú_bounds_scaleÚ_bounds_space_noterø  rý  r  r  rS  r�  r:  r?  rò  rñ  Ú_MAX_VISION_DIMrj  r  r#  r„  r  r—  rœ  Ústructr0  s   0r   ú<module>r¹     sÿ  ðòMõ
 #ã Û Û Û Û Û Û 	Û 	Û 
Û Û Ý "Ý Ý !ß =× =ç ~Õ ~à	ˆ×	Ñ	˜8Ó	$€ð Ð óñ Ò+Ó,©iÒ8VÓ.WÙÒ"Ó#¡YÒ/DÓ%EÙÒ-Ó.±	¸5À#¸,Ó0GÙÒ*Ó+©YÒ7PÓ-QÑS\Ð^fÐhlÐ]mÓSnð	Ð ð !¨V¸HÈUÐ[cØ ¨5¸%ñA€ðAUö V¸1˜*˜"Ÿ*™* Q¨¯©Õ6ò VÐ ówóóeð �	—‘Ó €Ø)-€Ð
&Ó -Ø+-€	Ð(Ó -Ø24Ð Ð/Ó 4Ø,.Ð ˜>Ó .ð =?Ð Ð9Ó >ð  �—‘Ó!€Ù›%Ð �CÓ ð (˜Ÿ™Ó)Ð Ø46Ð Ð1Ó 6Ø Ð óô9ó5ó
ó8óó	óóWô:ó$ð ‡�ònó ðnó*ð
 7;õ ô?Ð%ô ?ó>ó<^ó0Oó@óHóYòhòxó4òYó"ñ ˜Ð(MØ#(¨%Ñ1KÐ"LôN€á	� D°dÔ	;€ñ �IÐ)9Ô:Ù™7 9°AÔ6ÐBRÔSÙ™' )°GÔ<ÐHXÔYÙ™7 9°XÔ>ÐJZÔ[Ù�8ñ ({ô |á�Zñ  ,Cô  DÙÑpñ PôQáÑiÙSôUáñ Wó Xñ ñ ZàgkÙyô{ñ ˜;Ó'ÙÑxÓyÙ™W [°fÔ=Ó>Ù¡¨¸Ô CÓDñ-$€Ð
 ó ñ2 ÑE¨¯©Ó)9ÔEÓE€ð  %°UÈÐ\aÐpvØ¨	ÀyÐ`gÐxñÐ ô
`ó*qó"2ó5ó,ð Ð à !Ð ð Ð à(*Ð *Ð Ð%óFóó^ôHóJñ* r€ÙvÐ óZó,ô.	óWð ?TØ26ð*=Ø"/ð*=Ø;>ó*=ðZ 7;ð7Ø&3ð7Ø?Bó7ô.
ð	Ø2ð	Ø7Dó	óózð €ð ETô ó,ó(ðM€ð
 z~Ø@AÐbfØGKñ,dØ:=ð,dØR_ð,dà7Dð,dàP]ó,dó^)óô ùòYVs   Ã $N