
    Pmj                       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ZddlZddl	Z	ddl
Z
ddlmZmZ ddlmZmZ ddlmZ  ej        e          ZdZdZd	Zd
ZdZdZi Zded<   e G d d                      Z G d d          Z ed           G d d                      Z ee z  Z! G d d          Z" e"            Z#e G d d                      Z$e G d d                      Z% ej&        dd          Z'ded <    G d! d"          Z( e(            Z)dQd%Z*dRdSd(Z+dTd+Z,ddd,dUd2Z-dVd6Z.dWd9Z/dXd=Z0dXd>Z1dYd?Z2dZdCZ3dddDd[dHZ4dddDd\dJZ5d]dKZ6d^dLZ7d_dNZ8d`dPZ9dS )azBProfile-scoped NeMo Relay runtimes owned by the Hermes agent core.    )annotationsN)	dataclassfield)AnyCallable)get_hermes_homezhermes.sessionzhermes.turnzhermes.logical_llm_callzhermes.relay.schema_versionzhermes.relay.runtime.v1zhermes.relay.runtime_instancezdict[str, str]_PROFILE_KEY_CACHEc                      e Zd ZU dZded<   dZded<    eej        d          Z	ded	<   dZ
d
ed<   dZded<   dZded<   dS )RelaySessionz9One isolated Relay scope stack owned by a Hermes session.str
session_id parent_session_idFdefault_factoryreprthreading.RLocklockboolclosingNr   handlezcontextvars.Context | Nonecontext)__name__
__module____qualname____doc____annotations__r   r   	threadingRLockr   r   r   r        9/home/thesage/.hermes/hermes-agent/agent/relay_runtime.pyr   r      s         CCOOO!E)/NNNDNNNNGF*.G......r!   r   c                      e Zd ZdZd1ddd2d
Zd3dZd3dZd4dZdddd5dZddd6dZ	d7dZ
d8dZd9dZdd d:d(Zdd d:d)Zdddd;d+Zd<d-Zd7d.Zd=d/Zed>d0            ZdS )?RelayRuntimezAOwn Relay session scopes independently of any exporter or plugin.Nprofile_keyrelayr   r&   
str | NonereturnNonec                  |pt                      | _        |pt                      | _        t	          j                    j        | _        t          j	                    | _
        i | _        i | _        i | _        t          j	                    | _        t                      | _        d| _        t%          j        | j                   d S )NT)_load_nemo_relayr'   current_profile_keyr&   uuiduuid4hex
runtime_idr   r   _sessions_lock	_sessions_subagent_parents_subagent_parent_handles_execution_consumers_lockset_execution_consumers_shutdown_registeredatexitregistershutdown)selfr'   r&   s      r"   __init__zRelayRuntime.__init__,   s    0.00
&?*=*?*?*,,*'o//24138:%)2):):&.1ee!$(!&&&&&r!   consumerr   c                    |st          d          | j        5  | j                            |           ddd           dS # 1 swxY w Y   dS )z<Keep managed LLM and tool execution active for one consumer.z2Relay managed-execution consumer must not be emptyN)
ValueErrorr6   r8   addr=   r?   s     r"   retain_managed_executionz%RelayRuntime.retain_managed_execution9   s     	SQRRR+ 	4 	4%))(333	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4s   AAAc                z    | j         5  | j                            |           ddd           dS # 1 swxY w Y   dS )z3Release a consumer's managed-execution requirement.N)r6   r8   discardrC   s     r"   release_managed_executionz&RelayRuntime.release_managed_execution@   s    + 	8 	8%--h777	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8s   044r   c                l    | j         5  t          | j                  cddd           S # 1 swxY w Y   dS )zBReturn whether a Hermes-managed consumer needs the Relay pipeline.N)r6   r   r8   r=   s    r"   managed_execution_enabledz&RelayRuntime.managed_execution_enabledE   s}    + 	3 	3122	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3s   )--datametadataeventdict[str, Any]rL   rM   dict[str, Any] | NoneRelaySession | Nonec          
        t          |          }|sdS | j        5  | j                            |          }|6| j                            |d          }t          ||          }|| j        |<   ddd           n# 1 swxY w Y   |j        5  |j        r	 ddd           dS |j        d}i |pi t          t          t          | j        i}|j        re| j        5  | j                            |          }ddd           n# 1 swxY w Y   |%|                     d|j        i          }	|	|	j        }d|d<   t!          j                    }
	 |
                    | j        j        j        t,          | j        j        j        ||i |          |_        n# t2          $ r	 d|_         w xY w|
