Ë
    ãß²jX  ã                  ó  — U 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	 ddl
mZmZ ddlmZ  ej                  e«      ZdZh d£Zd	d	d
dddœZded<   ddd	ddœZded<   dddœdAd„Z	 ddlZddlmZ dZd„ ZdBd„ZdCd„Z dDd„Z!dEd „Z"e"d!fd"„ d#fd$œZ#dFd%„Z$	 	 	 	 dGd&„Z%	 	 	 	 dHd'„Z&	 	 dI	 	 	 	 	 	 	 dJd(„Z'd)d*e› d+�d,d-d.d/œd,i dd0d1œd-d2d/œd-d3d/œd4d5d6d7œd8œdgd9œd:œZ(ded;<   dKd<„Z) ejT                  d)d=e(d>„ e)d?¬@«       y# e$ r	 dZeZdZY Œ–w xY w)LuŽ  Raw Chrome DevTools Protocol (CDP) passthrough tool ``browser_cdp``.

Sends arbitrary CDP commands to the browser's DevTools WebSocket when a CDP URL is
configured (``/browser connect`` â†’ ``BROWSER_CDP_URL``, ``browser.cdp_url``, or a
CDP-backed cloud session). Escape hatch for operations the main browser tools don't
cover. Method reference: https://chromedevtools.github.io/devtools-protocol/
é    )ÚannotationsN)ÚAnyÚDictÚOptional)ÚregistryÚ
tool_error)Úrouted_browser_handlerz3https://chromedevtools.github.io/devtools-protocol/>   úPage.reloadúPage.stopLoadingúTarget.getTargetsúBrowser.getVersionúTarget.detachFromTargetúPage.navigateúTarget.attachToTarget))Údata))ÚbufferedData))ÚscreenshotData))ÚresponseÚbody)zPage.captureScreenshotzPage.printToPDFzNetwork.streamResourceContentzHeadlessExperimental.beginFramez"CacheStorage.requestCachedResponsezDict[str, tuple]Ú_CDP_ALWAYS_BINARY_PATHS))r   ))ÚpostData)zNetwork.getResponseBodyzFetch.getResponseBodyzIO.readzNetwork.getRequestPostDataÚ_CDP_FLAGGED_BINARY_PATHS© ©Úalways_pathsÚflagged_pathsc          	     óþ  — ddl m} t        | t        «      r
 || d¬«      S t        | t        t
        f«      r t        | «      d„ | D «       «      S t        | t        «      s| S | j                  d«      du }d
d„}dd„}i }| j                  «       D ]l  \  }}	 |||«      xs  |||«      xr |}
t        |t        «      r
 ||d¬«      n|}t        |	t        «      r|
