
    @'h                         d dl Z d dlZd dlmZmZmZmZmZmZm	Z	m
Z
mZmZ d dlmZmZmZ d dlmZmZmZmZmZ d dlmZmZmZmZ d dlmZ d dlmZ d dl m!Z!m"Z" d d	l#m$Z$m%Z% d d
l&m'Z'm(Z( d dl)m*Z* d dl+m,Z, d dl-m.Z.m/Z/ d dl0m1Z1 d dl2m3Z3 d dl4m5Z5m6Z6 d dl7m8Z8m9Z9 e
e:ef   Z;e
e:e<e   f   Z= e	dedef         Z> G d de"      Z? G d de      Z@ G d de?      ZA G d de@      ZB e	de
e?e@f         ZCeeC   ZDdZEe
eeFeeCgef   eeCef   f   ZGd?deCd eFd!ed"efd#ZHd$eeG   d"efd%ZId&e>d"e>fd'ZJd(ed)ee   d"eKfd*ZLd(ed"efd+ZMd,ee   d"dfd-ZNeJdddddddddd.d/dd0d(e
eFef   d)e
ee
eef      e1f   d$eeG   d1ee
e=eOeFe=f   f      d2ee9   d3eeD   d4eee      d5ee5   d6ee3   d7eePeF      d8eePeF      d9eKd:ed;   d<eeF   d"e*fd=       ZQeQZRg d>ZSy)@    N)
AnyCallableLiteralOptionalSequenceTypeTypeVarUnioncastget_type_hints)BaseChatModelLanguageModelInputLanguageModelLike)	AIMessage
AnyMessageBaseMessageSystemMessageToolMessage)RunnableRunnableBindingRunnableConfigRunnableSequence)BaseTool)	BaseModel)	Annotated	TypedDict)	ErrorCodecreate_error_message)END
StateGraph)CompiledGraph)add_messages)
IsLastStepRemainingSteps)ToolNode)	BaseStore)CheckpointerSend)RunnableCallableRunnableLikeF.)boundc                   @    e Zd ZU dZeee   ef   ed<   e	ed<   e
ed<   y)
AgentStateThe state of the agent.messagesis_last_stepremaining_stepsN)__name__
__module____qualname____doc__r   r   r   r"   __annotations__r#   r$        m/home/kushmeetdev/Regenta/Chatbot/venv/lib/python3.12/site-packages/langgraph/prebuilt/chat_agent_executor.pyr.   r.   9   s&    !-|;<<##r9   r.   c                   :    e Zd ZU dZeee   ef   ed<   dZ	e
ed<   y)AgentStatePydanticr/   r0      r2   N)r3   r4   r5   r6   r   r   r   r"   r7   r2   r$   r8   r9   r:   r<   r<   C   s$    !-|;<<&(O^(r9   r<   c                       e Zd ZU dZeed<   y) AgentStateWithStructuredResponse2The state of the agent with a structured response.structured_responseNr3   r4   r5   r6   StructuredResponser7   r8   r9   r:   r?   r?   K       <++r9   r?   c                       e Zd ZU dZeed<   y)(AgentStateWithStructuredResponsePydanticr@   rA   NrB   r8   r9   r:   rF   rF   Q   rD   r9   rF   StateSchemaPromptstatekeydefaultreturnc                 `    t        | t              r| j                  ||      S t        | ||      S N)
isinstancedictgetgetattr)rI   rJ   rK   s      r:   _get_state_valuerS   d   s6     eT" 			#w UC)r9   promptc                      t        d t              }|S t         t              r"t	               t        fdt              }|S t         t              rt         fdt              }|S t        j                         rt        d  t              }|S t               rt         t              }|S t         t              r }|S t        dt                      )Nc                     t        | d      S Nr0   rS   )rI   s    r:   <lambda>z&_get_prompt_runnable.<locals>.<lambda>p   s    *5*= r9   namecontentc                 $    gt        | d      z   S rW   rX   )rI   _system_messages    r:   rY   z&_get_prompt_runnable.<locals>.<lambda>u   s    ?+.>uj.QQ r9   c                 $    gt        | d      z   S rW   rX   )rI   rT   s    r:   rY   z&_get_prompt_runnable.<locals>.<lambda>z   s    6(%5eZ%HH r9   z"Got unexpected type for `prompt`: )r)   PROMPT_RUNNABLE_NAMErO   strr   inspectiscoroutinefunctioncallabler   
ValueErrortype)rT   prompt_runnabler_   s   ` @r:   _get_prompt_runnableri   l   s    ~*=DX
< 7 
FC	 '4V'D*Q%
2 + 
FM	**H%
( ! 
	$	$V	,*%
  
&	*%
  
FH	%   =d6l^LMMr9   funcc                      t        j                         dt        dt        dt        f fd       }t        t        |      S )z=Decorator that converts state_modifier kwarg to prompt kwarg.argskwargsrL   c                      |j                  d      }|j                  dd       }t        d ||fD              dkD  rt        d      ||}||d<    | i |S )NrT   state_modifierc              3   $   K   | ]  }|d u 
 y wrN   r8   ).0ps     r:   	<genexpr>z?_convert_modifier_to_prompt.<locals>.wrapper.<locals>.<genexpr>   s     ?q}?s      zBExpected only one of (prompt, state_modifier), got multiple values)rQ   popsumrf   )rl   rm   rT   ro   rj   s       r:   wrapperz,_convert_modifier_to_prompt.<locals>.wrapper   sq    H%$4d;?v~&>??!CT  %#F!xT$V$$r9   )	functoolswrapsr   r   r+   )rj   rw   s   ` r:   _convert_modifier_to_promptrz      sD     __T%s %c %c % % 7r9   modeltoolsc                    t        | t              rt        d | j                  D        |       } t        | t              syd| j
                  vry| j
                  d   }t        |      t        |      k7  rt        d      t        d |D              }t               }|D ]H  }|j                  d      dk(  r	|d   d   }n|j                  d      r|d   }n8|j                  |       J ||z
  x}rt        d	| d
      y)Nc              3   L   K   | ]  }t        |t        t        f      r|  y wrN   rO   r   r   rq   steps     r:   rs   z%_should_bind_tools.<locals>.<genexpr>   '      d_m$DE    "$Tr|   z[Number of tools in the model.bind_tools() and tools passed to create_react_agent must matchc              3   4   K   | ]  }|j                     y wrN   rZ   )rq   tools     r:   rs   z%_should_bind_tools.<locals>.<genexpr>   s     14TYY1s   rg   functionr[   zMissing tools 'z' in the model.bind_tools()F)rO   r   nextstepsr   rm   lenrf   setrQ   add)r{   r|   bound_tools
