§
    ~Štj­:  ã                  ó:  — 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ZddlZddl	m
Z
 ddlmZmZmZ ddlmZ ddlmZ erddlmZmZ  ej        e¦  «        Zd	ZdZd	Zd
ZdZdZd d„Zd!d„Z  G d„ d¦  «        Z!dZ"d"d„Z#d„ Z$ G d„ d¦  «        Z% G d„ d¦  «        Z&dS )#a  TCP tunnel for accessing services running inside sandboxes.

Establishes a WebSocket connection to the daemon's ``/tunnel`` endpoint,
runs a yamux multiplexing session on top, and forwards local TCP connections
through yamux streams to the target port inside the sandbox.
é    )ÚannotationsN)ÚMapping)ÚTYPE_CHECKINGÚAnyÚOptional)Úmerge_headers)ÚWS_OPEN_TIMEOUT)ÚYamuxSessionÚYamuxStreamé   é   é   z>BHÚstreamr   ÚportÚintÚreturnÚNonec                ól   — |                       t          j        t          t          |¦  «        ¦  «         dS )zAWrite the 3-byte connect header on a freshly opened yamux stream.N)ÚwriteÚstructÚpackÚ_CONNECT_HEADER_FMTÚPROTOCOL_VERSION)r   r   s     úW/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/langsmith/sandbox/_tunnel.pyÚ_write_connect_headerr   )   s*   € à
‡L‚L•”Õ0Õ2BÀDÑIÔIÑJÔJÐJÐJÐJó    c                ó^   — |                       d¦  «        }|st          d¦  «        ‚|d         S )z0Read the 1-byte status response from the daemon.r   z'tunnel: connection closed before statusr   )ÚreadÚConnectionError)r   Údatas     r   Ú_read_statusr!   .   s2   € à�;Š;�q‰>Œ>€DØð IÝÐGÑHÔHÐHØ�Œ7€Nr   c                  ó2   — e Zd ZdZdd„Zdd
„Zdd„Zdd„ZdS )Ú
_WSAdaptera
  Adapts the ``websockets`` message API to a byte-stream interface.

    yamux requires a plain read/write/close byte stream.  WebSocket is
    message-based, so this adapter buffers partially consumed messages on
    reads and sends one binary message per write.
    Úwsr   r   r   c                ój   — || _         t          ¦   «         | _        t          j        ¦   «         | _        d S ©N)Ú_wsÚ	bytearrayÚ_bufÚ	threadingÚLockÚ_write_lock)Úselfr$   s     r   Ú__init__z_WSAdapter.__init__C   s*   € ØˆŒÝ‘K”KˆŒ	Ý$œ>Ñ+Ô+ˆÔÐÐr   Únr   Úbytesc                ój  — t          | j        ¦  «        |k     rt| j                             ¦   «         }t	          |t
          ¦  «        r|                     ¦   «         }| j                             |¦  «         t          | j        ¦  «        |k     °tt          | j        d |…         ¦  «        }| j        d |…= |S r&   )	Úlenr)   r'   ÚrecvÚ
isinstanceÚstrÚencodeÚextendr0   )r-   r/   ÚmsgÚresults       r   r   z_WSAdapter.readH   s™   € Ý�$”)‰nŒn˜qÒ Ð Ø”(—-’-‘/”/ˆCÝ˜#�sÑ#Ô#ð #Ø—j’j‘l”l�ØŒI×Ò˜SÑ!Ô!Ð!õ	 �$”)‰nŒn˜qÒ Ð õ �t”y  ! ”}Ñ%Ô%ˆØŒI�b�q�bˆMØˆr   r    c                ó’   — | j         5  | j                             |¦  «         d d d ¦  «         n# 1 swxY w Y   t          |¦  «        S r&   )r,   r'   Úsendr2   )r-   r    s     r   r   z_WSAdapter.writeS   s€   € ØÔð 	 ð 	 ØŒH�MŠM˜$ÑÔÐð	 ð 	 ð 	 ñ 	 ô 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 øøøð 	 ð 	 ð 	 ð 	 å�4‰yŒyÐs   ˆ/¯3¶3c                ó\   — 	 | j                              ¦   «          d S # t          $ r Y d S w xY wr&   )r'   ÚcloseÚ	Exception©r-   s    r   r=   z_WSAdapter.closeX   sA   € ð	ØŒH�NŠNÑÔÐÐÐøÝð 	ð 	ð 	ØˆDˆDð	øøøs   ‚ �
+ª+N)r$   r   r   r   )r/   r   r   r0   )r    r0   r   r   ©r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r.   r   r   r=   © r   r   r#   r#   ;   sn   € € € € € ðð ð,ð ,ð ,ð ,ð
	ð 	ð 	ð 	ðð ð ð ð
