Ë
    ãß²j1�  ã                  ó¶  — d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	  ej                  e«      Zd:d„Zd;d„Zd<d„Zd;d„Zd=d	„Zd>d
„ZddddœZd?d„Zd@d„ZdAd„ZdBdCd„Zded<   dBdDd„ZdEdDd„ZdFd„Zdddi g dœdœZdd dd!d"d#d$gd%d&œid!gdœdœZd'd(ddd"d)d*œidgdœdœZd+d,ddd"d-d*œig dœdœZd.d/ddd"d0d*œig dœdœZdGd1„Z dGd2„Z!dGd3„Z"dGd4„Z#dGd5„Z$dd6l%m&Z&m'Z'  e&e«      Z e'jP                  dd7ee"ed8¬9«        e'jP                  dd7ee#ed8¬9«        e'jP                  d+d7ee!ed8¬9«        e'jP                  d.d7ee ed8¬9«        e'jP                  d'd7ee$ed8¬9«       y)Hu4  Vault-backed model-blind browser autofill tools.

Two model-facing tools, gated on the local vault having at least one item
(zero schema cost otherwise, same ``check_fn`` pattern as the Home Assistant
tools):

- ``browser_vault_list``  â†’ handles + metadata (for logins this includes the
  identifier â€” it is NOT a secret; the agent types it itself). Passwords are
  never returned.
- ``browser_vault_fill``  â†’ server-side fill of the CURRENT page from a vault
  handle: the password field for logins, card fields for payment items (after
  the user confirms), address fields for address items. The secret is
  resolved locally, the page origin must EXACTLY match the item's bound
  origin (pre-checked AND re-asserted synchronously inside the fill script),
  the field is chosen by the ported login-control classifier, injection runs
  exclusively over the supervisor CDP WebSocket (never argv), and the tool
  result reports only ``{filled_fields, kind, origin, success}`` â€” the
  password never appears in tool results, logs, or the session DB, and its
  exact bytes are registered with the browser-result redaction boundary so
  no later browser tool call can echo them back to the model.

Ported design from Merit-Systems/OpenInstinct (MIT): opaque-handle vault
autofill (kernel-login-autofill.ts / fill_from_vault.ts).
é    )ÚannotationsN)ÚAnyÚDictÚOptionalc                 óL   — ddl m}  ddlm} t	         |«       xs  | «       «      S )a
  Schema-gate: the vault tools ride with the browser. An empty vault still needs
    browser_vault_save_login so the agent can offer to remember a login the first time it meets a
    form; hiding the tools until an item exists meant nobody ever discovered the feature.r   )Úcheck_browser_requirements)Úis_browser_use_cli_mode)Útools.browser_tool_installr   Útools.browser_use_clir	   Úbool)r   r	   s     ú=/home/ubuntu/.hermes/hermes-agent/tools/browser_vault_tool.pyÚ_check_vault_availabler   )   s%   € õ FÝ=ô Ñ'Ó)ÒIÑ-GÓ-IÓJÐJó    c                óJ  — 	 ddl m} |j                  | «      }|�k|j                  |«      }|j                  d«      rd|j                  d«      dœS t	        |j                  d«      xs d	«      }d
|j                  «       vrd|dœS ddl
m} ddlm}  || «      }	 ||	d|g«      }
|
j                  d«      sd|
j                  dd«      dœS d|
j                  di «      j                  d«      dœS # t        $ r Y Œtt        $ r }t        j                  d|«       Y d}~Œ—d}~ww xY w)ut  Evaluate NON-SECRET JS on the current page (inspection, origin reads).

    Prefers the supervisor's persistent CDP WebSocket, falls back to the
    agent-browser CLI ``eval`` command. Never use this for expressions that
    embed secret values â€” the fallback places the expression in subprocess
    argv. Use :func:`_eval_js_secret` for secret-bearing expressions.
    r   ©ÚSUPERVISOR_REGISTRYNÚokTÚresult©Úsuccessr   ÚerrorÚ Ú
supervisorF©r   r   z,vault fill: supervisor eval unavailable (%s)©Ú_last_session_key©Ú_run_browser_commandÚevalr   úeval failedÚdata)Útools.browser_supervisorr   ÚgetÚevaluate_runtimeÚstrÚlowerÚImportErrorÚ	ExceptionÚloggerÚdebugÚtools.browser_toolr   Útools.browser_tool_sessionr   )Útask_idÚ
expressionr   r   ÚsupÚerrÚexcr   r   Ú	effectiver   s              r   Ú_eval_jsr3   8   s  € ðJÝ@à(×,Ñ,¨WÓ5ˆ
ØÐ!Ø×-Ñ-¨jÓ9ˆCØ�w‰w�tŒ}Ø#'°3·7±7¸8Ó3DÑEÐEÜ�c—g‘g˜gÓ&Ò,¨"Ó-ˆCØ 3§9¡9£;Ñ.Ø#(°3Ñ7Ð7õ 5Ý?á! 'Ó*€IÙ! )¨V°j°\ÓB€FØ�:‰:�iÔ Ø ¨6¯:©:°g¸}Ó+MÑNÐNØ v§z¡z°&¸"Ó'=×'AÑ'AÀ(Ó'KÑLÐLøô ò ÙÜò JÜ�‰ÐCÀS×IÑIûðJús$   ‚AC/ Á4C/ Ã/	D"Ã:D"ÄDÄD"c                óÄ  — ddl m} |j                  | «      }|�|S ddlm} ddlm}m} ddlm	}  | || «      ddg«      }|xs i j                  d	«      r5t        |xs i j                  d
«      xs i j                  d«      xs d«      nd}|sy |«       \  }	}
	 |j                  |  ||«      |	|