tool_namesbound_tool_names
bound_toolbound_tool_namemissing_toolss           r:   _should_bind_toolsr      s   %)*!KK
 
 e_-ell",,w'K
5zS%%i
 	
 1511Ju! .
>>&!Z/(4V<O^^F#(0O _-. #%555}5?=/9TUVVr9   c                     t        | t              rt        d | j                  D        |       } t        | t              r| j
                  } t        | t              st        dt        |              | S )zKGet the underlying model from a RunnableBinding or return the model itself.c              3   L   K   | ]  }t        |t        t        f      r|  y wrN   r   r   s     r:   rs   z_get_model.<locals>.<genexpr>   r   r   zXExpected `model` to be a ChatModel or RunnableBinding (e.g. model.bind_tools(...)), got )	rO   r   r   r   r   r,   r   	TypeErrorrg   )r{   s    r:   
_get_modelr      sr    %)*!KK
 
 %)e]+fgklqgrfst
 	
 Lr9   r0   c                 f   | D cg c]%  }t        |t              r|j                  D ]  }| ' }}}| D ch c]  }t        |t              s|j                  ! }}|D cg c]  }|d   |vr| }}|syt        d|dd  dt        j                        }t        |      c c}}w c c}w c c}w )zLValidate that all tool calls in AIMessages have a corresponding ToolMessage.idNz{Found AIMessages with tool_calls that do not have a corresponding ToolMessage. Here are the first few of those tool calls:    z.