|_        ddd           n# 1 swxY w Y   |S )z4Return the existing session scope or create it once.Nr   )r   r   r   subagentnemo_relay_scope_role)r   rL   inputrM   )_session_idr2   r3   getr4   r   r   r   r   RUNTIME_SCHEMA_KEYRUNTIME_SCHEMA_VERSIONRUNTIME_INSTANCE_KEYr1   r   r5   ensure_sessioncontextvarsContextrunr'   scopepushSESSION_SCOPE	ScopeTypeAgent	Exceptionr   )r=   rN   rL   rM   r   sessionr   parent_handlescope_metadataparentr   s              r"   r[   zRelayRuntime.ensure_sessionJ   s    !''
 	4  	5 	5n((44G$($:$>$>z2$N$N!&)&7   .5z*	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 \ "	* "	* "	* "	* "	* "	* "	* "	* "	* "	* ~% $"~2"&(>($/" "
 , 	I, V V(,(E(I(I*(U(UV V V V V V V V V V V V V V V$,!%!4!4('*C6 " " "-,2MM>HN#:;%-//%,[[
(-%
,2,! !/ &1 & &GNN !   &*GO #*E"	* "	* "	* "	* "	* "	* "	* "	* "	* "	* "	* "	* "	* "	* "	*F sh   AA::A>A>	F:"8F:D5F:D	F:D		AF:AFF:F$$
F::F>F>rM   c               4   t          |                    d          pd          }t          |                    d          pd          }|r|r||k    rdS |                     d|i          }|dn|j        }t	          |          }|D|j        s=|j        6|j        j        | u r(|j        j        |j        j        j	        |k    r|j        }| j
        5  || j        |<   |
|| j        |<   ddd           n# 1 swxY w Y   |                     d|i|          S )z@Open a child Agent scope under its spawning turn when available.r   r   child_session_idNr   ri   )r   rW   r[   r   active_turnclosedleasehostre   r   r2   r4   r5   )r=   rN   rM   r   rk   rh   rf   turns           r"   register_subagentzRelayRuntime.register_subagent   s     		*= > > D"EEuyy);<<BCC!	#	 !$4444$$l4E%FGG &FM,--K '
4''
".
"-1BBB KM  	P 	P7HD"#34(BO-.>?	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P ""+, # 
 
 	
s   C66C:=C:c                0   t          |                    d          pd          }|sdS |                     d|i           | j        5  | j                            |d           | j                            |d           ddd           dS # 1 swxY w Y   dS )z=Close a delegated session and forget its parent relationship.rk   r   Nr   )r   rW   close_sessionr2   r4   popr5   )r=   rN   rk   s      r"   unregister_subagentz RelayRuntime.unregister_subagent   s    uyy);<<BCC 	FL*:;<<<  	F 	F"&&'7>>>)--.>EEE	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	Fs   7BBBr   c                    | j         5  | j                            t          |pd                    }ddd           n# 1 swxY w Y   |dS |j        5  |j        rdn|cddd           S # 1 swxY w Y   dS )z;Return an active Hermes Relay session without creating one.r   N)r2   r3   rW   r   r   r   r=   r   re   s      r"   get_sessionzRelayRuntime.get_session   s     	@ 	@n((Z-=2)>)>??G	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@?4\ 	8 	8"?744	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8s!   *>AAA,,A03A0c                B    |                      |          }|dn|j        S )z?Return the Relay parent handle for a Hermes session, if active.N)rx   r   rw   s      r"   get_session_handlezRelayRuntime.get_session_handle   s%    "":..ttGN:r!   F)allow_closingre   r   callbackCallable[..., Any]argsr{   kwargsc                   |j         5  |j        r|st          d          |j        |j        t          d          |j                                        }ddd           n# 1 swxY w Y   t          j                    }|                                D ] \  }}	|	                    |j
        |	           !d fd}
|	                    |
          S )z?Run a Relay operation against a session's isolated scope stack.Hermes Relay session is closingN+Hermes Relay session context is unavailabler)   r   c                 F    j                                            i S N)r'   get_scope_stack)r~   r|   r   r=   s   r"   invokez+RelayRuntime.run_in_session.<locals>.invoke   s,    J&&(((8T,V,,,r!   r)   r   )r   r   RuntimeErrorr   r   copyr\   copy_contextitemsr^   r7   )r=   re   r|   r{   r~   r   relay_contextr   variablevaluer   s   ` ` ``     r"   run_in_sessionzRelayRuntime.run_in_session   sA    \ 	3 	3 F} F"#DEEE&'.*@"#PQQQ#O0022M	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 *,,,2244 	- 	-OHeKKe,,,,	- 	- 	- 	- 	- 	- 	- 	- 	- {{6"""s   AA''A+.A+c                  K   |j         5  |j        r|st          d          |j        |j        t          d          |j                                        }ddd           n# 1 swxY w Y   t          j                    }|                                D ] \  }}	|	                    |j
        |	           !d fd}
|	                    t          j         |
                      }| d{V S )zACreate and await an operation inside the session's saved context.r   Nr   r)   r   c                    K   j                                           i } t          j        |           r|  d {V S | S r   )r'   r   inspectisawaitable)resultr~   r|   r   r=   s    r"   r   z1RelayRuntime.run_in_session_async.<locals>.invoke   sY      J&&(((Xt.v..F"6** $#||||||#Mr!   r   )r   r   r   r   r   r   r\   r   r   r^   r7   asynciocreate_task)r=   re   r|   r{   r~   r   r   r   r   r   r   tasks   ` ` ``      r"   run_in_session_asyncz!RelayRuntime.run_in_session_async   sa      \ 	3 	3 F} F"#DEEE&'.*@"#PQQQ#O0022M	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 *,,,2244 	- 	-OHeKKe,,,,	 	 	 	 	 	 	 	 	 {{7.99zzzzzzs   AA))A-0A-namec                   |                      |          }|dS |                     || j        j        j        ||j        ||           dS )zCEmit a mark parented to the Hermes session identified by ``event``.NF)r   rL   rM   T)r[   r   r'   r_   rN   r   )r=   r   rN   rL   rM   re   s         r"   	emit_markzRelayRuntime.emit_mark   sa     %%e,,?5J"> 	 	
 	
 	
 tr!   	tool_namec               2   |                                  s|S t          t          | j        dd          dd          }t          |          s|S |                     d|i          }||S |                     ||||          }t          |t                    r|n|S )zCApply Relay request rewriting before Hermes authorizes a tool call.toolsNrequest_interceptsr   )rJ   getattrr'   callabler[   r   
