@langchain/core
Version:
Core LangChain.js abstractions and schemas
1 lines • 8.54 kB
Source Map (JSON)
{"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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"}