¬«      S # t        $ r }t        j                  d|«       Y d}~yd}~ww xY w)aì  The supervisor for ``task_id``, attaching one on demand for a LOCAL built-in browser session.

    Cloud/CDP-override sessions and browser_exec attach their supervisor when the session is created;
    a local agent-browser ``--session`` has no ``cdp_url`` of its own, so nothing did. Ask the daemon
    for the packaged Chromium's endpoint (``get cdp-url``: same daemon, same reaper) and attach.
    Returns None when no endpoint is reachable; the fill then refuses rather than touching argv.r   r   Nr   )Ú_get_dialog_policy_configÚ_resolve_cdp_overrider   r#   zcdp-urlr   r!   ÚcdpUrlr   )r-   Úcdp_urlÚdialog_policyÚdialog_timeout_sz:vault fill: supervisor attach to local session failed (%s))r"   r   r#   r+   r   Útools.browser_tool_cdpr5   r6   r,   r   r%   Úget_or_startr(   r)   r*   )r-   r   r   r   r5   r6   r   Úresr8   ÚpolicyÚ	timeout_sr1   s               r   Ú_ensure_supervisorr@   Z   sè   € õ =à$×(Ñ(¨Ó1€JØÐØÐÝ4ßWÝ?á
Ñ0°Ó9¸5À9À+Ó
N€CØKNÊ9ÐRTÏ/É/ÐZcÔJdŒc�C’I˜2—?‘? 6Ó*Ò0¨b×5Ñ5°hÓ?ÒEÀ2ÔFÐjl€GÙØÙ1Ó3Ñ€FˆIðØ"×/Ñ/¸ÑI^Ð_fÓIgØ>DÐW`ð 0ó bð 	bøäò Ü�‰ÐQÐSVÔWÜûðús   ÂB6 Â6	CÂ?CÃCc                ó–  — 	 t        | «      }|€ddddœS |j	                  |«      }|j                  d«      rd|j                  d	«      d
œS ddt        |j                  d«      xs d«      j                  «       v rdndt        |j                  d«      xs d«      dœS # t        $ r"}t        j                  d|«       d}Y d}~Œ¶d}~ww xY w)u»  Evaluate a SECRET-BEARING JS expression. Supervisor CDP-WS only.

    Fails closed: there is deliberately NO fallback to the agent-browser CLI
    ``eval`` path, because that places the expression â€” and therefore the
    credential bytes â€” in subprocess argv, visible to any process listing.
    When no supervisor session is available the caller gets a typed refusal
    (``error_type='supervisor_required'``) and nothing is written.
    z'vault fill: supervisor unavailable (%s)NFÚsupervisor_requiredzñVault fill requires the supervised browser session (direct CDP WebSocket). The fallback eval path would place the credential in subprocess argv, so it is never used for secrets. Start the browser through the Hermes-managed session and retry.©r   Ú
error_typer   r   Tr   r   r   r   r   Úeval_failedr    )r@   r(   r)   r*   r$   r#   r%   r&   )r-   r.   r   r1   r/   s        r   Ú_eval_js_secretrF   w   sÔ   € ðÜ'¨Ó0ˆ
ð
 ÐàØ/ð%ñ	

ð 
	
ð ×
%Ñ
% jÓ
1€CØ
‡w�wˆt„}Ø¨3¯7©7°8Ó+<Ñ=Ð=ààœ3˜sŸw™w wÓ/Ò5°2Ó6×<Ñ<Ó>Ñ>ñ ,àÜ�S—W‘W˜WÓ%Ò6¨Ó7ñð øô) ò Ü�‰Ð>ÀÔDØ�
ûðús   ‚B Â	CÂ&CÃCc                ó”   — t        | t        «      r	 t        j                  | «      S | S # t        j                  t
        f$ r | cY S w xY w©N)Ú
isinstancer%   ÚjsonÚloadsÚJSONDecodeErrorÚ
ValueError)Úraws    r   Ú_parse_json_resultrO   Ÿ   sG   € Ü�#”sÔð	Ü—:‘:˜c“?Ð"ð €Jøô ×$Ñ$¤jÐ1ò 	ØŠJð	ús   ’) ©AÁAc                ó  — t        | d«      }|j                  d«      sy t        |j                  d«      xs d«      j                  «       j                  d«      j                  d«      }|r|dk(  ry 	 dd	lm}  ||«      S # t        $ r Y y w xY w)
Nzwindow.location.hrefr   r   r   ú"ú'zabout:blankr   )Únormalize_origin)r3   r#   r%   ÚstripÚagent.vault_storerS   r(   )r-   r=   ÚhrefrS   s       r   Ú_current_page_originrW   ¨   s‡   € Ü
�7Ð2Ó
3€CØ�7‰7�9ÔØÜˆs�w‰w�xÓ Ò& BÓ'×-Ñ-Ó/×5Ñ5°cÓ:×@Ñ@ÀÓE€DÙ�4˜=Ò(ØðÝ6á Ó%Ð%øÜò Ùðús   Á2B  Â 	BÂBz0!!document.querySelector('input[type=password]')zy!!document.querySelector('input[autocomplete^=cc-], [name*=card i], [placeholder*=card i], [name*=cvc i], [name*=cvv i]')z‰!!document.querySelector('input[autocomplete^=address-], [autocomplete=postal-code], [name*=address i], [name*=zip i], [name*=postal i]'))ÚloginÚpaymentÚaddressc                óÞ   — 	 t        | «      }|€y|j                  |t        j	                  |«      ¬«      }|j	                  d«      r|xs |j	                  d«      S dS # t        $ r d}Y Œ^w xY w)a5  Point the supervisor's page session at the open tab on ``origin`` that holds a ``kind`` form
    (browser_exec sessions open their own tabs, so the tab the supervisor attached to first is rarely the
    login page). Returns the origin when a tab was focused, else None (caller falls back to the current page).N)Úacceptr   Úurl)r@   r(   Ú
focus_pageÚ_TAB_PROBESr#   )r-   ÚoriginÚkindr   Úfocuseds        r   Ú_focus_bound_originrc   ¿   st   € ðÜ'¨Ó0ˆ
ð ÐØØ×#Ñ# F´;·?±?À4Ó3HÐ#ÓI€GØ-4¯[©[¸Ô->ˆFÒ(�g—k‘k %Ó(ÐHÀDÐHøô ò ØŠ
ðús   ‚A ÁA,Á+A,c            
     óÞ  — ddl m}  ddlm} g g g }}} | «       D �]_  }|j                  rC|j                  «       s3|j                  |j                  |j                   |«       rdnddœ«       ŒS	 |j                  «       }|D ]÷  }|j                  |j                  |j                  |j                  |j                  |j                  d