r|	nt        |	 |||«       |||«      ¬	«      ||<   Œn |S )uŸ  Redact browser-originated CDP result text; opaque bytes stay byte-identical.

    Exemptions come ONLY from the calling method's spec as exact result paths. Path
    suffixes propagate only into the matching subtree, so ``base64Encoded`` is honored
    solely as a sibling on the trusted carrier object â€” never as ambient trust a
    ``Runtime.evaluate`` by-value object could spoof.

    See #94138, #94142.
    r   )Úredact_sensitive_textT)Úforcec              3  ó2   K  — | ]  }t        |«      –— Œ y ­w)N)Ú_redact_cdp_output)Ú.0Úitems     ú;/home/ubuntu/.hermes/hermes-agent/tools/browser_cdp_tool.pyú	<genexpr>z%_redact_cdp_output.<locals>.<genexpr>>   s   è ø€ ÒF¸Ô-¨d×3ÑFùs   ‚Úbase64Encodedc                ó,   ‡— t        ˆfd„| D «       «      S )Nc              3  óN   •K  — | ]  }t        |«      d k(  xr |d   ‰k(  –— Œ y­w©é   r   N©Úlen©r"   ÚpÚkeys     €r$   r%   z3_redact_cdp_output.<locals>.leaf.<locals>.<genexpr>C   s)   øè ø€ Ò>°1”3�q“6˜Q‘;Ò. 1 Q¡4¨3¡;Ó.Ñ>ùs   ƒ"%)Úany©Úpathsr/   s    `r$   Úleafz _redact_cdp_output.<locals>.leafB   s   ø€ ÜÓ>¸Ô>Ó>Ð>ó    c                ó,   ‡— t        ˆfd„| D «       «      S )Nc              3  óX   •K  — | ]!  }t        |«      d kD  sŒ|d   ‰k(  sŒ|d d –— Œ# y­wr)   r+   r-   s     €r$   r%   z6_redact_cdp_output.<locals>.descend.<locals>.<genexpr>E   s+   øè ø€ ÒH˜q¬S°«V°a«Z¸A¸a¹DÀC»K�Q�q�r”UÑHùs   ƒ*—* 
*)Útupler1   s    `r$   Údescendz#_redact_cdp_output.<locals>.descendD   s   ø€ ÜÓH EÔHÓHÐHr4   r   )r2   r7   r/   ÚstrÚreturnÚbool)r2   r7   r/   r9   r:   r7   )Úagent.redactr   Ú
isinstancer9   Úlistr7   ÚtypeÚdictÚgetÚitemsr!   )Úvaluer   r   r   Úbase64_flaggedr3   r8   Úredactedr/   r#   ÚopaqueÚout_keys               r$   r!   r!   0   s  € õ 3Ü�%œÔÙ$ U°$Ô7Ð7Ü�%œ$¤˜Ô'ØŒt�E‹{ÑFÀÔFÓFÐFÜ�eœTÔ"ØˆØ—Y‘Y˜Ó/°4Ð7€Nó?óIà!€HØ—[‘[“]ò f‰	ˆˆTÙ�l CÓ(ÒY©T°-ÀÓ-EÒ-XÈ.ˆÜ<FÀsÌCÔ<PÑ'¨°4Õ8ÐVYˆÜ$.¨t´SÔ$9¹f™DÔJ\Ø™w |°SÓ9ÉÐQ^Ð`cÓIdôKfˆ�Òðfð
 €Or4   )ÚWebSocketExceptionTFc                óž  — 	 t        j                  «       }|r…|j                  «       ruddl}ddl}|j                  j                  d¬«      5 }|j                  |j                  «       j                  t         j                  | «      j                  «       cddd«       S t        j                  | «      S # t        $ r d}Y Œ©w xY w# 1 sw Y   Œ/xY w)zJRun an async coroutine from a sync handler, safe inside or outside a loop.Nr   r*   )Úmax_workers)ÚasyncioÚget_running_loopÚRuntimeErrorÚ