isinstancedict)r=   r   r   r~   r   re   r   s          r"   apply_tool_request_interceptsz*RelayRuntime.apply_tool_request_intercepts  s     --// 	K$DJ.. 
 

 *++ 	K%%|Z&@AA?K$$	
 
 $FD11;vvt;r!   c                   t          |          }| j        5  | j                            |          }ddd           n# 1 swxY w Y   |W| j        5  | j                            |d           | j                            |d           ddd           n# 1 swxY w Y   dS g }|j        5  |j        r	 ddd           dS d|_        |j	        x	 | 
                    || j        j        j        |j	        i t          t          t          | j        id           n/# t"          $ r"}|                    d|            Y d}~nd}~ww xY wddd           n# 1 swxY w Y   	 | j        j                                         n/# t"          $ r"}|                    d|            Y d}~nd}~ww xY w| j        5  | j                            |          |u r| j                            |d           | j                            |d           | j                            |d           ddd           n# 1 swxY w Y   |r1t*                              d|d                    |                     dS dS )z=Close one session scope and remove it from the core registry.NT)outputrM   r{   zsession scope close failed: zsubscriber flush failed: z.Hermes Relay session %s closed with errors: %sz; )rV   r2   r3   rW   r4   rt   r5   r   r   r   r   r'   r_   rX   rY   rZ   r1   rd   appendsubscribersflushloggerwarningjoin)r=   rN   r   re   failuresexcs         r"   rs   zRelayRuntime.close_session+  s    ''
  	5 	5n((44G	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5?$ D D&**:t<<<-11*dCCCD D D D D D D D D D D D D D D F \ 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J #GO~)J''
(,!.0F0$/" '+ ( 
 
 
 
 ! J J JOO$H3$H$HIIIIIIIIJ#	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J 	J&	?J"((**** 	? 	? 	?OO===>>>>>>>>	?  	@ 	@~!!*--88"":t444"&&z4888)--j$???		@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@
  	NN@		(##    	 	s   >AA7BBB+	EEADE
E"D?:E?EEEEE> >
F*F%%F*4A.H..H25H2c                &   | j         5  t          | j                  }ddd           n# 1 swxY w Y   |D ]}|                     | j        d|i            | j        r4	 t          j        | j                   n# t          $ r Y nw xY wd| _        dS dS )z*Close all core-owned Relay session scopes.Nr   F)
r2   listr3   _safers   r9   r:   
unregisterr<   rd   )r=   session_idsr   s      r"   r<   zRelayRuntime.shutdownY  s      	/ 	/t~..K	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/% 	G 	GJJJt)L*+EFFFF$ 	.!$-0000   (-D%%%	. 	.s   )--A8 8
BBc                n    	  | |i |S # t           $ r  t                              dd           Y d S w xY w)Nz%Hermes Relay runtime operation failedTexc_info)rd   r   r   )r|   r~   r   s      r"   r   zRelayRuntime._safef  sU    	8T,V,,, 	 	 	NNBTNRRR44	s   
 &44r   )r'   r   r&   r(   r)   r*   r?   r   r)   r*   r)   r   )rN   rO   rL   r   rM   rP   r)   rQ   )rN   rO   rM   rP   r)   rQ   )rN   rO   r)   r*   )r   r   r)   rQ   r   r   r)   r   )re   r   r|   r}   r~   r   r{   r   r   r   r)   r   )
r   r   rN   rO   rL   r   rM   r   r)   r   r   r   r   r   r~   rO   r)   rO   r)   r*   )r|   r}   r~   r   r   r   r)   r   )r   r   r   r   r>   rD   rG   rJ   r[   rq   ru   rx   rz   r   r   r   r   rs   r<   staticmethodr   r    r!   r"   r$   r$   )   s       KK't ' ' ' ' ' '4 4 4 48 8 8 8
3 3 3 3 *.7 7 7 7 7 7z +/	"
 "
 "
 "
 "
 "
HF F F F8 8 8 8; ; ; ; $# # # # # #B $     F      ,< < < <8, , , ,\. . . .    \  r!   r$   T)frozenc                      e Zd ZU dZded<   ded<   edd            ZddZedd            Z	edd            Z
edd            ZddZdS )NoopRelayRuntimezDExplicit reduced-capability host for platforms without Relay wheels.r   r&   reasonr)   r   c                    dS NFr    rI   s    r"   	availablezNoopRelayRuntime.availablev      ur!   r   r   r~   rO   c               
    ~~|S r   r    )r=   r   r   r~   s       r"   r   z.NoopRelayRuntime.apply_tool_request_interceptsz  s     	r!   r?   r*   c                    ~ d S r   r    r?   s    r"   rD   z)NoopRelayRuntime.retain_managed_execution  	    HHr!   c                    ~ d S r   r    r   s    r"   rG   z*NoopRelayRuntime.release_managed_execution  r   r!   c                     dS r   r    r    r!   r"   rJ   z*NoopRelayRuntime.managed_execution_enabled  r   r!   c                    dS )z4No resources are allocated on unsupported platforms.Nr    rI   s    r"   r<   zNoopRelayRuntime.shutdown  s      r!   Nr   r   r   r   )r   r   r   r   r   propertyr   r   r   rD   rG   rJ   r<   r    r!   r"   r   r   o  s         NNKKK   X       \    \    \C C C C C Cr!   r   c                  <    e Zd ZdZddZ	 dddddZddZddZdS )RelayHostRegistryz=Own exactly one Relay host for each canonical Hermes profile.r)   r*   c                D    t          j                    | _        i | _        d S r   )r   r   _lock_hostsrI   s    r"   r>   zRelayHostRegistry.__init__  s    _&&
