§
    øžyjü-  ã                  óø   — 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mZm	Z	m
Z
 ddlZddlmZ ddlmZ  ej        e¦  «        Zi Zded<    ej        ¦   «         Zd	Zd
ZdZdd„Zdd„Zdd„Z G d„ de¦  «        ZdS )u‡  Browser Use cloud browser provider â€” plugin form.

Subclasses :class:`agent.browser_provider.BrowserProvider` (the plugin-facing
ABC introduced in PR #25214). The legacy in-tree module
``tools.browser_providers.browser_use`` was removed in the same PR; this file
is now the canonical implementation.

Browser Use is the only browser backend with dual auth: a direct
``BROWSER_USE_API_KEY`` for self-billed users, or the managed Nous tool
gateway (which Hermes uses to bill Browser Use sessions to a Nous
subscription). The dispatch order â€” direct API key first, managed gateway
second â€” preserves the pre-migration behaviour in
``tools.browser_providers.browser_use.BrowserUseProvider._get_config_or_none``.

Config keys this provider responds to::

    browser:
      cloud_provider: "browser-use"   # explicit selection
    tool_gateway:
      browser: "gateway"              # optional: prefer managed gateway
                                      #   even when BROWSER_USE_API_KEY is set

Auth env vars (one of)::

    BROWSER_USE_API_KEY=...           # https://browser-use.com
    # OR a managed Nous gateway entry (configured via 'hermes setup')
é    )ÚannotationsN)ÚAnyÚDictÚOptional)ÚBrowserProvider)Ú
get_secretúDict[str, str]Ú_pending_create_keysz"https://api.browser-use.com/api/v3é   ÚusÚtask_idÚstrÚreturnc                óæ   — t           5  t                               | ¦  «        }|r|cd d d ¦  «         S dt          j        ¦   «         j        › �}|t          | <   |cd d d ¦  «         S # 1 swxY w Y   d S )Nzbrowser-use-session-create:)Ú_pending_create_keys_lockr
   ÚgetÚuuidÚuuid4Úhex)r   ÚexistingÚcreateds      úJ/home/ragecks/.hermes/hermes-agent/plugins/browser/browser_use/provider.pyÚ!_get_or_create_pending_create_keyr   8   sÙ   € Ý	"ð ð Ý'×+Ò+¨GÑ4Ô4ˆØð 	Øðð ð ð ñ ô ð ð ð
 Cµ´
±´Ô0@ÐBÐBˆØ(/Õ˜WÑ%Øðð ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð ð ð s   ˆA&³&A&Á&A*Á-A*ÚNonec                ó|   — t           5  t                               | d ¦  «         d d d ¦  «         d S # 1 swxY w Y   d S )N)r   r
   Úpop)r   s    r   Ú_clear_pending_create_keyr   C   s‚   € Ý	"ð 0ð 0Ý× Ò  ¨$Ñ/Ô/Ð/ð0ð 0ð 0ñ 0ô 0ð 0ð 0ð 0ð 0ð 0ð 0ð 0øøøð 0ð 0ð 0ð 0ð 0ð 0s   ˆ1±5¸5Úresponseúrequests.ResponseÚboolc                ó~  — | j         dk    rdS | j         dk    rdS 	 |                      ¦   «         }n# t          $ r Y dS w xY wt          |t          ¦  «        sdS |                     d¦  «        }t          |t          ¦  «        sdS t          |                     d¦  «        pd¦  «                             ¦   «         }d|v S )	u¯  Decide whether to keep the idempotency key after a failed create.

    Preserve the key when the failure looks retryable (5xx) OR when the
    gateway reports the original request is still in flight (409 "already
    in progress") â€” in either case, retrying with the same key lets the
    gateway deduplicate.

    Drop the key on any other 4xx (auth failure, bad request, etc.) â€” those
    won't succeed by being retried.
    iô  Ti™  FÚerrorÚmessageÚ zalready in progress)Ústatus_codeÚjsonÚ	ExceptionÚ
