@langchain/core
Version:
Core LangChain.js abstractions and schemas
1 lines • 10.5 kB
Source Map (JSON)
{"version":3,"file":"branch.cjs","names":["Runnable","_coerceToRunnable","patchConfig","getCallbackManagerForConfig","_coerceToDict","concat"],"sources":["../../src/runnables/branch.ts"],"sourcesContent":["import {\n Runnable,\n RunnableLike,\n _coerceToDict,\n _coerceToRunnable,\n} from \"./base.js\";\nimport {\n RunnableConfig,\n getCallbackManagerForConfig,\n patchConfig,\n} from \"./config.js\";\nimport { CallbackManagerForChainRun } from \"../callbacks/manager.js\";\nimport { concat } from \"../utils/stream.js\";\n\n/**\n * Type for a branch in the RunnableBranch. It consists of a condition\n * runnable and a branch runnable. The condition runnable is used to\n * determine whether the branch should be executed, and the branch runnable\n * is executed if the condition is true.\n */\nexport type Branch<RunInput, RunOutput> = [\n Runnable<RunInput, boolean>,\n Runnable<RunInput, RunOutput>,\n];\n\nexport type BranchLike<RunInput, RunOutput> = [\n RunnableLike<RunInput, boolean>,\n RunnableLike<RunInput, RunOutput>,\n];\n\n/**\n * Class that represents a runnable branch. The RunnableBranch is\n * initialized with an array of branches and a default branch. When invoked,\n * it evaluates the condition of each branch in order and executes the\n * corresponding branch if the condition is true. If none of the conditions\n * are true, it executes the default branch.\n * @example\n * ```typescript\n * const branch = RunnableBranch.from([\n * [\n * (x: { topic: string; question: string }) =>\n * x.topic.toLowerCase().includes(\"anthropic\"),\n * anthropicChain,\n * ],\n * [\n * (x: { topic: string; question: string }) =>\n * x.topic.toLowerCase().includes(\"langchain\"),\n * langChainChain,\n * ],\n * generalChain,\n * ]);\n *\n * const fullChain = RunnableSequence.from([\n * {\n * topic: classificationChain,\n * question: (input: { question: string }) => input.question,\n * },\n * branch,\n * ]);\n *\n * const result = await fullChain.invoke({\n * question: \"how do I use LangChain?\",\n * });\n * ```\n */\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\nexport class RunnableBranch<RunInput = any, RunOutput = any> extends Runnable<\n RunInput,\n RunOutput\n> {\n static lc_name() {\n return \"RunnableBranch\";\n }\n\n lc_namespace = [\"langchain_core\", \"runnables\"];\n\n lc_serializable = true;\n\n default: Runnable<RunInput, RunOutput>;\n\n branches: Branch<RunInput, RunOutput>[];\n\n constructor(fields: {\n branches: Branch<RunInput, RunOutput>[];\n default: Runnable<RunInput, RunOutput>;\n }) {\n super(fields);\n this.branches = fields.branches;\n this.default = fields.default;\n }\n\n /**\n * Convenience method for instantiating a RunnableBranch from\n * RunnableLikes (objects, functions, or Runnables).\n *\n * Each item in the input except for the last one should be a\n * tuple with two items. The first is a \"condition\" RunnableLike that\n * returns \"true\" if the second RunnableLike in the tuple should run.\n *\n * The final item in the input should be a RunnableLike that acts as a\n * default branch if no other branches match.\n *\n * @example\n * ```ts\n * import { RunnableBranch } from \"@langchain/core/runnables\";\n *\n * const branch = RunnableBranch.from([\n * [(x: number) => x > 0, (x: number) => x + 1],\n * [(x: number) => x < 0, (x: number) => x - 1],\n * (x: number) => x\n * ]);\n * ```\n * @param branches An array where the every item except the last is a tuple of [condition, runnable]\n * pairs. The last item is a default runnable which is invoked if no other condition matches.\n * @returns A new RunnableBranch.\n */\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n static from<RunInput = any, RunOutput = any>(\n branches: [\n ...BranchLike<RunInput, RunOutput>[],\n RunnableLike<RunInput, RunOutput>,\n ]\n ) {\n if (branches.length < 1) {\n throw new Error(\"RunnableBranch requires at least one branch\");\n }\n const branchLikes = branches.slice(0, -1) as BranchLike<\n RunInput,\n RunOutput\n >[];\n const coercedBranches: Branch<RunInput, RunOutput>[] = branchLikes.map(\n ([condition, runnable]) => [\n _coerceToRunnable(condition),\n _coerceToRunnable(runnable),\n ]\n );\n const defaultBranch = _coerceToRunnable(\n branches[branches.length - 1] as RunnableLike<RunInput, RunOutput>\n );\n return new this({\n branches: coercedBranches,\n default: defaultBranch,\n });\n }\n\n async _invoke(\n input: RunInput,\n config?: Partial<RunnableConfig>,\n runManager?: CallbackManagerForChainRun\n ): Promise<RunOutput> {\n let result;\n for (let i = 0; i < this.branches.length; i += 1) {\n const [condition, branchRunnable] = this.branches[i];\n const conditionValue = await condition.invoke(\n input,\n patchConfig(config, {\n callbacks: runManager?.getChild(`condition:${i + 1}`),\n })\n );\n if (conditionValue) {\n result = await branchRunnable.invoke(\n input,\n patchConfig(config, {\n callbacks: runManager?.getChild(`branch:${i + 1}`),\n })\n );\n break;\n }\n }\n if (!result) {\n result = await this.default.invoke(\n input,\n patchConfig(config, {\n callbacks: runManager?.getChild(\"branch:default\"),\n })\n );\n }\n return result;\n }\n\n async invoke(\n input: RunInput,\n config: RunnableConfig = {}\n ): Promise<RunOutput> {\n return this._callWithConfig(this._invoke, input, config);\n }\n\n async *_streamIterator(input: RunInput, config?: Partial<RunnableConfig>) {\n const callbackManager_ = await getCallbackManagerForConfig(config);\n const runManager = await callbackManager_?.handleChainStart(\n this.toJSON(),\n _coerceToDict(input, \"input\"),\n config?.runId,\n undefined,\n undefined,\n undefined,\n config?.runName\n );\n let finalOutput;\n let finalOutputSupported = true;\n let stream;\n try {\n for (let i = 0; i < this.branches.length; i += 1) {\n const [condition, branchRunnable] = this.branches[i];\n const conditionValue = await condition.invoke(\n input,\n patchConfig(config, {\n callbacks: runManager?.getChild(`condition:${i + 1}`),\n })\n );\n if (conditionValue) {\n stream = await branchRunnable.stream(\n input,\n patchConfig(config, {\n callbacks: runManager?.getChild(`branch:${i + 1}`),\n })\n );\n for await (const chunk of stream) {\n yield chunk;\n if (finalOutputSupported) {\n if (finalOutput === undefined) {\n finalOutput = chunk;\n } else {\n try {\n finalOutput = concat(finalOutput, chunk);\n } catch {\n finalOutput = undefined;\n finalOutputSupported = false;\n }\n }\n }\n }\n break;\n }\n }\n if (stream === undefined) {\n stream = await this.default.stream(\n input,\n patchConfig(config, {\n callbacks: runManager?.getChild(\"branch:default\"),\n })\n );\n for await (const chunk of stream) {\n yield chunk;\n if (finalOutputSupported) {\n if (finalOutput === undefined) {\n finalOutput = chunk;\n } else {\n try {\n finalOutput = concat(finalOutput, chunk as RunOutput);\n } catch {\n finalOutput = undefined;\n finalOutputSupported = false;\n }\n }\n }\n }\n }\n } catch (e) {\n await runManager?.handleChainError(e);\n throw e;\n }\n await runManager?.handleChainEnd(finalOutput ?? {});\n }\n}\n"],"mappings":"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"}