ð ð ð ð ð r   r#   i @  Útcp_connúsocket.socketc                ót  ‡ ‡‡— t          j        ¦   «         Šd
ˆˆ ˆfd„}d
ˆˆ ˆfd„}t          j        |d¬¦  «        }t          j        |d¬¦  «        }|                     ¦   «          |                     ¦   «          ‰                     ¦   «          	 ‰                      ¦   «          n# t          $ r Y nw xY w	 ‰                     t          j	        ¦  «         n# t          $ r Y nw xY w	 ‰                     ¦   «          n# t          $ r Y nw xY w|                     d¬¦  «         |                     d¬¦  «         d	S )z:Copy data bidirectionally until one side closes or errors.r   r   c                 óî   •— 	 	 ‰                      t          ¦  «        } | sn‰                     | ¦  «         Œ3n# t          $ r Y nw xY w‰                     ¦   «          d S # ‰                     ¦   «          w xY wr&   )r   Ú_BRIDGE_BUF_SIZEÚsendallr>   Úset©r    Údoner   rF   s    €€€r   Ú_stream_to_tcpz_bridge.<locals>._stream_to_tcpj   s�   ø€ ð		ð'Ø—{’{Õ#3Ñ4Ô4�Øð ØØ× Ò  Ñ&Ô&Ð&ð	'ð øåð 	ð 	ð 	ØˆDð	øøøð �HŠH‰JŒJˆJˆJˆJøˆD�HŠH‰JŒJˆJˆJøøøó&   ƒ48 ·A ¸
AÁA ÁAÁA ÁA4c                 óî   •— 	 	 ‰                      t          ¦  «        } | sn‰                     | ¦  «         Œ3n# t          $ r Y nw xY w‰                     ¦   «          d S # ‰                     ¦   «          w xY wr&   )r3   rJ   r   r>   rL   rM   s    €€€r   Ú_tcp_to_streamz_bridge.<locals>._tcp_to_streamv   s‹   ø€ ð		ð#Ø—}’}Õ%5Ñ6Ô6�Øð ØØ—’˜TÑ"Ô"Ð"ð	#ð øåð 	ð 	ð 	ØˆDð	øøøð �HŠH‰JŒJˆJˆJˆJøˆD�HŠH‰JŒJˆJˆJøøørP   T)ÚtargetÚdaemoné   )ÚtimeoutNr@   )r*   ÚEventÚThreadÚstartÚwaitr=   r>   ÚshutdownÚsocketÚ	SHUT_RDWRÚOSErrorÚjoin)r   rF   rO   rR   Út1Út2rN   s   ``    @r   Ú_bridgerb   f   s�  øøø€ åŒ?ÑÔ€Dð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
õ 
Ô	 ¸Ð	=Ñ	=Ô	=€BÝ	Ô	 ¸Ð	=Ñ	=Ô	=€BØ‡H‚H�J„J€JØ‡H‚H�J„J€Jà‡I‚I�K„K€KðØ�Š‰ŒˆˆøÝð ð ð ØˆðøøøðØ×Ò�&Ô*Ñ+Ô+Ð+Ð+øÝð ð ð ØˆðøøøðØ�ŠÑÔÐÐøÝð ð ð Øˆðøøøð ‡G‚G�A€GÑÔÐØ‡G‚G�A€GÑÔÐÐÐs6   ÂB% Â%
B2Â1B2Â6C Ã
C#Ã"C#Ã'C< Ã<
D	ÄD	c                 óP   — 	 ddl m}  | S # t          $ r t          d¦  «        d‚w xY w)z5Import websockets sync client or raise a clear error.r   )Úconnectz„TCP tunnel requires the 'websockets' package, which ships with langsmith by default. Reinstall with: pip install --upgrade langsmithN)Úwebsockets.sync.clientrd   ÚImportError)Ú
ws_connects    r   Ú_ensure_websocketsrh   Ÿ   sV   € ð	Ø@Ð@Ð@Ð@Ð@Ð@àÐøÝð ð ð Ýð.ñ
ô 
ð ð		ðøøøs   ‚
 Š%c                  ó¬   — e Zd ZdZdZdZddddœd&d„Zed'd„¦   «         Zed'd„¦   «         Z	d(d„Z
d)d„Zd*d„Zd*d„Zd*d„Zd+d„Zd*d „Zd*d!„Zd,d$„Zd-d%„ZdS ).ÚTunnela  TCP tunnel to a port inside a sandbox.

    Opens a local TCP listener and forwards each accepted connection through
    a yamux-multiplexed WebSocket to the daemon, which dials the target port
    inside the sandbox.

    Typically used as a context manager::

        with sandbox.tunnel(remote_port=5432) as t:
            conn = psycopg2.connect(host="127.0.0.1", port=t.local_port)

    Or with explicit lifecycle::

        t = sandbox.tunnel(remote_port=5432)
        # ... use tunnel ...
        t.close()
    ç      à?g       @r   r   N©Ú