isinstanceÚdictr   r   Úlower)r   Úpayloadr"   r#   s       r   Ú#_should_preserve_pending_create_keyr,   H   sÖ   € ð Ô˜sÒ"Ð"ØˆtàÔ˜sÒ"Ð"ØˆuðØ—-’-‘/”/ˆˆøÝð ð ð Øˆuˆuðøøøõ �g�tÑ$Ô$ð Øˆuà�KŠK˜Ñ Ô €EÝ�e�TÑ"Ô"ð Øˆuå�%—)’)˜IÑ&Ô&Ð,¨"Ñ-Ô-×3Ò3Ñ5Ô5€GØ  GÐ+Ð+s   œ1 ±
?¾?c                  óˆ   — e Zd ZdZedd„¦   «         Zedd„¦   «         Zdd„Zdd	œdd„Zdd„Z	dd„Z
d d„Zd!d„Zd"d„Zdd„ZdS )#ÚBrowserUseBrowserProvideran  Browser Use (https://browser-use.com) cloud browser backend.

    Dual auth: prefers a direct BROWSER_USE_API_KEY when set, falling back
    to the managed Nous tool gateway when ``tool_gateway.browser`` config
    routes through it. Setting ``tool_gateway.browser: gateway`` flips the
    order so managed billing wins even when BROWSER_USE_API_KEY is present.
    r   r   c                ó   — dS )Núbrowser-use© ©Úselfs    r   ÚnamezBrowserUseBrowserProvider.namer   ó   € àˆ}ó    c                ó   — dS )NúBrowser User1   r2   s    r   Údisplay_namez&BrowserUseBrowserProvider.display_namev   r5   r6   r    c                ó2   — |                       d¬¦  «        d uS )NF©Úrefresh_token)Ú_get_config_or_noner2   s    r   Úis_availablez&BrowserUseBrowserProvider.is_availablez   s   € Ø×'Ò'°eÐ'Ñ<Ô<ÀDÐHÐHr6   Tr;   r<   úOptional[Dict[str, Any]]c               óÜ   — ddl m}m} ddlm} t          d¦  «        }|r |d¦  «        s|t          ddœS  |d|rd n|¬	¦  «        }|€d S |j        |j         	                    d
¦  «        ddœS )Nr   )Úpeek_nous_access_tokenÚresolve_managed_tool_gateway)Úprefers_gatewayÚBROWSER_USE_API_KEYÚbrowserF)Úapi_keyÚbase_urlÚmanaged_moder0   )Útoken_readerú/T)
Útools.managed_tool_gatewayrA   rB   Útools.tool_backend_helpersrC   r   Ú	_BASE_URLÚnous_user_tokenÚgateway_originÚrstrip)r3   r<   rA   rB   rC   rF   Úmanageds          r   r=   z-BrowserUseBrowserProvider._get_config_or_none�   sâ   € ð	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	?Ð>Ð>Ð>Ð>Ð>õ Ð2Ñ3Ô3ˆØð 	˜?˜?¨9Ñ5Ô5ð 	à"Ý%Ø %ðð ð ð /Ð.ØØ!.ÐJ˜˜Ð4Jð
ñ 
ô 
ˆð ˆ?Ø�4ð Ô.ØÔ.×5Ò5°cÑ:Ô:Ø ð
ð 
ð 	
r6   úDict[str, Any]c                óx   — ddl m} |                      ¦   «         }|€d} |¦   «         rd}t          |¦  «        ‚|S )Nr   )Úmanaged_nous_tools_enabledz=Browser Use requires a direct BROWSER_USE_API_KEY credential.zsBrowser Use requires either a direct BROWSER_USE_API_KEY credential or a managed Browser Use gateway configuration.)rL   rT   r=   Ú
ValueError)r3   rT   Úconfigr#   s       r   Ú_get_configz%BrowserUseBrowserProvider._get_config£   se   € ØIÐIÐIÐIÐIÐIà×)Ò)Ñ+Ô+ˆØˆ>àOð ð *Ð)Ñ+Ô+ð ðQð õ ˜WÑ%Ô%Ð%Øˆr6   rV   r	   c                ó   — d|d         dœS )Nzapplication/jsonrF   )zContent-TypezX-Browser-Use-API-Keyr1   )r3   rV   s     r   Ú_headersz"BrowserUseBrowserProvider._headers·   s   € à.Ø%+¨IÔ%6ð
ð 
ð 	
r6   r   úDict[str, object]c                óº  — |                       ¦   «         }t          |                     d¦  «        ¦  «        }|                      |¦  «        }|rt	          |¦  «        |d<   |rt
          t          dœni }	 t          j        |d         › d�||d¬¦  «        }n-# t          j	        $ r}|r‚ t          d|› �¦  «        |‚d }~ww xY w|j        s?|rt          |¦  «        st          |¦  «         t          d	|j        › d