,.r!   NTcreater&   r(   r   r   RelayHost | Nonec                  |pt                      }| j                            |          }||s|S | j        5  | j                            |          }||s|cd d d            S 	 t	          |          }nQ# t
          $ rD}t                              dd           t          |t          |                    }Y d }~nd }~ww xY w|| j        |<   |cd d d            S # 1 swxY w Y   d S )Nr%   z*Hermes Relay runtime initialization failedTr   )r&   r   )
r-   r   rW   r   r$   rd   r   r   r   r   )r=   r&   r   keyro   r   s         r"   for_profilezRelayHostRegistry.for_profile  s}    2022{s##6KZ 	 	;??3''Dv	 	 	 	 	 	 	 	J#444 J J J@4     (CCIII	J
  $DK	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s;    C &A76C 7
C:C ;C  CC  C$'C$r   c                    | j         5  | j                            |d           }d d d            n# 1 swxY w Y   ||                                 d S d S r   )r   r   rt   r<   )r=   r&   ro   s      r"   shutdown_profilez"RelayHostRegistry.shutdown_profile  s    Z 	6 	6;??;55D	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6 	6MMOOOOO s   044c                    | j         5  t          | j                                                  }| j                                         d d d            n# 1 swxY w Y   |D ]}|                                 d S r   )r   r   r   valuesclearr<   )r=   hostsro   s      r"   shutdown_allzRelayHostRegistry.shutdown_all  s    Z 	  	 ++--..EK	  	  	  	  	  	  	  	  	  	  	  	  	  	  	   	 	DMMOOOO	 	s   A AAAr   r   )r&   r(   r   r   r)   r   r&   r   r)   r*   )r   r   r   r   r>   r   r   r   r    r!   r"   r   r     s        GG/ / / / #' 	     0        r!   r   c                  b    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S )ConversationLeasez?A resumable reference to one profile-scoped conversation scope.r   r&   r   platform	RelayHostro   rQ   re   r   r   Fr   releasedN)r   r   r   r   r   r   r   r    r!   r"   r   r     sn         IIOOOMMMOOO    Hr!   r   c                     e Zd ZU dZded<   ded<   ded<   dZded	<    eed
          Zded<    ee	j
        d
          Zded<    ee	j
        d
          Zded<    edd
          Zded<    ed
