Ë
    ãß²j"  ã                   ó^  — d 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ZddlZddl	m
Z
 ddlmZ  ej                  d«      Zh d£Zd„ Zded	ed
efd„Zdededededededed
efd„Z	 ddej                  dedededededej4                  d	efd„Zdededededededej4                  d	efd„Zy)uA  Host-side RPC servers for execute_code sandboxes.

Two transports share one request pipeline (token check â†’ allow-list â†’ call
budget â†’ dispatch under output silence â†’ log): ``_rpc_server_loop`` serves the
local UDS/TCP socket, ``_rpc_poll_loop`` polls a remote filesystem for request
files via ``env.execute()``.
é    N)Úthread_scoped_silence)Ú
tool_errorztools.code_execution_tool>   ÚptyÚnotifyÚ	heartbeatÚ
backgroundÚwatch_patternsÚnotify_on_completec                 ó   ‡ ‡— ddl mŠ ˆˆ fd„S )Nr   )Úhandle_function_callc                 ó   •—  ‰| |‰¬«      S )N)Útask_id© )Ú	tool_nameÚ	tool_argsr   r   s     €€ú=/home/ubuntu/.hermes/hermes-agent/tools/code_execution_rpc.pyú<lambda>z#_default_dispatch.<locals>.<lambda>   s   ø€ Ñ(<¸YÈ	Ð[bÔ(c€ ó    )Úmodel_toolsr   )r   r   s   `@r   Ú_default_dispatchr      s   ù€ Ý0ÜcÐcr   ÚrequestÚ	rpc_tokenÚreturnc                 ó¸   — t        |«      xrN t        j                  t        | j	                  d«      xs d«      j                  «       |j                  «       «      S )z°Constant-time token check; an empty server token fails closed. Compared as bytes:
    compare_digest raises TypeError on a non-ASCII str, and the token is script-supplied JSON.ÚtokenÚ )ÚboolÚsecretsÚcompare_digestÚstrÚgetÚencode)r   r   s     r   Ú_rpc_token_okr#   !   sL   € ô �	‹?ò œw×5Ñ5ÜˆG�K‰K˜Ó Ò& BÓ'×.Ñ.Ó0°)×2BÑ2BÓ2Dó ð r   Úallowed_toolsÚtool_call_counterÚmax_tool_callsÚtool_call_logÚ
call_startÚwherec          
      ó¬  — | j                  dd«      }| j                  di «      }	||vr)t        d|› ddj                  t        |«      «      › �«      S |d   |k\  rt        d|› d	�«      S |d
k(  r-t	        |	t
        «      rt        D ]  }
|	j                  |
d«       Œ 	 t        «       5   |||	«      }ddd«       |dxx   dz  cc<   |j                  |t        |	«      dd t        t        j                   «       |z
  d«      dœ«       S # 1 sw Y   ŒXxY w# t        $ r7}t        j                  d||d¬«       t        t        |«      «      }Y d}~Œ–d}~ww xY w)z’Enforce allow-list + budget, then dispatch one authenticated request. Only a dispatched
    call consumes budget and is logged; refusals are free.Útoolr   ÚargszTool 'z/' is not available in execute_code. Available: z, r   zTool call limit reached (z0). No more tool calls allowed in this execution.ÚterminalNzTool call failed in %s: %sT©Úexc_infoé   éP   é   )r+   Úargs_previewÚduration)r!   r   ÚjoinÚsortedÚ
