ó
    ýÞ j�5 ã            	      óâ  • S r SSKJr  SSKrSSKrSSKrSSKJrJr  SSK	J	r	J
r
  SSKJrJrJr  SSKJr  SSKJrJrJrJrJrJrJrJrJrJrJr  SS	KJrJrJ r J!r!J"r"J#r#  SS
K$J%r%J&r&J'r'  SSK(J)r)J*r*  SSK(J+r,  SSK-J.r.J/r/J0r0J1r1J2r2  SSK3J4r4J5r5  SSK6J7r7  SSK8J9r9  SSK:J;r;  SSK<J=r=  SSK>J?r?J@r@  SSKAJBrB  SSKCJDrDJErEJFrF  SSKGJHrHJIrI  SSKJJKrKJLrL  \(       a  SSKJMrM  SSK>JNrN  SSKOJPrP  \K" S\QS9rR\K" SSS9rSSrTSrUS rVS!rW " S" S#\S$S%9rX\ " S& S'5      5       rY\\Y\\Y/\"\D-  4   /\"\D-  4   rZ \\Y\\Y/\\"\D-     4   /\\"\D-     4   r[  " S( S)\5      r\S?S* jr] " S+ S,\/5      r^S@S- jr_      SAS. jr`SBS/ jra      SCS0 jrb\ " S1 S25      5       rc " S3 S4\75      rd SD     SES5 jjre\ " S6 S7\0\\S\R4   5      5       rf " S8 S9\*5      rg " S: S;\*5      rh      SFS< jri      SGS= jrjSHS> jrkg)Ia�  Tool execution node for LangGraph workflows.

This module provides prebuilt functionality for executing tools in LangGraph.

Tools are functions that models can call to interact with external systems,
APIs, databases, or perform computations.

The module implements design patterns for:

- Parallel execution of multiple tool calls for efficiency
- Robust error handling with customizable error messages
- State injection for tools that need access to graph state
- Store injection for tools that need persistent storage
- Command-based state updates for advanced control flow

Key Components:

- [`ToolNode`][langgraph.prebuilt.ToolNode]: Main class for executing tools in LangGraph workflows
- [`InjectedState`][langgraph.prebuilt.InjectedState]: Annotation for injecting graph state into tools
- [`InjectedStore`][langgraph.prebuilt.InjectedStore]: Annotation for injecting persistent store into tools
- [`ToolRuntime`][langgraph.prebuilt.ToolRuntime]: Runtime information for tools, bundling together `state`, `context`,
    `config`, `stream_writer`, `tool_call_id`, and `store`
- [`tools_condition`][langgraph.prebuilt.tools_condition]: Utility function for conditional routing based on tool calls

Typical Usage:
    ```python
    from langchain_core.tools import tool
    from langchain.tools import ToolNode


    @tool
    def my_tool(x: int) -> str:
        return f"Result: {x}"


    tool_node = ToolNode([my_tool])
    ```
é    )ÚannotationsN)Ú	AwaitableÚCallable)ÚcopyÚdeepcopy)Ú	dataclassÚfieldÚreplace)Ú	UnionType)ÚTYPE_CHECKINGÚ	AnnotatedÚAnyÚGenericÚLiteralÚ	TypedDictÚUnionÚcastÚget_argsÚ
get_originÚget_type_hints)Ú	AIMessageÚ
AnyMessageÚRemoveMessageÚToolCallÚToolMessageÚconvert_to_messages)ÚRunnableConfigÚget_config_listÚget_executor_for_config)ÚBaseToolÚInjectedToolArg)Útool)ÚTOOL_MESSAGE_BLOCK_TYPESÚToolExceptionÚ_DirectlyInjectedToolArgÚ_is_injected_arg_typeÚget_all_basemodel_annotations)ÚCONFÚCONFIG_KEY_READ)ÚRunnableCallable)ÚGraphBubbleUp)ÚREMOVE_ALL_MESSAGES)Ú_tool_call_writer)ÚExecutionInfoÚ
ServerInfo)Ú	BaseStore)ÚCommandÚSendÚStreamWriter)Ú	BaseModelÚValidationError)ÚTypeVarÚUnpack)ÚSequence)ÚRuntime)ÚErrorDetailsÚStateT)ÚdefaultÚContextTzLError: {requested_tool} is not a valid tool, try one of [{available_tools}].z)Error: {error}
 Please fix your mistakes.zvError executing tool '{tool_name}' with kwargs {tool_kwargs} with error:
 {error}
 Please fix the error and try again.zuError invoking tool '{tool_name}' with kwargs {tool_kwargs} with error:
 {error}
 Please fix the error and try again.c                  ó8   • \ rS rSr% SrS\S'   S\S'   S\S'   S	rg
)Ú_ToolCallRequestOverridesé|   z9Possible overrides for ToolCallRequest.override() method.r   Ú	tool_callr    r"   r   Ústate© N©Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__Ú__static_attributes__rC   ó    ÚV/var/www/html/gaurav/venv/lib/python3.13/site-packages/langgraph/prebuilt/tool_node.pyr?   r?   |   s   ‡ ÙCàÓØ
ƒNØ†JrL   r?   F)Útotalc                  ó^   • \ rS rSr% SrS\S'   S\S'   S\S'   S	\S
'   SS jr    SS jrSrg)ÚToolCallRequesté„   aB  Tool execution request passed to tool call interceptors.

Attributes:
    tool_call: Tool call dict with name, args, and id from model output.
    tool: BaseTool instance to be invoked, or None if tool is not
        registered with the `ToolNode`. When tool is `None`, interceptors can
        handle the request without validation. If the interceptor calls `execute()`,
        validation will occur and raise an error for unregistered tools.
    state: Agent state (`dict`, `list`, or `BaseModel`).
    runtime: LangGraph runtime context (optional, `None` if outside graph).
r   rA   úBaseTool | Noner"   r   rB   ÚToolRuntimeÚruntimec                óÚ   • SSK n[        U S5      (       a  [        X5      (       d  [        R                  XU5        gUR	                  SU S3[
        SS9  [        R                  XU5        g)z�Raise deprecation warning when setting attributes directly.

Direct attribute assignment is deprecated. Use the `override()` method instead.
r   NÚ__dataclass_fields__zSetting attribute 'zt' on ToolCallRequest is deprecated. Use the override() method instead to create a new instance with modified values.é   )Ú
stacklevel)ÚwarningsÚhasattrÚobjectÚ__setattr__ÚwarnÚDeprecationWarning)ÚselfÚnameÚvaluerY   s       rM   r\   ÚToolCallRequest.__setattr__—   sm   € ó
 	ô �tÐ3×4Ñ4¼GÀD×<OÑ<OÜ×Ñ˜t¨5Õ1à�M‰MØ% d Vð ,cð cä"Øð	 ñ ô ×Ñ˜t¨5Õ1rL   c                ó   • [        U 40 UD6$ )aU  Replace the request with a new request with the given overrides.

Returns a new `ToolCallRequest` instance with the specified attributes replaced.
This follows an immutable pattern, leaving the original request unchanged.

Args:
    **overrides: Keyword arguments for attributes to override.

        Supported keys:

        - tool_call: Tool call dict with `name`, `args`, and `id`
        - state: Agent state (`dict`, `list`, or `BaseModel`)

Returns:
    New ToolCallRequest instance with specified overrides applied.

