
    `gj',                        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  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y)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Dict[str, str]_pending_create_keysz"https://api.browser-use.com/api/v3   usc                    t         5  t        j                  |       }|r|cd d d        S dt        j                         j
                   }|t        | <   |cd d d        S # 1 sw Y   y xY w)Nzbrowser-use-session-create:)_pending_create_keys_lockr	   getuuiduuid4hex)task_idexistingcreateds      W/root/.hermes/venv/lib/python3.12/site-packages/plugins/browser/browser_use/provider.py!_get_or_create_pending_create_keyr   7   sc    	" '++G4 
 0

0@0@/AB(/W%  s   A+AA(c                f    t         5  t        j                  | d        d d d        y # 1 sw Y   y xY w)N)r   r	   pop)r   s    r   _clear_pending_create_keyr   B   s*    	" 0  $/0 0 0s   '0c                H   | j                   dk\  ry| j                   dk7  ry	 | j                         }t        |t              sy|j                  d      }t        |t              syt        |j                  d      xs d      j                         }d|v S # t        $ r Y yw xY w)	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   strlower)responsepayloadr   r   s       r   #_should_preserve_pending_create_keyr'   G   s     s"s"--/ gt$KK EeT"%))I&,"-335G G++  s   B 	B! B!c                  z    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y)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.
    c                     y)Nbrowser-use selfs    r   namezBrowserUseBrowserProvider.nameq           c                     y)NBrowser User,   r-   s    r   display_namez&BrowserUseBrowserProvider.display_nameu   r0   r1   c                *    | j                  d      d uS )NFrefresh_token)_get_config_or_noner-   s    r   is_availablez&BrowserUseBrowserProvider.is_availabley   s    ''e'<DHHr1   Tr6   c                   ddl m}m} ddlm} t
        j                  j                  d      }|r |d      s
|t        ddS  |d|rd n|	      }|y |j                  |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_moder+   )token_reader/T)tools.managed_tool_gatewayr;   r<   tools.tool_backend_helpersr=   osenvironr   	_BASE_URLnous_user_tokengateway_originrstrip)r.   r7   r;   r<   r=   r@   manageds          r   r8   z-BrowserUseBrowserProvider._get_config_or_none   s    	
 	? **..!67?95"% %  /!.4J
 ? ....55c: 
 	
r1   c                b    ddl m} | j                         }|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.)rF   rO   r8   
ValueError)r.   rO   configr   s       r   _get_configz%BrowserUseBrowserProvider._get_config   sE    I))+>O  *+Q  W%%r1   c                    d|d   dS )Nzapplication/jsonr@   )zContent-TypezX-Browser-Use-API-Keyr,   )r.   rQ   s     r   _headersz"BrowserUseBrowserProvider._headers   s    .%+I%6
 	
r1   c                B   | j                         }t        |j                  d            }| j                  |      }|rt	        |      |d<   |rt
        t        dni }	 t        j                  |d    d||d      }|j                  s=|rt        |      st        |       t        d	|j                   d
|j                         |j!                         }|rt        |       d| dt#        j$                         j&                  d d  }	|r|j(                  j                  d      nd }
t*        j-                  d|	       |j                  d      xs |j                  d      xs d}|	|d   |ddi|
dS # t        j                  $ r}|r t        d|       |d }~ww xY w)NrB   zX-Idempotency-Key)timeoutproxyCountryCoderA   z	/browsers   headersr   rV   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browser_useT)session_namebb_session_idcdp_urlfeaturesexternal_call_id)rR   boolr   rT   r    _DEFAULT_MANAGED_TIMEOUT_MINUTES#_DEFAULT_MANAGED_PROXY_COUNTRY_CODErequestspostRequestExceptionRuntimeErrorokr'   r   r   textr   r   r   r   rZ   loggerinfo)r.   r   rQ   rB   rZ   r&   r%   excsession_datarc   rg   re   s               r   create_sessionz(BrowserUseBrowserProvider.create_session   s   !!#FJJ~67--'+LW+UG'(  <$G
  		}}*%&i0	H  {{$G$Q)'28''((--: 
  }}%g. 	4::<+;+;BQ+?*@A:FH  !56D 	 	4lC""8,T0@0@0NTRT ))$/&- 0
 	
= (( 	 5cU;	s   E4 4FFFc                   	 | j                         }	 t	        j
                  |d    d| | j                  |      ddid      }|j                  d	v rt        j                  d
|       yt        j                  d||j                  |j                  d d        y# t        $ r t        j                  d|       Y yw xY w# t        $ r!}t        j                  d||       Y d }~yd }~ww xY w)Nu;   Cannot close Browser Use session %s — missing credentialsFrA   
/browsers/actionstop
   rY   >            z*Successfully closed Browser Use session %sTz4Failed to close Browser Use session %s: HTTP %s - %sr{   z,Exception closing Browser Use session %s: %s)rR   rP   rq   warningrk   patchrT   r   debugrp   r    r   )r.   
session_idrQ   r%   es        r   close_sessionz'BrowserUseBrowserProvider.close_session   s    	%%'F	~~*%&j=f-'	H ##6I:VJ((MM$3'	 /  	NNMz 		0  	LLGUVW	s/   B AB? */B? B<;B<?	C)C$$C)c                   | j                         }|t        j                  d|       y 	 t        j                  |d    d| | j                  |      ddid       y # t        $ r!}t        j                  d||       Y d }~y d }~ww xY w)	NuG   Cannot emergency-cleanup Browser Use session %s — missing credentialsrA   rw   rx   ry   r
   rY   z7Emergency cleanup failed for Browser Use session %s: %s)r8   rq   r~   rk   r   rT   r    r   )r.   r   rQ   r   s       r   emergency_cleanupz+BrowserUseBrowserProvider.emergency_cleanup  s    ))+>NNY 
	NN*%&j=f-'	  	LLI:WX 	s   2A 	B'BBc                    dddddddgdd	S )
Nr3   paidz#Cloud browser with remote executionr>   zBrowser Use API keyzhttps://browser-use.com)keyprompturlagent_browser)r/   badgetagenv_vars
post_setupr,   r-   s    r   get_setup_schemaz*BrowserUseBrowserProvider.get_setup_schema0  s/    !8 134 *
 	
r1   N)returnr#   )r   rh   )r7   rh   r   zOptional[Dict[str, Any]])r   Dict[str, Any])rQ   r   r   r   )r   r#   r   zDict[str, object])r   r#   r   rh   )r   r#   r   None)__name__
__module____qualname____doc__propertyr/   r4   r9   r8   rR   rT   ru   r   r   r   r,   r1   r   r)   r)   h   s`        I <@  
D(
?
B>(
r1   r)   )r   r#   r   r#   )r   r#   r   r   )r%   zrequests.Responser   rh   )r   
__future__r   loggingrG   	threadingr   typingr   r   r   rk   agent.browser_providerr   	getLoggerr   rq   r	   __annotations__Lockr   rI   ri   rj   r   r   r'   r)   r,   r1   r   <module>r      s   8 #  	   & &  2			8	$ (* n )*INN, 0	#$  &* #0
,BU
 U
r1   