d
          Zded<   d
Zded<   dS )RelayTurnContextz;Runtime-only context for one Hermes turn or top-level task.r   rn   r   turn_idtask_idNr   r   Fr   rO   logical_llm_callsr   logical_llm_lockfinalize_lock)defaultr   z1contextvars.Token[RelayTurnContext | None] | None_tokenr   _active_registeredrm   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rm   r    r!   r"   r   r     s:        EELLLLLLF(-d(O(O(OOOOO(-!) ) )     &+U!& & &M     AFA A AF      %uU???????Fr!   r   hermes_relay_turn)r   z/contextvars.ContextVar[RelayTurnContext | None]_CURRENT_TURNc                      e Zd ZdZefd.dZd/dZd0dZd1dZdddd2dZ	d3dZ
d4d"Zd5d$Zd6d%Zd7d&Zd4d'Zed4d(            Zed6d)            Zed8d*            Zd9d+Zd:d,Zd-S );RelaySessionCoordinatorz=Own semantic conversation and turn lifetimes for Hermes core.registryr   r)   r*   c                    || _         t          j                    | _        i | _        t          j                    | _        i | _        d S r   )r   r   r   _initializer_lock_session_initializers_active_turns_lock_active_turns)r=   r   s     r"   r>   z RelaySessionCoordinator.__init__  sF     !*!2!2  	" #,/"3"3>@r!   r   r   r|   .Callable[[RelayRuntime, dict[str, Any]], None]c                Z    | j         5  || j        |<   ddd           dS # 1 swxY w Y   dS )zFRegister idempotent profile/session preparation before scope creation.N)r   r   )r=   r   r|   s      r"   register_session_initializerz4RelaySessionCoordinator.register_session_initializer  s~     # 	8 	8/7D&t,	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8 	8s    $$c                |    | j         5  | j                            |d           ddd           dS # 1 swxY w Y   dS )z3Remove a previously registered session initializer.N)r   r   rt   )r=   r   s     r"   unregister_session_initializerz6RelaySessionCoordinator.unregister_session_initializer  s    # 	7 	7&**4666	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7s   155ro   r$   r   rO   c                   | j         5  t          | j                                                  }d d d            n# 1 swxY w Y   |D ]?\  }}	  |||           # t          $ r  t
                              d|d           Y <w xY wd S )Nz+Hermes Relay session initializer failed: %sTr   )r   r   r   r   rd   r   r   )r=   ro   r   initializersr   r|   s         r"   _prepare_sessionz(RelaySessionCoordinator._prepare_session  s   
 # 	D 	D : @ @ B BCCL	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D* 	 	ND(w''''   A!      	 	s   ';??A'BBr   )r   modelr&   r   r   r   r  r   c                  | j                             |          }|t          |d          }d }t          |t                    r	 |||||d}|                     ||           d|pdi}	|r!||k    r|                    ||d|	          }n|                    d|i|	          }n,# t          $ r t          
                    dd	
           Y nw xY wt          ||||||          S )Nz Relay host creation was disabled)r&   r   r   r   r  hermes.execution_surfaceunknown)r   rk   ri   r   z/Hermes Relay conversation initialization failedTr   )r&   r   r   ro   re   r   )r   r   r   r   r$   r   rq   r[   rd   r   r   r   )
r=   r&   r   r   r   r  ro   re   session_contextrM   s
             r"   acquire_conversationz,RelaySessionCoordinator.acquire_conversation  sk    }((55<#K1STTDdL)) 	#.", ():"# # %%dO<<<68MIN$ ):j)H)H"441B0:  "* 5  GG #11%z2!) 2  G    E!      
 !#!/
 
 
 	
s   A B& &&CCrn   r   r   r   c               8   |j         rt          d          t          |||          }t          |j        t
                    r|j        	 |j                            |j        |j        j        j	        j
        t          |j        j        j        j        |j        j        i t          t           t"          |j        j        d|j        pdi          |_        n,# t(          $ r t*                              dd           Y nw xY wt.                              |          |_        |j        |j        f}| j        5  | j                            |t1                                                    tA          |                     d|_!        d d d            n# 1 swxY w Y   |S )	Nz+Hermes Relay conversation lease is released)rn   r   r   r  r  )r   rU   rM   z'Hermes Relay turn initialization failedTr   )"r   r   r   r   ro   r$   re   r   r'   r_   r`   