isinstanceÚdictÚ_TERMINAL_BLOCKED_PARAMSÚpopr   Ú	ExceptionÚloggerÚerrorr    ÚappendÚroundÚtimeÚ	monotonic)r   r$   r%   r&   Údispatchr'   r(   r)   r   r   ÚparamÚresultÚexcs                r   Ú_handle_rpc_requestrF   )   sn  € ð
 —‘˜F BÓ'€IØ—‘˜F BÓ'€IØ˜Ñ%Ü˜F 9 +ð .(Ø(,¯	©	´&¸Ó2GÓ(HÐ'IðKó Lð 	Là˜Ñ˜~Ò-ÜÐ5°nÐ5Eð FJð Jó Kð 	Kà�JÒ¤:¨i¼Ô#>Ü-ò 	'ˆEØ�M‰M˜% Õ&ð	'ð&Ü"Ó$ñ 	4Ù˜i¨Ó3ˆF÷	4ð
 �aÓ˜AÑÓØ×Ñ )¼SÀ»^ÈCÈRÐ=PÜ&+¬D¯N©NÓ,<¸zÑ,IÈ1Ó&MñOô Pà€M÷	4ð 	4ûäò &Ü�‰Ð1°5¸#ÈˆÔMÜœC ›HÓ%�ûð&ús0   Â
D Â&
DÂ0D ÄDÄD Ä	EÄ-EÅEÚserver_sockr   Ú
stop_eventc	           
      óf  — |€t        |«      }d}		 | j                  d«       |j                  «       s	 | j                  «       \  }	}
	 |	€	 |	r	 |	j                  «        yy|	j                  d«       d}	 	 |	j                  d«      }|sn»||z  }d|v r±|j                  dd	«      \  }}|j                  «       }|sŒ,t        j                  «       }	 t        j                   |j#                  «       «      }t%        ||«      rt'        |||||||d