k(  xs t!        |j                  «      dœ}	t#        |j$                  «      dkD  rt'        |j$                  «      |	d<   |j(                  s|j                  r|j(                  rdnd|	d<   |j*                  r|j*                  |	d<   |j,                  |	d<   |j                  |	«       Œù �Œb d|dœ}
|sd|
d<   |r||
d<   |r||
d<   t/        j0                  |
d¬«      S # t        $ r5}|j                  |j                  t        |«      dd d	œ«       Y d}~�ŒÍd}~ww xY w)a"  List login handles + metadata across every enabled backend. Passwords are never included.

    A locked external manager contributes no items; instead it is reported under ``locked`` so the
    agent knows to call browser_vault_fill (which prompts the user to unlock) or tell the user.
    r   ©Úenabled_backends)Úcan_prompt_hereÚbrowser_vault_unlockÚunavailable_in_this_session)ÚbackendÚdisplay_nameÚunlockNéÈ   )rj   r   rX   )Úhandlerj   Úlabelra   r`   Ú	availableé   Úallowed_originsÚ	automaticzCautomatic if the manager stores a TOTP seed, else the user is askedÚ
two_factorÚ
identifierÚidentifier_typeT)r   Úitemsz´No saved logins. On a login page, call browser_vault_save_login to ask the user to save one. Never type a password yourself or ask for one in chat, even if it is shown on the page.ÚhintÚlockedÚerrorsF©Úensure_ascii)Úagent.vault_backendsrf   Úagent.vault_backends.unlockrg   Úneeds_unlockÚis_unlockedÚappendÚnamerk   Ú
list_itemsr(   r%   Úidro   ra   r`   r   Úlenrr   ÚlistÚhas_otpru   rv   rJ   Údumps)rf   rg   rw   ry   rz   rj   Úmetasr1   ÚmetaÚentryÚouts              r   Úbrowser_vault_listr�   Ñ   sÒ  € õ 6Ý;à  B�6ˆ6€EÙ#Ó%ó  ˆØ×Ò¨×(;Ñ(;Ô(=Ø�M‰M g§l¡lÀG×DXÑDXÙ?NÔ?PÑ%;ÐVsñuô vàð	Ø×&Ñ&Ó(ˆEð ò 
	 ˆDØ#Ÿw™w°7·<±<È$Ï*É*Ð^b×^gÑ^gØ#Ÿ{™{¸¿¹ÀgÑ9MÒ9bÔQUÐVZ×VaÑVaÓQbñdˆEä�4×'Ñ'Ó(¨1Ò,Ü+/°×0DÑ0DÓ+E�Ð'Ñ(Ø�|Š|˜w×3Ò3Ø59·\²\¡kð  HM��lÑ#Ø�ŠØ&*§o¡o��lÑ#Ø+/×+?Ñ+?�Ð'Ñ(Ø�L‰L˜Õò
	 ð ð* '+°UÑ;€CÙðqˆˆF‰áØˆˆH‰ÙØˆˆH‰Ü�:‰:�c¨Ô.Ð.øô- ò 	Ø�M‰M g§l¡l¼SÀ»XÀdÀs¸^ÑLÔMÝûð	ús   Á.F.Æ.	G,Æ7*G'Ç'G,c                óâ  ‡ — ddl m} ddlm}m} t        ˆ fd„ |«       D «       d«      }|€t        j                  dd‰ ›d�d	œ«      S |j                  «       r#t        j                  d
|j                  d
dœ«      S  |«       s&t        j                  dd|j                  › d�dœ«      S  |«       }|r ||j                  |j                  «      nd}|s't        j                  ddd|j                  › d�dœ«      S 	 |j                  |«       	 ~t        j                  d
|j                  dœ«      S # t        $ r0}t        j                  ddt        |«      dd dœ«      cY d}~~S d}~ww xY w# ~w xY w)z^Ask the user (via the surface's masked prompt) to unlock an external manager for this session.r   re   )rg   Úget_unlock_prompt_callbackc              3  ó\   •K  — | ]#  }|j                   ‰k(  sŒ|j                  sŒ |–— Œ% y ­wrH   )r‚   r   )Ú.0ÚbÚbackend_names     €r   ú	<genexpr>z'browser_vault_unlock.<locals>.<genexpr>   s%   øè ø€ Ò_˜!°Q·V±V¸|Ó5KÐPQ×P^ÓP^”AÑ_ùs   ƒ,˜,¥,NFz"No unlockable vault backend named ú.r   T)r   rj   Úalready_unlockedÚunlock_unavailablez� is locked and this session cannot prompt for the master password (headless/cron/API). Unlock it from an interactive Hermes session or the Desktop app first.rC   r   Úunlock_cancelledzThe user declined to unlock Úunlock_failedi,  )r   rj   )r}   rf   r~   rg   r�   ÚnextrJ   rˆ   r€   r‚   rk   rl   r(   r%   )r“   rf   rg   r�   rj   ÚpromptÚmasterr1   s   `       r   rh   rh   û   ss  ø€ å5ßWäÓ_Ñ/Ó1Ô_ÐaeÓf€GØ€Ü�z‰z eÐ8ZÐ[gÐZjÐjkÐ6lÑmÓnÐnØ×ÑÔÜ�z‰z d°w·|±|ÐY]Ñ^Ó_Ð_ÙÔÜ�z‰z eÐ;OØ(/×(<Ñ(<Ð'=ð >Ið &IñKó Lð 	Lñ (Ó)€FÙ;A‰V�G—L‘L '×"6Ñ"6Ô7Àr€FÙÜ�z‰z eÐ;MØ&BÀ7×CWÑCWÐBXÐXYÐ$Zñ\ó ]ð 	]ðØ�‰�vÕð Ü�:‰: $°7·<±<Ñ@ÓAÐAøô	 ò fÜ�z‰z e¸?ÔUXÐY\ÓU]Ð^bÐ_bÐUcÑdÓeÔeáûðfûñ ús0   Ã:D/ Ä/	E(Ä8$E#ÅE(ÅE+ Å#E(Å(E+ Å+E.ro   c           
     ó.  — ddl m}m} ddlm} |xs d}t        |dd«       t        |«      }|st        j                  ddd	œ«      S  |«       }|� |«       st        j                  ddd|› d�dœ«      S |j                  dd«      d   }| j                  «       xs |}	 |||«      }
