"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MarkdownListOutputParser = exports.NumberedListOutputParser = exports.CustomListOutputParser = exports.CommaSeparatedListOutputParser = exports.ListOutputParser = void 0;
const base_js_1 = require("./base.cjs");
const transform_js_1 = require("./transform.cjs");
/**
 * Class to parse the output of an LLM call to a list.
 * @augments BaseOutputParser
 */
class ListOutputParser extends transform_js_1.BaseTransformOutputParser {
    constructor() {
        super(...arguments);
        Object.defineProperty(this, "re", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
    }
    async *_transform(inputGenerator) {
        let buffer = "";
        for await (const input of inputGenerator) {
            if (typeof input === "string") {
                // add current chunk to buffer
                buffer += input;
            }
            else {
                // extract message content and add to buffer
                buffer += input.content;
            }
            // get parts in buffer
            if (!this.re) {
                const parts = await this.parse(buffer);
                if (parts.length > 1) {
                    // if there are multiple parts, yield all but the last one
                    for (const part of parts.slice(0, -1)) {
                        yield [part];
                    }
                    // keep the last part in the buffer
                    buffer = parts[parts.length - 1];
                }
            }
            else {
                // if there is a regex, get all matches
                const matches = [...buffer.matchAll(this.re)];
                if (matches.length > 1) {
                    let doneIdx = 0;
                    // if there are multiple matches, yield all but the last one
                    for (const match of matches.slice(0, -1)) {
                        yield [match[1]];
                        doneIdx += (match.index ?? 0) + match[0].length;
                    }
                    // keep the last match in the buffer
                    buffer = buffer.slice(doneIdx);
                }
            }
        }
        // yield the last part
        for (const part of await this.parse(buffer)) {
            yield [part];
        }
    }
}
exports.ListOutputParser = ListOutputParser;
/**
 * Class to parse the output of an LLM call as a comma-separated list.
 * @augments ListOutputParser
 */
class CommaSeparatedListOutputParser extends ListOutputParser {
    constructor() {
        super(...arguments);
        Object.defineProperty(this, "lc_namespace", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: ["langchain_core", "output_parsers", "list"]
        });
        Object.defineProperty(this, "lc_serializable", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: true
        });
    }
    static lc_name() {
        return "CommaSeparatedListOutputParser";
    }
    /**
     * Parses the given text into an array of strings, using a comma as the
     * separator. If the parsing fails, throws an OutputParserException.
     * @param text The text to parse.
     * @returns An array of strings obtained by splitting the input text at each comma.
     */
    async parse(text) {
        try {
            return text
                .trim()
                .split(",")
                .map((s) => s.trim());
        }
        catch (e) {
            throw new base_js_1.OutputParserException(`Could not parse output: ${text}`, text);
        }
    }
    /**
     * Provides instructions on the expected format of the response for the
     * CommaSeparatedListOutputParser.
     * @returns A string containing instructions on the expected format of the response.
     */
    getFormatInstructions() {
        return `Your response should be a list of comma separated values, eg: \`foo, bar, baz\``;
    }
}
exports.CommaSeparatedListOutputParser = CommaSeparatedListOutputParser;
/**
 * Class to parse the output of an LLM call to a list with a specific length and separator.
 * @augments ListOutputParser
 */
class CustomListOutputParser extends ListOutputParser {
    constructor({ length, separator }) {
        super(...arguments);
        Object.defineProperty(this, "lc_namespace", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: ["langchain_core", "output_parsers", "list"]
        });
        Object.defineProperty(this, "length", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "separator", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        this.length = length;
        this.separator = separator || ",";
    }
    /**
     * Parses the given text into an array of strings, using the specified
     * separator. If the parsing fails or the number of items in the list
     * doesn't match the expected length, throws an OutputParserException.
     * @param text The text to parse.
     * @returns An array of strings obtained by splitting the input text at each occurrence of the specified separator.
     */
    async parse(text) {
        try {
            const items = text
                .trim()
                .split(this.separator)
                .map((s) => s.trim());
            if (this.length !== undefined && items.length !== this.length) {
                throw new base_js_1.OutputParserException(`Incorrect number of items. Expected ${this.length}, got ${items.length}.`);
            }
            return items;
        }
        catch (e) {
            if (Object.getPrototypeOf(e) === base_js_1.OutputParserException.prototype) {
                throw e;
            }
            throw new base_js_1.OutputParserException(`Could not parse output: ${text}`);
        }
    }
    /**
     * Provides instructions on the expected format of the response for the
     * CustomListOutputParser, including the number of items and the
     * separator.
     * @returns A string containing instructions on the expected format of the response.
     */
    getFormatInstructions() {
        return `Your response should be a list of ${this.length === undefined ? "" : `${this.length} `}items separated by "${this.separator}" (eg: \`foo${this.separator} bar${this.separator} baz\`)`;
    }
}
exports.CustomListOutputParser = CustomListOutputParser;
class NumberedListOutputParser extends ListOutputParser {
    constructor() {
        super(...arguments);
        Object.defineProperty(this, "lc_namespace", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: ["langchain_core", "output_parsers", "list"]
        });
        Object.defineProperty(this, "lc_serializable", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: true
        });
        Object.defineProperty(this, "re", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: /\d+\.\s([^\n]+)/g
        });
    }
    static lc_name() {
        return "NumberedListOutputParser";
    }
    getFormatInstructions() {
        return `Your response should be a numbered list with each item on a new line. For example: \n\n1. foo\n\n2. bar\n\n3. baz`;
    }
    async parse(text) {
        return [...(text.matchAll(this.re) ?? [])].map((m) => m[1]);
    }
}
exports.NumberedListOutputParser = NumberedListOutputParser;
class MarkdownListOutputParser extends ListOutputParser {
    constructor() {
        super(...arguments);
        Object.defineProperty(this, "lc_namespace", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: ["langchain_core", "output_parsers", "list"]
        });
        Object.defineProperty(this, "lc_serializable", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: true
        });
        Object.defineProperty(this, "re", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: /^\s*[-*]\s([^\n]+)$/gm
        });
    }
    static lc_name() {
        return "NumberedListOutputParser";
    }
    getFormatInstructions() {
        return `Your response should be a numbered list with each item on a new line. For example: \n\n1. foo\n\n2. bar\n\n3. baz`;
    }
    async parse(text) {
        return [...(text.matchAll(this.re) ?? [])].map((m) => m[1]);
    }
}
exports.MarkdownListOutputParser = MarkdownListOutputParser;