is_runningÚconcurrent.futuresÚcontextvarsÚfuturesÚThreadPoolExecutorÚsubmitÚcopy_contextÚrunÚresult)ÚcoroÚloopÚ
concurrentrP   Úpools        r$   Ú
_run_asyncr[   [   s²   € ðÜ×'Ñ'Ó)ˆñ �—‘Ô!Û!ÛØ×Ñ×2Ñ2¸qÐ2ÓAð 	[ÀTØ—;‘;˜{×7Ñ7Ó9×=Ñ=¼w¿{¹{ÈDÓQ×XÑXÓZ÷	[ñ 	[ä�;‰;�tÓÐøô ò ØŠðú÷
	[ð 	[ús   ‚B2 ÁACÂ2C Â?C ÃCc                 óš   — 	 ddl m}   | «       xs dj                  «       S # t        $ r }t        j                  d|«       Y d}~yd}~ww xY w)zONormalized CDP WebSocket URL via ``browser_tool_cdp._get_cdp_override``, or "".r   )Ú_get_cdp_overrideÚ z/browser_cdp: failed to resolve CDP endpoint: %sN)Útools.browser_tool_cdpr]   ÚstripÚ	ExceptionÚloggerÚdebug)r]   Úexcs     r$   Ú_resolve_cdp_endpointre   i   sC   € ðÝ<Ù!Ó#Ò) r×0Ñ0Ó2Ð2øÜò Ü�‰ÐFÈÔLÜûðús   ‚! ¡	A
ªAÁA
Úmethodc                ó&   — t        | |t        ¬«      S )N)rf   Úcdp_docs)r   ÚCDP_DOCS_URL)Úmessagerf   s     r$   Ú_blockedrk   s   s   € Ü�g f´|ÔDÐDr4   c                ó   — ddl m}  || «      S )Nr   )Ú_expression_targets_private_url)Útools.browser_tool_eval_policyrm   )Ú
expressionrm   s     r$   Ú_expression_private_targetrp   w   s   € ÝNÙ*¨:Ó6Ð6r4   úDict[str, Any]c                ó„   — ddl m} t        |j                  d«      xs d«      j	                  «       }|r || |«      r|S dS )z@Blocked URL literal for ``Page.navigate`` params, else ``None``.r   )Ú_url_blockedÚurlr^   N)rn   rs   r9   rA   r`   )ÚbtÚparamsrs   Ú
target_urls       r$   Ú_navigate_private_targetrx   |   s<   € å;Ü�V—Z‘Z Ó&Ò,¨"Ó-×3Ñ3Ó5€JÙ#©°R¸Ô(Dˆ:ÐNÈ$ÐNr4   zHBlocked: CDP Page.navigate target is a private or internal address ({}).c                óP   — t        t        |j                  d«      xs d«      «      S )Nro   r^   )rp   r9   rA   )ru   rv   s     r$   ú<lambda>rz   ‡   s!   € Ô,FÄsÈ6Ï:É:ÐVbÓKcÒKiÐgiÓGjÓ,k€ r4   zTBlocked: CDP Runtime.evaluate expression targets a private or internal address ({}).)r   zRuntime.evaluatec                ó‚  — 	 ddl m} ddl m} |j                  | «      syt        j                  |«      }|�/|\  }} |||xs i «      }|rt        |j                  |«      |«      S |t        vr&|j                  | «      }	|	rt        d|	› d|›d�|«      S y# t        $ r }
t        j                  d|
«       Y d}
~
yd}
~
ww xY w)	a3  Apply the browser SSRF/private-page guard to raw CDP calls.

    Raw CDP shares the cloud/private-network boundary of ``browser_snapshot`` /
    ``browser_console`` / ``browser_eval`` and must not become their bypass. Probes are
    best-effort; a probe failure never breaks local/custom CDP workflows.
    r   )Úbrowser_tool)Úbrowser_tool_eval_policyNz9Blocked: page URL targets a private or internal address (z). Raw CDP method z, could expose private page content or state.z0browser_cdp: private-page guard probe failed: %s)Útoolsr|   r}   Ú_eval_ssrf_guard_activeÚ_METHOD_PARAM_GUARDSrA   rk   ÚformatÚ!_CDP_PRIVATE_PAGE_ALLOWED_METHODSÚ_current_page_private_urlra   rb   rc   )Útask_idrf   rv   ru   ÚpolicyÚguardÚprobeÚtemplateÚliteralÚblocked_urlrd   s              r$   Ú_browser_cdp_private_guardr‹   Œ   sà   € ðNÝ,Ý<Ø×-Ñ-¨gÔ6ØÜ$×(Ñ(¨Ó0ˆØÐØ#‰OˆE�8Ù˜B ¢¨"Ó-ˆGÙÜ §¡°Ó 8¸&ÓAÐAØÔ:Ñ:Ø ×:Ñ:¸7ÓCˆKÙÜÐ"[Ð\gÐ[hð i2Ø28°Ð;gð!iØjpórð rð øô ò NÜ�‰ÐGÈ×MÐMØûðNús#   ‚B  AB Á&-B Â	B>ÂB9Â9B>c              ƒ  ó@  ‡‡
‡K  — t         €J ‚ddlm} t        j                  | fd‰dddœ || «      ¤Ž4 ƒd{  –—† ŠdŠ
dˆ
ˆˆfd„}||xs i dœ}|rb |d	|d
dœdœd|› �«      ƒ d{  –—† }d|v rt	        d|d   › �«      ‚|j                  di «      j                  d«      }	|	st	        d«      ‚|	|d<    ||d|› �«      ƒ d{  –—† }d|v rt	        d|d   › �«      ‚|j                  di «      cddd«      ƒd{  –—†  S 7 ŒÇ7 Œš7 Œ@7 Œ# 1 ƒd{  –—†7  sw Y   yxY w­w)zÇMake a single CDP call. With ``target_id``, ``Target.attachToTarget(flatten=True)`` multiplexes a
    page-level session over the browser-level WebSocket; without it ``method`` runs at browser level.Nr   )Úloopback_connect_kwargsé   )Úmax_sizeÚopen_timeoutÚclose_timeoutÚping_intervalr*   c              “  óî  •K  — ‰‰dz   c}Š‰j                  t        j                  d|i| ¥«      «      ƒ d {  –—†  t        j                  «       j                  «       ‰z   }	 |t        j                  «       j                  «       z
  }|dk  rt        d|› �«      ‚t        j                  t        j                  ‰j                  «       |¬«      ƒ d {  –—† «      }|j                  d«      |k(  r|S Œ�7 Œ¹7 Œ!­w)Nr*   Úidr   z
Timed out ©Útimeout)ÚsendÚjsonÚdumpsrK   rL   ÚtimeÚTimeoutErrorÚloadsÚwait_forÚrecvrA   )	ÚreqÚwhatÚcall_idÚdeadlineÚ	remainingÚmsgÚnext_idr–   Úwss	         €€€r$   Ú_sendz_cdp_call.<locals>._send´   sÚ   øè ø€ à&¨°!©ÐˆG�WØ—'‘'œ$Ÿ*™* d¨GÐ%;°sÐ%;Ó<Ó=×=Ð=Ü×/Ñ/Ó1×6Ñ6Ó8¸7ÑBˆHØØ$¤w×'?Ñ'?Ó'A×'FÑ'FÓ'HÑH�	Ø ’>Ü&¨°D°6Ð':Ó;Ð;Ü—j‘j¤w×'7Ñ'7¸¿¹»	È9Ô'U×!UÓV�Ø—7‘7˜4“= GÒ+Ø�Jð ð >øð "Vús"   ƒ4C5·C1¸BC5ÃC3Ã C5Ã3C5)rf   rv   r   T)ÚtargetIdÚflattenzattaching to target ÚerrorzTarget.attachToTarget failed: rV   Ú	sessionIdz0Target.attachToTarget did not return a sessionIdzwaiting for response to zCDP error: )rŸ   rq   r    r9   r:   rq   )Ú
websocketsÚagent.proxy_bypassr�   ÚconnectrM   rA   )Úws_urlrf   rv   Ú	target_idr–   r�   r§   rŸ   r¤   Ú
session_idr¥   r¦   s       `     @@r$   Ú	_cdp_callr²   ¨   se  úè ø€ ô Ð!Ð!Ð!Ý:ô ×!Ñ! &ð Y°4ÀgÐ]^Ø04ñYÙ8OÐPVÓ8WñY÷ %ð %Ø\^Øˆ÷	ð *0¸6º<ÀRÑHˆÙÙÐ)@ÐYbÐosÑLtÑuØ 4°Y°KÐ@óB÷ BˆCà˜#‰~Ü"Ð%CÀCÈÁLÀ>Ð#RÓSÐSØŸ™ ¨2Ó.×2Ñ2°;Ó?ˆJÙÜ"Ð#UÓVÐVØ)ˆC�Ñá˜#Ð!9¸&¸ÐBÓC×CˆØ�c‰>Ü ¨S°©\¨NÐ;Ó<Ð<Ø�w‰w�x Ó$÷?%÷ %ò %øð&Bøð Døð9%ø÷ %÷ %ñ %üsi   …4D¹DºD½+D	Á(DÁ)AD	ÃDÃ*D	Ã/DÃ;DÃ<DÄD	ÄD	ÄDÄ	DÄDÄDÄDc           
     ó  ‡— 	 ddl m} |j	                  | «      }|€t        d| ›d�«      S |j                  «       j                  }t        ˆfd„|j	                  d	«      g|j	                  d