local_portÚmax_reconnectsÚheadersÚdataplane_urlr5   Úapi_keyúOptional[str]Úremote_portr   rm   rn   ro   úOptional[Mapping[str, str]]r   r   c               óú   — || _         || _        || _        || _        |p|| _        | j        | _        || _        d | _        d | _        d | _	        d | _
        t          j        ¦   «         | _        d| _        d| _        d S )NF)Ú_dataplane_urlÚ_api_keyÚ_headersÚ_remote_portÚ_requested_local_portÚ_local_portÚ_max_reconnectsr'   Ú_yamuxÚ_server_socketÚ_accept_threadr*   r+   Ú_reconnect_lockÚ_closedÚ_started©r-   rp   rq   rs   rm   rn   ro   s          r   r.   zTunnel.__init__Ã   s‚   € ð ,ˆÔØˆŒØˆŒØ'ˆÔØ%/Ð%>°;ˆÔ"ØÔ5ˆÔØ-ˆÔàˆŒØ.2ˆŒØ7;ˆÔØ:>ˆÔÝ(œ~Ñ/Ô/ˆÔØˆŒØˆŒˆˆr   c                ó   — | j         S )z&Local port the tunnel is listening on.)r{   r?   s    r   rm   zTunnel.local_portÝ   s   € ð ÔÐr   c                ó   — | j         S )z4Port inside the sandbox that the tunnel connects to.)ry   r?   s    r   rs   zTunnel.remote_portâ   s   € ð Ô Ð r   c                ó   — | S r&   rE   r?   s    r   Ú	__enter__zTunnel.__enter__é   s   € Øˆr   ÚargsÚobjectc                ó.   — |                       ¦   «          d S r&   )r=   )r-   rˆ   s     r   Ú__exit__zTunnel.__exit__ì   s   € Ø�
Š
‰Œˆˆˆr   c                ó–   — | j         rd S d| _         	 |                      ¦   «          d S # t          $ r |                      ¦   «          ‚ w xY w)NT)r‚   Ú	_do_startr>   r=   r?   s    r   Ú_startzTunnel._startñ   s^   € ØŒ=ð 	ØˆFØˆŒð	Ø�NŠNÑÔÐÐÐøÝð 	ð 	ð 	Ø�JŠJ‰LŒLˆLØð	øøøs	   ’( ¨ Ac                ó„  — |                       ¦   «          t          j        t          j        t          j        ¦  «        | _        | j                             t          j        t          j        d¦  «         | j        }|dk    �r&t          j        t          j        t          j        ¦  «        }	 | 	                    d¦  «         | 
                    d|f¦  «         |                     ¦   «          t          d|› d�¦  «        ‚# t          $ r Y nMt          $ rA}dt          |¦  «        v rn%dt          |¦  «                             ¦   «         v r‚ 	 Y d }~nd }~ww xY w	 |                     ¦   «          n:# t          $ r Y n.w xY w# 	 |                     ¦   «          w # t          $ r Y w w xY wxY w| j                             d| j        f¦  «         | j                             d	¦  «         | j                             ¦   «         d         | _        t)          j        | j        d
d¬¦  «        | _        | j                             ¦   «          d S )Nr   r   rk   z	127.0.0.1zPort zE is already in use by another service. Choose a different local_port.zConnection refusedzalready in useé€   Tztunnel-accept)rS   rT   Úname)Ú_connectr\   ÚAF_INETÚSOCK_STREAMr~   Ú
setsockoptÚ
SOL_SOCKETÚSO_REUSEADDRrz   Ú
settimeoutrd   r=   r^   ÚConnectionRefusedErrorr5   ÚlowerÚbindÚlistenÚgetsocknamer{   r*   rX   Ú_accept_loopr   rY   )r-   r   ÚprobeÚes       r   r�   zTunnel._do_startü   sH  € Ø�Š‰Œˆå$œm­F¬N½FÔ<NÑOÔOˆÔØÔ×&Ò&¥vÔ'8½&Ô:MÈqÑQÔQÐQð
 Ô)ˆØ�1Š9‰9Ý”M¥&¤.µ&Ô2DÑEÔEˆEðØ× Ò  Ñ%Ô%Ð%Ø—’˜{¨DÐ1Ñ2Ô2Ð2Ø—’‘”�Ýð6˜Dð 6ð 6ð 6ñô ð øõ *ð ð ð Ø�Ýð ð ð Ø'­3¨q©6¬6Ð1Ð1ØØ%­¨Q©¬¯ª©¬Ð7Ð7ØàøøøøøøøøøðøøøðØ—K’K‘M”M�M�MøÝð ð ð Ø�DðøøøøðØ—K’K‘M”M�M�MøÝð ð ð Ø�Dðøøøøøøð 	Ô× Ò  +¨tÔ/IÐ!JÑKÔKÐKØÔ×"Ò" 3Ñ'Ô'Ð'ØÔ.×:Ò:Ñ<Ô<¸QÔ?ˆÔå'Ô.ØÔ$¨T¸ð
ñ 
ô 
ˆÔð 	Ô×!Ò!Ñ#Ô#Ð#Ð#Ð#sm   Â+AC> Ã>
EÄE= Ä
	EÄ7EÅ
E= ÅEÅE= ÅE- Å-
E:Å9E:Å=F$Å?FÆF$Æ
F!ÆF$Æ F!Æ!F$c                óz  — ddl m} | j        }|r&	 |                     ¦   «          n# t          $ r Y nw xY wt          ¦   «         }|                      ¦   «         }t          | j        r	d| j        ind| j	        ¦  «        } |||t          dd¬¦  «        | _        t          | j        ¦  «        } ||¦  «        | _        dS )z:Establish (or re-establish) the WebSocket + yamux session.r   )r
   z	X-Api-KeyNrU   )Úadditional_headersÚopen_timeoutÚclose_timeoutÚping_interval)Úlangsmith.sandbox._yamuxr
   r}   r=   r>   rh   Ú_build_ws_urlr   rw   rx   r	   r'   r#   )r-   r
   Ú	old_yamuxrg   Úws_urlro   Úadapters          r   r’   zTunnel._connect(  sò   € à9Ð9Ð9Ð9Ð9Ð9à”Kˆ	Øð 	ðØ—’Ñ!Ô!Ð!Ð!øÝð ð ð Ø�ðøøøõ (Ñ)Ô)ˆ
