import { OutputParserException, } from "@langchain/core/output_parsers";
import { renderTemplate } from "@langchain/core/prompts";
import { AgentActionOutputParser } from "../types.js";
import { FORMAT_INSTRUCTIONS } from "./prompt.js";
import { OutputFixingParser } from "../../output_parsers/fix.js";
/**
 * Class that represents an output parser for the ChatConversationalAgent
 * class. It extends the AgentActionOutputParser class and provides
 * methods for parsing the output of the MRKL chain into agent actions.
 */
export class ChatConversationalAgentOutputParser extends AgentActionOutputParser {
    constructor(fields) {
        super(...arguments);
        Object.defineProperty(this, "lc_namespace", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: ["langchain", "agents", "chat_convo"]
        });
        Object.defineProperty(this, "toolNames", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        this.toolNames = fields.toolNames;
    }
    /**
     * Parses the given text into an AgentAction or AgentFinish object. If an
     * output fixing parser is defined, uses it to parse the text.
     * @param text Text to parse.
     * @returns Promise that resolves to an AgentAction or AgentFinish object.
     */
    async parse(text) {
        let jsonOutput = text.trim();
        if (jsonOutput.includes("```json") || jsonOutput.includes("```")) {
            const testString = jsonOutput.includes("```json") ? "```json" : "```";
            const firstIndex = jsonOutput.indexOf(testString);
            const actionInputIndex = jsonOutput.indexOf("action_input");
            if (actionInputIndex > firstIndex) {
                jsonOutput = jsonOutput
                    .slice(firstIndex + testString.length)
                    .trimStart();
                const lastIndex = jsonOutput.lastIndexOf("```");
                if (lastIndex !== -1) {
                    jsonOutput = jsonOutput.slice(0, lastIndex).trimEnd();
                }
            }
        }
        try {
            const response = JSON.parse(jsonOutput);
            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 as a string. If the 'raw' option is
     * true, returns the raw FORMAT_INSTRUCTIONS.
     * @param options Options for getting the format instructions.
     * @returns Format instructions as a string.
     */
    getFormatInstructions() {
        return renderTemplate(FORMAT_INSTRUCTIONS, "f-string", {
            tool_names: this.toolNames.join(", "),
        });
    }
}
/**
 * Class that represents an output parser with retries for the
 * ChatConversationalAgent class. It extends the AgentActionOutputParser
 * class and provides methods for parsing the output of the MRKL chain
 * into agent actions with retry functionality.
 */
export class ChatConversationalAgentOutputParserWithRetries extends AgentActionOutputParser {
    constructor(fields) {
        super(fields);
        Object.defineProperty(this, "lc_namespace", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: ["langchain", "agents", "chat_convo"]
        });
        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 ChatConversationalAgentOutputParser({ toolNames: this.toolNames });
        this.outputFixingParser = fields?.outputFixingParser;
    }
    /**
     * Returns the format instructions as a string.
     * @returns Format instructions as a string.
     */
    getFormatInstructions(options) {
        if (options.raw) {
            return FORMAT_INSTRUCTIONS;
        }
        return renderTemplate(FORMAT_INSTRUCTIONS, "f-string", {
            tool_names: options.toolNames.join(", "),
        });
    }
    /**
     * Parses the given text into an AgentAction or AgentFinish object.
     * @param text Text to parse.
     * @returns Promise that resolves to an AgentAction or AgentFinish object.
     */
    async parse(text) {
        if (this.outputFixingParser !== undefined) {
            return this.outputFixingParser.parse(text);
        }
        return this.baseParser.parse(text);
    }
    /**
     * Static method to create a new
     * ChatConversationalAgentOutputParserWithRetries from a BaseLanguageModelInterface
     * and options. If no base parser is provided in the options, a new
     * ChatConversationalAgentOutputParser is created. An OutputFixingParser
     * is also created from the BaseLanguageModelInterface and the base parser.
     * @param llm BaseLanguageModelInterface instance used to create the OutputFixingParser.
     * @param options Options for creating the ChatConversationalAgentOutputParserWithRetries instance.
     * @returns A new instance of ChatConversationalAgentOutputParserWithRetries.
     */
    static fromLLM(llm, options) {
        const baseParser = options.baseParser ??
            new ChatConversationalAgentOutputParser({
                toolNames: options.toolNames ?? [],
            });
        const outputFixingParser = OutputFixingParser.fromLLM(llm, baseParser);
        return new ChatConversationalAgentOutputParserWithRetries({
            baseParser,
            outputFixingParser,
            toolNames: options.toolNames,
        });
    }
}
