
    sj2                      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ZddlZddlmZ ddlmZmZ ddlmZmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZmZ  ej         e!          Z"dZ#dZ$dZ%dZ&dZ'dZ(dZ)i Z*de+d<   dZ,da-de+d<    e
j.                    Z/d Z0d|dZ1ddddd}d$Z2 G d% d&e          Z3 G d' d(e4          Z5e G d) d*                      Z6da7d+e+d,<    e
j.                    Z8d~d.Z9dd0Z: G d1 d2          Z; G d3 d4          Z< e<            Z= ej>        e=j?                    G d5 d6          Z@ ed78           G d9 d:                      ZAe@eAz  ZB G d; d<          ZC eC            ZDe G d= d>                      ZEe G d? d@                      ZF ejG        dAdB          ZHdCe+dD<    ejG        dEdB          ZIdFe+dG<    G dH dI          ZJ G dJ dK          ZK eK            ZLddMZMddOZNdddRZOddUZPdddVddYZQdd\ZRdd_ZSddcZTdddZUddeZVddiZWd7ddjddnZXd7ddjddpZYddqZZddrZ[ddtZ\dduZ]ddvZ^ddxZ_ddzZ`dd{ZadS )zBProfile-scoped NeMo Relay runtimes owned by the Hermes agent core.    )annotationsN)TimeoutError)	dataclassfield)Enumauto)Path)AnyCallable)get_hermes_home)RELAY_PLUGINS_CONFIG_ENV configured_legacy_relay_env_varszhermes.sessionzhermes.turnzhermes.logical_llm_callzhermes.relay.schema_versionzhermes.relay.runtime.v1zhermes.relay.runtime_instancezhermes.nemo_relay.pluginszdict[str, str]_PROFILE_KEY_CACHEg      $@r
   _SCOPE_OP_EXECUTORc                     t           9t          5  t           ddlm}   | dd          a ddd           n# 1 swxY w Y   t           S )u  Shared daemon executor for bounded native scope operations.

    Daemon workers (tools.daemon_pool) so a wedged native call abandoned at
    timeout cannot block interpreter exit.  Sized generously: workers are
    only consumed for the duration of healthy (microsecond) operations plus
    any wedged calls, and ``Future.result(timeout=...)`` bounds callers even
    when every worker is consumed by wedged calls — an unstarted future
    still honors the result timeout, so exhaustion degrades to fast
    timeouts, never a new hang.
    Nr   DaemonThreadPoolExecutor   zrelay-scope-op)max_workersthread_name_prefix)r   _SCOPE_OP_EXECUTOR_LOCKtools.daemon_poolr   r   s    7/home/agent/.hermes/hermes-agent/agent/relay_runtime.py_scope_op_executorr   0   s     !$ 	 	!)FFFFFF%=%= !'7& & &"		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 s   6::fnCallable[[], Any]timeoutfloatreturnc                    g g d fd}t          j        |dd          }|                                 |                    |           |                                rt          d| d          rd	         rd	         nd
S )u  Bounded fallback lane for interpreter shutdown.

    When the shared executor refuses new futures (interpreter shutdown),
    the operation still must not run unbounded on the calling thread: a
    wedged native call would block process exit forever — the same defect
    class this module exists to prevent, on the exit lane.  Run it on a
    fresh daemon thread with a bounded join; on breach the daemon worker
    is abandoned exactly like the executor lane abandons its worker.
    r   Nonec                     	                                              d S # t          $ r }                      |            Y d } ~ d S d } ~ ww xY wN)appendBaseException)excerrorr   results    r   _targetz,_run_bounded_on_exit_thread.<locals>._targetU   si    	MM""$$ 	 	 	LL	s   " 
AAATzrelay-scope-op-exit)targetdaemonnameRelay scope operation exceeded zUs during interpreter shutdown; abandoning the native call so process exit can proceedr   Nr   r!   )	threadingThreadstartjoinis_aliver   )r   r   r)   workerr'   r(   s   `   @@r   _run_bounded_on_exit_threadr5   H   s     F!#E        t*?  F LLNNN
KK 
Og O O O
 
 	
  Ah(6!99D(    )outputmetadata	timestamprelayhandler7   r8   r9   c               ^   | j         j        }i }|||d<   |||d<   |||d<   	 t          j        |          j        n# t
          t          f$ r i Y nw xY wrKt          d                                 D                       s fd|	                                D             } ||fi |S )ar  Pop a Relay scope without passing kwargs the binding rejects.

    NeMo Relay ``scope.pop`` gained ``metadata`` in 0.4+. Older wheels (e.g.
    0.3.x) raise ``TypeError: pop() got an unexpected keyword argument
    'metadata'`` when Hermes finalization forwards runtime metadata. Filter to
    parameters the live binding accepts so turn/session close can complete.
    Nr7   r8   r9   c              3  J   K   | ]}|j         t          j        j        k    V  d S r#   )kindinspect	ParameterVAR_KEYWORD).0params     r   	<genexpr>z"pop_relay_scope.<locals>.<genexpr>   s@        8=
g'33     r6   c                $    i | ]\  }}|v 	||S  rF   )rB   keyvalueparamss      r   
<dictcomp>z#pop_relay_scope.<locals>.<dictcomp>   s$    OOOe#ur6   )
scopepopr?   	signature
parameters	TypeError
ValueErroranyvaluesitems)r:   r;   r7   r8   r9   rL   kwargsrI   s          @r   pop_relay_scoperU   j   s    +/CF!x%z'{"3''2z"    Pc  AG     P POOOv||~~OOO3v     s   A   AAc                  v    e Zd ZdZ e            Z e            Z e            Z e            Z e            Z	dS )_RelayPluginConfigurationStatez=Process-wide result shared by every currently hosted profile.N)
__name__
__module____qualname____doc__r   UNINITIALIZEDDISABLEDACTIVEFOREIGNFAILEDrF   r6   r   rW   rW      sK        GGDFFMtvvHTVVFdffGTVVFFFr6   rW   c                      e Zd ZdZdS )"_RelayPluginConfigurationLoadErrorzFAn explicitly selected Relay plugin configuration could not be loaded.N)rX   rY   rZ   r[   rF   r6   r   rb   rb      s        PPPPr6   rb   c                      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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
   r;   zcontextvars.Context | Nonecontextr   intsegmentsegment_turnsrotate_pendingclose_pending)rX   rY   rZ   r[   __annotations__rh   r   r/   RLockrm   ro   r;   rp   rr   rs   rt   ru   rF   r6   r   rd   rd      s         CCOOO!E)/NNNDNNNNGF*.G.... GM N      Mr6   rd   dict[str, Any] | None_SEGMENTS_CONFIGdict[str, Any]c            
     &   t           t          5  t           d} d}	 ddlm}  |                                d          pi                     d          pi }|                    d          pi }t          |                    dd                    } 	 t          dt          |                    d	d          pd                    }n# t          t          f$ r d}Y nw xY wn# t          $ r Y nw xY w| |d
a ddd           n# 1 swxY w Y   t           S )zAResolve session-segmentation settings; inert defaults when unset.NFr   )_load_gateway_configgateway	telemetrysession_segmentson_compaction	max_turns)r   r   )ry   _SEGMENTS_CONFIG_LOCKgateway.runr|   getrn   maxrq   rO   rP   	Exception)r   r   r|   r~   segmentss        r   _segments_configr      s    " 	 	' %	@@@@@@ .-//33I>>D"II'   	   )}}-?@@FBH$(ou)M)M$N$NM&$'3x||K/K/K/Pq+Q+Q$R$R		%z2 & & &$%			&    D &3!*$ $ +	 	 	 	 	 	 	 	 	 	 	 	 	 	 	2 sY   DA4C 3CC CC CC D 
C-*D,C--DDDr!   c                 
    d a d S r#   )ry   rF   r6   r    _reset_segments_config_for_testsr      s    r6   c                  *    e Zd ZdZddZddZddZdS )RelayOperationLeasezBKeep process-wide Relay plugins alive across a deferred operation.runtime'RelayRuntime'r   r!   c                D    t          j                    | _        || _        d S r#   )r/   Lock_lock_runtimeselfr   s     r   __init__zRelayOperationLease.__init__   s    ^%%