|j        › �¦  «        ‚|                     ¦   «         }|rt          |¦  «         d|› dt#          j        ¦   «         j        d d…         › �}	|r|j                             d¦  «        nd }
t*                               d|	¦  «         |                     d¦  «        p|                     d¦  «        pd}|	|d         ||                     d¦  «        ddi|
dœS )NrH   zX-Idempotency-Key)ÚtimeoutÚproxyCountryCoderG   z	/browsersé   ©Úheadersr&   r\   z#Browser Use API connection failed: z&Failed to create Browser Use session: Ú Úhermes_Ú_é   zx-external-call-idzCreated Browser Use session %sÚcdpUrlÚ
connectUrlr$   ÚidÚ	timeoutAtÚbrowser_useT)Úsession_nameÚbb_session_idÚcdp_urlÚ
expires_atÚfeaturesÚexternal_call_id)rW   r    r   rY   r   Ú _DEFAULT_MANAGED_TIMEOUT_MINUTESÚ#_DEFAULT_MANAGED_PROXY_COUNTRY_CODEÚrequestsÚpostÚRequestExceptionÚRuntimeErrorÚokr,   r   r%   Útextr&   r   r   r   r`   ÚloggerÚinfo)r3   r   rV   rH   r`   r+   r   ÚexcÚsession_datarj   ro   rl   s               r   Úcreate_sessionz(BrowserUseBrowserProvider.create_session½   sb  € Ø×!Ò!Ñ#Ô#ˆÝ˜FŸJšJ ~Ñ6Ô6Ñ7Ô7ˆà—-’- Ñ'Ô'ˆØð 	VÝ+LÈWÑ+UÔ+UˆGÐ'Ñ(ð ð	Ý;Ý$Gðð ð ð
 ð 	ð	Ý”}Ø˜*Ô%Ð0Ð0Ð0ØØØð	ñ ô ˆHˆHøõ Ô(ð 	ð 	ð 	ð ð ØÝØ;°cÐ;Ð;ñô àðøøøøð	øøøð Œ{ð 	Øð 3Õ$GÈÑ$QÔ$Qð 3Ý)¨'Ñ2Ô2Ð2Ýð:ØÔ'ð:ð :Ø*2¬-ð:ð :ñô ð ð
  —}’}‘”ˆØð 	/Ý% gÑ.Ô.Ð.ØA ÐAÐA­4¬:©<¬<Ô+;¸B¸Q¸BÔ+?ÐAÐAˆà:FÐPˆHÔ× Ò Ð!5Ñ6Ô6Ð6ÈDð 	õ 	�ŠÐ4°lÑCÔCÐCà×"Ò" 8Ñ,Ô,ÐT°×0@Ò0@ÀÑ0NÔ0NÐTÐRTˆð )Ø)¨$Ô/Øð '×*Ò*¨;Ñ7Ô7Ø&¨Ð-Ø 0ð

ð 

ð 
	
s   Á4!B ÂC Â%B;Â;C Ú
session_idc                ó  — 	 |                       ¦   «         }n,# t          $ r t                               d|¦  «         Y dS w xY w	 t	          j        |d         › d|› �|                      |¦  «        ddid¬¦  «        }|j        d	v rt                               d
|¦  «         dS t                               d||j        |j	        d d…         ¦  «         dS # t          $ r'}t                               d||¦  «         Y d }~dS d }~ww xY w)Nu;   Cannot close Browser Use session %s â€” missing credentialsFrG   ú
/browsers/ÚactionÚstopé
   r_   >   éÈ   éÉ   éÌ   z*Successfully closed Browser Use session %sTz4Failed to close Browser Use session %s: HTTP %s - %srƒ   z,Exception closing Browser Use session %s: %s)rW   rU   rx   Úwarningrr   ÚpatchrY   r%   Údebugrw   r'   r"   )r3   r}   rV   r   Úes        r   Úclose_sessionz'BrowserUseBrowserProvider.close_session  sI  € ð	Ø×%Ò%Ñ'Ô'ˆFˆFøÝð 	ð 	ð 	Ý�NŠNØMÈzñô ð ð �5�5ð		øøøð	Ý”~Ø˜*Ô%Ð=Ð=°Ð=Ð=ØŸš fÑ-Ô-Ø Ð'Øð	ñ ô ˆHð Ô# Ð6Ð6Ý—’ÐIÈ:ÑVÔVÐVØ�tå—’ØJØØÔ(Ø”M $ 3 $Ô'ñ	ô ð ð �uøÝð 	ð 	ð 	Ý�LŠLÐGÈÐUVÑWÔWÐWØ�5�5�5�5�5øøøøð	øøøs-   ‚ —%A ¿A ÁAC Â"/C Ã