«      xs g ¢D «       d«      }	|	€D|j                  5  |j                  j	                  ‰«      }
ddd«       
�|
j                  «       nd}	|	€t        d‰›d�«      S |	j	                  d«      }|st        d‰›d�«      S |j                  }|�|j                  «       st        d«      S 	 ddlm}  ||j                  ||xs i ||¬«      |«      }|€t        dt         ¬«      S |j#                  |dz   ¬«      }t)        j*                  d|‰||j	                  di «      dœd¬«      S # t        $ r}t        d|› d�«      cY d}~S d}~ww xY w# 1 sw Y   �ŒxY w# t        $ r4}t        dt%        |«      j&                  › d|› �t         ¬«      cY d}~S d}~ww xY w)zHRoute a CDP call through the live supervisor session for an OOPIF frame.r   )ÚSUPERVISOR_REGISTRYz!CDP supervisor is not available: zp. frame_id routing requires a running supervisor attached via /browser connect or an active Browserbase session.Nz'No CDP supervisor is attached for task=zª. Call browser_navigate or /browser connect first so the supervisor can attach. Once attached, browser_snapshot will populate frame_tree with frame_ids you can pass here.c              3  óR   •K  — | ]  }|sŒ|j                  d «      ‰k(  sŒ|–— Œ  y­w)Úframe_idN)rA   )r"   Úfr¶   s     €r$   r%   z._browser_cdp_via_supervisor.<locals>.<genexpr>ã   s%   øè ø€ ÒlˆqÊÈaÏeÉeÐT^ÓN_ÐckÓNkŒÑlùs   ƒ'‹' 'ÚtopÚchildrenz	frame_id zP not found in supervisor state. Call browser_snapshot to see current frame_tree.r±   zò is not an out-of-process iframe (no dedicated CDP session). For same-origin iframes, use `browser_cdp(method='Runtime.evaluate', params={'expression': "document.querySelector('iframe').contentDocument.title"})` at the top-level page instead.zKCDP supervisor loop is not running. Try reconnecting with /browser connect.)Úsafe_schedule_threadsafe)r±   r–   z0CDP call via supervisor failed: loop unavailable©rh   é   r•   z CDP call via supervisor failed: ú: TrV   )Úsuccessrf   r¶   r±   rV   F©Úensure_ascii)Útools.browser_supervisorr´   ra   r   rA   ÚsnapshotÚ
frame_treeÚnextÚ_state_lockÚ_framesÚto_dictÚ_looprN   Úagent.async_utilsrº   Ú_cdpri   rV   r?   Ú__name__r˜   r™   )r„   r¶   rf   rv   r–   r´   rd   Ú
supervisorÚtreeÚ
frame_infoÚrawÚ	child_sidrX   rº   ÚfutÚ
result_msgs    `              r$   Ú_browser_cdp_via_supervisorrÓ   Ò   s_  ø€ ðhÝ@ð
 %×(Ñ(¨Ó1€JØÐÜÐCÀGÀ;ð OWð Wó Xð 	Xð ×ÑÓ ×+Ñ+€DÜ+/Ûl�T—X‘X˜e“_ÐD¨¯©°Ó(<Ò(BÀÐDÔlÐnró,t€JàÐØ×#Ñ#ñ 	3Ø×$Ñ$×(Ñ(¨Ó2ˆC÷	3à&) o�S—[‘[”]¸4ˆ
ØÐÜ˜I h \ð 2Mð Mó Nð 	Nð —‘˜|Ó,€IÙÜ˜I h \ð 2yð yó zð 	zð ×Ñ€DØ€|˜4Ÿ?™?Ô,ÜÐgÓhÐhðqÝ>Ù&Ø�O‰O˜F F¢L¨b¸YÐPWˆOÓXÐZ^ó`ˆàˆ;ÜÐPÔ[gÔhÐhØ—Z‘Z¨°!©�ZÓ4ˆ
ô �:‰: $°&ÀhÐ^gØ!+§¡°¸"Ó!=ñ?ØMRôTð TøôS ò hÜÐ=¸c¸Uð Cgð gó hõ 	hûðhú÷	3ñ 	3ûô0 ò qÜÐ<¼TÀ#»Y×=OÑ=OÐ<PÐPRÐSVÐRWÐXÔcoÔpÕpûðqúsM   ƒF ÂGÄ"8G ÅG Æ	F?Æ&F:Æ4F?Æ:F?ÇGÇ	HÇ)HÈHÈHc           
     óÐ  — |xs d}|r&t        || |xs i ¬«      }|r|S t        ||| ||¬«      S | rt        | t        «      st	        dt
        ¬«      S t        st	        d«      S t        «       }|st	        dt
        ¬«      S |j                  d«      st	        d	|›d