TURN_SCOPErb   Functionr   rX   rY   rZ   r1   r   rd   r   r   r   r7   r   r&   r   r   r   
setdefaultrB   idr   )r=   rn   r   r   rp   r   s         r"   
begin_turnz"RelaySessionCoordinator.begin_turnQ  s    > 	NLMMMeWgNNNej,// 	YEM4MY#j77MJ$*/J$.7 =/*,B,ej.C2EN4Oi 8    Y Y YHSWXXXXXY#''-- %"23$ 	+ 	+))#suu5599"T((CCC&*D#	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ s&   BC &C=<C=4AFFFrp   outcomec               |   |j         5  |j        r#|                     |           	 d d d            d S d|_        |j        }	 t	          |j        t                    r|j        |                     ||           |j	        	 |j        
                    |j        |j        j        j        j        |j	        d|it          t          t           |j        j        i           n,# t$          $ r t&                              dd           Y nw xY w	 |j        r;t	          |j        t                    r!|j                            d|j        i           n,# t$          $ r t&                              dd           Y nw xY w|                     |           |                     |           n# |                     |           |                     |           w xY w# 	 |j        r;t	          |j        t                    r!|j                            d|j        i           n,# t$          $ r t&                              dd           Y nw xY w|                     |           |                     |           w # |                     |           |                     |           w xY wxY w	 d d d            d S # 1 swxY w Y   d S )	NTr  r  r   rM   z%Hermes Relay turn finalization failedr   rk   z3Hermes Relay child conversation finalization failed)r   rm   _reset_turn_contextrn   r   ro   r$   re   _finish_logical_callsr   r   r'   r_   rt   rX   rY   rZ   r1   rd   r   r   r   ru   r   _unregister_active_turn)r=   rp   r  rn   s       r"   end_turnz RelaySessionCoordinator.end_turns  s     ,	3 ,	3{ ((...,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 DKJE&3ej,77 EM<U..tW.EEE{.!J55 % %
 0 6 : $(17';$68N$8%*:O*" 6 	 	 	 	  )   "NN GRV +     
3
 /&uz<@@ 
66.0@8    !   NNM!% #      00666,,T2222 00666,,T2222%3
 /&uz<@@ 
66.0@8    !   NNM!% #      00666,,T2222 00666,,T22222Y,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3 ,	3s   J1J1?GACG&DGDGAEF&&E85F&7E88F&;+J1&,GJ1J AHI1&I	 I1I	I1+J 1,J	J  J11J58J5r   c                   ||f}| j         5  t          | j                            |                    cddd           S # 1 swxY w Y   dS )z?Return whether a turn is still running for one profile/session.N)r   r   r   rW   )r=   r&   r   r   s       r"   has_active_turnz'RelaySessionCoordinator.has_active_turn  s    J'$ 	5 	5*..s3344	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5s   'A  AAc                L   |j         sd S |j        j        |j        j        f}| j        5  | j                            |          }|?|                    t          |                     |s| j        	                    |d            d|_         d d d            d S # 1 swxY w Y   d S r   )
r   rn   r&   r   r   r   rW   rF   r  rt   )r=   rp   r   actives       r"   r  z/RelaySessionCoordinator._unregister_active_turn  s    & 	Fz%tz'<=$ 	, 	,'++C00F!r$xx((( 6&**3555&+D#	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	,s   A#BB Bc                x    | j         5  | j                                         d d d            d S # 1 swxY w Y   d S r   )r   r   r   rI   s    r"   _reset_active_turns_for_testsz5RelaySessionCoordinator._reset_active_turns_for_tests  s    $ 	' 	'$$&&&	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	' 	's   /33c                   |j         5  |j        r	 ddd           dS |                     ||           ddd           dS # 1 swxY w Y   dS )zBClose logical LLM children before sibling task aggregation scopes.Nr  )r   rm   r  )r=   rp   r  s      r"   finish_logical_callsz,RelaySessionCoordinator.finish_logical_calls  s      	> 	>{ 	> 	> 	> 	> 	> 	> 	> 	> &&tW&===	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	>s   	AAA	Ac                  | j         }t          |j        t                    r|j        d S | j        5  t          | j                                                  }| j        	                                 d d d            n# 1 swxY w Y   t          t          |          dz
  dd          D ]}||         \  }}	 |j                            |j        |j        j        j        j        |d|it           t"          t$          |j        j        i           f# t(          $ ro | j        5  |d |dz            D ] \  }}| j                            ||           !	 d d d            n# 1 swxY w Y   t,                              dd           Y  d S w xY wd S )N   r  r  z,Hermes Relay logical LLM finalization failedTr   )rn   r   ro   r$   re   r   r   r   r   r   rangelenr   r'   r_   rt   rX   rY   rZ   r1   rd   r
  r   r   )	rp   r  rn   logical_callsindex