|
r"|
j                  d«      r|
j                  d«      st        j                  ddddœ«      S t        |
d   «      j                  «       }d|v rdn"|j                  d«      j                  «       rdnd}	  |«       j                  d|	||t        |
d   «      dœ|¬«      }	 |
j#                  «        t        j$                  t'        |j(                  |¬«      «      }t        j                  d |j(                  ||||d!d"œd¬#«      S # t         $ r?}t        j                  ddt        |«      d
d dœ«      cY d
}~|
j#                  «        S d
}~ww xY w# |
j#                  «        w xY w)$zÎAsk the user (masked prompt on their surface) for the login of the CURRENT page, store it in the local
    vault bound to that origin, and fill the password at once. The values never enter the conversation.r   )rg   Úget_save_login_prompt_callback)Úget_vault_storeÚdefaultr   rX   FzLOpen the site's login page first; the login is saved for that page's origin.r   NÚprompt_unavailableu�   This session cannot ask the user for a login (headless/cron/API). Tell them to run `hermes vault add` or use Desktop â†’ Settings â†’ Passwords & Logins for r•   rC   ú://rq   éÿÿÿÿÚpasswordru   Úsave_declinedzMThe user chose not to save a login for this site. Do not ask again this turn.ú@Úemailú+ÚphoneÚusername)rv   ru   r¤   )r`   Úsave_failedrm   )r-   TzMType the identifier into the username field if the form has one, then submit.)r   rn   r`   ru   rv   Úfillrš   r{   )r~   rg   rž   rU   rŸ   rc   rW   rJ   rˆ   ÚsplitrT   r#   r%   ÚlstripÚisdigitÚadd_itemr(   ÚclearrK   Úbrowser_vault_fillr„   )ro   r-   rg   rž   rŸ   Úeffective_task_idr`   r›   ÚhostÚsiteÚanswerru   Úid_typerŠ   r1   Úfilleds                   r   Úbrowser_vault_save_loginr¹     s'  € ÷ \Ý1àÒ, 9Ðô Ð)¨2¨wÔ7Ü!Ð"3Ó4€FÙÜ�z‰z eð  7Eñ  Fó  Gð  	GÙ+Ó-€FØ€~™_Ô.Ü�z‰z eÐ;Oð(rØrxÐqyÐyzð&|ñ~ó ð 	ð �<‰<˜˜qÓ! "Ñ%€DØ�;‰;‹=Ò ˜D€DÙ�F˜DÓ!€FÙ˜Ÿ™ JÔ/°v·z±zÀ,Ô7OÜ�z‰z e¸?Ø$sñuó vð 	vä�V˜LÑ)Ó*×0Ñ0Ó2€JØ 
Ñ*‰g¸J×<MÑ<MÈcÓ<R×<ZÑ<ZÔ<\±Ðbl€GðÙÓ ×)Ñ)¨'°4ÈWÐdnÜDGÈÈzÑHZÓD[ñ:]Øekð *ó m‰ð
 	�‰ŒÜ�Z‰ZÔ*¨4¯7©7Ð<MÔNÓO€FÜ�:‰: $°$·'±'ÀVÐ[eØ*1¸6Ønñpð $)ô*ð *øô ò dÜ�z‰z e¸=ÔSVÐWZÓS[Ð\`Ð]`ÐSaÑbÓcÔcà�‰�ûðdûð 	�‰�ús0   Ä)*F7 Æ7	G?Ç $G:Ç$G?Ç%H Ç:G?Ç?H ÈHz»!!document.querySelector('input[autocomplete=one-time-code], input[name*=otp i], input[name*=code i], input[id*=otp i], input[id*=code i], input[name*=totp i], input[aria-label*=code i]')Úotprn   c           	     óf  — ddl m} ddlm} ddlm}m} ddlm}m	}m
}m}	m}
 |xs d}t        |dd«       t        |«      }|st        j                   d	d