-4r6   sessionrd   callbackCallable[..., Any]argsr
   rT   c                    | j         5  | j        }|t          d           |j        ||g|R i |cddd           S # 1 swxY w Y   dS )z=Run cleanup while this lease still owns the runtime lifetime.Nz(Hermes Relay operation lease is released)r   r   RuntimeError_run_in_session_untracked)r   r   r   r   rT   r   s         r   run_in_sessionz"RelayOperationLease.run_in_session   s     Z 		 		mG"#MNNN474    	 			 		 		 		 		 		 		 		 		 		 		 		 		 		 		 		 		 		s   *?AAc                    | j         5  | j        }d| _        ddd           n# 1 swxY w Y   ||                                 dS dS )z Release this lease exactly once.N)r   r   _end_operationr   s     r   releasezRelayOperationLease.release   s    Z 	! 	!mG DM	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! ""$$$$$ s   #''N)r   r   r   r!   )
r   rd   r   r   r   r
   rT   r
   r   r
   r.   )rX   rY   rZ   r[   r   r   r   rF   r6   r   r   r      sV        LL5 5 5 5   &% % % % % %r6   r   c                  J    e Zd Z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 ) _ProcessRelayPluginConfigurationz?Own one Relay plugin configuration across profile-scoped hosts.r   r!   c                    t          j                    | _        t                      | _        t
          j        | _        d| _        d | _	        d | _
        d S NF)r/   rw   r   set_ownersrW   r\   _state_active_relay_activationr   s    r   r   z)_ProcessRelayPluginConfiguration.__init__  sB    _&&
!$4B $r6   ownerr
   r:   rW   c                L   t          |          }| j        5  || j        v r| j        cddd           S | j        r-| j                            |           | j        cddd           S | j        rZ|                                 sFt                              d           | 	                    |t          j                  cddd           S 	 |j                                        }nX# t          $ rK t                              dd           | 	                    |t          j                  cY cddd           S w xY w|Ft                              d           | 	                    |t          j                  cddd           S 	 t!          |          }|,| 	                    |t          j                  cddd           S |\  }}|rd	 t%          |j                            ||                    }|t)          d          || _        n"# t          $ r}	t)          d          |	d}	~	ww xY w| j        't%          |j                            |                     ng# t          $ rZ}	d| _        t                              d	|	d           | 	                    |t          j                  cY d}	~	cddd           S d}	~	ww xY wd| _        || _        | 	                    |t          j                  }
t                              d
           |
cddd           S # 1 swxY w Y   dS )zCJoin the process configuration, initializing it for the first host.NzbHermes Relay plugin cleanup is still pending; refusing to replace the process-global configurationzxHermes could not determine whether a process-global Relay plugin configuration is already active; refusing to replace itTexc_infozA process-global Relay plugin configuration is already active outside Hermes native ownership; leaving it unchanged and disabling Hermes-managed Relay middleware for this processzFNeMo Relay dynamic plugin initialization returned no activation handlez-Hermes Relay dynamic plugin activation failedz-Hermes Relay plugin initialization failed: %sz^Relay plugins are active process-wide and apply to all profiles hosted by this Hermes process.)idr   r   r   addr   _clear_activeloggerwarning	_rememberrW   r`   pluginreportr   r_   _configured_plugin_inputsr]   _resolve_plugin_awaitableinitialize_with_dynamic_pluginsr   r   
initializer   r^   info)r   r   r:   owner_idexisting_reportconfigured_inputsplugin_configdynamic_plugins
activationr&   states              r   acquirez(_ProcessRelayPluginConfiguration.acquire  s	    e99Z ]	 ]	4<''{]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 | #  ***{]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 | D$6$6$8$8 ?   ~~29 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 "',"5"5"7"7 	 	 	U!    
 ~~29   1]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	$	 *Q  
 ~~2: E]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	N*$=e$D$D!$,>> 6? U]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	\ 2C." ##%>!LHH - / & &
 &-".!@# #  ,6(($ # # #*K "##
 #+ .el.E.Em.T.TUUU 
 
 
#' C!    
 ~~29      ]]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	N
  DLDKNN.5 E KK1   {]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	 ]	s   L'L(AL
