
    gh4                     b   d Z ddlmZ ddlmZmZ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 ddlmZmZ dd	lmZ dd
lmZmZ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# ddl$m%Z% ddl&m'Z' ddl(m)Z) ddl*m+Z+  eddd           G d de'                      Z,dedee         dedefdZ-dS )zHModule implements an agent that uses OpenAI's APIs function enabled API.    )Sequence)AnyOptionalUnion)
deprecated)AgentActionAgentFinish)BaseCallbackManager	Callbacks)BaseLanguageModel)BaseMessageSystemMessage)BasePromptTemplate)BaseMessagePromptTemplateChatPromptTemplateHumanMessagePromptTemplateMessagesPlaceholder)RunnableRunnablePassthrough)BaseToolconvert_to_openai_function)model_validator)Self)BaseSingleActionAgent"format_to_openai_function_messages) OpenAIFunctionsAgentOutputParserz0.1.0create_openai_functions_agentz1.0)alternativeremovalc                      e Zd ZU dZeed<   ee         ed<   eed<   e	Z
ee	         ed<   dee         fdZ ed	          defd
            Zedee         fd            Zedee         fd            Z	 	 ddeeeef                  dedededeeef         f
dZ	 ddeeeef                  dededeeef         fdZdedeeeef                  dedefdZe  e!d          dfde"e!         de"ee#                  de$fd            Z%e dd e!d          fdedee         de"e&         de"ee#                  de"e!         dede'fd            Z(dS ) OpenAIFunctionsAgentaz  An Agent driven by OpenAIs function powered API.

    Args:
        llm: This should be an instance of ChatOpenAI, specifically a model
            that supports using `functions`.
        tools: The tools this agent has access to.
        prompt: The prompt for this agent, should support agent_scratchpad as one
            of the variables. For an easy way to construct this prompt, use
            `OpenAIFunctionsAgent.create_prompt(...)`
        output_parser: The output parser for this agent. Should be an instance of
            OpenAIFunctionsAgentOutputParser.
            Defaults to OpenAIFunctionsAgentOutputParser.
    llmtoolspromptoutput_parserreturnc                 $    d | j         D             S )zGet allowed tools.c                     g | ]	}|j         
S  )name.0ts     i/var/www/FlaskApp/flask-venv/lib/python3.11/site-packages/langchain/agents/openai_functions_agent/base.py
<listcomp>z:OpenAIFunctionsAgent.get_allowed_tools.<locals>.<listcomp>=   s    +++1+++    r%   selfs    r0   get_allowed_toolsz&OpenAIFunctionsAgent.get_allowed_tools;   s    ++
++++r2   after)modec                 T    | j         }d|j        vrt          d|j                   | S )zValidate prompt.

        Args:
            values: Values to validate.

        Returns:
            Validated values.

        Raises:
            ValueError: If `agent_scratchpad` is not in the prompt.
        agent_scratchpadzE`agent_scratchpad` should be one of the variables in the prompt, got )r&   input_variables
ValueError)r5   r&   s     r0   validate_promptz$OpenAIFunctionsAgent.validate_prompt?   sG     &*[V%;;;0-0 0   r2   c                     dgS )z0Get input keys. Input refers to user input here.inputr+   r4   s    r0   
input_keyszOpenAIFunctionsAgent.input_keysT   s     yr2   c                 $    d | j         D             S )zGet functions.c                 F    g | ]}t          t          |                    S r+   )dictr   r-   s     r0   r1   z2OpenAIFunctionsAgent.functions.<locals>.<listcomp>]   s)    HHH/2233HHHr2   r3   r4   s    r0   	functionszOpenAIFunctionsAgent.functionsY   s     IHTZHHHHr2   NTintermediate_steps	callbackswith_functionskwargsc                 x   t          |          }fd| j        j        D             }t          di |d|i} | j        j        di |}|                                }	|r#| j                            |	| j        |          }
n| j                            |	|          }
| j	        
                    |
          }|S )a
  Given input, decided what to do.

        Args:
            intermediate_steps: Steps the LLM has taken to date,
                along with observations.
            callbacks: Callbacks to use. Defaults to None.
            with_functions: Whether to use functions. Defaults to True.
            **kwargs: User inputs.

        Returns:
            Action specifying what tool to use.
            If the agent is finished, returns an AgentFinish.
            If the agent is not finished, returns an AgentAction.
        c                 .    i | ]}|d k    ||         S r:   r+   r.   krH   s     r0   
