@langchain/langgraph 1.5.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/channels/delta.cjs +1 -1
- package/dist/channels/delta.cjs.map +1 -1
- package/dist/channels/delta.js +1 -1
- package/dist/channels/delta.js.map +1 -1
- package/dist/graph/graph.cjs +11 -2
- package/dist/graph/graph.cjs.map +1 -1
- package/dist/graph/graph.d.cts.map +1 -1
- package/dist/graph/graph.d.ts.map +1 -1
- package/dist/graph/graph.js +11 -2
- package/dist/graph/graph.js.map +1 -1
- package/dist/graph/message.cjs +10 -4
- package/dist/graph/message.cjs.map +1 -1
- package/dist/graph/message.d.cts.map +1 -1
- package/dist/graph/message.d.ts.map +1 -1
- package/dist/graph/message.js +10 -4
- package/dist/graph/message.js.map +1 -1
- package/dist/prebuilt/tool_node.cjs +1 -1
- package/dist/prebuilt/tool_node.cjs.map +1 -1
- package/dist/prebuilt/tool_node.d.cts.map +1 -1
- package/dist/prebuilt/tool_node.d.ts.map +1 -1
- package/dist/prebuilt/tool_node.js +2 -2
- package/dist/prebuilt/tool_node.js.map +1 -1
- package/dist/pregel/index.cjs +4 -2
- package/dist/pregel/index.cjs.map +1 -1
- package/dist/pregel/index.d.cts.map +1 -1
- package/dist/pregel/index.d.ts.map +1 -1
- package/dist/pregel/index.js +4 -2
- package/dist/pregel/index.js.map +1 -1
- package/dist/pregel/messages.cjs +35 -17
- package/dist/pregel/messages.cjs.map +1 -1
- package/dist/pregel/messages.js +35 -17
- package/dist/pregel/messages.js.map +1 -1
- package/dist/pregel/remote.cjs +3 -2
- package/dist/pregel/remote.cjs.map +1 -1
- package/dist/pregel/remote.d.cts.map +1 -1
- package/dist/pregel/remote.d.ts.map +1 -1
- package/dist/pregel/remote.js +3 -2
- package/dist/pregel/remote.js.map +1 -1
- package/dist/pregel/stream.cjs +33 -2
- package/dist/pregel/stream.cjs.map +1 -1
- package/dist/pregel/stream.d.cts.map +1 -1
- package/dist/pregel/stream.d.ts.map +1 -1
- package/dist/pregel/stream.js +32 -3
- package/dist/pregel/stream.js.map +1 -1
- package/dist/state/values/delta.cjs.map +1 -1
- package/dist/state/values/delta.d.cts +2 -2
- package/dist/state/values/delta.d.ts +2 -2
- package/dist/state/values/delta.js.map +1 -1
- package/package.json +7 -7
package/dist/graph/graph.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.js","names":["Graph","DrawableGraph","isUuid"],"sources":["../../src/graph/graph.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\nimport {\n _coerceToRunnable,\n Runnable,\n RunnableConfig,\n RunnableInterface,\n RunnableIOSchema,\n type RunnableLike as LangChainRunnableLike,\n} from \"@langchain/core/runnables\";\nimport {\n Node as DrawableGraphNode,\n Graph as DrawableGraph,\n} from \"@langchain/core/runnables/graph\";\nimport { All, BaseCheckpointSaver } from \"@langchain/langgraph-checkpoint\";\nimport { z } from \"zod/v4\";\nimport { validate as isUuid } from \"@langchain/core/utils/uuid\";\nimport type {\n RunnableLike,\n LangGraphRunnableConfig,\n} from \"../pregel/runnable_types.js\";\nimport { PregelNode } from \"../pregel/read.js\";\nimport { Channel, Pregel } from \"../pregel/index.js\";\nimport type { PregelOptions, PregelParams } from \"../pregel/types.js\";\nimport { BaseChannel } from \"../channels/base.js\";\nimport { EphemeralValue } from \"../channels/ephemeral_value.js\";\nimport { ChannelWrite, PASSTHROUGH } from \"../pregel/write.js\";\nimport {\n _isSend,\n CHECKPOINT_NAMESPACE_END,\n CHECKPOINT_NAMESPACE_SEPARATOR,\n END,\n Send,\n START,\n TAG_HIDDEN,\n} from \"../constants.js\";\nimport {\n gatherIterator,\n gatherIteratorSync,\n RunnableCallable,\n} from \"../utils.js\";\nimport {\n InvalidUpdateError,\n NodeError,\n NodeInterrupt,\n UnreachableNodeError,\n} from \"../errors.js\";\nimport { StateDefinition, StateType } from \"./annotation.js\";\nimport { isPregelLike } from \"../pregel/utils/subgraph.js\";\nimport type { StreamTransformer } from \"../stream/types.js\";\nimport type { GraphNodeReturnValue } from \"./types.js\";\n\nexport interface BranchOptions<\n IO,\n N extends string,\n CallOptions extends LangGraphRunnableConfig = LangGraphRunnableConfig,\n> {\n source: N;\n path: RunnableLike<IO, BranchPathReturnValue, CallOptions>;\n pathMap?: Record<string, N | typeof END> | (N | typeof END)[];\n}\n\nexport type BranchPathReturnValue =\n | string\n | Send\n | (string | Send)[]\n | Promise<string | Send | (string | Send)[]>;\n\ntype CompiledGraphTypeNode<Spec> = Spec extends { node: infer N extends string }\n ? N\n : any; // eslint-disable-line @typescript-eslint/no-explicit-any\n\ntype CompiledGraphTypeContext<Spec> = Spec extends {\n context: infer Context extends Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n ? Context\n : Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n\ntype CompiledGraphTypeStreamTransformers<Spec> = Spec extends {\n streamTransformers: infer Transformers;\n}\n ? Transformers extends ReadonlyArray<\n () => StreamTransformer<any> // eslint-disable-line @typescript-eslint/no-explicit-any\n >\n ? Transformers\n : Transformers extends ReadonlyArray<\n StreamTransformer<any> // eslint-disable-line @typescript-eslint/no-explicit-any\n >\n ? { readonly [K in keyof Transformers]: () => Transformers[K] }\n : Transformers extends StreamTransformer<any> // eslint-disable-line @typescript-eslint/no-explicit-any\n ? readonly [() => Transformers]\n : []\n : [];\n\n/**\n * Convenience type for referencing a compiled graph by named type slots.\n *\n * @example\n * ```ts\n * type MyCompiledGraph = CompiledGraphType<{\n * state: State;\n * update: Update;\n * streamTransformers: [\n * StreamTransformer<Extensions>,\n * StreamTransformer<MoreExtensions>,\n * ];\n * }>;\n * ```\n */\nexport type CompiledGraphType<Spec extends object = object> = CompiledGraph<\n CompiledGraphTypeNode<Spec>,\n Spec extends { state: infer State } ? State : any, // eslint-disable-line @typescript-eslint/no-explicit-any\n Spec extends { update: infer Update } ? Update : any, // eslint-disable-line @typescript-eslint/no-explicit-any\n CompiledGraphTypeContext<Spec>,\n Spec extends { input: infer Input } ? Input : any, // eslint-disable-line @typescript-eslint/no-explicit-any\n Spec extends { output: infer Output } ? Output : any, // eslint-disable-line @typescript-eslint/no-explicit-any\n Spec extends { nodeReturn: infer NodeReturn } ? NodeReturn : unknown,\n Spec extends { command: infer Command } ? Command : unknown,\n Spec extends { streamCustom: infer StreamCustom } ? StreamCustom : any, // eslint-disable-line @typescript-eslint/no-explicit-any\n CompiledGraphTypeStreamTransformers<Spec>\n>;\n\ntype NodeAction<S, U, C extends StateDefinition> = RunnableLike<\n S,\n U extends object ? U & Record<string, any> : U, // eslint-disable-line @typescript-eslint/no-explicit-any\n LangGraphRunnableConfig<StateType<C>>\n>;\n\nexport class Branch<\n IO,\n N extends string,\n CallOptions extends LangGraphRunnableConfig = LangGraphRunnableConfig,\n> {\n path: Runnable<IO, BranchPathReturnValue>;\n\n ends?: Record<string, N | typeof END>;\n\n constructor(options: Omit<BranchOptions<IO, N, CallOptions>, \"source\">) {\n if (Runnable.isRunnable(options.path)) {\n this.path = options.path as Runnable<IO, BranchPathReturnValue>;\n } else {\n this.path = _coerceToRunnable(\n options.path as LangChainRunnableLike<IO, BranchPathReturnValue>\n );\n }\n this.ends = Array.isArray(options.pathMap)\n ? options.pathMap.reduce(\n (acc, n) => {\n acc[n] = n;\n return acc;\n },\n {} as Record<string, N | typeof END>\n )\n : options.pathMap;\n }\n\n run(\n writer: (\n dests: (string | Send)[],\n config: LangGraphRunnableConfig\n ) => Runnable | void | Promise<void>,\n reader?: (config: CallOptions) => IO\n ) {\n return ChannelWrite.registerWriter(\n new RunnableCallable({\n name: \"<branch_run>\",\n trace: false,\n func: async (input: IO, config: CallOptions) => {\n try {\n return await this._route(input, config, writer, reader);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any) {\n // Detect & warn if NodeInterrupt is thrown in a conditional edge\n if (e.name === NodeInterrupt.unminifiable_name) {\n console.warn(\n \"[WARN]: 'NodeInterrupt' thrown in conditional edge. This is likely a bug in your graph implementation.\\n\" +\n \"NodeInterrupt should only be thrown inside a node, not in edge conditions.\"\n );\n }\n throw e;\n }\n },\n })\n );\n }\n\n async _route(\n input: IO,\n config: CallOptions,\n writer: (\n dests: (string | Send)[],\n config: LangGraphRunnableConfig\n ) => Runnable | void | Promise<void>,\n reader?: (config: CallOptions) => IO\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<Runnable | any> {\n let result = await this.path.invoke(\n reader ? reader(config) : input,\n config\n );\n if (!Array.isArray(result)) {\n result = [result];\n }\n\n let destinations: (string | Send)[];\n if (this.ends) {\n destinations = result.map((r) => (_isSend(r) ? r : this.ends![r]));\n } else {\n destinations = result;\n }\n if (destinations.some((dest) => !dest)) {\n throw new Error(\"Branch condition returned unknown or null destination\");\n }\n if (destinations.filter(_isSend).some((packet) => packet.node === END)) {\n throw new InvalidUpdateError(\"Cannot send a packet to the END node\");\n }\n const writeResult = await writer(destinations, config);\n return writeResult ?? input;\n }\n}\n\nexport type NodeSpec<RunInput, RunOutput> = {\n runnable: Runnable<RunInput, RunOutput>;\n metadata?: Record<string, unknown>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n subgraphs?: Pregel<any, any>[];\n ends?: string[];\n defer?: boolean;\n /** Whether this node is an auto-generated node-level error handler. */\n isErrorHandler?: boolean;\n /** Name of the auto-generated error handler node to run on failure. */\n errorHandlerNode?: string;\n};\n\n/**\n * Return value type for node-level error handlers.\n *\n * Handlers may return a partial state update, a `Command`, or a Promise of either.\n *\n * @template Update - The update type (what fields can be returned)\n * @template Nodes - Union of valid node names for Command.goto\n */\nexport type NodeErrorHandlerReturnValue<\n Update,\n Nodes extends string = string,\n> = GraphNodeReturnValue<Update, Nodes>;\n\n/**\n * A node-level error handler callable.\n *\n * Invoked with the node input state, a {@link NodeError} describing the failed\n * node and thrown error, and the runnable config. The handler runs ONLY after\n * the failing node's {@link RetryPolicy} is exhausted. It may return a state\n * update or a `Command` (to route via `goto`).\n */\nexport type NodeErrorHandler<\n TState = unknown,\n TUpdate = Partial<TState>,\n Nodes extends string = string,\n> = (\n state: TState,\n error: NodeError,\n config?: LangGraphRunnableConfig\n) => NodeErrorHandlerReturnValue<TUpdate, Nodes>;\n\nexport type AddNodeOptions<Nodes extends string = string> = {\n metadata?: Record<string, unknown>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n subgraphs?: Pregel<any, any>[];\n ends?: Nodes[];\n defer?: boolean;\n};\n\nexport class Graph<\n N extends string = typeof START | typeof END,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunInput = any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput = any,\n NodeSpecType extends NodeSpec<RunInput, RunOutput> = NodeSpec<\n RunInput,\n RunOutput\n >,\n C extends StateDefinition = StateDefinition,\n> {\n nodes: Record<N, NodeSpecType>;\n\n edges: Set<[N | typeof START, N | typeof END]>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n branches: Record<string, Record<string, Branch<RunInput, N, any>>>;\n\n entryPoint?: string;\n\n compiled = false;\n\n constructor() {\n this.nodes = {} as Record<N, NodeSpecType>;\n this.edges = new Set();\n this.branches = {};\n }\n\n protected warnIfCompiled(message: string): void {\n if (this.compiled) {\n console.warn(message);\n }\n }\n\n get allEdges(): Set<[string, string]> {\n return this.edges;\n }\n\n addNode<K extends string, NodeInput = RunInput, NodeOutput = RunOutput>(\n nodes:\n | Record<K, NodeAction<NodeInput, NodeOutput, C>>\n | [\n key: K,\n action: NodeAction<NodeInput, NodeOutput, C>,\n options?: AddNodeOptions,\n ][]\n ): Graph<N | K, RunInput, RunOutput>;\n\n addNode<K extends string, NodeInput = RunInput, NodeOutput = RunOutput>(\n key: K,\n action: NodeAction<NodeInput, NodeOutput, C>,\n options?: AddNodeOptions\n ): Graph<N | K, RunInput, RunOutput>;\n\n addNode<K extends string, NodeInput = RunInput, NodeOutput = RunOutput>(\n ...args:\n | [\n key: K,\n action: NodeAction<NodeInput, NodeOutput, C>,\n options?: AddNodeOptions,\n ]\n | [\n nodes:\n | Record<K, NodeAction<NodeInput, NodeOutput, C>>\n | [\n key: K,\n action: NodeAction<NodeInput, NodeOutput, C>,\n options?: AddNodeOptions,\n ][],\n ]\n ): Graph<N | K, RunInput, RunOutput> {\n function isMutlipleNodes(\n args: unknown[]\n ): args is [\n nodes:\n | Record<K, NodeAction<NodeInput, RunOutput, C>>\n | [\n key: K,\n action: NodeAction<NodeInput, RunOutput, C>,\n options?: AddNodeOptions,\n ][],\n options?: AddNodeOptions,\n ] {\n return args.length >= 1 && typeof args[0] !== \"string\";\n }\n\n const nodes = (\n isMutlipleNodes(args) // eslint-disable-line no-nested-ternary\n ? Array.isArray(args[0])\n ? args[0]\n : Object.entries(args[0])\n : [[args[0], args[1], args[2]]]\n ) as [K, NodeAction<NodeInput, RunOutput, C>, AddNodeOptions][];\n\n if (nodes.length === 0) {\n throw new Error(\"No nodes provided in `addNode`\");\n }\n\n for (const [key, action, options] of nodes) {\n for (const reservedChar of [\n CHECKPOINT_NAMESPACE_SEPARATOR,\n CHECKPOINT_NAMESPACE_END,\n ]) {\n if (key.includes(reservedChar)) {\n throw new Error(\n `\"${reservedChar}\" is a reserved character and is not allowed in node names.`\n );\n }\n }\n this.warnIfCompiled(\n `Adding a node to a graph that has already been compiled. This will not be reflected in the compiled graph.`\n );\n\n if (key in this.nodes) {\n throw new Error(`Node \\`${key}\\` already present.`);\n }\n if (key === END) {\n throw new Error(`Node \\`${key}\\` is reserved.`);\n }\n\n const runnable = _coerceToRunnable<RunInput, RunOutput>(\n // Account for arbitrary state due to Send API\n action as RunnableLike<RunInput, RunOutput>\n );\n\n this.nodes[key as unknown as N] = {\n runnable,\n metadata: options?.metadata,\n subgraphs: isPregelLike(runnable) ? [runnable] : options?.subgraphs,\n ends: options?.ends,\n } as NodeSpecType;\n }\n\n return this as Graph<N | K, RunInput, RunOutput, NodeSpecType>;\n }\n\n addEdge(startKey: N | typeof START, endKey: N | typeof END): this {\n this.warnIfCompiled(\n `Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.`\n );\n\n if (startKey === END) {\n throw new Error(\"END cannot be a start node\");\n }\n if (endKey === START) {\n throw new Error(\"START cannot be an end node\");\n }\n if (\n Array.from(this.edges).some(([start]) => start === startKey) &&\n !(\"channels\" in this)\n ) {\n throw new Error(\n `Already found path for ${startKey}. For multiple edges, use StateGraph.`\n );\n }\n\n this.edges.add([startKey, endKey]);\n\n return this;\n }\n\n addConditionalEdges(\n source: BranchOptions<RunInput, N, LangGraphRunnableConfig<StateType<C>>>\n ): this;\n\n addConditionalEdges(\n source: N,\n path: RunnableLike<\n RunInput,\n BranchPathReturnValue,\n LangGraphRunnableConfig<StateType<C>>\n >,\n pathMap?: BranchOptions<\n RunInput,\n N,\n LangGraphRunnableConfig<StateType<C>>\n >[\"pathMap\"]\n ): this;\n\n addConditionalEdges(\n source:\n | N\n | BranchOptions<RunInput, N, LangGraphRunnableConfig<StateType<C>>>,\n path?: RunnableLike<\n RunInput,\n BranchPathReturnValue,\n LangGraphRunnableConfig<StateType<C>>\n >,\n pathMap?: BranchOptions<\n RunInput,\n N,\n LangGraphRunnableConfig<StateType<C>>\n >[\"pathMap\"]\n ): this {\n const options: BranchOptions<\n RunInput,\n N,\n LangGraphRunnableConfig<StateType<C>>\n > = typeof source === \"object\" ? source : { source, path: path!, pathMap };\n\n this.warnIfCompiled(\n \"Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.\"\n );\n if (!Runnable.isRunnable(options.path)) {\n options.path = _coerceToRunnable(\n options.path as LangChainRunnableLike<RunInput, BranchPathReturnValue>\n );\n }\n // find a name for condition\n const name =\n options.path.getName() === \"RunnableLambda\"\n ? \"condition\"\n : options.path.getName();\n // validate condition\n if (this.branches[options.source] && this.branches[options.source][name]) {\n throw new Error(\n `Condition \\`${name}\\` already present for node \\`${source}\\``\n );\n }\n // save it\n this.branches[options.source] ??= {};\n this.branches[options.source][name] = new Branch(options);\n return this;\n }\n\n /**\n * @deprecated use `addEdge(START, key)` instead\n */\n setEntryPoint(key: N): this {\n this.warnIfCompiled(\n \"Setting the entry point of a graph that has already been compiled. This will not be reflected in the compiled graph.\"\n );\n\n return this.addEdge(START, key);\n }\n\n /**\n * @deprecated use `addEdge(key, END)` instead\n */\n setFinishPoint(key: N): this {\n this.warnIfCompiled(\n \"Setting a finish point of a graph that has already been compiled. This will not be reflected in the compiled graph.\"\n );\n\n return this.addEdge(key, END);\n }\n\n compile<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const TTransformers extends ReadonlyArray<() => StreamTransformer<any>> =\n [],\n >({\n checkpointer,\n interruptBefore,\n interruptAfter,\n name,\n transformers,\n }: {\n checkpointer?: BaseCheckpointSaver | false;\n interruptBefore?: N[] | All;\n interruptAfter?: N[] | All;\n name?: string;\n /**\n * Stream transformer factories baked into the compiled graph. These run\n * automatically for every `streamEvents(..., { version: \"v3\" })` call,\n * before any call-site transformers.\n */\n transformers?: TTransformers;\n } = {}): CompiledGraph<\n N,\n RunInput,\n RunOutput,\n Record<string, any>,\n any,\n any,\n unknown,\n unknown,\n any,\n TTransformers\n > {\n // eslint-disable-line @typescript-eslint/no-explicit-any\n // validate the graph\n this.validate([\n ...(Array.isArray(interruptBefore) ? interruptBefore : []),\n ...(Array.isArray(interruptAfter) ? interruptAfter : []),\n ]);\n\n // create empty compiled graph\n const compiled = new CompiledGraph({\n builder: this,\n checkpointer,\n interruptAfter,\n interruptBefore,\n autoValidate: false,\n nodes: {} as Record<N | typeof START, PregelNode<RunInput, RunOutput>>,\n channels: {\n [START]: new EphemeralValue(),\n [END]: new EphemeralValue(),\n } as Record<N | typeof START | typeof END | string, BaseChannel>,\n inputChannels: START,\n outputChannels: END,\n streamChannels: [] as N[],\n streamMode: \"values\",\n name,\n streamTransformers: transformers,\n });\n\n // attach nodes, edges and branches\n for (const [key, node] of Object.entries<NodeSpec<RunInput, RunOutput>>(\n this.nodes\n )) {\n compiled.attachNode(key as N, node);\n }\n for (const [start, end] of this.edges) {\n compiled.attachEdge(start, end);\n }\n for (const [start, branches] of Object.entries(this.branches)) {\n for (const [name, branch] of Object.entries(branches)) {\n compiled.attachBranch(start as N, name, branch);\n }\n }\n\n return compiled.validate();\n }\n\n validate(interrupt?: string[]): void {\n // assemble sources\n const allSources = new Set([...this.allEdges].map(([src, _]) => src));\n for (const [start] of Object.entries(this.branches)) {\n allSources.add(start);\n }\n\n // validate sources\n for (const source of allSources) {\n if (source !== START && !(source in this.nodes)) {\n throw new Error(`Found edge starting at unknown node \\`${source}\\``);\n }\n }\n\n // assemble targets\n const allTargets = new Set([...this.allEdges].map(([_, target]) => target));\n for (const [start, branches] of Object.entries(this.branches)) {\n for (const branch of Object.values(branches)) {\n if (branch.ends != null) {\n for (const end of Object.values(branch.ends)) {\n allTargets.add(end);\n }\n } else {\n allTargets.add(END);\n for (const node of Object.keys(this.nodes)) {\n if (node !== start) {\n allTargets.add(node);\n }\n }\n }\n }\n }\n for (const node of Object.values<NodeSpecType>(this.nodes)) {\n for (const target of node.ends ?? []) {\n allTargets.add(target);\n }\n }\n // Node-level error handlers can route to any node via `Command({ goto })`\n // (saga / compensation flows), so treat them like an open-ended branch:\n // any node may be a recovery target reachable from a handler.\n const hasErrorHandler = Object.values<NodeSpecType>(this.nodes).some(\n (node) => node.isErrorHandler\n );\n if (hasErrorHandler) {\n for (const node of Object.keys(this.nodes)) {\n allTargets.add(node);\n }\n }\n // validate targets\n for (const node of Object.keys(this.nodes)) {\n // auto-generated error handler nodes are reachable only on failure of\n // their source node, so they are exempt from the reachability check.\n if (this.nodes[node as N].isErrorHandler) {\n continue;\n }\n if (!allTargets.has(node)) {\n throw new UnreachableNodeError(\n [\n `Node \\`${node}\\` is not reachable.`,\n \"\",\n \"If you are returning Command objects from your node,\",\n 'make sure you are passing names of potential destination nodes as an \"ends\" array',\n 'into \".addNode(..., { ends: [\"node1\", \"node2\"] })\".',\n ].join(\"\\n\"),\n {\n lc_error_code: \"UNREACHABLE_NODE\",\n }\n );\n }\n }\n for (const target of allTargets) {\n if (target !== END && !(target in this.nodes)) {\n throw new Error(`Found edge ending at unknown node \\`${target}\\``);\n }\n }\n\n // validate interrupts\n if (interrupt) {\n for (const node of interrupt) {\n if (!(node in this.nodes)) {\n throw new Error(`Interrupt node \\`${node}\\` is not present`);\n }\n }\n }\n\n this.compiled = true;\n }\n}\n\nexport class CompiledGraph<\n N extends string,\n State = any, // eslint-disable-line @typescript-eslint/no-explicit-any\n Update = any, // eslint-disable-line @typescript-eslint/no-explicit-any\n ContextType extends Record<string, any> = Record<string, any>, // eslint-disable-line @typescript-eslint/no-explicit-any\n InputType = any, // eslint-disable-line @typescript-eslint/no-explicit-any\n OutputType = any, // eslint-disable-line @typescript-eslint/no-explicit-any\n NodeReturnType = unknown,\n CommandType = unknown,\n StreamCustomType = any, // eslint-disable-line @typescript-eslint/no-explicit-any\n TStreamTransformers extends ReadonlyArray<() => StreamTransformer<any>> = [], // eslint-disable-line @typescript-eslint/no-explicit-any\n> extends Pregel<\n Record<N | typeof START, PregelNode<State, Update>>,\n Record<N | typeof START | typeof END | string, BaseChannel>,\n ContextType & Record<string, any>, // eslint-disable-line @typescript-eslint/no-explicit-any\n InputType,\n OutputType,\n InputType,\n OutputType,\n NodeReturnType,\n CommandType,\n StreamCustomType,\n TStreamTransformers\n> {\n declare \"~NodeType\": N;\n\n declare \"~NodeReturnType\": NodeReturnType;\n\n declare \"~RunInput\": Update;\n\n declare \"~RunOutput\": State;\n\n builder: Graph<N, State, Update>;\n\n constructor({\n builder,\n ...rest\n }: { builder: Graph<N, State, Update> } & PregelParams<\n Record<N | typeof START, PregelNode<State, Update>>,\n Record<N | typeof START | typeof END | string, BaseChannel>,\n TStreamTransformers\n >) {\n super(rest);\n this.builder = builder;\n }\n\n override withConfig<\n const TTransformers extends ReadonlyArray<() => StreamTransformer<any>> =\n [],\n >(\n config: Omit<LangGraphRunnableConfig, \"store\" | \"writer\" | \"interrupt\"> & {\n streamTransformers: TTransformers;\n }\n ): CompiledGraph<\n N,\n State,\n Update,\n ContextType,\n InputType,\n OutputType,\n NodeReturnType,\n CommandType,\n StreamCustomType,\n readonly [...TStreamTransformers, ...TTransformers]\n >;\n\n override withConfig(\n config: PregelOptions<\n Record<N | typeof START, PregelNode<State, Update>>,\n Record<N | typeof START | typeof END | string, BaseChannel>,\n ContextType & Record<string, any>\n >\n ): this;\n\n override withConfig(\n config: Omit<LangGraphRunnableConfig, \"store\" | \"writer\" | \"interrupt\"> & {\n streamTransformers?: ReadonlyArray<() => StreamTransformer<any>>;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): any {\n return (super.withConfig as any)(config) as unknown as CompiledGraph<\n N,\n State,\n Update,\n ContextType,\n InputType,\n OutputType,\n NodeReturnType,\n CommandType,\n StreamCustomType,\n ReadonlyArray<() => StreamTransformer<any>>\n >;\n }\n\n attachNode(key: N, node: NodeSpec<State, Update>): void {\n this.channels[key] = new EphemeralValue();\n this.nodes[key] = new PregelNode({\n channels: [],\n triggers: [],\n metadata: node.metadata,\n subgraphs: node.subgraphs,\n ends: node.ends,\n })\n .pipe(node.runnable)\n .pipe(\n new ChannelWrite([{ channel: key, value: PASSTHROUGH }], [TAG_HIDDEN])\n );\n (this.streamChannels as N[]).push(key);\n }\n\n attachEdge(start: N | typeof START, end: N | typeof END): void {\n if (end === END) {\n if (start === START) {\n throw new Error(\"Cannot have an edge from START to END\");\n }\n this.nodes[start].writers.push(\n new ChannelWrite([{ channel: END, value: PASSTHROUGH }], [TAG_HIDDEN])\n );\n } else {\n this.nodes[end].triggers.push(start);\n (this.nodes[end].channels as string[]).push(start);\n }\n }\n\n attachBranch(\n start: N | typeof START,\n name: string,\n branch: Branch<State, N>\n ) {\n // add hidden start node\n if (start === START && !this.nodes[START]) {\n this.nodes[START] = Channel.subscribeTo(START, { tags: [TAG_HIDDEN] });\n }\n\n // attach branch writer\n this.nodes[start].pipe(\n branch.run((dests) => {\n const writes = dests.map((dest) => {\n if (_isSend(dest)) {\n return dest;\n }\n return {\n channel: dest === END ? END : `branch:${start}:${name}:${dest}`,\n value: PASSTHROUGH,\n };\n });\n return new ChannelWrite(writes, [TAG_HIDDEN]);\n })\n );\n\n // attach branch readers\n const ends = branch.ends\n ? Object.values(branch.ends)\n : (Object.keys(this.nodes) as N[]);\n for (const end of ends) {\n if (end !== END) {\n const channelName = `branch:${start}:${name}:${end}`;\n (this.channels as Record<string, BaseChannel>)[channelName] =\n new EphemeralValue();\n this.nodes[end].triggers.push(channelName);\n (this.nodes[end].channels as string[]).push(channelName);\n }\n }\n }\n\n /**\n * Returns a drawable representation of the computation graph.\n */\n override async getGraphAsync(\n config?: RunnableConfig & { xray?: boolean | number }\n ): Promise<DrawableGraph> {\n const xray = config?.xray;\n const graph = new DrawableGraph();\n const startNodes: Record<string, DrawableGraphNode> = {\n [START]: graph.addNode({ schema: z.any() }, START),\n };\n const endNodes: Record<string, DrawableGraphNode> = {};\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let subgraphs: Record<string, CompiledGraph<any>> = {};\n if (xray) {\n subgraphs = Object.fromEntries(\n (await gatherIterator(this.getSubgraphsAsync())).filter(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (x): x is [string, CompiledGraph<any>] => isCompiledGraph(x[1])\n )\n );\n }\n\n const discoveredEdges: DiscoveredGraphEdge[] = [];\n\n function addEdge(\n start: string,\n end: string,\n label?: string,\n conditional = false\n ) {\n if (end === END && endNodes[END] === undefined) {\n endNodes[END] = graph.addNode({ schema: z.any() }, END);\n }\n if (startNodes[start] === undefined) {\n return;\n }\n if (endNodes[end] === undefined) {\n throw new Error(`End node ${end} not found!`);\n }\n discoveredEdges.push({ src: start, dest: end, conditional });\n return graph.addEdge(\n startNodes[start],\n endNodes[end],\n label !== end ? label : undefined,\n conditional\n );\n }\n\n for (const [key, nodeSpec] of Object.entries(this.builder.nodes) as [\n N,\n NodeSpec<State, Update>,\n ][]) {\n const displayKey = _escapeMermaidKeywords(key);\n const node = nodeSpec.runnable;\n const metadata = nodeSpec.metadata ?? {};\n if (\n this.interruptBefore?.includes(key) &&\n this.interruptAfter?.includes(key)\n ) {\n metadata.__interrupt = \"before,after\";\n } else if (this.interruptBefore?.includes(key)) {\n metadata.__interrupt = \"before\";\n } else if (this.interruptAfter?.includes(key)) {\n metadata.__interrupt = \"after\";\n }\n if (xray) {\n const newXrayValue = typeof xray === \"number\" ? xray - 1 : xray;\n const drawableSubgraph =\n subgraphs[key] !== undefined\n ? await subgraphs[key].getGraphAsync({\n ...config,\n xray: newXrayValue,\n })\n : node.getGraph(config);\n\n drawableSubgraph.trimFirstNode();\n drawableSubgraph.trimLastNode();\n\n if (Object.keys(drawableSubgraph.nodes).length > 1) {\n const [e, s] = graph.extend(drawableSubgraph, displayKey);\n if (e === undefined) {\n throw new Error(\n `Could not extend subgraph \"${key}\" due to missing entrypoint.`\n );\n }\n\n // TODO: Remove default name once we stop supporting core 0.2.0\n // eslint-disable-next-line no-inner-declarations\n function _isRunnableInterface(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n thing: any\n ): thing is RunnableInterface {\n return thing ? thing.lc_runnable : false;\n }\n // eslint-disable-next-line no-inner-declarations\n function _nodeDataStr(\n id: string | undefined,\n data: RunnableInterface | RunnableIOSchema\n ): string {\n if (id !== undefined && !isUuid(id)) {\n return id;\n } else if (_isRunnableInterface(data)) {\n try {\n let dataStr = data.getName();\n dataStr = dataStr.startsWith(\"Runnable\")\n ? dataStr.slice(\"Runnable\".length)\n : dataStr;\n return dataStr;\n } catch {\n return data.getName();\n }\n } else {\n return data.name ?? \"UnknownSchema\";\n }\n }\n // TODO: Remove casts when we stop supporting core 0.2.0\n if (s !== undefined) {\n startNodes[displayKey] = {\n name: _nodeDataStr(s.id, s.data),\n ...s,\n } as DrawableGraphNode;\n }\n endNodes[displayKey] = {\n name: _nodeDataStr(e.id, e.data),\n ...e,\n } as DrawableGraphNode;\n } else {\n // TODO: Remove when we stop supporting core 0.2.0\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const newNode = graph.addNode(node, displayKey, metadata);\n startNodes[displayKey] = newNode;\n endNodes[displayKey] = newNode;\n }\n } else {\n // TODO: Remove when we stop supporting core 0.2.0\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const newNode = graph.addNode(node, displayKey, metadata);\n startNodes[displayKey] = newNode;\n endNodes[displayKey] = newNode;\n }\n }\n const sortedEdges = [...this.builder.allEdges].sort(([a], [b]) => {\n if (a < b) {\n return -1;\n } else if (b > a) {\n return 1;\n } else {\n return 0;\n }\n });\n for (const [start, end] of sortedEdges) {\n addEdge(_escapeMermaidKeywords(start), _escapeMermaidKeywords(end));\n }\n for (const [start, branches] of Object.entries(this.builder.branches)) {\n const defaultEnds: Record<string, string> = {\n ...Object.fromEntries(\n Object.keys(this.builder.nodes)\n .filter((k) => k !== start)\n .map((k) => [_escapeMermaidKeywords(k), _escapeMermaidKeywords(k)])\n ),\n [END]: END,\n };\n for (const branch of Object.values(branches)) {\n let ends;\n if (branch.ends !== undefined) {\n ends = branch.ends;\n } else {\n ends = defaultEnds;\n }\n for (const [label, end] of Object.entries(ends)) {\n addEdge(\n _escapeMermaidKeywords(start),\n _escapeMermaidKeywords(end),\n label,\n true\n );\n }\n }\n }\n for (const [key, node] of Object.entries(this.builder.nodes) as [\n N,\n NodeSpec<State, Update>,\n ][]) {\n if (node.ends !== undefined) {\n for (const end of node.ends) {\n addEdge(\n _escapeMermaidKeywords(key),\n _escapeMermaidKeywords(end),\n undefined,\n true\n );\n }\n }\n }\n addImplicitTerminalEndEdges(this.builder.nodes, discoveredEdges, addEdge);\n return graph;\n }\n\n /**\n * Returns a drawable representation of the computation graph.\n *\n * @deprecated Use getGraphAsync instead. The async method will be the default in the next minor core release.\n */\n override getGraph(\n config?: RunnableConfig & { xray?: boolean | number }\n ): DrawableGraph {\n const xray = config?.xray;\n const graph = new DrawableGraph();\n const startNodes: Record<string, DrawableGraphNode> = {\n [START]: graph.addNode(\n {\n schema: z.any(),\n },\n START\n ),\n };\n const endNodes: Record<string, DrawableGraphNode> = {};\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let subgraphs: Record<string, CompiledGraph<any>> = {};\n if (xray) {\n subgraphs = Object.fromEntries(\n gatherIteratorSync(this.getSubgraphs()).filter(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (x): x is [string, CompiledGraph<any>] => isCompiledGraph(x[1])\n )\n );\n }\n\n const discoveredEdges: DiscoveredGraphEdge[] = [];\n\n function addEdge(\n start: string,\n end: string,\n label?: string,\n conditional = false\n ) {\n if (end === END && endNodes[END] === undefined) {\n endNodes[END] = graph.addNode({ schema: z.any() }, END);\n }\n if (startNodes[start] === undefined) {\n return;\n }\n if (endNodes[end] === undefined) {\n throw new Error(`End node ${end} not found!`);\n }\n discoveredEdges.push({ src: start, dest: end, conditional });\n return graph.addEdge(\n startNodes[start],\n endNodes[end],\n label !== end ? label : undefined,\n conditional\n );\n }\n\n for (const [key, nodeSpec] of Object.entries(this.builder.nodes) as [\n N,\n NodeSpec<State, Update>,\n ][]) {\n const displayKey = _escapeMermaidKeywords(key);\n const node = nodeSpec.runnable;\n const metadata = nodeSpec.metadata ?? {};\n if (\n this.interruptBefore?.includes(key) &&\n this.interruptAfter?.includes(key)\n ) {\n metadata.__interrupt = \"before,after\";\n } else if (this.interruptBefore?.includes(key)) {\n metadata.__interrupt = \"before\";\n } else if (this.interruptAfter?.includes(key)) {\n metadata.__interrupt = \"after\";\n }\n if (xray) {\n const newXrayValue = typeof xray === \"number\" ? xray - 1 : xray;\n const drawableSubgraph =\n subgraphs[key] !== undefined\n ? subgraphs[key].getGraph({\n ...config,\n xray: newXrayValue,\n })\n : node.getGraph(config);\n drawableSubgraph.trimFirstNode();\n drawableSubgraph.trimLastNode();\n if (Object.keys(drawableSubgraph.nodes).length > 1) {\n const [e, s] = graph.extend(drawableSubgraph, displayKey);\n if (e === undefined) {\n throw new Error(\n `Could not extend subgraph \"${key}\" due to missing entrypoint.`\n );\n }\n\n // TODO: Remove default name once we stop supporting core 0.2.0\n // eslint-disable-next-line no-inner-declarations\n function _isRunnableInterface(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n thing: any\n ): thing is RunnableInterface {\n return thing ? thing.lc_runnable : false;\n }\n // eslint-disable-next-line no-inner-declarations\n function _nodeDataStr(\n id: string | undefined,\n data: RunnableInterface | RunnableIOSchema\n ): string {\n if (id !== undefined && !isUuid(id)) {\n return id;\n } else if (_isRunnableInterface(data)) {\n try {\n let dataStr = data.getName();\n dataStr = dataStr.startsWith(\"Runnable\")\n ? dataStr.slice(\"Runnable\".length)\n : dataStr;\n return dataStr;\n } catch {\n return data.getName();\n }\n } else {\n return data.name ?? \"UnknownSchema\";\n }\n }\n // TODO: Remove casts when we stop supporting core 0.2.0\n if (s !== undefined) {\n startNodes[displayKey] = {\n name: _nodeDataStr(s.id, s.data),\n ...s,\n } as DrawableGraphNode;\n }\n endNodes[displayKey] = {\n name: _nodeDataStr(e.id, e.data),\n ...e,\n } as DrawableGraphNode;\n } else {\n // TODO: Remove when we stop supporting core 0.2.0\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const newNode = graph.addNode(node, displayKey, metadata);\n startNodes[displayKey] = newNode;\n endNodes[displayKey] = newNode;\n }\n } else {\n // TODO: Remove when we stop supporting core 0.2.0\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const newNode = graph.addNode(node, displayKey, metadata);\n startNodes[displayKey] = newNode;\n endNodes[displayKey] = newNode;\n }\n }\n const sortedEdges = [...this.builder.allEdges].sort(([a], [b]) => {\n if (a < b) {\n return -1;\n } else if (b > a) {\n return 1;\n } else {\n return 0;\n }\n });\n for (const [start, end] of sortedEdges) {\n addEdge(_escapeMermaidKeywords(start), _escapeMermaidKeywords(end));\n }\n for (const [start, branches] of Object.entries(this.builder.branches)) {\n const defaultEnds: Record<string, string> = {\n ...Object.fromEntries(\n Object.keys(this.builder.nodes)\n .filter((k) => k !== start)\n .map((k) => [_escapeMermaidKeywords(k), _escapeMermaidKeywords(k)])\n ),\n [END]: END,\n };\n for (const branch of Object.values(branches)) {\n let ends;\n if (branch.ends !== undefined) {\n ends = branch.ends;\n } else {\n ends = defaultEnds;\n }\n for (const [label, end] of Object.entries(ends)) {\n addEdge(\n _escapeMermaidKeywords(start),\n _escapeMermaidKeywords(end),\n label,\n true\n );\n }\n }\n }\n for (const [key, node] of Object.entries(this.builder.nodes) as [\n N,\n NodeSpec<State, Update>,\n ][]) {\n if (node.ends !== undefined) {\n for (const end of node.ends) {\n addEdge(\n _escapeMermaidKeywords(key),\n _escapeMermaidKeywords(end),\n undefined,\n true\n );\n }\n }\n }\n addImplicitTerminalEndEdges(this.builder.nodes, discoveredEdges, addEdge);\n return graph;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isCompiledGraph(x: unknown): x is CompiledGraph<any> {\n return (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (x as CompiledGraph<any>).attachNode === \"function\" &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (x as CompiledGraph<any>).attachEdge === \"function\"\n );\n}\n\nfunction _escapeMermaidKeywords(key: string) {\n if (key === \"subgraph\") {\n return `\"${key}\"`;\n }\n return key;\n}\n\n/**\n * An edge collected while building a {@link DrawableGraph} from a compiled\n * {@link StateGraph}.\n *\n * Used by {@link addImplicitTerminalEndEdges} to detect nodes that should\n * receive an implicit edge to {@link END} (terminal nodes with no outgoing\n * edges in the drawable view).\n *\n * @internal\n */\ntype DiscoveredGraphEdge = {\n /** Display name of the source node (Mermaid-escaped). */\n src: string;\n /** Display name of the target node (Mermaid-escaped), or {@link END}. */\n dest: string;\n /**\n * Whether the edge comes from a conditional branch or `node.ends` declaration.\n * Non-conditional edges alone determine implicit terminal `→ END` links.\n */\n conditional: boolean;\n};\n\n/**\n * Add implicit edges to END for terminal nodes (targets with no outgoing edges).\n *\n * Only nodes reached by a non-conditional edge are considered, so\n * conditional-branch targets are not treated as implicit sinks.\n */\nfunction addImplicitTerminalEndEdges<N extends string>(\n nodes: Record<N, NodeSpec<unknown, unknown>>,\n discovered: DiscoveredGraphEdge[],\n addEdge: (\n start: string,\n end: string,\n label?: string,\n conditional?: boolean\n ) => void\n): void {\n const sources = new Set(discovered.map((e) => e.src));\n const nonConditionalDestinations = [\n ...new Set(\n discovered\n .filter((e) => !e.conditional && e.dest !== END)\n .map((e) => e.dest)\n ),\n ].sort();\n\n for (const displayDest of nonConditionalDestinations) {\n if (sources.has(displayDest)) continue;\n const rawKey = (Object.keys(nodes) as N[]).find(\n (k) => _escapeMermaidKeywords(k) === displayDest\n );\n if (rawKey !== undefined && nodes[rawKey]?.isErrorHandler) continue;\n addEdge(displayDest, END);\n }\n}\n"],"mappings":";;;;;;;;;;;;;AA+HA,IAAa,SAAb,MAIE;CACA;CAEA;CAEA,YAAY,SAA4D;AACtE,MAAI,SAAS,WAAW,QAAQ,KAAK,CACnC,MAAK,OAAO,QAAQ;MAEpB,MAAK,OAAO,kBACV,QAAQ,KACT;AAEH,OAAK,OAAO,MAAM,QAAQ,QAAQ,QAAQ,GACtC,QAAQ,QAAQ,QACb,KAAK,MAAM;AACV,OAAI,KAAK;AACT,UAAO;KAET,EAAE,CACH,GACD,QAAQ;;CAGd,IACE,QAIA,QACA;AACA,SAAO,aAAa,eAClB,IAAI,iBAAiB;GACnB,MAAM;GACN,OAAO;GACP,MAAM,OAAO,OAAW,WAAwB;AAC9C,QAAI;AACF,YAAO,MAAM,KAAK,OAAO,OAAO,QAAQ,QAAQ,OAAO;aAEhD,GAAQ;AAEf,SAAI,EAAE,SAAS,cAAc,kBAC3B,SAAQ,KACN,qLAED;AAEH,WAAM;;;GAGX,CAAC,CACH;;CAGH,MAAM,OACJ,OACA,QACA,QAIA,QAEyB;EACzB,IAAI,SAAS,MAAM,KAAK,KAAK,OAC3B,SAAS,OAAO,OAAO,GAAG,OAC1B,OACD;AACD,MAAI,CAAC,MAAM,QAAQ,OAAO,CACxB,UAAS,CAAC,OAAO;EAGnB,IAAI;AACJ,MAAI,KAAK,KACP,gBAAe,OAAO,KAAK,MAAO,QAAQ,EAAE,GAAG,IAAI,KAAK,KAAM,GAAI;MAElE,gBAAe;AAEjB,MAAI,aAAa,MAAM,SAAS,CAAC,KAAK,CACpC,OAAM,IAAI,MAAM,wDAAwD;AAE1E,MAAI,aAAa,OAAO,QAAQ,CAAC,MAAM,WAAW,OAAO,SAAA,UAAa,CACpE,OAAM,IAAI,mBAAmB,uCAAuC;AAGtE,SADoB,MAAM,OAAO,cAAc,OAAO,IAChC;;;AAwD1B,IAAaA,UAAb,MAWE;CACA;CAEA;CAGA;CAEA;CAEA,WAAW;CAEX,cAAc;AACZ,OAAK,QAAQ,EAAE;AACf,OAAK,wBAAQ,IAAI,KAAK;AACtB,OAAK,WAAW,EAAE;;CAGpB,eAAyB,SAAuB;AAC9C,MAAI,KAAK,SACP,SAAQ,KAAK,QAAQ;;CAIzB,IAAI,WAAkC;AACpC,SAAO,KAAK;;CAmBd,QACE,GAAG,MAegC;EACnC,SAAS,gBACP,MAUA;AACA,UAAO,KAAK,UAAU,KAAK,OAAO,KAAK,OAAO;;EAGhD,MAAM,QACJ,gBAAgB,KAAK,GACjB,MAAM,QAAQ,KAAK,GAAG,GACpB,KAAK,KACL,OAAO,QAAQ,KAAK,GAAG,GACzB,CAAC;GAAC,KAAK;GAAI,KAAK;GAAI,KAAK;GAAG,CAAC;AAGnC,MAAI,MAAM,WAAW,EACnB,OAAM,IAAI,MAAM,iCAAiC;AAGnD,OAAK,MAAM,CAAC,KAAK,QAAQ,YAAY,OAAO;AAC1C,QAAK,MAAM,gBAAgB,CAAA,KAAA,IAG1B,CACC,KAAI,IAAI,SAAS,aAAa,CAC5B,OAAM,IAAI,MACR,IAAI,aAAa,6DAClB;AAGL,QAAK,eACH,6GACD;AAED,OAAI,OAAO,KAAK,MACd,OAAM,IAAI,MAAM,UAAU,IAAI,qBAAqB;AAErD,OAAI,QAAA,UACF,OAAM,IAAI,MAAM,UAAU,IAAI,iBAAiB;GAGjD,MAAM,WAAW,kBAEf,OACD;AAED,QAAK,MAAM,OAAuB;IAChC;IACA,UAAU,SAAS;IACnB,WAAW,aAAa,SAAS,GAAG,CAAC,SAAS,GAAG,SAAS;IAC1D,MAAM,SAAS;IAChB;;AAGH,SAAO;;CAGT,QAAQ,UAA4B,QAA8B;AAChE,OAAK,eACH,8GACD;AAED,MAAI,aAAA,UACF,OAAM,IAAI,MAAM,6BAA6B;AAE/C,MAAI,WAAA,YACF,OAAM,IAAI,MAAM,8BAA8B;AAEhD,MACE,MAAM,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,UAAU,SAAS,IAC5D,EAAE,cAAc,MAEhB,OAAM,IAAI,MACR,0BAA0B,SAAS,uCACpC;AAGH,OAAK,MAAM,IAAI,CAAC,UAAU,OAAO,CAAC;AAElC,SAAO;;CAqBT,oBACE,QAGA,MAKA,SAKM;EACN,MAAM,UAIF,OAAO,WAAW,WAAW,SAAS;GAAE;GAAc;GAAO;GAAS;AAE1E,OAAK,eACH,8GACD;AACD,MAAI,CAAC,SAAS,WAAW,QAAQ,KAAK,CACpC,SAAQ,OAAO,kBACb,QAAQ,KACT;EAGH,MAAM,OACJ,QAAQ,KAAK,SAAS,KAAK,mBACvB,cACA,QAAQ,KAAK,SAAS;AAE5B,MAAI,KAAK,SAAS,QAAQ,WAAW,KAAK,SAAS,QAAQ,QAAQ,MACjE,OAAM,IAAI,MACR,eAAe,KAAK,gCAAgC,OAAO,IAC5D;AAGH,OAAK,SAAS,QAAQ,YAAY,EAAE;AACpC,OAAK,SAAS,QAAQ,QAAQ,QAAQ,IAAI,OAAO,QAAQ;AACzD,SAAO;;;;;CAMT,cAAc,KAAc;AAC1B,OAAK,eACH,uHACD;AAED,SAAO,KAAK,QAAQ,OAAO,IAAI;;;;;CAMjC,eAAe,KAAc;AAC3B,OAAK,eACH,sHACD;AAED,SAAO,KAAK,QAAQ,KAAK,IAAI;;CAG/B,QAIE,EACA,cACA,iBACA,gBACA,MACA,iBAYE,EAAE,EAWJ;AAGA,OAAK,SAAS,CACZ,GAAI,MAAM,QAAQ,gBAAgB,GAAG,kBAAkB,EAAE,EACzD,GAAI,MAAM,QAAQ,eAAe,GAAG,iBAAiB,EAAE,CACxD,CAAC;EAGF,MAAM,WAAW,IAAI,cAAc;GACjC,SAAS;GACT;GACA;GACA;GACA,cAAc;GACd,OAAO,EAAE;GACT,UAAU;KACP,QAAQ,IAAI,gBAAgB;KAC5B,MAAM,IAAI,gBAAgB;IAC5B;GACD,eAAe;GACf,gBAAgB;GAChB,gBAAgB,EAAE;GAClB,YAAY;GACZ;GACA,oBAAoB;GACrB,CAAC;AAGF,OAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAC/B,KAAK,MACN,CACC,UAAS,WAAW,KAAU,KAAK;AAErC,OAAK,MAAM,CAAC,OAAO,QAAQ,KAAK,MAC9B,UAAS,WAAW,OAAO,IAAI;AAEjC,OAAK,MAAM,CAAC,OAAO,aAAa,OAAO,QAAQ,KAAK,SAAS,CAC3D,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,SAAS,CACnD,UAAS,aAAa,OAAY,MAAM,OAAO;AAInD,SAAO,SAAS,UAAU;;CAG5B,SAAS,WAA4B;EAEnC,MAAM,aAAa,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,KAAK,CAAC,KAAK,OAAO,IAAI,CAAC;AACrE,OAAK,MAAM,CAAC,UAAU,OAAO,QAAQ,KAAK,SAAS,CACjD,YAAW,IAAI,MAAM;AAIvB,OAAK,MAAM,UAAU,WACnB,KAAI,WAAA,eAAoB,EAAE,UAAU,KAAK,OACvC,OAAM,IAAI,MAAM,yCAAyC,OAAO,IAAI;EAKxE,MAAM,aAAa,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,KAAK,CAAC,GAAG,YAAY,OAAO,CAAC;AAC3E,OAAK,MAAM,CAAC,OAAO,aAAa,OAAO,QAAQ,KAAK,SAAS,CAC3D,MAAK,MAAM,UAAU,OAAO,OAAO,SAAS,CAC1C,KAAI,OAAO,QAAQ,KACjB,MAAK,MAAM,OAAO,OAAO,OAAO,OAAO,KAAK,CAC1C,YAAW,IAAI,IAAI;OAEhB;AACL,cAAW,IAAI,IAAI;AACnB,QAAK,MAAM,QAAQ,OAAO,KAAK,KAAK,MAAM,CACxC,KAAI,SAAS,MACX,YAAW,IAAI,KAAK;;AAM9B,OAAK,MAAM,QAAQ,OAAO,OAAqB,KAAK,MAAM,CACxD,MAAK,MAAM,UAAU,KAAK,QAAQ,EAAE,CAClC,YAAW,IAAI,OAAO;AAS1B,MAHwB,OAAO,OAAqB,KAAK,MAAM,CAAC,MAC7D,SAAS,KAAK,eAChB,CAEC,MAAK,MAAM,QAAQ,OAAO,KAAK,KAAK,MAAM,CACxC,YAAW,IAAI,KAAK;AAIxB,OAAK,MAAM,QAAQ,OAAO,KAAK,KAAK,MAAM,EAAE;AAG1C,OAAI,KAAK,MAAM,MAAW,eACxB;AAEF,OAAI,CAAC,WAAW,IAAI,KAAK,CACvB,OAAM,IAAI,qBACR;IACE,UAAU,KAAK;IACf;IACA;IACA;IACA;IACD,CAAC,KAAK,KAAK,EACZ,EACE,eAAe,oBAChB,CACF;;AAGL,OAAK,MAAM,UAAU,WACnB,KAAI,WAAA,aAAkB,EAAE,UAAU,KAAK,OACrC,OAAM,IAAI,MAAM,uCAAuC,OAAO,IAAI;AAKtE,MAAI;QACG,MAAM,QAAQ,UACjB,KAAI,EAAE,QAAQ,KAAK,OACjB,OAAM,IAAI,MAAM,oBAAoB,KAAK,mBAAmB;;AAKlE,OAAK,WAAW;;;AAIpB,IAAa,gBAAb,cAWU,OAYR;CASA;CAEA,YAAY,EACV,SACA,GAAG,QAKF;AACD,QAAM,KAAK;AACX,OAAK,UAAU;;CA+BjB,WACE,QAIK;AACL,SAAQ,MAAM,WAAmB,OAAO;;CAc1C,WAAW,KAAQ,MAAqC;AACtD,OAAK,SAAS,OAAO,IAAI,gBAAgB;AACzC,OAAK,MAAM,OAAO,IAAI,WAAW;GAC/B,UAAU,EAAE;GACZ,UAAU,EAAE;GACZ,UAAU,KAAK;GACf,WAAW,KAAK;GAChB,MAAM,KAAK;GACZ,CAAC,CACC,KAAK,KAAK,SAAS,CACnB,KACC,IAAI,aAAa,CAAC;GAAE,SAAS;GAAK,OAAO;GAAa,CAAC,EAAE,CAAC,WAAW,CAAC,CACvE;AACF,OAAK,eAAuB,KAAK,IAAI;;CAGxC,WAAW,OAAyB,KAA2B;AAC7D,MAAI,QAAA,WAAa;AACf,OAAI,UAAA,YACF,OAAM,IAAI,MAAM,wCAAwC;AAE1D,QAAK,MAAM,OAAO,QAAQ,KACxB,IAAI,aAAa,CAAC;IAAE,SAAS;IAAK,OAAO;IAAa,CAAC,EAAE,CAAC,WAAW,CAAC,CACvE;SACI;AACL,QAAK,MAAM,KAAK,SAAS,KAAK,MAAM;AACnC,QAAK,MAAM,KAAK,SAAsB,KAAK,MAAM;;;CAItD,aACE,OACA,MACA,QACA;AAEA,MAAI,UAAA,eAAmB,CAAC,KAAK,MAAA,aAC3B,MAAK,MAAM,SAAS,QAAQ,YAAY,OAAO,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;AAIxE,OAAK,MAAM,OAAO,KAChB,OAAO,KAAK,UAAU;AAUpB,UAAO,IAAI,aATI,MAAM,KAAK,SAAS;AACjC,QAAI,QAAQ,KAAK,CACf,QAAO;AAET,WAAO;KACL,SAAS,SAAA,YAAe,MAAM,UAAU,MAAM,GAAG,KAAK,GAAG;KACzD,OAAO;KACR;KACD,EAC8B,CAAC,WAAW,CAAC;IAC7C,CACH;EAGD,MAAM,OAAO,OAAO,OAChB,OAAO,OAAO,OAAO,KAAK,GACzB,OAAO,KAAK,KAAK,MAAM;AAC5B,OAAK,MAAM,OAAO,KAChB,KAAI,QAAA,WAAa;GACf,MAAM,cAAc,UAAU,MAAM,GAAG,KAAK,GAAG;AAC9C,QAAK,SAAyC,eAC7C,IAAI,gBAAgB;AACtB,QAAK,MAAM,KAAK,SAAS,KAAK,YAAY;AACzC,QAAK,MAAM,KAAK,SAAsB,KAAK,YAAY;;;;;;CAQ9D,MAAe,cACb,QACwB;EACxB,MAAM,OAAO,QAAQ;EACrB,MAAM,QAAQ,IAAIC,OAAe;EACjC,MAAM,aAAgD,GACnD,QAAQ,MAAM,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,EACnD;EACD,MAAM,WAA8C,EAAE;EAEtD,IAAI,YAAgD,EAAE;AACtD,MAAI,KACF,aAAY,OAAO,aAChB,MAAM,eAAe,KAAK,mBAAmB,CAAC,EAAE,QAE9C,MAAyC,gBAAgB,EAAE,GAAG,CAChE,CACF;EAGH,MAAM,kBAAyC,EAAE;EAEjD,SAAS,QACP,OACA,KACA,OACA,cAAc,OACd;AACA,OAAI,QAAA,aAAe,SAAA,eAAkB,KAAA,EACnC,UAAS,OAAO,MAAM,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI;AAEzD,OAAI,WAAW,WAAW,KAAA,EACxB;AAEF,OAAI,SAAS,SAAS,KAAA,EACpB,OAAM,IAAI,MAAM,YAAY,IAAI,aAAa;AAE/C,mBAAgB,KAAK;IAAE,KAAK;IAAO,MAAM;IAAK;IAAa,CAAC;AAC5D,UAAO,MAAM,QACX,WAAW,QACX,SAAS,MACT,UAAU,MAAM,QAAQ,KAAA,GACxB,YACD;;AAGH,OAAK,MAAM,CAAC,KAAK,aAAa,OAAO,QAAQ,KAAK,QAAQ,MAAM,EAG3D;GACH,MAAM,aAAa,uBAAuB,IAAI;GAC9C,MAAM,OAAO,SAAS;GACtB,MAAM,WAAW,SAAS,YAAY,EAAE;AACxC,OACE,KAAK,iBAAiB,SAAS,IAAI,IACnC,KAAK,gBAAgB,SAAS,IAAI,CAElC,UAAS,cAAc;YACd,KAAK,iBAAiB,SAAS,IAAI,CAC5C,UAAS,cAAc;YACd,KAAK,gBAAgB,SAAS,IAAI,CAC3C,UAAS,cAAc;AAEzB,OAAI,MAAM;IACR,MAAM,eAAe,OAAO,SAAS,WAAW,OAAO,IAAI;IAC3D,MAAM,mBACJ,UAAU,SAAS,KAAA,IACf,MAAM,UAAU,KAAK,cAAc;KACjC,GAAG;KACH,MAAM;KACP,CAAC,GACF,KAAK,SAAS,OAAO;AAE3B,qBAAiB,eAAe;AAChC,qBAAiB,cAAc;AAE/B,QAAI,OAAO,KAAK,iBAAiB,MAAM,CAAC,SAAS,GAAG;KAClD,MAAM,CAAC,GAAG,KAAK,MAAM,OAAO,kBAAkB,WAAW;AACzD,SAAI,MAAM,KAAA,EACR,OAAM,IAAI,MACR,8BAA8B,IAAI,8BACnC;KAKH,SAAS,qBAEP,OAC4B;AAC5B,aAAO,QAAQ,MAAM,cAAc;;KAGrC,SAAS,aACP,IACA,MACQ;AACR,UAAI,OAAO,KAAA,KAAa,CAACC,SAAO,GAAG,CACjC,QAAO;eACE,qBAAqB,KAAK,CACnC,KAAI;OACF,IAAI,UAAU,KAAK,SAAS;AAC5B,iBAAU,QAAQ,WAAW,WAAW,GACpC,QAAQ,MAAM,EAAkB,GAChC;AACJ,cAAO;cACD;AACN,cAAO,KAAK,SAAS;;UAGvB,QAAO,KAAK,QAAQ;;AAIxB,SAAI,MAAM,KAAA,EACR,YAAW,cAAc;MACvB,MAAM,aAAa,EAAE,IAAI,EAAE,KAAK;MAChC,GAAG;MACJ;AAEH,cAAS,cAAc;MACrB,MAAM,aAAa,EAAE,IAAI,EAAE,KAAK;MAChC,GAAG;MACJ;WACI;KAIL,MAAM,UAAU,MAAM,QAAQ,MAAM,YAAY,SAAS;AACzD,gBAAW,cAAc;AACzB,cAAS,cAAc;;UAEpB;IAIL,MAAM,UAAU,MAAM,QAAQ,MAAM,YAAY,SAAS;AACzD,eAAW,cAAc;AACzB,aAAS,cAAc;;;EAG3B,MAAM,cAAc,CAAC,GAAG,KAAK,QAAQ,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO;AAChE,OAAI,IAAI,EACN,QAAO;YACE,IAAI,EACb,QAAO;OAEP,QAAO;IAET;AACF,OAAK,MAAM,CAAC,OAAO,QAAQ,YACzB,SAAQ,uBAAuB,MAAM,EAAE,uBAAuB,IAAI,CAAC;AAErE,OAAK,MAAM,CAAC,OAAO,aAAa,OAAO,QAAQ,KAAK,QAAQ,SAAS,EAAE;GACrE,MAAM,cAAsC;IAC1C,GAAG,OAAO,YACR,OAAO,KAAK,KAAK,QAAQ,MAAM,CAC5B,QAAQ,MAAM,MAAM,MAAM,CAC1B,KAAK,MAAM,CAAC,uBAAuB,EAAE,EAAE,uBAAuB,EAAE,CAAC,CAAC,CACtE;KACA,MAAM;IACR;AACD,QAAK,MAAM,UAAU,OAAO,OAAO,SAAS,EAAE;IAC5C,IAAI;AACJ,QAAI,OAAO,SAAS,KAAA,EAClB,QAAO,OAAO;QAEd,QAAO;AAET,SAAK,MAAM,CAAC,OAAO,QAAQ,OAAO,QAAQ,KAAK,CAC7C,SACE,uBAAuB,MAAM,EAC7B,uBAAuB,IAAI,EAC3B,OACA,KACD;;;AAIP,OAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,QAAQ,MAAM,CAI1D,KAAI,KAAK,SAAS,KAAA,EAChB,MAAK,MAAM,OAAO,KAAK,KACrB,SACE,uBAAuB,IAAI,EAC3B,uBAAuB,IAAI,EAC3B,KAAA,GACA,KACD;AAIP,8BAA4B,KAAK,QAAQ,OAAO,iBAAiB,QAAQ;AACzE,SAAO;;;;;;;CAQT,SACE,QACe;EACf,MAAM,OAAO,QAAQ;EACrB,MAAM,QAAQ,IAAID,OAAe;EACjC,MAAM,aAAgD,GACnD,QAAQ,MAAM,QACb,EACE,QAAQ,EAAE,KAAK,EAChB,EACD,MACD,EACF;EACD,MAAM,WAA8C,EAAE;EAEtD,IAAI,YAAgD,EAAE;AACtD,MAAI,KACF,aAAY,OAAO,YACjB,mBAAmB,KAAK,cAAc,CAAC,CAAC,QAErC,MAAyC,gBAAgB,EAAE,GAAG,CAChE,CACF;EAGH,MAAM,kBAAyC,EAAE;EAEjD,SAAS,QACP,OACA,KACA,OACA,cAAc,OACd;AACA,OAAI,QAAA,aAAe,SAAA,eAAkB,KAAA,EACnC,UAAS,OAAO,MAAM,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI;AAEzD,OAAI,WAAW,WAAW,KAAA,EACxB;AAEF,OAAI,SAAS,SAAS,KAAA,EACpB,OAAM,IAAI,MAAM,YAAY,IAAI,aAAa;AAE/C,mBAAgB,KAAK;IAAE,KAAK;IAAO,MAAM;IAAK;IAAa,CAAC;AAC5D,UAAO,MAAM,QACX,WAAW,QACX,SAAS,MACT,UAAU,MAAM,QAAQ,KAAA,GACxB,YACD;;AAGH,OAAK,MAAM,CAAC,KAAK,aAAa,OAAO,QAAQ,KAAK,QAAQ,MAAM,EAG3D;GACH,MAAM,aAAa,uBAAuB,IAAI;GAC9C,MAAM,OAAO,SAAS;GACtB,MAAM,WAAW,SAAS,YAAY,EAAE;AACxC,OACE,KAAK,iBAAiB,SAAS,IAAI,IACnC,KAAK,gBAAgB,SAAS,IAAI,CAElC,UAAS,cAAc;YACd,KAAK,iBAAiB,SAAS,IAAI,CAC5C,UAAS,cAAc;YACd,KAAK,gBAAgB,SAAS,IAAI,CAC3C,UAAS,cAAc;AAEzB,OAAI,MAAM;IACR,MAAM,eAAe,OAAO,SAAS,WAAW,OAAO,IAAI;IAC3D,MAAM,mBACJ,UAAU,SAAS,KAAA,IACf,UAAU,KAAK,SAAS;KACtB,GAAG;KACH,MAAM;KACP,CAAC,GACF,KAAK,SAAS,OAAO;AAC3B,qBAAiB,eAAe;AAChC,qBAAiB,cAAc;AAC/B,QAAI,OAAO,KAAK,iBAAiB,MAAM,CAAC,SAAS,GAAG;KAClD,MAAM,CAAC,GAAG,KAAK,MAAM,OAAO,kBAAkB,WAAW;AACzD,SAAI,MAAM,KAAA,EACR,OAAM,IAAI,MACR,8BAA8B,IAAI,8BACnC;KAKH,SAAS,qBAEP,OAC4B;AAC5B,aAAO,QAAQ,MAAM,cAAc;;KAGrC,SAAS,aACP,IACA,MACQ;AACR,UAAI,OAAO,KAAA,KAAa,CAACC,SAAO,GAAG,CACjC,QAAO;eACE,qBAAqB,KAAK,CACnC,KAAI;OACF,IAAI,UAAU,KAAK,SAAS;AAC5B,iBAAU,QAAQ,WAAW,WAAW,GACpC,QAAQ,MAAM,EAAkB,GAChC;AACJ,cAAO;cACD;AACN,cAAO,KAAK,SAAS;;UAGvB,QAAO,KAAK,QAAQ;;AAIxB,SAAI,MAAM,KAAA,EACR,YAAW,cAAc;MACvB,MAAM,aAAa,EAAE,IAAI,EAAE,KAAK;MAChC,GAAG;MACJ;AAEH,cAAS,cAAc;MACrB,MAAM,aAAa,EAAE,IAAI,EAAE,KAAK;MAChC,GAAG;MACJ;WACI;KAIL,MAAM,UAAU,MAAM,QAAQ,MAAM,YAAY,SAAS;AACzD,gBAAW,cAAc;AACzB,cAAS,cAAc;;UAEpB;IAIL,MAAM,UAAU,MAAM,QAAQ,MAAM,YAAY,SAAS;AACzD,eAAW,cAAc;AACzB,aAAS,cAAc;;;EAG3B,MAAM,cAAc,CAAC,GAAG,KAAK,QAAQ,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO;AAChE,OAAI,IAAI,EACN,QAAO;YACE,IAAI,EACb,QAAO;OAEP,QAAO;IAET;AACF,OAAK,MAAM,CAAC,OAAO,QAAQ,YACzB,SAAQ,uBAAuB,MAAM,EAAE,uBAAuB,IAAI,CAAC;AAErE,OAAK,MAAM,CAAC,OAAO,aAAa,OAAO,QAAQ,KAAK,QAAQ,SAAS,EAAE;GACrE,MAAM,cAAsC;IAC1C,GAAG,OAAO,YACR,OAAO,KAAK,KAAK,QAAQ,MAAM,CAC5B,QAAQ,MAAM,MAAM,MAAM,CAC1B,KAAK,MAAM,CAAC,uBAAuB,EAAE,EAAE,uBAAuB,EAAE,CAAC,CAAC,CACtE;KACA,MAAM;IACR;AACD,QAAK,MAAM,UAAU,OAAO,OAAO,SAAS,EAAE;IAC5C,IAAI;AACJ,QAAI,OAAO,SAAS,KAAA,EAClB,QAAO,OAAO;QAEd,QAAO;AAET,SAAK,MAAM,CAAC,OAAO,QAAQ,OAAO,QAAQ,KAAK,CAC7C,SACE,uBAAuB,MAAM,EAC7B,uBAAuB,IAAI,EAC3B,OACA,KACD;;;AAIP,OAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,QAAQ,MAAM,CAI1D,KAAI,KAAK,SAAS,KAAA,EAChB,MAAK,MAAM,OAAO,KAAK,KACrB,SACE,uBAAuB,IAAI,EAC3B,uBAAuB,IAAI,EAC3B,KAAA,GACA,KACD;AAIP,8BAA4B,KAAK,QAAQ,OAAO,iBAAiB,QAAQ;AACzE,SAAO;;;AAKX,SAAS,gBAAgB,GAAqC;AAC5D,QAEE,OAAQ,EAAyB,eAAe,cAEhD,OAAQ,EAAyB,eAAe;;AAIpD,SAAS,uBAAuB,KAAa;AAC3C,KAAI,QAAQ,WACV,QAAO,IAAI,IAAI;AAEjB,QAAO;;;;;;;;AA+BT,SAAS,4BACP,OACA,YACA,SAMM;CACN,MAAM,UAAU,IAAI,IAAI,WAAW,KAAK,MAAM,EAAE,IAAI,CAAC;CACrD,MAAM,6BAA6B,CACjC,GAAG,IAAI,IACL,WACG,QAAQ,MAAM,CAAC,EAAE,eAAe,EAAE,SAAA,UAAa,CAC/C,KAAK,MAAM,EAAE,KAAK,CACtB,CACF,CAAC,MAAM;AAER,MAAK,MAAM,eAAe,4BAA4B;AACpD,MAAI,QAAQ,IAAI,YAAY,CAAE;EAC9B,MAAM,SAAU,OAAO,KAAK,MAAM,CAAS,MACxC,MAAM,uBAAuB,EAAE,KAAK,YACtC;AACD,MAAI,WAAW,KAAA,KAAa,MAAM,SAAS,eAAgB;AAC3D,UAAQ,aAAa,IAAI"}
|
|
1
|
+
{"version":3,"file":"graph.js","names":["Graph","DrawableGraph","isUuid"],"sources":["../../src/graph/graph.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-use-before-define */\nimport {\n _coerceToRunnable,\n Runnable,\n RunnableConfig,\n RunnableInterface,\n RunnableIOSchema,\n type RunnableLike as LangChainRunnableLike,\n} from \"@langchain/core/runnables\";\nimport {\n Node as DrawableGraphNode,\n Graph as DrawableGraph,\n} from \"@langchain/core/runnables/graph\";\nimport { All, BaseCheckpointSaver } from \"@langchain/langgraph-checkpoint\";\nimport { z } from \"zod/v4\";\nimport { validate as isUuid } from \"@langchain/core/utils/uuid\";\nimport type {\n RunnableLike,\n LangGraphRunnableConfig,\n} from \"../pregel/runnable_types.js\";\nimport { PregelNode } from \"../pregel/read.js\";\nimport { Channel, Pregel } from \"../pregel/index.js\";\nimport type { PregelOptions, PregelParams } from \"../pregel/types.js\";\nimport { BaseChannel } from \"../channels/base.js\";\nimport { EphemeralValue } from \"../channels/ephemeral_value.js\";\nimport { ChannelWrite, PASSTHROUGH } from \"../pregel/write.js\";\nimport {\n _isSend,\n CHECKPOINT_NAMESPACE_END,\n CHECKPOINT_NAMESPACE_SEPARATOR,\n END,\n Send,\n START,\n TAG_HIDDEN,\n} from \"../constants.js\";\nimport {\n gatherIterator,\n gatherIteratorSync,\n RunnableCallable,\n} from \"../utils.js\";\nimport {\n InvalidUpdateError,\n NodeError,\n NodeInterrupt,\n UnreachableNodeError,\n} from \"../errors.js\";\nimport { StateDefinition, StateType } from \"./annotation.js\";\nimport { isPregelLike } from \"../pregel/utils/subgraph.js\";\nimport type { StreamTransformer } from \"../stream/types.js\";\nimport type { GraphNodeReturnValue } from \"./types.js\";\n\nexport interface BranchOptions<\n IO,\n N extends string,\n CallOptions extends LangGraphRunnableConfig = LangGraphRunnableConfig,\n> {\n source: N;\n path: RunnableLike<IO, BranchPathReturnValue, CallOptions>;\n pathMap?: Record<string, N | typeof END> | (N | typeof END)[];\n}\n\nexport type BranchPathReturnValue =\n | string\n | Send\n | (string | Send)[]\n | Promise<string | Send | (string | Send)[]>;\n\ntype CompiledGraphTypeNode<Spec> = Spec extends { node: infer N extends string }\n ? N\n : any; // eslint-disable-line @typescript-eslint/no-explicit-any\n\ntype CompiledGraphTypeContext<Spec> = Spec extends {\n context: infer Context extends Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n ? Context\n : Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any\n\ntype CompiledGraphTypeStreamTransformers<Spec> = Spec extends {\n streamTransformers: infer Transformers;\n}\n ? Transformers extends ReadonlyArray<\n () => StreamTransformer<any> // eslint-disable-line @typescript-eslint/no-explicit-any\n >\n ? Transformers\n : Transformers extends ReadonlyArray<\n StreamTransformer<any> // eslint-disable-line @typescript-eslint/no-explicit-any\n >\n ? { readonly [K in keyof Transformers]: () => Transformers[K] }\n : Transformers extends StreamTransformer<any> // eslint-disable-line @typescript-eslint/no-explicit-any\n ? readonly [() => Transformers]\n : []\n : [];\n\n/**\n * Convenience type for referencing a compiled graph by named type slots.\n *\n * @example\n * ```ts\n * type MyCompiledGraph = CompiledGraphType<{\n * state: State;\n * update: Update;\n * streamTransformers: [\n * StreamTransformer<Extensions>,\n * StreamTransformer<MoreExtensions>,\n * ];\n * }>;\n * ```\n */\nexport type CompiledGraphType<Spec extends object = object> = CompiledGraph<\n CompiledGraphTypeNode<Spec>,\n Spec extends { state: infer State } ? State : any, // eslint-disable-line @typescript-eslint/no-explicit-any\n Spec extends { update: infer Update } ? Update : any, // eslint-disable-line @typescript-eslint/no-explicit-any\n CompiledGraphTypeContext<Spec>,\n Spec extends { input: infer Input } ? Input : any, // eslint-disable-line @typescript-eslint/no-explicit-any\n Spec extends { output: infer Output } ? Output : any, // eslint-disable-line @typescript-eslint/no-explicit-any\n Spec extends { nodeReturn: infer NodeReturn } ? NodeReturn : unknown,\n Spec extends { command: infer Command } ? Command : unknown,\n Spec extends { streamCustom: infer StreamCustom } ? StreamCustom : any, // eslint-disable-line @typescript-eslint/no-explicit-any\n CompiledGraphTypeStreamTransformers<Spec>\n>;\n\ntype NodeAction<S, U, C extends StateDefinition> = RunnableLike<\n S,\n U extends object ? U & Record<string, any> : U, // eslint-disable-line @typescript-eslint/no-explicit-any\n LangGraphRunnableConfig<StateType<C>>\n>;\n\nexport class Branch<\n IO,\n N extends string,\n CallOptions extends LangGraphRunnableConfig = LangGraphRunnableConfig,\n> {\n path: Runnable<IO, BranchPathReturnValue>;\n\n ends?: Record<string, N | typeof END>;\n\n constructor(options: Omit<BranchOptions<IO, N, CallOptions>, \"source\">) {\n if (Runnable.isRunnable(options.path)) {\n this.path = options.path as Runnable<IO, BranchPathReturnValue>;\n } else {\n this.path = _coerceToRunnable(\n options.path as LangChainRunnableLike<IO, BranchPathReturnValue>\n );\n }\n this.ends = Array.isArray(options.pathMap)\n ? options.pathMap.reduce(\n (acc, n) => {\n acc[n] = n;\n return acc;\n },\n {} as Record<string, N | typeof END>\n )\n : options.pathMap;\n }\n\n run(\n writer: (\n dests: (string | Send)[],\n config: LangGraphRunnableConfig\n ) => Runnable | void | Promise<void>,\n reader?: (config: CallOptions) => IO\n ) {\n return ChannelWrite.registerWriter(\n new RunnableCallable({\n name: \"<branch_run>\",\n trace: false,\n func: async (input: IO, config: CallOptions) => {\n try {\n return await this._route(input, config, writer, reader);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any) {\n // Detect & warn if NodeInterrupt is thrown in a conditional edge\n if (e.name === NodeInterrupt.unminifiable_name) {\n console.warn(\n \"[WARN]: 'NodeInterrupt' thrown in conditional edge. This is likely a bug in your graph implementation.\\n\" +\n \"NodeInterrupt should only be thrown inside a node, not in edge conditions.\"\n );\n }\n throw e;\n }\n },\n })\n );\n }\n\n async _route(\n input: IO,\n config: CallOptions,\n writer: (\n dests: (string | Send)[],\n config: LangGraphRunnableConfig\n ) => Runnable | void | Promise<void>,\n reader?: (config: CallOptions) => IO\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): Promise<Runnable | any> {\n let result = await this.path.invoke(\n reader ? reader(config) : input,\n config\n );\n if (!Array.isArray(result)) {\n result = [result];\n }\n\n let destinations: (string | Send)[];\n if (this.ends) {\n destinations = result.map((r) => (_isSend(r) ? r : this.ends![r]));\n } else {\n destinations = result;\n }\n if (destinations.some((dest) => !dest)) {\n throw new Error(\"Branch condition returned unknown or null destination\");\n }\n if (destinations.filter(_isSend).some((packet) => packet.node === END)) {\n throw new InvalidUpdateError(\"Cannot send a packet to the END node\");\n }\n const writeResult = await writer(destinations, config);\n return writeResult ?? input;\n }\n}\n\nexport type NodeSpec<RunInput, RunOutput> = {\n runnable: Runnable<RunInput, RunOutput>;\n metadata?: Record<string, unknown>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n subgraphs?: Pregel<any, any>[];\n ends?: string[];\n defer?: boolean;\n /** Whether this node is an auto-generated node-level error handler. */\n isErrorHandler?: boolean;\n /** Name of the auto-generated error handler node to run on failure. */\n errorHandlerNode?: string;\n};\n\n/**\n * Return value type for node-level error handlers.\n *\n * Handlers may return a partial state update, a `Command`, or a Promise of either.\n *\n * @template Update - The update type (what fields can be returned)\n * @template Nodes - Union of valid node names for Command.goto\n */\nexport type NodeErrorHandlerReturnValue<\n Update,\n Nodes extends string = string,\n> = GraphNodeReturnValue<Update, Nodes>;\n\n/**\n * A node-level error handler callable.\n *\n * Invoked with the node input state, a {@link NodeError} describing the failed\n * node and thrown error, and the runnable config. The handler runs ONLY after\n * the failing node's {@link RetryPolicy} is exhausted. It may return a state\n * update or a `Command` (to route via `goto`).\n */\nexport type NodeErrorHandler<\n TState = unknown,\n TUpdate = Partial<TState>,\n Nodes extends string = string,\n> = (\n state: TState,\n error: NodeError,\n config?: LangGraphRunnableConfig\n) => NodeErrorHandlerReturnValue<TUpdate, Nodes>;\n\nexport type AddNodeOptions<Nodes extends string = string> = {\n metadata?: Record<string, unknown>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n subgraphs?: Pregel<any, any>[];\n ends?: Nodes[];\n defer?: boolean;\n};\n\nexport class Graph<\n N extends string = typeof START | typeof END,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunInput = any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput = any,\n NodeSpecType extends NodeSpec<RunInput, RunOutput> = NodeSpec<\n RunInput,\n RunOutput\n >,\n C extends StateDefinition = StateDefinition,\n> {\n nodes: Record<N, NodeSpecType>;\n\n edges: Set<[N | typeof START, N | typeof END]>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n branches: Record<string, Record<string, Branch<RunInput, N, any>>>;\n\n entryPoint?: string;\n\n compiled = false;\n\n constructor() {\n this.nodes = {} as Record<N, NodeSpecType>;\n this.edges = new Set();\n this.branches = {};\n }\n\n protected warnIfCompiled(message: string): void {\n if (this.compiled) {\n console.warn(message);\n }\n }\n\n get allEdges(): Set<[string, string]> {\n return this.edges;\n }\n\n addNode<K extends string, NodeInput = RunInput, NodeOutput = RunOutput>(\n nodes:\n | Record<K, NodeAction<NodeInput, NodeOutput, C>>\n | [\n key: K,\n action: NodeAction<NodeInput, NodeOutput, C>,\n options?: AddNodeOptions,\n ][]\n ): Graph<N | K, RunInput, RunOutput>;\n\n addNode<K extends string, NodeInput = RunInput, NodeOutput = RunOutput>(\n key: K,\n action: NodeAction<NodeInput, NodeOutput, C>,\n options?: AddNodeOptions\n ): Graph<N | K, RunInput, RunOutput>;\n\n addNode<K extends string, NodeInput = RunInput, NodeOutput = RunOutput>(\n ...args:\n | [\n key: K,\n action: NodeAction<NodeInput, NodeOutput, C>,\n options?: AddNodeOptions,\n ]\n | [\n nodes:\n | Record<K, NodeAction<NodeInput, NodeOutput, C>>\n | [\n key: K,\n action: NodeAction<NodeInput, NodeOutput, C>,\n options?: AddNodeOptions,\n ][],\n ]\n ): Graph<N | K, RunInput, RunOutput> {\n function isMutlipleNodes(\n args: unknown[]\n ): args is [\n nodes:\n | Record<K, NodeAction<NodeInput, RunOutput, C>>\n | [\n key: K,\n action: NodeAction<NodeInput, RunOutput, C>,\n options?: AddNodeOptions,\n ][],\n options?: AddNodeOptions,\n ] {\n return args.length >= 1 && typeof args[0] !== \"string\";\n }\n\n const nodes = (\n isMutlipleNodes(args) // eslint-disable-line no-nested-ternary\n ? Array.isArray(args[0])\n ? args[0]\n : Object.entries(args[0])\n : [[args[0], args[1], args[2]]]\n ) as [K, NodeAction<NodeInput, RunOutput, C>, AddNodeOptions][];\n\n if (nodes.length === 0) {\n throw new Error(\"No nodes provided in `addNode`\");\n }\n\n for (const [key, action, options] of nodes) {\n for (const reservedChar of [\n CHECKPOINT_NAMESPACE_SEPARATOR,\n CHECKPOINT_NAMESPACE_END,\n ]) {\n if (key.includes(reservedChar)) {\n throw new Error(\n `\"${reservedChar}\" is a reserved character and is not allowed in node names.`\n );\n }\n }\n this.warnIfCompiled(\n `Adding a node to a graph that has already been compiled. This will not be reflected in the compiled graph.`\n );\n\n if (key in this.nodes) {\n throw new Error(`Node \\`${key}\\` already present.`);\n }\n if (key === END) {\n throw new Error(`Node \\`${key}\\` is reserved.`);\n }\n\n const runnable = _coerceToRunnable<RunInput, RunOutput>(\n // Account for arbitrary state due to Send API\n action as RunnableLike<RunInput, RunOutput>\n );\n\n this.nodes[key as unknown as N] = {\n runnable,\n metadata: options?.metadata,\n subgraphs: isPregelLike(runnable) ? [runnable] : options?.subgraphs,\n ends: options?.ends,\n } as NodeSpecType;\n }\n\n return this as Graph<N | K, RunInput, RunOutput, NodeSpecType>;\n }\n\n addEdge(startKey: N | typeof START, endKey: N | typeof END): this {\n this.warnIfCompiled(\n `Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.`\n );\n\n if (startKey === END) {\n throw new Error(\"END cannot be a start node\");\n }\n if (endKey === START) {\n throw new Error(\"START cannot be an end node\");\n }\n if (\n Array.from(this.edges).some(([start]) => start === startKey) &&\n !(\"channels\" in this)\n ) {\n throw new Error(\n `Already found path for ${startKey}. For multiple edges, use StateGraph.`\n );\n }\n\n this.edges.add([startKey, endKey]);\n\n return this;\n }\n\n addConditionalEdges(\n source: BranchOptions<RunInput, N, LangGraphRunnableConfig<StateType<C>>>\n ): this;\n\n addConditionalEdges(\n source: N,\n path: RunnableLike<\n RunInput,\n BranchPathReturnValue,\n LangGraphRunnableConfig<StateType<C>>\n >,\n pathMap?: BranchOptions<\n RunInput,\n N,\n LangGraphRunnableConfig<StateType<C>>\n >[\"pathMap\"]\n ): this;\n\n addConditionalEdges(\n source:\n | N\n | BranchOptions<RunInput, N, LangGraphRunnableConfig<StateType<C>>>,\n path?: RunnableLike<\n RunInput,\n BranchPathReturnValue,\n LangGraphRunnableConfig<StateType<C>>\n >,\n pathMap?: BranchOptions<\n RunInput,\n N,\n LangGraphRunnableConfig<StateType<C>>\n >[\"pathMap\"]\n ): this {\n const options: BranchOptions<\n RunInput,\n N,\n LangGraphRunnableConfig<StateType<C>>\n > = typeof source === \"object\" ? source : { source, path: path!, pathMap };\n\n this.warnIfCompiled(\n \"Adding an edge to a graph that has already been compiled. This will not be reflected in the compiled graph.\"\n );\n if (!Runnable.isRunnable(options.path)) {\n options.path = _coerceToRunnable(\n options.path as LangChainRunnableLike<RunInput, BranchPathReturnValue>\n );\n }\n // find a name for condition\n const name =\n options.path.getName() === \"RunnableLambda\"\n ? \"condition\"\n : options.path.getName();\n // validate condition\n if (this.branches[options.source] && this.branches[options.source][name]) {\n throw new Error(\n `Condition \\`${name}\\` already present for node \\`${source}\\``\n );\n }\n // save it\n this.branches[options.source] ??= {};\n this.branches[options.source][name] = new Branch(options);\n return this;\n }\n\n /**\n * @deprecated use `addEdge(START, key)` instead\n */\n setEntryPoint(key: N): this {\n this.warnIfCompiled(\n \"Setting the entry point of a graph that has already been compiled. This will not be reflected in the compiled graph.\"\n );\n\n return this.addEdge(START, key);\n }\n\n /**\n * @deprecated use `addEdge(key, END)` instead\n */\n setFinishPoint(key: N): this {\n this.warnIfCompiled(\n \"Setting a finish point of a graph that has already been compiled. This will not be reflected in the compiled graph.\"\n );\n\n return this.addEdge(key, END);\n }\n\n compile<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const TTransformers extends ReadonlyArray<() => StreamTransformer<any>> =\n [],\n >({\n checkpointer,\n interruptBefore,\n interruptAfter,\n name,\n transformers,\n }: {\n checkpointer?: BaseCheckpointSaver | false;\n interruptBefore?: N[] | All;\n interruptAfter?: N[] | All;\n name?: string;\n /**\n * Stream transformer factories baked into the compiled graph. These run\n * automatically for every `streamEvents(..., { version: \"v3\" })` call,\n * before any call-site transformers.\n */\n transformers?: TTransformers;\n } = {}): CompiledGraph<\n N,\n RunInput,\n RunOutput,\n Record<string, any>,\n any,\n any,\n unknown,\n unknown,\n any,\n TTransformers\n > {\n // eslint-disable-line @typescript-eslint/no-explicit-any\n // validate the graph\n this.validate([\n ...(Array.isArray(interruptBefore) ? interruptBefore : []),\n ...(Array.isArray(interruptAfter) ? interruptAfter : []),\n ]);\n\n // create empty compiled graph\n const compiled = new CompiledGraph({\n builder: this,\n checkpointer,\n interruptAfter,\n interruptBefore,\n autoValidate: false,\n nodes: {} as Record<N | typeof START, PregelNode<RunInput, RunOutput>>,\n channels: {\n [START]: new EphemeralValue(),\n [END]: new EphemeralValue(),\n } as Record<N | typeof START | typeof END | string, BaseChannel>,\n inputChannels: START,\n outputChannels: END,\n streamChannels: [] as N[],\n streamMode: \"values\",\n name,\n streamTransformers: transformers,\n });\n\n // attach nodes, edges and branches\n for (const [key, node] of Object.entries<NodeSpec<RunInput, RunOutput>>(\n this.nodes\n )) {\n compiled.attachNode(key as N, node);\n }\n for (const [start, end] of this.edges) {\n compiled.attachEdge(start, end);\n }\n for (const [start, branches] of Object.entries(this.branches)) {\n for (const [name, branch] of Object.entries(branches)) {\n compiled.attachBranch(start as N, name, branch);\n }\n }\n\n return compiled.validate();\n }\n\n validate(interrupt?: string[]): void {\n // assemble sources\n const allSources = new Set([...this.allEdges].map(([src, _]) => src));\n for (const [start] of Object.entries(this.branches)) {\n allSources.add(start);\n }\n\n // validate sources\n for (const source of allSources) {\n if (source !== START && !(source in this.nodes)) {\n throw new Error(`Found edge starting at unknown node \\`${source}\\``);\n }\n }\n\n // assemble targets\n const allTargets = new Set([...this.allEdges].map(([_, target]) => target));\n for (const [start, branches] of Object.entries(this.branches)) {\n for (const branch of Object.values(branches)) {\n if (branch.ends != null) {\n for (const end of Object.values(branch.ends)) {\n allTargets.add(end);\n }\n } else {\n allTargets.add(END);\n for (const node of Object.keys(this.nodes)) {\n if (node !== start) {\n allTargets.add(node);\n }\n }\n }\n }\n }\n for (const node of Object.values<NodeSpecType>(this.nodes)) {\n for (const target of node.ends ?? []) {\n allTargets.add(target);\n }\n }\n // Node-level error handlers can route to any node via `Command({ goto })`\n // (saga / compensation flows), so treat them like an open-ended branch:\n // any node may be a recovery target reachable from a handler.\n const hasErrorHandler = Object.values<NodeSpecType>(this.nodes).some(\n (node) => node.isErrorHandler\n );\n if (hasErrorHandler) {\n for (const node of Object.keys(this.nodes)) {\n allTargets.add(node);\n }\n }\n // validate targets\n for (const node of Object.keys(this.nodes)) {\n // auto-generated error handler nodes are reachable only on failure of\n // their source node, so they are exempt from the reachability check.\n if (this.nodes[node as N].isErrorHandler) {\n continue;\n }\n if (!allTargets.has(node)) {\n throw new UnreachableNodeError(\n [\n `Node \\`${node}\\` is not reachable.`,\n \"\",\n \"If you are returning Command objects from your node,\",\n 'make sure you are passing names of potential destination nodes as an \"ends\" array',\n 'into \".addNode(..., { ends: [\"node1\", \"node2\"] })\".',\n ].join(\"\\n\"),\n {\n lc_error_code: \"UNREACHABLE_NODE\",\n }\n );\n }\n }\n for (const target of allTargets) {\n if (target !== END && !(target in this.nodes)) {\n throw new Error(`Found edge ending at unknown node \\`${target}\\``);\n }\n }\n\n // validate interrupts\n if (interrupt) {\n for (const node of interrupt) {\n if (!(node in this.nodes)) {\n throw new Error(`Interrupt node \\`${node}\\` is not present`);\n }\n }\n }\n\n this.compiled = true;\n }\n}\n\nexport class CompiledGraph<\n N extends string,\n State = any, // eslint-disable-line @typescript-eslint/no-explicit-any\n Update = any, // eslint-disable-line @typescript-eslint/no-explicit-any\n ContextType extends Record<string, any> = Record<string, any>, // eslint-disable-line @typescript-eslint/no-explicit-any\n InputType = any, // eslint-disable-line @typescript-eslint/no-explicit-any\n OutputType = any, // eslint-disable-line @typescript-eslint/no-explicit-any\n NodeReturnType = unknown,\n CommandType = unknown,\n StreamCustomType = any, // eslint-disable-line @typescript-eslint/no-explicit-any\n TStreamTransformers extends ReadonlyArray<() => StreamTransformer<any>> = [], // eslint-disable-line @typescript-eslint/no-explicit-any\n> extends Pregel<\n Record<N | typeof START, PregelNode<State, Update>>,\n Record<N | typeof START | typeof END | string, BaseChannel>,\n ContextType & Record<string, any>, // eslint-disable-line @typescript-eslint/no-explicit-any\n InputType,\n OutputType,\n InputType,\n OutputType,\n NodeReturnType,\n CommandType,\n StreamCustomType,\n TStreamTransformers\n> {\n declare \"~NodeType\": N;\n\n declare \"~NodeReturnType\": NodeReturnType;\n\n declare \"~RunInput\": Update;\n\n declare \"~RunOutput\": State;\n\n builder: Graph<N, State, Update>;\n\n constructor({\n builder,\n ...rest\n }: { builder: Graph<N, State, Update> } & PregelParams<\n Record<N | typeof START, PregelNode<State, Update>>,\n Record<N | typeof START | typeof END | string, BaseChannel>,\n TStreamTransformers\n >) {\n super(rest);\n this.builder = builder;\n }\n\n override withConfig<\n const TTransformers extends ReadonlyArray<() => StreamTransformer<any>> =\n [],\n >(\n config: Omit<LangGraphRunnableConfig, \"store\" | \"writer\" | \"interrupt\"> & {\n streamTransformers: TTransformers;\n }\n ): CompiledGraph<\n N,\n State,\n Update,\n ContextType,\n InputType,\n OutputType,\n NodeReturnType,\n CommandType,\n StreamCustomType,\n readonly [...TStreamTransformers, ...TTransformers]\n >;\n\n override withConfig(\n config: PregelOptions<\n Record<N | typeof START, PregelNode<State, Update>>,\n Record<N | typeof START | typeof END | string, BaseChannel>,\n ContextType & Record<string, any>\n >\n ): this;\n\n override withConfig(\n config: Omit<LangGraphRunnableConfig, \"store\" | \"writer\" | \"interrupt\"> & {\n streamTransformers?: ReadonlyArray<() => StreamTransformer<any>>;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ): any {\n return (super.withConfig as any)(config) as unknown as CompiledGraph<\n N,\n State,\n Update,\n ContextType,\n InputType,\n OutputType,\n NodeReturnType,\n CommandType,\n StreamCustomType,\n ReadonlyArray<() => StreamTransformer<any>>\n >;\n }\n\n attachNode(key: N, node: NodeSpec<State, Update>): void {\n this.channels[key] = new EphemeralValue();\n this.nodes[key] = new PregelNode({\n channels: [],\n triggers: [],\n metadata: node.metadata,\n subgraphs: node.subgraphs,\n ends: node.ends,\n })\n .pipe(node.runnable)\n .pipe(\n new ChannelWrite([{ channel: key, value: PASSTHROUGH }], [TAG_HIDDEN])\n );\n (this.streamChannels as N[]).push(key);\n }\n\n attachEdge(start: N | typeof START, end: N | typeof END): void {\n if (end === END) {\n if (start === START) {\n throw new Error(\"Cannot have an edge from START to END\");\n }\n this.nodes[start].writers.push(\n new ChannelWrite([{ channel: END, value: PASSTHROUGH }], [TAG_HIDDEN])\n );\n } else {\n this.nodes[end].triggers.push(start);\n (this.nodes[end].channels as string[]).push(start);\n }\n }\n\n attachBranch(\n start: N | typeof START,\n name: string,\n branch: Branch<State, N>\n ) {\n // add hidden start node\n if (start === START && !this.nodes[START]) {\n this.nodes[START] = Channel.subscribeTo(START, { tags: [TAG_HIDDEN] });\n }\n\n // attach branch writer\n this.nodes[start].pipe(\n branch.run((dests) => {\n const writes = dests.map((dest) => {\n if (_isSend(dest)) {\n return dest;\n }\n return {\n channel: dest === END ? END : `branch:${start}:${name}:${dest}`,\n value: PASSTHROUGH,\n };\n });\n return new ChannelWrite(writes, [TAG_HIDDEN]);\n })\n );\n\n // attach branch readers\n const ends = branch.ends\n ? Object.values(branch.ends)\n : (Object.keys(this.nodes) as N[]);\n for (const end of ends) {\n if (end !== END) {\n const channelName = `branch:${start}:${name}:${end}`;\n (this.channels as Record<string, BaseChannel>)[channelName] =\n new EphemeralValue();\n this.nodes[end].triggers.push(channelName);\n (this.nodes[end].channels as string[]).push(channelName);\n }\n }\n }\n\n /**\n * Returns a drawable representation of the computation graph.\n */\n override async getGraphAsync(\n config?: RunnableConfig & { xray?: boolean | number }\n ): Promise<DrawableGraph> {\n const xray = config?.xray;\n const graph = new DrawableGraph();\n const startNodes: Record<string, DrawableGraphNode> = {\n [START]: graph.addNode({ schema: z.any() }, START),\n };\n const endNodes: Record<string, DrawableGraphNode> = {};\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let subgraphs: Record<string, CompiledGraph<any>> = {};\n if (xray) {\n subgraphs = Object.fromEntries(\n (await gatherIterator(this.getSubgraphsAsync())).filter(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (x): x is [string, CompiledGraph<any>] => isCompiledGraph(x[1])\n )\n );\n }\n\n const discoveredEdges: DiscoveredGraphEdge[] = [];\n\n function addEdge(\n start: string,\n end: string,\n label?: string,\n conditional = false\n ) {\n if (end === END && endNodes[END] === undefined) {\n endNodes[END] = graph.addNode({ schema: z.any() }, END);\n }\n if (startNodes[start] === undefined) {\n return;\n }\n if (endNodes[end] === undefined) {\n throw new Error(`End node ${end} not found!`);\n }\n discoveredEdges.push({ src: start, dest: end, conditional });\n return graph.addEdge(\n startNodes[start],\n endNodes[end],\n label !== end ? label : undefined,\n conditional\n );\n }\n\n for (const [key, nodeSpec] of Object.entries(this.builder.nodes) as [\n N,\n NodeSpec<State, Update>,\n ][]) {\n const displayKey = _escapeMermaidKeywords(key);\n const node = nodeSpec.runnable;\n const metadata = { ...nodeSpec.metadata };\n if (\n this.interruptBefore?.includes(key) &&\n this.interruptAfter?.includes(key)\n ) {\n metadata.__interrupt = \"before,after\";\n } else if (this.interruptBefore?.includes(key)) {\n metadata.__interrupt = \"before\";\n } else if (this.interruptAfter?.includes(key)) {\n metadata.__interrupt = \"after\";\n }\n const toolNames = _getToolNames(node);\n if (toolNames !== undefined) {\n metadata.__tools = toolNames;\n }\n if (xray) {\n const newXrayValue = typeof xray === \"number\" ? xray - 1 : xray;\n const drawableSubgraph =\n subgraphs[key] !== undefined\n ? await subgraphs[key].getGraphAsync({\n ...config,\n xray: newXrayValue,\n })\n : node.getGraph(config);\n\n drawableSubgraph.trimFirstNode();\n drawableSubgraph.trimLastNode();\n\n if (Object.keys(drawableSubgraph.nodes).length > 1) {\n const [e, s] = graph.extend(drawableSubgraph, displayKey);\n if (e === undefined) {\n throw new Error(\n `Could not extend subgraph \"${key}\" due to missing entrypoint.`\n );\n }\n\n // TODO: Remove default name once we stop supporting core 0.2.0\n // eslint-disable-next-line no-inner-declarations\n function _isRunnableInterface(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n thing: any\n ): thing is RunnableInterface {\n return thing ? thing.lc_runnable : false;\n }\n // eslint-disable-next-line no-inner-declarations\n function _nodeDataStr(\n id: string | undefined,\n data: RunnableInterface | RunnableIOSchema\n ): string {\n if (id !== undefined && !isUuid(id)) {\n return id;\n } else if (_isRunnableInterface(data)) {\n try {\n let dataStr = data.getName();\n dataStr = dataStr.startsWith(\"Runnable\")\n ? dataStr.slice(\"Runnable\".length)\n : dataStr;\n return dataStr;\n } catch {\n return data.getName();\n }\n } else {\n return data.name ?? \"UnknownSchema\";\n }\n }\n // TODO: Remove casts when we stop supporting core 0.2.0\n if (s !== undefined) {\n startNodes[displayKey] = {\n name: _nodeDataStr(s.id, s.data),\n ...s,\n } as DrawableGraphNode;\n }\n endNodes[displayKey] = {\n name: _nodeDataStr(e.id, e.data),\n ...e,\n } as DrawableGraphNode;\n } else {\n // TODO: Remove when we stop supporting core 0.2.0\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const newNode = graph.addNode(node, displayKey, metadata);\n startNodes[displayKey] = newNode;\n endNodes[displayKey] = newNode;\n }\n } else {\n // TODO: Remove when we stop supporting core 0.2.0\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const newNode = graph.addNode(node, displayKey, metadata);\n startNodes[displayKey] = newNode;\n endNodes[displayKey] = newNode;\n }\n }\n const sortedEdges = [...this.builder.allEdges].sort(([a], [b]) => {\n if (a < b) {\n return -1;\n } else if (b > a) {\n return 1;\n } else {\n return 0;\n }\n });\n for (const [start, end] of sortedEdges) {\n addEdge(_escapeMermaidKeywords(start), _escapeMermaidKeywords(end));\n }\n for (const [start, branches] of Object.entries(this.builder.branches)) {\n const defaultEnds: Record<string, string> = {\n ...Object.fromEntries(\n Object.keys(this.builder.nodes)\n .filter((k) => k !== start)\n .map((k) => [_escapeMermaidKeywords(k), _escapeMermaidKeywords(k)])\n ),\n [END]: END,\n };\n for (const branch of Object.values(branches)) {\n let ends;\n if (branch.ends !== undefined) {\n ends = branch.ends;\n } else {\n ends = defaultEnds;\n }\n for (const [label, end] of Object.entries(ends)) {\n addEdge(\n _escapeMermaidKeywords(start),\n _escapeMermaidKeywords(end),\n label,\n true\n );\n }\n }\n }\n for (const [key, node] of Object.entries(this.builder.nodes) as [\n N,\n NodeSpec<State, Update>,\n ][]) {\n if (node.ends !== undefined) {\n for (const end of node.ends) {\n addEdge(\n _escapeMermaidKeywords(key),\n _escapeMermaidKeywords(end),\n undefined,\n true\n );\n }\n }\n }\n addImplicitTerminalEndEdges(this.builder.nodes, discoveredEdges, addEdge);\n return graph;\n }\n\n /**\n * Returns a drawable representation of the computation graph.\n *\n * @deprecated Use getGraphAsync instead. The async method will be the default in the next minor core release.\n */\n override getGraph(\n config?: RunnableConfig & { xray?: boolean | number }\n ): DrawableGraph {\n const xray = config?.xray;\n const graph = new DrawableGraph();\n const startNodes: Record<string, DrawableGraphNode> = {\n [START]: graph.addNode(\n {\n schema: z.any(),\n },\n START\n ),\n };\n const endNodes: Record<string, DrawableGraphNode> = {};\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let subgraphs: Record<string, CompiledGraph<any>> = {};\n if (xray) {\n subgraphs = Object.fromEntries(\n gatherIteratorSync(this.getSubgraphs()).filter(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (x): x is [string, CompiledGraph<any>] => isCompiledGraph(x[1])\n )\n );\n }\n\n const discoveredEdges: DiscoveredGraphEdge[] = [];\n\n function addEdge(\n start: string,\n end: string,\n label?: string,\n conditional = false\n ) {\n if (end === END && endNodes[END] === undefined) {\n endNodes[END] = graph.addNode({ schema: z.any() }, END);\n }\n if (startNodes[start] === undefined) {\n return;\n }\n if (endNodes[end] === undefined) {\n throw new Error(`End node ${end} not found!`);\n }\n discoveredEdges.push({ src: start, dest: end, conditional });\n return graph.addEdge(\n startNodes[start],\n endNodes[end],\n label !== end ? label : undefined,\n conditional\n );\n }\n\n for (const [key, nodeSpec] of Object.entries(this.builder.nodes) as [\n N,\n NodeSpec<State, Update>,\n ][]) {\n const displayKey = _escapeMermaidKeywords(key);\n const node = nodeSpec.runnable;\n const metadata = { ...nodeSpec.metadata };\n if (\n this.interruptBefore?.includes(key) &&\n this.interruptAfter?.includes(key)\n ) {\n metadata.__interrupt = \"before,after\";\n } else if (this.interruptBefore?.includes(key)) {\n metadata.__interrupt = \"before\";\n } else if (this.interruptAfter?.includes(key)) {\n metadata.__interrupt = \"after\";\n }\n const toolNames = _getToolNames(node);\n if (toolNames !== undefined) {\n metadata.__tools = toolNames;\n }\n if (xray) {\n const newXrayValue = typeof xray === \"number\" ? xray - 1 : xray;\n const drawableSubgraph =\n subgraphs[key] !== undefined\n ? subgraphs[key].getGraph({\n ...config,\n xray: newXrayValue,\n })\n : node.getGraph(config);\n drawableSubgraph.trimFirstNode();\n drawableSubgraph.trimLastNode();\n if (Object.keys(drawableSubgraph.nodes).length > 1) {\n const [e, s] = graph.extend(drawableSubgraph, displayKey);\n if (e === undefined) {\n throw new Error(\n `Could not extend subgraph \"${key}\" due to missing entrypoint.`\n );\n }\n\n // TODO: Remove default name once we stop supporting core 0.2.0\n // eslint-disable-next-line no-inner-declarations\n function _isRunnableInterface(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n thing: any\n ): thing is RunnableInterface {\n return thing ? thing.lc_runnable : false;\n }\n // eslint-disable-next-line no-inner-declarations\n function _nodeDataStr(\n id: string | undefined,\n data: RunnableInterface | RunnableIOSchema\n ): string {\n if (id !== undefined && !isUuid(id)) {\n return id;\n } else if (_isRunnableInterface(data)) {\n try {\n let dataStr = data.getName();\n dataStr = dataStr.startsWith(\"Runnable\")\n ? dataStr.slice(\"Runnable\".length)\n : dataStr;\n return dataStr;\n } catch {\n return data.getName();\n }\n } else {\n return data.name ?? \"UnknownSchema\";\n }\n }\n // TODO: Remove casts when we stop supporting core 0.2.0\n if (s !== undefined) {\n startNodes[displayKey] = {\n name: _nodeDataStr(s.id, s.data),\n ...s,\n } as DrawableGraphNode;\n }\n endNodes[displayKey] = {\n name: _nodeDataStr(e.id, e.data),\n ...e,\n } as DrawableGraphNode;\n } else {\n // TODO: Remove when we stop supporting core 0.2.0\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const newNode = graph.addNode(node, displayKey, metadata);\n startNodes[displayKey] = newNode;\n endNodes[displayKey] = newNode;\n }\n } else {\n // TODO: Remove when we stop supporting core 0.2.0\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const newNode = graph.addNode(node, displayKey, metadata);\n startNodes[displayKey] = newNode;\n endNodes[displayKey] = newNode;\n }\n }\n const sortedEdges = [...this.builder.allEdges].sort(([a], [b]) => {\n if (a < b) {\n return -1;\n } else if (b > a) {\n return 1;\n } else {\n return 0;\n }\n });\n for (const [start, end] of sortedEdges) {\n addEdge(_escapeMermaidKeywords(start), _escapeMermaidKeywords(end));\n }\n for (const [start, branches] of Object.entries(this.builder.branches)) {\n const defaultEnds: Record<string, string> = {\n ...Object.fromEntries(\n Object.keys(this.builder.nodes)\n .filter((k) => k !== start)\n .map((k) => [_escapeMermaidKeywords(k), _escapeMermaidKeywords(k)])\n ),\n [END]: END,\n };\n for (const branch of Object.values(branches)) {\n let ends;\n if (branch.ends !== undefined) {\n ends = branch.ends;\n } else {\n ends = defaultEnds;\n }\n for (const [label, end] of Object.entries(ends)) {\n addEdge(\n _escapeMermaidKeywords(start),\n _escapeMermaidKeywords(end),\n label,\n true\n );\n }\n }\n }\n for (const [key, node] of Object.entries(this.builder.nodes) as [\n N,\n NodeSpec<State, Update>,\n ][]) {\n if (node.ends !== undefined) {\n for (const end of node.ends) {\n addEdge(\n _escapeMermaidKeywords(key),\n _escapeMermaidKeywords(end),\n undefined,\n true\n );\n }\n }\n }\n addImplicitTerminalEndEdges(this.builder.nodes, discoveredEdges, addEdge);\n return graph;\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isCompiledGraph(x: unknown): x is CompiledGraph<any> {\n return (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (x as CompiledGraph<any>).attachNode === \"function\" &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n typeof (x as CompiledGraph<any>).attachEdge === \"function\"\n );\n}\n\nfunction _escapeMermaidKeywords(key: string) {\n if (key === \"subgraph\") {\n return `\"${key}\"`;\n }\n return key;\n}\n\n// Duck-typed so tool nodes from other packages are covered too.\nfunction _getToolNames(node: unknown): string[] | undefined {\n const tools = (node as { tools?: unknown })?.tools;\n if (\n !Array.isArray(tools) ||\n tools.length === 0 ||\n !tools.every((tool) => typeof tool?.name === \"string\")\n ) {\n return undefined;\n }\n return tools.map((tool) => tool.name);\n}\n\n/**\n * An edge collected while building a {@link DrawableGraph} from a compiled\n * {@link StateGraph}.\n *\n * Used by {@link addImplicitTerminalEndEdges} to detect nodes that should\n * receive an implicit edge to {@link END} (terminal nodes with no outgoing\n * edges in the drawable view).\n *\n * @internal\n */\ntype DiscoveredGraphEdge = {\n /** Display name of the source node (Mermaid-escaped). */\n src: string;\n /** Display name of the target node (Mermaid-escaped), or {@link END}. */\n dest: string;\n /**\n * Whether the edge comes from a conditional branch or `node.ends` declaration.\n * Non-conditional edges alone determine implicit terminal `→ END` links.\n */\n conditional: boolean;\n};\n\n/**\n * Add implicit edges to END for terminal nodes (targets with no outgoing edges).\n *\n * Only nodes reached by a non-conditional edge are considered, so\n * conditional-branch targets are not treated as implicit sinks.\n */\nfunction addImplicitTerminalEndEdges<N extends string>(\n nodes: Record<N, NodeSpec<unknown, unknown>>,\n discovered: DiscoveredGraphEdge[],\n addEdge: (\n start: string,\n end: string,\n label?: string,\n conditional?: boolean\n ) => void\n): void {\n const sources = new Set(discovered.map((e) => e.src));\n const nonConditionalDestinations = [\n ...new Set(\n discovered\n .filter((e) => !e.conditional && e.dest !== END)\n .map((e) => e.dest)\n ),\n ].sort();\n\n for (const displayDest of nonConditionalDestinations) {\n if (sources.has(displayDest)) continue;\n const rawKey = (Object.keys(nodes) as N[]).find(\n (k) => _escapeMermaidKeywords(k) === displayDest\n );\n if (rawKey !== undefined && nodes[rawKey]?.isErrorHandler) continue;\n addEdge(displayDest, END);\n }\n}\n"],"mappings":"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"}
|
package/dist/graph/message.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const require_config = require("../pregel/utils/config.cjs");
|
|
2
2
|
const require_messages_reducer = require("./messages_reducer.cjs");
|
|
3
|
+
const require_stream = require("../pregel/stream.cjs");
|
|
3
4
|
const require_state = require("./state.cjs");
|
|
4
5
|
let _langchain_core_messages = require("@langchain/core/messages");
|
|
5
6
|
//#region src/graph/message.ts
|
|
@@ -36,12 +37,17 @@ function pushMessage(message, options) {
|
|
|
36
37
|
if (typeof config.callbacks !== "undefined") return config.callbacks.handlers;
|
|
37
38
|
return [];
|
|
38
39
|
})();
|
|
39
|
-
const
|
|
40
|
+
const messagesHandlers = callbacks.filter((cb) => "name" in cb && cb.name === "StreamMessagesHandler");
|
|
40
41
|
const protocolMessagesHandler = callbacks.find((cb) => "name" in cb && cb.name === "StreamProtocolMessagesHandler");
|
|
41
|
-
if (
|
|
42
|
+
if (messagesHandlers.length > 0 || protocolMessagesHandler) {
|
|
42
43
|
const metadata = config.metadata ?? {};
|
|
43
|
-
const
|
|
44
|
-
|
|
44
|
+
const checkpointNs = metadata.langgraph_checkpoint_ns ?? "";
|
|
45
|
+
const namespace = checkpointNs.split("|");
|
|
46
|
+
if (messagesHandlers.length > 0) for (const handler of messagesHandlers) {
|
|
47
|
+
const options = handler.namespaceOptions;
|
|
48
|
+
const eventNs = require_stream.eventNamespace(checkpointNs, metadata, options);
|
|
49
|
+
if (!require_stream.isOutsideStream(eventNs, options)) handler._emit([eventNs, metadata], validMessage, void 0, false);
|
|
50
|
+
}
|
|
45
51
|
else if (protocolMessagesHandler) protocolMessagesHandler.emitFinalMessage([namespace, metadata], validMessage, void 0, false);
|
|
46
52
|
}
|
|
47
53
|
if (stateKey) config.configurable?.__pregel_send?.([[stateKey, validMessage]]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.cjs","names":["StateGraph","messagesStateReducer","ensureLangGraphConfig"],"sources":["../../src/graph/message.ts"],"sourcesContent":["import {\n BaseMessage,\n BaseMessageLike,\n coerceMessageLikeToMessage,\n} from \"@langchain/core/messages\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { StateGraph } from \"./state.js\";\nimport { ensureLangGraphConfig } from \"../pregel/utils/config.js\";\nimport type { StreamMessagesHandler } from \"../pregel/messages.js\";\nimport type { StreamProtocolMessagesHandler } from \"../pregel/messages-v2.js\";\nimport { messagesStateReducer, type Messages } from \"./messages_reducer.js\";\n\n/** @ignore */\nexport class MessageGraph extends StateGraph<\n BaseMessage[],\n BaseMessage[],\n Messages\n> {\n constructor() {\n super({\n channels: {\n __root__: {\n reducer: messagesStateReducer,\n default: () => [],\n },\n },\n });\n }\n}\n\n/**\n * Manually push a message to a message stream.\n *\n * This is useful when you need to push a manually created message before the node\n * has finished executing.\n *\n * When a message is pushed, it will be automatically persisted to the state after the node has finished executing.\n * To disable persisting, set `options.stateKey` to `null`.\n *\n * @param message The message to push. The message must have an ID set, otherwise an error will be thrown.\n * @param options RunnableConfig / Runtime coming from node context.\n */\nexport function pushMessage(\n message: BaseMessage | BaseMessageLike,\n options?: RunnableConfig & {\n /**\n * The key of the state to push the message to. Set to `null` to avoid persisting.\n * @default \"messages\"\n */\n stateKey?: string | null;\n }\n) {\n const { stateKey: userStateKey, ...userConfig } = options ?? {};\n const config = ensureLangGraphConfig(userConfig);\n\n let stateKey: string | undefined = userStateKey ?? \"messages\";\n if (userStateKey === null) stateKey = undefined;\n\n // coerce to message\n const validMessage = coerceMessageLikeToMessage(message);\n if (!validMessage.id) throw new Error(\"Message ID is required.\");\n\n const callbacks = (() => {\n if (Array.isArray(config.callbacks)) {\n return config.callbacks;\n }\n\n if (typeof config.callbacks !== \"undefined\") {\n return config.callbacks.handlers;\n }\n\n return [];\n })();\n\n const
|
|
1
|
+
{"version":3,"file":"message.cjs","names":["StateGraph","messagesStateReducer","ensureLangGraphConfig","eventNamespace","isOutsideStream"],"sources":["../../src/graph/message.ts"],"sourcesContent":["import {\n BaseMessage,\n BaseMessageLike,\n coerceMessageLikeToMessage,\n} from \"@langchain/core/messages\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { StateGraph } from \"./state.js\";\nimport { ensureLangGraphConfig } from \"../pregel/utils/config.js\";\nimport type { StreamMessagesHandler } from \"../pregel/messages.js\";\nimport type { StreamProtocolMessagesHandler } from \"../pregel/messages-v2.js\";\nimport { eventNamespace, isOutsideStream } from \"../pregel/stream.js\";\nimport { messagesStateReducer, type Messages } from \"./messages_reducer.js\";\n\n/** @ignore */\nexport class MessageGraph extends StateGraph<\n BaseMessage[],\n BaseMessage[],\n Messages\n> {\n constructor() {\n super({\n channels: {\n __root__: {\n reducer: messagesStateReducer,\n default: () => [],\n },\n },\n });\n }\n}\n\n/**\n * Manually push a message to a message stream.\n *\n * This is useful when you need to push a manually created message before the node\n * has finished executing.\n *\n * When a message is pushed, it will be automatically persisted to the state after the node has finished executing.\n * To disable persisting, set `options.stateKey` to `null`.\n *\n * @param message The message to push. The message must have an ID set, otherwise an error will be thrown.\n * @param options RunnableConfig / Runtime coming from node context.\n */\nexport function pushMessage(\n message: BaseMessage | BaseMessageLike,\n options?: RunnableConfig & {\n /**\n * The key of the state to push the message to. Set to `null` to avoid persisting.\n * @default \"messages\"\n */\n stateKey?: string | null;\n }\n) {\n const { stateKey: userStateKey, ...userConfig } = options ?? {};\n const config = ensureLangGraphConfig(userConfig);\n\n let stateKey: string | undefined = userStateKey ?? \"messages\";\n if (userStateKey === null) stateKey = undefined;\n\n // coerce to message\n const validMessage = coerceMessageLikeToMessage(message);\n if (!validMessage.id) throw new Error(\"Message ID is required.\");\n\n const callbacks = (() => {\n if (Array.isArray(config.callbacks)) {\n return config.callbacks;\n }\n\n if (typeof config.callbacks !== \"undefined\") {\n return config.callbacks.handlers;\n }\n\n return [];\n })();\n\n const messagesHandlers = callbacks.filter(\n (cb): cb is StreamMessagesHandler =>\n \"name\" in cb && cb.name === \"StreamMessagesHandler\"\n );\n const protocolMessagesHandler = callbacks.find(\n (cb): cb is StreamProtocolMessagesHandler =>\n \"name\" in cb && cb.name === \"StreamProtocolMessagesHandler\"\n );\n\n if (messagesHandlers.length > 0 || protocolMessagesHandler) {\n const metadata = config.metadata ?? {};\n const checkpointNs = (metadata.langgraph_checkpoint_ns ?? \"\") as string;\n const namespace = checkpointNs.split(\"|\");\n\n if (messagesHandlers.length > 0) {\n // A node that streams its own subgraph adds a handler after its\n // caller's, and the caller's may skip the message, so ask each one.\n for (const handler of messagesHandlers) {\n const options = handler.namespaceOptions;\n const eventNs = eventNamespace(checkpointNs, metadata, options);\n if (!isOutsideStream(eventNs, options)) {\n handler._emit([eventNs, metadata], validMessage, undefined, false);\n }\n }\n } else if (protocolMessagesHandler) {\n // streamEvents v3 registers StreamProtocolMessagesHandler instead of\n // StreamMessagesHandler; without this branch, pushed messages are\n // silently absent from the live `messages` channel and only surface in\n // state at node end. else-if: the handlers are mutually exclusive per\n // stream, and a single emission path avoids double emits if a caller\n // ever registers both.\n protocolMessagesHandler.emitFinalMessage(\n [namespace, metadata],\n validMessage,\n undefined,\n false\n );\n }\n }\n\n if (stateKey) {\n config.configurable?.__pregel_send?.([[stateKey, validMessage]]);\n }\n\n return validMessage;\n}\n"],"mappings":";;;;;;;AAcA,IAAa,eAAb,cAAkCA,cAAAA,WAIhC;CACA,cAAc;AACZ,QAAM,EACJ,UAAU,EACR,UAAU;GACR,SAASC,yBAAAA;GACT,eAAe,EAAE;GAClB,EACF,EACF,CAAC;;;;;;;;;;;;;;;AAgBN,SAAgB,YACd,SACA,SAOA;CACA,MAAM,EAAE,UAAU,cAAc,GAAG,eAAe,WAAW,EAAE;CAC/D,MAAM,SAASC,eAAAA,sBAAsB,WAAW;CAEhD,IAAI,WAA+B,gBAAgB;AACnD,KAAI,iBAAiB,KAAM,YAAW,KAAA;CAGtC,MAAM,gBAAA,GAAA,yBAAA,4BAA0C,QAAQ;AACxD,KAAI,CAAC,aAAa,GAAI,OAAM,IAAI,MAAM,0BAA0B;CAEhE,MAAM,mBAAmB;AACvB,MAAI,MAAM,QAAQ,OAAO,UAAU,CACjC,QAAO,OAAO;AAGhB,MAAI,OAAO,OAAO,cAAc,YAC9B,QAAO,OAAO,UAAU;AAG1B,SAAO,EAAE;KACP;CAEJ,MAAM,mBAAmB,UAAU,QAChC,OACC,UAAU,MAAM,GAAG,SAAS,wBAC/B;CACD,MAAM,0BAA0B,UAAU,MACvC,OACC,UAAU,MAAM,GAAG,SAAS,gCAC/B;AAED,KAAI,iBAAiB,SAAS,KAAK,yBAAyB;EAC1D,MAAM,WAAW,OAAO,YAAY,EAAE;EACtC,MAAM,eAAgB,SAAS,2BAA2B;EAC1D,MAAM,YAAY,aAAa,MAAM,IAAI;AAEzC,MAAI,iBAAiB,SAAS,EAG5B,MAAK,MAAM,WAAW,kBAAkB;GACtC,MAAM,UAAU,QAAQ;GACxB,MAAM,UAAUC,eAAAA,eAAe,cAAc,UAAU,QAAQ;AAC/D,OAAI,CAACC,eAAAA,gBAAgB,SAAS,QAAQ,CACpC,SAAQ,MAAM,CAAC,SAAS,SAAS,EAAE,cAAc,KAAA,GAAW,MAAM;;WAG7D,wBAOT,yBAAwB,iBACtB,CAAC,WAAW,SAAS,EACrB,cACA,KAAA,GACA,MACD;;AAIL,KAAI,SACF,QAAO,cAAc,gBAAgB,CAAC,CAAC,UAAU,aAAa,CAAC,CAAC;AAGlE,QAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.cts","names":[],"sources":["../../src/graph/message.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"message.d.cts","names":[],"sources":["../../src/graph/message.ts"],"mappings":";;;;;;;;cAca,YAAA,SAAqB,UAAA,CAChC,WAAA,IACA,WAAA,IACA,QAAA;EAEA,WAAA,CAAA;AAAA;;;;;;;;;;;;;iBAwBc,WAAA,CACd,OAAA,EAAS,WAAA,GAAc,eAAA,EACvB,OAAA,GAAU,cAAA;EA1BV;;AAwBF;;EAOI,QAAA;AAAA,IACD,WAAA,CAAA,yBAAA,CAAA,gBAAA,CANuB,yBAAA,CAMvB,cAAA,GAAA,yBAAA,CAAA,WAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","names":[],"sources":["../../src/graph/message.ts"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"message.d.ts","names":[],"sources":["../../src/graph/message.ts"],"mappings":";;;;;;;;cAca,YAAA,SAAqB,UAAA,CAChC,WAAA,IACA,WAAA,IACA,QAAA;EAEA,WAAA,CAAA;AAAA;;;;;;;;;;;;;iBAwBc,WAAA,CACd,OAAA,EAAS,WAAA,GAAc,eAAA,EACvB,OAAA,GAAU,cAAA;EA1BV;;AAwBF;;EAOI,QAAA;AAAA,IACD,WAAA,CAAA,yBAAA,CAAA,gBAAA,CANuB,yBAAA,CAMvB,cAAA,GAAA,yBAAA,CAAA,WAAA"}
|
package/dist/graph/message.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ensureLangGraphConfig } from "../pregel/utils/config.js";
|
|
2
2
|
import { messagesStateReducer } from "./messages_reducer.js";
|
|
3
|
+
import { eventNamespace, isOutsideStream } from "../pregel/stream.js";
|
|
3
4
|
import { StateGraph } from "./state.js";
|
|
4
5
|
import { coerceMessageLikeToMessage } from "@langchain/core/messages";
|
|
5
6
|
//#region src/graph/message.ts
|
|
@@ -36,12 +37,17 @@ function pushMessage(message, options) {
|
|
|
36
37
|
if (typeof config.callbacks !== "undefined") return config.callbacks.handlers;
|
|
37
38
|
return [];
|
|
38
39
|
})();
|
|
39
|
-
const
|
|
40
|
+
const messagesHandlers = callbacks.filter((cb) => "name" in cb && cb.name === "StreamMessagesHandler");
|
|
40
41
|
const protocolMessagesHandler = callbacks.find((cb) => "name" in cb && cb.name === "StreamProtocolMessagesHandler");
|
|
41
|
-
if (
|
|
42
|
+
if (messagesHandlers.length > 0 || protocolMessagesHandler) {
|
|
42
43
|
const metadata = config.metadata ?? {};
|
|
43
|
-
const
|
|
44
|
-
|
|
44
|
+
const checkpointNs = metadata.langgraph_checkpoint_ns ?? "";
|
|
45
|
+
const namespace = checkpointNs.split("|");
|
|
46
|
+
if (messagesHandlers.length > 0) for (const handler of messagesHandlers) {
|
|
47
|
+
const options = handler.namespaceOptions;
|
|
48
|
+
const eventNs = eventNamespace(checkpointNs, metadata, options);
|
|
49
|
+
if (!isOutsideStream(eventNs, options)) handler._emit([eventNs, metadata], validMessage, void 0, false);
|
|
50
|
+
}
|
|
45
51
|
else if (protocolMessagesHandler) protocolMessagesHandler.emitFinalMessage([namespace, metadata], validMessage, void 0, false);
|
|
46
52
|
}
|
|
47
53
|
if (stateKey) config.configurable?.__pregel_send?.([[stateKey, validMessage]]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.js","names":[],"sources":["../../src/graph/message.ts"],"sourcesContent":["import {\n BaseMessage,\n BaseMessageLike,\n coerceMessageLikeToMessage,\n} from \"@langchain/core/messages\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { StateGraph } from \"./state.js\";\nimport { ensureLangGraphConfig } from \"../pregel/utils/config.js\";\nimport type { StreamMessagesHandler } from \"../pregel/messages.js\";\nimport type { StreamProtocolMessagesHandler } from \"../pregel/messages-v2.js\";\nimport { messagesStateReducer, type Messages } from \"./messages_reducer.js\";\n\n/** @ignore */\nexport class MessageGraph extends StateGraph<\n BaseMessage[],\n BaseMessage[],\n Messages\n> {\n constructor() {\n super({\n channels: {\n __root__: {\n reducer: messagesStateReducer,\n default: () => [],\n },\n },\n });\n }\n}\n\n/**\n * Manually push a message to a message stream.\n *\n * This is useful when you need to push a manually created message before the node\n * has finished executing.\n *\n * When a message is pushed, it will be automatically persisted to the state after the node has finished executing.\n * To disable persisting, set `options.stateKey` to `null`.\n *\n * @param message The message to push. The message must have an ID set, otherwise an error will be thrown.\n * @param options RunnableConfig / Runtime coming from node context.\n */\nexport function pushMessage(\n message: BaseMessage | BaseMessageLike,\n options?: RunnableConfig & {\n /**\n * The key of the state to push the message to. Set to `null` to avoid persisting.\n * @default \"messages\"\n */\n stateKey?: string | null;\n }\n) {\n const { stateKey: userStateKey, ...userConfig } = options ?? {};\n const config = ensureLangGraphConfig(userConfig);\n\n let stateKey: string | undefined = userStateKey ?? \"messages\";\n if (userStateKey === null) stateKey = undefined;\n\n // coerce to message\n const validMessage = coerceMessageLikeToMessage(message);\n if (!validMessage.id) throw new Error(\"Message ID is required.\");\n\n const callbacks = (() => {\n if (Array.isArray(config.callbacks)) {\n return config.callbacks;\n }\n\n if (typeof config.callbacks !== \"undefined\") {\n return config.callbacks.handlers;\n }\n\n return [];\n })();\n\n const
|
|
1
|
+
{"version":3,"file":"message.js","names":[],"sources":["../../src/graph/message.ts"],"sourcesContent":["import {\n BaseMessage,\n BaseMessageLike,\n coerceMessageLikeToMessage,\n} from \"@langchain/core/messages\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { StateGraph } from \"./state.js\";\nimport { ensureLangGraphConfig } from \"../pregel/utils/config.js\";\nimport type { StreamMessagesHandler } from \"../pregel/messages.js\";\nimport type { StreamProtocolMessagesHandler } from \"../pregel/messages-v2.js\";\nimport { eventNamespace, isOutsideStream } from \"../pregel/stream.js\";\nimport { messagesStateReducer, type Messages } from \"./messages_reducer.js\";\n\n/** @ignore */\nexport class MessageGraph extends StateGraph<\n BaseMessage[],\n BaseMessage[],\n Messages\n> {\n constructor() {\n super({\n channels: {\n __root__: {\n reducer: messagesStateReducer,\n default: () => [],\n },\n },\n });\n }\n}\n\n/**\n * Manually push a message to a message stream.\n *\n * This is useful when you need to push a manually created message before the node\n * has finished executing.\n *\n * When a message is pushed, it will be automatically persisted to the state after the node has finished executing.\n * To disable persisting, set `options.stateKey` to `null`.\n *\n * @param message The message to push. The message must have an ID set, otherwise an error will be thrown.\n * @param options RunnableConfig / Runtime coming from node context.\n */\nexport function pushMessage(\n message: BaseMessage | BaseMessageLike,\n options?: RunnableConfig & {\n /**\n * The key of the state to push the message to. Set to `null` to avoid persisting.\n * @default \"messages\"\n */\n stateKey?: string | null;\n }\n) {\n const { stateKey: userStateKey, ...userConfig } = options ?? {};\n const config = ensureLangGraphConfig(userConfig);\n\n let stateKey: string | undefined = userStateKey ?? \"messages\";\n if (userStateKey === null) stateKey = undefined;\n\n // coerce to message\n const validMessage = coerceMessageLikeToMessage(message);\n if (!validMessage.id) throw new Error(\"Message ID is required.\");\n\n const callbacks = (() => {\n if (Array.isArray(config.callbacks)) {\n return config.callbacks;\n }\n\n if (typeof config.callbacks !== \"undefined\") {\n return config.callbacks.handlers;\n }\n\n return [];\n })();\n\n const messagesHandlers = callbacks.filter(\n (cb): cb is StreamMessagesHandler =>\n \"name\" in cb && cb.name === \"StreamMessagesHandler\"\n );\n const protocolMessagesHandler = callbacks.find(\n (cb): cb is StreamProtocolMessagesHandler =>\n \"name\" in cb && cb.name === \"StreamProtocolMessagesHandler\"\n );\n\n if (messagesHandlers.length > 0 || protocolMessagesHandler) {\n const metadata = config.metadata ?? {};\n const checkpointNs = (metadata.langgraph_checkpoint_ns ?? \"\") as string;\n const namespace = checkpointNs.split(\"|\");\n\n if (messagesHandlers.length > 0) {\n // A node that streams its own subgraph adds a handler after its\n // caller's, and the caller's may skip the message, so ask each one.\n for (const handler of messagesHandlers) {\n const options = handler.namespaceOptions;\n const eventNs = eventNamespace(checkpointNs, metadata, options);\n if (!isOutsideStream(eventNs, options)) {\n handler._emit([eventNs, metadata], validMessage, undefined, false);\n }\n }\n } else if (protocolMessagesHandler) {\n // streamEvents v3 registers StreamProtocolMessagesHandler instead of\n // StreamMessagesHandler; without this branch, pushed messages are\n // silently absent from the live `messages` channel and only surface in\n // state at node end. else-if: the handlers are mutually exclusive per\n // stream, and a single emission path avoids double emits if a caller\n // ever registers both.\n protocolMessagesHandler.emitFinalMessage(\n [namespace, metadata],\n validMessage,\n undefined,\n false\n );\n }\n }\n\n if (stateKey) {\n config.configurable?.__pregel_send?.([[stateKey, validMessage]]);\n }\n\n return validMessage;\n}\n"],"mappings":";;;;;;;AAcA,IAAa,eAAb,cAAkC,WAIhC;CACA,cAAc;AACZ,QAAM,EACJ,UAAU,EACR,UAAU;GACR,SAAS;GACT,eAAe,EAAE;GAClB,EACF,EACF,CAAC;;;;;;;;;;;;;;;AAgBN,SAAgB,YACd,SACA,SAOA;CACA,MAAM,EAAE,UAAU,cAAc,GAAG,eAAe,WAAW,EAAE;CAC/D,MAAM,SAAS,sBAAsB,WAAW;CAEhD,IAAI,WAA+B,gBAAgB;AACnD,KAAI,iBAAiB,KAAM,YAAW,KAAA;CAGtC,MAAM,eAAe,2BAA2B,QAAQ;AACxD,KAAI,CAAC,aAAa,GAAI,OAAM,IAAI,MAAM,0BAA0B;CAEhE,MAAM,mBAAmB;AACvB,MAAI,MAAM,QAAQ,OAAO,UAAU,CACjC,QAAO,OAAO;AAGhB,MAAI,OAAO,OAAO,cAAc,YAC9B,QAAO,OAAO,UAAU;AAG1B,SAAO,EAAE;KACP;CAEJ,MAAM,mBAAmB,UAAU,QAChC,OACC,UAAU,MAAM,GAAG,SAAS,wBAC/B;CACD,MAAM,0BAA0B,UAAU,MACvC,OACC,UAAU,MAAM,GAAG,SAAS,gCAC/B;AAED,KAAI,iBAAiB,SAAS,KAAK,yBAAyB;EAC1D,MAAM,WAAW,OAAO,YAAY,EAAE;EACtC,MAAM,eAAgB,SAAS,2BAA2B;EAC1D,MAAM,YAAY,aAAa,MAAM,IAAI;AAEzC,MAAI,iBAAiB,SAAS,EAG5B,MAAK,MAAM,WAAW,kBAAkB;GACtC,MAAM,UAAU,QAAQ;GACxB,MAAM,UAAU,eAAe,cAAc,UAAU,QAAQ;AAC/D,OAAI,CAAC,gBAAgB,SAAS,QAAQ,CACpC,SAAQ,MAAM,CAAC,SAAS,SAAS,EAAE,cAAc,KAAA,GAAW,MAAM;;WAG7D,wBAOT,yBAAwB,iBACtB,CAAC,WAAW,SAAS,EACrB,cACA,KAAA,GACA,MACD;;AAIL,KAAI,SACF,QAAO,cAAc,gBAAgB,CAAC,CAAC,UAAU,aAAa,CAAC,CAAC;AAGlE,QAAO"}
|
|
@@ -215,7 +215,7 @@ var ToolNode = class extends require_utils.RunnableCallable {
|
|
|
215
215
|
});
|
|
216
216
|
} catch (e) {
|
|
217
217
|
if (!this.handleToolErrors) throw e;
|
|
218
|
-
if (require_errors.isGraphInterrupt(e)) throw e;
|
|
218
|
+
if (require_errors.isGraphInterrupt(e) || require_errors.isGraphDrained(e)) throw e;
|
|
219
219
|
return new _langchain_core_messages.ToolMessage({
|
|
220
220
|
status: "error",
|
|
221
221
|
content: `Error: ${e.message}\n Please fix your mistakes.`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool_node.cjs","names":["isBaseMessage","RunnableCallable","isCommand","ToolMessage","isGraphInterrupt","Command","_isSend","END"],"sources":["../../src/prebuilt/tool_node.ts"],"sourcesContent":["import {\n BaseMessage,\n ToolMessage,\n AIMessage,\n isBaseMessage,\n isAIMessage,\n} from \"@langchain/core/messages\";\nimport { RunnableToolLike } from \"@langchain/core/runnables\";\nimport {\n DynamicTool,\n StructuredToolInterface,\n type ToolRuntime,\n} from \"@langchain/core/tools\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport { RunnableCallable } from \"../utils.js\";\nimport { MessagesAnnotation } from \"../graph/messages_annotation.js\";\nimport { isGraphInterrupt } from \"../errors.js\";\nimport { END, isCommand, Command, _isSend, Send } from \"../constants.js\";\nimport type { LangGraphRunnableConfig } from \"../pregel/runnable_types.js\";\n\nexport type ToolNodeOptions = {\n name?: string;\n tags?: string[];\n handleToolErrors?: boolean;\n};\n\nconst isBaseMessageArray = (input: unknown): input is BaseMessage[] =>\n Array.isArray(input) && input.every(isBaseMessage);\n\nconst isMessagesState = (\n input: unknown\n): input is { messages: BaseMessage[] } =>\n typeof input === \"object\" &&\n input != null &&\n \"messages\" in input &&\n isBaseMessageArray(input.messages);\n\nconst isSendInput = (input: unknown): input is { lg_tool_call: ToolCall } =>\n typeof input === \"object\" && input != null && \"lg_tool_call\" in input;\n\n/**\n * A node that runs the tools requested in the last AIMessage. It can be used\n * either in StateGraph with a \"messages\" key or in MessageGraph. If multiple\n * tool calls are requested, they will be run in parallel. The output will be\n * a list of ToolMessages, one for each tool call.\n *\n * @example\n * ```ts\n * import { ToolNode } from \"@langchain/langgraph/prebuilt\";\n * import { tool } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n * import { AIMessage } from \"@langchain/core/messages\";\n *\n * const getWeather = tool((input) => {\n * if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n * return \"It's 60 degrees and foggy.\";\n * } else {\n * return \"It's 90 degrees and sunny.\";\n * }\n * }, {\n * name: \"get_weather\",\n * description: \"Call to get the current weather.\",\n * schema: z.object({\n * location: z.string().describe(\"Location to get the weather for.\"),\n * }),\n * });\n *\n * const tools = [getWeather];\n * const toolNode = new ToolNode(tools);\n *\n * const messageWithSingleToolCall = new AIMessage({\n * content: \"\",\n * tool_calls: [\n * {\n * name: \"get_weather\",\n * args: { location: \"sf\" },\n * id: \"tool_call_id\",\n * type: \"tool_call\",\n * }\n * ]\n * })\n *\n * await toolNode.invoke({ messages: [messageWithSingleToolCall] });\n * // Returns tool invocation responses as:\n * // { messages: ToolMessage[] }\n * ```\n *\n * @example\n * ```ts\n * import {\n * StateGraph,\n * MessagesAnnotation,\n * } from \"@langchain/langgraph\";\n * import { ToolNode } from \"@langchain/langgraph/prebuilt\";\n * import { tool } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n * import { ChatAnthropic } from \"@langchain/anthropic\";\n *\n * const getWeather = tool((input) => {\n * if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n * return \"It's 60 degrees and foggy.\";\n * } else {\n * return \"It's 90 degrees and sunny.\";\n * }\n * }, {\n * name: \"get_weather\",\n * description: \"Call to get the current weather.\",\n * schema: z.object({\n * location: z.string().describe(\"Location to get the weather for.\"),\n * }),\n * });\n *\n * const tools = [getWeather];\n * const modelWithTools = new ChatAnthropic({\n * model: \"claude-3-haiku-20240307\",\n * temperature: 0\n * }).bindTools(tools);\n *\n * const toolNodeForGraph = new ToolNode(tools)\n *\n * const shouldContinue = (state: typeof MessagesAnnotation.State) => {\n * const { messages } = state;\n * const lastMessage = messages[messages.length - 1];\n * if (\"tool_calls\" in lastMessage && Array.isArray(lastMessage.tool_calls) && lastMessage.tool_calls?.length) {\n * return \"tools\";\n * }\n * return \"__end__\";\n * }\n *\n * const callModel = async (state: typeof MessagesAnnotation.State) => {\n * const { messages } = state;\n * const response = await modelWithTools.invoke(messages);\n * return { messages: response };\n * }\n *\n * const graph = new StateGraph(MessagesAnnotation)\n * .addNode(\"agent\", callModel)\n * .addNode(\"tools\", toolNodeForGraph)\n * .addEdge(\"__start__\", \"agent\")\n * .addConditionalEdges(\"agent\", shouldContinue)\n * .addEdge(\"tools\", \"agent\")\n * .compile();\n *\n * const inputs = {\n * messages: [{ role: \"user\", content: \"what is the weather in SF?\" }],\n * };\n *\n * const stream = await graph.stream(inputs, {\n * streamMode: \"values\",\n * });\n *\n * for await (const { messages } of stream) {\n * console.log(messages);\n * }\n * // Returns the messages in the state at each step of execution\n * ```\n *\n * ### Accessing graph state and runtime context from tools\n *\n * Tools executed by a `ToolNode` only receive the arguments produced by the\n * model. To give a tool access to the surrounding graph state or other runtime\n * context, read them from the {@link ToolRuntime} that is passed as the\n * second argument to every tool:\n *\n * - `runtime.state` — the input the `ToolNode` was invoked with. When the\n * `ToolNode` runs as a graph node (e.g. inside `createReactAgent`), this is\n * the current graph state. This works in any runtime, including web browsers,\n * because it does not rely on `node:async_hooks`/`AsyncLocalStorage`.\n * - `runtime.config`, `runtime.context`, `runtime.store`, etc. — other\n * run-scoped values.\n *\n * @example\n * ```ts\n * import { ToolNode } from \"@langchain/langgraph/prebuilt\";\n * import { StateGraph, MessagesZodState } from \"@langchain/langgraph\";\n * import { tool, type ToolRuntime } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n *\n * // Define the graph state with a Zod schema. The extra `userId` key becomes\n * // part of the state that the ToolNode forwards to its tools via `runtime.state`.\n * const AgentState = z.object({\n * ...MessagesZodState.shape,\n * userId: z.string(),\n * });\n *\n * const getUserInfo = tool(\n * async (_input, runtime: ToolRuntime<typeof AgentState>) => {\n * // Read the current graph state directly from the second argument.\n * const userId = runtime.state.userId;\n * return userId === \"user_123\" ? \"User is John Smith\" : \"Unknown user\";\n * },\n * {\n * name: \"get_user_info\",\n * description: \"Look up user info.\",\n * schema: z.object({}),\n * }\n * );\n *\n * // Wire the ToolNode into a StateGraph that uses `AgentState`. Because the\n * // node runs with the graph state as its input, the tool can read `userId`.\n * const graph = new StateGraph(AgentState)\n * .addNode(\"tools\", new ToolNode([getUserInfo]))\n * .addEdge(\"__start__\", \"tools\")\n * .compile();\n *\n * await graph.invoke({ messages: [...], userId: \"user_123\" });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class ToolNode<T = any> extends RunnableCallable<T, T> {\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[];\n\n handleToolErrors = true;\n\n trace = false;\n\n constructor(\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[],\n options?: ToolNodeOptions\n ) {\n const { name, tags, handleToolErrors } = options ?? {};\n super({ name, tags, func: (input, config) => this.run(input, config) });\n this.tools = tools;\n this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n }\n\n protected async runTool(\n call: ToolCall,\n config: LangGraphRunnableConfig,\n state: unknown\n ): Promise<ToolMessage | Command> {\n const tool = this.tools.find((tool) => tool.name === call.name);\n try {\n if (tool === undefined) {\n throw new Error(`Tool \"${call.name}\" not found.`);\n }\n const toolCall = { ...call, type: \"tool_call\" } as ToolCall;\n const runtime: ToolRuntime = {\n ...config,\n state,\n toolCallId: call.id ?? \"\",\n config,\n context: config.context,\n store: (config.store as ToolRuntime[\"store\"] | undefined) ?? null,\n writer: config.writer ?? config.configurable?.writer ?? null,\n };\n const output = await tool.invoke(toolCall, runtime);\n\n if (\n (isBaseMessage(output) && output.getType() === \"tool\") ||\n isCommand(output)\n ) {\n return output as ToolMessage | Command;\n }\n\n return new ToolMessage({\n status: \"success\",\n name: tool.name,\n content: typeof output === \"string\" ? output : JSON.stringify(output),\n tool_call_id: call.id!,\n });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any) {\n if (!this.handleToolErrors) throw e;\n\n if (isGraphInterrupt(e)) {\n // `NodeInterrupt` errors are a breakpoint to bring a human into the loop.\n // As such, they are not recoverable by the agent and shouldn't be fed\n // back. Instead, re-throw these errors even when `handleToolErrors = true`.\n throw e;\n }\n\n return new ToolMessage({\n status: \"error\",\n content: `Error: ${e.message}\\n Please fix your mistakes.`,\n name: call.name,\n tool_call_id: call.id ?? \"\",\n });\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async run(\n input: unknown,\n config: LangGraphRunnableConfig\n ): Promise<T> {\n let outputs: (ToolMessage | Command)[];\n\n if (isSendInput(input)) {\n // Drop the internal `lg_tool_call` routing key so tools only see state.\n const { lg_tool_call: toolCall, ...state } = input as {\n lg_tool_call: ToolCall;\n } & Record<string, unknown>;\n outputs = [await this.runTool(toolCall, config, state)];\n } else {\n let messages: BaseMessage[];\n if (isBaseMessageArray(input)) {\n messages = input;\n } else if (isMessagesState(input)) {\n messages = input.messages;\n } else {\n throw new Error(\n \"ToolNode only accepts BaseMessage[] or { messages: BaseMessage[] } as input.\"\n );\n }\n\n const toolMessageIds: Set<string> = new Set(\n messages\n .filter((msg) => msg.getType() === \"tool\")\n .map((msg) => (msg as ToolMessage).tool_call_id)\n );\n\n let aiMessage: AIMessage | undefined;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (isAIMessage(message)) {\n aiMessage = message;\n break;\n }\n }\n\n if (aiMessage == null || !isAIMessage(aiMessage)) {\n throw new Error(\"ToolNode only accepts AIMessages as input.\");\n }\n\n outputs = await Promise.all(\n aiMessage.tool_calls\n ?.filter((call) => call.id == null || !toolMessageIds.has(call.id))\n .map((call) => this.runTool(call, config, input)) ?? []\n );\n }\n\n // Preserve existing behavior for non-command tool outputs for backwards compatibility\n if (!outputs.some(isCommand)) {\n return (Array.isArray(input) ? outputs : { messages: outputs }) as T;\n }\n\n // Handle mixed Command and non-Command outputs\n const combinedOutputs: (\n | { messages: BaseMessage[] }\n | BaseMessage[]\n | Command\n )[] = [];\n let parentCommand: Command | null = null;\n\n for (const output of outputs) {\n if (isCommand(output)) {\n if (\n output.graph === Command.PARENT &&\n Array.isArray(output.goto) &&\n output.goto.every((send) => _isSend(send))\n ) {\n if (parentCommand) {\n (parentCommand.goto as Send[]).push(...(output.goto as Send[]));\n } else {\n parentCommand = new Command({\n graph: Command.PARENT,\n goto: output.goto,\n });\n }\n } else {\n combinedOutputs.push(output);\n }\n } else {\n combinedOutputs.push(\n Array.isArray(input) ? [output] : { messages: [output] }\n );\n }\n }\n\n if (parentCommand) {\n combinedOutputs.push(parentCommand);\n }\n\n return combinedOutputs as T;\n }\n}\n\n/**\n * A conditional edge function that determines whether to route to a tools node or end the graph.\n *\n * This function is designed to be used as a conditional edge in a LangGraph state graph to implement\n * the common pattern of checking if an AI message contains tool calls that need to be executed.\n *\n * @param state - The current state of the graph, which can be either:\n * - An array of `BaseMessage` objects, where the last message is checked for tool calls\n * - A state object conforming to `MessagesAnnotation.State`, which contains a `messages` array\n *\n * @returns A string indicating the next node to route to:\n * - `\"tools\"` - If the last message contains tool calls that need to be executed\n * - `END` - If there are no tool calls, indicating the graph should terminate\n *\n * @example\n * ```typescript\n * import { StateGraph, MessagesAnnotation, END, START } from \"@langchain/langgraph\";\n * import { ToolNode, toolsCondition } from \"@langchain/langgraph/prebuilt\";\n *\n * const graph = new StateGraph(MessagesAnnotation)\n * .addNode(\"agent\", agentNode)\n * .addNode(\"tools\", new ToolNode([searchTool, calculatorTool]))\n * .addEdge(START, \"agent\")\n * .addConditionalEdges(\"agent\", toolsCondition, [\"tools\", END])\n * .addEdge(\"tools\", \"agent\")\n * .compile();\n * ```\n *\n * @remarks\n * The function checks the last message in the state for the presence of `tool_calls`.\n * If the message is an `AIMessage` with one or more tool calls, it returns `\"tools\"`,\n * indicating that the graph should route to a tools node (typically a `ToolNode`) to\n * execute those tool calls. Otherwise, it returns `END` to terminate the graph execution.\n *\n * This is a common pattern in agentic workflows where an AI model decides whether to\n * use tools or provide a final response.\n */\nexport function toolsCondition(\n state: BaseMessage[] | typeof MessagesAnnotation.State\n): \"tools\" | typeof END {\n const message = Array.isArray(state)\n ? state[state.length - 1]\n : state.messages[state.messages.length - 1];\n\n if (\n message !== undefined &&\n \"tool_calls\" in message &&\n ((message as AIMessage).tool_calls?.length ?? 0) > 0\n ) {\n return \"tools\";\n } else {\n return END;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tool_node.cjs","names":["isBaseMessage","RunnableCallable","isCommand","ToolMessage","isGraphInterrupt","isGraphDrained","Command","_isSend","END"],"sources":["../../src/prebuilt/tool_node.ts"],"sourcesContent":["import {\n BaseMessage,\n ToolMessage,\n AIMessage,\n isBaseMessage,\n isAIMessage,\n} from \"@langchain/core/messages\";\nimport { RunnableToolLike } from \"@langchain/core/runnables\";\nimport {\n DynamicTool,\n StructuredToolInterface,\n type ToolRuntime,\n} from \"@langchain/core/tools\";\nimport type { ToolCall } from \"@langchain/core/messages/tool\";\nimport { RunnableCallable } from \"../utils.js\";\nimport { MessagesAnnotation } from \"../graph/messages_annotation.js\";\nimport { isGraphDrained, isGraphInterrupt } from \"../errors.js\";\nimport { END, isCommand, Command, _isSend, Send } from \"../constants.js\";\nimport type { LangGraphRunnableConfig } from \"../pregel/runnable_types.js\";\n\nexport type ToolNodeOptions = {\n name?: string;\n tags?: string[];\n handleToolErrors?: boolean;\n};\n\nconst isBaseMessageArray = (input: unknown): input is BaseMessage[] =>\n Array.isArray(input) && input.every(isBaseMessage);\n\nconst isMessagesState = (\n input: unknown\n): input is { messages: BaseMessage[] } =>\n typeof input === \"object\" &&\n input != null &&\n \"messages\" in input &&\n isBaseMessageArray(input.messages);\n\nconst isSendInput = (input: unknown): input is { lg_tool_call: ToolCall } =>\n typeof input === \"object\" && input != null && \"lg_tool_call\" in input;\n\n/**\n * A node that runs the tools requested in the last AIMessage. It can be used\n * either in StateGraph with a \"messages\" key or in MessageGraph. If multiple\n * tool calls are requested, they will be run in parallel. The output will be\n * a list of ToolMessages, one for each tool call.\n *\n * @example\n * ```ts\n * import { ToolNode } from \"@langchain/langgraph/prebuilt\";\n * import { tool } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n * import { AIMessage } from \"@langchain/core/messages\";\n *\n * const getWeather = tool((input) => {\n * if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n * return \"It's 60 degrees and foggy.\";\n * } else {\n * return \"It's 90 degrees and sunny.\";\n * }\n * }, {\n * name: \"get_weather\",\n * description: \"Call to get the current weather.\",\n * schema: z.object({\n * location: z.string().describe(\"Location to get the weather for.\"),\n * }),\n * });\n *\n * const tools = [getWeather];\n * const toolNode = new ToolNode(tools);\n *\n * const messageWithSingleToolCall = new AIMessage({\n * content: \"\",\n * tool_calls: [\n * {\n * name: \"get_weather\",\n * args: { location: \"sf\" },\n * id: \"tool_call_id\",\n * type: \"tool_call\",\n * }\n * ]\n * })\n *\n * await toolNode.invoke({ messages: [messageWithSingleToolCall] });\n * // Returns tool invocation responses as:\n * // { messages: ToolMessage[] }\n * ```\n *\n * @example\n * ```ts\n * import {\n * StateGraph,\n * MessagesAnnotation,\n * } from \"@langchain/langgraph\";\n * import { ToolNode } from \"@langchain/langgraph/prebuilt\";\n * import { tool } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n * import { ChatAnthropic } from \"@langchain/anthropic\";\n *\n * const getWeather = tool((input) => {\n * if ([\"sf\", \"san francisco\"].includes(input.location.toLowerCase())) {\n * return \"It's 60 degrees and foggy.\";\n * } else {\n * return \"It's 90 degrees and sunny.\";\n * }\n * }, {\n * name: \"get_weather\",\n * description: \"Call to get the current weather.\",\n * schema: z.object({\n * location: z.string().describe(\"Location to get the weather for.\"),\n * }),\n * });\n *\n * const tools = [getWeather];\n * const modelWithTools = new ChatAnthropic({\n * model: \"claude-3-haiku-20240307\",\n * temperature: 0\n * }).bindTools(tools);\n *\n * const toolNodeForGraph = new ToolNode(tools)\n *\n * const shouldContinue = (state: typeof MessagesAnnotation.State) => {\n * const { messages } = state;\n * const lastMessage = messages[messages.length - 1];\n * if (\"tool_calls\" in lastMessage && Array.isArray(lastMessage.tool_calls) && lastMessage.tool_calls?.length) {\n * return \"tools\";\n * }\n * return \"__end__\";\n * }\n *\n * const callModel = async (state: typeof MessagesAnnotation.State) => {\n * const { messages } = state;\n * const response = await modelWithTools.invoke(messages);\n * return { messages: response };\n * }\n *\n * const graph = new StateGraph(MessagesAnnotation)\n * .addNode(\"agent\", callModel)\n * .addNode(\"tools\", toolNodeForGraph)\n * .addEdge(\"__start__\", \"agent\")\n * .addConditionalEdges(\"agent\", shouldContinue)\n * .addEdge(\"tools\", \"agent\")\n * .compile();\n *\n * const inputs = {\n * messages: [{ role: \"user\", content: \"what is the weather in SF?\" }],\n * };\n *\n * const stream = await graph.stream(inputs, {\n * streamMode: \"values\",\n * });\n *\n * for await (const { messages } of stream) {\n * console.log(messages);\n * }\n * // Returns the messages in the state at each step of execution\n * ```\n *\n * ### Accessing graph state and runtime context from tools\n *\n * Tools executed by a `ToolNode` only receive the arguments produced by the\n * model. To give a tool access to the surrounding graph state or other runtime\n * context, read them from the {@link ToolRuntime} that is passed as the\n * second argument to every tool:\n *\n * - `runtime.state` — the input the `ToolNode` was invoked with. When the\n * `ToolNode` runs as a graph node (e.g. inside `createReactAgent`), this is\n * the current graph state. This works in any runtime, including web browsers,\n * because it does not rely on `node:async_hooks`/`AsyncLocalStorage`.\n * - `runtime.config`, `runtime.context`, `runtime.store`, etc. — other\n * run-scoped values.\n *\n * @example\n * ```ts\n * import { ToolNode } from \"@langchain/langgraph/prebuilt\";\n * import { StateGraph, MessagesZodState } from \"@langchain/langgraph\";\n * import { tool, type ToolRuntime } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n *\n * // Define the graph state with a Zod schema. The extra `userId` key becomes\n * // part of the state that the ToolNode forwards to its tools via `runtime.state`.\n * const AgentState = z.object({\n * ...MessagesZodState.shape,\n * userId: z.string(),\n * });\n *\n * const getUserInfo = tool(\n * async (_input, runtime: ToolRuntime<typeof AgentState>) => {\n * // Read the current graph state directly from the second argument.\n * const userId = runtime.state.userId;\n * return userId === \"user_123\" ? \"User is John Smith\" : \"Unknown user\";\n * },\n * {\n * name: \"get_user_info\",\n * description: \"Look up user info.\",\n * schema: z.object({}),\n * }\n * );\n *\n * // Wire the ToolNode into a StateGraph that uses `AgentState`. Because the\n * // node runs with the graph state as its input, the tool can read `userId`.\n * const graph = new StateGraph(AgentState)\n * .addNode(\"tools\", new ToolNode([getUserInfo]))\n * .addEdge(\"__start__\", \"tools\")\n * .compile();\n *\n * await graph.invoke({ messages: [...], userId: \"user_123\" });\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class ToolNode<T = any> extends RunnableCallable<T, T> {\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[];\n\n handleToolErrors = true;\n\n trace = false;\n\n constructor(\n tools: (StructuredToolInterface | DynamicTool | RunnableToolLike)[],\n options?: ToolNodeOptions\n ) {\n const { name, tags, handleToolErrors } = options ?? {};\n super({ name, tags, func: (input, config) => this.run(input, config) });\n this.tools = tools;\n this.handleToolErrors = handleToolErrors ?? this.handleToolErrors;\n }\n\n protected async runTool(\n call: ToolCall,\n config: LangGraphRunnableConfig,\n state: unknown\n ): Promise<ToolMessage | Command> {\n const tool = this.tools.find((tool) => tool.name === call.name);\n try {\n if (tool === undefined) {\n throw new Error(`Tool \"${call.name}\" not found.`);\n }\n const toolCall = { ...call, type: \"tool_call\" } as ToolCall;\n const runtime: ToolRuntime = {\n ...config,\n state,\n toolCallId: call.id ?? \"\",\n config,\n context: config.context,\n store: (config.store as ToolRuntime[\"store\"] | undefined) ?? null,\n writer: config.writer ?? config.configurable?.writer ?? null,\n };\n const output = await tool.invoke(toolCall, runtime);\n\n if (\n (isBaseMessage(output) && output.getType() === \"tool\") ||\n isCommand(output)\n ) {\n return output as ToolMessage | Command;\n }\n\n return new ToolMessage({\n status: \"success\",\n name: tool.name,\n content: typeof output === \"string\" ? output : JSON.stringify(output),\n tool_call_id: call.id!,\n });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any) {\n if (!this.handleToolErrors) throw e;\n\n if (isGraphInterrupt(e) || isGraphDrained(e)) {\n // `NodeInterrupt` errors are a breakpoint to bring a human into the loop,\n // and a drain stops the run to resume it later. Neither is recoverable\n // by the agent, so neither is fed back: re-throw them even when\n // `handleToolErrors = true`.\n throw e;\n }\n\n return new ToolMessage({\n status: \"error\",\n content: `Error: ${e.message}\\n Please fix your mistakes.`,\n name: call.name,\n tool_call_id: call.id ?? \"\",\n });\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected async run(\n input: unknown,\n config: LangGraphRunnableConfig\n ): Promise<T> {\n let outputs: (ToolMessage | Command)[];\n\n if (isSendInput(input)) {\n // Drop the internal `lg_tool_call` routing key so tools only see state.\n const { lg_tool_call: toolCall, ...state } = input as {\n lg_tool_call: ToolCall;\n } & Record<string, unknown>;\n outputs = [await this.runTool(toolCall, config, state)];\n } else {\n let messages: BaseMessage[];\n if (isBaseMessageArray(input)) {\n messages = input;\n } else if (isMessagesState(input)) {\n messages = input.messages;\n } else {\n throw new Error(\n \"ToolNode only accepts BaseMessage[] or { messages: BaseMessage[] } as input.\"\n );\n }\n\n const toolMessageIds: Set<string> = new Set(\n messages\n .filter((msg) => msg.getType() === \"tool\")\n .map((msg) => (msg as ToolMessage).tool_call_id)\n );\n\n let aiMessage: AIMessage | undefined;\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n const message = messages[i];\n if (isAIMessage(message)) {\n aiMessage = message;\n break;\n }\n }\n\n if (aiMessage == null || !isAIMessage(aiMessage)) {\n throw new Error(\"ToolNode only accepts AIMessages as input.\");\n }\n\n outputs = await Promise.all(\n aiMessage.tool_calls\n ?.filter((call) => call.id == null || !toolMessageIds.has(call.id))\n .map((call) => this.runTool(call, config, input)) ?? []\n );\n }\n\n // Preserve existing behavior for non-command tool outputs for backwards compatibility\n if (!outputs.some(isCommand)) {\n return (Array.isArray(input) ? outputs : { messages: outputs }) as T;\n }\n\n // Handle mixed Command and non-Command outputs\n const combinedOutputs: (\n | { messages: BaseMessage[] }\n | BaseMessage[]\n | Command\n )[] = [];\n let parentCommand: Command | null = null;\n\n for (const output of outputs) {\n if (isCommand(output)) {\n if (\n output.graph === Command.PARENT &&\n Array.isArray(output.goto) &&\n output.goto.every((send) => _isSend(send))\n ) {\n if (parentCommand) {\n (parentCommand.goto as Send[]).push(...(output.goto as Send[]));\n } else {\n parentCommand = new Command({\n graph: Command.PARENT,\n goto: output.goto,\n });\n }\n } else {\n combinedOutputs.push(output);\n }\n } else {\n combinedOutputs.push(\n Array.isArray(input) ? [output] : { messages: [output] }\n );\n }\n }\n\n if (parentCommand) {\n combinedOutputs.push(parentCommand);\n }\n\n return combinedOutputs as T;\n }\n}\n\n/**\n * A conditional edge function that determines whether to route to a tools node or end the graph.\n *\n * This function is designed to be used as a conditional edge in a LangGraph state graph to implement\n * the common pattern of checking if an AI message contains tool calls that need to be executed.\n *\n * @param state - The current state of the graph, which can be either:\n * - An array of `BaseMessage` objects, where the last message is checked for tool calls\n * - A state object conforming to `MessagesAnnotation.State`, which contains a `messages` array\n *\n * @returns A string indicating the next node to route to:\n * - `\"tools\"` - If the last message contains tool calls that need to be executed\n * - `END` - If there are no tool calls, indicating the graph should terminate\n *\n * @example\n * ```typescript\n * import { StateGraph, MessagesAnnotation, END, START } from \"@langchain/langgraph\";\n * import { ToolNode, toolsCondition } from \"@langchain/langgraph/prebuilt\";\n *\n * const graph = new StateGraph(MessagesAnnotation)\n * .addNode(\"agent\", agentNode)\n * .addNode(\"tools\", new ToolNode([searchTool, calculatorTool]))\n * .addEdge(START, \"agent\")\n * .addConditionalEdges(\"agent\", toolsCondition, [\"tools\", END])\n * .addEdge(\"tools\", \"agent\")\n * .compile();\n * ```\n *\n * @remarks\n * The function checks the last message in the state for the presence of `tool_calls`.\n * If the message is an `AIMessage` with one or more tool calls, it returns `\"tools\"`,\n * indicating that the graph should route to a tools node (typically a `ToolNode`) to\n * execute those tool calls. Otherwise, it returns `END` to terminate the graph execution.\n *\n * This is a common pattern in agentic workflows where an AI model decides whether to\n * use tools or provide a final response.\n */\nexport function toolsCondition(\n state: BaseMessage[] | typeof MessagesAnnotation.State\n): \"tools\" | typeof END {\n const message = Array.isArray(state)\n ? state[state.length - 1]\n : state.messages[state.messages.length - 1];\n\n if (\n message !== undefined &&\n \"tool_calls\" in message &&\n ((message as AIMessage).tool_calls?.length ?? 0) > 0\n ) {\n return \"tools\";\n } else {\n return END;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool_node.d.cts","names":[],"sources":["../../src/prebuilt/tool_node.ts"],"mappings":";;;;;;;;;;KAoBY,eAAA;EACV,IAAA;EACA,IAAA;EACA,gBAAA;AAAA;;;;;;;AA0LF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"tool_node.d.cts","names":[],"sources":["../../src/prebuilt/tool_node.ts"],"mappings":";;;;;;;;;;KAoBY,eAAA;EACV,IAAA;EACA,IAAA;EACA,gBAAA;AAAA;;;;;;;AA0LF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+MA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA/Ma,QAAA,kBAA0B,gBAAA,CAAiB,CAAA,EAAG,CAAA;EACzD,KAAA,GAAQ,uBAAA,GAA0B,WAAA,GAAc,gBAAA;EAEhD,gBAAA;EAEA,KAAA;EAEA,WAAA,CACE,KAAA,GAAQ,uBAAA,GAA0B,WAAA,GAAc,gBAAA,KAChD,OAAA,GAAU,eAAA;EAAA,UAQI,OAAA,CACd,IAAA,EAAM,QAAA,EACN,MAAA,EAAQ,uBAAA,EACR,KAAA,YACC,OAAA,CAAQ,WAAA,GAAc,OAAA;EAAA,UAqDT,GAAA,CACd,KAAA,WACA,MAAA,EAAQ,uBAAA,GACP,OAAA,CAAQ,CAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkIG,cAAA,CACd,KAAA,EAAO,WAAA,YAAuB,kBAAA,CAAmB,KAAA,oBAC/B,GAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool_node.d.ts","names":[],"sources":["../../src/prebuilt/tool_node.ts"],"mappings":";;;;;;;;;;KAoBY,eAAA;EACV,IAAA;EACA,IAAA;EACA,gBAAA;AAAA;;;;;;;AA0LF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"tool_node.d.ts","names":[],"sources":["../../src/prebuilt/tool_node.ts"],"mappings":";;;;;;;;;;KAoBY,eAAA;EACV,IAAA;EACA,IAAA;EACA,gBAAA;AAAA;;;;;;;AA0LF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+MA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA/Ma,QAAA,kBAA0B,gBAAA,CAAiB,CAAA,EAAG,CAAA;EACzD,KAAA,GAAQ,uBAAA,GAA0B,WAAA,GAAc,gBAAA;EAEhD,gBAAA;EAEA,KAAA;EAEA,WAAA,CACE,KAAA,GAAQ,uBAAA,GAA0B,WAAA,GAAc,gBAAA,KAChD,OAAA,GAAU,eAAA;EAAA,UAQI,OAAA,CACd,IAAA,EAAM,QAAA,EACN,MAAA,EAAQ,uBAAA,EACR,KAAA,YACC,OAAA,CAAQ,WAAA,GAAc,OAAA;EAAA,UAqDT,GAAA,CACd,KAAA,WACA,MAAA,EAAQ,uBAAA,GACP,OAAA,CAAQ,CAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkIG,cAAA,CACd,KAAA,EAAO,WAAA,YAAuB,kBAAA,CAAmB,KAAA,oBAC/B,GAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command, END, _isSend, isCommand } from "../constants.js";
|
|
2
|
-
import { isGraphInterrupt } from "../errors.js";
|
|
2
|
+
import { isGraphDrained, isGraphInterrupt } from "../errors.js";
|
|
3
3
|
import { RunnableCallable } from "../utils.js";
|
|
4
4
|
import { ToolMessage, isAIMessage, isBaseMessage } from "@langchain/core/messages";
|
|
5
5
|
//#region src/prebuilt/tool_node.ts
|
|
@@ -215,7 +215,7 @@ var ToolNode = class extends RunnableCallable {
|
|
|
215
215
|
});
|
|
216
216
|
} catch (e) {
|
|
217
217
|
if (!this.handleToolErrors) throw e;
|
|
218
|
-
if (isGraphInterrupt(e)) throw e;
|
|
218
|
+
if (isGraphInterrupt(e) || isGraphDrained(e)) throw e;
|
|
219
219
|
return new ToolMessage({
|
|
220
220
|
status: "error",
|
|
221
221
|
content: `Error: ${e.message}\n Please fix your mistakes.`,
|