
    i                     L   U d Z ddlZddlZddlZ ej        e          Z e ej        d                    Z	e	re
                    ej                    e            Zee         ed<    ej                    Zddededz  ddfdZdefd	Z G d
 d          Z e            ZdS )uy  Per-thread interrupt signaling for all tools.

Provides thread-scoped interrupt tracking so that interrupting one agent
session does not kill tools running in other sessions.  This is critical
in the gateway where multiple agents run concurrently in the same process.

The agent stores its execution thread ID at the start of run_conversation()
and passes it to set_interrupt()/clear_interrupt().  Tools call
is_interrupted() which checks the CURRENT thread — no argument needed.

Usage in tools:
    from tools.interrupt import is_interrupted
    if is_interrupted():
        return {"output": "[interrupted]", "returncode": 130}
    NHERMES_DEBUG_INTERRUPT_interrupted_threadsactive	thread_idreturnc                    ||nt          j                    j        }t          5  | rt                              |           nt                              |           t          rt          t                    nd}ddd           n# 1 swxY w Y   t          r6t          
                    d| |t          j                    j        |           dS dS )zSet or clear interrupt for a specific thread.

    Args:
        active: True to signal interrupt, False to clear it.
        thread_id: Target thread ident.  When None, targets the
                   current thread (backward compat for CLI/tests).
    Nz[[interrupt-debug] set_interrupt(active=%s, target_tid=%s) called_from_tid=%s current_set=%s)	threadingcurrent_threadident_lockr   adddiscard_DEBUG_INTERRUPTsetloggerinfo)r   r   tid	_snapshots       4/home/ubuntu/.hermes/hermes-agent/tools/interrupt.pyset_interruptr   '   s#    !,)))2J2L2L2RC	 L L 	. $$S)))) ((---1AKC,---t	L L L L L L L L L L L L L L L  
0C13399	
 	
 	
 	
 	

 
s   ABB	B	c                      t          j                    j        } t          5  | t          v cddd           S # 1 swxY w Y   dS )u   Check if an interrupt has been requested for the current thread.

    Safe to call from any thread — each thread only sees its own
    interrupt state.
    N)r	   r
   r   r   r   )r   s    r   is_interruptedr   >   s     
"
$
$
*C	 + +**+ + + + + + + + + + + + + + + + + +s   	6::c                   F    e Zd ZdZdefdZd	dZd	dZd
dedz  defdZ	dS )_ThreadAwareEventProxyzDDrop-in proxy that maps threading.Event methods to per-thread state.r   c                     t                      S N)r   selfs    r   is_setz_ThreadAwareEventProxy.is_setT   s        Nc                 $    t          d           d S )NTr   r   s    r   r   z_ThreadAwareEventProxy.setW   s    dr    c                 $    t          d           d S )NFr"   r   s    r   clearz_ThreadAwareEventProxy.clearZ   s    er    timeoutc                 *    |                                  S )u:   Not truly supported — returns current state immediately.)r   )r   r%   s     r   waitz_ThreadAwareEventProxy.wait]   s    {{}}r    )r   Nr   )
__name__
__module____qualname____doc__boolr   r   r$   floatr'    r    r   r   r   Q   s        NN                EDL D      r    r   r   )r+   loggingosr	   	getLoggerr(   r   r,   getenvr   setLevelINFOr   r   int__annotations__Lockr   r   r   r   _interrupt_eventr.   r    r   <module>r9      s;       				    		8	$	$ 4		":;;<<  " OOGL!!! "% c#h & & &	
 
$ 
3: 
 
 
 
 
.+ + + + +&       " *)++   r    