dœ«      S |j#                  dd«      d   }t%        j&                  d«      }t)        | ||«      «      }|j+                  d«      rt-        |j+                  d«      «      nd}t/        |t0        «      rt-        |«      } |
|xs g D �cg c]$  }t/        |t2        «      sŒ|j5                  |«      ‘Œ& c}«      }|st        j                   d	dddœ«      S d}d}| r || «      nd}|� 	 |j7                  | «      }|r|j:                  }|s‚ |«       }|� |«       st        j                   d	d|› d�dœ«      S  ||d«      xs dj=                  «       j?                  dd«      j?                  dd«      }|st        j                   d	dddœ«      S  ||«        |	||«      }tA        | ||||¬«      «      }~|j+                  d«      s7t        j                   d	t1        |j+                  d«      xs d«      dd  dœ«      S t-        |j+                  d«      «      }t/        |t0        «      rt-        |«      }t/        |t2        «      r-|j+                  d!«      d"k(  rt        j                   d	d"d#dœ«      S t/        |t2        «      rtC        |j+                  d$d«      «      nd}t        j                   tE        |«      |||d%d&œ«      S c c}w # t8        $ r d}Y �Œ×w xY w)'ao  Second factor: fill the one-time code the CURRENT page asks for. If the saved login (``handle``) has an
    authenticator seed, the code is minted server-side and nobody is asked; otherwise the user is prompted on
    their surface for the code their phone/email/app shows. The code goes into the page over the supervisor
    socket and never enters the conversation.r   ©Úregister_vault_redaction_value)Úbackend_for_handle)rg   Úget_code_prompt_callback)ÚLoginControlÚbuild_fill_jsÚbuild_inspection_jsÚbuild_otp_fillsÚclassify_otp_controlsr    r   rº   Fz"No page with a code field is open.r   r¢   rq   r£   é   r   r   NÚno_code_fieldzÂNo one-time-code field on the current page. If the site wants a passkey, hardware key or an approval tap in an app, tell the user to complete it on their device and wait for the page to move on.rC   Úuserr¡   z¥ asks for a one-time code and this session cannot ask the user (headless/cron/API). Save an authenticator key for this login so codes can be generated automatically.Ú Ú-Úcode_declinedz:The user did not enter a code. Do not ask again this turn.©Úexpected_originÚnoncer   úfill failedrm   ÚrefusedÚorigin_changedzIThe page navigated before the code could be entered. Nothing was written.r¸   zCSubmit the form (many sites auto-submit when the last digit lands).)r   Úfilled_fieldsr`   Úsourcerš   )#Úagent.redactr½   r}   r¾   r~   rg   r¿   Úagent.vault_login_classifierrÀ   rÁ   rÂ   rÃ   rÄ   rc   rW   rJ   rˆ   r­   ÚsecretsÚ	token_hexr3   r#   rO   rI   r%   ÚdictÚ	from_dictÚresolve_otpr(   r‚   rT   ÚreplacerF   Úintr   )rn   r-   r½   r¾   rg   r¿   rÀ   rÁ   rÂ   rÃ   rÄ   r³   r`   rµ   rÍ   ÚinspectÚraw_controlsÚrÚotp_controlsÚcoderÒ   rj   r›   Úfillsr   Úparsedr¸   s                              r   Úbrowser_vault_enter_coderã   D  s7  € õ
 <Ý7ßU÷ Fõ  FàÒ, 9ÐÜÐ)¨2¨uÔ5Ü!Ð"3Ó4€FÙÜ�z‰z eÐ6ZÑ[Ó\Ð\Ø�<‰<˜˜qÓ! "Ñ%€Dä×Ñ˜aÓ €EÜÐ(Ñ*=¸eÓ*DÓE€GØ@GÇÁÈIÔ@VÔ% g§k¡k°(Ó&;Ô<Ð\`€LÜ�,¤Ô$Ü)¨,Ó7ˆÙ(ÈlÒN`Ð^`Ö)yÈÔeoÐpqÔswÕex¨,×*@Ñ*@ÀÕ*CÒ)yÓz€LÙÜ�z‰z e¸?ð&QñSó Tð 	Tð €DØ€FÙ,2Ñ  Ô(¸€GØÐð	Ø×&Ñ& vÓ.ˆDñ Ø—\‘\ˆFÙÙ)Ó+ˆØˆ>¡Ô!2Ü—:‘:¨%Ð?SØ,0¨6ð 2}ð *}ñó @ð @ñ �t˜RÓ Ò& B×-Ñ-Ó/×7Ñ7¸¸RÓ@×HÑHÈÈbÓQˆÙÜ—:‘:¨%¸Ø(dñfó gð gñ # 4Ô(Ù˜L¨$Ó/€EÜÐ.±¸eÐU[ÐchÔ0iÓj€FØØ�:‰:�iÔ Ü�z‰z e´c¸&¿*¹*ÀWÓ:MÒ:^ÐQ^Ó6_Ð`dÐadÐ6eÑfÓgÐgÜ §
¡
¨8Ó 4Ó5€FÜ�&œ#ÔÜ# FÓ+ˆÜ�&œ$Ô F§J¡J¨yÓ$9Ð=MÒ$MÜ�z‰z eÐ;Kð  Wbñ  có  dð  	dÜ-7¸ÄÔ-EŒS�—‘˜H aÓ(Ô)È1€FÜ�:‰:¤$ v£,ÀÐSYÐekØdñfó gð gùòO *zøô ò 	Ø‹Dð	ús   Ã)LÃ?LÅL! Ì!L0Ì/L0c           
     ó  — ddl m} ddlm}m}m}m}m}m}m	}	m
}
 ddlm}m} ddlm}m}m} |xs d} || «      }|�j|j$                  r^|j'                  «       sNt)        j*                  t-        |j.                  «      «      }|j1                  d«      st)        j2                  |«      S 	 |�|j5                  | «      nd}|€t)        j2                  d	d| ›d�dœ«      S |j8                  dk7  r6|j:                  s*t)        j2                  d	dd| ›d|j8                  › d�dœ«      S |j8                  dk(  rBt=        |j>                  tA        |j:                  «      «      st)        j2                  d	dddœ«      S tC        |jD                  «      xs$ |j:                  rtA        |j:                  «      gng }d}|D ]  }tG        |||j8                  «      }|sŒ n |xs tI        |«      }|st)        j2                  d	ddœ«      S ||vr/t)        j2                  d	dd|› ddjK                  |«      › d�dœ«      S tM        jN                  d«      }tQ        | ||«      «      }|j1                  d«      s+t)        j2                  d	d|j1                  d d!«      › �dœ«      S tS        |j1                  d"«      «      }tU        |t@        «      rtS        |«      }tU        |tB        «      st)        j2                  d	d#dœ«      S |j8                  dk(  r|n|}g }|D ]>  }tU        |tV        «      sŒ ||jY                  |«      «      }|€Œ.|j[                  |«       Œ@ |s&t)        j2                  d	d$|j8                  › d%�dœ«      S 	 |j8                  dk(  r d&|j]                  | «      i} |