�«      S |xs i }	t        |	t        «      s!t	        dt        |	«      j                  › �«      S t        || |	¬«      }|r|S 	 |rt        |«      nd}
t        dt!        |
d«      «      }
	 t#        t%        || |	||
«      «      }d| t5        |t6        j9                  | d«      t:        j9                  | d«      ¬«      dœ}|r||d<   t=        j>                  |d¬«      S # t        t        f$ r d}
Y Œšw xY w# t&        j(                  $ r}t	        d|
› d|› �| ¬«      cY d}~S d}~wt(        t*        f$ r }t	        t        |«      | ¬«      cY d}~S d}~wt,        $ r}t	        d|› d|› d�| ¬«      cY d}~S d}~wt.        $ rE}t0        j3                  d«       t	        dt        |«      j                  › d|› �| ¬«      cY d}~S d}~ww xY w)uë  Send a raw CDP command (see ``CDP_DOCS_URL``). ``target_id`` attaches a fresh stateless connection
    to a tab; ``frame_id`` (OOPIF from ``browser_snapshot.frame_tree``) routes through the supervisor's live
    WebSocket instead â€” the only reliable way to evaluate inside an iframe where fresh per-call connections
    hit signed-URL expiry (Browserbase). Both paths share the same private-page/SSRF guard. Returns JSON
    ``{"success": True, "method", "result"}`` or ``{"error": ...}``.Údefault)r„   rf   rv   )r„   r¶   rf   rv   r–   z/'method' is required (e.g. 'Target.getTargets')r»   zfThe 'websockets' Python package is required but not installed. Install it with: pip install websocketszØNo CDP endpoint is available. Run '/browser connect' to attach to a running Chrome, Brave, Chromium, or Edge browser, or set 'browser.cdp_url' in config.yaml. The Camofox backend is REST-only and does not expose CDP.)zws://zwss://z%CDP endpoint is not a WebSocket URL: u¬   . Expected ws://... or wss://... â€” the /browser connect resolver should have rewritten this. Check that a Chromium-family browser is actually listening on the debug port.z%'params' must be an object/dict, got ç      >@g      ð?g     Àr@zCDP call timed out after zs: )rf   Nz"WebSocket error talking to CDP at r½   uE   . The browser may have disconnected â€” try '/browser connect' again.zbrowser_cdp unexpected errorzUnexpected error: Tr   r   )r¾   rf   rV   r°   Fr¿   ) r‹   rÓ   r=   r9   r   ri   Ú_WS_AVAILABLEre   Ú