¬«      n
t)        d«      }|	j/                  |dz   j1                  «       «       d|v rŒ±ŒÐ|	r	 |	j                  «        yy# t        j
                  $ r Y �ŒLw xY w# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w# t        j
                  $ r Y Œpw xY w# t        j*                  t,        f$ r}t)        d|› �«      }Y d}~ŒÈd}~ww xY w# t        j
                  $ r t        j                  d«       Y ŒÒt        $ r"}t        j                  d|d¬«       Y d}~Œ÷d}~ww xY w# t        $ r }t        j                  d|«       Y d}~yd}~ww xY w# |	r>	 |	j                  «        w # t        $ r }t        j                  d|«       Y d}~w d}~ww xY ww xY w)aƒ  Accept one client and serve newline-delimited JSON requests until it disconnects, idles
    300s, or the call limit is reached. ``tool_call_counter`` is a mutable ``[int]``. ``dispatch``
    overrides how an allowed, budgeted call runs: per-call sandboxes use the default (the thread
    carries the cell's context); session kernels rebind each call to the CURRENT cell's authority.
    Ngš™™™™™©?zRPC conn close error: %si,  r   Ti   ó   
r0   Úsandbox©r$   r%   r&   rB   r'   r(   r)   zUnauthorized RPC requestzInvalid RPC request: Ú
zRPC listener socket timeoutzRPC listener socket error: %sr.   )r   Ú
settimeoutÚis_setÚacceptÚsocketÚtimeoutÚcloseÚOSErrorr<   ÚdebugÚrecvÚsplitÚstripr@   rA   ÚjsonÚloadsÚdecoder#   rF   r   ÚJSONDecodeErrorÚUnicodeDecodeErrorÚsendallr"   )rG   r   r'   r%   r&   r$   rH   r   rB   ÚconnÚ_ÚeÚbufÚchunkÚliner(   r   ÚresprE   s                      r   Ú_rpc_server_looprf   F   s¥  € ð ÐÜ$ WÓ-ˆØ€Dð.<Ø×Ñ˜tÔ$Ø×#Ñ#Ô%ðØ%×,Ñ,Ó.‘��aØð ˆ<ØñB ð<Ø—
‘
•ð ðA 	�‰˜ÔØˆØðØŸ	™	 %Ó(�ñ ØØ�5‰LˆCØ˜3‘,ØŸI™I e¨QÓ/‘	��cØ—z‘z“|�ÙØÜ!Ÿ^™^Ó-�
ð	gÜ"Ÿj™j¨¯©«Ó7�Gô ' w°	Ô:ô	 /Ø¨}ÐPaØ'5ÀÐXeØ#-°Yõô AKÐKeÓ@fð	 ð
 —‘˜d T™k×1Ñ1Ó3Ô4ð! ˜3’,ð ñ< ð<Ø—
‘
•ð øôI —>‘>ò ÚðûôN ò <Ü—‘Ð7¸×;Ñ;ûð<ûô= —>‘>ò Ùðûô ×,Ñ,Ô.@ÐAò EÜ%Ð(=¸c¸UÐ&CÓD•DûðEûô �>‰>ò 4Ü�‰Ð2Ö3Üò HÜ�‰Ð4°aÀ$ˆ×GÑGûðHûô ò <Ü—‘Ð7¸×;Ñ;ûð<ûñ ð<Ø—
‘
•øÜò <Ü—‘Ð7¸×;Ñ;ûð<úð ús  ‘!G+ ³E ÁG+ ÁE2 ÁG+ Á4F ÂAG+ Ã#F7 Ã1AG+ ÅG+ ÅI ÅE/Å+G+ Å.E/Å/G+ Å2	FÅ;FÆFÆF4Æ1G+ Æ3F4Æ4G+ Æ7G(ÇG#ÇG+ Ç#G(Ç(G+ Ç+(H?ÈI. ÈH?ÈH:È5I. È:H?È?I. É	I+ÉI&É&I+É.J0É2JÊJ0Ê	J,ÊJ'Ê"J0Ê'J,Ê,J0Úrpc_dirc	                 óš  — t        |«      }	d}
t        j                  |«      }|j                  «       �s	 | j	                  d|› d�dd¬«      }|j                  dd«      j                  «       }|s|j                  |
«       Œ^t        d	„ d
„ |j                  d«      D «       D «       «      }|D �]^  }|j                  «       r �nKt        j                  «       }t        j                  |«      }| j	                  d|› �dd¬«      }	 t        j                  |j                  dd«      «      }t%        ||«      s.t         j#                  d|«       | j	                  d|› �dd¬«       Œ·t'        |||||	||d¬«      }t        j                  |› d|j                  dd«      d›�«      }t)        j*                  |j-                  d«      «      j/                  d«      }| j	                  d|› d|› d|› d|› �dd¬«       | j	                  d|› �dd¬«       �Œa |j                  «       s|j                  |
«       |j                  «       s�Œy!y!# t        j                  t        f$ r1 t         j#                  d|«       | j	                  d|› �dd¬«       Y �Œàw xY w# t0        $ r2}|j                  «       st         j#                  d|d¬ «       Y d!}~Œ¸d!}~ww xY w)"a  Poll the remote filesystem for request files and answer them. Background thread; each
    ``env.execute()`` is an independent process, so this is safe alongside the script-execution
    thread. Malformed or unauthorized requests are removed without a response.gš™™™™™¹?zls -1 z/req_* 2>/dev/null || trueú/é
   )ÚcwdrR   Úoutputr   c              3   óN   K  — | ]  }|r|j                  d «      sd|v r|–— Œ y­w)z.tmpz/req_N)Úendswith)Ú.0Úfs     r   ú	<genexpr>z!_rpc_poll_loop.<locals>.<genexpr>’   s-   è ø€ ò Q QÙ"#¨A¯J©J°vÔ,>À7ÈaÁ<ô  !ñ Qùs   ‚#%c              3   ó<   K  — | ]  }|j                  «       –— Œ y ­w©N)rX   )ro   rd   s     r   rq   z!_rpc_poll_loop.<locals>.<genexpr>’   s   è ø€ Ò*W¸D¨4¯:©:¯<Ñ*Wùs   ‚rM   zcat zMalformed RPC request in %szrm -f é   zUnauthorized RPC request in %szremote sandboxrL   z/res_Úseqr   Ú06dzutf-8Úasciizecho 'z' | base64 -d > z.tmp && mv z.tmp é<   zRPC poll error: %sTr.   N)r   ÚshlexÚquoterO   Úexecuter!   rX   Úwaitr6   rW   r@   rA   rY   rZ   r\   Ú
