agsamantha/node_modules/langchain/dist/agents/structured_chat/outputParser.js

158 lines
6.2 KiB
JavaScript
Raw Normal View History

2024-10-02 15:15:21 -05:00
import { OutputParserException } from "@langchain/core/output_parsers";
import { renderTemplate } from "@langchain/core/prompts";
import { AgentActionOutputParser } from "../types.js";
import { AGENT_ACTION_FORMAT_INSTRUCTIONS, FORMAT_INSTRUCTIONS, } from "./prompt.js";
import { OutputFixingParser } from "../../output_parsers/fix.js";
/**
* A class that provides a custom implementation for parsing the output of
* a StructuredChatAgent action. It extends the `AgentActionOutputParser`
* class and extracts the action and action input from the text output,
* returning an `AgentAction` or `AgentFinish` object.
*/
export class StructuredChatOutputParser extends AgentActionOutputParser {
constructor(fields) {
super(...arguments);
Object.defineProperty(this, "lc_namespace", {
enumerable: true,
configurable: true,
writable: true,
value: ["langchain", "agents", "structured_chat"]
});
Object.defineProperty(this, "toolNames", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
this.toolNames = fields.toolNames;
}
/**
* Parses the given text and returns an `AgentAction` or `AgentFinish`
* object. If an `OutputFixingParser` is provided, it is used for parsing;
* otherwise, the base parser is used.
* @param text The text to parse.
* @param callbacks Optional callbacks for asynchronous operations.
* @returns A Promise that resolves to an `AgentAction` or `AgentFinish` object.
*/
async parse(text) {
try {
const regex = /```(?:json)?(.*)(```)/gs;
const actionMatch = regex.exec(text);
if (actionMatch === null) {
throw new OutputParserException(`Could not parse an action. The agent action must be within a markdown code block, and "action" must be a provided tool or "Final Answer"`);
}
const response = JSON.parse(actionMatch[1].trim());
const { action, action_input } = response;
if (action === "Final Answer") {
return { returnValues: { output: action_input }, log: text };
}
return { tool: action, toolInput: action_input || {}, log: text };
}
catch (e) {
throw new OutputParserException(`Failed to parse. Text: "${text}". Error: ${e}`);
}
}
/**
* Returns the format instructions for parsing the output of an agent
* action in the style of the StructuredChatAgent.
* @returns A string representing the format instructions.
*/
getFormatInstructions() {
return renderTemplate(AGENT_ACTION_FORMAT_INSTRUCTIONS, "f-string", {
tool_names: this.toolNames.join(", "),
});
}
}
/**
* A class that provides a wrapper around the `StructuredChatOutputParser`
* and `OutputFixingParser` classes. It extends the
* `AgentActionOutputParser` class and allows for retrying the output
* parsing using the `OutputFixingParser` if it is provided.
* @example
* ```typescript
* const outputParser = new StructuredChatOutputParserWithRetries.fromLLM(
* new ChatOpenAI({ temperature: 0 }),
* {
* toolNames: ["calculator", "random-number-generator"],
* },
* );
* const result = await outputParser.parse(
* "What is a random number between 5 and 10 raised to the second power?"
* );
* ```
*/
export class StructuredChatOutputParserWithRetries extends AgentActionOutputParser {
constructor(fields) {
super(fields);
Object.defineProperty(this, "lc_namespace", {
enumerable: true,
configurable: true,
writable: true,
value: ["langchain", "agents", "structured_chat"]
});
Object.defineProperty(this, "baseParser", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "outputFixingParser", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "toolNames", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
this.toolNames = fields.toolNames ?? this.toolNames;
this.baseParser =
fields?.baseParser ??
new StructuredChatOutputParser({ toolNames: this.toolNames });
this.outputFixingParser = fields?.outputFixingParser;
}
/**
* Parses the given text and returns an `AgentAction` or `AgentFinish`
* object. Throws an `OutputParserException` if the parsing fails.
* @param text The text to parse.
* @returns A Promise that resolves to an `AgentAction` or `AgentFinish` object.
*/
async parse(text, callbacks) {
if (this.outputFixingParser !== undefined) {
return this.outputFixingParser.parse(text, callbacks);
}
return this.baseParser.parse(text);
}
/**
* Returns the format instructions for parsing the output of an agent
* action in the style of the StructuredChatAgent.
* @returns A string representing the format instructions.
*/
getFormatInstructions() {
return renderTemplate(FORMAT_INSTRUCTIONS, "f-string", {
tool_names: this.toolNames.join(", "),
});
}
/**
* Creates a new `StructuredChatOutputParserWithRetries` instance from a
* `BaseLanguageModel` and options. The options can include a base parser
* and tool names.
* @param llm A `BaseLanguageModel` instance.
* @param options Options for creating a `StructuredChatOutputParserWithRetries` instance.
* @returns A new `StructuredChatOutputParserWithRetries` instance.
*/
static fromLLM(llm, options) {
const baseParser = options.baseParser ??
new StructuredChatOutputParser({ toolNames: options.toolNames ?? [] });
const outputFixingParser = OutputFixingParser.fromLLM(llm, baseParser);
return new StructuredChatOutputParserWithRetries({
baseParser,
outputFixingParser,
toolNames: options.toolNames,
});
}
}