startswithr@   r?   rË   ÚfloatÚ	TypeErrorÚ
ValueErrorÚmaxÚminr[   r²   rK   r›   rM   rH   ra   rb   Ú	exceptionr!   r   rA   r   r˜   r™   )rf   rv   r°   r¶   r–   r„   Úeffective_task_idÚblockedÚendpointÚcall_paramsÚsafe_timeoutrV   rd   Úpayloads                 r$   Úbrowser_cdprå     sª  € ð  Ò, 9ÐáÜ,Ð5FÈvÐ^dÒ^jÐhjÔkˆÙØˆNÜ*Ð3DÈxÐ`fØ28À'ôKð 	Kñ œ F¬CÔ0ÜÐKÔVbÔcÐcÝÜð Dó Eð 	Eä$Ó&€HÙÜð JäT`ôbð 	bð ×ÑÐ2Ô3ÜÐAÀ(Àð NMð Mó Nð 	Nð #)¢,¨B€KÜ�k¤4Ô(ÜÐAÄ$À{ÓBS×B\ÑB\ÐA]Ð^Ó_Ð_ä(Ð1BÈ6ÐZeÔf€GÙØˆðÙ)0”u˜W”~°dˆô �sœC ¨eÓ4Ó5€Lð[ÜœI h°¸ÀYÐP\Ó]Ó^ˆð +/¸&ÔL^ØÔ5×9Ñ9¸&À"ÓEÜ/×3Ñ3°F¸BÓ?ôMAñ B€Gñ Ø(ˆ�ÑÜ�:‰:�g¨EÔ2Ð2øô+ ”zÐ"ò ØŠðûô
 ×Ñò ]ÜÐ5°l°^À3ÀsÀeÐLÐU[Ô\Õ\ûÜœ,Ð'ò 3Üœ#˜c›(¨6Ô2Õ2ûÜò [ÜÐ>¸x¸jÈÈ3È%ð PKð KØSYô[õ 	[ûäò [Ü×ÑÐ7Ô8ÜÐ.¬t°C«y×/AÑ/AÐ.BÀ"ÀSÀEÐJÐSYÔZÕZûð[úsf   Ã*F  ÄF Æ FÆFÆI%Æ*GÆ<I%ÇI%ÇG/Ç)I%Ç/I%Ç;HÈI%ÈI%È :I ÉI%É I%rå   uœ  Send a raw Chrome DevTools Protocol (CDP) command. Escape hatch for browser operations not covered by browser_navigate, browser_click, browser_console, etc.

**Requires a reachable CDP endpoint.** Available when the user has run '/browser connect' to attach to a running Chrome, Brave, Chromium, or Edge browser, or when 'browser.cdp_url' is set in config.yaml. Not currently wired up for cloud backends (Browserbase, Browser Use, Firecrawl) â€” those expose CDP per session but live-session routing is a follow-up. Camofox is REST-only and will never support CDP. If the tool is in your toolset at all, a CDP endpoint is already reachable.

**CDP method reference:** uÅ   â€” use an available documentation lookup or extraction tool on a method's URL (e.g. '/tot/Page/#method-handleJavaScriptDialog') to look up parameters and return shape.

**Common patterns:**
- List tabs: method='Target.getTargets', params={}
- Handle a native JS dialog: method='Page.handleJavaScriptDialog', params={'accept': true, 'promptText': ''}, target_id=<tabId>
- Get all cookies: method='Network.getAllCookies', params={}
- Eval in a specific tab: method='Runtime.evaluate', params={'expression': '...', 'returnByValue': true}, target_id=<tabId>
- Set viewport for a tab: method='Emulation.setDeviceMetricsOverride', params={'width': 1280, 'height': 720, 'deviceScaleFactor': 1, 'mobile': false}, target_id=<tabId>

**Usage rules:**
- Browser-level methods (Target.*, Browser.*, Storage.*): omit target_id and frame_id.
- Page-level methods (Page.*, Runtime.*, DOM.*, Emulation.*, Network.* scoped to a tab): pass target_id from Target.getTargets.
- **Cross-origin iframe scope** (Runtime.evaluate inside an OOPIF, Page.* targeting a frame target, etc.): pass frame_id from the browser_snapshot frame_tree output. This routes through the CDP supervisor's live connection â€” the only reliable way on Browserbase where stateless CDP calls hit signed-URL expiry.
- Each stateless call (without frame_id) is independent â€” sessions and event subscriptions do not persist between calls. For stateful workflows, prefer the dedicated browser tools or use frame_id routing.ÚobjectÚstringz]CDP method name, e.g. 'Target.getTargets', 'Runtime.evaluate', 'Page.handleJavaScriptDialog'.)r?   ÚdescriptionzaMethod-specific parameters as a JSON object. Omit or pass {} for methods that take no parameters.)r?   Ú
propertiesÚadditionalPropertiesrè   z©Optional. Target/tab ID from Target.getTargets result (each entry's 'targetId'). Use for page-level methods at the top-level tab scope. Mutually exclusive with frame_id.aà  Optional. Out-of-process iframe (OOPIF) frame_id from browser_snapshot.frame_tree.children[] where is_oopif=true. When set, routes the call through the CDP supervisor's live session for that iframe. Essential for Runtime.evaluate inside cross-origin iframes, especially on Browserbase where fresh per-call CDP connections can't keep up with signed URL rotation. For same-origin iframes, use parent contentWindow/contentDocument from Runtime.evaluate at the top-level page instead.Únumberé   z)Timeout in seconds (default 30, max 300).)r?   rÕ   rè   )rf   rv   r°   r¶   r–   )r?   ré   Úrequired)Únamerè   Ú
parametersÚBROWSER_CDP_SCHEMAc                 ó¦   — 	 ddl m}  ddlm} t         |«       xr  | «       «      S # t        $ r }t
        j                  d|«       Y d}~yd}~ww xY w)aH  Availability check: offered only when a static CDP URL is set (Camofox is REST-only;
    the default local agent-browser hides its CDP port; cloud per-session ``cdp_url`` isn't
    surfaced). Raw (no-I/O) gate: check_fns run at every startup, and resolving the endpoint
    over HTTP here would block launch on a stale endpoint.r   )Ú_get_cdp_override_raw)Úcheck_browser_requirementsz1browser_cdp check: browser_tool import failed: %sNF)r_   rò   Útools.browser_tool_installró   ÚImportErrorrb   rc   r;   )rò   ró   rd   s      r$   Ú_browser_cdp_checkrö   ~  sK   € ð