C$#L$AD9*L8D99>L0II
A H
I
H*H%%H**1IL
K &AJ;)K *L;K  ALL Lr   rq   r   c                H    | j                             |           || _        |S )zARetain one process decision for all concurrently hosted profiles.)r   r   r   )r   r   r   s      r   r   z*_ProcessRelayPluginConfiguration._rememberu  s&     	"""r6   c                :   t          |          }| j        5  || j        vr	 ddd           dS | j                            |           | j        r	 ddd           dS |                                 rt
          j        | _        ddd           dS # 1 swxY w Y   dS )z<Release one host and clear Relay after the final host exits.N)r   r   r   remover   rW   r\   r   )r   r   r   s      r   r   z(_ProcessRelayPluginConfiguration.release  sC   e99Z 	K 	Kt|++	K 	K 	K 	K 	K 	K 	K 	K L)))| 	K 	K 	K 	K 	K 	K 	K 	K !!## K<J	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	Ks   B"B%BBBc                    | j         5  | j                                         |                                 rt          j        | _        ddd           dS # 1 swxY w Y   dS )zCClear process-global state left by directly constructed test hosts.N)r   r   clearr   rW   r\   r   r   s    r   reset_for_testsz0_ProcessRelayPluginConfiguration.reset_for_tests  s    Z 	K 	KL   !!## K<J	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	K 	Ks   ?AAAc                    | j         5  | j        s%|                                 rt          j        | _        ddd           dS # 1 swxY w Y   dS )z<Retry a failed final cleanup without disrupting live owners.N)r   r   r   rW   r\   r   r   s    r   retry_pending_cleanupz6_ProcessRelayPluginConfiguration.retry_pending_cleanup  s    Z 	O 	O< O%%'' O"@"NDK	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	Os   -AA	Arn   c                   | j         }| j        }| j        }|r|dS 	 t          |           n-# t          $ r  t
                              dd           Y dS w xY w	 |Gt          |dd           }t          |          st          d          t           |                       nt          |           n-# t          $ r  t
                              dd           Y dS w xY wd| _        d | _         d | _        dS )NTz+Hermes Relay plugin subscriber flush failedr   Fclosez8NeMo Relay dynamic plugin activation has no close methodz0Hermes Relay plugin configuration cleanup failed)r   r   r   _flush_relay_subscribersr   r   r   getattrcallabler   r   _clear_relay_plugins)r   r:   r   activer   s        r   r   z._ProcessRelayPluginConfiguration._clear_active  sM   %
 	4	$U++++ 	 	 	NN=     55		%
GT:: &R   *%%''2222$U+++ 	 	 	NNB     55	 ts"   - &AAAB4 4&CCNr.   )r   r
   r:   r
   r   rW   )r   rq   r   rW   r   rW   )r   r
   r   r!   r   rn   )rX   rY   rZ   r[   r   r   r   r   r   r   r   rF   r6   r   r   r     s        II% % % %d d d dL   
K 
K 
K 
KK K K KO O O O! ! ! ! ! !r6   r   c                  ,   e Zd ZdZdHdddId
ZdJdZdJdZdKdZddddLdZdMdZ	dddNdZ
dOdZdPd!ZdQd"Zd#dd$dRd,Zd#dd$dRd-Zd#d.dSd/ZdTd0ZdTd1ZdUd3ZddddVd5ZdWd7Zdd#d8d9d#d:dXdAZdOdBZdOdCZdTdDZdTdEZdTdFZedYdG            ZdS )ZRelayRuntimezCOwn Relay session scopes and optional process plugin configuration.Nprofile_keyr:   r
   r   
str | Noner   r!   c                  |pt                      | _        |pt                      | _        t	          j                    j        | _        t          j	                    | _
        i | _        i | _        i | _        d| _        d| _        t          j                    | _        t          j                    | _        | j                                         d| _        t          j	                    | _        t'                      | _        t.                              | | j                  | _        d| _        | j        t6          j        u r|                     t<                     d| _        tA          j!        | j"                   d S )NFr   T)#_load_nemo_relayr:   current_profile_keyr   uuiduuid4hex
runtime_idr/   rw   _sessions_lock	_sessions_subagent_parents_subagent_parent_handles_closing_shutdown_startedEvent_shutdown_complete_operations_idler   _active_operations_execution_consumers_lock_execution_consumers_PLUGIN_CONFIGURATIONr   _plugin_configuration_state _plugin_configuration_registeredrW   r^   retain_managed_execution RELAY_PLUGINS_EXECUTION_CONSUMER_shutdown_registeredatexitregistershutdown)r   r:   r   s      r   r   zRelayRuntime.__init__  s?   0.00
&?*=*?*?*,,*'o//24138:%!&"+/"3"3 ) 1 1!!###"#)2):):&.1ee!+@+H+HJ,
 ,
( 15-,-45 5 ))*JKKK$(!&&&&&r6   consumerre   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)rP   r   r   r   r   r   s     r   r   z%RelayRuntime.retain_managed_execution  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)r   r   discardr   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rn   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)r   rn   r   r   s    r   managed_execution_enabledz&RelayRuntime.managed_execution_enabled  s}    + 	3 	3122	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3s   )--datar8   eventrz   r   r8   rx   RelaySession | Nonec                  t          |          }|sdS | j        5  | j        r	 ddd           dS | 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                    }
	 	 t'                                          |
j        | j        j        j        t2          | j        j        j        ||i |                              t:                    |_	        nT# t<          $ rG |
                    | j        j        j        t2          | j        j        j        ||i |          |_	        Y nw xY wn# t>          $ 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.Nrg   )rf   rh   rf   subagentnemo_relay_scope_role)r;   r   inputr8   r   )!_session_idr   r   r   r   r   rd   rm   ro   r;   RUNTIME_SCHEMA_KEYRUNTIME_SCHEMA_VERSIONRUNTIME_INSTANCE_KEYr   rh   r   ensure_sessioncontextvarsContextr   submitrunr:   rK   pushSESSION_SCOPE	ScopeTypeAgentr(   _SCOPE_OP_TIMEOUTr   r   rp   )r   r   r   r8   rf   r   rh   parent_handlescope_metadataparentrp   s              r   r  zRelayRuntime.ensure_session  s    !''
 	4  
	5 
	5} 
	5 
	5 
	5 
	5 
	5 
	5 
	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 \ 0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	* ~% $"~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#:;%-//);)=)=)D)D#K J,1) J06#0!%"$%3 *E 	* 	* !&):&;;   (    *1 J,1) J06#0!%"$%3 *5 * * !   &*GO #*a0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	* 0	*b s   	BABBB!	I78I/D
ID	ID	AI"A/GH'AH# H'"H##H'&I'H::
IIIr   rd   reasonc               6   |j         5  |j        s|j        	 ddd           dS |j        }|xj        dz  c_        d|_        d|_        	 |                     || j        j        j	        |d|it          t          t          | j        it                     n;# t          $ r. t                               d|j        |j        dz
  d	           Y nw xY wt          t          t          | j        d
|j        d|i}d}|j        rC| j        5  | j                            |j                  }ddd           n# 1 swxY w Y   d|d<   t/          j                    }	 t3                                          |j        | j        j        j        t:          | j        j        j        |i |                               t                    |_        ||_!        n8# t          $ r+ t                               d|j        |j        d	           Y nw xY wddd           dS # 1 swxY w Y   dS )u  Close the current session scope and open the next segment.

        Called ONLY at a turn boundary (before the turn scope pushes), never
        mid-turn: the scope stack is LIFO and rotating under a live child
        would close a parent out of order. Both native calls are bounded by
        ``_SCOPE_OP_TIMEOUT`` — a wedged rotation costs one segment span,
        never the agent. Segment bookkeeping advances even when a native
        call fails, so a degraded rotation cannot retry on every turn.
        N   r   Fzhermes.session.segment_reason)r7   r8   r   zZHermes Relay segment close failed (session=%s segment=%d); abandoning the old segment spanTr   zhermes.session.segmentr  r  )r;   r  r8   r  zXHermes Relay segment open failed (session=%s segment=%d); keeping the prior scope handle)"rm   ro   r;   rr   rs   rt   r   r:   rK   rL   r  r	  r
  r   r  r   r   r   rf   rh   r   r   r   r  r  r   r  r  r  r  r  r  r(   rp   )r   r   r  
old_handler  r  rp   s          r   rotate_session_scopez!RelayRuntime.rotate_session_scope;  s    \ =	 =	 '."8=	 =	 =	 =	 =	 =	 =	 =	 !J OOq OO$%G!%*G"##J$(;VD*,B,do . $ 
 
 
 
    6&Oa'!       #$:$do('//	N !M( E(  $($A$E$E*% %M               ;E67!)++G!3!5!5!<!<KJ$)!J(.(+ "= " " &!2&33  #*   5&O!      m=	 =	 =	 =	 =	 =	 =	 =	 =	 =	 =	 =	 =	 =	 =	 =	 =	 =	s   H%HA	BH5C
HC6H D/#H/D3	3H6D3	7HA5G	H	2G>;H=G>>HHHr8   c               ^   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        r	 ddd           dS || 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.rh   rg   child_session_idNrf   r  )re   r   r  r;   active_turnclosedleasehostr   rf   r   r   r   r   )r   r   r8   rh   r  r  r  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} 	P 	P 	P 	P 	P 	P 	P 	P 8ID"#34(BO-.>?	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P ""+, # 
 
 	
s   	D)DDD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.r  rg   Nrf   )re   r   close_sessionr   r   rL   r   )r   r   r  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rf   c                   | j         5  | j        r	 ddd           dS | 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.Nrg   )r   r   r   r   re   rm   ro   r   rf   r   s      r   get_sessionzRelayRuntime.get_session  sX     	@ 	@} 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 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A)BBBc                B    |                      |          }|dn|j        S )z?Return the Relay parent handle for a Hermes session, if active.N)r+  r;   r*  s      r   get_session_handlezRelayRuntime.get_session_handle  s%    "":..ttGN:r6   Fallow_closingr   r   r   r   r/  r   float | NonerT   c                   |                                   	  | j        ||g|R ||d||                                  S # |                                  w xY w)u  Run a Relay operation against a session's isolated scope stack.

        ``timeout`` (seconds) bounds the native call by running it on a
        shared daemon executor; ``TimeoutError`` propagates to the caller's
        existing exception handling on breach.  ``None`` (default) preserves
        the historical synchronous behavior.  Scope lifecycle operations
        that gate turn/session completion pass ``_SCOPE_OP_TIMEOUT``: the
        native binding's ``scope.pop`` "returns after the scope is closed
        successfully" — unbounded — and a wedged native pipeline (proven
        live 2026-08-10 in the delegation topology) must cost at most one
        span, never the agent.  The abandoned daemon worker cannot block
        process exit (tools.daemon_pool contract).
        r.  )_begin_operationr   r   )r   r   r   r/  r   r   rT   s          r   r   zRelayRuntime.run_in_session  s    , 	
	"141   ,    !!!!D!!!!s	   ? Ac                   |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 	 t                                          j	                  }
n$# t          $ r t          fd|          cY S w xY w	 |
                    |          S # t          $ r!}t!          d	| d
|j         d          |d}~ww xY w)z?Run inside a session whose host-level lifetime is already held.Hermes Relay session is closingN+Hermes Relay session context is unavailabler   r
   c                 F    j                                            i S r#   )r:   get_scope_stack)r   r   rT   r   s   r   invokez6RelayRuntime._run_in_session_untracked.<locals>.invoke  s,    J&&(((8T,V,,,r6   c                 .                                    S r#   )r  )rp   r8  s   r   <lambda>z8RelayRuntime._run_in_session_untracked.<locals>.<lambda>  s    F++ r6   r  r-   zs (session=u[   ); abandoning the native call so the agent can continue — the span for this scope is lostr   r
   )rm   ro   r   rp   r;   copyr  copy_contextrS   r  r   r   r  r5   r(   FuturesTimeoutErrorr   rf   )r   r   r   r/  r   r   rT   relay_contextvariablerH   futurer&   rp   r8  s   ` `  ``     @@r   r   z&RelayRuntime._run_in_session_untracked  s1    \ 	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,,,,	- 	- 	- 	- 	- 	- 	- 	- 	- ?;;v&&&
	'))00fEEFF 	 	 	 /+++++W    		===111" 	 	 	P' P P#.P P P  		s<   AA))A-0A-'D D&%D&*E   
E+
E&&E+)r/  c               p   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 #                                   w xY w)zACreate and await an operation inside the session's saved context.r4  Nr5  r   r
   c                    K   j                                           i } t          j        |           r|  d {V S | S r#   )r:   r7  r?   isawaitable)r(   r   r   rT   r   s    r   r8  z1RelayRuntime.run_in_session_async.<locals>.invoke.  sY      
**,,,!42622&v.. (!'<<<<<<'r6   r;  )r2  rm   ro   r   rp   r;   r<  r  r=  rS   r  r   asynciocreate_taskr   )r   r   r   r/  r   rT   r?  rp   r@  rH   r8  tasks   ` ` ``      r   run_in_session_asyncz!RelayRuntime.run_in_session_async  s      		" 7 7? J= J&'HIII?*gn.D&'TUUU ' 4 4 6 67 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ".00G#0#6#6#8#8 1 1%HL%0000         ;;w2FFHH==D::::::!!!!D!!!!s0   D AA>2D >BD BBD D5c                    | j         5  | j        rt          d          | xj        dz  c_        | j                                         ddd           dS # 1 swxY w Y   dS )z9Admit one Relay call while keeping process plugins alive.z%Hermes Relay runtime is shutting downr  N)r   r   r   r   r   r   r   s    r   r2  zRelayRuntime._begin_operation:  s      	* 	*} L"#JKKK##q(##!'')))		* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*s   A AAAc                    | j         5  | xj        dz  c_        | j        dk    r| j                                         d d d            d S # 1 swxY w Y   d S )Nr  r   )r   r   r   r   r   s    r   r   zRelayRuntime._end_operationB  s      	, 	,##q(##&!++%))+++	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	,s   5A

AAr   c                H    |                                   t          |           S )z>Retain plugin lifetime for work that outlives one Relay await.)r2  r   r   s    r   acquire_operation_leasez$RelayRuntime.acquire_operation_leaseH  s"    "4(((r6   r,   c                   |                      |          }|dS |                     || j        j        j        ||j        ||           dS )zCEmit a mark parented to the Hermes session identified by ``event``.NF)r;   r   r8   T)r  r   r:   rK   r   r;   )r   r,   r   r   r8   r   s         r   	emit_markzRelayRuntime.emit_markM  sa     %%e,,?5J"> 	 	
 	
 	
 tr6   	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_interceptsrf   )r   r   r:   r   r  r   
isinstancedict)r   rf   rO  r   rR  r   r(   s          r   apply_tool_request_interceptsz*RelayRuntime.apply_tool_request_interceptsc  s     --// 	K$DJ.. 
 

 *++ 	K%%|Z&@AA?K$$	
 
 $FD11;vvt;r6   zscope close failed    )r7   r/  failure_labeldrain_limitoperation_already_heldr;   r7   rW  rX  rq   rY  c          	     |    dS t           t          t           j        i|pi |j        ddii d fd}	 |r j        n j        }	 |	|||t                     n# t          $ r}
| d|
 cY d}
~
S d}
~
ww xY w	                    d	          p	                    d
          }|| d| S dS )ae  Pop ``handle``, draining orphaned children in the same session context.

        Relay scopes are strict LIFO. Empty-stream retries + interrupt can
        abandon a physical LLM scope above TURN/SESSION (#81521). Drain and
        close must run inside one ``run_in_session`` callback so ContextVar
        stack views stay consistent across pops.
        Ncountr   r   r!   c                    dfd} dd}	 t          j                   d S # t          $ r}|
d	<   Y d }~nd }~ww xY wt                    D ]} |             }| ||          r nz ||          rur nf	 t          j        |d
dd           	dxx         dz  cc<   ]# t          $ r,}|
d<   t                              dd           Y d }~ nd }~ww xY w	d         r"t                              d	d                    	 t          j                   
                    d	d            
                    dd            d S # t          $ r}|
d<   Y d }~d S d }~ww xY w)Nr   r
   c                    t          t          j        dd           dd           } t          |           r	  |             S # t          $ r Y nw xY wj                                        }t          |t                    r|r|d         nd S |S )NrK   
get_handle)r   r:   r   r   r7  rS  list)r^  topr   s     r   current_topzORelayRuntime._close_scope_handle.<locals>.close_with_drain.<locals>.current_top  s     %DJ66d 
 J'' )z||+$   j0022
 c4(( 4&)33r77t3
s   	A 
AAabrn   c                    | || |u S | |u s| |k    rdS t          | dd           }t          |dd           }|d uo||k    S )NTr   )r   )rc  rd  a_uuidb_uuids       r   same_handlezORelayRuntime._close_scope_handle.<locals>.close_with_drain.<locals>.same_handle  sc     9	6M66Q!VV4 FD11 FD11T)>f.>>r6   )r7   r8   first	cancelledT)outcomezhermes.orphan_drainr[  r  drainz(Hermes Relay orphaned scope drain failedr   z;Hermes Relay drained %d orphaned scope(s) before closing %sretryr;  )rc  r
   rd  r
   r   rn   )rU   r:   r   ranger   r   rL   )rb  rh  	first_exc_ra  	drain_exc	retry_excclose_outputrX  drained_holdererror_holderr;   r8   r   session_roots          r   close_with_drainz:RelayRuntime._close_scope_handle.<locals>.close_with_drain  s        0
? 
? 
? 
?	2J'%	     2 2 2(1W%%%%%%2 ;''  !kmm;++c6":":;E !,#C66 -l22E#
'237    "*    #7+++q0++++    ,5L)NNB!% #    EEEEE g& Q"7+  

2J'%	      $///  $///// 2 2 2(1W%%%%%%%2sC   ' 
A ;A +B//
C%9!C  C%AE 
E3#E..E3r.  : rm  ri  r.   )
r  r	  r
  r   r;   r   r   r  r   r   )r   r   r;   r7   r/  rW  rX  rY  rw  r   r&   rr  rs  rt  ru  r8   rv  s   ` `   `     @@@@@r   _close_scope_handlez RelayRuntime._close_scope_handle  sr   $ >4 6 $/
 |~!113^	2 ^	2 ^	2 ^	2 ^	2 ^	2 ^	2 ^	2 ^	2 ^	2 ^	2 ^	2 ^	2@	- *)..( 
 N +
 *	 	 	 	 	  	- 	- 	-#,,s,,,,,,,,	- $$W--J1A1A'1J1J	 #22y222ts   $A+ +
B5B;BBc                    	 |                                   n# t          $ r Y dS w xY w	 |                     |           |                                  dS # |                                  w xY w)z=Close one session scope and remove it from the core registry.N)r2  r   _close_sessionr   )r   r   s     r   r'  zRelayRuntime.close_session  s    	!!#### 	 	 	FF		"&&&!!!!!D!!!!s    
%%A A*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	        7| 
                    ||j	        i ddd          }|r|                    |           ddd           n# 1 swxY w Y   | 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 already admitted by the host lifecycle gate.NTzsession scope close failed)r7   r/  rW  rY  z.Hermes Relay session %s closed with errors: %sz; )r  r   r   r   r   rL   r   rm   ro   r;   ry  r$   r   r   r2   )r   r   rf   r   failuresfailures         r   r{  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 \ 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- #GO~)22N"&">+/ 3    -OOG,,,	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	- 	-$   	@ 	@~!!*--88"":t444"&&z4888)--j$???		@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@
  	NN@		(##    	 	sM   >AA7BBB+	DADDD$A.FF"%F"c                   | j         5  | j        r	 ddd           dS d| _        d| _        | j        dk    }ddd           n# 1 swxY w Y   |rt	          j        | j        d| j        dd          d          }	 |                                 nR# t          $ rE | j         5  d| _        ddd           n# 1 swxY w Y   t                              dd	           Y nw xY wdS |                                  dS )
z;Close core scopes and release process plugin configuration.NTr   zhermes-nemo-relay-shutdown-r   r*   r,   r+   Fz.Hermes Relay deferred shutdown could not startr   )r   r   r   r   r/   r0   !_finish_shutdown_after_operationsr   r1   r   r   r   _finish_shutdown)r   has_active_operationsthreads      r   r   zRelayRuntime.shutdownG  s     	@ 	@% 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ &*D" DM$($;a$?!	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ 	@ ! 	%=H4?2A23FHH  F
   ( 3 3-2D*3 3 3 3 3 3 3 3 3 3 3 3 3 3 3D!       FsL   	AAA
A=B C!#B7+C!7B;	;C!>B;	?C! C!c                `    | j                                          |                                  d S r#   )r   waitr  r   s    r   r  z.RelayRuntime._finish_shutdown_after_operationsa  s/    ""$$$r6   c                   	 | j         5  t          | j                  }d d d            n# 1 swxY w Y   |D ]}|                     | j        d|i            | j        rN| j        t          j        u r| 	                    t                     t                              |            d| _        | j        r2	 t          j        | j                   n# t"          $ r Y nw xY wd| _        nS# t"          $ rF | j         5  d| _        d d d            n# 1 swxY w Y   t&                              dd           Y d S w xY w| j         5  | j                                         d d d            d S # 1 swxY w Y   d S )Nrf   FzHermes Relay shutdown failedTr   )r   r`  r   _safer{  r   r   rW   r^   r   r   r   r   r   r   
unregisterr   r   r   r   r   r   r   )r   session_idsrf   s      r   r  zRelayRuntime._finish_shutdowne  sr   	$ 3 3"4>223 3 3 3 3 3 3 3 3 3 3 3 3 3 3) L L


4.z0JKKKK4 	>45<= = 228   &--d3338=5( 2%dm4444    D,1) 	 	 	$ / /).&/ / / / / / / / / / / / / / /NN9DNIIIFF		
   	* 	*#'')))	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	* 	*s   C& *C& .C& .BC& 4C C& 
CC& C
C& &D67D?D6D	D6D	D65D6 E''E+.E+c                n    	  | |i |S # t           $ r  t                              dd           Y d S w xY w)Nz%Hermes Relay runtime operation failedTr   )r   r   r   )r   r   rT   s      r   r  zRelayRuntime._safe  sU    	8T,V,,, 	 	 	NNBTNRRR44	s   
 &44r#   )r:   r
   r   r   r   r!   r   re   r   r!   r   )r   rz   r   r
   r8   rx   r   r  )r   rd   r  re   r   r!   )r   rz   r8   rx   r   r  )r   rz   r   r!   )rf   re   r   r  rf   re   r   r
   )r   rd   r   r   r   r
   r/  rn   r   r0  rT   r
   r   r
   )r   rd   r   r   r   r
   r/  rn   rT   r
   r   r
   r.   )r   r   )
r,   re   r   rz   r   r
   r8   r
   r   rn   rf   re   rO  re   r   rz   r   rz   )r   rd   r;   r
   r7   rx   r/  rn   rW  re   rX  rq   rY  rn   r   r   )r   r   r   r
   rT   r
   r   r
   )rX   rY   rZ   r[   r   r   r   r   r  r  r%  r(  r+  r-  r   r   rH  r2  r   rL  rN  rU  ry  r'  r{  r   r  r  staticmethodr  rF   r6   r   r   r     s       MM't ' ' ' ' ' ':4 4 4 48 8 8 8
3 3 3 3 *.G G G G G GRG G G GZ +/	$
 $
 $
 $
 $
 $
LF F F F	8 	8 	8 	8; ; ; ; $ $!" !" !" !" !" !"P $ $/ / / / / /l $ "  "  "  "  "  "D* * * *, , , ,) ) ) )      ,< < < <B )-#1',R R R R R Rh	" 	" 	" 	"' ' ' 'R       4       * * * *<    \  r6   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.re   r   r  r   rn   c                    dS r   rF   r   s    r   	availablezNoopRelayRuntime.available      ur6   rf   rO  r   rz   c               
    ~~|S r#   rF   )r   rf   rO  r   s       r   rU  z.NoopRelayRuntime.apply_tool_request_intercepts  s     	r6   r   r!   c                    ~ d S r#   rF   r   s    r   r   z)NoopRelayRuntime.retain_managed_execution  	    HHr6   c                    ~ d S r#   rF   r  s    r   r   z*NoopRelayRuntime.release_managed_execution  r  r6   c                     dS r   rF   rF   r6   r   r   z*NoopRelayRuntime.managed_execution_enabled  r  r6   c                    dS )z4No resources are allocated on unsupported platforms.NrF   r   s    r   r   zNoopRelayRuntime.shutdown  s      r6   Nr   r  r  r.   )rX   rY   rZ   r[   rv   propertyr  rU  r  r   r   r   r   rF   r6   r   r  r    s         NNKKK   X       \    \    \C C C C C Cr6   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/   rw   r   _hostsr   s    r   r   zRelayHostRegistry.__init__  s    _&&
,.r6   NTcreater   r   r  rn   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  r   r   r   r   r   r   r  re   )r   r   r  rG   r#  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$re   c                    | j         5  | j                            |d           }d d d            n# 1 swxY w Y   ||                                 d S d S r#   )r   r  rL   r   )r   r   r#  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  rR   r   r   )r   hostsr#  s      r   shutdown_allzRelayHostRegistry.shutdown_all  s    Z 	  	 ++--..EK	  	  	  	  	  	  	  	  	  	  	  	  	  	  	   	 	DMMOOOO	 	s   A AAAr.   r#   )r   r   r  rn   r   r  r   re   r   r!   )rX   rY   rZ   r[   r   r  r  r  rF   r6   r   r  r    s        GG/ / / / #' 	     0        r6   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.re   r   rf   platform	RelayHostr#  r  r   rg   rh   Frn   releasedN)rX   rY   rZ   r[   rv   rh   r  rF   r6   r   r  r    sn         IIOOOMMMOOO    Hr6   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
Zded<   dS )RelayTurnContextz;Runtime-only context for one Hermes turn or top-level task.r  r"  re   turn_idtask_idNr
   r;   Fri   rz   logical_llm_callsrl   logical_llm_lockfinalize_lock)defaultrk   RelayTurnContext | None_previous_turnrn   _active_registeredTrelay_enabledr!  )rX   rY   rZ   r[   rv   r;   r   rT  r  r/   rw   r  r  r  r  r  r!  rF   r6   r   r  r    s4        EELLLLLLF(-d(O(O(OOOOO(-!) ) )     &+U!& & &M     /4eDu.M.M.MNMMMM$uU???????MFr6   r  hermes_relay_turn)r  z/contextvars.ContextVar[RelayTurnContext | None]_CURRENT_TURN#hermes_relay_managed_callback_depthzcontextvars.ContextVar[int]_MANAGED_CALLBACK_DEPTHc                  "    e Zd ZdZd
dZddZd	S )managed_callback_guardan  Mark the current context as inside a managed Relay callback.

    Synchronous context manager used by the relay adapters around the
    ``invoke()`` callbacks they hand to the native pipeline. Everything the
    callback transitively calls (including work it forwards to worker threads
    via ``contextvars.copy_context()``) sees the marker and runs unmanaged.
    r   'managed_callback_guard'c                x    t                               t                                           dz             | _        | S )Nr  )r  r   r   _tokenr   s    r   	__enter__z managed_callback_guard.__enter__!  s/    -112I2M2M2O2ORS2STTr6   r   r
   r!   c                D    t                               | j                   d S r#   )r  resetr  )r   r   s     r   __exit__zmanaged_callback_guard.__exit__%  s    %%dk22222r6   N)r   r  )r   r
   r   r!   )rX   rY   rZ   r[   r  r  rF   r6   r   r  r    sF            3 3 3 3 3 3r6   r  c                      e Zd ZdZefd3dZd4dZd5dZd6dZdddd7dZ	d8dZ
d9d"Zd:d$Zdd%d;d'Zd<d)Zd=d*Zd>d+Zd9d,Zed9d-            Zed=d.            Zed?d/            Zd@d0ZdAd1Zd2S )B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/   rw   _initializer_lock_session_initializers_active_turns_lock_active_turns)r   r  s     r   r   z RelaySessionCoordinator.__init__,  sF     !*!2!2  	" #,/"3"3>@r6   r,   re   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_initializer6  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  rL   )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r#  r   rp   rz   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  rS   r   r   r   )r   r#  rp   initializersr,   r   s         r   _prepare_sessionz(RelaySessionCoordinator._prepare_sessionD  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rg   )rh   modelr   rf   r  rh   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   rf   r  rh   r  hermes.execution_surfaceunknown)rh   r  r  rf   z/Hermes Relay conversation initialization failedTr   )r   rf   r  r#  r   rh   )r  r  r  rS  r   r  r%  r  r   r   r   r  )
r   r   rf   r  rh   r  r#  r   session_contextr8   s
             r   acquire_conversationz,RelaySessionCoordinator.acquire_conversationU  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r"  r  r  r  c                  |j         rt          d          t          |||          }|j        |j        f}| j        5  | j                            |          }|r)d|_        t          
                    d||j                   nt          |          h| j        |<   d|_        d d d            n# 1 swxY w Y   |j        ryt          |j        t                    r^|j        V	 t#                      }|j        }|d         }	|d         r|j        s|	dk    r:|j        |	k    r/|d         r	|j        rd	nd}
|j                            ||

           n,# t*          $ r t          
                    dd           Y nw xY w	 |j                            |j        |j        j        j        j        t4          |j        j        j        j        |j        j        i t<          t>          t@          |j        j!        d|j"        pditF                    |_        n,# t*          $ r t          
                    dd           Y nw xY wtH                                          |_%        tH          &                    |           |S )Nz+Hermes Relay conversation lease is released)r"  r  r  FzJSkipping Relay instrumentation for concurrent Hermes turn %s in session %sTr   r   r   
compaction)r  z$Hermes Relay segment rotation failedr   r  r  )r;   r  r8   r   z'Hermes Relay turn initialization failed)'r  r   r  r   rf   r  r  r   r  r   r   r   r  rS  r#  r   r   r   rt   rs   r  r   r   r:   rK   r  
TURN_SCOPEr  Functionr;   r  r	  r
  r   r  r  r  r  r   )r   r"  r  r  r$  rG   r   configr   capr  s              r   
begin_turnz"RelaySessionCoordinator.begin_turn  s    > 	NLMMMeWgNNN %"23$ 	/ 	/'++C00F / &+"'$	    ,.d88*"3'*.'	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/" *	Y5:|44*	Y ))++-[)?+ L0F L!GG 5 < < "/2)7>7M)( 
 J33GF3KKK   :T      Y#j77MJ$*/J$.7 =/*,B,ej.C2EN4Oi
 . 8    Y Y YHSWXXXXXY+//11$s8   A%B//B36B3&A,E &E<;E< BH &H87H8r$  rk  c          	        |j         5  |j        r#|                     |           	 d d d            d S d|_        |j        }	 t	          |j        t                    rl|j        e|                     ||           |j	        G|j        
                    |j        |j	        d|id          }|rt                              d|           	 |j        rZt	          |j        t                    r@|j        9|j        j        5  |j        xj        dz  c_        d d d            n# 1 swxY w Y   n# t           $ r 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|                     |           nW# 	 |j        rZt	          |j        t                    r@|j        9|j        j        5  |j        xj        dz  c_        d d d            n# 1 swxY w Y   n# t           $ r 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|                     |           w xY w	 d d d            d S # 1 swxY w Y   d S )NTrk  rk  zturn scope close failedr7   rW  z)Hermes Relay turn finalization failed: %sr  r  z3Hermes Relay child conversation finalization failedr   )r  r!  _reset_turn_contextr"  rS  r#  r   r   _finish_logical_callsr;   ry  r   r   r  rm   rs   r   rh   r(  rf   _unregister_active_turn_consume_deferred_close)r   r$  rk  r"  r~  s        r   end_turnz RelaySessionCoordinator.end_turn  s     4	4 4	4{ ((...4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 DKJE.4ej,77 EM<U..tW.EEE{."'*"@"@!M K$-w#7*C	 #A # # # "NN K '  

 /=&uz<@@= "M5"]/ = =!M771<77= = = = = = = = = = = = = = =    D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,,U3333=
 /=&uz<@@= "M5"]/ = =!M771<77= = = = = = = = = = = = = = =    D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,,U33333i4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4 4	4s'  NNBH	4D+=DD+D#	#D+&D#	'D+*N+
D85N7D88N<AE?>G?&F(%G'F((G++N,HNM04J I4	(J 4I88J ;I8<J ?M0 
J	
M0J	M0AKL+&K=	:L+<K=	=L+ +M0+,M	M00NNNr
   c                   	 t          |j        t                    r|j        dS |j        }|j        5  |j        o|j         }ddd           n# 1 swxY w Y   |sdS |                     |j        |j	                  rdS |j        
                    d|j	        i           dS # t          $ r  t                              dd           Y dS w xY w)u2  Close a session whose rotating-compaction close was deferred.

        ``notify_session_compacted`` sets ``close_pending`` instead of
        closing when the old session still has a live turn (closing then
        would pop the session scope under the live turn scope — LIFO
        violation). The turn that was live consumes the flag here, after
        its own turn scope popped and it unregistered from the
        active-turn table. Skips when another turn is still live on the
        same session; that turn's end_turn will consume it instead.
        Nr   rf   rf   z*Hermes Relay deferred session close failedTr   )rS  r#  r   r   rm   ru   ro   has_active_turnr   rf   r'  r   r   r   )r   r"  r   pendings       r   r  z/RelaySessionCoordinator._consume_deferred_close  sY   	5:|449>9RmG H H!/G4GH H H H H H H H H H H H H H H ##!-%:J $    J$$lE4D%EFFFFF 	 	 	NN<t       	sE   !B$ B$ AB$ AB$ AB$ !B$ !B$ $&CC)old_session_idr  c               
   	 t                      d         sdS | j                            |          }t          |t                    sdS |r||k    r|j        5  |j                            |          }ddd           n# 1 swxY w Y   |F|                     ||          r/|j	        5  |j
        sd|_        ddd           n# 1 swxY w Y   dS |                    d|i           dS |j        5  |j                            |          }ddd           n# 1 swxY w Y   |dS |j	        5  |j
        sd|_        ddd           dS # 1 swxY w Y   dS # t          $ r  t                              dd           Y dS w xY w)u  React to a completed compaction, per compaction mode.

        In-place compaction (``old_session_id`` empty or equal to
        ``session_id``): flag the session for segment rotation at its next
        turn boundary. Never rotates immediately — a compaction can
        complete while a turn is live, and rotation under a live turn
        scope would violate the scope stack's LIFO order; ``begin_turn``
        consumes the flag.

        Legacy rotating compaction (``old_session_id`` differs): the next
        turn acquires a fresh Relay session under the new id on its own,
        but the OLD session's scope would stay open forever — an
        unexported orphan. Close it now so the pre-compaction segment
        exports.

        Unknown sessions and disabled config are silent no-ops; this
        method must never add work or failure modes to the compaction
        critical path.
        r   Nr  Trf   z+Hermes Relay compaction notification failedr   )r   r  r  rS  r   r   r   r   r  rm   ro   ru   r'  rt   r   r   r   )r   r   rf   r  r#  old_sessionr   s          r   notify_session_compactedz0RelaySessionCoordinator.notify_session_compacted-  s   4!	#%%o6 =,,[99DdL11  .J">"> ( E E"&."4"4^"D"DKE E E E E E E E E E E E E E E*t/C/C + 0D 0 0* %) = =*2 =8<K5= = = = = = = = = = = = = = = F""L.#ABBB$ 9 9.,,Z889 9 9 9 9 9 9 9 9 9 9 9 9 9 9 2 2 2-1G*2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2  	 	 	NN=       	s   E /E 	E A?3E ?BE B#E *C9E C		E C	E E +E 2DE DE  D!E (E /E>E EE EE &FFrn   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  rn   r  r   )r   r   rf   rG   s       r   r  z'RelaySessionCoordinator.has_active_turnj  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  r"  r   rf   r  r  r   r   r   rL   )r   r$  rG   r   s       r   r  z/RelaySessionCoordinator._unregister_active_turnp  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   r   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  r!  r  )r   r$  rk  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        |d|id          }|5| j        5  |d |dz            D ] \  }}	| j                            ||	           !	 d d d            n# 1 swxY w Y   t                              d|            d S d S )Nr  r_  rk  zlogical LLM scope close failedr  z0Hermes Relay logical LLM finalization failed: %s)r"  rS  r#  r   r   r  r`  r  rS   r   rn  lenry  
setdefaultr   r   )
r$  rk  r"  logical_callsindex
request_idlogical_handler~  pending_request_idpending_handles
             r   r  z-RelaySessionCoordinator._finish_logical_calls  s    
%*l33 	u}7LF" 	+ 	+ !7!=!=!?!?@@M"((***	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 3}--12r:: 	 	E)6u)=&Jj44!7+>	 5  G &  
 ;HeaiK;  6& *55*&                  NNMwWWWEE/	 	s$   A A>>BB&/D""D&	)D&	c                @   t                                           | urdS | j        }t          |           h}|M|j        rFt          |          |v rd}n2|                    t          |                     |j        }||j        Ft                               |           dS )z>Unwind ``turn`` without disturbing a newer context-local turn.N)r  r   r  r   r!  r   r   )r$  previousseens      r   r  z+RelaySessionCoordinator._reset_turn_context  s     d**F&4z"x"(||t##HHR\\""".H "x" 	(#####r6   c                    d| _         dS )z@Release a caller lease without closing a resumable conversation.TN)r  )r"  s    r   release_conversationz,RelaySessionCoordinator.release_conversation  s     r6   c                   | j                             |d          }t          |t                    r|                    d|i           d S d S )NFr  rf   )r  r  rS  r   r'  )r   r   rf   r#  s       r   finalize_conversationz-RelaySessionCoordinator.finalize_conversation  sY     }((U(CCdL)) 	;j9:::::	; 	;r6   c                :    | j                             |           d S r#   )r  r  )r   r   s     r   r  z(RelaySessionCoordinator.shutdown_profile  s    &&{33333r6   N)r  r  r   r!   )r,   re   r   r  r   r!   )r,   re   r   r!   )r#  r   rp   rz   r   r!   )r   re   rf   re   r  re   rh   re   r  re   r   r  )r"  r  r  re   r  re   r   r  )r$  r  rk  re   r   r!   )r"  r
   r   r!   )r   re   rf   re   r  re   r   r!   )r   re   rf   re   r   rn   )r$  r  r   r!   r.   )r"  r  r   r!   )r   re   rf   re   r   r!   r  )rX   rY   rZ   r[   HOST_REGISTRYr   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rF   r6   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H H H HT:4 :4 :4 :4x   H !; ; ; ; ; ;z5 5 5 5