ValueErrorr<   rU   r#   rF   Úbase64Ú	b64encoder"   r[   r;   )Úenvrg   r   r'   r%   r&   r$   rH   r   rB   Úpoll_intervalÚquoted_rpc_dirÚ	ls_resultrl   Ú	req_filesÚreq_filer(   Úquoted_req_fileÚread_resultr   Útool_resultÚquoted_res_fileÚencoded_resultra   s                           r   Ú_rpc_poll_loopr‹   ‚   sÊ  € ô ! Ó)€HØ€MÜ—[‘[ Ó)€NØ×ÑÕ!ð)	EØŸ™ f¨^Ð,<Ð<VÐ$WÐ]`Ðjl˜ÓmˆIØ—]‘] 8¨RÓ0×6Ñ6Ó8ˆFÙØ—‘ Ô.ØÜñ QÑ*WÀFÇLÁLÐQUÓDVÔ*Wô Qó QˆIà%ó L�Ø×$Ñ$Ô&ÚÜ!Ÿ^™^Ó-�
Ü"'§+¡+¨hÓ"7�Ø!Ÿk™k¨D°Ð0AÐ*BÈÐUW˜kÓX�ðÜ"Ÿj™j¨¯©¸À2Ó)FÓG�Gô
 % W¨iÔ8Ü—L‘LÐ!AÀ8ÔLØ—K‘K &¨Ð(9Ð :ÀÈQ�KÔOØÜ1Ø¨=ÐL]Ø#1¸HÐTaØ)Ð1Aô�ô #(§+¡+°°	¸¸w¿{¹{È5ÐRSÓ?TÐUXÐ>YÐ.ZÓ"[�Ü!'×!1Ñ!1°+×2DÑ2DÀWÓ2MÓ!N×!UÑ!UÐV]Ó!^�Ø—‘Ø˜^Ð,Ð,<¸_Ð<Mð NØ-Ð.¨e°OÐ3DðFà Rð ô ð
 —‘˜f _Ð$5Ð6¸CÈ�ÖKð=LðD × Ñ Ô"Ø�O‰O˜MÔ*ðY ×Ñ×!Ð!øô" ×,Ñ,¬jÐ9ò Ü—L‘LÐ!>ÀÔIØ—K‘K &¨Ð(9Ð :ÀÈQ�KÔOÚðûô. ò 	EØ×$Ñ$Ô&Ü—‘Ð1°1¸t�ÔDÿøð	EúsE   µAJ ÂBJ Ä%IÄ(C%J ÉAJÊJ ÊJÊJ Ê	K
Ê(KËK
rs   )Ú__doc__r~   rY   Úloggingr   ry   rQ   Ú	threadingr@   Úagent.thread_scoped_outputr   Útools.registryr   Ú	getLoggerr<   r9   r   r8   r    r   r#   Ú	frozensetÚlistÚintÚfloatrF   ÚEventrf   r‹   r   r   r   ú<module>r—      sC  ðñó Û Û Û Û Û Û Û å <Ý %ð 
ˆ×	Ñ	Ð6Ó	7€ò pÐ òdð
˜4ð ¨Cð °Dó ð ð ¸ð ÐW[ð Ø(+ðØFJðØX]ðà"ðà'*óð> LPñ9< &§-¡-ð 9<¸#ð 9<Èdð 9<Ø(,ð9<Ø>Að9<ØR[ð9<à!*§¡ð9<à=@ó9<ðx5+ ð 5+¨sð 5+À4ð 5+Ð\`ð 5+Ø#&ð5+Ø7@ð5+ØNWÏoÉoð5+à!ô5+r   