Examples:
    ```python
    # Modify tool call arguments without mutating original
    modified_call = {**request.tool_call, "args": {"value": 10}}
    new_request = request.override(tool_call=modified_call)

    # Override multiple attributes
    new_request = request.override(tool_call=modified_call, state=new_state)
    ```
)r
   )r_   Ú	overridess     rM   ÚoverrideÚToolCallRequest.overrideª   s   € ô: �tÑ)˜yÑ)Ð)rL   rC   N)r`   Ústrra   r   ÚreturnÚNone)rd   z!Unpack[_ToolCallRequestOverrides]rh   rP   )	rE   rF   rG   rH   rI   rJ   r\   re   rK   rC   rL   rM   rP   rP   „   s:   ‡ ñ
ð ÓØ
ÓØƒJØÓô2ð&*Ø<ð*à	÷*rL   rP   c                  ó:   • \ rS rSr% SrS\S'   S\S'    S\S'   S	rg
)ÚToolCallWithContexti  a}  ToolCall with additional context for graph state.

This is an internal data structure meant to help the `ToolNode` accept
tool calls with additional context (e.g. state) when dispatched using the
Send API.

The Send API is used in create_agent to distribute tool calls in parallel
and support human-in-the-loop workflows where graph execution may be paused
for an indefinite time.
r   rA   z!Literal['tool_call_with_context']Ú_ToolCallWithContext__typer   rB   rC   NrD   rC   rL   rM   rk   rk     s$   ‡ ñ	ð ÓØ-Ó-ðð
 ƒJÚ6rL   rk   c                óê   • [        U [        5      (       d,  [        U [        5      (       a  [        S U  5       5      (       a  U $  [        R
                  " U SS9$ ! [         a    [        U 5      s $ f = f)a<  Convert tool output to `ToolMessage` content format.

Handles `str`, `list[dict]` (content blocks), and arbitrary objects by attempting
JSON serialization with fallback to str().

Args:
    output: Tool execution output of any type.

Returns:
    String or list of content blocks suitable for `ToolMessage.content`.
c              3  ó~   #   • U H4  n[        U[        5      =(       a    UR                  S 5      [        ;   v •  M6     g7f)ÚtypeN)Ú
isinstanceÚdictÚgetr#   )Ú.0Úxs     rM   Ú	<genexpr>Ú%msg_content_output.<locals>.<genexpr>C  s4   é € ð 
á�ô �qœ$Ó×M A§E¡E¨&£MÔ5MÑ$MÔMÚùs   ‚;=F)Úensure_ascii)rp   rg   ÚlistÚallÚjsonÚdumpsÚ	Exception)Úoutputs    rM   Úmsg_content_outputr~   5  sn   € ô �&œ#×ÑÜ�6œ4× Ñ Üñ 
áó
÷ 
ñ 
ð
 ˆð
Ü�zŠz˜&¨uÑ5Ð5øÜó Ü�6‹{Òðús   ÁA ÁA2Á1A2c                  óH   ^ • \ rS rSrSr S         SU 4S jjjrSrU =r$ )ÚToolInvocationErroriS  zŒAn error occurred while invoking a tool due to invalid arguments.

This exception is only raised when invoking a tool using the `ToolNode`!
c                ó�  >• Ubm  / nU HS  nSR                  S UR                  SS5       5       5      nUR                  SS5      nUR                  U SU 35        MU     S	R                  U5      n	O[        U5      n	[        R                  XU	S
9U l        Xl        X0l        X l	        X@l
        [        T
U ]1  U R                  5        g)a1  Initialize the ToolInvocationError.

Args:
    tool_name: The name of the tool that failed.
    source: The exception that occurred.
    tool_kwargs: The keyword arguments that were passed to the tool.
    filtered_errors: Optional list of filtered validation errors excluding
        injected arguments.
NÚ.c              3  ó6   #   • U H  n[        U5      v •  M     g 7f©N)rg   )rs   Úlocs     rM   ru   Ú/ToolInvocationError.__init__.<locals>.<genexpr>n  s   é € Ð"LÑ7K°¤3 s§8 8Ò7Kùs   ‚r…   rC   ÚmsgzUnknown errorz: Ú
)Ú	tool_nameÚtool_kwargsÚerror)Újoinrr   Úappendrg   ÚTOOL_INVOCATION_ERROR_TEMPLATEÚformatÚmessager‰   rŠ   ÚsourceÚfiltered_errorsÚsuperÚ__init__)r_   r‰   r‘   rŠ   r’   Úerror_str_partsr‹   Úloc_strr‡   Úerror_display_strÚ	__class__s             €rM   r”   ÚToolInvocationError.__init__Y  sÃ   ø€ ð" Ñ&à ˆOÛ(�ØŸ(™(Ñ"L°u·y±yÀÈÔ7KÓ"LÓL�Ø—i‘i  Ó7�Ø×&Ñ&¨'¨°"°S°EÐ':Ö;ñ )ð !%§	¡	¨/Ó :Ñä # F£Ðä5×<Ñ<ØÐ@Qð =ð 
ˆŒð #ŒØ&ÔØŒØ.ÔÜ‰Ñ˜Ÿ™Õ&rL   )r’   r�   r‘   rŠ   r‰   r„   )
r‰   rg   r‘   r5   rŠ   údict[str, Any]r’   zlist[ErrorDetails] | Nonerh   ri   )rE   rF   rG   rH   rI   r”   rK   Ú__classcell__©r˜   s   @rM   r€   r€   S  sG   ø† ñð 6:ð#'àð#'ð  ð#'ð $ð	#'ð
 3ð#'ð 
÷#'ö #'rL   r€   c                óH   • [        U [        5      (       a  U R                  $ U e)z€Default error handler for tool errors.

If the tool is a tool invocation error, return its message.
Otherwise, raise the error.
)rp   r€   r�   )Úes    rM   Ú_default_handle_tool_errorsrŸ     s!   € ô �!Ô(×)Ñ)Ø�y‰yÐØ
€GrL   c               óN  • [        U[        [        45      (       d*  [        U[        5      (       a3  [	        U[
        5      (       a  [        R                  [        U 5      S9nU$ [        U[        5      (       a  UnU$ [        U5      (       a
  U" U 5      nU$ SU 3n[        U5      e)a|  Generate error message content based on exception handling configuration.

This function centralizes error message generation logic, supporting different
error handling strategies configured via the `ToolNode`'s `handle_tool_errors`
parameter.

Args:
    e: The exception that occurred during tool execution.
    flag: Configuration for how to handle the error. Can be:
        - bool: If `True`, use default error template
        - str: Use this string as the error message
        - Callable: Call this function with the exception to get error message
        - tuple: Not used in this context (handled by caller)

Returns:
    A string containing the error message to include in the `ToolMessage`.

Raises:
    ValueError: If flag is not one of the supported types.

!!! note
    The tuple case is handled by the caller through exception type checking,
    not by this function directly.
)r‹   zVGot unexpected type of `handle_tool_error`. Expected bool, str or callable. Received: )rp   ÚboolÚtuplero   Ú
issubclassr|   ÚTOOL_CALL_ERROR_TEMPLATEr�   Úreprrg   ÚcallableÚ
ValueError)rž   ÚflagÚcontentr‡   s       rM   Ú_handle_tool_errorrª   Š  s£   € ôB �$œœu˜×&Ñ&Ü�4œ×Ñ¤:¨d´I×#>Ñ#>ä*×1Ñ1¼¸Q»Ð1Ð@ˆð €Nô 
�Dœ#×	Ñ	Øˆð €Nô 
�$�‰Ù�q“'ˆð €Nð	&Ø&* Vð-ð 	ô ˜‹oÐrL   c                óz  • [         R                  " U 5      n[        UR                  R	                  5       5      nU(       aõ  US   R
                  S;   a  [        U5      S:X  a  US   nOUS   n[        U 5      nUR
                  U;   a­  [        UR                  5      nU[        [        4;   aR  [        UR                  5      n[        S U 5       5      (       a  [        U5      $ SUR                   S3n[        U5      eXCR
                     n[         UR"                  ;   a  U4$ SU S3n[        U5      e[         4$ )	aä  Infer exception types handled by a custom error handler function.

This function analyzes the type annotations of a custom error handler to determine
which exception types it's designed to handle. This enables type-safe error handling
where only specific exceptions are caught and processed by the handler.

Args:
    handler: A callable that takes an exception and returns an error message string.
            The first parameter (after self/cls if present) should be type-annotated
            with the exception type(s) to handle.

Returns:
    A tuple of exception types that the handler can process. Returns (Exception,)
    if no specific type information is available for backward compatibility.

Raises:
    ValueError: If the handler's annotation contains non-Exception types or
        if Union types contain non-Exception types.

!!! note
    This function supports both single exception types and Union types for
    handlers that need to handle multiple exception types differently.
r   )r_   ÚclsrW   é   c              3  ó@   #   • U H  n[        U[        5      v •  M     g 7fr„   )r£   r|   )rs   Úargs     rM   ru   Ú'_infer_handled_types.<locals>.<genexpr>â  s   é € ÐB¹T°c”z #¤y×1Ð1ºTùó   ‚z’All types in the error handler error annotation must be Exception types. For example, `def custom_handler(e: Union[ValueError, TypeError])`. Got 'z
' instead.a  Arbitrary types are not supported in the error handler signature. Please annotate the error with either a specific Exception type or a union of Exception types. For example, `def custom_handler(e: ValueError)` or `def custom_handler(e: Union[ValueError, TypeError])`. Got ')ÚinspectÚ	signaturerx   Ú
parametersÚvaluesr`   Úlenr   r   Ú
annotationr   r   r   ry   r¢   r§   r|   Ú__mro__)	ÚhandlerÚsigÚparamsÚfirst_paramÚ
type_hintsÚoriginÚargsr‡   Úexception_types	            rM   Ú_infer_handled_typesrÁ   ¼  s:  € ô0 ×
Ò
˜GÓ
$€CÜ�#—.‘.×'Ñ'Ó)Ó*€FÞà�!‰9�>‰>˜_Ó,´°V³ÀÓ1AØ  ™)‰Kà  ™)ˆKä# GÓ,ˆ
Ø×Ñ˜zÓ)Ü × 6Ñ 6Ó7ˆFØœ%¤Ð+Ó+Ü × 6Ñ 6Ó7�ÜÑB¹TÓB×BÑBÜ  ›;Ð&ðð (×2Ñ2Ð3°:ð?ð ô ! “oÐ%à'×(8Ñ(8Ñ9ˆNÜ˜N×2Ñ2Ó2Ø&Ð(Ð(ðð
 'Ð' zð3ð ô ˜S“/Ð!ô ˆ<ÐrL   c                ó–  • [        5       nU(       a’  UR                  (       a)  UR                  UR                  R                  5       5        UR                  (       a  UR                  UR                  5        UR                  (       a  UR                  UR                  5        / nU R                  5        H‰  nUS   (       d  M  US   S   U;  d  M  0 UEn[        UR                  S5      [        5      (       a3  US   nUR                  5        VVs0 sH  u  pxXr;  d  M  Xx_M     n	nnX•S'   UR                  U5        M‹     U$ s  snnf )a¯  Filter validation errors to only include LLM-controlled arguments.

When a tool invocation fails validation, only errors for arguments that the LLM
controls should be included in error messages. This ensures the LLM receives
focused, actionable feedback about parameters it can actually fix. System-injected
arguments (state, store, runtime) are filtered out since the LLM has no control
over them.

This function also removes injected argument values from the `input` field in error
details, ensuring that only LLM-provided arguments appear in error messages.

Args:
    validation_error: The Pydantic ValidationError raised during tool invocation.
    injected_args: The _InjectedArgs structure containing all injected arguments,
        or None if there are no injected arguments.

Returns:
    List of ErrorDetails containing only errors for LLM-controlled arguments,
    with system-injected argument values removed from the input field.
r…   r   Úinput)ÚsetrB   ÚupdateÚkeysÚstoreÚaddrT   Úerrorsrp   rr   rq   Úitemsr�   )
Úvalidation_errorÚinjected_argsÚinjected_arg_namesr’   r‹   Ú
error_copyÚ
input_dictÚkÚvÚ
input_copys
             rM   Ú_filter_validation_errorsrÓ   þ  s%  € ô2 $'£5ÐÞØ××Ø×%Ñ% m×&9Ñ&9×&>Ñ&>Ó&@ÔAØ××Ø×"Ñ" =×#6Ñ#6Ô7Ø× × Ø×"Ñ" =×#8Ñ#8Ô9à*,€OØ!×(Ñ(Ö*ˆð ��<‰<˜E %™L¨™OÐ3EÕEà)2¨E¨ˆJô ˜*Ÿ.™.¨Ó1´4×8Ñ8Ø'¨Ñ0�
à%/×%5Ñ%5Ô%7ôÙ%7™T˜Q¸1Ñ;V“D�A’DÑ%7ð ñ ð '1˜7Ñ#ð ×"Ñ" :Ö.ñ! +ð$ Ðùós   Ä
EÄ!Ec                  óL   • \ rS rSr% SrS\S'   S\S'   S\S'   S\S	'   S\S
'   Srg)Ú_InjectedArgsi6  a³  Internal structure for tracking injected arguments for a tool.

This data structure is built once during ToolNode initialization by analyzing
the tool's signature and args schema, then reused during execution for efficient
injection without repeated reflection.

The structure maps from tool parameter names to their injection sources, enabling
the ToolNode to know exactly which arguments need to be injected and where to
get their values from.

Attributes:
    state: Mapping from tool parameter names to state field names for injection.
        Keys are tool parameter names, values are either:
        - str: Name of the state field to extract and inject
        - None: Inject the entire state object
        Empty dict if no state injection is needed.
    store: Name of the tool parameter where the store should be injected,
        or None if no store injection is needed.
    runtime: Name of the tool parameter where the runtime should be injected,
        or None if no runtime injection is needed.

Example:
    For a tool with signature:
    ```python
    def my_tool(
        x: int,
        messages: Annotated[list, InjectedState("messages")],
        full_state: Annotated[dict, InjectedState()],
        store: Annotated[BaseStore, InjectedStore()],
        runtime: ToolRuntime,
    ) -> str:
        ...
    ```

    The resulting `_InjectedArgs` would be:
    ```python
    _InjectedArgs(
        state={
            "messages": "messages",  # Extract state["messages"]
            "full_state": None,      # Inject entire state
        },
        store="store",               # Inject into "store" parameter
        runtime="runtime",           # Inject into "runtime" parameter
    )
    ```
zdict[str, str | None]rB   ú
str | NonerÇ   rT   zset[str]Úall_injected_keysÚ_optional_state_argsrC   NrD   rC   rL   rM   rÕ   rÕ   6  s(   ‡ ñ-ð^ !Ó ØÓØÓØÓØ"Ö"rL   rÕ   c                  óÞ  ^ • \ rS rSr% SrSrS\S'   SS\SSSS.               SU 4S	 jjjr\	SS
 j5       r
        SS jr        SS jr      SS jr        S S jr        S!S jr        S S jr        S!S jr    S"S jrS#S jr      S$S jr S%       S&S jjr        S'S jr        S(S jrSS.         S)S jjrSrU =r$ )*ÚToolNodein  uŠ  A node for executing tools in LangGraph workflows.

Handles tool execution patterns including function calls, state injection,
persistent storage, and control flow. Manages parallel execution,
error handling.

Use `ToolNode` when building custom workflows that require fine-grained control over
tool executionâ€”for example, custom routing logic, specialized error handling, or
non-standard agent architectures.

For standard ReAct-style agents, use [`create_agent`][langchain.agents.create_agent]
instead. It uses `ToolNode` internally with sensible defaults for the agent loop,
conditional routing, and error handling.

Input Formats:
    1. **Graph state** with `messages` key that has a list of messages:
        - Common representation for agentic workflows
        - Supports custom messages key via `messages_key` parameter

    2. **Message List**: `[AIMessage(..., tool_calls=[...])]`
        - List of messages with tool calls in the last AIMessage

    3. **Direct Tool Calls**: `[{"name": "tool", "args": {...}, "id": "1", "type": "tool_call"}]`
        - Bypasses message parsing for direct tool execution
        - For programmatic tool invocation and testing

Output Formats:
    Output format depends on input type and tool behavior:

    **For Regular tools**:

    - Dict input â†’ `{"messages": [ToolMessage(...)]}`
    - List input â†’ `[ToolMessage(...)]`

    **For Command tools**:

    - Returns `[Command(...)]` or mixed list with regular tool outputs
    - `Command` can update state, trigger navigation, or send messages

Args:
    tools: A sequence of tools that can be invoked by this node.

        Supports:

        - **BaseTool instances**: Tools with schemas and metadata
        - **Plain functions**: Automatically converted to tools with inferred schemas

    name: The name identifier for this node in the graph. Used for debugging
        and visualization.
    tags: Optional metadata tags to associate with the node for filtering
        and organization.
    handle_tool_errors: Configuration for error handling during tool execution.
        Supports multiple strategies:

        - `True`: Catch all errors and return a `ToolMessage` with the default
            error template containing the exception details.
        - `str`: Catch all errors and return a `ToolMessage` with this custom
            error message string.
        - `type[Exception]`: Only catch exceptions with the specified type and
            return the default error message for it.
        - `tuple[type[Exception], ...]`: Only catch exceptions with the specified
            types and return default error messages for them.
        - `Callable[..., str]`: Catch exceptions matching the callable's signature
            and return the string result of calling it with the exception.
        - `False`: Disable error handling entirely, allowing exceptions to
            propagate.

        Defaults to a callable that:

        - Catches tool invocation errors (due to invalid arguments provided by the
            model) and returns a descriptive error message
        - Ignores tool execution errors (they will be re-raised)

    messages_key: The key in the state dictionary that contains the message list.
        This same key will be used for the output `ToolMessage` objects.

        Allows custom state schemas with different message field names.

Examples:
    Basic usage:

    ```python
    from langchain.tools import ToolNode
    from langchain_core.tools import tool

    @tool
    def calculator(a: int, b: int) -> int:
        """Add two numbers."""
        return a + b

    tool_node = ToolNode([calculator])
    ```

    State injection:

    ```python
    from typing_extensions import Annotated
    from langchain.tools import InjectedState

    @tool
    def context_tool(query: str, state: Annotated[dict, InjectedState]) -> str:
        """Some tool that uses state."""
        return f"Query: {query}, Messages: {len(state['messages'])}"

    tool_node = ToolNode([context_tool])
    ```

    Error handling:

    ```python
    def handle_errors(e: ValueError) -> str:
        return "Invalid input provided"


    tool_node = ToolNode([my_tool], handle_tool_errors=handle_errors)
    ```
Útoolsrg   r`   NÚmessages)r`   ÚtagsÚhandle_tool_errorsÚmessages_keyÚwrap_tool_callÚawrap_tool_callc               óz  >• [         T
U ]  U R                  U R                  X#SS9  0 U l        0 U l        X@l        XPl        X`l        Xpl	        U Hj  n[        U[        5      (       d  [        [        SU5      5      n	OUn	X�R                  U	R                  '   [        U	5      U R
                  U	R                  '   Ml     g)a¬  Initialize `ToolNode` with tools and configuration.

Args:
    tools: Sequence of tools to make available for execution.
    name: Node name for graph identification.
    tags: Optional metadata tags.
    handle_tool_errors: Error handling configuration.
    messages_key: State key containing messages.
    wrap_tool_call: Sync wrapper function to intercept tool execution. Receives
        ToolCallRequest and execute callable, returns ToolMessage or Command.
        Enables retries, caching, request modification, and control flow.
    awrap_tool_call: Async wrapper function to intercept tool execution.
        If not provided, falls back to wrap_tool_call for async execution.
F)r`   rÝ   Útraceztype[BaseTool]N)r“   r”   Ú_funcÚ_afuncÚ_tools_by_nameÚ_injected_argsÚ_handle_tool_errorsÚ_messages_keyÚ_wrap_tool_callÚ_awrap_tool_callrp   r    Úcreate_toolr   r`   Ú_get_all_injected_args)r_   rÛ   r`   rÝ   rÞ   rß   rà   rá   r"   Útool_r˜   s             €rM   r”   ÚToolNode.__init__ç  s¤   ø€ ô: 	‰Ñ˜Ÿ™ T§[¡[°tÈeÐÑTØ35ˆÔØ8:ˆÔØ#5Ô Ø)ÔØ-ÔØ /ÔÛˆDÜ˜d¤H×-Ñ-Ü#¤DÐ)9¸4Ó$@ÓA‘à�Ø.3×Ñ §
¡
Ñ+ä.DÀUÓ.KˆD×Ñ §
¡
Ó+ò rL   c                ó   • U R                   $ )z,Mapping from tool name to BaseTool instance.)ræ   )r_   s    rM   Útools_by_nameÚToolNode.tools_by_name  s   € ð ×"Ñ"Ð"rL   c                óf  • U R                  U5      u  pE[        U[        U5      5      n/ n[        XFSS9 HŽ  u  p‰U R	                  X5      n
[        U
US   U	UR                  UR                  UR                  [        U R                  R                  5       5      UR                  UR                  S9	nUR                  U5        M�     U/[        U5      -  n[        U5       n[        UR!                  U R"                  XLU5      5      nS S S 5        U R%                  WU5      $ ! , (       d  f       N = f©NF)ÚstrictÚid)	rB   Útool_call_idÚconfigÚcontextrÇ   Ústream_writerrÛ   Úexecution_infoÚserver_info)Ú_parse_inputr   r¶   ÚzipÚ_extract_staterS   rù   rÇ   rú   rx   rñ   rµ   rû   rü   r�   r   ÚmapÚ_run_oneÚ_combine_tool_outputs)r_   rÃ   rø   rT   Ú
tool_callsÚ
input_typeÚconfig_listÚtool_runtimesÚcallÚcfgrB   Útool_runtimeÚinput_typesÚexecutorÚoutputss                  rM   rä   ÚToolNode._func  s  € ð "&×!2Ñ!2°5Ó!9Ñˆ
Ü% f¬c°*«oÓ>ˆð ˆÜ˜Z¸UÔC‰IˆDØ×'Ñ'¨Ó3ˆEÜ&ØØ! $™ZØØŸ™Ø—m‘mØ%×3Ñ3Ü˜4×-Ñ-×4Ñ4Ó6Ó7Ø&×5Ñ5Ø#×/Ñ/ñ
ˆLð × Ñ  Ö.ñ Dð  "�l¤S¨£_Ñ4ˆÜ$ VÔ,°ÜØ—‘˜TŸ]™]¨JÀ]ÓSóˆG÷ -ð
 ×)Ñ)¨'°:Ó>Ð>÷ -Õ,ús   Ã!'D"Ä"
D0c              ƒ  ó^  #   • U R                  U5      u  pE[        U[        U5      5      n/ n[        XFSS9 HŽ  u  p‰U R	                  X5      n
[        U
US   U	UR                  UR                  UR                  [        U R                  R                  5       5      UR                  UR                  S9	nUR                  U5        M�     / n[        XGSS9 H&  u  p‹UR                  U R                  X…U5      5        M(     [         R"                  " U6 I S h  v•N nU R%                  XÕ5      $  N7frô   )rý   r   r¶   rþ   rÿ   rS   rù   rÇ   rú   rx   rñ   rµ   rû   rü   r�   Ú	_arun_oneÚasyncioÚgatherr  )r_   rÃ   rø   rT   r  r  r  r  r  r  rB   r	  Úcorosr  s                 rM   rå   ÚToolNode._afunc<  s  é € ð "&×!2Ñ!2°5Ó!9Ñˆ
Ü% f¬c°*«oÓ>ˆð ˆÜ˜Z¸UÔC‰IˆDØ×'Ñ'¨Ó3ˆEÜ&ØØ! $™ZØØŸ™Ø—m‘mØ%×3Ñ3Ü˜4×-Ñ-×4Ñ4Ó6Ó7Ø&×5Ñ5Ø#×/Ñ/ñ
ˆLð × Ñ  Ö.ñ Dð  ˆÜ"% jÈÔ"NÑˆDØ�L‰L˜Ÿ™¨¸,ÓGÖHñ #OäŸš¨Ð.×.ˆà×)Ñ)¨'Ó>Ð>ñ /ùs   ‚DD-ÄD+ÄD-c                ó†  • [        S U 5       5      (       aE  / nU H<  n[        U[        5      (       a  UR                  U5        M+  UR	                  U5        M>     O[        SU5      n[        S U 5       5      (       d  US:X  a  U$ U R                  U0$ / nS nU GH  n[        U[        5      (       aÈ  UR                  [        R                  L a˜  [        UR                  [        5      (       ay  [        S UR                   5       5      (       aX  U(       a-  [        U[        SUR                  5      UR                  -   S9nMª  [        [        R                  UR                  S9nMÎ  UR	                  U5        Má  UR	                  US:X  a  U/OU R                  U/05        GM     U(       a  UR	                  U5        U$ )	Nc              3  ó@   #   • U H  n[        U[        5      v •  M     g 7fr„   )rp   rx   ©rs   r}   s     rM   ru   Ú1ToolNode._combine_tool_outputs.<locals>.<genexpr>e  s   é € Ð>±g¨FŒz˜&¤$×'Ð'²gùr±   zlist[ToolMessage | Command]c              3  ó@   #   • U H  n[        U[        5      v •  M     g 7fr„   )rp   r1   r  s     rM   ru   r  q  s   é € ÐJ¹\°6”:˜f¤g×.Ð.º\ùr±   rx   c              3  ó@   #   • U H  n[        U[        5      v •  M     g 7fr„   )rp   r2   )rs   Úsends     rM   ru   r  †  s   é € ÐK¹{°tœJ t¬T×2Ð2º{ùr±   z
list[Send])Úgoto)Úgraphr  )Úanyrp   rx   Úextendr�   r   ré   r1   r  ÚPARENTr  ry   r
   )r_   r  r  Úflat_outputsr}   Úcombined_outputsÚparent_commands          rM   r  ÚToolNode._combine_tool_outputs^  s†  € ô Ñ>±gÓ>×>Ñ>ØˆLÛ!�Ü˜f¤d×+Ñ+Ø ×'Ñ'¨Ö/à ×'Ñ'¨Ö/ò	 "ô  Ð =¸wÓGˆLô ÑJ¹\ÓJ×JÑJð  Ó'ð ðð ×(Ñ(¨,Ð7ðð ð 	ð
 *.ˆÜ"ˆFÜ˜&¤'×*Ñ*à—L‘L¤G§N¡NÒ2Ü" 6§;¡;´×5Ñ5ÜÑK¸v¿{º{ÓK×KÑKæ%Ü)0Ø*Ü!% l°N×4GÑ4GÓ!HÈ6Ï;É;Ñ!Vñ*šô
 *1´w·~±~ÈFÏKÉKÑ)Xšà$×+Ñ+¨FÖ3à ×'Ñ'Ø *¨fÓ 4�V‘H¸4×;MÑ;MÐPVÈxÐ:X÷ñ# #ö* Ø×#Ñ# NÔ3ØÐrL   c                óF  • UR                   nUR                  nUc.  U R                  U5      =n(       a  U$ SUS    S3n[        U5      eU R	                  XAR
                  U5      n0 UESS0En	  UR                  X“5      n
U R                  X¡R                   U5      $ ! [         aB  nU R                  R                  US   5      n[        X¼5      n[        US   X´S   U5      UeSnAff = f! [         a    e [         Ga  n[        U R                   ["        5      (       a-  [%        U R                   [        5      (       a  U R                   4nO‚[        U R                   [&        5      (       a  U R                   nOV[)        U R                   5      (       a5  [        U R                   ["        5      (       d  [+        U R                   5      nO[        4nU R                   (       a  [        Xï5      (       d  e [-        XàR                   S9n[/        UUS   US	   S
S9s SnA$ SnAff = f)a+  Execute tool call with configured error handling.

Args:
    request: Tool execution request.
    input_type: Input format.
    config: Runnable configuration.

Returns:
    ToolMessage, Command, or list of Command/ToolMessage.

Raises:
    Exception: If tool fails and handle_tool_errors is False.
NúTool r`   ú  is not registered with ToolNodero   rA   r¿   ©r¨   rö   r‹   ©r©   r`   r÷   Ústatus)rA   r"   Ú_validate_tool_callÚ	TypeErrorÚ_inject_tool_argsrT   Úinvoker5   rç   rr   rÓ   r€   Ú_normalize_tool_responser+   r|   rp   rè   ro   r£   r¢   r¦   rÁ   rª   r   ©r_   Úrequestr  rø   r  r"   Úinvalid_tool_messager‡   Úinjected_callÚ	call_argsÚresponseÚexcÚinjectedr’   rž   Úhandled_typesr©   s                    rM   Ú_execute_tool_syncÚToolNode._execute_tool_syncš  s  € ð& × Ñ ˆØ�|‰|ˆð ‰<Ø'+×'?Ñ'?ÀÓ'EÐEÐ#ÕEØ+Ð+à˜$˜v™,˜Ð'GÐHˆCÜ˜C“.Ð ð ×.Ñ.¨t·_±_ÀdÓKˆØ:�}Ð: f¨kÑ:ˆ	ð8	ð	ØŸ;™; yÓ9�ð ×0Ñ0Ø×+Ñ+¨Zóð øô #ó à×.Ñ.×2Ñ2°4¸±<Ó@�Ü";¸CÓ"J�ä)Ø˜‘L #¨F¡|°_óàðûðûô. ó 	ØÜô 	ô ˜$×2Ñ2´D×9Ñ9¼jØ×(Ñ(¬)÷?ñ ?ð "&×!9Ñ!9Ð ;‘Ü˜D×4Ñ4´e×<Ñ<Ø $× 8Ñ 8‘Ü˜$×2Ñ2×3Ñ3¼JØ×(Ñ(¬$÷=ñ =ô !5°T×5MÑ5MÓ N‘ô "+ �ð ×+×+´:¸a×3OÑ3OØô )¨×1IÑ1IÑJˆGÜØØ˜&‘\Ø! $™ZØñ	õ ûð/	ús=   Á0B ÂC, Â
C)Â'=C$Ã$C)Ã)C, Ã,H ÄDHÈH ÈH c                óÆ  ^ ^^	• T R                   R                  US   5      n[        UUUR                  US9nUR                  m	T R
                  c  T R                  UTT	5      $ S	U	UU 4S jjn T R                  XV5      $ ! [         aV  nT R                  (       d  e [        UT R                  S9n[        UUR                  S   UR                  S   SS9s SnA$ SnAff = f)
zÉExecute single tool call with wrap_tool_call wrapper if configured.

Args:
    call: Tool call dict.
    input_type: Input format.
    tool_runtime: Tool runtime.

Returns:
    ToolMessage or Command.
r`   ©rA   r"   rB   rT   Nc                ó*   >• TR                  U TT5      $ )ú>Execute tool with given request. Can be called multiple times.©r8  ©Úreqrø   r  r_   s    €€€rM   ÚexecuteÚ"ToolNode._run_one.<locals>.execute  ó   ø€ à×*Ñ*¨3°
¸FÓCÐCrL   r'  rö   r‹   r(  ©r@  rP   rh   zToolMessage | Command)rñ   rr   rP   rB   rø   rê   r8  r|   rè   rª   r   rA   )
r_   r  r  r	  r"   Útool_requestrA  rž   r©   rø   s
   ` `      @rM   r  ÚToolNode._run_oneö  sê   ú€ ð$ ×!Ñ!×%Ñ% d¨6¡lÓ3ˆô 'ØØØ×$Ñ$Ø ñ	
ˆð ×$Ñ$ˆà×ÑÑ'à×*Ñ*¨<¸ÀVÓLÐL÷	Dñ 	Dð
	Ø×'Ñ'¨Ó>Ð>øÜó 	à×+×+Øä(¨°×1IÑ1IÑJˆGÜØØ!×+Ñ+¨FÑ3Ø)×3Ñ3°DÑ9Øñ	õ ûð	ús   Á/B  Â 
C Â
ACÃC ÃC c              ƒ  ób  #   • UR                   nUR                  nUc.  U R                  U5      =n(       a  U$ SUS    S3n[        U5      eU R	                  XAR
                  U5      n0 UESS0En	  UR                  X“5      I Sh  v•N n
U R                  X¡R                   U5      $  N ! [         aB  nU R                  R                  US   5      n[        X¼5      n[        US   X´S   U5      UeSnAff = f! [         a    e [         Ga  n[        U R                   ["        5      (       a-  [%        U R                   [        5      (       a  U R                   4nO‚[        U R                   [&        5      (       a  U R                   nOV[)        U R                   5      (       a5  [        U R                   ["        5      (       d  [+        U R                   5      nO[        4nU R                   (       a  [        Xï5      (       d  e [-        XàR                   S9n[/        UUS   US	   S
S9s SnA$ SnAff = f7f)a:  Execute tool call asynchronously with configured error handling.

Args:
    request: Tool execution request.
    input_type: Input format.
    config: Runnable configuration.

Returns:
    ToolMessage, Command, or list of Command/ToolMessage.

Raises:
    Exception: If tool fails and handle_tool_errors is False.
Nr%  r`   r&  ro   rA   r¿   r'  rö   r‹   r(  )rA   r"   r*  r+  r,  rT   Úainvoker5   rç   rr   rÓ   r€   r.  r+   r|   rp   rè   ro   r£   r¢   r¦   rÁ   rª   r   r/  s                    rM   Ú_execute_tool_asyncÚToolNode._execute_tool_async-  s  é € ð& × Ñ ˆØ�|‰|ˆð ‰<Ø'+×'?Ñ'?ÀÓ'EÐEÐ#ÕEØ+Ð+à˜$˜v™,˜Ð'GÐHˆCÜ˜C“.Ð ð ×.Ñ.¨t·_±_ÀdÓKˆØ:�}Ð: f¨kÑ:ˆ	ð8	ð	Ø!%§¡¨iÓ!@×@�ð ×0Ñ0Ø×+Ñ+¨Zóð ñ AøÜ"ó à×.Ñ.×2Ñ2°4¸±<Ó@�Ü";¸CÓ"J�ä)Ø˜‘L #¨F¡|°_óàðûðûô. ó 	ØÜô 	ô ˜$×2Ñ2´D×9Ñ9¼jØ×(Ñ(¬)÷?ñ ?ð "&×!9Ñ!9Ð ;‘Ü˜D×4Ñ4´e×<Ñ<Ø $× 8Ñ 8‘Ü˜$×2Ñ2×3Ñ3¼JØ×(Ñ(¬$÷=ñ =ô !5°T×5MÑ5MÓ N‘ô "+ �ð ×+×+´:¸a×3OÑ3OØô )¨×1IÑ1IÑJˆGÜØØ˜&‘\Ø! $™ZØñ	õ ûð/	üsg   ‚A.H/Á2B) ÂB'ÂB) ÂC8 Â&H/Â'B) Â)
C5Â3=C0Ã0C5Ã5C8 Ã8H,ÄDH'È!H,È"H/È'H,È,H/c              ƒ  ó–  ^ ^^
#   • T R                   R                  US   5      n[        UUUR                  US9nUR                  m
T R
                  c(  T R                  c  T R                  UTT
5      I Sh  v•N $ SU
UU 4S jjnSU
UU 4S jjn T R
                  b  T R                  XV5      I Sh  v•N $ [        ST R                  5      T l        T R                  XW5      $  Nk N2! [         aV  nT R                  (       d  e [        UT R                  S9n	[        U	UR                  S   UR                  S   S	S
9s SnA$ SnAff = f7f)zÙExecute single tool call asynchronously with awrap_tool_call wrapper if configured.

Args:
    call: Tool call dict.
    input_type: Input format.
    tool_runtime: Tool runtime.

Returns:
    ToolMessage or Command.
r`   r;  Nc              “  óF   >#   • TR                  U TT5      I Sh  v•N $  N7f)r=  N)rI  r?  s    €€€rM   rA  Ú#ToolNode._arun_one.<locals>.execute¬  s!   øé € à×1Ñ1°#°zÀ6ÓJ×JÐJÑJùs   ƒ!š›!c                ó*   >• TR                  U TT5      $ )z'Sync execute fallback for sync wrapper.r>  r?  s    €€€rM   Ú_sync_executeÚ)ToolNode._arun_one.<locals>._sync_execute°  rC  rL   ÚToolCallWrapperr'  rö   r‹   r(  rD  )rñ   rr   rP   rB   rø   rë   rê   rI  r   r|   rè   rª   r   rA   )r_   r  r  r	  r"   rE  rA  rO  rž   r©   rø   s   ` `       @rM   r  ÚToolNode._arun_one‰  sJ  úé € ð$ ×!Ñ!×%Ñ% d¨6¡lÓ3ˆô 'ØØØ×$Ñ$Ø ñ	
ˆð ×$Ñ$ˆà× Ñ Ñ(¨T×-AÑ-AÑ-Ià×1Ñ1°,À
ÈFÓS×SÐS÷	Kñ 	K÷	Dñ 	Dð
	Ø×$Ñ$Ñ0Ø!×2Ñ2°<ÓI×IÐIä#'Ð(9¸4×;OÑ;OÓ#PˆDÔ Ø×'Ñ'¨ÓDÐDñ# Tñ Jøô ó 	à×+×+Øä(¨°×1IÑ1IÑJˆGÜØØ!×+Ñ+¨FÑ3Ø)×3Ñ3°DÑ9Øñ	õ ûð	üsa   …A1E	Á6C"Á7E	Â!C& Â1C$Â2C& Â5E	Â6+C& Ã!E	Ã$C& Ã&
EÃ0AEÄ;EÄ<E	ÅEÅE	c                ó¦  • [        U[        5      (       aF  [        US   [        5      (       a)  US   R                  S5      S:X  a  Sn[	        SU5      nX24$ SnUnO¨[        U[        5      (       a+  UR                  S5      S:X  a  [	        S	U5      nSnUS   /U4$ [        U[        5      (       a&  UR                  U R
                  / 5      =n(       a  S
nO-[        XR
                  / 5      =n(       a  S
nOSn[        U5      e [        S [        U5       5       5      n[        UR                  5      nX24$ ! [         a    Sn[        U5      ef = f)Néÿÿÿÿro   rA   r  zlist[ToolCall]rx   Ú__typeÚtool_call_with_contextrk   rq   zNo message found in inputc              3  óR   #   • U H  n[        U[        5      (       d  M  Uv •  M      g 7fr„   )rp   r   )rs   Úms     rM   ru   Ú(ToolNode._parse_input.<locals>.<genexpr>ê  s   é € ð %Ù-�a´¸A¼y×1I—‘Ò-ùs   ‚'ž	'zNo AIMessage found in input)rp   rx   rq   rr   r   ré   Úgetattrr§   ÚnextÚreversedÚStopIterationr  )r_   rÃ   r  r  rÜ   Úinput_with_ctxr‡   Úlatest_ai_messages           rM   rý   ÚToolNode._parse_inputÈ  sX  € ô
 �eœT×"Ñ"Ü˜% ™)¤T×*Ñ*¨u°R©y¯}©}¸VÓ/DÈÓ/SØ)�
Ü!Ð"2°EÓ:�
Ø!Ð-Ð-ØˆJØ‰Hä�uœd×#Ñ#¨¯	©	°(Ó(;Ð?WÓ(Wô "Ð"7¸Ó?ˆNØ%ˆJØ" ;Ñ/Ð0°*Ð<Ð<Ü˜œt×$Ñ$ØŸ	™	 $×"4Ñ"4°bÓ9Ð9ˆHÕ9à‰JÜ  ×(:Ñ(:¸BÓ?Ð?ˆXÕ?à‰Jà-ˆCÜ˜S“/Ð!ð	"Ü $ñ %Ü# HÔ-ó%ó !Ðô Ð+×6Ñ6Ó7ˆ
ØÐ%Ð%øô ó 	"Ø/ˆCÜ˜S“/Ð!ð	"ús   ÄD8 Ä8Ec                óÔ   • US   nX R                   ;  aT  [        U R                   R                  5       5      n[        R	                  USR                  U5      S9n[        XBUS   SS9$ g )Nr`   ú, )Úrequested_toolÚavailable_toolsrö   r‹   )r`   r÷   r)  )rñ   rx   rÆ   Ú INVALID_TOOL_NAME_ERROR_TEMPLATEr�   rŒ   r   )r_   r  rc  Úall_tool_namesr©   s        rM   r*  ÚToolNode._validate_tool_callô  ss   € Ø˜f™ˆØ×!3Ñ!3Ó3Ü! $×"4Ñ"4×"9Ñ"9Ó";Ó<ˆNÜ6×=Ñ=Ø-Ø $§	¡	¨.Ó 9ð >ð ˆGô Ø¸4À¹:Ègñð ð rL   c                ó®  • [        U[        5      (       a  UR                  S5      S:X  a  US   $ [        U[        5      (       a�  U(       a‰  [        US   [        5      (       aq  US   R                  S5      S:X  aY  UR                  [        0 5      R                  [
        5      nUc  0 $ UR                  S   n[        SU" [        U5      S	5      5      $ U$ )
uf  Extract state from input.

Three input shapes:

- `ToolCallWithContext` dict â€” legacy Send payload carrying an inlined
  state snapshot; return `input["state"]`.
- list of `ToolCall` dicts â€” new Send payload with no inlined state;
  hydrate state from channels via `CONFIG_KEY_READ`.
- regular graph state (dict/list/BaseModel) â€” return `input` as-is.
rU  rV  rB   rT  ro   rA   r­   rš   T)rp   rq   rr   rx   r(   r)   r¿   r   )r_   rÃ   rø   ÚreadÚchannelss        rM   rÿ   ÚToolNode._extract_state  s´   € ô �eœT×"Ñ" u§y¡y°Ó':Ð>VÓ'VØ˜‘>Ð!ä�uœd×#Ñ#ÞÜ˜5 ™9¤d×+Ñ+Ø�b‘	—‘˜fÓ%¨Ó4à—:‘:œd BÓ'×+Ñ+¬OÓ<ˆDØ‰|Ø�	ð
 —y‘y ‘|ˆHÜÐ(©$¬t°H«~¸tÓ*DÓEÐEØˆrL   c                óv  • U R                   R                  US   5      nU(       d  Ub  [        U5      nU(       d  U$ [        U5      n0 nUR                  (       Gaµ  UR                  n[        U[        5      (       a¾  [        UR                  R                  5       5      n[        U5      S:X  a  US   U R                  :X  d  US   c  U R                  U0nOdSUS    S3n	[        S UR                  R                  5        5       5      (       a!  SR                  S U 5       5      n
U	S	U
 S
3-  n	[        U	5      e[        U[        5      (       aX  UR                  R                  5        H9  u  p¼U(       d  XvU'   M  XÇ;   a  X|   Xk'   M  X´R                  ;  d  M0  [!        U5      e   OiUR                  R                  5        HK  u  p¼U(       d  XvU'   M  [#        X|5      (       a  [%        X|5      Xk'   M1  X´R                  ;  d  MB  ['        U5      e   UR(                  (       a2  UR(                  c  Sn[        U5      eUR(                  XdR(                  '   UR*                  (       a  X&UR*                  '   US   R                  5        VVs0 sH  u  pïXäR,                  ;  d  M  Xï_M     nnn0 UEUEUS'   U$ s  snnf )a>  Inject graph state, store, and runtime into tool call arguments.

This is an internal method that enables tools to access graph context that
should not be controlled by the model. Tools can declare dependencies on graph
state, persistent storage, or runtime context using InjectedState, InjectedStore,
and ToolRuntime annotations. This method automatically identifies these
dependencies and injects the appropriate values.

The injection process preserves the original tool call structure while adding
the necessary context arguments. This allows tools to be both model-callable
and context-aware without exposing internal state management to the model.

Args:
    tool_call: The tool call dictionary to augment with injected arguments.
        Must contain 'name', 'args', 'id', and 'type' fields.
    tool_runtime: The ToolRuntime instance containing all runtime context
        (state, config, store, context, stream_writer) to inject into tools.
    tool: Optional tool instance. When provided, allows injection for
        dynamically registered tools that are not in self.tools_by_name
        (e.g., tools added via middleware's wrap_tool_call).

Returns:
    A new ToolCall dictionary with the same structure as the input but with
    additional arguments injected based on the tool's annotation requirements.

Raises:
    ValueError: If a tool requires store injection but no store is provided,
        or if state injection requirements cannot be satisfied.

!!! note
    This method is called automatically during tool execution. It should not
    be called from outside the `ToolNode`.
r`   r­   r   z Invalid input to ToolNode. Tool z$ requires graph state dict as input.c              3  ó"   #   • U H  ov •  M     g 7fr„   rC   )rs   Ústate_fields     rM   ru   Ú-ToolNode._inject_tool_args.<locals>.<genexpr>f  s   é € ÐRÑ:Q¨;œ;Ò:Qùs   ‚rb  c              3  ó4   #   • U H  o(       d  M  Uv •  M     g 7fr„   rC   )rs   Úfs     rM   ru   ro  g  s   é € Ð7XÁ?¸aÓVW¿¹Â?ùs   ‚	�	z State should contain fields r‚   zgCannot inject store into tools with InjectedStore annotations - please compile your graph with a store.r¿   )rç   rr   rí   r   rB   rp   rx   rµ   r¶   ré   r  rŒ   r§   rq   rÊ   rØ   ÚKeyErrorrZ   rZ  ÚAttributeErrorrÇ   rT   r×   )r_   rA   r	  r"   r6  Útool_call_copyrÌ   rB   Úrequired_fieldsÚerr_msgÚrequired_fields_strÚtool_argrn  r‡   rÐ   rÑ   Ústripped_argss                    rM   r,  ÚToolNode._inject_tool_args#  s¨  € ðN ×&Ñ&×*Ñ*¨9°VÑ+<Ó=ˆÞ˜DÑ,ô .¨dÓ3ˆHÞØÐä#'¨	£?ˆØ(*ˆð �>�>ˆ>Ø ×&Ñ&ˆEä˜%¤×&Ñ&Ü"& x§~¡~×'<Ñ'<Ó'>Ó"?�ä˜Ó(¨AÓ-Ø'¨Ñ*¨d×.@Ñ.@Ó@Ø$ QÑ'Ñ/Ø!×/Ñ/°Ð7‘Eð ;¸9ÀVÑ;LÐ:Mð N5ð 6ð ô ÑR¸(¿.¹.×:OÑ:OÔ:QÓR×RÑRØ.2¯i©iÑ7XÁ?Ó7XÓ.XÐ+ØØ;Ð<OÐ;PÐPQÐRñ˜ô % WÓ-Ð-ô ˜%¤×&Ñ&Ø-5¯^©^×-AÑ-AÖ-CÑ)�HÞ&Ø27 hÓ/Ø$Ó-Ø27Ñ2D˜Ó/Ø!×)FÑ)FÕFÜ& {Ó3Ð3ò .Dð .6¯^©^×-AÑ-AÖ-CÑ)�HÞ&Ø27 hÓ/Ü  ×4Ñ4Ü29¸%Ó2M˜Ó/Ø!×)FÑ)FÕFÜ,¨[Ó9Ð9ñ .Dð �>�>Ø×!Ñ!Ñ)ð>ð ô ! “oÐ%Ø,8×,>Ñ,>ˆMŸ.™.Ñ)ð ××Ø.:˜(×*Ñ*Ñ+ð ' vÑ.×4Ñ4Ô6ô
á6‘�Ø×2Ñ2Ñ2ó ˆAŠDÙ6ð 	ñ 
ð
 "D MÐ!C°]Ð!Cˆ�vÑØÐùó
s   Ê	J5Ê!J5c                ó¨  • [        U[        5      (       a  U R                  XU5      $ [        U[        5      (       a&  [	        S[        UR                  5      5      Ul        U$ [        U[        5      (       a=  [        S U 5       5      (       a  U R                  XU5      $ SUS    S3n[        U5      eSUS    S[        U5       3n[        U5      e)z1Validate and normalize a tool's raw return value.ú
str | listc              3  óL   #   • U H  n[        U[        [        45      v •  M     g 7fr„   )rp   r1   r   )rs   Úrs     rM   ru   Ú4ToolNode._normalize_tool_response.<locals>.<genexpr>¥  s   é € ÐKÁ(¸Q”:˜a¤'¬;Ð!7×8Ð8Â(ùs   ‚"$r%  r`   zP returned a list with invalid element types: expected all Command or ToolMessagez returned unexpected type: )rp   r1   Ú_validate_tool_commandr   r   r~   r©   rx   ry   Ú_validate_tool_command_listr+  ro   )r_   r4  rA   r  r‡   s        rM   r.  Ú!ToolNode._normalize_tool_response˜  sÒ   € ô �h¤×(Ñ(Ø×.Ñ.¨xÀJÓOÐOÜ�h¤×,Ñ,Ü# LÔ2DÀX×EUÑEUÓ2VÓWˆHÔØˆOÜ�h¤×%Ñ%ÜÑKÁ(ÓK×KÑKØ×7Ñ7¸ÈZÓXÐXà˜	 &Ñ)Ð*ð +=ð =ð ô ˜C“.Ð Ø�i Ñ'Ð(Ð(CÄDÈÃNÐCSÐTˆÜ˜‹nÐrL   c           
     óØ  • US   nSnU HÄ  n[        U[        5      (       a  UR                  U:X  a  US-  nM/  M1  [        U[        5      (       d  MH  [        UR                  [
        5      (       d  Mi  UR                  R                  U R                  / 5       H1  n[        U[        5      (       d  M  UR                  U:X  d  M,  US-  nM3     MÆ     US:w  a  SUS    SU SU< S3n[        U5      e/ nU Ho  n[        U[        5      (       a"  UR                  U R                  XbUS	S
95        M:  [        S[        UR                  5      5      Ul        UR                  U5        Mq     U$ )uô   Validate a list of Command/ToolMessage returned by a single tool call.

Requires exactly one terminating ToolMessage (matching the outer tool_call_id)
across the list â€” either as a top-level element or nested in a
Command.update["messages"].
rö   r   r­   r%  r`   z returned a list with z  messages bound to tool_call_id z/; expected exactly one terminating ToolMessage.F©Úrequire_terminatorr|  )rp   r   r÷   r1   rÅ   rq   rr   ré   r§   r�   r€  r   r~   r©   )	r_   r4  rA   r  Úexpected_idÚterminator_countÚitemr‡   Ú	validateds	            rM   r�  Ú$ToolNode._validate_tool_command_list¯  sb  € ð   ‘oˆàÐÛˆDÜ˜$¤×,Ñ,Ø×$Ñ$¨Ó3Ø$¨Ñ)Ò$ñ 4ä˜D¤'×*Ó*¬z¸$¿+¹+Ät×/LÓ/LØŸ;™;Ÿ?™?¨4×+=Ñ+=¸rÖB�CÜ! #¤{×3Ó3¸×8HÑ8HÈKÕ8WØ(¨AÑ-Ò(ó Cñ ð ˜qÓ à˜	 &Ñ)Ð*Ð*@Ø#Ð$Ð$DØ‘/Ð!PðRð ô
 ˜S“/Ð!ð
 24ˆ	ÛˆDÜ˜$¤×(Ñ(Ø× Ñ Ø×/Ñ/Ø¨Èð 0ð öô  $ LÔ2DÀTÇ\Á\Ó2RÓS�”Ø× Ñ  Ö&ñ ð ÐrL   Tr„  c               ó<  • [        UR                  [        5      (       a{  US;  a.  SU R                   SUR                   SUS    S3n[	        U5      e[        U5      n[        SUR                  5      =(       d    0 nUR                  U R                  / 5      nO`[        UR                  [        5      (       a?  US:w  a!  S	UR                   SUS    S3n[	        U5      e[        U5      nUR                  nOU$ [        U5      nU[        [        S
9/:X  a  U$ Sn	U H;  n
[        U
[        5      (       d  M  U
R                  US   :X  d  M/  US   U
l        Sn	M=     U(       a8  UR                  c+  U	(       d$  US:X  a  SOSnSUS    SU SU S3n[	        U5      eU$ )N)rq   r  zFTools can provide a dict in Command.update only when using dict with 'z' key as ToolNode input, got: z for tool 'r`   Ú'rš   rx   zpTools can provide a list of messages in Command.update only when using list of messages as ToolNode input, got: )rö   Frö   Trq   z]`Command(update={"messages": [ToolMessage("Success", tool_call_id=tool_call_id), ...]}, ...)`zO`Command(update=[ToolMessage("Success", tool_call_id=tool_call_id), ...], ...)`zDExpected to have a matching ToolMessage in Command.update for tool 'z', got: zŸ. Every tool call (LLM requesting to call a tool) in the message history MUST have a corresponding ToolMessage. You can fix it by modifying the tool to return r‚   )rp   rÅ   rq   ré   r§   r   r   rr   rx   r   r   r,   r   r÷   r`   r  )r_   Úcommandr  r  r…  r‡   Úupdated_commandÚstate_updateÚmessages_updateÚhas_matching_tool_messager�   Úexample_updates               rM   r€  ÚToolNode._validate_tool_commandß  sá  € ô �g—n‘n¤d×+Ñ+ð Ð!7Ó7ðØ!×/Ñ/Ð0ð 1Ø#ŸN™NÐ+¨;°t¸F±|°nÀAðGð ô
 ! “oÐ%ä& wÓ/ˆOÜÐ 0°/×2HÑ2HÓI×OÈRˆLØ*×.Ñ.¨t×/AÑ/AÀ2ÓF‰OÜ˜Ÿ™¬×-Ñ-ð ˜VÓ#ðà#ŸN™NÐ+¨;°t¸F±|°nÀAðGð ô
 ! “oÐ%ä& wÓ/ˆOØ-×4Ñ4‰OàˆNô .¨oÓ>ˆð œ}Ô0CÑDÐEÓEØ"Ð"à$)Ð!Û&ˆGÜ˜g¤{×3Ñ3Ùà×#Ñ# t¨D¡zÕ1Ø# F™|�”Ø,0Ò)ñ 'ö Ø×%Ñ%Ñ-Þ-ð
  Ó'ñSðRð	 ðØ! &™\˜N¨(°?Ð2Cð DBð CQÐAQÐQRð	Tð ô ˜S“/Ð!ØÐrL   )rë   rè   rç   ré   ræ   rê   )rÛ   zSequence[BaseTool | Callable]r`   rg   rÝ   zlist[str] | NonerÞ   úObool | str | Callable[..., str] | type[Exception] | tuple[type[Exception], ...]rß   rg   rà   zToolCallWrapper | Nonerá   zAsyncToolCallWrapper | Nonerh   ri   )rh   zdict[str, BaseTool])rÃ   ú-list[AnyMessage] | dict[str, Any] | BaseModelrø   r   rT   r9   rh   r   )r  z9list[ToolMessage | Command | list[ToolMessage | Command]]r  ú%Literal['list', 'dict', 'tool_calls']rh   z@list[Command | list[ToolMessage] | dict[str, list[ToolMessage]]])r0  rP   r  r–  rø   r   rh   ú3ToolMessage | Command | list[Command | ToolMessage])r  r   r  r–  r	  rS   rh   r—  )rÃ   r•  rh   z<tuple[list[ToolCall], Literal['list', 'dict', 'tool_calls']])r  r   rh   zToolMessage | None)rÃ   r•  rø   r   rh   r•  r„   )rA   r   r	  rS   r"   rR   rh   r   )r4  r   rA   r   r  r–  rh   r—  )r4  úlist[Command | ToolMessage]rA   r   r  r–  rh   r˜  )
r�  r1   r  r   r  r–  r…  r¡   rh   r1   )rE   rF   rG   rH   rI   r`   rJ   rŸ   r”   Úpropertyrñ   rä   rå   r  r8  r  rI  r  rý   r*  rÿ   r,  r.  r�  r€  rK   r›   rœ   s   @rM   rÚ   rÚ   n  sì  ø‡ ñtðl €Dˆ#Óð Ø!%ð
 )DØ&Ø15Ø7;ñ+Là,ð+Lð ð	+Lð
 ð+Lð&ð+Lð ð+Lð /ð+Lð 5ð+Lð 
÷+Lð +LðZ ó#ó ð#ð!?à<ð!?ð ð!?ð ð	!?ð
 
ô!?ðF ?à<ð ?ð ð ?ð ð	 ?ð
 
ô ?ðD: àJð: ð :ð: ð 
Jô	: ðxZà ðZð :ðZð ð	Zð
 
=ôZðx5àð5ð :ð5ð "ð	5ð
 
=ô5ðnZà ðZð :ðZð ð	Zð
 
=ôZðx=àð=ð :ð=ð "ð	=ð
 
=ô=ð~*&à<ð*&ð 
Fô*&ôXð à<ð ð ð ð 
7ô	 ðL !%ð	sàðsð "ðsð ð	sð
 
õsðjàðð ðð :ð	ð
 
=ôð..à-ð.ð ð.ð :ð	.ð
 
%ô.ðl $(ñLàðLð ðLð :ð	Lð !ðLð 
÷Ló LrL   rÚ   c                ó>  • [        U [        5      (       a  U S   nOW[        U [        5      (       a  U R                  U/ 5      =n(       d  [	        X/ 5      =n(       a  US   nOSU  3n[        U5      e[        US5      (       a  [        UR                  5      S:”  a  gg)a�  Conditional routing function for tool-calling workflows.

This utility function implements the standard conditional logic for ReAct-style
agents: if the last `AIMessage` contains tool calls, route to the tool execution
node; otherwise, end the workflow. This pattern is fundamental to most tool-calling
agent architectures.

The function handles multiple state formats commonly used in LangGraph applications,
making it flexible for different graph designs while maintaining consistent behavior.

Args:
    state: The current graph state to examine for tool calls. Supported formats:
        - Dictionary containing a messages key (for `StateGraph`)
        - `BaseModel` instance with a messages attribute
    messages_key: The key or attribute name containing the message list in the state.
        This allows customization for graphs using different state schemas.

Returns:
    Either `'tools'` if tool calls are present in the last `AIMessage`, or `'__end__'`
        to terminate the workflow. These are the standard routing destinations for
        tool-calling conditional edges.

Raises:
    ValueError: If no messages can be found in the provided state format.

Example:
    Basic usage in a ReAct agent:

    ```python
    from langgraph.graph import StateGraph
    from langchain.tools import ToolNode
    from langchain.tools.tool_node import tools_condition
    from typing_extensions import TypedDict


    class State(TypedDict):
        messages: list


    graph = StateGraph(State)
    graph.add_node("llm", call_model)
    graph.add_node("tools", ToolNode([my_tool]))
    graph.add_conditional_edges(
        "llm",
        tools_condition,  # Routes to "tools" or "__end__"
        {"tools": "tools", "__end__": "__end__"},
    )
    ```

    Custom messages key:

    ```python
    def custom_condition(state):
        return tools_condition(state, messages_key="chat_history")
    ```

!!! note
    This function is designed to work seamlessly with `ToolNode` and standard
    LangGraph patterns. It expects the last message to be an `AIMessage` when
    tool calls are present, which is the standard output format for tool-calling
    language models.
rT  z/No messages found in input state to tool_edge: r  r   rÛ   Ú__end__)	rp   rx   rq   rr   rZ  r§   rZ   r¶   r  )rB   rß   Ú
ai_messagerÜ   r‡   s        rM   Útools_conditionr�  .  s“   € ôD �%œ×ÑØ˜2‘Y‰
Ü
�UœD×
!Ñ
!°5·9±9¸\È2Ó3NÐ'N xÕ'NÜ˜E°Ó4Ð4ˆÕ4à˜b‘\‰
à?À¸wÐGˆÜ˜‹oÐÜˆz˜<×(Ñ(¬S°×1FÑ1FÓ-GÈ!Ó-KØØrL   c                  ó’   • \ rS rSr% SrS\S'   S\S'   S\S'   S	\S
'   S\S'   S\S'   \" \S9rS\S'   Sr	S\S'   Sr
S\S'   SS jrSrg)rS   i~  a`  Runtime context automatically injected into tools.

!!! note

    This is distinct from `Runtime` (from `langgraph.runtime`), which is injected
    into graph nodes and middleware. `ToolRuntime` includes additional tool-specific
    attributes like `config`, `state`, and `tool_call_id` that `Runtime` does not
    have.

When a tool function has a parameter named `runtime` with type hint
`ToolRuntime`, the tool execution system will automatically inject an instance
containing:

- `state`: The current graph state
- `tool_call_id`: The ID of the current tool call
- `config`: `RunnableConfig` for the current execution
- `context`: Runtime context (shared with `Runtime`)
- `store`: `BaseStore` instance for persistent storage (shared with `Runtime`)
- `stream_writer`: `StreamWriter` for streaming output (shared with `Runtime`)
- `tools`: List of all available `BaseTool` instances

No `Annotated` wrapper is needed - just use `runtime: ToolRuntime`
as a parameter.

Example:
    ```python
    from langchain_core.tools import tool
    from langchain.tools import ToolRuntime

    @tool
    def my_tool(x: int, runtime: ToolRuntime) -> str:
        """Tool that accesses runtime context."""
        # Access state
        messages = tool_runtime.state["messages"]

        # Access tool_call_id
        print(f"Tool call ID: {tool_runtime.tool_call_id}")

        # Access config
        print(f"Run ID: {tool_runtime.config.get('run_id')}")

        # Access runtime context
        user_id = tool_runtime.context.get("user_id")

        # Access store
        tool_runtime.store.put(("metrics",), "count", 1)

        # Stream output
        tool_runtime.stream_writer.write("Processing...")

        return f"Processed {x}"
    ```

!!! note
    This is a marker class used for type checking and detection.
    The actual runtime object will be constructed during tool execution.
r;   rB   r=   rù   r   rø   r3   rú   rÖ   r÷   zBaseStore | NonerÇ   )Údefault_factoryzlist[BaseTool]rÛ   NzExecutionInfo | Nonerû   zServerInfo | Nonerü   c                óF   • [         R                  " 5       nUc  gU" U5        g)a.  Stream a partial output chunk on the `tools` stream channel.

Reads the per-tool-call writer that `StreamToolCallHandler`
installs on a ContextVar at `on_tool_start` and forwards `delta`
through it. Silent no-op when the graph was not run with
`"tools"` in `stream_mode` (no writer is set), so tool authors
can leave `emit_output_delta` calls in place without gating
them on stream mode.

Args:
    delta: Partial output chunk. Any JSON-serializable value;
        surfaced as-is on the `tools` channel's
        `tool-output-delta` payload under `"delta"`.
N)r-   rr   )r_   ÚdeltaÚwriters      rM   Úemit_output_deltaÚToolRuntime.emit_output_deltaÄ  s!   € ô #×&Ò&Ó(ˆØ‰>ØÙˆu�rL   rC   )r¡  r   rh   ri   )rE   rF   rG   rH   rI   rJ   r	   rx   rÛ   rû   rü   r£  rK   rC   rL   rM   rS   rS   ~  sW   ‡ ñ8ðt ƒMØÓØÓØÓØÓØÓÙ!°$Ñ7€Eˆ>Ó7Ø+/€NÐ(Ó/Ø%)€KÐ"Ó)÷rL   rS   c                  ó&   • \ rS rSrSrSSS jjrSrg)ÚInjectedStateiÙ  a%	  Annotation for injecting graph state into tool arguments.

This annotation enables tools to access graph state without exposing state
management details to the language model. Tools annotated with `InjectedState`
receive state data automatically during execution while remaining invisible
to the model's tool-calling interface.

Args:
    field: Optional key to extract from the state dictionary. If `None`, the entire
        state is injected. If specified, only that field's value is injected.
        This allows tools to request specific state components rather than
        processing the full state structure.

Example:
    ```python
    from typing import List
    from typing_extensions import Annotated, TypedDict

    from langchain_core.messages import BaseMessage, AIMessage
    from langchain.tools import InjectedState, ToolNode, tool


    class AgentState(TypedDict):
        messages: List[BaseMessage]
        foo: str


    @tool
    def state_tool(x: int, state: Annotated[dict, InjectedState]) -> str:
        '''Do something with state.'''
        if len(state["messages"]) > 2:
            return state["foo"] + str(x)
        else:
            return "not enough messages"


    @tool
    def foo_tool(x: int, foo: Annotated[str, InjectedState("foo")]) -> str:
        '''Do something else with state.'''
        return foo + str(x + 1)


    node = ToolNode([state_tool, foo_tool])

    tool_call1 = {"name": "state_tool", "args": {"x": 1}, "id": "1", "type": "tool_call"}
    tool_call2 = {"name": "foo_tool", "args": {"x": 1}, "id": "2", "type": "tool_call"}
    state = {
        "messages": [AIMessage("", tool_calls=[tool_call1, tool_call2])],
        "foo": "bar",
    }
    node.invoke(state)
    ```

    ```python
    [
        ToolMessage(content="not enough messages", name="state_tool", tool_call_id="1"),
        ToolMessage(content="bar2", name="foo_tool", tool_call_id="2"),
    ]
    ```

!!! note
    - `InjectedState` arguments are automatically excluded from tool schemas
        presented to language models
    - `ToolNode` handles the injection process during execution
    - Tools can mix regular arguments (controlled by the model) with injected
        arguments (controlled by the system)
    - State injection occurs after the model generates tool calls but before
        tool execution
Nc                ó   • Xl         g)z*Initialize the `InjectedState` annotation.N©r	   )r_   r	   s     rM   r”   ÚInjectedState.__init__   s   € à�
rL   r¨  r„   )r	   rÖ   rh   ri   )rE   rF   rG   rH   rI   r”   rK   rC   rL   rM   r¦  r¦  Ù  s   † ñD÷Lñ rL   r¦  c                  ó   • \ rS rSrSrSrg)ÚInjectedStorei%  aà	  Annotation for injecting persistent store into tool arguments.

This annotation enables tools to access LangGraph's persistent storage system
without exposing storage details to the language model. Tools annotated with
`InjectedStore` receive the store instance automatically during execution while
remaining invisible to the model's tool-calling interface.

The store provides persistent, cross-session data storage that tools can use
for maintaining context, user preferences, or any other data that needs to
persist beyond individual workflow executions.

!!! warning
    `InjectedStore` annotation requires `langchain-core >= 0.3.8`

Example:
    ```python
    from typing_extensions import Annotated
    from langgraph.store.memory import InMemoryStore
    from langchain.tools import InjectedStore, ToolNode, tool

    @tool
    def save_preference(
        key: str,
        value: str,
        store: Annotated[Any, InjectedStore()]
    ) -> str:
        """Save user preference to persistent storage."""
        store.put(("preferences",), key, value)
        return f"Saved {key} = {value}"

    @tool
    def get_preference(
        key: str,
        store: Annotated[Any, InjectedStore()]
    ) -> str:
        """Retrieve user preference from persistent storage."""
        result = store.get(("preferences",), key)
        return result.value if result else "Not found"
    ```

    Usage with `ToolNode` and graph compilation:

    ```python
    from langgraph.graph import StateGraph
    from langgraph.store.memory import InMemoryStore

    store = InMemoryStore()
    tool_node = ToolNode([save_preference, get_preference])

    graph = StateGraph(State)
    graph.add_node("tools", tool_node)
    compiled_graph = graph.compile(store=store)  # Store is injected automatically
    ```

    Cross-session persistence:

    ```python
    # First session
    result1 = graph.invoke({"messages": [HumanMessage("Save my favorite color as blue")]})

    # Later session - data persists
    result2 = graph.invoke({"messages": [HumanMessage("What's my favorite color?")]})
    ```

!!! note
    - `InjectedStore` arguments are automatically excluded from tool schemas
        presented to language models
    - The store instance is automatically injected by `ToolNode` during execution
    - Tools can access namespaced storage using the store's get/put methods
    - Store injection requires the graph to be compiled with a store instance
    - Multiple tools can share the same store instance for data consistency
rC   N)rE   rF   rG   rH   rI   rK   rC   rL   rM   r«  r«  %  s   † ôGrL   r«  c                óJ  ^• [        U T5      (       d&  [        U [        5      (       a  [        U T5      (       a  g[        U 5      nU[        L d	  U[
        L a  [        U4S j[        U 5       5       5      $ Ub,  UTL d&  [        U[        5      (       a  [        UT5      (       a  gg)a  Check if a type argument represents an injection annotation.

This utility function determines whether a type annotation indicates that
an argument should be injected with state or store data. It handles both
direct annotations and nested annotations within Union or Annotated types.

Args:
    type_arg: The type argument to check for injection annotations.
    injection_type: The injection type to look for (InjectedState or InjectedStore).

Returns:
    True if the type argument contains the specified injection annotation.
Tc              3  ó:   >#   • U H  n[        UT5      v •  M     g 7fr„   )Ú_is_injection)rs   ÚtaÚinjection_types     €rM   ru   Ú _is_injection.<locals>.<genexpr>‡  s   øé € ÐRÑ?Q¸”=  ^×4Ð4Ò?Qùs   ƒF)rp   ro   r£   r   r   r   r  r   )Útype_argr°  Úorigin_s    ` rM   r®  r®  p  sŠ   ø€ ô" �(˜N×+Ñ+Ü�8œT×"Ñ"¤z°(¸N×'KÑ'KàÜ˜Ó"€GØ”%Ò˜7¤iÒ/ÜÔR¼xÈÔ?QÓRÓRÐRàÑØ�>Ò!Ü�w¤×%Ñ%¬*°W¸n×*MÑ*MàØrL   c                ó  • [        U 5      nU Vs/ sH  n[        X15      (       d  M  UPM     nn[        U5      S:”  a  SUR                   SU 3n[	        U5      e[        U5      S:X  a  US   $ [        X5      (       a  ggs  snf )a  Extract injection instance from a type annotation.

Args:
    type_: The type annotation to check.
    injection_type: The injection type to look for.

Returns:
    The injection instance if found, True if injection marker found without instance, None otherwise.
r­   z-A tool argument should not be annotated with z more than once. Found: r   TN)r   r®  r¶   rE   r§   )Útype_r°  Ú	type_argsr¯   Úmatchesr‡   s         rM   Ú_get_injection_from_typer¸  ‘  s�   € ô ˜“€IÙ'ÓN™i�s¬=¸×+M�s™i€GÐNä
ˆ7ƒ|�aÓà;¸N×<SÑ<SÐ;Tð U&Ø&- Yð0ð 	ô ˜‹oÐä
ˆ7ƒ|�qÓØ�q‰zÐÜ	�u×	-Ñ	-Øàùò Os
   �B§Bc                ó  • U R                  5       n[        U5      n[        U SS5      =(       d    [        U SS5      nU(       a
  [        USS9O0 n0 UEUEn0 nSnSn[	        5       n	[	        5       n
UR                  5        Hö  u  p¼[        U5      (       a  U	R                  U5        US:X  a  Un[        U[        5      =n(       a�  [        U[        5      (       ah  UR                  (       aW  UR                  Xk'   UR                  R                  U5      nU(       a&  UR                  5       (       d  U
R                  U5        OSXk'   [        U[        5      (       a  Un[        U[         5      (       d  Mô  UnMø     [#        UUUU	U
S9$ )a]  Extract all injected arguments from tool in a single pass.

This function analyzes both the tool's input schema and function signature
to identify all arguments that should be injected (state, store, runtime).

Args:
    tool: The tool to analyze for injection requirements.

Returns:
    _InjectedArgs structure containing all detected injections.
ÚfuncNÚ	coroutineT)Úinclude_extrasrT   )rB   rÇ   rT   r×   rØ   )Úget_input_schemar'   rZ  r   rÄ   rÊ   r&   rÈ   r¸  r¦  rp   r	   Úmodel_fieldsrr   Úis_requiredr«  rS   rÕ   )r"   Úfull_schemaÚschema_annotationsrº  Úfunc_annotationsÚall_annotationsÚ
state_argsÚ	store_argÚruntime_argr×   rØ   r`   rµ  Ú	state_injÚ
field_infos                  rM   rí   rí   ¯  ss  € ð ×'Ñ'Ó)€KÜ6°{ÓCÐä�4˜ Ó&×J¬'°$¸ÀTÓ*J€DÞDH”~ d¸4Ò@ÈbÐð AÐ)Ð@Ð-?Ð@€Oð )+€JØ €IØ"€KÜ"%£%ÐÜ%(£UÐà&×,Ñ,Ö.‰ˆä  ×'Ñ'Ø×!Ñ! $Ô'ð �9ÓØˆKô 1°¼ÓFÐFˆ9ÕFÜ˜)¤]×3Ñ3¸	¿¿Ø#,§?¡?�
Ñ Ø(×5Ñ5×9Ñ9¸$Ó?�
Þ j×&<Ñ&<×&>Ñ&>Ø(×,Ñ,¨TÔ2øà#'�
Ñ ô $ E¬=×9Ñ9ØˆIô $ E¬;×7Ó7ØŠKñ3 /ô6 ØØØØ+Ø1ñð rL   )r}   r   rh   zstr | list[dict])rž   r|   rh   rg   )rž   r|   r¨   r”  rh   rg   )r¹   zCallable[..., str]rh   ztuple[type[Exception], ...])rË   r5   rÌ   z_InjectedArgs | Nonerh   zlist[ErrorDetails])rÜ   )rB   r•  rß   rg   rh   zLiteral['tools', '__end__'])r²  r   r°  ú1type[InjectedState | InjectedStore | ToolRuntime]rh   r¡   )rµ  r   r°  rÉ  rh   z
Any | None)r"   r    rh   rÕ   )lrI   Ú
__future__r   r  r²   rz   Úcollections.abcr   r   r   r   Údataclassesr   r	   r
   Útypesr   Útypingr   r   r   r   r   r   r   r   r   r   r   Úlangchain_core.messagesr   r   r   r   r   r   Úlangchain_core.runnables.configr   r   r   Úlangchain_core.toolsr    r!   r"   rì   Úlangchain_core.tools.baser#   r$   r%   r&   r'   Úlanggraph._internal._constantsr(   r)   Úlanggraph._internal._runnabler*   Úlanggraph.errorsr+   Úlanggraph.graph.messager,   Úlanggraph.pregel._toolsr-   Úlanggraph.runtimer.   r/   Úlanggraph.store.baser0   Úlanggraph.typesr1   r2   r3   Úpydanticr4   r5   Útyping_extensionsr6   r7   r8   r9   Úpydantic_corer:   rq   r;   r=   re  r¤   ÚTOOL_EXECUTION_ERROR_TEMPLATErŽ   r?   rP   rQ  ÚAsyncToolCallWrapperrk   r~   r€   rŸ   rª   rÁ   rÓ   rÕ   rÚ   r�  rS   r¦  r«  r®  r¸  rí   rC   rL   rM   Ú<module>rà     sÇ  ðñ%õN #ã Û Û ß /ß ß 1Ñ 1Ý ÷÷ ÷ ñ ÷÷ ÷ñ ÷
 ;Ý 4÷õ ÷ AÝ :Ý *Ý 7Ý 5ß 7Ý *ß 7Ñ 7ß /ß -æÝ(å)Ý*ñ
 
� 4Ñ	(€Ù�: tÑ,€ð Sð !ð HÐ ð+ð ð+ð ô 	°ò ð ÷B*ð B*ó ðB*ðJ Ø�h Ð0°+ÀÑ2GÐGÑHÐIØ�'Ñðñ€ðGðR  Ø�h Ð0°)¸KÈ'Ñ<QÑ2RÐRÑSÐTØˆk˜GÑ#Ñ$ð&ñÐ ð Eô7˜)ô 7ô.ô<)'˜-ô )'ôXð/Øð/ð"ð/ð 	ô/ôd?ðD5Ø%ð5à'ð5ð ô5ðp ÷4#ð 4#ó ð4#ôn}Ðô }ðD #ðMØ8ðMàðMð !õMð` ôWÐ*¨G°H¸fÐ4DÑ,Eó Wó ðWôtI�Oô IôXH�Oô HðVØðàEðð 
ôðBØðØ Qðàôõ<?rL   