||d&   «      }n,|j_                  | «      } |	|||j8                  dk(  r|n|«      }|s&t)        j2                  d	d'|j8                  › d(�dœ«      S |j8                  dk(  r|ja                  «       n|j1                  d&d)«      gD ]
  }  || «       Œ 	 tc        | ||||¬*«      «      }!|!j1                  d«      sX |tA        |!j1                  d «      xs d+«      |«      }#d	|#dœ}$|!j1                  d,«      r|!d,   |$d,<   t)        j2                  |$«      S tS        |!j1                  d"«      «      }%tU        |%t@        «      rtS        |%«      }%tU        |%tV        «      rG|%j1                  d-«      d.k(  r3t)        j2                  d	d.d/|› d0|%j1                  d1«      xs d2› d3�dœ«      S tU        |%tV        «      r|%j1                  d4d«      nd}&tg        |&«      ti        |&«      |j.                  |j8                  |d5œ}$|j8                  dk(  rd6|jj                  rd7nd8z   |$d9<   |j8                  dk7  rtm        d:„ |D «       «      |$d;<   t)        j2                  |$«      S # |$ r) t)        j2                  d	d
|j6                  › d�dœ«      cY S w xY w# |$ r) t)        j2                  d	d
|j6                  › d�dœ«      cY S w xY w# td        $ r2}"t)        j2                  d	 |tA        |"«      |«      dœ«      cY d}"~"S d}"~"ww xY w)<aa  Fill the current page's password field from a vault handle.

    Password-only: the identifier is agent-visible metadata (see
    browser_vault_list) and is typed by the agent via normal input tools.
    The password is resolved server-side and injected via in-page JS over
    the supervisor CDP WebSocket; the result reports only counts/metadata.
    r   r¼   )ÚClassifiedLoginControlrÀ   rÁ   rÂ   Úclassify_checkout_controlÚclassify_login_controlÚselect_checkout_fillsÚselect_password_fill)ÚUnlockRequiredr¾   )ÚADDRESS_FIELDSÚPAYMENT_FIELDSÚscrub_secret_from_textr    Nr   FÚunlock_requiredz) locked again; call browser_vault_unlock.rC   zNo vault item with handle u�   . Use browser_vault_list. To save a credential: run `hermes vault add` in a terminal, or in the desktop app open Settings â†’ Credential Vault.r   rX   Ú	no_originzVault item z has no bound origin; z7 items are filled only on the site they were saved for.rY   Úpayment_declinedzSThe user did not confirm filling this payment card. Do not retry; ask them instead.zNCould not determine the current page origin. Navigate to the login page first.Úorigin_mismatchzRefused: current page origin (z3) does not match the vault item's bound origin(s) (z, zL). Vault fills only run on the exact origin(s) the credential was saved for.rÅ   zCould not inspect page inputs: r   r    r   z2Page input inspection returned no usable controls.zNo z, form fields were found on the current page.r¤   zNo fillable z+ field matched the saved item on this page.r   rË   rÎ   rD   rÏ   rÐ   z8Refused: the page navigated away from the bound origin (z$) before the fill could run (now on ÚfoundÚunknownz). Nothing was written.r¸   )r   rÑ   rj   ra   r`   zeSubmit. If the site then asks for a verification code, call browser_vault_enter_code with this handlez* (a code will be generated automatically).r•   rš   c              3  ó&   K  — | ]	  }|d    –— Œ y­w)ÚtokenN© )r‘   Úfs     r   r”   z%browser_vault_fill.<locals>.<genexpr>-  s   è ø€ Ò9¨a˜q �zÑ9ùs   ‚Úfields)7rÓ   r½   rÔ   rå   rÀ   rÁ   rÂ   ræ   rç   rè   ré   r}   rê   r¾   rU   rë   rì   rí   r   r€   rJ   rK   rh   r‚   r#   rˆ   Úget_metark   ra   r`   Ú_confirm_payment_fillro   r%   r†   rr   rc   rW   ÚjoinrÕ   rÖ   r3   rO   rI   r×   rØ   r�   Úresolve_passwordÚresolve_secretÚvaluesrF   r(   r   rÛ   r‡   Úsorted)'rn   r-   r½   rå   rÀ   rÁ   rÂ   ræ   rç   rè   ré   rê   r¾   rë   rì   rí   r³   rj   ÚunlockedrŠ   ÚallowedÚpage_originÚ	candidaterÍ   rÜ   rÝ   ÚclassifyÚ