Every tool call (LLM requesting to call a tool) in the message history MUST have a corresponding ToolMessage (result of a tool invocation to return to the LLM) - this is required by most LLM providers.)message
error_code)	rO   r   
tool_callsr   tool_call_idr   r   INVALID_CHAT_HISTORYrf   )r0   r   	tool_callall_tool_callstool_call_ids_with_resultstool_calls_without_resultserror_messages          r:   _validate_chat_historyr      s      gy) ++	  	N  -5"!(
7K8X" "
 ("T?"<< 	" "
 &(77QRTST7U6V Wgg 11M ]
##1""s   *B#B)B)!B.Fv1)rT   response_formatpre_model_hookstate_schemaconfig_schemacheckpointerstoreinterrupt_beforeinterrupt_afterdebugversionr[   r   r   r   r   r   r   r   r   r   r   r   v2r[   c                 	    !"#$% dvrt        d d      Jddh}|j                  d       t        t                    }|t        |      z
  x}rt        d| d      t        nt
        t        |t              r&t        |j                  j                               }|%n.t        |      %t        %j                  j                               }t         t              r	 d	d
lm} t        t          |              t#        |      d	kD  }t%         |      r!|rt        t                j'                  |       t)        |       z  #|D ch c]  }|j*                  s|j,                   c}$dt.        dt0        dt2        f$fd dt.        dt.        ffd!dt.        dt4        dt.        f !#fd}dt.        dt4        dt.        f !#fd}Mt        t6              r/t9        t:              rd	dlm}  |dt        t@           df      }n G d d      }|}n}dt.        dt4        dt.        f fd}dt.        dt4        dt.        f fd}|stC        |      }|jE                  dtG        ||      |       '|jE                  d       |jI                  dd       d"nd"|jK                  "       .|jE                  dtG        ||             |jI                  dd       |jM                  ||	|
|       S dt.        dtN        t        t        f   f%fd!}tC        xs t
        |      }|jE                  dtG        ||      |       |jE                  d"%       '|jE                  d       |jI                  dd       d"nd"|jK                  "       7|jE                  dtG        ||             |jI                  dtP               d"dg}nd"tP        g}|jS                  d||#       dt.        dt        f"$fd$}$r|jS                  d"|"tP        g#       n|jI                  d""       |jM                  ||	|