DÃC?Ã?Dr   c                óF  — |                       ¦   «         }|€t                               d|¦  «         d S 	 t          j        |d         › d|› �|                      |¦  «        ddid¬¦  «         d S # t          $ r'}t                               d||¦  «         Y d }~d S d }~ww xY w)	NuG   Cannot emergency-cleanup Browser Use session %s â€” missing credentialsrG   r   r€   r�   r   r_   z7Emergency cleanup failed for Browser Use session %s: %s)r=   rx   r†   rr   r‡   rY   r'   rˆ   )r3   r}   rV   r‰   s       r   Úemergency_cleanupz+BrowserUseBrowserProvider.emergency_cleanup!  sð   € Ø×)Ò)Ñ+Ô+ˆØˆ>Ý�NŠNØYØñô ð ð ˆFð
	ÝŒNØ˜*Ô%Ð=Ð=°Ð=Ð=ØŸš fÑ-Ô-Ø Ð'Øð	ñ ô ð ð ð øõ ð 	ð 	ð 	Ý�LŠLØIÈ:ÐWXñô ð ð ð ð ð ð ð øøøøð	øøøs   µ8A/ Á/
B Á9BÂB c                ó   — dddddddœgdd	œS )
Nr8   Úpaidz#Cloud browser with remote executionrD   zBrowser Use API keyzhttps://browser-use.com)ÚkeyÚpromptÚurlÚbrowserbase)r4   ÚbadgeÚtagÚenv_varsÚ
post_setupr1   r2   s    r   Úget_setup_schemaz*BrowserUseBrowserProvider.get_setup_schema5  s9   € à!ØØ8ð 1Ø3Ø4ðð ðð (ð
ð 
ð 	
r6   N)r   r   )r   r    )r<   r    r   r?   )r   rR   )rV   rR   r   r	   )r   r   r   rZ   )r}   r   r   r    )r}   r   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úpropertyr4   r9   r>   r=   rW   rY   r|   rŠ   rŒ   r—   r1   r6   r   r.   r.   i   s  € € € € € ðð ð ðð ð ñ „Xðð ðð ð ñ „XððIð Ið Ið Ið <@ð  
ð  
ð  
ð  
ð  
ð  
ðDð ð ð ð(
ð 
ð 
ð 
ðC
ð C
ð C
ð C
ðJð ð ð ð>ð ð ð ð(
ð 
ð 
ð 
ð 
ð 
r6   r.   )r   r   r   r   )r   r   r   r   )r   r   r   r    )r›   Ú
__future__r   ÚloggingÚosÚ	threadingr   Útypingr   r   r   rr   Úagent.browser_providerr   Úagent.secret_scoper   Ú	getLoggerr˜   rx   r
   Ú__annotations__ÚLockr   rM   rp   rq   r   r   r,   r.   r1   r6   r   ú<module>r§      s\  ððð ð ð8 #Ð "Ð "Ð "Ð "Ð "à €€€Ø 	€	€	€	Ø Ð Ð Ð Ø €€€Ø &Ð &Ð &Ð &Ð &Ð &Ð &Ð &Ð &Ð &à €€€à 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø )Ð )Ð )Ð )Ð )Ð )à	ˆÔ	˜8Ñ	$Ô	$€ð (*Ð Ð )Ð )Ð )Ñ )Ø*˜IœNÑ,Ô,Ð à0€	Ø#$Ð  Ø&*Ð #ðð ð ð ð0ð 0ð 0ð 0ð
,ð ,ð ,ð ,ðB[
ð [
ð [
ð [
ð [
 ñ [
ô [
ð [
ð [
ð [
r6   