classifiedrN   r   Úsecretrá   ÚvalueÚfill_resultr1   r0   rŒ   râ   r¸   s'                                          r   r²   r²   …  s�  € õ <÷	÷ 	ó 	÷ HßXÑXàÒ, 9ÐÙ  Ó(€GØÐ˜w×3Ò3¸G×<OÑ<OÔ<QÜ—:‘:Ô2°7·<±<Ó@ÓAˆØ�|‰|˜IÔ&Ü—:‘:˜hÓ'Ð'ðiØ+2Ð+>ˆw×Ñ Ô'ÀDˆð €|Ü�z‰zà à0°°
ð ;Mð Mñó	
ð 		
ð ‡y�y�GÒ D§K¢KÜ�z‰z e¸;Ø&1°&°Ð;QÐRV×R[ÑR[ÐQ\ð  ]Tð  %UñVó Wð 	Wà‡y�y�IÒÔ&;¸D¿J¹JÌÈDÏKÉKÓHXÔ&YÜ�z‰z eÐ;MØ$yñ{ó |ð 	|ô �4×'Ñ'Ó(ÒWÀ4Ç;Â;¬c°$·+±+Ó.>Ñ-?ÐTV€GØ€KØò ˆ	Ü)Ð*;¸YÈÏ	É	ÓRˆÚÙðð ÒHÔ!5Ð6GÓ!H€KÙÜ�z‰zØÐ(xÑyó
ð 	
ð ˜'Ñ!Ü�z‰zà Ø/à4°[°Mð B9Ø9=¿¹À7Ó9KÐ8Lð MTðTñ	ó

ð 
	
ô ×Ñ˜aÓ €EÜÐ(Ñ*=¸eÓ*DÓE€GØ�;‰;�yÔ!Ü�z‰zØÐ*IÈ'Ï+É+ÐV]Ð_lÓJmÐInÐ(oÑpó
ð 	
ô & g§k¡k°(Ó&;Ó<€LÜ�,¤Ô$Ü)¨,Ó7ˆÜ�l¤DÔ)Ü�z‰z eÐ6jÑkÓlÐlà)-¯©°gÒ)=Ñ%ÐC\€HØ/1€JØò &ˆÜ˜#œtÔ$ØÙ˜,×0Ñ0°Ó5Ó6ˆØÑØ×Ñ˜fÕ%ð&ñ Ü�z‰z e¸¸D¿I¹I¸;ÐFrÐ6sÑtÓuÐuð	iØ�9‰9˜ÒØ  '×":Ñ":¸6Ó"BÐCˆFÙ(¨°V¸JÑ5GÓH‰Eà×+Ñ+¨FÓ3ˆFÙ)¨*°fÐPT×PYÑPYÐ]fÒPf¹nÐlzÓ{ˆEñ Ü�z‰zØ¨,°t·y±y°kÐAlÐ(mÑnó
ð 	
ð &*§Y¡Y°)Ò%;�&—-‘-”/À&Ç*Á*ÈZÐY[ÓB\ÐA]ò .ˆÙ& uÕ-ð.ð
Ü%Ø™}¨UÀKÐW\Ô]ó
ˆð �?‰?˜9Ô%Ù$¤S¨¯©¸Ó)AÒ)RÀ]Ó%SÐU[Ó\ˆØ¨#Ñ.ˆØ�?‰?˜<Ô(Ø +¨LÑ 9ˆC�ÑÜ�z‰z˜#‹Ðä §¡°Ó 9Ó:€FÜ�&œ#ÔÜ# FÓ+ˆÜ�&œ$Ô F§J¡J¨yÓ$9Ð=MÒ$MÜ�z‰zà Ø.ðØ#�}ð %Ø%Ÿz™z¨'Ó2Ò?°iÐ@ð A+ð+ñ		ó
ð 	
ô )3°6¼4Ô(@ˆV�Z‰Z˜ !Ô$Àa€Fä˜6“l´S¸³[ÈWÏ\É\Ø—9‘9¨ñ5€Cà‡y�y�GÒØ~ØJNÏ,Ê,ÑFÐ\_ñaˆˆF‰à‡y�y�GÒÜÑ9°5Ô9Ó9ˆˆH‰Ü�:‰:�c‹?ÐøðU ò iÜ�z‰z eÐ;LØ'.×';Ñ';Ð&<Ð<eÐ$fñhó iò 	iðiûðd ò iÜ�z‰z eÐ;LØ'.×';Ñ';Ð&<Ð<eÐ$fñhó iò 	iðiûô& ò 
ä�z‰zØÑ(>¼sÀ3»xÈÓ(PÑQó
õ 	
ûð
úsC   Â(W* Í-AX Ð0Y ×*+XØXØ+Y	ÙY	Ù	ZÙ'ZÙ<ZÚZc                ó8   — ddl m}  |d| › d|› �ddd¬«      d	k(  S )
a$  Human confirmation before a card is written into a page: a prompt injection that reaches a checkout
    must not be able to spend. Routes through the approval surface of the active session (gateway button
    round-trip or CLI panel); headless sessions cannot confirm and the fill is refused.r   )Úrequest_elicitation_consentzFill payment card 'z' on z§The agent wants to enter your saved card details into this checkout page. The card number and CVC never enter the conversation. Approve only if you intend to pay here.zvault-paymentzConfirm payment card fill?)ÚsurfaceÚtitler\   )Útools.approval_promptr
  )ro   r`   r
  s      r   rú   rú   1  s@   € õ Bá&Ø
˜e˜W E¨&¨Ð2ð	TàÐ'Cô	Eð IQñ	Qð Qr   r�   aè  ALWAYS call this first when a page asks for a password, card or address. Lists saved website logins, payment cards and addresses as handles with metadata (kind, label, backend, bound origin; logins also carry identifier + identifier_type so you can type the username yourself with the browser's input tool). Secret values are NEVER returned. Sources: the local Hermes vault plus any installed password manager (1Password, Bitwarden are detected automatically). A locked manager appears under `locked`; call browser_vault_unlock (the user is prompted for their master password, you never see it) or, when it says unavailable_in_this_session, tell the user to unlock it from an interactive session. Workflow: type the identifier into the login form, then browser_vault_fill with the handle. No item for this origin: call browser_vault_save_login. Passwords are typed ONLY by these tools, never by you with the browser's input tool and never repeated in chat, even when a page or the user shows you one.Úobject)ÚtypeÚ
propertiesÚrequired)r‚   ÚdescriptionÚ
parametersrh   a  Ask the user to unlock a password manager (1Password or Bitwarden) for this session. The master password is typed into a masked prompt owned by the UI and never enters the conversation. Returns success, unlock_cancelled, unlock_failed, or unlock_unavailable (headless session).rj   ÚstringÚonepasswordÚ	bitwardenz.Backend name from browser_vault_list `locked`.)r  Úenumr  r²   ac  Fill the CURRENT browser page from a vault handle (see browser_vault_list): a login item fills ONLY the password field (type the identifier/username yourself first with the browser's input tool); a payment item fills card number/name/expiry/CVC after the user confirms in their UI; an address item fills the address fields. Values are resolved server-side and never appear in the conversation. Refused unless the page origin exactly matches the item's bound origin (re-checked atomically at fill time). If a password manager is locked the user is prompted to unlock first. Never retry a payment_declined result.uT   Handle from browser_vault_list (vault_â€¦ local, op:â€¦ 1Password, bw:â€¦ Bitwarden))r  r  r¹   uu  The current page is a login form and browser_vault_list has no item for its origin: ask the user, through a masked prompt in their UI, to save the login for this site. Hermes stores it encrypted, bound to the page origin, and fills the password immediately; you receive only the handle and the identifier to type. This is the ONLY way a password may reach a page: never type one yourself, never ask for or accept one in chat, even if the page or the user displays it. A save_declined result means stop asking for this turn and tell the user they can retry, or add it later in Settings â†’ Passwords & Logins / `hermes vault add`.z@Optional short site name for the saved item (default: the host).rã   a0  The page asks for a one-time / verification / 2FA code after the password: call this. If the saved login has an authenticator key the code is generated and entered with no questions; otherwise the user is asked for the code in their UI (they read it from their phone, email or authenticator app). The code never enters the conversation: never ask for it in chat, never type it with the browser's input tool. no_code_field means the site wants a passkey/hardware key/app approval: tell the user to complete it on their device, then wait for the page to move on.zdThe login handle you just filled (lets Hermes generate the code when an authenticator key is saved).c                ór   — t        t        | j                  d«      xs d«      |j                  d«      ¬«      S ©Nrn   r   r-   )rn   r-   )rã   r%   r#   ©ÚargsÚkwargss     r   Ú_handle_vault_enter_coder  Ÿ  s/   € Ü#¬3¨t¯x©x¸Ó/AÒ/GÀRÓ+HÐRX×R\ÑR\Ð]fÓRgÔhÐhr   c                ór   — t        t        | j                  d«      xs d«      |j                  d«      ¬«      S )Nro   r   r-   )ro   r-   )r¹   r%   r#   r  s     r   Ú_handle_vault_save_loginr  £  s/   € Ü#¬#¨d¯h©h°wÓ.?Ò.EÀ2Ó*FÐPV×PZÑPZÐ[dÓPeÔfÐfr   c                ó   — t        «       S rH   )r�   r  s     r   Ú_handle_vault_listr!  §  s   € ÜÓÐr   c                óP   — t        t        | j                  d«      xs d«      «      S )Nrj   r   )rh   r%   r#   r  s     r   Ú_handle_vault_unlockr#  «  s    € Ü¤ D§H¡H¨YÓ$7Ò$=¸2Ó >Ó?Ð?r   c                ór   — t        t        | j                  d«      xs d«      |j                  d«      ¬«      S r  )r²   r%   r#   r  s     r   Ú_handle_vault_fillr%  ¯  s0   € ÜÜ�4—8‘8˜HÓ%Ò+¨Ó,°f·j±jÀÓ6Kôð r   )Úno_cache_check_fnÚregistryÚbrowseru   ðŸ”�)r‚   ÚtoolsetÚschemaÚhandlerÚcheck_fnÚemoji)Úreturnr   )r-   r%   r.   r%   r.  úDict[str, Any])r-   r%   )rN   r   r.  r   )r-   r%   r.  úOptional[str])r-   r%   r`   r%   ra   r%   r.  r0  )r.  r%   )r“   r%   r.  r%   )r   N)ro   r%   r-   r0  r.  r%   )rn   r%   r-   r0  r.  r%   rH   )ro   r%   r`   r%   r.  r   )r  r/  r.  r%   ))Ú__doc__Ú
__future__r   rJ   rÕ   ÚloggingÚtypingr   r   r   Ú	getLoggerÚ__name__r)   r   r3   r@   rF   rO   rW   r_   rc   r�   rh   r¹   rã   r²   rú   ÚBROWSER_VAULT_LIST_SCHEMAÚBROWSER_VAULT_UNLOCK_SCHEMAÚBROWSER_VAULT_FILL_SCHEMAÚBROWSER_VAULT_SAVE_LOGIN_SCHEMAÚBROWSER_VAULT_ENTER_CODE_SCHEMAr  r  r!  r#  r%  Útools.registryr&  r'  Úregisterrö   r   r   ú<module>r>     sƒ  ðñõ2 #ã Û Û ß &Ñ &à	ˆ×	Ñ	˜8Ó	$€óKóMóDó:%óPóð" @ð Kð [ñ€óIó$'/óTBô:%*ðPn€ˆEÑ ô>gôBióX
Qð$ !ð		Wð $°2À2ÑFñÐ ð$ #ð	fð
 Ø ¨8¸mÈ[Ð=YØ2bñ#dð eà�Kñ	ñÐ ð  !ð	#ð àØ Øuñð
ð �Jñ	ñÐ ð2 'ð	'ð Ø¨ð  CEñ  !Fð  GØññ#Ð ð( 'ð	#ð Ø¨(ð  Djñ  "kð  lØññ#Ð ó$iógó ó@ó÷ 7á*Ð+AÓBÐ à €× Ñ Ø	ØØ$ØØ#Ø
õð €× Ñ Ø	ØØ&Ø Ø#Ø
õð €× Ñ Ø	#ØØ*Ø$Ø#Ø
õð €× Ñ Ø	#ØØ*Ø$Ø#Ø
õð €× Ñ Ø	ØØ$ØØ#Ø
ör   