<dictcomp>z-OpenAIFunctionsAgent.plan.<locals>.<dictcomp>u   1     
 
 
FXAXAXAvayAXAXAXr2   r:   rD   rF   )rF   r+   )r   r&   r;   rC   format_promptto_messagesr$   predict_messagesrD   r'   _parse_ai_message)r5   rE   rF   rG   rH   r:   selected_inputsfull_inputsr&   messagespredicted_messageagent_decisions       `       r0   planzOpenAIFunctionsAgent.plan_   s   * >>PQQ
 
 
 
"&+"=
 
 
 PP_PP?OPPP**99[99%%'' 
	 $ 9 9.# !: ! ! !% 9 9# !: ! ! +==>OPPr2   c                 J  K   t          |          }fd| j        j        D             }t          di |d|i} | j        j        di |}|                                }| j                            || j        |           d{V }	| j	        
                    |	          }
|
S )a  Async given input, decided what to do.

        Args:
            intermediate_steps: Steps the LLM has taken to date,
                along with observations.
            callbacks: Callbacks to use. Defaults to None.
            **kwargs: User inputs.

        Returns:
            Action specifying what tool to use.
            If the agent is finished, returns an AgentFinish.
            If the agent is not finished, returns an AgentAction.
        c                 .    i | ]}|d k    ||         S rK   r+   rL   s     r0   rN   z.OpenAIFunctionsAgent.aplan.<locals>.<dictcomp>   rO   r2   r:   rP   Nr+   )r   r&   r;   rC   rQ   rR   r$   apredict_messagesrD   r'   rT   )r5   rE   rF   rH   r:   rU   rV   r&   rW   rX   rY   s      `       r0   aplanzOpenAIFunctionsAgent.aplan   s      & >>PQQ
 
 
 
"&+"=
 
 
 PP_PP?OPPP**99[99%%''"&("<"<) #= #
 #
 
 
 
 
 
 
 +==>OPPr2   early_stopping_methodc                     |dk    rt          ddid          S |dk    r9 | j        |fddi|}t          |t                     r|S t          d|           t          d	|           )
a  Return response when agent has been stopped due to max iterations.

        Args:
            early_stopping_method: The early stopping method to use.
            intermediate_steps: Intermediate steps.
            **kwargs: User inputs.

        Returns:
            AgentFinish.

        Raises:
            ValueError: If `early_stopping_method` is not `force` or `generate`.
            ValueError: If `agent_decision` is not an AgentAction.
        forceoutputz3Agent stopped due to iteration limit or time limit. generaterG   Fz,got AgentAction with no functions provided: zBearly_stopping_method should be one of `force` or `generate`, got )r	   rZ   
isinstancer<   )r5   r_   rE   rH   rY   s        r0   return_stopped_responsez,OpenAIFunctionsAgent.return_stopped_response   s    ( !G++PQSU   #j00&TY" 38<B N .+66 %% S>SS   /,/ /  r2   zYou are a helpful AI assistant.)contentsystem_messageextra_prompt_messagesc                     |pg }|r|g}ng }|                     g |t          j        d          t          d                     t	          |          S )a  Create prompt for this agent.

        Args:
            system_message: Message to use as the system message that will be the
                first in the prompt.
            extra_prompt_messages: Prompt messages that will be placed between the
                system message and the new human input.

        Returns:
            A prompt template to pass into this agent.
        z{input}r:   )variable_name)rW   )extendr   from_templater   r   )clsrh   ri   _promptsrW   s        r0   create_promptz"OpenAIFunctionsAgent.create_prompt   s    & ).B 	&'HHH*8CC $2DEEE	
 	
 	
 "84444r2   callback_managerc                 J    |                      ||          } | d||||d|S )a  Construct an agent from an LLM and tools.

        Args:
            llm: The LLM to use as the agent.
            tools: The tools to use.
            callback_manager: The callback manager to use. Defaults to None.
            extra_prompt_messages: Extra prompt messages to use. Defaults to None.
            system_message: The system message to use.
                Defaults to a default system message.
            kwargs: Additional parameters to pass to the agent.
        )ri   rh   )r$   r&   r%   rq   r+   )rp   )rn   r$   r%   rq   ri   rh   rH   r&   s           r0   from_llm_and_toolsz'OpenAIFunctionsAgent.from_llm_and_tools   sZ    . """7) # 
 
 s 
-	
 

 
 
 	
r2   )NT)N))__name__
__module____qualname____doc__r   __annotations__r   r   r   r   r'   typeliststrr6   r   r   r=   propertyr@   rC   rD   tupler   r   boolr   r   r	   rZ   r^   rf   classmethodr   r   r   r   rp   r
   r   rs   r+   r2   r0   r#   r#   $   sB          