request_idlogical_handlepending_request_idpending_handles	            r"   r  z-RelaySessionCoordinator._finish_logical_calls  sW    
%*l33 	u}7LF" 	+ 	+ !7!=!=!?!?@@M"((***	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 3}--12r:: 	 	E)6u)=&J
))MJ$*."%w/*,B,ej.C * 	 	 	 	    * 
 
 ?L#%!)?  :*N .99.*   	
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 B!     !	 	sI   A A>>BB8ADF	!/EF	E!!F	$E!%F	F	c                    | j         dS 	 t                              | j                    n# t          $ r Y dS w xY wd| _         dS )zCReset the originating ContextVar token when called in that context.N)r   r   resetrA   )rp   s    r"   r  z+RelaySessionCoordinator._reset_turn_context  s`     ;F	,,,, 	 	 	 FF	 s   + 
99c                    d| _         dS )z@Release a caller lease without closing a resumable conversation.TN)r   )rn   s    r"   release_conversationz,RelaySessionCoordinator.release_conversation  s     r!   c                   | j                             |d          }t          |t                    r|                    d|i           d S d S )NFr   r   )r   r   r   r$   rs   )r=   r&   r   ro   s       r"   finalize_conversationz-RelaySessionCoordinator.finalize_conversation  sY     }((U(CCdL)) 	;j9:::::	; 	;r!   c                :    | j                             |           d S r   )r   r   )r=   r&   s     r"   r   z(RelaySessionCoordinator.shutdown_profile  s    &&{33333r!   N)r   r   r)   r*   )r   r   r|   r   r)   r*   )r   r   r)   r*   )ro   r$   r   rO   r)   r*   )r&   r   r   r   r   r   r   r   r  r   r)   r   )rn   r   r   r   r   r   r)   r   )rp   r   r  r   r)   r*   )r&   r   r   r   r)   r   )rp   r   r)   r*   r   )rn   r   r)   r*   )r&   r   r   r   r)   r*   r   )r   r   r   r   HOST_REGISTRYr>   r   r   r   r  r  r  r  r  r  r  r   r  r  r+  r-  r   r    r!   r"   r   r     s       GG5B A A A A A8 8 8 87 7 7 7
   . "$1
 1
 1
 1
 1
 1
