
    L0&j$'                    H   U d Z ddlmZ ddlZddlmZ ddlmZmZ ddl	m
Z
mZmZmZmZ  ej        e          ZdZdZd	Zd
ZdZdZeZeZeeeehZded<   e G d d                      Zd3dZd3dZd4dZd5dZ d6dZ!d5d Z"d7d#Z#d8d$Z$d7d%Z%d9d(Z&d:d*Z'd;d,Z(d<d0Z)d=d2Z*dS )>a  Hermes middleware contract helpers.

Observer hooks report what happened. Middleware can change what happens by
rewriting a request or wrapping the actual execution callback. Keep the small
contract helpers here so agent-loop call sites and plugins share one vocabulary.
    )annotationsN)deepcopy)	dataclassfield)AnyCallableDictListOptionalzhermes.observer.v1zhermes.middleware.v1tool_requesttool_executionllm_requestllm_executionzset[str]VALID_MIDDLEWAREc                  X    e Zd ZU dZded<   ded<   dZded<    ee          Zd	ed
<   dS )RequestMiddlewareResultz;Result of applying request middleware to a mutable payload.r   payloadoriginal_payloadFboolchanged)default_factoryzList[Dict[str, Any]]traceN)	__name__
__module____qualname____doc____annotations__r   r   listr        :/home/ubuntu/.hermes/hermes-agent/hermes_cli/middleware.pyr   r   %   s\         EELLLG"'%"="="=E======r    r   kwargsr   returnDict[str, Any]c                 <    |                      dt                     | S )Ntelemetry_schema_version)
setdefaultOBSERVER_SCHEMA_VERSIONr"   s    r!   observer_payloadr*   /   s    
02IJJJMr    c                 r    |                      dt                     |                      dt                     | S )Nr&   middleware_schema_version)r'   r(   MIDDLEWARE_SCHEMA_VERSIONr)   s    r!   middleware_payloadr.   4   s7    
02IJJJ
13LMMMMr    r   c                    	 t          |           S # t          $ rP}t                              d|           t	          | t
                    rt          |           cY d}~S | cY d}~S d}~ww xY w)a  Deep-copy a request payload, tolerating non-deepcopyable members.

    Request payloads are normally plain JSON-shaped dicts, but an LLM request
    can occasionally carry non-deepcopyable objects (clients, callbacks, file
    handles). A hard ``deepcopy`` failure there would otherwise abort the whole
    request-middleware pass. Fall back to a shallow ``dict`` copy so middleware
    still runs and the original nested objects are shared by reference rather
    than corrupting the live payload.
    z<deepcopy failed for request payload (%s); using shallow copyN)r   	Exceptionloggerdebug
isinstancedict)r   excs     r!   
_safe_copyr6   :   s          SUXYYYgt$$ 	!==      	s&    
A+>A&A+A& A+&A+requestcontextc                   t          t                    st          | | dg           S t          |           }t          |          }g }t	          t          f||d|D ]t}t          |t                    s|                    d          }t          |t                    sCt          |          }|                    t          |                     ut          ||t          |          |          S )zApply registered LLM request middleware.

    Middleware may return ``{"request": {...}}`` to replace the effective
    provider kwargs before Hermes sends them.
    Fr   r   r   r   r7   original_requestr7   )_has_middlewareLLM_REQUEST_MIDDLEWAREr   r6   _invoke_middlewarer3   r4   getappend_trace_entryr   )r7   r8   r<   current_requestr   resultnext_requests          r!   apply_llm_request_middlewarerF   M   s!    122 
&$	
 
 
 	
 "'** !122O"$E$)  	  + + &$'' 	zz),,,-- 	$\22\&))****")U	   r    	tool_namestrargsc                   t          t                    st          ||dg           S t          |          }t          |          }g }t	          t          f| ||d|D ]t}t          |t                    s|                    d          }t          |t                    sCt          |          }|                    t          |                     ut          ||t          |          |          S )zApply registered tool request middleware.

    Middleware may return ``{"args": {...}}`` to replace the effective tool
    arguments before hooks, guardrails, approvals, and execution see them.
    Fr:   rG   rI   original_argsrI   )r=   TOOL_REQUEST_MIDDLEWAREr   r6   r?   r3   r4   r@   rA   rB   r   )rG   rI   r8   rL   current_argsr   rD   	next_argss           r!   apply_tool_request_middlewarerP   x   s"    233 
