{"version":3,"file":"index.cjs","names":["FunctionMessage","AIMessage","Agent","OpenAIFunctionsAgentOutputParser","PREFIX","ChatPromptTemplate","SystemMessagePromptTemplate","MessagesPlaceholder","HumanMessagePromptTemplate","LLMChain","AgentRunnableSequence","RunnablePassthrough","formatToOpenAIFunctionMessages"],"sources":["../../../src/agents/openai_functions/index.ts"],"sourcesContent":["import type {\n  BaseLanguageModelInterface,\n  BaseLanguageModelInput,\n  BaseFunctionCallOptions,\n} from \"@langchain/core/language_models/base\";\nimport type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport { Runnable, RunnablePassthrough } from \"@langchain/core/runnables\";\nimport { ChatOpenAI, ChatOpenAICallOptions } from \"@langchain/openai\";\nimport type {\n  AgentAction,\n  AgentFinish,\n  AgentStep,\n} from \"@langchain/core/agents\";\nimport { convertToOpenAIFunction } from \"@langchain/core/utils/function_calling\";\nimport {\n  AIMessage,\n  BaseMessage,\n  FunctionMessage,\n  SystemMessage,\n  BaseMessageChunk,\n} from \"@langchain/core/messages\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\nimport {\n  ChatPromptTemplate,\n  HumanMessagePromptTemplate,\n  MessagesPlaceholder,\n  SystemMessagePromptTemplate,\n  BasePromptTemplate,\n} from \"@langchain/core/prompts\";\nimport { CallbackManager } from \"@langchain/core/callbacks/manager\";\nimport { Agent, AgentArgs, AgentRunnableSequence } from \"../agent.js\";\nimport { AgentInput } from \"../types.js\";\nimport { PREFIX } from \"./prompt.js\";\nimport { LLMChain } from \"../../chains/llm_chain.js\";\nimport {\n  FunctionsAgentAction,\n  OpenAIFunctionsAgentOutputParser,\n} from \"../openai/output_parser.js\";\nimport { formatToOpenAIFunctionMessages } from \"../format_scratchpad/openai_functions.js\";\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\ntype CallOptionsIfAvailable<T> = T extends { CallOptions: infer CO } ? CO : any;\n\n/**\n * Checks if the given action is a FunctionsAgentAction.\n * @param action The action to check.\n * @returns True if the action is a FunctionsAgentAction, false otherwise.\n */\nfunction isFunctionsAgentAction(\n  action: AgentAction | FunctionsAgentAction\n): action is FunctionsAgentAction {\n  return (action as FunctionsAgentAction).messageLog !== undefined;\n}\n\nfunction _convertAgentStepToMessages(\n  action: AgentAction | FunctionsAgentAction,\n  observation: string\n) {\n  if (isFunctionsAgentAction(action) && action.messageLog !== undefined) {\n    return action.messageLog?.concat(\n      new FunctionMessage(observation, action.tool)\n    );\n  } else {\n    return [new AIMessage(action.log)];\n  }\n}\n\nexport function _formatIntermediateSteps(\n  intermediateSteps: AgentStep[]\n): BaseMessage[] {\n  return intermediateSteps.flatMap(({ action, observation }) =>\n    _convertAgentStepToMessages(action, observation)\n  );\n}\n\n/**\n * Interface for the input data required to create an OpenAIAgent.\n */\nexport interface OpenAIAgentInput extends AgentInput {\n  tools: StructuredToolInterface[];\n}\n\n/**\n * Interface for the arguments required to create a prompt for an\n * OpenAIAgent.\n */\nexport interface OpenAIAgentCreatePromptArgs {\n  prefix?: string;\n  systemMessage?: SystemMessage;\n}\n\n/**\n * Class representing an agent for the OpenAI chat model in LangChain. It\n * extends the Agent class and provides additional functionality specific\n * to the OpenAIAgent type.\n */\nexport class OpenAIAgent extends Agent {\n  static lc_name() {\n    return \"OpenAIAgent\";\n  }\n\n  lc_namespace = [\"langchain\", \"agents\", \"openai\"];\n\n  _agentType() {\n    return \"openai-functions\" as const;\n  }\n\n  observationPrefix() {\n    return \"Observation: \";\n  }\n\n  llmPrefix() {\n    return \"Thought:\";\n  }\n\n  _stop(): string[] {\n    return [\"Observation:\"];\n  }\n\n  tools: StructuredToolInterface[];\n\n  outputParser: OpenAIFunctionsAgentOutputParser =\n    new OpenAIFunctionsAgentOutputParser();\n\n  constructor(input: Omit<OpenAIAgentInput, \"outputParser\">) {\n    super({ ...input, outputParser: undefined });\n    this.tools = input.tools;\n  }\n\n  /**\n   * Creates a prompt for the OpenAIAgent using the provided tools and\n   * fields.\n   * @param _tools The tools to be used in the prompt.\n   * @param fields Optional fields for creating the prompt.\n   * @returns A BasePromptTemplate object representing the created prompt.\n   */\n  static createPrompt(\n    _tools: StructuredToolInterface[],\n    fields?: OpenAIAgentCreatePromptArgs\n  ): BasePromptTemplate {\n    const { prefix = PREFIX } = fields || {};\n    return ChatPromptTemplate.fromMessages([\n      SystemMessagePromptTemplate.fromTemplate(prefix),\n      new MessagesPlaceholder(\"chat_history\"),\n      HumanMessagePromptTemplate.fromTemplate(\"{input}\"),\n      new MessagesPlaceholder(\"agent_scratchpad\"),\n    ]);\n  }\n\n  /**\n   * Creates an OpenAIAgent from a BaseLanguageModel and a list of tools.\n   * @param llm The BaseLanguageModel to use.\n   * @param tools The tools to be used by the agent.\n   * @param args Optional arguments for creating the agent.\n   * @returns An instance of OpenAIAgent.\n   */\n  static fromLLMAndTools(\n    llm: BaseLanguageModelInterface,\n    tools: StructuredToolInterface[],\n    args?: OpenAIAgentCreatePromptArgs & Pick<AgentArgs, \"callbacks\">\n  ) {\n    OpenAIAgent.validateTools(tools);\n    if (llm._modelType() !== \"base_chat_model\" || llm._llmType() !== \"openai\") {\n      throw new Error(\"OpenAIAgent requires an OpenAI chat model\");\n    }\n    const prompt = OpenAIAgent.createPrompt(tools, args);\n    const chain = new LLMChain({\n      prompt,\n      llm,\n      callbacks: args?.callbacks,\n    });\n    return new OpenAIAgent({\n      llmChain: chain,\n      allowedTools: tools.map((t) => t.name),\n      tools,\n    });\n  }\n\n  /**\n   * Constructs a scratch pad from a list of agent steps.\n   * @param steps The steps to include in the scratch pad.\n   * @returns A string or a list of BaseMessages representing the constructed scratch pad.\n   */\n  async constructScratchPad(\n    steps: AgentStep[]\n  ): Promise<string | BaseMessage[]> {\n    return _formatIntermediateSteps(steps);\n  }\n\n  /**\n   * Plans the next action or finish state of the agent based on the\n   * provided steps, inputs, and optional callback manager.\n   * @param steps The steps to consider in planning.\n   * @param inputs The inputs to consider in planning.\n   * @param callbackManager Optional CallbackManager to use in planning.\n   * @returns A Promise that resolves to an AgentAction or AgentFinish object representing the planned action or finish state.\n   */\n  async plan(\n    steps: Array<AgentStep>,\n    inputs: ChainValues,\n    callbackManager?: CallbackManager\n  ): Promise<AgentAction | AgentFinish> {\n    // Add scratchpad and stop to inputs\n    const thoughts = await this.constructScratchPad(steps);\n    const newInputs: ChainValues = {\n      ...inputs,\n      agent_scratchpad: thoughts,\n    };\n    if (this._stop().length !== 0) {\n      newInputs.stop = this._stop();\n    }\n\n    // Split inputs between prompt and llm\n    const llm = this.llmChain.llm as\n      | ChatOpenAI\n      | Runnable<\n          BaseLanguageModelInput,\n          BaseMessageChunk,\n          ChatOpenAICallOptions\n        >;\n\n    const valuesForPrompt = { ...newInputs };\n    const valuesForLLM: CallOptionsIfAvailable<typeof llm> = {\n      functions: this.tools.map((tool) => convertToOpenAIFunction(tool)),\n    };\n    const callKeys =\n      \"callKeys\" in this.llmChain.llm ? this.llmChain.llm.callKeys : [];\n    for (const key of callKeys) {\n      if (key in inputs) {\n        valuesForLLM[key as keyof CallOptionsIfAvailable<typeof llm>] =\n          inputs[key];\n        delete valuesForPrompt[key];\n      }\n    }\n\n    const promptValue =\n      await this.llmChain.prompt.formatPromptValue(valuesForPrompt);\n\n    const message = await (\n      llm as Runnable<\n        BaseLanguageModelInput,\n        BaseMessageChunk,\n        ChatOpenAICallOptions\n      >\n    ).invoke(promptValue.toChatMessages(), {\n      ...valuesForLLM,\n      callbacks: callbackManager,\n    });\n    return this.outputParser.parseAIMessage(message);\n  }\n}\n\n/**\n * Params used by the createOpenAIFunctionsAgent function.\n */\nexport type CreateOpenAIFunctionsAgentParams = {\n  /**\n   * LLM to use as the agent. Should work with OpenAI function calling,\n   * so must either be an OpenAI model that supports that or a wrapper of\n   * a different model that adds in equivalent support.\n   */\n  llm: BaseChatModel<BaseFunctionCallOptions>;\n  /** Tools this agent has access to. */\n  tools: StructuredToolInterface[];\n  /** The prompt to use, must have an input key for `agent_scratchpad`. */\n  prompt: ChatPromptTemplate;\n  /**\n   * Whether to invoke the underlying model in streaming mode,\n   * allowing streaming of intermediate steps. Defaults to true.\n   */\n  streamRunnable?: boolean;\n};\n\n/**\n * Create an agent that uses OpenAI-style function calling.\n * @param params Params required to create the agent. Includes an LLM, tools, and prompt.\n * @returns A runnable sequence representing an agent. It takes as input all the same input\n *     variables as the prompt passed in does. It returns as output either an\n *     AgentAction or AgentFinish.\n *\n * @example\n * ```typescript\n * import { AgentExecutor, createOpenAIFunctionsAgent } from \"langchain/agents\";\n * import { pull } from \"langchain/hub\";\n * import type { ChatPromptTemplate } from \"@langchain/core/prompts\";\n * import { AIMessage, HumanMessage } from \"@langchain/core/messages\";\n *\n * import { ChatOpenAI } from \"@langchain/openai\";\n *\n * // Define the tools the agent will have access to.\n * const tools = [...];\n *\n * // Get the prompt to use - you can modify this!\n * // If you want to see the prompt in full, you can at:\n * // https://smith.langchain.com/hub/hwchase17/openai-functions-agent\n * const prompt = await pull<ChatPromptTemplate>(\n *   \"hwchase17/openai-functions-agent\"\n * );\n *\n * const llm = new ChatOpenAI({\n *   model: \"gpt-4o-mini\",\n *   temperature: 0,\n * });\n *\n * const agent = await createOpenAIFunctionsAgent({\n *   llm,\n *   tools,\n *   prompt,\n * });\n *\n * const agentExecutor = new AgentExecutor({\n *   agent,\n *   tools,\n * });\n *\n * const result = await agentExecutor.invoke({\n *   input: \"what is LangChain?\",\n * });\n *\n * // With chat history\n * const result2 = await agentExecutor.invoke({\n *   input: \"what's my name?\",\n *   chat_history: [\n *     new HumanMessage(\"hi! my name is cob\"),\n *     new AIMessage(\"Hello Cob! How can I assist you today?\"),\n *   ],\n * });\n * ```\n */\nexport async function createOpenAIFunctionsAgent({\n  llm,\n  tools,\n  prompt,\n  streamRunnable,\n}: CreateOpenAIFunctionsAgentParams) {\n  if (!prompt.inputVariables.includes(\"agent_scratchpad\")) {\n    throw new Error(\n      [\n        `Prompt must have an input variable named \"agent_scratchpad\".`,\n        `Found ${JSON.stringify(prompt.inputVariables)} instead.`,\n      ].join(\"\\n\")\n    );\n  }\n  const llmWithTools = llm.bindTools\n    ? llm.bindTools(tools)\n    : llm.withConfig({\n        functions: tools.map((tool) => convertToOpenAIFunction(tool)),\n      });\n  const agent = AgentRunnableSequence.fromRunnables(\n    [\n      RunnablePassthrough.assign({\n        agent_scratchpad: (input: { steps: AgentStep[] }) =>\n          formatToOpenAIFunctionMessages(input.steps),\n      }),\n      prompt,\n      llmWithTools,\n      new OpenAIFunctionsAgentOutputParser(),\n    ],\n    {\n      name: \"OpenAIFunctionsAgent\",\n      streamRunnable,\n      singleAction: true,\n    }\n  );\n  return agent;\n}\n"],"mappings":"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"}