Home / File/ openai_functions.py — langchain Source File

openai_functions.py — langchain Source File

Architecture documentation for openai_functions.py, a python file in the langchain codebase. 7 imports, 0 dependents.

Entity Profile

Dependency Diagram

graph LR
  3a6df24c_7bea_5f3b_0f9d_b4754b06c94e["openai_functions.py"]
  d6fe6653_f36c_cb5d_8853_46c26a36510e["json.py"]
  3a6df24c_7bea_5f3b_0f9d_b4754b06c94e --> d6fe6653_f36c_cb5d_8853_46c26a36510e
  59e0d3b0_0f8e_4b79_d442_e9b4821561c7["langchain_core.agents"]
  3a6df24c_7bea_5f3b_0f9d_b4754b06c94e --> 59e0d3b0_0f8e_4b79_d442_e9b4821561c7
  049d69ec_d53a_d170_b6fa_35c395793702["langchain_core.exceptions"]
  3a6df24c_7bea_5f3b_0f9d_b4754b06c94e --> 049d69ec_d53a_d170_b6fa_35c395793702
  9444498b_8066_55c7_b3a2_1d90c4162a32["langchain_core.messages"]
  3a6df24c_7bea_5f3b_0f9d_b4754b06c94e --> 9444498b_8066_55c7_b3a2_1d90c4162a32
  4382dc25_6fba_324a_49e2_e9742d579385["langchain_core.outputs"]
  3a6df24c_7bea_5f3b_0f9d_b4754b06c94e --> 4382dc25_6fba_324a_49e2_e9742d579385
  f85fae70_1011_eaec_151c_4083140ae9e5["typing_extensions"]
  3a6df24c_7bea_5f3b_0f9d_b4754b06c94e --> f85fae70_1011_eaec_151c_4083140ae9e5
  496466eb_d5c8_fece_1b1f_31541c641cdd["langchain_classic.agents.agent"]
  3a6df24c_7bea_5f3b_0f9d_b4754b06c94e --> 496466eb_d5c8_fece_1b1f_31541c641cdd
  style 3a6df24c_7bea_5f3b_0f9d_b4754b06c94e fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

import json
from json import JSONDecodeError

from langchain_core.agents import AgentAction, AgentActionMessageLog, AgentFinish
from langchain_core.exceptions import OutputParserException
from langchain_core.messages import (
    AIMessage,
    BaseMessage,
)
from langchain_core.outputs import ChatGeneration, Generation
from typing_extensions import override

from langchain_classic.agents.agent import AgentOutputParser


class OpenAIFunctionsAgentOutputParser(AgentOutputParser):
    """Parses a message into agent action/finish.

    Is meant to be used with OpenAI models, as it relies on the specific
    function_call parameter from OpenAI to convey what tools to use.

    If a function_call parameter is passed, then that is used to get
    the tool and tool input.

    If one is not passed, then the AIMessage is assumed to be the final output.
    """

    @property
    def _type(self) -> str:
        return "openai-functions-agent"

    @staticmethod
    def parse_ai_message(message: BaseMessage) -> AgentAction | AgentFinish:
        """Parse an AI message."""
        if not isinstance(message, AIMessage):
            msg = f"Expected an AI message got {type(message)}"
            raise TypeError(msg)

        function_call = message.additional_kwargs.get("function_call", {})

        if function_call:
            function_name = function_call["name"]
            try:
                if len(function_call["arguments"].strip()) == 0:
                    # OpenAI returns an empty string for functions containing no args
                    _tool_input = {}
                else:
                    # otherwise it returns a json object
                    _tool_input = json.loads(function_call["arguments"], strict=False)
            except JSONDecodeError as e:
                msg = (
                    f"Could not parse tool input: {function_call} because "
                    f"the `arguments` is not valid JSON."
                )
                raise OutputParserException(msg) from e

            # A hack here:
            # The code that encodes tool input into Open AI uses a special variable
            # name called `__arg1` to handle old style tools that do not expose a
            # schema and expect a single string argument as an input.
            # We unpack the argument here if it exists.
            # Open AI does not support passing in a JSON array as an argument.
            if "__arg1" in _tool_input:
                tool_input = _tool_input["__arg1"]
            else:
                tool_input = _tool_input

            content_msg = f"responded: {message.content}\n" if message.content else "\n"
            log = f"\nInvoking: `{function_name}` with `{tool_input}`\n{content_msg}\n"
            return AgentActionMessageLog(
                tool=function_name,
                tool_input=tool_input,
                log=log,
                message_log=[message],
            )

        return AgentFinish(
            return_values={"output": message.content},
            log=str(message.content),
        )

    @override
    def parse_result(
        self,
        result: list[Generation],
        *,
        partial: bool = False,
    ) -> AgentAction | AgentFinish:
        if not isinstance(result[0], ChatGeneration):
            msg = "This output parser only works on ChatGeneration output"
            raise ValueError(msg)  # noqa: TRY004
        message = result[0].message
        return self.parse_ai_message(message)

    @override
    def parse(self, text: str) -> AgentAction | AgentFinish:
        msg = "Can only parse messages"
        raise ValueError(msg)

Subdomains

Dependencies

  • json.py
  • langchain_classic.agents.agent
  • langchain_core.agents
  • langchain_core.exceptions
  • langchain_core.messages
  • langchain_core.outputs
  • typing_extensions

Frequently Asked Questions

What does openai_functions.py do?
openai_functions.py is a source file in the langchain codebase, written in python. It belongs to the AgentOrchestration domain, ClassicChains subdomain.
What does openai_functions.py depend on?
openai_functions.py imports 7 module(s): json.py, langchain_classic.agents.agent, langchain_core.agents, langchain_core.exceptions, langchain_core.messages, langchain_core.outputs, typing_extensions.
Where is openai_functions.py in the architecture?
openai_functions.py is located at libs/langchain/langchain_classic/agents/output_parsers/openai_functions.py (domain: AgentOrchestration, subdomain: ClassicChains, directory: libs/langchain/langchain_classic/agents/output_parsers).

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free