&!	
 
 
 	
 t$$Mm,,L"$E$#	 
   + + &$'' 	JJv&&	)T** 	!),,\&))****"&U	   r    c                    t          | fi |S )z7Compatibility wrapper for older ``api_request`` naming.)rF   )r7   r8   s     r!   apply_api_request_middlewarerR      s    
 (;;7;;;r    	next_callCallable[[Dict[str, Any]], Any]c                    t          t                    }|s ||           S t          t          ||f| |                    d|           d|S )zCRun provider execution through registered LLM execution middleware.r<   r;   )_get_middleware_callbacksLLM_EXECUTION_MIDDLEWARE_run_execution_chainpop)r7   rS   r8   	callbackss       r!   run_llm_execution_middlewarer[      sp     **BCCI "y!!!   %7AA    r    c           	         t          t                    }|s ||          S t          t          ||f| ||                    d|          d|S )z@Run tool execution through registered tool execution middleware.rL   rK   )rV   TOOL_EXECUTION_MIDDLEWARErX   rY   )rG   rI   rS   r8   rZ   s        r!   run_tool_execution_middlewarer^      sp     **CDDI y! kk/488    r    c                    t          | |fi |S )z9Compatibility wrapper for older ``api_execution`` naming.)r[   )r7   rS   r8   s      r!   run_api_execution_middlewarer`      s     (FFgFFFr    kind	List[Any]c           	     4    ddl m}  || fi t          di |S )Nr   )invoke_middlewarer   )hermes_cli.pluginsrd   r.   )ra   r"   rd   s      r!   r?   r?      s<    444444TBB%7%A%A&%A%ABBBr    r   c                $    ddl m}  ||           S )Nr   )has_middleware)re   rg   )ra   rg   s     r!   r=   r=      s$    111111>$r    List[Callable]c                n    ddl m} t           |            j                            | g                     S )Nr   )get_plugin_manager)re   rj   r   _middlewarer@   )ra   rj   s     r!   rV   rV      s?    555555""$$044T2>>???r    rZ   terminal_callCallable[[Any], Any]c                     dv rdnd G d dt                     d fd
 d                   S )Nr7   rI   c                        e Zd Zd fdZ xZS )7_run_execution_chain.<locals>._DownstreamExecutionErrororiginalBaseExceptionr#   Nonec                r    t                                          t          |                     || _        d S N)super__init__rH   rq   )selfrq   	__class__s     r!   rw   z@_run_execution_chain.<locals>._DownstreamExecutionError.__init__   s,    GGS]]+++$DMMMr    )rq   rr   r#   rs   )r   r   r   rw   __classcell__)ry   s   @r!   _DownstreamExecutionErrorrp      s=        	% 	% 	% 	% 	% 	% 	% 	% 	% 	%r    r{   indexintr   r   r#   c                     t                    k    r           S           ddd d
d	
 f	d}t          di }|<   ||d<   	  di |S # 	$ r}|j        d }~wt          $ r^}t                              dt          dt                              |           rcY d }~S r  
 d	z             cY d }~S d }~ww xY w)NFnext_payloadr   r#   c                   	 r2t          d dt          dt                               d          d	  dz   | 
n|           d	S # t          $ r} |          |d }~ww xY w)NzMiddleware 'z' callback r   zF called next_call() more than once; downstream execution is single-useT   )RuntimeErrorgetattrreprr0   )r   r5   r{   call_atcallbackr|   ra   next_callednext_resultnext_succeededr   s     r!   rS   z8_run_execution_chain.<locals>.call_at.<locals>.next_call  s      "U4 U UxT(^^DDU U U  
 K>%geaiL<PVbcc!%"" > > >//44#=>s   A 
A+A&&A+rS   z&Middleware '%s' callback %s raised: %sr   r   ru   )r   r   r#   r   r   )lenr.   rq   r0   r1   warningr   r   )r|   r   rS   call_kwargsr5   r   r   r   r   r{   r   rZ   ra   r"   payload_keyrl   s   ``   @@@@r!   r   z%_run_execution_chain.<locals>.call_at   s   C	NN"" =)))U#	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	>( )22622#*K #,K 	/8**k***( 	 	 	, 	/ 	/ 	/NN8*d8nn==	    #""""""" 7519g........	/s6   A" "C'A..C;<C7C=CCCr   )r|   r}   r   r   r#   r   )r0   )ra   rZ   rl   r"   r{   r   r   s   ````@@@r!   rX   rX      s      )F22))K% % % % %I % % %
// // // // // // // // // // // //b 71f[)***r    rD   c                    i }dD ]3}|                      |          }t          |t                    r|r|||<   4|sd|d<   |S )N)sourcereasonnamepluginr   )r@   r3   rH   )rD   entrykeyvalues       r!   rB   rB   1  s^    E+  

3eS!! 	e 	E#J #"hLr    )r"   r   r#   r$   )r   r   r#   r   )r7   r$   r8   r   r#   r   )rG   rH   rI   r$   r8   r   r#   r   )r7   r$   rS   rT   r8   r   r#   r   )
rG   rH   rI   r$   rS   rT   r8   r   r#   r   )ra   rH   r"   r   r#   rb   )ra   rH   r#   r   )ra   rH   r#   rh   )
ra   rH   rZ   rh   rl   rm   r"   r   r#   r   )rD   r$   r#   r$   )+r   
__future__r   loggingcopyr   dataclassesr   r   typingr   r   r	   r
   r   	getLoggerr   r1   r(   r-   rM   r]   r>   rW   API_REQUEST_MIDDLEWAREAPI_EXECUTION_MIDDLEWAREr   r   r   r*   r.   r6   rF   rP   rR   r[   r^   r`   r?   r=   rV   rX   rB   r   r    r!   <module>r      sX     # " " " " "        ( ( ( ( ( ( ( ( 6 6 6 6 6 6 6 6 6 6 6 6 6 6		8	$	$. 2 ( , & *  0 3  	      > > > > > > > >   
      &( ( ( (V* * * *Z< < < <   &   *G G G GC C C C       @ @ @ @>+ >+ >+ >+B     r    