Ë
    ãß²j�   ã                  ó¾   — d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	m
Z
mZmZmZmZ  ej                  d«      ZdZdZd	d
d	dœZe G d„ d«      «       Z G d„ d«      Zy)af  Frame / OOPIF target tracking half of the CDP supervisor.

Maintains ``CDPSupervisor._frames`` from ``Page.frame*`` and ``Target.*``
events and renders the bounded ``frame_tree`` snapshot payload. ``FrameInfo``
entries for OOPIFs carry the child CDP session id so ``browser_cdp(frame_id=)``
can route calls into the iframe over the supervisor's live socket.
é    )ÚannotationsN)Ú	dataclassÚreplace)ÚAnyÚCallableÚDictÚListÚOptionalÚTupleztools.browser_supervisoré   é   TF)Ú
autoAttachÚwaitForDebuggerOnStartÚflattenc                  óh   — e Zd ZU dZded<   ded<   ded<   ded<   ded	<   d
Zded<   dZded<   dd„Zy
)Ú	FrameInfozâOne frame in the page's frame tree. ``is_oopif`` frames have their own CDP
    target (reachable via ``cdp_session_id``); same-origin / srcdoc iframes share
    the parent process (``is_oopif=False``, ``cdp_session_id=None``).ÚstrÚframe_idÚurlÚoriginúOptional[str]Úparent_frame_idÚboolÚis_oopifNÚcdp_session_idÚ Únamec                ó  — | j                   | j                  | j                  | j                  dœ}d| j                  fd| j
                  fd| j                  ff}|j                  |D ��ci c]  \  }}|sŒ	||“Œ c}}«       |S c c}}w )N)r   r   r   r   Ú