|       S # t        $ r t        d      w xY wc c}w )%axG  Creates a graph that works with a chat model that utilizes tool calling.

    Args:
        model: The `LangChain` chat model that supports tool calling.
        tools: A list of tools or a ToolNode instance.
            If an empty list is provided, the agent will consist of a single LLM node without tool calling.
        prompt: An optional prompt for the LLM. Can take a few different forms:

            - str: This is converted to a SystemMessage and added to the beginning of the list of messages in state["messages"].
            - SystemMessage: this is added to the beginning of the list of messages in state["messages"].
            - Callable: This function should take in full graph state and the output is then passed to the language model.
            - Runnable: This runnable should take in full graph state and the output is then passed to the language model.

        response_format: An optional schema for the final agent output.

            If provided, output will be formatted to match the given schema and returned in the 'structured_response' state key.
            If not provided, `structured_response` will not be present in the output state.
            Can be passed in as:

                - an OpenAI function/tool schema,
                - a JSON Schema,
                - a TypedDict class,
                - or a Pydantic class.
                - a tuple (prompt, schema), where schema is one of the above.
                    The prompt will be used together with the model that is being used to generate the structured response.

            !!! Important
                `response_format` requires the model to support `.with_structured_output`

            !!! Note
                The graph will make a separate call to the LLM to generate the structured response after the agent loop is finished.
                This is not the only strategy to get structured responses, see more options in [this guide](https://langchain-ai.github.io/langgraph/how-tos/react-agent-structured-output/).

        pre_model_hook: An optional node to add before the `agent` node (i.e., the node that calls the LLM).
            Useful for managing long message histories (e.g., message trimming, summarization, etc.).
            Pre-model hook must be a callable or a runnable that takes in current graph state and returns a state update in the form of
                ```python
                # At least one of `messages` or `llm_input_messages` MUST be provided
                {
                    # If provided, will UPDATE the `messages` in the state
                    "messages": [RemoveMessage(id=REMOVE_ALL_MESSAGES), ...],
                    # If provided, will be used as the input to the LLM,
                    # and will NOT UPDATE `messages` in the state
                    "llm_input_messages": [...],
                    # Any other state keys that need to be propagated
                    ...
                }
                ```

            !!! Important
                At least one of `messages` or `llm_input_messages` MUST be provided and will be used as an input to the `agent` node.
                The rest of the keys will be added to the graph state.

            !!! Warning
                If you are returning `messages` in the pre-model hook, you should OVERWRITE the `messages` key by doing the following:

                ```python
                {
                    "messages": [RemoveMessage(id=REMOVE_ALL_MESSAGES), *new_messages]
                    ...
                }
                ```
        state_schema: An optional state schema that defines graph state.
            Must have `messages` and `remaining_steps` keys.
            Defaults to `AgentState` that defines those two keys.
        config_schema: An optional schema for configuration.
            Use this to expose configurable parameters via agent.config_specs.
        checkpointer: An optional checkpoint saver object. This is used for persisting
            the state of the graph (e.g., as chat memory) for a single thread (e.g., a single conversation).
        store: An optional store object. This is used for persisting data
            across multiple threads (e.g., multiple conversations / users).
        interrupt_before: An optional list of node names to interrupt before.
            Should be one of the following: "agent", "tools".
            This is useful if you want to add a user confirmation or other interrupt before taking an action.
        interrupt_after: An optional list of node names to interrupt after.
            Should be one of the following: "agent", "tools".
            This is useful if you want to return directly or run additional processing on an output.
        debug: A flag indicating whether to enable debug mode.
        version: Determines the version of the graph to create.
            Can be one of:

            - `"v1"`: The tool node processes a single message. All tool
                calls in the message are executed in parallel within the tool node.
            - `"v2"`: The tool node processes a tool call.
                Tool calls are distributed across multiple instances of the tool
                node using the [Send](https://langchain-ai.github.io/langgraph/concepts/low_level/#send)
                API.
        name: An optional name for the CompiledStateGraph.
            This name will be automatically used when adding ReAct agent graph to another graph as a subgraph node -
            particularly useful for building multi-agent systems.

    Returns:
        A compiled LangChain runnable that can be used for chat interactions.

    The resulting graph looks like this:

    ``` mermaid
    stateDiagram-v2
        [*] --> Start
        Start --> Agent
        Agent --> Tools : continue
        Tools --> Agent
        Agent --> End : end
        End --> [*]

        classDef startClass fill:#ffdfba;
        classDef endClass fill:#baffc9;
        classDef otherClass fill:#fad7de;

        class Start startClass
        class End endClass
        class Agent,Tools otherClass
    ```

    The "agent" node calls the language model with the messages list (after applying the messages modifier).
    If the resulting AIMessage contains `tool_calls`, the graph will then call the ["tools"][langgraph.prebuilt.tool_node.ToolNode].
    The "tools" node executes the tools (1 tool per `tool_call`) and adds the responses to the messages list
    as `ToolMessage` objects. The agent node then calls the language model again.
    The process repeats until no more `tool_calls` are present in the response.
    The agent then returns the full list of messages as a dictionary containing the key "messages".

    ``` mermaid
        sequenceDiagram
            participant U as User
            participant A as Agent (LLM)
            participant T as Tools
            U->>A: Initial input
            Note over A: Messages modifier + LLM
            loop while tool_calls present
                A->>T: Execute tools
                T-->>A: ToolMessage for each tool_calls
            end
            A->>U: Return final state
    ```

    Examples:
        Use with a simple tool:

        ```pycon
        >>> from langchain_openai import ChatOpenAI
        >>> from langgraph.prebuilt import create_react_agent


        ... def check_weather(location: str) -> str:
        ...     '''Return the weather forecast for the specified location.'''
        ...     return f"It's always sunny in {location}"
        >>>
        >>> tools = [check_weather]
        >>> model = ChatOpenAI(model="gpt-4o")
        >>> graph = create_react_agent(model, tools=tools)
        >>> inputs = {"messages": [("user", "what is the weather in sf")]}
        >>> for s in graph.stream(inputs, stream_mode="values"):
        ...     message = s["messages"][-1]
        ...     if isinstance(message, tuple):
        ...         print(message)
        ...     else:
        ...         message.pretty_print()
        ('user', 'what is the weather in sf')
        ================================== Ai Message ==================================
        Tool Calls:
        check_weather (call_LUzFvKJRuaWQPeXvBOzwhQOu)
        Call ID: call_LUzFvKJRuaWQPeXvBOzwhQOu
        Args:
            location: San Francisco
        ================================= Tool Message =================================
        Name: check_weather
        It's always sunny in San Francisco
        ================================== Ai Message ==================================
        The weather in San Francisco is sunny.
        ```
        Add a system prompt for the LLM:

        ```pycon
        >>> system_prompt = "You are a helpful bot named Fred."
        >>> graph = create_react_agent(model, tools, prompt=system_prompt)
        >>> inputs = {"messages": [("user", "What's your name? And what's the weather in SF?")]}
        >>> for s in graph.stream(inputs, stream_mode="values"):
        ...     message = s["messages"][-1]
        ...     if isinstance(message, tuple):
        ...         print(message)
        ...     else:
        ...         message.pretty_print()
        ('user', "What's your name? And what's the weather in SF?")
        ================================== Ai Message ==================================
        Hi, my name is Fred. Let me check the weather in San Francisco for you.
        Tool Calls:
        check_weather (call_lqhj4O0hXYkW9eknB4S41EXk)
        Call ID: call_lqhj4O0hXYkW9eknB4S41EXk
        Args:
            location: San Francisco
        ================================= Tool Message =================================
        Name: check_weather
        It's always sunny in San Francisco
        ================================== Ai Message ==================================
        The weather in San Francisco is currently sunny. If you need any more details or have other questions, feel free to ask!
        ```

        Add a more complex prompt for the LLM:

        ```pycon
        >>> from langchain_core.prompts import ChatPromptTemplate
        >>> prompt = ChatPromptTemplate.from_messages([
        ...     ("system", "You are a helpful bot named Fred."),
        ...     ("placeholder", "{messages}"),
        ...     ("user", "Remember, always be polite!"),
        ... ])
        >>>
        >>> graph = create_react_agent(model, tools, prompt=prompt)
        >>> inputs = {"messages": [("user", "What's your name? And what's the weather in SF?")]}
        >>> for s in graph.stream(inputs, stream_mode="values"):
        ...     message = s["messages"][-1]
        ...     if isinstance(message, tuple):
        ...         print(message)
        ...     else:
        ...         message.pretty_print()
        ```

        Add complex prompt with custom graph state:

        ```pycon
        >>> from typing_extensions import TypedDict
        >>>
        >>> from langgraph.managed import IsLastStep
        >>> prompt = ChatPromptTemplate.from_messages(
        ...     [
        ...         ("system", "Today is {today}"),
        ...         ("placeholder", "{messages}"),
        ...     ]
        ... )
        >>>
        >>> class CustomState(TypedDict):
        ...     today: str
        ...     messages: Annotated[list[BaseMessage], add_messages]
        ...     is_last_step: IsLastStep
        >>>
        >>> graph = create_react_agent(model, tools, state_schema=CustomState, prompt=prompt)
        >>> inputs = {"messages": [("user", "What's today's date? And what's the weather in SF?")], "today": "July 16, 2004"}
        >>> for s in graph.stream(inputs, stream_mode="values"):
        ...     message = s["messages"][-1]
        ...     if isinstance(message, tuple):
        ...         print(message)
        ...     else:
        ...         message.pretty_print()
        ```

        Add thread-level "chat memory" to the graph:

        ```pycon
        >>> from langgraph.checkpoint.memory import MemorySaver
        >>> graph = create_react_agent(model, tools, checkpointer=MemorySaver())
        >>> config = {"configurable": {"thread_id": "thread-1"}}
        >>> def print_stream(graph, inputs, config):
        ...     for s in graph.stream(inputs, config, stream_mode="values"):
        ...         message = s["messages"][-1]
        ...         if isinstance(message, tuple):
        ...             print(message)
        ...         else:
        ...             message.pretty_print()
        >>> inputs = {"messages": [("user", "What's the weather in SF?")]}
        >>> print_stream(graph, inputs, config)
        >>> inputs2 = {"messages": [("user", "Cool, so then should i go biking today?")]}
        >>> print_stream(graph, inputs2, config)
        ('user', "What's the weather in SF?")
        ================================== Ai Message ==================================
        Tool Calls:
        check_weather (call_ChndaktJxpr6EMPEB5JfOFYc)
        Call ID: call_ChndaktJxpr6EMPEB5JfOFYc
        Args:
            location: San Francisco
        ================================= Tool Message =================================
        Name: check_weather
        It's always sunny in San Francisco
        ================================== Ai Message ==================================
        The weather in San Francisco is sunny. Enjoy your day!
        ================================ Human Message =================================
        Cool, so then should i go biking today?
        ================================== Ai Message ==================================
        Since the weather in San Francisco is sunny, it sounds like a great day for biking! Enjoy your ride!
        ```

        Add an interrupt to let the user confirm before taking an action:

        ```pycon
        >>> graph = create_react_agent(
        ...     model, tools, interrupt_before=["tools"], checkpointer=MemorySaver()
        >>> )
        >>> config = {"configurable": {"thread_id": "thread-1"}}

        >>> inputs = {"messages": [("user", "What's the weather in SF?")]}
        >>> print_stream(graph, inputs, config)
        >>> snapshot = graph.get_state(config)
        >>> print("Next step: ", snapshot.next)
        >>> print_stream(graph, None, config)
        ```

        Add cross-thread memory to the graph:

        ```pycon
        >>> from langgraph.prebuilt import InjectedStore
        >>> from langgraph.store.base import BaseStore

        >>> def save_memory(memory: str, *, config: RunnableConfig, store: Annotated[BaseStore, InjectedStore()]) -> str:
        ...     '''Save the given memory for the current user.'''
        ...     # This is a **tool** the model can use to save memories to storage
        ...     user_id = config.get("configurable", {}).get("user_id")
        ...     namespace = ("memories", user_id)
        ...     store.put(namespace, f"memory_{len(store.search(namespace))}", {"data": memory})
        ...     return f"Saved memory: {memory}"

        >>> def prepare_model_inputs(state: AgentState, config: RunnableConfig, store: BaseStore):
        ...     # Retrieve user memories and add them to the system message
        ...     # This function is called **every time** the model is prompted. It converts the state to a prompt
        ...     user_id = config.get("configurable", {}).get("user_id")
        ...     namespace = ("memories", user_id)
        ...     memories = [m.value["data"] for m in store.search(namespace)]
        ...     system_msg = f"User memories: {', '.join(memories)}"
        ...     return [{"role": "system", "content": system_msg)] + state["messages"]

        >>> from langgraph.checkpoint.memory import MemorySaver
        >>> from langgraph.store.memory import InMemoryStore
        >>> store = InMemoryStore()
        >>> graph = create_react_agent(model, [save_memory], prompt=prepare_model_inputs, store=store, checkpointer=MemorySaver())
        >>> config = {"configurable": {"thread_id": "thread-1", "user_id": "1"}}

        >>> inputs = {"messages": [("user", "Hey I'm Will, how's it going?")]}
        >>> print_stream(graph, inputs, config)
        ('user', "Hey I'm Will, how's it going?")
        ================================== Ai Message ==================================
        Hello Will! It's nice to meet you. I'm doing well, thank you for asking. How are you doing today?

        >>> inputs2 = {"messages": [("user", "I like to bike")]}
        >>> print_stream(graph, inputs2, config)
        ================================ Human Message =================================
        I like to bike
        ================================== Ai Message ==================================
        That's great to hear, Will! Biking is an excellent hobby and form of exercise. It's a fun way to stay active and explore your surroundings. Do you have any favorite biking routes or trails you enjoy? Or perhaps you're into a specific type of biking, like mountain biking or road cycling?

        >>> config = {"configurable": {"thread_id": "thread-2", "user_id": "1"}}
        >>> inputs3 = {"messages": [("user", "Hi there! Remember me?")]}
        >>> print_stream(graph, inputs3, config)
        ================================ Human Message =================================
        Hi there! Remember me?
        ================================== Ai Message ==================================
        User memories:
        Hello! Of course, I remember you, Will! You mentioned earlier that you like to bike. It's great to hear from you again. How have you been? Have you been on any interesting bike rides lately?
        ```

        Add a timeout for a given step:

        ```pycon
        >>> import time
        ... def check_weather(location: str) -> str:
        ...     '''Return the weather forecast for the specified location.'''
        ...     time.sleep(2)
        ...     return f"It's always sunny in {location}"
        >>>
        >>> tools = [check_weather]
        >>> graph = create_react_agent(model, tools)
        >>> graph.step_timeout = 1 # Seconds
        >>> for s in graph.stream({"messages": [("user", "what is the weather in sf")]}):
        ...     print(s)
        TimeoutError: Timed out at step 2
        ```
    r   zInvalid version z'. Supported versions are 'v1' and 'v2'.r0   r2   rA   zMissing required key(s) z in state_schemar   )init_chat_modelzsPlease install langchain (`pip install langchain`) to use '<provider>:<model>' string syntax for `model` parameter.rI   responserL   c                 0   t        |t              xr |j                  }t        |t              rt        fd|j                  D              nd}t	        | dd       }t	        | dd      }|d u xr |xr |xs  |d uxr	 |dk  xr |xs |d uxr	 |dk  xr |S )Nc              3   ,   K   | ]  }|d    v   yw)r[   Nr8   )rq   callshould_return_directs     r:   rs   zEcreate_react_agent.<locals>._are_more_steps_needed.<locals>.<genexpr>  s     UV 44Us   Fr2   r1   rt      )rO   r   r   allrS   )rI   r   has_tool_callsall_tools_return_directr2   r1   r   s         r:   _are_more_steps_neededz2create_react_agent.<locals>._are_more_steps_needed  s    #Hi8PX=P=P (I. UATATUU 	 
 +52CTJ'~uE$HH. Xt+ ,#a',+	X  t+V!0CV	
r9   c                      t        | d      xs t        | d      }d|  }nt        | d      }d|  }|t        |      t        |       t        t              rt        t              r	|| _        | S || d<   | S )Nllm_input_messagesr0   zUExpected input to call_model to have 'llm_input_messages' or 'messages' key, but got z=Expected input to call_model to have 'messages' key, but got )rS   rf   r   rO   rg   
issubclassr   r0   )rI   r0   	error_msgr   r   s      r:   _get_model_input_statez2create_react_agent.<locals>._get_model_input_state  s    % (<=5!%4  ppuovwI'z:HOPUwW  Y''x(lD)jy.Q%EN  !)E*r9   configc                      |       } t        t        j                  | |            }|_         | |      rdt        |j                  d      giS d|giS Nr0   z/Sorry, need more steps to process this request.)r   r]   )r   r   invoker[   r   rI   r   r   r   r   model_runnabler[   s      r:   
call_modelz&create_react_agent.<locals>.call_model  sj    &u-	>#8#8#GH!%2#;; Q  XJ''r9   c                    K    |       } t        t        j                  | |       d {         }|_         | |      rdt        |j                  d      giS d|giS 7 7wr   )r   r   ainvoker[   r   r   s      r:   acall_modelz'create_react_agent.<locals>.acall_model  sw     &u-	)?)?v)N#NO!%2#;; Q  XJ'' $Os   (A%A#
8A%)create_modelCallModelInputSchema.)r   __base__c                       e Zd ZU ee   ed<   y)0create_react_agent.<locals>.CallModelInputSchemar   N)r3   r4   r5   listr   r7   r8   r9   r:   r   r     s    $($44r9   c                     t        | d      }}t        t              r\  }}t        |      gt	        |      z   }t              j                  t        t        |            }|j                  ||      }d|iS Nr0   r\   rA   )
rS   rO   tupler   r   r   with_structured_outputr   StructuredResponseSchemar   	rI   r   r0   structured_response_schemasystem_promptmodel_with_structured_outputr   r{   r   s	          r:   generate_structured_responsez8create_react_agent.<locals>.generate_structured_response  s     $E:6%4"ou-8G5M5%m<=XNH'1%'8'O'O)+EF(
$ 066xH%x00r9   c                   K   t        | d      }}t        t              r\  }}t        |      gt	        |      z   }t              j                  t        t        |            }|j                  ||       d {   }d|iS 7 wr   )
rS   rO   r   r   r   r   r   r   r   r   r   s	          r:   agenerate_structured_responsez9create_react_agent.<locals>.agenerate_structured_response.  s      $E:6%4"ou-8G5M5%m<=XNH'1%'8'O'O)+EF(
$ 6==hOO%x00 Ps   A:B=B>	B)r   agent)inputr   r   )r   r   r   r   r   r[   c                 (   t        | d      }|d   }t        |t              r|j                  s
t        S dS 	dk(  ry	dk(  rE|j                  D cg c]  }j                  ||        }}|D cg c]  }t        d|g       c}S y c c}w c c}w )Nr0   r   r   r|   r   )rS   rO   r   r   r   inject_tool_argsr(   )
rI   r0   last_messager   r   r   r   r   	tool_noder   s
         r:   should_continuez+create_react_agent.<locals>.should_continuea  s    #E:6|,	2,:Q:Q)13U7UU $D !- 7 7 ..tUEB
  EOOyWyk2OO ! Ps   B
