{"version":3,"file":"index.cjs","names":["Agent","StructuredChatOutputParserWithRetries","PREFIX","SUFFIX","SystemMessagePromptTemplate","PromptTemplate","FORMAT_INSTRUCTIONS","HumanMessagePromptTemplate","ChatPromptTemplate","LLMChain","isOpenAITool","isStructuredTool","renderTextDescriptionAndArgs","AgentRunnableSequence","RunnablePassthrough","formatLogToString"],"sources":["../../../src/agents/structured_chat/index.ts"],"sourcesContent":["import type { StructuredToolInterface } from \"@langchain/core/tools\";\nimport {\n  isOpenAITool,\n  type BaseLanguageModel,\n  type BaseLanguageModelInterface,\n  type ToolDefinition,\n} from \"@langchain/core/language_models/base\";\nimport { RunnablePassthrough } from \"@langchain/core/runnables\";\nimport type { BasePromptTemplate } from \"@langchain/core/prompts\";\nimport {\n  BaseMessagePromptTemplate,\n  ChatPromptTemplate,\n  HumanMessagePromptTemplate,\n  SystemMessagePromptTemplate,\n  PromptTemplate,\n} from \"@langchain/core/prompts\";\nimport { AgentStep } from \"@langchain/core/agents\";\nimport { isStructuredTool } from \"@langchain/core/utils/function_calling\";\nimport { isInteropZodSchema } from \"@langchain/core/utils/types\";\nimport {\n  type JsonSchema7Type,\n  toJsonSchema,\n} from \"@langchain/core/utils/json_schema\";\nimport { LLMChain } from \"../../chains/llm_chain.js\";\nimport { Optional } from \"../../types/type-utils.js\";\nimport {\n  Agent,\n  AgentArgs,\n  AgentRunnableSequence,\n  OutputParserArgs,\n} from \"../agent.js\";\nimport { AgentInput } from \"../types.js\";\nimport { StructuredChatOutputParserWithRetries } from \"./outputParser.js\";\nimport { FORMAT_INSTRUCTIONS, PREFIX, SUFFIX } from \"./prompt.js\";\nimport { renderTextDescriptionAndArgs } from \"../../tools/render.js\";\nimport { formatLogToString } from \"../format_scratchpad/log.js\";\n\n/**\n * Interface for arguments used to create a prompt for a\n * StructuredChatAgent.\n */\nexport interface StructuredChatCreatePromptArgs {\n  /** String to put after the list of tools. */\n  suffix?: string;\n  /** String to put before the list of tools. */\n  prefix?: string;\n  /** String to use directly as the human message template. */\n  humanMessageTemplate?: string;\n  /** List of input variables the final prompt will expect. */\n  inputVariables?: string[];\n  /** List of historical prompts from memory.  */\n  memoryPrompts?: BaseMessagePromptTemplate[];\n}\n\n/**\n * Type for input data for creating a StructuredChatAgent, with the\n * 'outputParser' property made optional.\n */\nexport type StructuredChatAgentInput = Optional<AgentInput, \"outputParser\">;\n\n/**\n * Agent that interoperates with Structured Tools using React logic.\n * @augments Agent\n */\nexport class StructuredChatAgent extends Agent {\n  static lc_name() {\n    return \"StructuredChatAgent\";\n  }\n\n  lc_namespace = [\"langchain\", \"agents\", \"structured_chat\"];\n\n  constructor(input: StructuredChatAgentInput) {\n    const outputParser =\n      input?.outputParser ?? StructuredChatAgent.getDefaultOutputParser();\n    super({ ...input, outputParser });\n  }\n\n  _agentType() {\n    return \"structured-chat-zero-shot-react-description\" 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  /**\n   * Validates that all provided tools have a description. Throws an error\n   * if any tool lacks a description.\n   * @param tools Array of StructuredTool instances to validate.\n   */\n  static validateTools(tools: StructuredToolInterface[]) {\n    const descriptionlessTool = tools.find((tool) => !tool.description);\n    if (descriptionlessTool) {\n      const msg =\n        `Got a tool ${descriptionlessTool.name} without a description.` +\n        ` This agent requires descriptions for all tools.`;\n      throw new Error(msg);\n    }\n  }\n\n  /**\n   * Returns a default output parser for the StructuredChatAgent. If an LLM\n   * is provided, it creates an output parser with retry logic from the LLM.\n   * @param fields Optional fields to customize the output parser. Can include an LLM and a list of tool names.\n   * @returns An instance of StructuredChatOutputParserWithRetries.\n   */\n  static getDefaultOutputParser(\n    fields?: OutputParserArgs & {\n      toolNames: string[];\n    }\n  ) {\n    if (fields?.llm) {\n      return StructuredChatOutputParserWithRetries.fromLLM(fields.llm, {\n        toolNames: fields.toolNames,\n      });\n    }\n    return new StructuredChatOutputParserWithRetries({\n      toolNames: fields?.toolNames,\n    });\n  }\n\n  /**\n   * Constructs the agent's scratchpad from a list of steps. If the agent's\n   * scratchpad is not empty, it prepends a message indicating that the\n   * agent has not seen any previous work.\n   * @param steps Array of AgentStep instances to construct the scratchpad from.\n   * @returns A Promise that resolves to a string representing the agent's scratchpad.\n   */\n  async constructScratchPad(steps: AgentStep[]): Promise<string> {\n    const agentScratchpad = await super.constructScratchPad(steps);\n    if (agentScratchpad) {\n      return `This was your previous work (but I haven't seen any of it! I only see what you return as final answer):\\n${agentScratchpad}`;\n    }\n    return agentScratchpad;\n  }\n\n  /**\n   * Creates a string representation of the schemas of the provided tools.\n   * @param tools Array of StructuredTool instances to create the schemas string from.\n   * @returns A string representing the schemas of the provided tools.\n   */\n  static createToolSchemasString(tools: StructuredToolInterface[]) {\n    return tools\n      .map((tool) => {\n        const jsonSchema = (\n          isInteropZodSchema(tool.schema)\n            ? toJsonSchema(tool.schema)\n            : tool.schema\n        ) as { properties?: Record<string, JsonSchema7Type> } | undefined;\n        return `${tool.name}: ${tool.description}, args: ${JSON.stringify(\n          jsonSchema?.properties\n        )}`;\n      })\n      .join(\"\\n\");\n  }\n\n  /**\n   * Create prompt in the style of the agent.\n   *\n   * @param tools - List of tools the agent will have access to, used to format the prompt.\n   * @param args - Arguments to create the prompt with.\n   * @param args.suffix - String to put after the list of tools.\n   * @param args.prefix - String to put before the list of tools.\n   * @param args.inputVariables List of input variables the final prompt will expect.\n   * @param args.memoryPrompts List of historical prompts from memory.\n   */\n  static createPrompt(\n    tools: StructuredToolInterface[],\n    args?: StructuredChatCreatePromptArgs\n  ) {\n    const {\n      prefix = PREFIX,\n      suffix = SUFFIX,\n      inputVariables = [\"input\", \"agent_scratchpad\"],\n      humanMessageTemplate = \"{input}\\n\\n{agent_scratchpad}\",\n      memoryPrompts = [],\n    } = args ?? {};\n    const template = [prefix, FORMAT_INSTRUCTIONS, suffix].join(\"\\n\\n\");\n    const messages = [\n      new SystemMessagePromptTemplate(\n        new PromptTemplate({\n          template,\n          inputVariables,\n          partialVariables: {\n            tool_schemas: StructuredChatAgent.createToolSchemasString(tools),\n            tool_names: tools.map((tool) => tool.name).join(\", \"),\n          },\n        })\n      ),\n      ...memoryPrompts,\n      new HumanMessagePromptTemplate(\n        new PromptTemplate({\n          template: humanMessageTemplate,\n          inputVariables,\n        })\n      ),\n    ];\n    return ChatPromptTemplate.fromMessages(messages);\n  }\n\n  /**\n   * Creates a StructuredChatAgent from an LLM and a list of tools.\n   * Validates the tools, creates a prompt, and sets up an LLM chain for the\n   * agent.\n   * @param llm BaseLanguageModel instance to create the agent from.\n   * @param tools Array of StructuredTool instances to create the agent from.\n   * @param args Optional arguments to customize the creation of the agent. Can include arguments for creating the prompt and AgentArgs.\n   * @returns A new instance of StructuredChatAgent.\n   */\n  static fromLLMAndTools(\n    llm: BaseLanguageModelInterface,\n    tools: StructuredToolInterface[],\n    args?: StructuredChatCreatePromptArgs & AgentArgs\n  ) {\n    StructuredChatAgent.validateTools(tools);\n    const prompt = StructuredChatAgent.createPrompt(tools, args);\n    const outputParser =\n      args?.outputParser ??\n      StructuredChatAgent.getDefaultOutputParser({\n        llm,\n        toolNames: tools.map((tool) => tool.name),\n      });\n    const chain = new LLMChain({\n      prompt,\n      llm,\n      callbacks: args?.callbacks,\n    });\n\n    return new StructuredChatAgent({\n      llmChain: chain,\n      outputParser,\n      allowedTools: tools.map((t) => t.name),\n    });\n  }\n}\n\n/**\n * Params used by the createStructuredChatAgent function.\n */\nexport type CreateStructuredChatAgentParams = {\n  /** LLM to use as the agent. */\n  llm: BaseLanguageModelInterface;\n  /** Tools this agent has access to. */\n  tools: (StructuredToolInterface | ToolDefinition)[];\n  /**\n   * The prompt to use. Must have input keys for\n   * `tools`, `tool_names`, and `agent_scratchpad`.\n   */\n  prompt: BasePromptTemplate;\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 aimed at supporting tools with multiple inputs.\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, createStructuredChatAgent } 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/structured-chat-agent\n * const prompt = await pull<ChatPromptTemplate>(\n *   \"hwchase17/structured-chat-agent\"\n * );\n *\n * const llm = new ChatOpenAI({\n *   temperature: 0,\n *   model: \"gpt-3.5-turbo-1106\",\n * });\n *\n * const agent = await createStructuredChatAgent({\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 createStructuredChatAgent({\n  llm,\n  tools,\n  prompt,\n  streamRunnable,\n}: CreateStructuredChatAgentParams) {\n  const missingVariables = [\"tools\", \"tool_names\", \"agent_scratchpad\"].filter(\n    (v) => !prompt.inputVariables.includes(v)\n  );\n  if (missingVariables.length > 0) {\n    throw new Error(\n      `Provided prompt is missing required input variables: ${JSON.stringify(\n        missingVariables\n      )}`\n    );\n  }\n  let toolNames: string[] = [];\n  if (tools.every(isOpenAITool)) {\n    toolNames = tools.map((tool) => tool.function.name);\n  } else if (tools.every(isStructuredTool)) {\n    toolNames = tools.map((tool) => tool.name);\n  } else {\n    throw new Error(\n      \"All tools must be either OpenAI or Structured tools, not a mix.\"\n    );\n  }\n  const partialedPrompt = await prompt.partial({\n    tools: renderTextDescriptionAndArgs(tools),\n    tool_names: toolNames.join(\", \"),\n  });\n  // TODO: Add .bind to core runnable interface.\n  const llmWithStop = (llm as BaseLanguageModel).withConfig({\n    stop: [\"Observation\"],\n  });\n  const agent = AgentRunnableSequence.fromRunnables(\n    [\n      RunnablePassthrough.assign({\n        agent_scratchpad: (input: { steps: AgentStep[] }) =>\n          formatLogToString(input.steps),\n      }),\n      partialedPrompt,\n      llmWithStop,\n      StructuredChatOutputParserWithRetries.fromLLM(llm, {\n        toolNames,\n      }),\n    ],\n    {\n      name: \"StructuredChatAgent\",\n      streamRunnable,\n      singleAction: true,\n    }\n  );\n  return agent;\n}\n"],"mappings":"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"}