Ø×#Ò#Ñ%Ô%ˆÝØ,0¬MÐCˆ[˜$œ-Ð(Ð(¸tØŒMñ
ô 
ˆð
 �:ØØ&Ý(ØØð
ñ 
ô 
ˆŒõ ˜TœXÑ&Ô&ˆØ"�l 7Ñ+Ô+ˆŒˆˆs   ‘& ¦
3²3r
   c                óX  — ddl m} | j        r| j        j        s| j        S | j        5  | j        r| j        j        s| j        cddd¦  «         S d}t          | j        ¦  «        D ]¤}	 |                      ¦   «          t           	                    d|dz   ¦  «         | j        c cddd¦  «         S # t          $ rN}|}|| j        dz
  k     r4t          | j        d|z  z  | j        ¦  «        }t          j        |¦  «         Y d}~Œ�d}~ww xY w |d| j        › d�¦  «        |‚# 1 swxY w Y   dS )	z4Return a live yamux session, reconnecting if needed.r   )ÚTunnelErrorNz tunnel: reconnected (attempt %d)r   r   ztunnel: reconnect failed after z	 attempts)Úlangsmith.sandbox._exceptionsr¬   r}   Ú	is_closedr€   Úranger|   r’   ÚloggerÚdebugr>   ÚminÚ_BACKOFF_BASEÚ_BACKOFF_MAXÚtimeÚsleep)r-   r¬   Úlast_errÚattemptÚexcÚdelays         r   Ú_ensure_sessionzTunnel._ensure_sessionE  s×  € à=Ð=Ð=Ð=Ð=Ð=àŒ;ð 	˜tœ{Ô4ð 	Ø”;ÐàÔ!ð 	ð 	ØŒ{ð # 4¤;Ô#8ð #Ø”{ð	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð -1ˆHÝ  Ô!5Ñ6Ô6ð *ð *�ð*Ø—M’M‘O”O�OÝ—L’LÐ!CÀWÈqÁ[ÑQÔQÐQØœ;Ð&Ð&ð	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	øõ !ð *ð *ð *Ø"�HØ Ô!5¸Ñ!9Ò9Ð9Ý #Ø Ô.°!°W±*Ñ=Ø Ô-ñ!ô !˜õ œ
 5Ñ)Ô)Ð)øøøøøøøøøð*øøøð �+ØQ°$Ô2FÐQÐQÐQñô àðð'	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	sB   ¨DÁDÁ(8B/Â DÂ/
DÂ9ADÃ=DÄDÄDÄD#Ä&D#c                óÎ   — | j         rdS d| _         | j        r+	 | j                             ¦   «          n# t          $ r Y nw xY w| j        r| j                             ¦   «          dS dS )z.Shut down the tunnel, closing all connections.NT)r�   r~   r=   r^   r}   r?   s    r   r=   zTunnel.closec  s�   € àŒ<ð 	ØˆFØˆŒàÔð 	ðØÔ#×)Ò)Ñ+Ô+Ð+Ð+øÝð ð ð Ø�ðøøøð Œ;ð 	 ØŒK×ÒÑÔÐÐÐð	 ð 	 s   ™3 ³
A ¿A c                óä   — | j         sh	 | j                             ¦   «         \  }}n# t          $ r Y d S w xY wt	          j        | j        |fdd¬¦  «                             ¦   «          | j         ¯fd S d S )NTztunnel-bridge)rS   rˆ   rT   r‘   )r�   r~   Úacceptr^   r*   rX   Ú_handle_connrY   )r-   ÚconnÚ_s      r   rž   zTunnel._accept_loopt  s    € Ø”,ð 
	ðØÔ-×4Ò4Ñ6Ô6‘��a�aøÝð ð ð Ø��ðøøøåÔØÔ(Ø�WØØ$ð	ñ ô ÷
 Še‰gŒgˆgð ”,ð 
	ð 
	ð 
	ð 
	ð 
	s   ‰& ¦
4³4rF   rG   c                ó,  — 	 |                       ¦   «         }|                     ¦   «         }t          || j        ¦  «         t	          |¦  «        }|t
          k    rt          ||¦  «         d S |                     ¦   «          |                     ¦   «          |t          k    r"t           
                    d| j        ¦  «         d S |t          k    r"t           
                    d| j        ¦  «         d S |t          k    r"t           
                    dt          ¦  «         d S t           
                    d|¦  «         d S # t          $ rR}t                               d|¦  «         	 |                     ¦   «          n# t           $ r Y n