Ý@ÝIô Ñ*Ó,ÒHÑ1FÓ1HÓIÐIøô ò Ü�‰ÐHÈ#ÔNÜûðús   ‚' §	A°AÁAzbrowser-cdpc           	     ój   ‡ ‡— t        d‰ ˆ ˆfd„‰j                  d«      ‰j                  d«      ¬«      S )Nrå   c            
     óÞ   •— t        ‰ j                  dd«      ‰ j                  d«      ‰ j                  d«      ‰ j                  d«      ‰ j                  dd«      ‰j                  d«      ¬	«      S )
Nrf   r^   rv   r°   r¶   r–   rÖ   r„   )rf   rv   r°   r¶   r–   r„   )rå   rA   ©ÚargsÚkws   €€r$   rz   z<lambda>.<locals>.<lambda>’  s\   ø€ œØ—8‘8˜H bÓ)°$·(±(¸8Ó2DÐPT×PXÑPXÐYdÓPeØ—X‘X˜jÓ)°4·8±8¸IÀtÓ3LÐVX×V\ÑV\Ð]fÓVgô
€ r4   r„   r±   )Úfallbackr„   r±   )r	   rA   rù   s   ``r$   rz   rz   �  s0   ù€ Ô5Ø�tô
ð —‘�yÓ!¨b¯f©f°\Ó.Bô € r4   u   ðŸ§ª)rî   ÚtoolsetÚschemaÚhandlerÚcheck_fnÚemoji)rC   r   r   r7   r   r7   r:   r   )r:   r9   )rj   r9   rf   r9   r:   r9   )ro   r9   r:   úOptional[str])ru   r   rv   rq   r:   r  )r„   r9   rf   r9   rv   rq   r:   r  )r¯   r9   rf   r9   rv   rq   r°   r  r–   rÙ   r:   rq   )r„   r9   r¶   r9   rf   r9   rv   úOptional[Dict[str, Any]]r–   rÙ   r:   r9   )NNNrÖ   N)rf   r9   rv   r  r°   r  r¶   r  r–   rÙ   r„   r  r:   r9   )r:   r;   )+Ú__doc__Ú
__future__r   rK   r˜   ÚloggingÚtypingr   r   r   Útools.registryr   r   Útools.browser_extension_routerr	   Ú	getLoggerrË   rb   ri   r‚   r   Ú__annotations__r   r!   r¬   Úwebsockets.exceptionsrH   r×   rõ   ra   r[   re   rk   rp   rx   r€   r‹   r²   rÓ   rå   rð   rö   Úregisterr   r4   r$   ú<module>r     s  ðòõ #ã Û Û ß &Ñ &ç /Ý Aà	ˆ×	Ñ	˜8Ó	$€àD€ò%Ð !ð +¸|Ø%9Ð^tØ*Añ.Ð Ð*ó ð  ,ÀlØÐ;Kñ/Ð Ð+ó ð =?ÐWYõ ð@ÛÝ8à€MòóóEó7ó
Oð /Ø`ðbákØoðqñÐ óð8'%Ø"ð'%Ø'5ó'%ðT/TØ).ð/TØ36ó/Tðd bfØ`dð=3Ø'ð=3Ø9>ð=3ØP]ð=3Øiló=3ðB ð	%ð &2 Nð 3ð	ð@ à'Øoñrà'°rÐSWØsñvà"*ðcñeð "*ð*ñ,ð !)°RÐHsÑtñ
ð" �Jñ'ñE7&Ð �Nó 7ótJð €× Ñ Ø	ØØñð  Ø
öøðo	 ò Ø€JØ"ÐØ‚Mðús   Á(C= Ã=DÄ
D