session_idr   r   )r   r   r   r   r   r   r   Úupdate)ÚselfÚdÚoptionalÚkÚvs        úD/home/ubuntu/.hermes/hermes-agent/tools/browser_supervisor_frames.pyÚto_dictzFrameInfo.to_dict(   s~   € ØŸ™¨t¯x©xÀ4Ç;Á;Ð\`×\iÑ\iÑjˆØ! 4×#6Ñ#6Ð7Ð:KÈT×MaÑMaÐ9bÐekÐmq×mvÑmvÐdwÐxˆØ	�‰ 8×1™4˜1˜aªq�!�Q‘$Ó1Ô2Øˆùó 2s   Á)
B
Á4B
©ÚreturnúDict[str, Any])Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r   r   r'   © ó    r&   r   r      s<   … ñIð ƒMØ	ƒHØƒKØ"Ó"ØƒNØ$(€N�MÓ(Ø€Dˆ#ƒNôr1   r   c                  óx   — e Zd ZU dZdd„Zdd„Zdd„Zdd„Zdd„Zddd„Z	dd	„Z
ddd
„Zdd„Zeeee	edœZded<   y)ÚFrameTrackingMixinzNFrame-tree bookkeeping for ``CDPSupervisor`` (event handlers run on its loop).c             ƒ  óÊ   K  — | j                  d||¬«      ƒ d{  –—†  | j                  d||¬«      ƒ d{  –—†  | j                  dt        ||¬«      ƒ d{  –—†  y7 ŒB7 Œ(7 Œ	­w)zAPage.enable + Runtime.enable + nested auto-attach on one session.zPage.enable)r   ÚtimeoutNzRuntime.enablezTarget.setAutoAttach)Ú_cdpÚ_AUTO_ATTACH_PARAMS)r!   r   r5   s      r&   Ú_enable_page_domainsz'FrameTrackingMixin._enable_page_domains2   sc   è ø€ à�i‰i˜°*ÀgˆiÓN×NÐNØ�i‰iÐ(°ZÈˆiÓQ×QÐQØ�i‰iÐ.Ô0CÐPZÐdkˆiÓl×lÑlð 	OøØQøØlús1   ‚A#šA›A#¶A· A#ÁA!ÁA#ÁA#Á!A#c           
     óŠ   — |j                  d«      }|r0| j                  t        |dd|j                  d«      d|¬«      «       y y )NÚframeIdr   ÚparentFrameIdF)r   r   r   r   r   r   )ÚgetÚ
_set_framer   )r!   Úparamsr   r   s       r&   Ú_on_frame_attachedz%FrameTrackingMixin._on_frame_attached8   sG   € Ø—:‘:˜iÓ(ˆÙØ�O‰OœI¨x¸RÈÐ\b×\fÑ\fÐgvÓ\wØ/4ÀZôQõ Rð r1   c                óx   — | j                   5  || j                  |j                  <   d d d «       y # 1 sw Y   y xY w©N)Ú_state_lockÚ_framesr   )r!   Úframes     r&   r=   zFrameTrackingMixin._set_frame>   s2   € Ø×Ññ 	1Ø+0ˆD�L‰L˜Ÿ™Ñ(÷	1÷ 	1ñ 	1ús   �0°9c                ót  — |j                  d«      xs i }|j                  d«      }|sy | j                  5  | j                  j                  |«      xs t        |ddd d|«      }t        |t	        |j                  d«      xs d«      t	        |j                  d«      xs |j                  d«      xs d«      |j                  d«      xs |j
                  |j                  |j                  t	        |j                  d	«      xs |j                  «      ¬
«      | j                  |<   d d d «       y # 1 sw Y   y xY w)NrD   Úidr   Fr   ÚsecurityOriginr   ÚparentIdr   )r   r   r   r   r   r   r   )	r<   rB   rC   r   r   r   r   r   r   )r!   r>   r   rD   r   Úolds         r&   Ú_on_frame_navigatedz&FrameTrackingMixin._on_frame_navigatedB   s  € Ø—
‘
˜7Ó#Ò) rˆØ—9‘9˜T“?ˆÙØØ×Ññ 	Ø—,‘,×"Ñ" 8Ó,Òd´	¸(ÀBÈÈDÐRWÐYcÓ0dˆCÜ%.Ø!¤s¨5¯9©9°UÓ+;Ò+A¸rÓ'BÜ˜5Ÿ9™9Ð%5Ó6ÒS¸%¿)¹)ÀHÓ:MÒSÐQSÓTØ %§	¡	¨*Ó 5Ò L¸×9LÑ9LÐWZ×WcÑWcØ"×1Ñ1¼¸E¿I¹IÀfÓ<MÒ<YÐQT×QYÑQYÓ8Zô	&ˆD�L‰L˜Ñ"÷	÷ 	ñ 	ús   ¶C/D.Ä.D7c                ón  — |j                  d«      }|r/t        |j                  d«      xs d«      j                  «       dk(  ry| j                  5  | j                  j                  |«      }|r|j
                  r|j                  s| j                  j                  |d«       ddd«       y# 1 sw Y   yxY w)u^  Drop a frame only when it's truly gone. ``reason="swap"`` = migrating processes
        (e.g. promoted to an OOPIF) â€” dropping would hide the iframe. Even with ``remove``
        the parent only knows the child left ITS process; a live child session means it's
        still alive, so keep it until Target.detached + a later frameDetached clear it.r:   ÚreasonÚremoveÚswapN)r<   r   ÚlowerrB   rC   r   r   Úpop)r!   r>   r   r   rI   s        r&   Ú_on_frame_detachedz%FrameTrackingMixin._on_frame_detachedP   s’   € ð
 —:‘:˜iÓ(ˆÙœ3˜vŸz™z¨(Ó3Ò?°xÓ@×FÑFÓHÈFÒRØØ×Ññ 	1Ø—,‘,×"Ñ" 8Ó,ˆCÙ˜CŸLšL¨S×-?Ò-?Ø—‘× Ñ  ¨4Ô0÷	1÷ 	1ñ 	1ús   ÁAB+Â+B4Nc              ƒ  óZ  K  — |j                  d«      xs i }|j                  d«      }|j                  d«      }|r|dvry |dk(  r´|j                  d«      }| j                  5  | j                  j                  |«      }t        |t	        |j                  d«      xs d«      dd	||r|j
                  nd t	        |j                  d
«      xs |r|j                  nd«      ¬«      | j                  |<   d d d «       t        j                  | j                  |«      «       y # 1 sw Y   Œ.xY w­w)NÚ
targetInfoÚ	sessionIdÚtype>   ÚiframeÚworkerrV   ÚtargetIdr   r   TÚtitle)r   r   r   r   r   r   r   )
r<   rB   rC   r   r   r   r   ÚasyncioÚcreate_taskÚ_enable_child_domains)r!   r>   r   ÚinfoÚsidÚtarget_typeÚ	target_idrI   s           r&   Ú_on_target_attachedz&FrameTrackingMixin._on_target_attached]   s  è ø€ Ø�z‰z˜,Ó'Ò-¨2ˆØ�j‰j˜Ó%ˆØ—h‘h˜vÓ&ˆÙ�kÐ)=Ñ=ØØ˜(Ò"ð Ÿ™ Ó,ˆIØ×!Ñ!ñ Ø—l‘l×&Ñ& yÓ1�Ü*3Ø&¬C°·±¸³Ò0EÀ2Ó,FÈrÐ\`ÐqtÙ;> C×$7Ò$7ÀDÌsÐSW×S[ÑS[Ð\cÓSdò  TBÑuxÐil×iqÒiqð  Aó  PCô+�—‘˜YÑ'÷ô 	×Ñ˜D×6Ñ6°sÓ;Õ<÷ð üs   ‚A!D+Á#BDÃ2-D+ÄD(Ä$D+c              ƒ  óÞ   K  — 	 | j                  |d¬«      ƒ d{  –—†  | j	                  |«      ƒ d{  –—†  y7 Œ# t        $ r$}t        j                  d|dd |«       Y d}~ŒDd}~ww xY w7 Œ7­w)zUEnable Page+Runtime (+nested setAutoAttach) and the dialog bridge on a child session.g      @)r5   Nz!child session %s setup failed: %sé   )r8   Ú	ExceptionÚloggerÚdebugÚ_install_dialog_bridge)r!   r^   Úes      r&   r\   z(FrameTrackingMixin._enable_child_domainsq   so   è ø€ ð	KØ×+Ñ+¨C¸Ð+Ó=×=Ð=ð ×)Ñ)¨#Ó.×.Ñ.ð >ùÜò 	KÜ�L‰LÐ<¸cÀ#À2¸hÈ×JÑJûð	Kúà.úsA   ‚A-„; š9›; ŸA-³A+´A-¹; »	A(ÁA#ÁA-Á#A(Á(A-c                ó<  — |j                  d«      }|sy| j                  5  | j                  j                  | j                  j	                  «       D ��ci c]"  \  }}|j
                  |k(  r|t        |d¬«      “Œ$ c}}«       ddd«       yc c}}w # 1 sw Y   yxY w)a  Clear the session binding of frames on a detached child session. Frames are
        deliberately NOT dropped: Browserbase fires transient detaches during page transitions
        while the iframe is still visible; ``Page.frameDetached`` cleans up if it truly goes away.rT   N)r   )r<   rB   rC   r    Úitemsr   r   )r!   r>   r   r^   ÚfidÚfs         r&   Ú_on_target_detachedz&FrameTrackingMixin._on_target_detachedy   s”   € ð �j‰j˜Ó%ˆÙØØ×Ññ 	>Ø�L‰L×ÑÐTX×T`ÑT`×TfÑTfÓTh÷ !=É&È#ÈqØ$%×$4Ñ$4¸Ò$;ð "%¤g¨aÀÔ&EÑ!Eó !=ô >÷	>ð 	>ùó!=÷	>ð 	>ús   ¡3BÁ'BÁ;BÂBÂBc                ó2  ‡‡	‡
— | j                   }|j                  «       D �cg c]  }|j                  rŒ|‘Œ }}t        d„ |D «       |r|d   nd«      }|€dg ddœS g }d}|j                  «       D �cg c]   }|j                  |j                  k(  sŒ|df‘Œ" }}|j                  hŠ
|rÆt        |«      t        k  r´|j                  d«      \  Š	Š‰	j                  ‰
v rŒ7‰
j                  ‰	j                  «       ‰	j                  r‰t        kD  rd}Œj|j                  ‰	j                  «       «       |j                  ˆˆ	ˆ
fd„|j                  «       D «       «       |rt        |«      t        k  rŒ´|j                  «       ||xs t        |«      dœS c c}w c c}w )	zÚCapped frame_tree payload (must hold state lock). Top frame = one with
        no parent, preferring oopif=False; BFS from it, capped by
        FRAME_TREE_MAX_ENTRIES and FRAME_TREE_MAX_OOPIF_DEPTH for OOPIF branches.c              3  ó:   K  — | ]  }|j                   rŒ|–— Œ y ­wrA   )r   )Ú.0rl   s     r&   ú	<genexpr>z>FrameTrackingMixin._build_frame_tree_locked.<locals>.<genexpr>Š   s   è ø€ Ò6˜!¨1¯:«:”AÑ6ùs   ‚”r   NF)ÚtopÚchildrenÚ	truncatedé   Tc              3  óz   •K  — | ]2  }|j                   ‰j                  k(  r|j                  ‰vr	|‰d z   f–— Œ4 y­w)ru   N)r   r   )rp   rl   ÚdepthrD   Úvisiteds     €€€r&   rq   z>FrameTrackingMixin._build_frame_tree_locked.<locals>.<genexpr>›   s@   øè ø€ ò _¨AØ×-Ñ-°·±Ò?ÀAÇJÁJÐV]ÑD]ð ˜U Q™Yœñ _ùs   ƒ8;)rC   Úvaluesr   Únextr   ÚlenÚFRAME_TREE_MAX_ENTRIESrP   Úaddr   ÚFRAME_TREE_MAX_OOPIF_DEPTHÚappendr'   Úextendr   )r!   Úframesrl   Útopsrr   rs   rt   Úqueuerw   rD   rx   s           @@@r&   Ú_build_frame_tree_lockedz+FrameTrackingMixin._build_frame_tree_locked„   si  ú€ ð —‘ˆØ!Ÿ=™=›?ÖD�a°!×2CÓ2C’ÐDˆÐDÜÑ6˜tÔ6Á4¸¸QºÈTÓRˆØˆ;Ø¨R¸eÑDÐDà)+ˆØˆ	Ø>D¿m¹m»oÖ-s¸ÐQR×QbÑQbÐfi×frÑfrÓQr¨q°!ªfÐ-sˆÐ-sØ—<‘<�.ˆÙœ˜H›Ô(>Ò>Ø Ÿ9™9 Q›<‰LˆE�5Ø�~‰~ Ñ(ØØ�K‰K˜Ÿ™Ô'Ø�~Š~ %Ô*DÒ"DØ �	ØØ�O‰O˜EŸM™M›OÔ,Ø�L‰Lõ _°·±³ô _ô _ñ œ˜H›Ô(>Ó>ð —{‘{“}°(ÈÒIaÔVZÐ[`ÓVaÑbÐbùò) Eùò .ts   ¢F´FÁ2FÂF)zPage.frameAttachedzPage.frameNavigatedzPage.frameDetachedzTarget.attachedToTargetzTarget.detachedFromTargetzDict[str, Callable[..., Any]]ÚEVENT_HANDLERS)r   r   r5   Úfloatr)   ÚNone)r>   r*   r   r   r)   r‡   )rD   r   r)   r‡   rA   )r^   r   r)   r‡   r(   )r+   r,   r-   r.   r8   r?   r=   rJ   rQ   ra   r\   rm   r„   r…   r/   r0   r1   r&   r3   r3   /   sU   … ÙXómóRó1óó1ô=ó(/ô	>ócð: 1Ø2Ø0Ø#6Ø%8ñ5€NÐ1ô r1   r3   )r.   Ú
__future__r   rZ   ÚloggingÚdataclassesr   r   Útypingr   r   r   r	   r
   r   Ú	getLoggerre   r|   r~   r7   r   r3   r0   r1   r&   ú<module>r�      st   ðñõ #ã Û ß *ß =× =ð 
ˆ×	Ñ	Ð5Ó	6€ð Ð ØÐ à%)ÀUÐW[Ñ\Ð ð ÷ð ó ð÷(wò wr1   