w xY wY d }~d S Y d }~d S d }~ww xY w)Nz%tunnel: port %d not allowed by daemonz3tunnel: nothing listening on port %d inside sandboxz.tunnel: protocol version mismatch (client v%d)ztunnel: unknown status %dz$tunnel: connection handler error: %s)r»   Úopen_streamr   ry   r!   Ú	STATUS_OKrb   r=   ÚSTATUS_PORT_NOT_ALLOWEDr°   ÚwarningÚSTATUS_DIAL_FAILEDÚSTATUS_UNSUPPORTED_VERSIONr   r>   r±   r^   )r-   rF   Úsessionr   Ústatusr¹   s         r   r¿   zTunnel._handle_conn�  sÐ  € ð$	Ø×*Ò*Ñ,Ô,ˆGØ×(Ò(Ñ*Ô*ˆFÝ! &¨$Ô*;Ñ<Ô<Ð<Ý! &Ñ)Ô)ˆFà�Ò"Ð"Ý˜ Ñ)Ô)Ð)Ø�à�LŠL‰NŒNˆNØ�NŠNÑÔÐàÕ0Ò0Ð0Ý—’Ø;ØÔ%ñô ð ð ð ð Õ-Ò-Ð-Ý—’ØIØÔ%ñô ð ð ð ð Õ5Ò5Ð5Ý—’ØDÝ$ñô ð ð ð õ
 —’Ð:¸FÑCÔCÐCÐCÐCøåð 	ð 	ð 	Ý�LŠLÐ?ÀÑEÔEÐEðØ—’Ñ Ô Ð Ð øÝð ð ð Ø�ðøøøð !Ð Ð Ð Ð Ð à�����øøøøð	øøøsU   ‚A'D7 Á+AD7 Ã +D7 Ã-+D7 ÄD7 Ä7
FÅFÅE2Å1FÅ2
E?Å<FÅ>E?Å?FÆFc                ó”   — | j                              d¦  «        }|                     dd¦  «                             dd¦  «        }|› d�S )Nú/zhttps://zwss://zhttp://zws://z/tunnel)rv   ÚrstripÚreplace)r-   Úurls     r   r§   zTunnel._build_ws_url¨  sG   € ØÔ!×(Ò(¨Ñ-Ô-ˆØ�kŠk˜* hÑ/Ô/×7Ò7¸	À7ÑKÔKˆØˆˆˆÐr   ©rp   r5   rq   rr   rs   r   rm   r   rn   r   ro   rt   r   r   ©r   r   )r   rj   ©rˆ   r‰   r   r   r@   )r   r
   )rF   rG   r   r   )r   r5   )rA   rB   rC   rD   r³   r´   r.   Úpropertyrm   rs   r‡   r‹   rŽ   r�   r’   r»   r=   rž   r¿   r§   rE   r   r   rj   rj   ­   s]  € € € € € ðð ð$ €MØ€Lð ØØ/3ðð ð ð ð ð ð4 ð ð  ð  ñ „Xð ð ð!ð !ð !ñ „Xð!ðð ð ð ðð ð ð ð
	ð 	ð 	ð 	ð*$ð *$ð *$ð *$ðX,ð ,ð ,ð ,ð:ð ð ð ð< ð  ð  ð  ð"ð ð ð ð%ð %ð %ð %ðNð ð ð ð ð r   rj   c                  ól   — e Zd ZdZddddœdd„Zedd„¦   «         Zedd„¦   «         Zdd„Zdd„Z	dd„Z
