
    Rmj`+              
       v   d Z ddlmZmZmZmZmZ ddlmZ	 ddlm
Z ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ dededededdf
dZdedefdZ dedededdfdZ!dedefdZ"dededededdf
dZ#dedefdZ$dedededdfdZ%dedefdZ&dedededdfdZ'dedefdZ(g dZ)dS )aR  Global middleware intercept registration for tools and LLMs.

Request intercepts transform inputs before execution. Execution intercepts wrap
the downstream callable and can observe, modify, or replace the result.

Example::

    import nemo_relay

    def add_header(
        name: str,
        request: nemo_relay.LLMRequest,
        annotated: nemo_relay.AnnotatedLLMRequest | None
    ) -> nemo_relay.LLMRequestInterceptOutcome:
        # The request object is immutable, however we can return a new instance with updated headers.
        headers = request.headers.copy()
        headers["X-Trace"] = "demo"
        return nemo_relay.LLMRequestInterceptOutcome(
            nemo_relay.LLMRequest(headers=headers, content=request.content), annotated
        )

    nemo_relay.intercepts.register_llm_request("trace-header", 10, False, add_header)
    )LlmExecutionInterceptLlmRequestInterceptLlmStreamExecutionInterceptToolExecutionInterceptToolRequestIntercept)"deregister_llm_execution_intercept) deregister_llm_request_intercept))deregister_llm_stream_execution_intercept)#deregister_tool_execution_intercept)!deregister_tool_request_intercept) register_llm_execution_intercept)register_llm_request_intercept)'register_llm_stream_execution_intercept)!register_tool_execution_intercept)register_tool_request_interceptnameprioritybreak_chainfnreturnNc                 &    t          | |||          S )a  Register an intercept that rewrites tool arguments before execution.

    Args:
        name: Unique intercept name used for later replacement or removal.
        priority: Execution order for the intercept. Lower values run first.
        break_chain: Whether to stop applying lower-priority request intercepts
            after this intercept runs.
        fn: Callable invoked as ``fn(tool_name, args)`` that returns the
            rewritten tool arguments.

    Returns:
        None: This function returns after the intercept is registered.

    Notes:
        Request intercepts run after conditional-execution guardrails and
        before sanitize-request guardrails or execution intercepts.

    Example::

        import nemo_relay

        def add_trace_id(tool_name, args):
            return {**args, "trace_id": "req-123"}

        nemo_relay.intercepts.register_tool_request(
            "trace-id",
            10,
            False,
            add_trace_id,
        )
    )_native_register_tool_requestr   r   r   r   s       ]/home/thesage/.hermes/hermes-agent/venv/lib/python3.11/site-packages/nemo_relay/intercepts.pyregister_tool_requestr   G   s    @ )xbIII    c                      t          |           S )az  Remove a previously registered tool request intercept.

    Args:
        name: Intercept name previously passed to ``register_tool_request()``.

    Returns:
        bool: ``True`` if an intercept was removed, otherwise ``False``.

    Notes:
        Removal affects only future executions. In-flight calls continue using
        the intercept chain they already resolved.
    )_native_deregister_tool_requestr   s    r   deregister_tool_requestr    j   s     +4000r   c                 $    t          | ||          S )a  Register middleware around tool execution.

    Args:
        name: Unique intercept name used for later replacement or removal.
        priority: Execution order for the intercept. Lower values run first.
        fn: Callable invoked as ``fn(tool_name, args, next_call)``. The
            callback may await or call ``next_call(args)`` to continue the
            chain, modify the result, or bypass downstream execution entirely.
            It must return ``ToolExecutionInterceptOutcome``.

    Returns:
        None: This function returns after the intercept is registered.

    Notes:
        Execution intercepts wrap the downstream tool callback. They are the
        right place for timing, retries, short-circuiting, or result shaping.
    )_native_register_tool_executionr   r   r   s      r   register_tool_executionr$   z   s    $ +42>>>r   c                      t          |           S )a  Remove a previously registered tool execution intercept.

    Args:
        name: Intercept name previously passed to
            ``register_tool_execution()``.

    Returns:
        bool: ``True`` if an intercept was removed, otherwise ``False``.

    Notes:
        Removal affects only future executions. In-flight calls continue using
        the execution chain they already resolved.
    )!_native_deregister_tool_executionr   s    r   deregister_tool_executionr'      s     -T222r   c                 &    t          | |||          S )a  Register an intercept that rewrites an ``LLMRequest`` before execution.

    Args:
        name: Unique intercept name used for later replacement or removal.
        priority: Execution order for the intercept. Lower values run first.
        break_chain: Whether to stop applying lower-priority request intercepts
            after this intercept runs.
        fn: Callable invoked as ``fn(name, request, annotated)`` that returns an
            ``nemo_relay.LLMRequestInterceptOutcome`` for the next intercept or
            the provider callback.

    Returns:
        None: This function returns after the intercept is registered.

    Notes:
        ``annotated`` is ``None`` unless a request codec was supplied to the
        managed LLM call. Intercepts should preserve both values when they do
        not need to mutate them.

    Example::

        import nemo_relay

        def add_header(
            name: str, request: nemo_relay.LLMRequest,
            annotated: nemo_relay.AnnotatedLLMRequest | None
        ) -> nemo_relay.LLMRequestInterceptOutcome:
            headers = request.headers.copy()
            headers["X-Trace"] = "req-123"
            return nemo_relay.LLMRequestInterceptOutcome(
                nemo_relay.LLMRequest(headers=headers, content=request.content), annotated
            )

        nemo_relay.intercepts.register_llm_request(
            "trace-header",
            10,
            False,
            add_header,
        )
    )_native_register_llm_requestr   s       r   register_llm_requestr*      s    R (hRHHHr   c                      t          |           S )ax  Remove a previously registered LLM request intercept.

    Args:
        name: Intercept name previously passed to ``register_llm_request()``.

    Returns:
        bool: ``True`` if an intercept was removed, otherwise ``False``.

    Notes:
        Removal affects only future executions. In-flight calls continue using
        the intercept chain they already resolved.
    )_native_deregister_llm_requestr   s    r   deregister_llm_requestr-      s     *$///r   c                 $    t          | ||          S )a  Register middleware around non-streaming LLM execution.

    Args:
        name: Unique intercept name used for later replacement or removal.
        priority: Execution order for the intercept. Lower values run first.
        fn: Callable invoked as ``fn(name, request, next_call)``. The callback
            may call ``next_call(request)`` to continue execution, modify the
            result, or short-circuit the provider call.

    Returns:
        None: This function returns after the intercept is registered.

    Notes:
        Execution intercepts wrap only non-streaming LLM execution. Use
        ``register_llm_stream_execution()`` for streaming callbacks.
    )_native_register_llm_executionr#   s      r   register_llm_executionr0      s    " *$"===r   c                      t          |           S )a  Remove a previously registered LLM execution intercept.

    Args:
        name: Intercept name previously passed to
            ``register_llm_execution()``.

    Returns:
        bool: ``True`` if an intercept was removed, otherwise ``False``.

    Notes:
        Removal affects only future executions. In-flight calls continue using
        the execution chain they already resolved.
    ) _native_deregister_llm_executionr   s    r   deregister_llm_executionr3      s     ,D111r   c                 $    t          | ||          S )a  Register middleware around streaming LLM execution.

    Args:
        name: Unique intercept name used for later replacement or removal.
        priority: Execution order for the intercept. Lower values run first.
        fn: Callable invoked as ``fn(request, next_call)`` that returns an
            async iterator of JSON chunks, either by delegating to
            ``next_call(request)`` or by replacing the stream entirely.

    Returns:
        None: This function returns after the intercept is registered.

    Notes:
        Streaming execution intercepts wrap chunk production only. They do not
        replace the separate collector or finalizer callbacks.
    )%_native_register_llm_stream_executionr#   s      r   register_llm_stream_executionr6     s    * 1xDDDr   c                      t          |           S )a  Remove a previously registered streaming LLM execution intercept.

    Args:
        name: Intercept name previously passed to
            ``register_llm_stream_execution()``.

    Returns:
        bool: ``True`` if an intercept was removed, otherwise ``False``.

    Notes:
        Removal affects only future executions. In-flight streams continue
        using the execution chain they already resolved.
    )'_native_deregister_llm_stream_executionr   s    r   deregister_llm_stream_executionr9     s     34888r   )r   r   r   r   r   r   r    r$   r'   r*   r-   r0   r3   r6   r9   )*__doc__
nemo_relayr   r   r   r   r   nemo_relay._nativer   r2   r	   r,   r
   r8   r   r&   r   r   r   r/   r   r)   r   r5   r   r"   r   r   strintboolr   r    r$   r'   r*   r-   r0   r3   r6   r9   __all__ r   r   <module>rB      sj   0                                                                J  Js  J  JK_  Jdh  J  J  J  JF1# 1$ 1 1 1 1 ?# ? ?:P ?UY ? ? ? ?*3C 3D 3 3 3 3,)Is )Ic )I )IJ] )Ibf )I )I )I )IX0 0 0 0 0 0 > > >9N >SW > > > >(23 24 2 2 2 2"E
EE 	$E 
	E E E E09# 9$ 9 9 9 9"  r   