UNPKG

@langchain/core

Version:
1 lines 10.9 kB
{"version":3,"file":"branch.cjs","names":["Runnable","fields: {\n branches: Branch<RunInput, RunOutput>[];\n default: Runnable<RunInput, RunOutput>;\n }","branches: [\n ...BranchLike<RunInput, RunOutput>[],\n RunnableLike<RunInput, RunOutput>\n ]","coercedBranches: Branch<RunInput, RunOutput>[]","_coerceToRunnable","input: RunInput","config?: Partial<RunnableConfig>","runManager?: CallbackManagerForChainRun","patchConfig","config: RunnableConfig","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// eslint-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 // eslint-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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"}