dS )ÚAsyncTunnelaw  Async wrapper around :class:`Tunnel`.

    The underlying tunnel runs in background threads (TCP listener + bridges);
    async context-manager methods delegate to the sync tunnel via the event
    loop's executor.

    Usage::

        async with await sandbox.tunnel(remote_port=5432) as t:
            conn = await asyncpg.connect(host="127.0.0.1", port=t.local_port)
    r   r   Nrl   rp   r5   rq   rr   rs   r   rm   rn   ro   rt   r   r   c               ó:   — t          ||||||¬¦  «        | _        d S )Nrl   )rj   Ú_tunnelrƒ   s          r   r.   zAsyncTunnel.__init__À  s0   € õ ØØØØ!Ø)Øð
ñ 
ô 
ˆŒˆˆr   c                ó   — | j         j        S r&   )r×   rm   r?   s    r   rm   zAsyncTunnel.local_portÓ  s   € àŒ|Ô&Ð&r   c                ó   — | j         j        S r&   )r×   rs   r?   s    r   rs   zAsyncTunnel.remote_port×  s   € àŒ|Ô'Ð'r   c              ƒ  ó|   K  — t          j        ¦   «         }|                     d | j        j        ¦  «        ƒ d {V —† | S r&   )ÚasyncioÚget_running_loopÚrun_in_executorr×   rŽ   )r-   Úloops     r   Ú
__aenter__zAsyncTunnel.__aenter__Û  sF   è è € ÝÔ'Ñ)Ô)ˆØ×"Ò" 4¨¬Ô)<Ñ=Ô=Ð=Ð=Ð=Ð=Ð=Ð=Ð=Øˆr   rˆ   r‰   c              ‡  ó|   K  — t          j        ¦   «         }|                     d | j        j        ¦  «        ƒ d {V —† d S r&   )rÛ   rÜ   rÝ   r×   r=   )r-   rˆ   rÞ   s      r   Ú	__aexit__zAsyncTunnel.__aexit__à  sG   è è € ÝÔ'Ñ)Ô)ˆØ×"Ò" 4¨¬Ô);Ñ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ð<r   c                ó8   — | j                              ¦   «          dS )z;Shut down the tunnel (sync, safe to call from any context).N)r×   r=   r?   s    r   r=   zAsyncTunnel.closeä  s   € àŒ×ÒÑÔÐÐÐr   rÐ   rÑ   )r   rÕ   rÒ   r@   )rA   rB   rC   rD   r.   rÓ   rm   rs   rß   rá   r=   rE   r   r   rÕ   rÕ   ³  sÃ   € € € € € ð
ð 
ð$ ØØ/3ð
ð 
ð 
ð 
ð 
ð 
ð& ð'ð 'ð 'ñ „Xð'ð ð(ð (ð (ñ „Xð(ðð ð ð ð
=ð =ð =ð =ðð ð ð ð ð r   rÕ   )r   r   r   r   r   r   )r   r   r   r   )r   r   rF   rG   r   r   )'rD   Ú
__future__r   rÛ   Úloggingr\   r   r*   rµ   Úcollections.abcr   Útypingr   r   r   Úlangsmith.sandbox._helpersr   Úlangsmith.sandbox._ws_executer	   r¦   r
   r   Ú	getLoggerrA   r°   r   rÄ   rÅ   rÇ   rÈ   r   r   r!   r#   rJ   rb   rh   rj   rÕ   rE   r   r   ú<module>rê      sì  ððð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ø €€€Ø #Ð #Ð #Ð #Ð #Ð #Ø /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /Ð /à 4Ð 4Ð 4Ð 4Ð 4Ð 4Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9àð CØBÐBÐBÐBÐBÐBÐBÐBà	ˆÔ	˜8Ñ	$Ô	$€ð Ð à€	ØÐ ØÐ Ø!Ð àÐ ðKð Kð Kð Kð
ð ð ð ð!ð !ð !ð !ð !ñ !ô !ð !ðP Ð ð1ð 1ð 1ð 1ðrð ð ð~ð ~ð ~ð ~ð ~ñ ~ô ~ð ~ðL3ð 3ð 3ð 3ð 3ñ 3ô 3ð 3ð 3ð 3r   