2Br|   )path_mapc                     t        t        | d            D ]+  }t        |t              s S |j                  v s%t
        c S  S rW   )reversedrS   rO   r   r[   r   )rI   m
entrypointr   s     r:   route_tool_responsesz0create_react_agent.<locals>.route_tool_responses  sP    *5*=> 	Aa-  vv--
		
 r9   )*rf   r   r   r   r?   r.   rO   r%   r   tools_by_namevaluesrb   langchain.chat_modelsr   ImportErrorr   r   r   r   
bind_toolsri   return_directr[   rG   r   boolr   rg   r   r   pydanticr   r   r    add_noder)   add_edgeset_entry_pointcompiler
   r   add_conditional_edges)&r{   r|   rT   r   r   r   r   r   r   r   r   r   r   r[   required_keysschema_keysmissing_keystool_classesr   tool_calling_enabledtr   r   r   input_schemar   r   r   workflowr   should_continue_destinationsr   r   r   r   r   r   r   s&   `  ```  `   ``                  @@@@@@r:   create_react_agentr    s   @ l"wi'NO
 	
 #%67&34.67(3{+;;;<;7~EUVWW * - 	 %"E//6689	UO	I33::<=%	 ]OE$:;|,q0%.3G]E*55lC)&1E9N -9LqAOOAFFL
k 
[ 
T 
&k k 2(+ (~ (+ ( ($( (n ( ( ($ !lD)jy.Q-'&$($4c#:%L5| 5 0L#11$21	111$21	1  l-HZ5 	 	

 %.?.8)J J  ,&. 02O g'EF%-+   
 	
P{ PuS$Y/? P P$ ,4*MRH !*k:,   gy) !*N;*G4%

 Z( "*,.K	
 	8#>(/1O'P$(/~$ "" 	- # K C  &&)Z4E 	' 	
 	':.
 !)'   Q  	 F 	  Ms   2Q# Q;-Q;#Q8)r  create_tool_calling_executorr.   r<   r?   rF   rN   )Trx   rc   typingr   r   r   r   r   r   r	   r
   r   r   langchain_core.language_modelsr   r   r   langchain_core.messagesr   r   r   r   r   langchain_core.runnablesr   r   r   r   langchain_core.toolsr   r   r   typing_extensionsr   r   langgraph.errorsr   r   langgraph.graphr   r    langgraph.graph.graphr!   langgraph.graph.messager"   langgraph.managedr#   r$   langgraph.prebuilt.tool_noder%   langgraph.store.baser&   langgraph.typesr'   r(   langgraph.utils.runnabler)   r*   rP   rC   rg   r   r+   r.   r<   r?   rF   rG   StateSchemaTypera   rb   rH   rS   ri   rz   r   r   r   r   r   r   r  r  __all__r8   r9   r:   <module>r     s-       
   *  2 < + / 0 8 1 * . C4?+  tI!67 CxS)*$ $) ),z ,,/A , m5=O1O+PQ{# 	k]../[,,-/
K c C 3 !&!1 !h !Ha A *)/ )8J )t )X' M .${#$	$> 
  $ 	-1.2)-+/!%,0+/#'#p
''(p
%( 234h>?p
 V	p

 &c3K.K(LLMp
 \*p
 ?+p
 DI&p
 <(p
 Ip
 tCy)p
 d3i(p
 p
  Z !p
" 3-#p
$ %p
 p
h  2 r9   