{"version":3,"file":"list.cjs","names":["BaseTransformOutputParser","OutputParserException"],"sources":["../../src/output_parsers/list.ts"],"sourcesContent":["import { BaseMessage } from \"../messages/index.js\";\nimport { OutputParserException } from \"./base.js\";\nimport { BaseTransformOutputParser } from \"./transform.js\";\n\n/**\n * Class to parse the output of an LLM call to a list.\n * @augments BaseOutputParser\n */\nexport abstract class ListOutputParser extends BaseTransformOutputParser<\n  string[]\n> {\n  re?: RegExp;\n\n  async *_transform(\n    inputGenerator: AsyncGenerator<string | BaseMessage>\n  ): AsyncGenerator<string[]> {\n    let buffer = \"\";\n    for await (const input of inputGenerator) {\n      if (typeof input === \"string\") {\n        // add current chunk to buffer\n        buffer += input;\n      } else {\n        // extract message content and add to buffer\n        buffer += input.content;\n      }\n      // get parts in buffer\n      if (!this.re) {\n        const parts = await this.parse(buffer);\n        if (parts.length > 1) {\n          // if there are multiple parts, yield all but the last one\n          for (const part of parts.slice(0, -1)) {\n            yield [part];\n          }\n          // keep the last part in the buffer\n          buffer = parts[parts.length - 1];\n        }\n      } else {\n        // if there is a regex, get all matches\n        const matches = [...buffer.matchAll(this.re)];\n        if (matches.length > 1) {\n          let doneIdx = 0;\n          // if there are multiple matches, yield all but the last one\n          for (const match of matches.slice(0, -1)) {\n            yield [match[1]];\n            doneIdx += (match.index ?? 0) + match[0].length;\n          }\n          // keep the last match in the buffer\n          buffer = buffer.slice(doneIdx);\n        }\n      }\n    }\n\n    // yield the last part\n    for (const part of await this.parse(buffer)) {\n      yield [part];\n    }\n  }\n}\n\n/**\n * Class to parse the output of an LLM call as a comma-separated list.\n * @augments ListOutputParser\n */\nexport class CommaSeparatedListOutputParser extends ListOutputParser {\n  static lc_name() {\n    return \"CommaSeparatedListOutputParser\";\n  }\n\n  lc_namespace = [\"langchain_core\", \"output_parsers\", \"list\"];\n\n  lc_serializable = true;\n\n  /**\n   * Parses the given text into an array of strings, using a comma as the\n   * separator. If the parsing fails, throws an OutputParserException.\n   * @param text The text to parse.\n   * @returns An array of strings obtained by splitting the input text at each comma.\n   */\n  async parse(text: string): Promise<string[]> {\n    try {\n      return text\n        .trim()\n        .split(\",\")\n        .map((s) => s.trim());\n    } catch {\n      throw new OutputParserException(`Could not parse output: ${text}`, text);\n    }\n  }\n\n  /**\n   * Provides instructions on the expected format of the response for the\n   * CommaSeparatedListOutputParser.\n   * @returns A string containing instructions on the expected format of the response.\n   */\n  getFormatInstructions(): string {\n    return `Your response should be a list of comma separated values, eg: \\`foo, bar, baz\\``;\n  }\n}\n\n/**\n * Class to parse the output of an LLM call to a list with a specific length and separator.\n * @augments ListOutputParser\n */\nexport class CustomListOutputParser extends ListOutputParser {\n  lc_namespace = [\"langchain_core\", \"output_parsers\", \"list\"];\n\n  private length: number | undefined;\n\n  private separator: string;\n\n  constructor({ length, separator }: { length?: number; separator?: string }) {\n    super(...arguments);\n    this.length = length;\n    this.separator = separator || \",\";\n  }\n\n  /**\n   * Parses the given text into an array of strings, using the specified\n   * separator. If the parsing fails or the number of items in the list\n   * doesn't match the expected length, throws an OutputParserException.\n   * @param text The text to parse.\n   * @returns An array of strings obtained by splitting the input text at each occurrence of the specified separator.\n   */\n  async parse(text: string): Promise<string[]> {\n    try {\n      const items = text\n        .trim()\n        .split(this.separator)\n        .map((s) => s.trim());\n      if (this.length !== undefined && items.length !== this.length) {\n        throw new OutputParserException(\n          `Incorrect number of items. Expected ${this.length}, got ${items.length}.`\n        );\n      }\n      return items;\n    } catch (e) {\n      if (Object.getPrototypeOf(e) === OutputParserException.prototype) {\n        throw e;\n      }\n      throw new OutputParserException(`Could not parse output: ${text}`);\n    }\n  }\n\n  /**\n   * Provides instructions on the expected format of the response for the\n   * CustomListOutputParser, including the number of items and the\n   * separator.\n   * @returns A string containing instructions on the expected format of the response.\n   */\n  getFormatInstructions(): string {\n    return `Your response should be a list of ${\n      this.length === undefined ? \"\" : `${this.length} `\n    }items separated by \"${this.separator}\" (eg: \\`foo${this.separator} bar${\n      this.separator\n    } baz\\`)`;\n  }\n}\n\nexport class NumberedListOutputParser extends ListOutputParser {\n  static lc_name() {\n    return \"NumberedListOutputParser\";\n  }\n\n  lc_namespace = [\"langchain_core\", \"output_parsers\", \"list\"];\n\n  lc_serializable = true;\n\n  getFormatInstructions(): string {\n    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`;\n  }\n\n  re = /\\d+\\.\\s([^\\n]+)/g;\n\n  async parse(text: string): Promise<string[]> {\n    return [...(text.matchAll(this.re) ?? [])].map((m) => m[1]);\n  }\n}\n\nexport class MarkdownListOutputParser extends ListOutputParser {\n  static lc_name() {\n    return \"NumberedListOutputParser\";\n  }\n\n  lc_namespace = [\"langchain_core\", \"output_parsers\", \"list\"];\n\n  lc_serializable = true;\n\n  getFormatInstructions(): string {\n    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`;\n  }\n\n  re = /^\\s*[-*]\\s([^\\n]+)$/gm;\n\n  async parse(text: string): Promise<string[]> {\n    return [...(text.matchAll(this.re) ?? [])].map((m) => m[1]);\n  }\n}\n"],"mappings":"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"}