H( 489   ,49 , , , , _'"""    #"( DI    X I4: I I I XI  $#	( ( {C'7!89( ( 	(
 ( 
{K'	(( ( ( (Z  $  {C'7!89  	
 
{K'	(   @("( !{C'7!89( 	(
 
( ( ( (T  3@-53
 3
 3
 LP 5  5 / 5
  (-F(GH 5 
 5  5  5 [ 5D 
 ;?KO2?-53
 3
 3
 
  
 
 ! 
 ##67	 

  (-F(GH 
 !/ 
  
 
 
  
  
 [ 
  
  
r2   r#   r$   r%   r&   r(   c                    d|j         t          |j                  z   vrt          d|j          d          |                     d |D                       }t          j        d           |z  |z  t                      z  }|S )a	  Create an agent that uses OpenAI function calling.

    Args:
        llm: LLM to use as the agent. Should work with OpenAI function calling,
            so either be an OpenAI model that supports that or a wrapper of
            a different model that adds in equivalent support.
        tools: Tools this agent has access to.
        prompt: The prompt to use. See Prompt section below for more.

    Returns:
        A Runnable sequence representing an agent. It takes as input all the same input
            variables as the prompt passed in does. It returns as output either an
            AgentAction or AgentFinish.

    Raises:
        ValueError: If `agent_scratchpad` is not in the prompt.

    Example:

        Creating an agent with no memory

        .. code-block:: python

            from langchain_community.chat_models import ChatOpenAI
            from langchain.agents import AgentExecutor, create_openai_functions_agent
            from langchain import hub

            prompt = hub.pull("hwchase17/openai-functions-agent")
            model = ChatOpenAI()
            tools = ...

            agent = create_openai_functions_agent(model, tools, prompt)
            agent_executor = AgentExecutor(agent=agent, tools=tools)

            agent_executor.invoke({"input": "hi"})

            # Using with chat history
            from langchain_core.messages import AIMessage, HumanMessage
            agent_executor.invoke(
                {
                    "input": "what's my name?",
                    "chat_history": [
                        HumanMessage(content="hi! my name is bob"),
                        AIMessage(content="Hello Bob! How can I assist you today?"),
                    ],
                }
            )

    Prompt:

        The agent prompt must have an `agent_scratchpad` key that is a
            ``MessagesPlaceholder``. Intermediate agent actions and tool output
            messages will be passed in here.

        Here's an example:

        .. code-block:: python

            from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

            prompt = ChatPromptTemplate.from_messages(
                [
                    ("system", "You are a helpful assistant"),
                    MessagesPlaceholder("chat_history", optional=True),
                    ("human", "{input}"),
                    MessagesPlaceholder("agent_scratchpad"),
                ]
            )
    r:   zLPrompt must have input variable `agent_scratchpad`, but wasn't found. Found z	 instead.c                 ,    g | ]}t          |          S r+   r   r-   s     r0   r1   z1create_openai_functions_agent.<locals>.<listcomp>i  s!    (V(V(V1)CA)F)F(V(V(Vr2   )rD   c                 ,    t          | d                   S )NrE   r   )xs    r0   <lambda>z/create_openai_functions_agent.<locals>.<lambda>l  s    'I&'( ( r2   rK   )r;   rz   partial_variablesr<   bindr   assignr   )r$   r%   r&   llm_with_toolsagents        r0   r   r     s    P f&>!?!??  7+7 7 7
 
 	
 XX(V(VPU(V(V(VXWWN" 	
 	
 	

 	 	 +
,
,	- 
 Lr2   N).rw   collections.abcr   typingr   r   r   langchain_core._apir   langchain_core.agentsr   r	   langchain_core.callbacksr
   r   langchain_core.language_modelsr   langchain_core.messagesr   r   langchain_core.promptsr   langchain_core.prompts.chatr   r   r   r   langchain_core.runnablesr   r   langchain_core.toolsr   %langchain_core.utils.function_callingr   pydanticr   typing_extensionsr   langchain.agentsr   3langchain.agents.format_scratchpad.openai_functionsr   0langchain.agents.output_parsers.openai_functionsr   r#   r   r+   r2   r0   <module>r      sY   N N $ $ $ $ $ $ ' ' ' ' ' ' ' ' ' ' * * * * * * : : : : : : : : C C C C C C C C < < < < < <        6 5 5 5 5 5            C B B B B B B B ) ) ) ) ) ) L L L L L L $ $ $ $ $ $ " " " " " " 2 2 2 2 2 2          
 G!@%PPPr
 r
 r
 r
 r
0 r
 r
 QPr
jZ	Z#+H#5Z?QZZ Z Z Z Z Zr2   