f       D23 23 23 23h5 5 5 5
, 
, 
, 
,' ' ' '
> 
> 
> 
> ( ( ( \(T 
 
 
 \
    \; ; ; ;4 4 4 4 4 4r!   r   r)   RelayTurnContext | Nonec                 4    t                                           S )zCReturn the turn context inherited by current async and thread work.)r   rW   r    r!   r"   current_turnr2    s    r!   r   r(   c                |   t                      }||j        s|j        j        rdS |j        j        t                      k    rdS | |j        j        | k    rdS t          |j        j        t                    rE|j        j
        dS |j        j                            |j        j                  |j        j
        urdS |S )zFReturn a live turn only when it belongs to the active profile/session.N)r2  rm   rn   r   r&   r-   r   r   ro   r$   re   rx   )r   rp   s     r"   rl   rl     s    >>D|t{|dj&9|tz!4!6!666t$*"7:"E"Et$*/<00 :%4:?&&tz'<==TZEWWW4Kr!   r   4tuple[RelayRuntime | None, RelaySession | None, Any]c                   t          |           }|Rt          |j        j        t                    r3|j        j        '|j        j        }|j        j        ||j        p|j        fS t          d          }|dS |                                sdS |	                    |           }||
                    d| i          }|||dn|j        fS )zCResolve one active turn/session parent for managed Relay execution.NFr   )NNNr   )rl   r   rn   ro   r$   re   r   get_runtimerJ   rx   r[   )r   rp   re   runtimes       r"   resolve_execution_contextr8  -  s     z""Dtz55 	J**$z)FFF '''G,,..  !!*--G((,
)CDDGW_TT'.HHr!   rK   r   rL   r   rM   r   c                   t          d          }|dS 	 |                    | d|i||          S # t          $ r! t                              d| d           Y dS w xY w)	z3Emit a fail-open Relay mark under a Hermes session.Fr   Nr   rK   zHermes Relay mark failed: %sTr   )r6  r   rd   r   r   )r   r   rL   rM   r7  s        r"   r   r   G  s     '''Gu	  :&	 ! 
 
 	
    5tdKKKuus   1 'AAr   r~   rO   c                b    | s|S t          d          }||S |                    | ||          S )zDReturn Relay-rewritten arguments at Hermes's authorization boundary.Fr   N)r   r   r~   )r6  r   )r   r   r~   r7  s       r"   r   r   ^  sQ      '''G00 1   r!   r   rQ   c                    t                      }|dS 	 |                    d| i|          S # t          $ r  t                              dd           Y dS w xY w)z>Create or return the shared Relay session used by Hermes core.Nr   z*Hermes Relay session initialization failedTr   )r6  r[   rd   r   r   )r   r   r7  s      r"   r[   r[   q  sq    mmGt%%|Z&K7&KLLL   CdSSStts   - &AAr|   r}   r   c                    t                      }|t          d          |                    |           }||                    d| i          }|t          d           |j        ||g|R i |S )z>Run a scope, LLM, or tool API against a shared Hermes session.N#Hermes Relay runtime is unavailabler   #Hermes Relay session is unavailable)r6  r   rx   r[   r   r   r|   r~   r   r7  re   s         r"   r   r   }  s     mmG@AAA!!*--G((,
)CDD@AAA!7!'8EdEEEfEEEr!   c                   K   t                      }|t          d          |                    |           }||                    d| i          }|t          d           |j        ||g|R i | d{V S )z?Await a Relay operation inside a shared Hermes session context.Nr=  r   r>  )r6  r   rx   r[   r   r?  s         r"   r   r     s       mmG@AAA!!*--G((,
)CDD@AAA--gxQ$QQQ&QQQQQQQQQr!   c                T    t          d          }|dn|                    |           S )z?Return the shared Relay handle for direct core instrumentation.Fr   N)r6  rz   )r   r7  s     r"   rz   rz     s.    '''G?44(B(B:(N(NNr!   relay_errorBaseExceptioncallback_errorc                    | u rdS t          | t                    sdS j        }|j        |j        |j         d|j         h}t          |           t          fd|D                       S )zDMatch Relay's native callback wrapper without masking policy errors.TF.c              3  N   K   | ]}                     d | d           V   dS )zinternal error: z: N)
startswith).0	type_namerD  messages     r"   	<genexpr>z3_is_relay_wrapped_callback_error.<locals>.<genexpr>  sV         	KiKK>KKLL     r!   )r   r   	__class__r   r   r   r   any)rB  rD  callback_type
type_namesrK  s    `  @r"    _is_relay_wrapped_callback_errorrQ    s    
 n$$tk<00 u",M"#BBm&@BBJ
 +G     #     r!   r   r&   r   r&   RelayRuntime | Nonec                l    t                               ||           }t          |t                    r|ndS )z4Return the Relay host for the active Hermes profile.r   N)r/  r   r   r$   )r   r&   ro   s      r"   r6  r6    s5     $$[$@@DdL11;44t;r!   r   c                :    t                               ||           S )zBReturn the explicit real or reduced-capability host for a profile.r   )r/  r   rR  s     r"   get_hostrV    s     $$[$@@@r!   c                 ~   t                                                      } |                                 s!t          |                                           S t          |           }t
                              |          }||S t          |                                           }t
                              ||          S )zAReturn the canonical profile identity used for runtime isolation.)r   
expanduseris_absoluter   resolver	   rW   r
  )homerawcachedresolveds       r"   r-   r-     s    ''))D #4<<>>"""
d))C##C((F4<<>>""H((h777r!   c                 *    t          j        d          S )z>Load the binding only when a producer or consumer needs Relay.
nemo_relay)	importlibimport_moduler    r!   r"   r,   r,     s    "<000r!   rN   c                J    t          |                     d          pd          S )Nr   r   )r   rW   )rN   s    r"   rV   rV     s!    uyy&&,"---r!   r*   c                     t                                            t                                           t                                           dS )z8Reset all profile-scoped Relay hosts for isolated tests.N)SESSION_COORDINATORr  r/  r   r	   r   r    r!   r"   _reset_for_testsrf    s>    55777   r!   )r)   r0  r   )r   r(   r)   r0  )r   r   r)   r4  )
r   r   r   r   rL   r   rM   r   r)   r   r   )r   r   r   r   r)   rQ   )
r   r   r|   r}   r~   r   r   r   r)   r   r   )rB  rC  rD  rC  r)   r   )r   r   r&   r(   r)   rS  )r   r   r&   r(   r)   r   )r)   r   r   )rN   rO   r)   r   r   ):r   
__future__r   r:   r   r\   ra  r   loggingr   r.   dataclassesr   r   typingr   r   hermes_constantsr   	getLoggerr   r   ra   r  LOGICAL_LLM_SCOPErX   rY   rZ   r	   r   r   r$   r   r   r   r/  r   r   
ContextVarr   r   re  r2  rl   r8  r   r   r[   r   r   rz   rQ  r6  rV  r-   r,   rV   rf  r    r!   r"   <module>ro     sm   H H H " " " " " "                  ( ( ( ( ( ( ( (                 , , , , , ,		8	$	$ 
- 2 2 6 %'  ' ' ' ' / / / / / / / /C C C C C C C CL
 $!C !C !C !C !C !C !C !CH ++	* * * * * * * *Z "!## 	 	 	 	 	 	 	 	        0 BXAWB B B    
_4 _4 _4 _4 _4 _4 _4 _4D	 .-//    
    "I I I I<      .   &	 	 	 	F F F F$R R R R$O O O O   0 "< < < < < < "A A A A A A
8 
8 
8 
81 1 1 1
. . . .     r!   