{"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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"}