
    i)                        S r SSKJr  SSKJr  SSKJr  SSKJrJ	r	  SSK
Jr  SSKJr  \(       a  SSKJrJr  SS	KJr  SS
K
Jr  SSKJr   " S S\5      rg)z%Tool emulator middleware for testing.    )annotations)TYPE_CHECKING)BaseChatModel)HumanMessageToolMessage)AgentMiddleware)init_chat_model)	AwaitableCallable)Command)ToolCallRequest)BaseToolc                  p   ^  \ rS rSrSrSSS.     S	U 4S jjjr      S
S jr      SS jrSrU =r	$ )LLMToolEmulator   a7  Emulates specified tools using an LLM instead of executing them.

This middleware allows selective emulation of tools for testing purposes.
By default (when tools=None), all tools are emulated. You can specify which
tools to emulate by passing a list of tool names or BaseTool instances.

Examples:
    Emulate all tools (default behavior):
    ```python
    from langchain.agents.middleware import LLMToolEmulator

    middleware = LLMToolEmulator()

    agent = create_agent(
        model="openai:gpt-4o",
        tools=[get_weather, get_user_location, calculator],
        middleware=[middleware],
    )
    ```

    Emulate specific tools by name:
    ```python
    middleware = LLMToolEmulator(tools=["get_weather", "get_user_location"])
    ```

    Use a custom model for emulation:
    ```python
    middleware = LLMToolEmulator(
        tools=["get_weather"], model="anthropic:claude-sonnet-4-5-20250929"
    )
    ```

    Emulate specific tools by passing tool instances:
    ```python
    middleware = LLMToolEmulator(tools=[get_weather, get_user_location])
    ```
N)toolsmodelc                 > [         TU ]  5         USL U l        [        5       U l        U R                  (       dc  Ub`  U HZ  n[        U[        5      (       a  U R                  R                  U5        M5  U R                  R                  UR                  5        M\     Uc  [        SSS9U l
        g[        U[        5      (       a  X l
        g[        USS9U l
        g)a{  Initialize the tool emulator.

Args:
    tools: List of tool names (str) or BaseTool instances to emulate.
        If None (default), ALL tools will be emulated.
        If empty list, no tools will be emulated.
    model: Model to use for emulation.
        Defaults to "anthropic:claude-sonnet-4-5-20250929".
        Can be a model identifier string or BaseChatModel instance.
Nz$anthropic:claude-sonnet-4-5-20250929   )temperature)super__init__emulate_allsettools_to_emulate
isinstancestraddnamer	   r   r   )selfr   r   tool	__class__s       c/home/james-whalen/.local/lib/python3.13/site-packages/langchain/agents/middleware/tool_emulator.pyr   LLMToolEmulator.__init__=   s      	 !D=*-%E$5dC(())--d3 ))--dii8  =()O]^_DJ}--J(A>DJ    c                   UR                   S   nU R                  =(       d    X0R                  ;   nU(       d  U" U5      $ UR                   S   nUR                  (       a  UR                  R                  OSnSU SU SU S3nU R
                  R                  [        U5      /5      n[        UR                  UR                   S   US	9$ )
aD  Emulate tool execution using LLM if tool should be emulated.

Args:
    request: Tool call request to potentially emulate.
    handler: Callback to execute the tool (can be called multiple times).

Returns:
    ToolMessage with emulated response if tool should be emulated,
    otherwise calls handler for normal execution.
r   argsNo description available;You are emulating a tool call for testing purposes.

Tool: 
Description: 
Arguments: 

Generate a realistic response that this tool would return given these arguments.
Return ONLY the tool's output, no explanation or preamble. Introduce variation into your responses.idcontenttool_call_idr   )
	tool_callr   r   r!   descriptionr   invoker   r   r/   	r    requesthandler	tool_nameshould_emulate	tool_argstool_descriptionpromptresponses	            r#   wrap_tool_callLLMToolEmulator.wrap_tool_calld   s     %%f-	 ))OY:O:O-O7## %%f-	7>||7<<33IcK  ,- .# %78 	 ::$$l6&:%;< $$ **40
 	
r%   c                  #    UR                   S   nU R                  =(       d    X0R                  ;   nU(       d  U" U5      I Sh  vN $ UR                   S   nUR                  (       a  UR                  R                  OSnSU SU SU S3nU R
                  R                  [        U5      /5      I Sh  vN n[        UR                  UR                   S	   US
9$  N N(7f)al  Async version of wrap_tool_call.

Emulate tool execution using LLM if tool should be emulated.

Args:
    request: Tool call request to potentially emulate.
    handler: Async callback to execute the tool (can be called multiple times).

Returns:
    ToolMessage with emulated response if tool should be emulated,
    otherwise calls handler for normal execution.
r   Nr'   r(   r)   r*   r+   r,   r-   r.   )
r1   r   r   r!   r2   r   ainvoker   r   r/   r4   s	            r#   awrap_tool_callLLMToolEmulator.awrap_tool_call   s     " %%f-	 ))OY:O:O-O ))) %%f-	7>||7<<33IcK  ,- .# %78 	 ++\&-A,BCC $$ **40
 	
- *& Ds%   AC!CA0C!6C7'C!C!)r   r   r   )r   zlist[str | BaseTool] | Noner   zstr | BaseChatModel | NonereturnNone)r5   r   r6   z2Callable[[ToolCallRequest], ToolMessage | Command]rC   ToolMessage | Command)r5   r   r6   z=Callable[[ToolCallRequest], Awaitable[ToolMessage | Command]]rC   rE   )
__name__
__module____qualname____firstlineno____doc__r   r=   rA   __static_attributes____classcell__)r"   s   @r#   r   r      s    $R .2,0	%? +%? *	%?
 
%? %?N0
 0
 D0
 
	0
d2
 2
 O2
 
	2
 2
r%   r   N)rJ   
__future__r   typingr   *langchain_core.language_models.chat_modelsr   langchain_core.messagesr   r   !langchain.agents.middleware.typesr   langchain.chat_models.baser	   collections.abcr
   r   langgraph.typesr   r   langchain.toolsr   r    r%   r#   <module>rW      s7    + "   D = = 63'A(r
o r
r%   