, 
, 
, 
,' ' ' '
> 
> 
> 
> " " " \"H $ $ $ \$    \; ; ; ;4 4 4 4 4 4r6   r  r  c                 4    t                                           S )zCReturn the turn context inherited by current async and thread work.)r  r   rF   r6   r   current_turnr    s    r6   rn   c                 D    t                      } | du p| j        o| j         S )zDReturn whether this inherited turn may create Relay instrumentation.N)r  r  r!  )r$  s    r   relay_instrumentation_enabledr    s&    >>D4<CD.Bt{?Cr6   rf   r   c                   t                      }||j        r|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)r  r  r!  r"  r  r   r   rf   rS  r#  r   r   r+  )rf   r$  s     r   r   r     s    >>D! 	; 	 : 	
 tz!4!6!666t$*"7:"E"Et$*/<00 :%4:?&&tz'<==TZEWWW4Kr6   re   4tuple[RelayRuntime | None, RelaySession | None, Any]c                   t                                           dk    rdS t                      }||j        r|j        rdS 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.r   )NNNNFr  rf   )r  r   r  r  r!  r   rS  r"  r#  r   r   r;   get_runtimer   r+  r  )rf   inherited_turnr$  r   r   s        r   resolve_execution_contextr    s&    ""$$q((  !^^N!( ",:,A "  z""Dtz55 	J**$z)FFF '''G,,..  !!*--G((,
)CDDGW_TT'.HHr6   r   r,   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  Nrf   r   zHermes Relay mark failed: %sTr   )r  rN  r   r   r   )r,   rf   r   r8   r   s        r   rN  rN  $  s     '''Gu	  :&	 ! 
 
 	
    5tdKKKuus   1 'AArO  r   c                b    | s|S t          d          }||S |                    | ||          S )zDReturn Relay-rewritten arguments at Hermes's authorization boundary.Fr  N)rf   rO  r   )r  rU  )rf   rO  r   r   s       r   rU  rU  ;  sQ      '''G00 1   r6   rp   r  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.Nrf   z*Hermes Relay session initialization failedTr   )r  r  r   r   r   )rf   rp   r   s      r   r  r  N  sq    mmGt%%|Z&K7&KLLL   CdSSStts   - &AAr   r   rT   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 unavailablerf   #Hermes Relay session is unavailable)r  r   r+  r  r   rf   r   r   rT   r   r   s         r   r   r   Z  s     mmG@AAA!!*--G((,
)CDD@AAA!7!'8EdEEEfEEEr6   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  rf   r  )r  r   r+  r  rH  r   s         r   rH  rH  l  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Qr6   c                T    t          d          }|dn|                    |           S )z?Return the shared Relay handle for direct core instrumentation.Fr  N)r  r-  )rf   r   s     r   r-  r-  ~  s.    '''G?44(B(B:(N(NNr6   relay_errorr%   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: rx  N)
startswith)rB   	type_namer$  messages     r   rD   z3_is_relay_wrapped_callback_error.<locals>.<genexpr>  sV         	KiKK>KKLL     r6   )rS  r   	__class__rX   rZ   rY   re   rQ   )r#  r$  callback_type
type_namesr*  s    `  @r    _is_relay_wrapped_callback_errorr.    s    
 n$$tk<00 u",M"#BBm&@BBJ
 +G     #     r6   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  rS  r   )r  r   r#  s      r   r  r    s5     $$[$@@DdL11;44t;r6   r  c                :    t                               ||           S )zBReturn the explicit real or reduced-capability host for a profile.r  )r  r  r/  s     r   get_hostr3    s     $$[$@@@r6   c                 ~   t                                                      } |                                 s!t          |                                           S t          |           }t
                              |          }||S t          |                                           }t
                              ||          S )zAReturn the canonical profile identity used for runtime isolation.)r   
expanduseris_absolutere   resolver   r   r   )homerawcachedresolveds       r   r   r     s    ''))D #4<<>>"""
d))C##C((F4<<>>""H((h777r6   c                 *    t          j        d          S )z>Load the binding only when a producer or consumer needs Relay.
nemo_relay)	importlibimport_modulerF   r6   r   r   r     s    "<000r6   'tuple[dict[str, Any], list[Any]] | Nonec                   t           j                            t          d                                          }|sQt          t           j                  }|r4t                              dt          d                    |                     dS t          |          
                                }	 |                    d          5 }t          j        |          }ddd           n# 1 swxY w Y   d|v rt          d          g }d|v r| j                            |          }t#          |          }|                    dd           ||fS # t&          $ r}t)          d	| d
          |d}~ww xY w)zHLoad selected plugin inputs, or return ``None`` when none were selected.rg   zLegacy NeMo Relay exporter variables are set but no %s was provided. %s no longer activate Relay exporters; migrate the exporter configuration to a Relay plugins.toml file.z, Nrbr   zYHermes [[dynamic_plugins]] records are unsupported; use Relay [[plugins.dynamic]] recordspluginsz;Hermes Relay plugin configuration could not be loaded from z"; continuing without Relay plugins)osenvironr   r   stripr   r   r   r2   r	   r5  opentomllibloadrP   r   $load_dynamic_plugin_activation_specsrT  rL   r   rb   )	r:   
configuredlegacy_varsconfig_pathconfig_filer  r   r   r&   s	            r   r   r     s     8"==CCEEJ 
6rzBB 	NNG )		+&&   tz""--//Kd## 	/{\+..F	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/&&.   &(#lOO O V)T***o--   0?? ? ?
 
 	s=   -E
 C#E
 #C''E
 *C'+AE
 

E-E((E-c                R    t          | j                                                   dS )z:Flush Relay without blocking an asyncio event-loop thread.N)r   subscribersflush_asyncr:   s    r   r   r     s%    e/;;==>>>>>r6   c                R    t          | j                                                   dS )zBClear Relay plugins without blocking an asyncio event-loop thread.N)r   r   clear_asyncrR  s    r   r   r     s$    el668899999r6   rH   c                ~    t          j                   s S 	 t          j                     n$# t          $ r t          j                   cY S w xY wi i d	 fd}t          j        |dd          }|                                 |	                                 dv rd         
                    d          S )
zDResolve Relay's async plugin API from synchronous host construction.r   r!   c                 r    	 t          j                  d<   d S # t          $ r} | d<   Y d } ~ d S d } ~ ww xY w)NrH   r&   )rE  r  r%   )r&   r'   r(   rH   s    r   _runnerz*_resolve_plugin_awaitable.<locals>._runner  sS    	%k%00F7OOO 	 	 	E%LLLLLLL	s    
616z"hermes-nemo-relay-plugin-lifecycleTr  r&   rH   r.   )r?   rD  rE  get_running_loopr   r  r/   r0   r1   r2   r   )rH   rW  r  r'   r(   s   `  @@r   r   r     s    u%% " """" " " "{5!!!!!"  F&(E        1  F
 LLNNN
KKMMM~~El::gs   / AAr   c                J    t          |                     d          pd          S )Nrf   rg   )re   r   )r   s    r   r  r    s!    uyy&&,"---r6   c                     t                                            t                                           t                                           t                                           dS )z8Reset all profile-scoped Relay hosts for isolated tests.N)SESSION_COORDINATORr  r  r  r   r   r   r   rF   r6   r   _reset_for_testsr\    sP    55777   ))+++r6   )r   r   r   r   r   r
   )r:   r
   r;   r
   r7   r
   r8   r
   r9   r
   r   r
   )r   rz   r.   )r   r  r   r#   )rf   r   r   r  )rf   re   r   r  )
r,   re   rf   re   r   r
   r8   r
   r   rn   r  )rf   re   rp   r
   r   r  )
rf   re   r   r   r   r
   rT   r
   r   r
   r  )r#  r%   r$  r%   r   rn   )r  rn   r   r   r   r0  )r  rn   r   r   r   r  )r   re   r;  )r:   r
   r   r@  )r:   r
   r   r!   )rH   r
   r   r
   )r   rz   r   re   )br[   
__future__r   r   rE  r  r>  r?   loggingrD  r/   rH  r   concurrent.futuresr   r>  dataclassesr   r   enumr   r   pathlibr	   typingr
   r   hermes_constantsr   hermes_cli.relay_plugin_cutoverr   r   	getLoggerrX   r   r  r  LOGICAL_LLM_SCOPEr  r	  r
  r   r   rv   r  r   r   r   r   r5   rU   rW   r   rb   rd   ry   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  
ContextVarr  r  r  r  r[  r  r  r   r  rN  rU  r  r   rH  r-  r.  r  r3  r   r   r   r   r   r   r  r\  rF   r6   r   <module>ri     sU   H H H " " " " " "             				       B B B B B B ( ( ( ( ( ( ( (                               , , , , , ,       
 
	8	$	$ 
- 2 2 6 #>  %'  ' ' ' '       ().**   0) ) ) )L ! ! ! ! ! !D    T   Q Q Q Q Q Q Q Q                : +/  . . . .&	((    @   
 %  %  %  %  %  %  %  %Fv v v v v v v vr 98::  %; < < <H H H H H H H HV $!C !C !C !C !C !C !C !CH ++	* * * * * * * *Z "!## 	 	 	 	 	 	 	 	        , BXAWB B B     8N{7M)18 8 8     
3 3 3 3 3 3 3 3"g4 g4 g4 g4 g4 g4 g4 g4T .-//    
D D D D    ,*I *I *I *Ib      .   &	 	 	 	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? ? ? ?
: : : :
   <. . . .     r6   