@langchain/langgraph 1.4.2 → 1.4.4
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 +8 -9
- package/dist/channels/delta.cjs.map +1 -1
- package/dist/channels/delta.d.cts.map +1 -1
- package/dist/channels/delta.d.ts.map +1 -1
- package/dist/channels/delta.js +8 -9
- package/dist/channels/delta.js.map +1 -1
- package/dist/constants.cjs +10 -1
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +10 -1
- package/dist/constants.js.map +1 -1
- package/dist/graph/messages_reducer.cjs +12 -4
- package/dist/graph/messages_reducer.cjs.map +1 -1
- package/dist/graph/messages_reducer.d.cts +8 -3
- package/dist/graph/messages_reducer.d.cts.map +1 -1
- package/dist/graph/messages_reducer.d.ts +8 -3
- package/dist/graph/messages_reducer.d.ts.map +1 -1
- package/dist/graph/messages_reducer.js +12 -4
- package/dist/graph/messages_reducer.js.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/pregel/algo.cjs +20 -3
- package/dist/pregel/algo.cjs.map +1 -1
- package/dist/pregel/algo.js +20 -3
- package/dist/pregel/algo.js.map +1 -1
- package/dist/pregel/debug.cjs +25 -1
- package/dist/pregel/debug.cjs.map +1 -1
- package/dist/pregel/debug.js +25 -1
- package/dist/pregel/debug.js.map +1 -1
- package/dist/pregel/index.cjs +8 -1
- 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 +9 -2
- package/dist/pregel/index.js.map +1 -1
- package/dist/pregel/loop.cjs +19 -1
- package/dist/pregel/loop.cjs.map +1 -1
- package/dist/pregel/loop.js +20 -2
- package/dist/pregel/loop.js.map +1 -1
- package/dist/pregel/messages-v2.cjs +1 -0
- package/dist/pregel/messages-v2.cjs.map +1 -1
- package/dist/pregel/messages-v2.js +1 -0
- package/dist/pregel/messages-v2.js.map +1 -1
- package/dist/pregel/utils/config.cjs +106 -9
- package/dist/pregel/utils/config.cjs.map +1 -1
- package/dist/pregel/utils/config.d.cts.map +1 -1
- package/dist/pregel/utils/config.d.ts.map +1 -1
- package/dist/pregel/utils/config.js +107 -11
- package/dist/pregel/utils/config.js.map +1 -1
- package/dist/pregel/utils/index.cjs +0 -16
- package/dist/pregel/utils/index.cjs.map +1 -1
- package/dist/pregel/utils/index.js +1 -16
- package/dist/pregel/utils/index.js.map +1 -1
- package/dist/state/index.cjs +1 -0
- package/dist/state/index.d.ts +2 -1
- package/dist/state/index.js +1 -0
- package/dist/state/prebuilt/index.d.ts +1 -1
- package/dist/state/prebuilt/messages.cjs +25 -0
- package/dist/state/prebuilt/messages.cjs.map +1 -1
- package/dist/state/prebuilt/messages.d.cts +18 -1
- package/dist/state/prebuilt/messages.d.cts.map +1 -1
- package/dist/state/prebuilt/messages.d.ts +18 -1
- package/dist/state/prebuilt/messages.d.ts.map +1 -1
- package/dist/state/prebuilt/messages.js +31 -4
- package/dist/state/prebuilt/messages.js.map +1 -1
- package/dist/state/schema.cjs +14 -6
- package/dist/state/schema.cjs.map +1 -1
- package/dist/state/schema.d.cts +7 -4
- package/dist/state/schema.d.cts.map +1 -1
- package/dist/state/schema.d.ts +7 -4
- package/dist/state/schema.d.ts.map +1 -1
- package/dist/state/schema.js +14 -6
- package/dist/state/schema.js.map +1 -1
- package/dist/state/values/delta.cjs +77 -0
- package/dist/state/values/delta.cjs.map +1 -0
- package/dist/state/values/delta.d.cts +152 -0
- package/dist/state/values/delta.d.cts.map +1 -0
- package/dist/state/values/delta.d.ts +152 -0
- package/dist/state/values/delta.d.ts.map +1 -0
- package/dist/state/values/delta.js +77 -0
- package/dist/state/values/delta.js.map +1 -0
- package/dist/state/values/index.cjs +1 -0
- package/dist/state/values/index.d.ts +3 -0
- package/dist/state/values/index.js +1 -0
- package/dist/stream/transformers/lifecycle.cjs +93 -2
- package/dist/stream/transformers/lifecycle.cjs.map +1 -1
- package/dist/stream/transformers/lifecycle.js +93 -2
- package/dist/stream/transformers/lifecycle.js.map +1 -1
- package/dist/web.cjs +3 -0
- package/dist/web.d.cts +3 -2
- package/dist/web.d.ts +3 -2
- package/dist/web.js +3 -2
- package/package.json +4 -4
package/dist/pregel/loop.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.js","names":["uuidv4","#interruptStreamNamespace"],"sources":["../../src/pregel/loop.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport type { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { BaseMessage } from \"@langchain/core/messages\";\nimport { v4 as uuidv4 } from \"@langchain/core/utils/uuid\";\nimport {\n BaseCheckpointSaver,\n Checkpoint,\n CheckpointTuple,\n copyCheckpoint,\n emptyCheckpoint,\n PendingWrite,\n CheckpointPendingWrite,\n CheckpointMetadata,\n All,\n BaseStore,\n AsyncBatchedStore,\n WRITES_IDX_MAP,\n BaseCache,\n CacheFullKey,\n CacheNamespace,\n} from \"@langchain/langgraph-checkpoint\";\n\nimport {\n BaseChannel,\n createCheckpoint,\n channelsFromCheckpoint,\n deltaChannelsToSnapshot,\n isDeltaChannel,\n} from \"../channels/base.js\";\nimport type {\n Call,\n CallTaskPath,\n Durability,\n PregelExecutableTask,\n PregelScratchpad,\n StreamMode,\n} from \"./types.js\";\nimport {\n isCommand,\n _isSend,\n CHECKPOINT_NAMESPACE_SEPARATOR,\n Command,\n CONFIG_KEY_CHECKPOINT_MAP,\n CONFIG_KEY_READ,\n CONFIG_KEY_RESUMING,\n CONFIG_KEY_STREAM,\n ERROR,\n ERROR_SOURCE_NODE,\n INPUT,\n INTERRUPT,\n NULL_TASK_ID,\n RESUME,\n TAG_HIDDEN,\n TASKS,\n PUSH,\n CONFIG_KEY_SCRATCHPAD,\n CONFIG_KEY_CHECKPOINT_NS,\n CHECKPOINT_NAMESPACE_END,\n CONFIG_KEY_CHECKPOINT_ID,\n CONFIG_KEY_RESUME_MAP,\n CONFIG_KEY_REPLAY_STATE,\n START,\n} from \"../constants.js\";\nimport { ReplayState } from \"./replay.js\";\nimport {\n _applyWrites,\n _prepareNextTasks,\n _prepareNodeErrorHandlerTask,\n _prepareSingleTask,\n increment,\n shouldInterrupt,\n sanitizeUntrackedValuesInSend,\n WritesProtocol,\n} from \"./algo.js\";\nimport {\n gatherIterator,\n gatherIteratorSync,\n prefixGenerator,\n} from \"../utils.js\";\nimport {\n mapCommand,\n mapInput,\n mapOutputUpdates,\n mapOutputValues,\n readChannels,\n} from \"./io.js\";\nimport {\n EmptyInputError,\n GraphInterrupt,\n isGraphInterrupt,\n} from \"../errors.js\";\nimport { getNewChannelVersions, patchConfigurable } from \"./utils/index.js\";\nimport {\n mapDebugTasks,\n mapDebugCheckpoint,\n mapDebugTaskResults,\n printStepTasks,\n} from \"./debug.js\";\nimport { PregelNode } from \"./read.js\";\nimport { LangGraphRunnableConfig } from \"./runnable_types.js\";\nimport type { RunControl } from \"./runtime.js\";\nimport {\n createDuplexStream,\n IterableReadableWritableStream,\n StreamChunkMeta,\n} from \"./stream.js\";\nimport { isXXH3 } from \"../hash.js\";\n\nconst INPUT_DONE = Symbol.for(\"INPUT_DONE\");\nconst INPUT_RESUMING = Symbol.for(\"INPUT_RESUMING\");\nconst DEFAULT_LOOP_LIMIT = 25;\n\n/**\n * Recursively assign a stable UUID to any {@link BaseMessage} (in a value, an\n * array, or an object's values) that is missing an `id`. Used so DeltaChannel\n * writes — replayed on every read — reconstruct identical message identities.\n */\nfunction ensureMessageIds(value: unknown): void {\n if (value == null || typeof value !== \"object\") return;\n if (BaseMessage.isInstance(value)) {\n const msg = value as BaseMessage;\n if (msg.id == null) {\n msg.id = uuidv4();\n if (msg.lc_kwargs != null) msg.lc_kwargs.id = msg.id;\n }\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) ensureMessageIds(item);\n return;\n }\n}\n\nexport type PregelLoopInitializeParams = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n input?: any | Command;\n config: RunnableConfig;\n checkpointer?: BaseCheckpointSaver;\n outputKeys: string | string[];\n streamKeys: string | string[];\n nodes: Record<string, PregelNode>;\n channelSpecs: Record<string, BaseChannel>;\n stream: IterableReadableWritableStream;\n store?: BaseStore;\n cache?: BaseCache<PendingWrite<string>[]>;\n interruptAfter: string[] | All;\n interruptBefore: string[] | All;\n durability: Durability;\n manager?: CallbackManagerForChainRun;\n debug: boolean;\n triggerToNodes: Record<string, string[]>;\n};\n\ntype PregelLoopParams = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n input?: any | Command;\n config: RunnableConfig;\n checkpointer?: BaseCheckpointSaver;\n checkpoint: Checkpoint;\n checkpointMetadata: CheckpointMetadata;\n checkpointPreviousVersions: Record<string, string | number>;\n checkpointPendingWrites: CheckpointPendingWrite[];\n checkpointConfig: RunnableConfig;\n channels: Record<string, BaseChannel>;\n step: number;\n stop: number;\n outputKeys: string | string[];\n streamKeys: string | string[];\n nodes: Record<string, PregelNode>;\n checkpointNamespace: string[];\n skipDoneTasks: boolean;\n isNested: boolean;\n resumeAtHead: boolean;\n manager?: CallbackManagerForChainRun;\n stream: IterableReadableWritableStream;\n store?: AsyncBatchedStore;\n cache?: BaseCache<PendingWrite<string>[]>;\n prevCheckpointConfig: RunnableConfig | undefined;\n interruptAfter: string[] | All;\n interruptBefore: string[] | All;\n durability: Durability;\n debug: boolean;\n triggerToNodes: Record<string, string[]>;\n hasPersistedParent?: boolean;\n};\n\n/**\n * Split a serialized checkpoint namespace into its path segments.\n *\n * Checkpoint namespaces are stored as a single string whose nested levels are\n * joined by {@link CHECKPOINT_NAMESPACE_SEPARATOR} (e.g. `\"parent|child\"`).\n * The root namespace — represented as `undefined` or the empty string — maps\n * to an empty array.\n *\n * @param ns - The serialized checkpoint namespace, or `undefined`.\n * @returns The namespace as an array of path segments (`[]` for the root).\n */\nfunction checkpointNamespaceFromNs(ns: string | undefined): string[] {\n if (ns === undefined || ns === \"\") return [];\n return ns.split(CHECKPOINT_NAMESPACE_SEPARATOR);\n}\n\n/**\n * Find the most deeply nested namespace recorded in a checkpoint map.\n *\n * The checkpoint map ({@link CONFIG_KEY_CHECKPOINT_MAP}) associates every\n * namespace seen on a thread with its checkpoint id. Because nested namespaces\n * are built by appending segments to their parent, a deeper namespace always\n * yields a longer key — so the longest non-empty key is the deepest one.\n *\n * Used by the loop's `#interruptStreamNamespace()` during subgraph\n * time-travel: interrupt events must be emitted against the active (deepest)\n * subgraph namespace rather than the root graph.\n *\n * @param map - The checkpoint map (namespace -> checkpoint id), or `undefined`.\n * @returns The deepest namespace as path segments, or `[]` when the map is\n * absent, empty, or only contains the root namespace.\n */\nfunction deepestCheckpointMapNamespace(\n map: Record<string, string> | undefined\n): string[] {\n if (!map) return [];\n let deepest = \"\";\n for (const key of Object.keys(map)) {\n if (key !== \"\" && key.length > deepest.length) {\n deepest = key;\n }\n }\n return checkpointNamespaceFromNs(deepest);\n}\n\nclass AsyncBatchedCache extends BaseCache<PendingWrite<string>[]> {\n protected cache: BaseCache<PendingWrite<string>[]>;\n\n private queue: Promise<unknown> = Promise.resolve();\n\n constructor(cache: BaseCache<unknown>) {\n super();\n this.cache = cache as BaseCache<PendingWrite<string>[]>;\n }\n\n async get(keys: CacheFullKey[]) {\n return this.enqueueOperation(\"get\", keys);\n }\n\n async set(\n pairs: {\n key: CacheFullKey;\n value: PendingWrite<string>[];\n ttl?: number;\n }[]\n ) {\n return this.enqueueOperation(\"set\", pairs);\n }\n\n async clear(namespaces: CacheNamespace[]) {\n return this.enqueueOperation(\"clear\", namespaces);\n }\n\n async stop() {\n await this.queue;\n }\n\n private enqueueOperation<Type extends \"get\" | \"set\" | \"clear\">(\n type: Type,\n ...args: Parameters<(typeof this.cache)[Type]>\n ) {\n const newPromise = this.queue.then(() => {\n // @ts-expect-error Tuple type warning\n return this.cache[type](...args) as Promise<\n ReturnType<(typeof this.cache)[Type]>\n >;\n });\n\n this.queue = newPromise.then(\n () => void 0,\n () => void 0\n );\n\n return newPromise;\n }\n}\n\nexport class PregelLoop {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected input?: any | Command;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n output: any;\n\n config: LangGraphRunnableConfig;\n\n protected checkpointer?: BaseCheckpointSaver;\n\n protected checkpointerGetNextVersion: (current: number | undefined) => number;\n\n channels: Record<string, BaseChannel>;\n\n protected checkpoint: Checkpoint;\n\n protected checkpointIdSaved: string | undefined;\n\n /**\n * Exit-mode accumulator of DeltaChannel writes across the whole run, as\n * `[step, taskId, channel, value]`. `undefined` outside \"exit\" durability.\n */\n protected _exitDeltaWrites: [number, string, string, unknown][] | undefined;\n\n /** Whether a real checkpoint was loaded from the saver at initialization. */\n protected _hasPersistedParent = false;\n\n /** The checkpointConfig as captured at initialization (anchor for exit writes). */\n protected _initialCheckpointConfig: RunnableConfig | undefined;\n\n protected checkpointConfig: RunnableConfig;\n\n checkpointMetadata: CheckpointMetadata;\n\n protected checkpointNamespace: string[];\n\n protected checkpointPendingWrites: CheckpointPendingWrite[] = [];\n\n protected checkpointPreviousVersions: Record<string, string | number>;\n\n step: number;\n\n protected stop: number;\n\n protected durability: Durability;\n\n protected outputKeys: string | string[];\n\n protected streamKeys: string | string[];\n\n protected nodes: Record<string, PregelNode>;\n\n protected skipDoneTasks: boolean;\n\n protected prevCheckpointConfig: RunnableConfig | undefined;\n\n protected updatedChannels: Set<string> | undefined;\n\n status:\n | \"pending\"\n | \"done\"\n | \"interrupt_before\"\n | \"interrupt_after\"\n | \"out_of_steps\"\n | \"draining\" = \"pending\";\n\n /**\n * Run-scoped control surface for cooperative draining. Populated from the\n * run config. When `control.drainRequested` is true, the loop stops at the\n * next superstep boundary instead of dispatching more tasks.\n */\n control?: RunControl;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tasks: Record<string, PregelExecutableTask<any, any>> = {};\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: IterableReadableWritableStream;\n\n checkpointerPromises: Set<Promise<unknown>> = new Set();\n\n isNested: boolean;\n\n /** True when an explicit checkpoint_id targets the latest saved checkpoint. */\n protected resumeAtHead: boolean;\n\n protected _checkpointerChainedPromise: Promise<unknown> = Promise.resolve();\n\n /**\n * Track a checkpointer promise, removing it from the set on success.\n * Failed promises are kept so that Promise.all() in the finally block\n * of _streamIterator can surface the error.\n *\n * @internal\n */\n protected _trackCheckpointerPromise(promise: Promise<unknown>) {\n const tracked = promise.then(\n (value) => {\n this.checkpointerPromises.delete(tracked);\n return value;\n },\n (error) => {\n // Keep failed promises in the set so errors surface via Promise.all()\n throw error;\n }\n );\n this.checkpointerPromises.add(tracked);\n }\n\n store?: AsyncBatchedStore;\n\n cache?: AsyncBatchedCache;\n\n manager?: CallbackManagerForChainRun;\n\n interruptAfter: string[] | All;\n\n interruptBefore: string[] | All;\n\n toInterrupt: PregelExecutableTask<string, string>[] = [];\n\n debug: boolean = false;\n\n triggerToNodes: Record<string, string[]>;\n\n get isResuming() {\n let hasChannelVersions = false;\n if (START in this.checkpoint.channel_versions) {\n // For common channels, we can short-circuit the check\n hasChannelVersions = true;\n } else {\n for (const chan in this.checkpoint.channel_versions) {\n if (\n Object.prototype.hasOwnProperty.call(\n this.checkpoint.channel_versions,\n chan\n )\n ) {\n hasChannelVersions = true;\n break;\n }\n }\n }\n\n const configHasResumingFlag =\n this.config.configurable?.[CONFIG_KEY_RESUMING] !== undefined;\n const configIsResuming =\n configHasResumingFlag && this.config.configurable?.[CONFIG_KEY_RESUMING];\n\n const inputIsNullOrUndefined =\n this.input === null || this.input === undefined;\n const inputIsCommandResuming =\n isCommand(this.input) && this.input.resume != null;\n const inputIsResuming = this.input === INPUT_RESUMING;\n\n const runIdMatchesPrevious =\n !this.isNested &&\n this.config.metadata?.run_id !== undefined &&\n (this.checkpointMetadata as { run_id?: unknown })?.run_id !== undefined &&\n this.config.metadata.run_id ===\n (this.checkpointMetadata as { run_id?: unknown })?.run_id;\n\n return (\n hasChannelVersions &&\n (configIsResuming ||\n inputIsNullOrUndefined ||\n inputIsCommandResuming ||\n inputIsResuming ||\n runIdMatchesPrevious)\n );\n }\n\n get isReplaying(): boolean {\n return !this.skipDoneTasks;\n }\n\n constructor(params: PregelLoopParams) {\n this.input = params.input;\n this.checkpointer = params.checkpointer;\n // TODO: if managed values no longer needs graph we can replace with\n // managed_specs, channel_specs\n if (this.checkpointer !== undefined) {\n this.checkpointerGetNextVersion = this.checkpointer.getNextVersion.bind(\n this.checkpointer\n );\n } else {\n this.checkpointerGetNextVersion = increment;\n }\n this.checkpoint = params.checkpoint;\n this.checkpointMetadata = params.checkpointMetadata;\n this.checkpointPreviousVersions = params.checkpointPreviousVersions;\n this.channels = params.channels;\n this.checkpointPendingWrites = params.checkpointPendingWrites;\n this.step = params.step;\n this.stop = params.stop;\n this.config = params.config;\n this.checkpointConfig = params.checkpointConfig;\n this.isNested = params.isNested;\n this.resumeAtHead = params.resumeAtHead;\n this.manager = params.manager;\n this.outputKeys = params.outputKeys;\n this.streamKeys = params.streamKeys;\n this.nodes = params.nodes;\n this.skipDoneTasks = params.skipDoneTasks;\n this.store = params.store;\n this.cache = params.cache ? new AsyncBatchedCache(params.cache) : undefined;\n this.stream = params.stream;\n this.checkpointNamespace = params.checkpointNamespace;\n this.prevCheckpointConfig = params.prevCheckpointConfig;\n this.interruptAfter = params.interruptAfter;\n this.interruptBefore = params.interruptBefore;\n this.durability = params.durability;\n this.debug = params.debug;\n this.triggerToNodes = params.triggerToNodes;\n this.control = this.config.control;\n // Exit-mode delta-channel accumulator: in \"exit\" durability, per-step\n // writes are not persisted incrementally, so DeltaChannel writes would be\n // lost. Accumulate them across the run and persist (anchored to a parent\n // or stub) at exit. `undefined` outside exit mode disables capture.\n this._exitDeltaWrites =\n this.durability === \"exit\" && this.checkpointer != null ? [] : undefined;\n this._hasPersistedParent = params.hasPersistedParent ?? false;\n this._initialCheckpointConfig = params.checkpointConfig;\n this.checkpointIdSaved = params.checkpoint.id;\n }\n\n static async initialize(params: PregelLoopInitializeParams) {\n let { config, stream } = params;\n if (\n stream !== undefined &&\n config.configurable?.[CONFIG_KEY_STREAM] !== undefined\n ) {\n stream = createDuplexStream(\n stream,\n config.configurable[CONFIG_KEY_STREAM]\n );\n }\n const skipDoneTasks = config.configurable\n ? !(\"checkpoint_id\" in config.configurable)\n : true;\n\n const scratchpad = config.configurable?.[CONFIG_KEY_SCRATCHPAD] as\n | PregelScratchpad\n | undefined;\n\n if (config.configurable && scratchpad) {\n if (scratchpad.subgraphCounter > 0) {\n config = patchConfigurable(config, {\n [CONFIG_KEY_CHECKPOINT_NS]: [\n config.configurable[CONFIG_KEY_CHECKPOINT_NS],\n scratchpad.subgraphCounter.toString(),\n ].join(CHECKPOINT_NAMESPACE_SEPARATOR),\n });\n }\n\n scratchpad.subgraphCounter += 1;\n }\n\n const requestedCheckpointId = config.configurable?.checkpoint_id as\n | string\n | undefined;\n\n const isNested = CONFIG_KEY_READ in (config.configurable ?? {});\n if (\n !isNested &&\n config.configurable?.checkpoint_ns !== undefined &&\n config.configurable?.checkpoint_ns !== \"\"\n ) {\n config = patchConfigurable(config, {\n checkpoint_ns: \"\",\n checkpoint_id: undefined,\n });\n }\n let checkpointConfig = config;\n if (\n config.configurable?.checkpoint_id === undefined &&\n config.configurable?.[CONFIG_KEY_CHECKPOINT_MAP] !== undefined &&\n config.configurable?.[CONFIG_KEY_CHECKPOINT_MAP]?.[\n config.configurable?.checkpoint_ns\n ]\n ) {\n checkpointConfig = patchConfigurable(config, {\n checkpoint_id:\n config.configurable[CONFIG_KEY_CHECKPOINT_MAP][\n config.configurable?.checkpoint_ns\n ],\n });\n }\n const checkpointNamespace = checkpointNamespaceFromNs(\n config.configurable?.checkpoint_ns\n );\n\n let saved: CheckpointTuple | undefined;\n if (!params.checkpointer) {\n saved = undefined;\n } else if (checkpointConfig.configurable?.[CONFIG_KEY_CHECKPOINT_ID]) {\n saved = await params.checkpointer.getTuple(checkpointConfig);\n } else if (config.configurable?.[CONFIG_KEY_REPLAY_STATE]) {\n const replayState = config.configurable[\n CONFIG_KEY_REPLAY_STATE\n ] as ReplayState;\n saved = await replayState.getCheckpoint(\n config.configurable?.[CONFIG_KEY_CHECKPOINT_NS] ?? \"\",\n params.checkpointer,\n checkpointConfig\n );\n if (config.configurable) {\n delete config.configurable[CONFIG_KEY_RESUMING];\n }\n } else {\n saved = await params.checkpointer.getTuple(checkpointConfig);\n }\n const hasPersistedParent = saved !== undefined;\n if (!saved) {\n saved = {\n config,\n checkpoint: emptyCheckpoint(),\n metadata: { source: \"input\", step: -2, parents: {} },\n pendingWrites: [],\n };\n }\n checkpointConfig = {\n ...config,\n ...saved.config,\n configurable: {\n checkpoint_ns: \"\",\n ...config.configurable,\n ...saved.config.configurable,\n },\n };\n const prevCheckpointConfig = saved.parentConfig;\n const checkpoint = copyCheckpoint(saved.checkpoint);\n const checkpointMetadata = { ...saved.metadata } as CheckpointMetadata;\n let checkpointPendingWrites = saved.pendingWrites ?? [];\n const currentCheckpointNamespace = config.configurable?.checkpoint_ns;\n const checkpointMap = config.configurable?.[CONFIG_KEY_CHECKPOINT_MAP];\n const isDirectSubgraphTimeTravel =\n typeof currentCheckpointNamespace === \"string\" &&\n currentCheckpointNamespace !== \"\" &&\n typeof checkpointMap === \"object\" &&\n checkpointMap !== null &&\n currentCheckpointNamespace in checkpointMap;\n\n if (isDirectSubgraphTimeTravel && checkpointPendingWrites.length > 0) {\n // Direct subgraph time-travel should re-fire interrupts instead of\n // consuming stale resume values that were written during the original run.\n checkpointPendingWrites = checkpointPendingWrites.filter(\n ([, channel]) => channel !== RESUME\n );\n }\n\n let resumeAtHead = false;\n const threadId = checkpointConfig.configurable?.thread_id;\n const checkpointNs = checkpointConfig.configurable?.checkpoint_ns ?? \"\";\n if (\n params.checkpointer &&\n requestedCheckpointId &&\n typeof threadId === \"string\"\n ) {\n const latest = await params.checkpointer.getTuple({\n configurable: { thread_id: threadId, checkpoint_ns: checkpointNs },\n });\n resumeAtHead =\n latest?.config.configurable?.checkpoint_id === requestedCheckpointId &&\n checkpointMetadata.source !== \"update\" &&\n checkpointMetadata.source !== \"fork\";\n }\n\n const channels = await channelsFromCheckpoint(\n params.channelSpecs,\n checkpoint,\n {\n saver: params.checkpointer,\n config: checkpointConfig,\n }\n );\n\n const step = (checkpointMetadata.step ?? 0) + 1;\n const stop = step + (config.recursionLimit ?? DEFAULT_LOOP_LIMIT) + 1;\n const checkpointPreviousVersions = { ...checkpoint.channel_versions };\n\n const store = params.store\n ? new AsyncBatchedStore(params.store)\n : undefined;\n\n if (store) {\n // Start the store. This is a batch store, so it will run continuously\n await store.start();\n }\n return new PregelLoop({\n input: params.input,\n config,\n checkpointer: params.checkpointer,\n checkpoint,\n checkpointMetadata,\n checkpointConfig,\n prevCheckpointConfig,\n checkpointNamespace,\n channels,\n isNested,\n resumeAtHead,\n manager: params.manager,\n skipDoneTasks,\n step,\n stop,\n checkpointPreviousVersions,\n checkpointPendingWrites,\n outputKeys: params.outputKeys ?? [],\n streamKeys: params.streamKeys ?? [],\n nodes: params.nodes,\n stream,\n store,\n cache: params.cache,\n interruptAfter: params.interruptAfter,\n interruptBefore: params.interruptBefore,\n durability: params.durability,\n debug: params.debug,\n triggerToNodes: params.triggerToNodes,\n hasPersistedParent,\n });\n }\n\n protected _checkpointerPutAfterPrevious(input: {\n config: RunnableConfig;\n checkpoint: Checkpoint;\n metadata: CheckpointMetadata;\n newVersions: Record<string, string | number>;\n }) {\n this._checkpointerChainedPromise = this._checkpointerChainedPromise.then(\n () => {\n return this.checkpointer?.put(\n input.config,\n input.checkpoint,\n input.metadata,\n input.newVersions\n );\n }\n );\n this._trackCheckpointerPromise(this._checkpointerChainedPromise);\n }\n\n /**\n * Put writes for a task, to be read by the next tick.\n * @param taskId\n * @param writes\n */\n putWrites(taskId: string, writes: PendingWrite<string>[]) {\n let writesCopy = writes;\n if (writesCopy.length === 0) return;\n\n // deduplicate writes to special channels, last write wins\n if (writesCopy.every(([key]) => key in WRITES_IDX_MAP)) {\n writesCopy = Array.from(\n new Map(writesCopy.map((w) => [w[0], w])).values()\n );\n }\n\n // Check if any channels are UntrackedValue (manual loop for perf)\n let hasUntrackedChannels = false;\n for (const key in this.channels) {\n if (Object.prototype.hasOwnProperty.call(this.channels, key)) {\n const channel = this.channels[key];\n if (channel.lc_graph_name === \"UntrackedValue\") {\n hasUntrackedChannels = true;\n break;\n }\n }\n }\n\n // Sanitize writes for checkpointing: remove UntrackedValue writes and sanitize Send packets\n let writesToSave = writesCopy;\n if (hasUntrackedChannels) {\n writesToSave = writesCopy\n .filter(([c]) => {\n // Don't persist UntrackedValue channel writes\n const channel = this.channels[c];\n return !channel || channel.lc_graph_name !== \"UntrackedValue\";\n })\n .map(([c, v]) => {\n // Sanitize UntrackedValues nested within Send packets\n if (c === TASKS && _isSend(v)) {\n return [c, sanitizeUntrackedValuesInSend(v, this.channels)] as [\n string,\n unknown,\n ];\n }\n return [c, v] as [string, unknown];\n });\n }\n\n // remove existing writes for this task\n this.checkpointPendingWrites = this.checkpointPendingWrites.filter(\n (w) => w[0] !== taskId\n );\n\n // save writes\n for (const [c, v] of writesToSave) {\n this.checkpointPendingWrites.push([taskId, c, v]);\n }\n\n // Assign stable IDs to any id-less BaseMessages in DeltaChannel writes\n // before they are serialised. DeltaChannel state is reconstructed by\n // replaying these stored writes, so without stable IDs every getState()\n // replay would mint a fresh UUID and dedup/RemoveMessage would break.\n for (const [c, v] of writesToSave) {\n const channel = this.channels[c];\n if (channel != null && isDeltaChannel(channel)) {\n ensureMessageIds(v);\n }\n }\n\n const config = patchConfigurable(this.checkpointConfig, {\n [CONFIG_KEY_CHECKPOINT_NS]: this.config.configurable?.checkpoint_ns ?? \"\",\n [CONFIG_KEY_CHECKPOINT_ID]: this.checkpoint.id,\n });\n\n if (this.durability !== \"exit\" && this.checkpointer != null) {\n this._trackCheckpointerPromise(\n // Use sanitized writes for checkpointer\n this.checkpointer.putWrites(config, writesToSave, taskId)\n );\n }\n\n if (this.tasks) {\n this._outputWrites(taskId, writesCopy);\n }\n\n if (!writes.length || !this.cache || !this.tasks) {\n return;\n }\n\n // only cache tasks with a cache key\n const task = this.tasks[taskId];\n if (task == null || task.cache_key == null) {\n return;\n }\n\n // only cache successful tasks\n if (writes[0][0] === ERROR || writes[0][0] === INTERRUPT) {\n return;\n }\n\n void this.cache.set([\n {\n key: [task.cache_key.ns, task.cache_key.key],\n value: task.writes,\n ttl: task.cache_key.ttl,\n },\n ]);\n }\n\n _outputWrites(taskId: string, writes: [string, unknown][], cached = false) {\n const task = this.tasks[taskId];\n if (task !== undefined) {\n if (\n task.config !== undefined &&\n (task.config.tags ?? []).includes(TAG_HIDDEN)\n ) {\n return;\n }\n\n if (writes.length > 0) {\n if (writes[0][0] === INTERRUPT) {\n // in `algo.ts` we append a bool to the task path to indicate\n // whether or not a call was present. If so, we don't emit the\n // the interrupt as it'll be emitted by the parent.\n if (\n task.path?.[0] === PUSH &&\n task.path?.[task.path.length - 1] === true\n )\n return;\n\n const interruptWrites = writes\n .filter((w) => w[0] === INTERRUPT)\n .flatMap((w) => w[1] as string[]);\n\n this._emit([\n [\"updates\", { [INTERRUPT]: interruptWrites }],\n [\"values\", { [INTERRUPT]: interruptWrites }],\n ]);\n } else if (writes[0][0] !== ERROR) {\n this._emit(\n gatherIteratorSync(\n prefixGenerator(\n mapOutputUpdates(this.outputKeys, [[task, writes]], cached),\n \"updates\"\n )\n )\n );\n }\n }\n if (!cached) {\n this._emit(\n gatherIteratorSync(\n prefixGenerator(\n mapDebugTaskResults([[task, writes]], this.streamKeys),\n \"tasks\"\n )\n )\n );\n }\n }\n }\n\n async _matchCachedWrites() {\n if (!this.cache) return [];\n\n const matched: {\n task: PregelExecutableTask<string, string>;\n result: unknown;\n }[] = [];\n\n const serializeKey = ([ns, key]: CacheFullKey) => {\n return `ns:${ns.join(\",\")}|key:${key}`;\n };\n\n const keys: CacheFullKey[] = [];\n const keyMap: Record<string, PregelExecutableTask<string, string>> = {};\n\n for (const task of Object.values(this.tasks)) {\n if (task.cache_key != null && !task.writes.length) {\n keys.push([task.cache_key.ns, task.cache_key.key]);\n keyMap[serializeKey([task.cache_key.ns, task.cache_key.key])] = task;\n }\n }\n\n if (keys.length === 0) return [];\n const cache = await this.cache.get(keys);\n\n for (const { key, value } of cache) {\n const task = keyMap[serializeKey(key)];\n if (task != null) {\n // update the task with the cached writes\n task.writes.push(...value);\n matched.push({ task, result: value });\n }\n }\n\n return matched;\n }\n\n /**\n * Execute a single iteration of the Pregel loop.\n * Returns true if more iterations are needed.\n * @param params - The input keys to use for the tick.\n * @returns True if more iterations are needed, false otherwise.\n */\n async tick(params: { inputKeys?: string | string[] }): Promise<boolean> {\n if (this.store && !this.store.isRunning) {\n await this.store?.start();\n }\n const { inputKeys = [] } = params;\n if (this.status !== \"pending\") {\n throw new Error(\n `Cannot tick when status is no longer \"pending\". Current status: \"${this.status}\"`\n );\n }\n if (![INPUT_DONE, INPUT_RESUMING].includes(this.input)) {\n await this._first(inputKeys);\n } else if (this.toInterrupt.length > 0) {\n this.status = \"interrupt_before\";\n throw new GraphInterrupt();\n } else if (\n Object.values(this.tasks).every((task) => task.writes.length > 0)\n ) {\n const finishTaskList = Object.values(this.tasks);\n // finish superstep\n const writes = finishTaskList.flatMap((t) => t.writes);\n // All tasks have finished\n this.updatedChannels = _applyWrites(\n this.checkpoint,\n this.channels,\n finishTaskList,\n this.checkpointerGetNextVersion,\n this.triggerToNodes\n );\n // produce values output\n const valuesOutput = await gatherIterator(\n prefixGenerator(\n mapOutputValues(this.outputKeys, writes, this.channels),\n \"values\"\n )\n );\n // capture delta-channel writes for the exit-mode accumulator before\n // clearing (in \"exit\" durability they are not persisted incrementally)\n if (this._exitDeltaWrites !== undefined) {\n for (const [tid, ch, v] of this.checkpointPendingWrites) {\n const channel = this.channels[ch];\n if (channel != null && isDeltaChannel(channel)) {\n this._exitDeltaWrites.push([this.step, tid, ch, v]);\n }\n }\n }\n // clear pending writes\n this.checkpointPendingWrites = [];\n // persist the new checkpoint BEFORE emitting values, so the\n // attached `checkpoint` envelope on the values event points at\n // the fork target that captures this superstep's final state.\n await this._putCheckpoint({ source: \"loop\" });\n this._emitValuesWithCheckpointMeta(valuesOutput);\n // after execution, check if we should interrupt\n if (\n shouldInterrupt(this.checkpoint, this.interruptAfter, finishTaskList)\n ) {\n this.status = \"interrupt_after\";\n throw new GraphInterrupt();\n }\n\n // unset resuming flag\n if (this.config.configurable?.[CONFIG_KEY_RESUMING] !== undefined) {\n delete this.config.configurable?.[CONFIG_KEY_RESUMING];\n }\n } else {\n return false;\n }\n if (this.step > this.stop) {\n this.status = \"out_of_steps\";\n return false;\n }\n\n const nextTasks = _prepareNextTasks(\n this.checkpoint,\n this.checkpointPendingWrites,\n this.nodes,\n this.channels,\n this.config,\n true,\n {\n step: this.step,\n checkpointer: this.checkpointer,\n isResuming: this.isResuming,\n manager: this.manager,\n store: this.store,\n stream: this.stream,\n triggerToNodes: this.triggerToNodes,\n updatedChannels: this.updatedChannels,\n }\n );\n this.tasks = nextTasks;\n let taskList = Object.values(this.tasks);\n\n // Full-state checkpoint snapshots are expensive; skip unless a consumer\n // subscribed to \"checkpoints\" or the legacy \"debug\" wrapper mode.\n if (\n this.checkpointer &&\n (this.stream.modes.has(\"checkpoints\") || this.stream.modes.has(\"debug\"))\n ) {\n this._emit(\n await gatherIterator(\n prefixGenerator(\n mapDebugCheckpoint(\n this.checkpointConfig,\n this.channels,\n this.streamKeys,\n this.checkpointMetadata,\n taskList,\n this.checkpointPendingWrites,\n this.prevCheckpointConfig,\n this.outputKeys\n ),\n \"checkpoints\"\n )\n )\n );\n }\n\n if (taskList.length === 0) {\n this.status = \"done\";\n return false;\n }\n // Cooperative drain: the previous superstep's writes have been applied\n // and checkpointed above, and the next tasks have been prepared. If a\n // drain was requested and tasks remain, stop here (without dispatching\n // them) so the run can be resumed later from the saved checkpoint.\n if (this.control != null && this.control.drainRequested) {\n this.status = \"draining\";\n return false;\n }\n // if there are pending writes from a previous loop, apply them\n if (this.skipDoneTasks && this.checkpointPendingWrites.length > 0) {\n for (const [tid, k, v] of this.checkpointPendingWrites) {\n if (\n k === ERROR ||\n k === ERROR_SOURCE_NODE ||\n k === INTERRUPT ||\n k === RESUME\n ) {\n continue;\n }\n const task = taskList.find((t) => t.id === tid);\n if (task) {\n task.writes.push([k, v]);\n }\n }\n // On resume, re-schedule error handlers for nodes that failed in a prior\n // run (recorded via ERROR_SOURCE_NODE) before they completed handling.\n this._resumeErrorHandlersIfApplicable();\n // Re-scheduling can add handler tasks to `this.tasks`, so refresh the\n // cached task list before emitting writes and the downstream re-tick /\n // interrupt / debug checks see the newly scheduled handlers.\n taskList = Object.values(this.tasks);\n for (const task of taskList) {\n if (task.writes.length > 0) {\n this._outputWrites(task.id, task.writes, true);\n }\n }\n }\n // if all tasks have finished, re-tick\n if (taskList.every((task) => task.writes.length > 0)) {\n return this.tick({ inputKeys });\n }\n\n // Before execution, check if we should interrupt\n if (shouldInterrupt(this.checkpoint, this.interruptBefore, taskList)) {\n this.status = \"interrupt_before\";\n throw new GraphInterrupt();\n }\n\n if (this.stream.modes.has(\"tasks\") || this.stream.modes.has(\"debug\")) {\n const debugOutput = await gatherIterator(\n prefixGenerator(mapDebugTasks(taskList), \"tasks\")\n );\n this._emit(debugOutput);\n }\n\n return true;\n }\n\n async finishAndHandleError(error?: Error) {\n // persist current checkpoint and writes\n if (\n this.durability === \"exit\" &&\n // if it's a top graph\n (!this.isNested ||\n // or a nested graph with error or interrupt\n typeof error !== \"undefined\" ||\n // or a nested graph with checkpointer: true\n this.checkpointNamespace.every(\n (part) => !part.includes(CHECKPOINT_NAMESPACE_END)\n ))\n ) {\n await this._putExitDeltaWrites();\n this._putCheckpoint(this.checkpointMetadata);\n this._flushPendingWrites();\n }\n\n const suppress = this._suppressInterrupt(error);\n if (suppress || error === undefined) {\n this.output = readChannels(this.channels, this.outputKeys);\n }\n if (suppress) {\n // emit one last \"values\" event, with pending writes applied\n if (\n this.tasks !== undefined &&\n this.checkpointPendingWrites.length > 0 &&\n Object.values(this.tasks).some((task) => task.writes.length > 0)\n ) {\n this.updatedChannels = _applyWrites(\n this.checkpoint,\n this.channels,\n Object.values(this.tasks),\n this.checkpointerGetNextVersion,\n this.triggerToNodes\n );\n\n this._emitValuesWithCheckpointMeta(\n gatherIteratorSync(\n prefixGenerator(\n mapOutputValues(\n this.outputKeys,\n Object.values(this.tasks).flatMap((t) => t.writes),\n this.channels\n ),\n \"values\"\n )\n )\n );\n }\n\n // Emit INTERRUPT event (not a state snapshot — no checkpoint envelope)\n if (isGraphInterrupt(error) && !error.interrupts.length) {\n this._emit(\n [\n [\"updates\", { [INTERRUPT]: [] }],\n [\"values\", { [INTERRUPT]: [] }],\n ],\n this.#interruptStreamNamespace()\n );\n }\n }\n return suppress;\n }\n\n async acceptPush(\n task: PregelExecutableTask<string, string>,\n writeIdx: number,\n call?: Call\n ): Promise<PregelExecutableTask<string, string> | void> {\n if (\n this.interruptAfter?.length > 0 &&\n shouldInterrupt(this.checkpoint, this.interruptAfter, [task])\n ) {\n this.toInterrupt.push(task);\n return;\n }\n\n const pushed = _prepareSingleTask(\n [PUSH, task.path ?? [], writeIdx, task.id, call] as CallTaskPath,\n this.checkpoint,\n this.checkpointPendingWrites,\n this.nodes,\n this.channels,\n task.config ?? {},\n true,\n {\n step: this.step,\n checkpointer: this.checkpointer,\n manager: this.manager,\n store: this.store,\n stream: this.stream,\n }\n );\n\n if (!pushed) return;\n if (\n this.interruptBefore?.length > 0 &&\n shouldInterrupt(this.checkpoint, this.interruptBefore, [pushed])\n ) {\n this.toInterrupt.push(pushed);\n return;\n }\n\n if (this.stream.modes.has(\"tasks\") || this.stream.modes.has(\"debug\")) {\n this._emit(\n gatherIteratorSync(prefixGenerator(mapDebugTasks([pushed]), \"tasks\"))\n );\n }\n\n if (this.debug) printStepTasks(this.step, [pushed]);\n this.tasks[pushed.id] = pushed;\n if (this.skipDoneTasks) this._matchWrites({ [pushed.id]: pushed });\n\n const tasks = await this._matchCachedWrites();\n for (const { task } of tasks) {\n this._outputWrites(task.id, task.writes, true);\n }\n\n return pushed;\n }\n\n /**\n * Returns the name of the error handler node registered for `nodeName`, or\n * `undefined` if none is configured.\n */\n getErrorHandlerNode(nodeName: string): string | undefined {\n return this.nodes[nodeName]?.errorHandlerNode;\n }\n\n /**\n * Whether `nodeName` is itself an auto-generated error handler node.\n */\n isErrorHandlerNode(nodeName: string): boolean {\n return this.nodes[nodeName]?.isErrorHandler === true;\n }\n\n /**\n * Schedule a node-level error handler task for a task that failed after its\n * retry policy was exhausted. Prepares the handler task (injecting a\n * {@link NodeError}), registers it so the runner executes it within the\n * current step, and returns it (or `undefined` if no handler applies).\n *\n * The failure provenance (`ERROR` + `ERROR_SOURCE_NODE`) is checkpointed by\n * the runner via {@link PregelLoop#putWrites} so handlers observe the same\n * context after a resume.\n */\n scheduleErrorHandler(\n failedTask: PregelExecutableTask<string, string>,\n error: Error\n ): PregelExecutableTask<string, string> | undefined {\n const handlerNode = this.getErrorHandlerNode(String(failedTask.name));\n if (!handlerNode) return undefined;\n\n const handlerTask = _prepareNodeErrorHandlerTask(\n failedTask,\n handlerNode,\n error,\n this.checkpoint,\n this.checkpointPendingWrites,\n this.nodes,\n this.channels,\n failedTask.config ?? this.config,\n {\n step: this.step,\n checkpointer: this.checkpointer,\n manager: this.manager,\n store: this.store,\n stream: this.stream,\n }\n ) as PregelExecutableTask<string, string> | undefined;\n\n if (handlerTask === undefined) return undefined;\n\n this.tasks[handlerTask.id] = handlerTask;\n\n this._emit(\n gatherIteratorSync(prefixGenerator(mapDebugTasks([handlerTask]), \"tasks\"))\n );\n if (this.debug) printStepTasks(this.step, [handlerTask]);\n\n return handlerTask;\n }\n\n /**\n * On resume, re-schedule error handlers for tasks that failed in a prior run\n * but had not finished being handled. Scans pending writes for\n * `ERROR_SOURCE_NODE` markers (paired with `ERROR`), marks the originating\n * task as done (so the runner won't re-run it), and prepares a fresh handler\n * task so the runner picks it up.\n */\n protected _resumeErrorHandlersIfApplicable() {\n // Collect failed task ids with both ERROR_SOURCE_NODE and ERROR writes.\n const failed = new Map<string, Error>();\n for (const [tid, chan] of this.checkpointPendingWrites) {\n if (chan !== ERROR_SOURCE_NODE) continue;\n const errorWrite = this.checkpointPendingWrites.find(\n ([t, c]) => t === tid && c === ERROR\n );\n if (errorWrite === undefined) continue;\n const value = errorWrite[2] as { message?: string; name?: string };\n const error = new Error(value?.message ?? String(value));\n if (value?.name) error.name = value.name;\n failed.set(tid, error);\n }\n\n for (const [tid, error] of failed) {\n const task = this.tasks[tid];\n if (task === undefined) continue;\n const handlerNode = this.getErrorHandlerNode(String(task.name));\n if (!handlerNode) continue;\n // Non-empty writes => runner's `writes.length === 0` filter skips it.\n if (task.writes.length === 0) {\n task.writes.push([ERROR, { message: error.message, name: error.name }]);\n }\n this.scheduleErrorHandler(task, error);\n }\n }\n\n protected _suppressInterrupt(e?: Error): boolean {\n return isGraphInterrupt(e) && !this.isNested;\n }\n\n protected async _first(inputKeys: string | string[]) {\n /*\n * Resuming from previous checkpoint requires\n * - finding a previous checkpoint\n * - receiving null input (outer graph) or RESUMING flag (subgraph)\n */\n\n const { configurable } = this.config;\n\n // take resume value from parent\n const scratchpad = configurable?.[\n CONFIG_KEY_SCRATCHPAD\n ] as PregelScratchpad;\n\n if (scratchpad && scratchpad.nullResume !== undefined) {\n this.putWrites(NULL_TASK_ID, [[RESUME, scratchpad.nullResume]]);\n }\n\n // map command to writes\n if (isCommand(this.input)) {\n const hasResume = this.input.resume != null;\n\n if (\n this.input.resume != null &&\n typeof this.input.resume === \"object\" &&\n Object.keys(this.input.resume).every(isXXH3)\n ) {\n this.config.configurable ??= {};\n this.config.configurable[CONFIG_KEY_RESUME_MAP] = this.input.resume;\n }\n\n if (hasResume && this.checkpointer == null) {\n throw new Error(\"Cannot use Command(resume=...) without checkpointer\");\n }\n\n const writes: { [key: string]: PendingWrite[] } = {};\n\n // group writes by task id\n for (const [tid, key, value] of mapCommand(\n this.input,\n this.checkpointPendingWrites\n )) {\n writes[tid] ??= [];\n writes[tid].push([key, value]);\n }\n if (Object.keys(writes).length === 0) {\n throw new EmptyInputError(\"Received empty Command input\");\n }\n\n // save writes\n for (const [tid, ws] of Object.entries(writes)) {\n this.putWrites(tid, ws);\n }\n }\n\n // apply null writes\n const nullWrites = (this.checkpointPendingWrites ?? [])\n .filter((w) => w[0] === NULL_TASK_ID)\n .map((w) => w.slice(1)) as PendingWrite<string>[];\n if (nullWrites.length > 0) {\n _applyWrites(\n this.checkpoint,\n this.channels,\n [\n {\n name: INPUT,\n writes: nullWrites,\n triggers: [],\n },\n ],\n this.checkpointerGetNextVersion,\n this.triggerToNodes\n );\n }\n const inputIsCommand = isCommand(this.input);\n const isCommandUpdateOrGoto = inputIsCommand && nullWrites.length > 0;\n\n const isTimeTraveling =\n this.isReplaying &&\n // Time-travel to a subgraph checkpoint: the parent sets RESUMING=True\n // (it can't distinguish time-travel from resume), so we check if this\n // subgraph's own ns is in checkpoint_map.\n ((this.isNested &&\n configurable?.[CONFIG_KEY_CHECKPOINT_NS] !== undefined &&\n configurable?.[CONFIG_KEY_CHECKPOINT_NS] !== \"\" &&\n configurable?.[CONFIG_KEY_CHECKPOINT_MAP] !== undefined &&\n configurable[CONFIG_KEY_CHECKPOINT_NS] in\n configurable[CONFIG_KEY_CHECKPOINT_MAP]) ||\n !(\n (inputIsCommand && (this.input as Command).resume != null) ||\n configurable?.[CONFIG_KEY_RESUMING] === true ||\n this.resumeAtHead\n ));\n\n if (isTimeTraveling) {\n this.checkpointPendingWrites = this.checkpointPendingWrites.filter(\n (w) => w[1] !== RESUME\n );\n }\n\n const cachedIsResuming = this.isResuming;\n if (cachedIsResuming || isCommandUpdateOrGoto) {\n // One spread (O(N)) instead of O(N²) per-channel spreads. Must be a\n // new object — copyCheckpoint shallow-copies versions_seen.\n const interruptSeen: Record<string, string | number> = {\n ...this.checkpoint.versions_seen[INTERRUPT],\n };\n for (const channelName in this.channels) {\n if (!Object.prototype.hasOwnProperty.call(this.channels, channelName))\n continue;\n if (this.checkpoint.channel_versions[channelName] !== undefined) {\n interruptSeen[channelName] =\n this.checkpoint.channel_versions[channelName];\n }\n }\n this.checkpoint.versions_seen[INTERRUPT] = interruptSeen;\n\n if (\n isTimeTraveling &&\n this.checkpointMetadata.source !== \"update\" &&\n this.checkpointMetadata.source !== \"fork\"\n ) {\n this.checkpointPendingWrites = this.checkpointPendingWrites.filter(\n (w) => w[1] !== INTERRUPT\n );\n await this._putCheckpoint({ source: \"fork\" });\n }\n\n // produce values output\n const valuesOutput = await gatherIterator(\n prefixGenerator(\n mapOutputValues(this.outputKeys, true, this.channels),\n \"values\"\n )\n );\n // Preserve the original `isResuming`-first priority: when both\n // `isResuming` and `isCommandUpdateOrGoto` are true (resuming from\n // an interrupt with a Command update/goto), the resume path wins\n // and no new input checkpoint is created here.\n if (cachedIsResuming) {\n this.input = INPUT_RESUMING;\n } else if (isCommandUpdateOrGoto) {\n // Persist the input checkpoint BEFORE emitting values so the\n // attached `checkpoint` envelope points at the just-created\n // fork target. We need a new checkpoint for Command(update=...)\n // or Command(goto=...) in case the result of Command(goto=...)\n // is an interrupt. If not done, the checkpoint containing the\n // interrupt will be lost.\n await this._putCheckpoint({ source: \"input\" });\n this.input = INPUT_DONE;\n }\n // Emit after any checkpoint persistence so the `checkpoint` envelope\n // on the values event points at the fork target for the emitted state.\n this._emitValuesWithCheckpointMeta(valuesOutput);\n } else {\n // map inputs to channel updates\n const inputWrites = await gatherIterator(mapInput(inputKeys, this.input));\n if (inputWrites.length > 0) {\n const discardTasks = _prepareNextTasks(\n this.checkpoint,\n this.checkpointPendingWrites,\n this.nodes,\n this.channels,\n this.config,\n true,\n { step: this.step }\n );\n this.updatedChannels = _applyWrites(\n this.checkpoint,\n this.channels,\n (Object.values(discardTasks) as WritesProtocol[]).concat([\n {\n name: INPUT,\n writes: inputWrites as PendingWrite[],\n triggers: [],\n },\n ]),\n this.checkpointerGetNextVersion,\n this.triggerToNodes\n );\n // Input writes go through `_applyWrites` directly (above) — they never\n // enter `checkpointPendingWrites`, so the after-tick capture site does\n // not see them.\n const deltaInput = (inputWrites as PendingWrite[]).filter(([c]) => {\n const channel = this.channels[c];\n return channel != null && isDeltaChannel(channel);\n });\n if (deltaInput.length > 0) {\n if (this._exitDeltaWrites !== undefined) {\n // Exit mode: capture so the accumulator includes input deltas.\n for (const [c, v] of deltaInput) {\n this._exitDeltaWrites.push([this.step, NULL_TASK_ID, c, v]);\n }\n } else if (this.checkpointer != null) {\n // Non-exit: persist so sub-frequency inputs are recoverable via the\n // ancestor walk (StateGraph routes inputs through a START node whose\n // writes are persisted; this covers raw Pregel delta input channels).\n this.putWrites(NULL_TASK_ID, deltaInput);\n }\n }\n // save input checkpoint\n await this._putCheckpoint({ source: \"input\" });\n\n this.input = INPUT_DONE;\n } else if (!(CONFIG_KEY_RESUMING in (this.config.configurable ?? {}))) {\n throw new EmptyInputError(\n `Received no input writes for ${JSON.stringify(inputKeys, null, 2)}`\n );\n } else {\n // done with input\n this.input = INPUT_DONE;\n }\n }\n if (!this.isNested) {\n let replayState: ReplayState | undefined;\n // Only pass ReplayState during time-travel, not when resuming from the\n // current head with an explicit checkpoint_id (see Python _loop._first).\n if (isTimeTraveling) {\n let replayCheckpointId = this.checkpoint.id;\n if (\n (this.checkpointMetadata.source === \"update\" ||\n this.checkpointMetadata.source === \"fork\") &&\n this.prevCheckpointConfig\n ) {\n replayCheckpointId =\n this.prevCheckpointConfig.configurable?.[\n CONFIG_KEY_CHECKPOINT_ID\n ] ?? replayCheckpointId;\n }\n replayState = new ReplayState(replayCheckpointId);\n }\n this.config = patchConfigurable(this.config, {\n [CONFIG_KEY_RESUMING]: this.isResuming,\n [CONFIG_KEY_REPLAY_STATE]: replayState,\n });\n }\n }\n\n #interruptStreamNamespace(): string[] {\n const ns = this.checkpointNamespace;\n const isRootNamespace =\n ns.length === 0 || (ns.length === 1 && ns[0] === \"\");\n if (\n !isRootNamespace ||\n this.config.configurable?.[CONFIG_KEY_STREAM] === undefined\n ) {\n return ns;\n }\n const deepest = deepestCheckpointMapNamespace(\n this.config.configurable?.[CONFIG_KEY_CHECKPOINT_MAP] as\n | Record<string, string>\n | undefined\n );\n return deepest.length > 0 ? deepest : ns;\n }\n\n protected _emit(\n values: Array<[StreamMode, unknown]>,\n namespace: string[] = this.checkpointNamespace\n ) {\n for (const [mode, payload] of values) {\n if (this.stream.modes.has(mode)) {\n this.stream.push([namespace, mode, payload]);\n }\n\n // debug mode is a \"checkpoints\" or \"tasks\" wrapped in an object\n // TODO: consider deprecating this in 1.x\n if (\n (mode === \"checkpoints\" || mode === \"tasks\") &&\n this.stream.modes.has(\"debug\")\n ) {\n const step = mode === \"checkpoints\" ? this.step - 1 : this.step;\n const timestamp = new Date().toISOString();\n const type = (() => {\n if (mode === \"checkpoints\") {\n return \"checkpoint\";\n } else if (\n typeof payload === \"object\" &&\n payload != null &&\n \"result\" in payload\n ) {\n return \"task_result\";\n } else {\n return \"task\";\n }\n })();\n\n this.stream.push([\n namespace,\n \"debug\",\n { step, type, timestamp, payload },\n ]);\n }\n }\n }\n\n /**\n * Build a {@link StreamChunkMeta} describing the currently active checkpoint.\n * Emitted as a separate ``[namespace, \"checkpoints\", envelope]`` chunk before\n * the paired ``values`` chunk. Returns `undefined` if no checkpoint metadata\n * is available yet.\n */\n protected _currentCheckpointMeta(): StreamChunkMeta | undefined {\n if (!this.checkpointMetadata || !this.checkpoint?.id) return undefined;\n const parent_id = this.prevCheckpointConfig?.configurable?.checkpoint_id as\n | string\n | undefined;\n return {\n checkpoint: {\n id: this.checkpoint.id,\n ...(parent_id ? { parent_id } : {}),\n step: this.checkpointMetadata.step,\n source: this.checkpointMetadata.source,\n },\n };\n }\n\n /**\n * Emit stream entries. When checkpoint meta is available, push a lightweight\n * ``[namespace, \"checkpoints\", envelope]`` chunk before each ``values`` chunk.\n */\n protected _emitValuesWithCheckpointMeta(\n entries: [StreamMode, unknown][]\n ): void {\n const meta = this._currentCheckpointMeta();\n for (const [mode, payload] of entries) {\n if (\n mode === \"values\" &&\n meta?.checkpoint != null &&\n !this.stream.modes.has(\"checkpoints\")\n ) {\n this.stream.push([\n this.checkpointNamespace,\n \"checkpoints\",\n meta.checkpoint,\n ]);\n }\n if (this.stream.modes.has(mode)) {\n this.stream.push([this.checkpointNamespace, mode, payload]);\n }\n }\n }\n\n protected _putCheckpoint(\n inputMetadata: Omit<CheckpointMetadata, \"step\" | \"parents\">\n ) {\n const exiting = this.checkpointMetadata === inputMetadata;\n\n const doCheckpoint =\n this.checkpointer != null && (this.durability !== \"exit\" || exiting);\n\n const storeCheckpoint = (checkpoint: Checkpoint) => {\n // store the previous checkpoint config for debug events\n this.prevCheckpointConfig = this.checkpointConfig?.configurable\n ?.checkpoint_id\n ? this.checkpointConfig\n : undefined;\n\n // child graphs keep at most one checkpoint per parent checkpoint\n // this is achieved by writing child checkpoints as progress is made\n // (so that error recovery / resuming from interrupt don't lose work)\n // but doing so always with an id equal to that of the parent checkpoint\n this.checkpointConfig = patchConfigurable(this.checkpointConfig, {\n [CONFIG_KEY_CHECKPOINT_NS]:\n this.config.configurable?.checkpoint_ns ?? \"\",\n });\n\n const channelVersions = { ...this.checkpoint.channel_versions };\n const newVersions = getNewChannelVersions(\n this.checkpointPreviousVersions,\n channelVersions\n );\n this.checkpointPreviousVersions = channelVersions;\n // save it, without blocking\n // if there's a previous checkpoint save in progress, wait for it\n // ensuring checkpointers receive checkpoints in order\n void this._checkpointerPutAfterPrevious({\n config: { ...this.checkpointConfig },\n checkpoint: copyCheckpoint(checkpoint),\n metadata: { ...this.checkpointMetadata },\n newVersions,\n });\n this.checkpointConfig = {\n ...this.checkpointConfig,\n configurable: {\n ...this.checkpointConfig.configurable,\n checkpoint_id: this.checkpoint.id,\n },\n };\n };\n\n // Per-delta-channel counter bookkeeping. Each delta channel tracks a\n // [updates, supersteps] pair: `updates` increments only when the channel\n // is written this step; `supersteps` increments every superstep. The exit\n // call must NOT bump again (the last intermediate call already counted the\n // final superstep) or it would double-count.\n let newCounters: Record<string, [number, number]>;\n if (!exiting) {\n const prevCounters =\n this.checkpointMetadata.counters_since_delta_snapshot ?? {};\n newCounters = {};\n const updated = this.updatedChannels ?? new Set<string>();\n for (const chName in this.channels) {\n if (!Object.prototype.hasOwnProperty.call(this.channels, chName))\n continue;\n if (!isDeltaChannel(this.channels[chName])) continue;\n const [u, s] = prevCounters[chName] ?? [0, 0];\n newCounters[chName] = [updated.has(chName) ? u + 1 : u, s + 1];\n }\n this.checkpointMetadata = {\n ...inputMetadata,\n step: this.step,\n parents: this.config.configurable?.[CONFIG_KEY_CHECKPOINT_MAP] ?? {},\n };\n } else {\n newCounters = {\n ...(this.checkpointMetadata.counters_since_delta_snapshot ?? {}),\n };\n }\n\n const channelsToSnapshot = doCheckpoint\n ? deltaChannelsToSnapshot(this.channels, newCounters)\n : new Set<string>();\n\n // create new checkpoint\n this.checkpoint = createCheckpoint(\n this.checkpoint,\n doCheckpoint ? this.channels : undefined,\n this.step,\n {\n id: exiting ? this.checkpoint.id : undefined,\n channelsToSnapshot,\n updatedChannels: this.updatedChannels,\n getNextVersion: doCheckpoint\n ? (current) =>\n this.checkpointerGetNextVersion(current as number | undefined)\n : undefined,\n }\n );\n\n // Reset counters for channels that just snapshotted, and persist the\n // non-zero remainder into metadata (or clear the field entirely).\n for (const k of channelsToSnapshot) newCounters[k] = [0, 0];\n const nonZero: Record<string, [number, number]> = {};\n for (const k in newCounters) {\n if (!Object.prototype.hasOwnProperty.call(newCounters, k)) continue;\n const [u, s] = newCounters[k];\n if (u !== 0 || s !== 0) nonZero[k] = [u, s];\n }\n if (Object.keys(nonZero).length > 0) {\n this.checkpointMetadata.counters_since_delta_snapshot = nonZero;\n } else {\n delete this.checkpointMetadata.counters_since_delta_snapshot;\n }\n\n // Bail if no checkpointer\n if (doCheckpoint) storeCheckpoint(this.checkpoint);\n\n if (!exiting) {\n // increment step\n this.step += 1;\n }\n }\n\n /**\n * Stage the exit-mode accumulator of DeltaChannel writes so the final\n * checkpoint can be reconstructed. In \"exit\" durability per-step writes are\n * not persisted, so delta writes are accumulated across the run and anchored\n * here — under the saved parent, or a freshly-created stub when this is a\n * first run with no persisted parent. Channels that will snapshot in the\n * final checkpoint are excluded (their full value lives in `channel_values`).\n *\n * Must run BEFORE the final `_putCheckpoint` so the stub branch can adjust\n * `checkpointConfig` to anchor the final checkpoint on the stub.\n */\n protected async _putExitDeltaWrites(): Promise<void> {\n if (\n this._exitDeltaWrites === undefined ||\n this._exitDeltaWrites.length === 0 ||\n this.checkpointer == null ||\n this._initialCheckpointConfig === undefined\n ) {\n return;\n }\n\n const counters =\n this.checkpointMetadata.counters_since_delta_snapshot ?? {};\n const channelsToSnapshot = deltaChannelsToSnapshot(this.channels, counters);\n\n const pending = this._exitDeltaWrites.filter(\n ([, , ch]) => !channelsToSnapshot.has(ch)\n );\n if (pending.length === 0) return;\n\n let anchorConfig: RunnableConfig;\n if (this._hasPersistedParent) {\n // _initialCheckpointConfig points at the saved parent checkpoint.\n anchorConfig = this._initialCheckpointConfig;\n } else {\n // No persisted parent: create a stub empty checkpoint (no parent) and\n // anchor on it, then point the final checkpoint at the stub.\n const stubCp = emptyCheckpoint();\n stubCp.id = this.checkpointIdSaved ?? stubCp.id;\n stubCp.ts = new Date().toISOString();\n const stubPutConfig = patchConfigurable(this._initialCheckpointConfig, {\n [CONFIG_KEY_CHECKPOINT_ID]: undefined,\n });\n anchorConfig = patchConfigurable(this._initialCheckpointConfig, {\n [CONFIG_KEY_CHECKPOINT_ID]: stubCp.id,\n });\n this._trackCheckpointerPromise(\n this.checkpointer.put(\n stubPutConfig,\n stubCp,\n { source: \"loop\", step: -2, parents: {} },\n {}\n )\n );\n this.checkpointConfig = anchorConfig;\n }\n\n const anchorWriteConfig = patchConfigurable(anchorConfig, {\n [CONFIG_KEY_CHECKPOINT_NS]: this.config.configurable?.checkpoint_ns ?? \"\",\n [CONFIG_KEY_CHECKPOINT_ID]:\n anchorConfig.configurable?.[CONFIG_KEY_CHECKPOINT_ID],\n });\n\n // Group by [step, taskId]; a step-prefixed synthetic task id preserves\n // chronological super-step order under the saver's (task_id, idx) sort.\n const grouped = new Map<string, PendingWrite<string>[]>();\n const order: { key: string; step: number; tid: string }[] = [];\n for (const [step, tid, ch, v] of pending) {\n const key = `${step}\\u0000${tid}`;\n let group = grouped.get(key);\n if (group === undefined) {\n group = [];\n grouped.set(key, group);\n order.push({ key, step, tid });\n }\n group.push([ch, v]);\n }\n for (const { key, step, tid } of order) {\n const synthTid = `${String(step).padStart(8, \"0\")}-${tid}`;\n this._trackCheckpointerPromise(\n this.checkpointer.putWrites(\n anchorWriteConfig,\n grouped.get(key)!,\n synthTid\n )\n );\n }\n }\n\n protected _flushPendingWrites() {\n if (this.checkpointer == null) return;\n if (this.checkpointPendingWrites.length === 0) return;\n\n // patch config\n const config = patchConfigurable(this.checkpointConfig, {\n [CONFIG_KEY_CHECKPOINT_NS]: this.config.configurable?.checkpoint_ns ?? \"\",\n [CONFIG_KEY_CHECKPOINT_ID]: this.checkpoint.id,\n });\n\n // group writes by task id\n const byTask: Record<string, PendingWrite<string>[]> = {};\n for (const [tid, key, value] of this.checkpointPendingWrites) {\n byTask[tid] ??= [];\n byTask[tid].push([key, value]);\n }\n\n // submit writes to checkpointer\n for (const [tid, ws] of Object.entries(byTask)) {\n this._trackCheckpointerPromise(\n this.checkpointer.putWrites(config, ws, tid)\n );\n }\n }\n\n protected _matchWrites(\n tasks: Record<string, PregelExecutableTask<string, string>>\n ) {\n for (const [tid, k, v] of this.checkpointPendingWrites) {\n if (k === ERROR || k === INTERRUPT || k === RESUME) {\n continue;\n }\n const task = Object.values(tasks).find((t) => t.id === tid);\n if (task) {\n task.writes.push([k, v]);\n }\n }\n for (const task of Object.values(tasks)) {\n if (task.writes.length > 0) {\n this._outputWrites(task.id, task.writes, true);\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"loop.js","names":["uuidv4","#interruptStreamNamespace"],"sources":["../../src/pregel/loop.ts"],"sourcesContent":["import type { RunnableConfig } from \"@langchain/core/runnables\";\nimport type { CallbackManagerForChainRun } from \"@langchain/core/callbacks/manager\";\nimport { BaseMessage } from \"@langchain/core/messages\";\nimport { v4 as uuidv4 } from \"@langchain/core/utils/uuid\";\nimport {\n BaseCheckpointSaver,\n Checkpoint,\n CheckpointTuple,\n copyCheckpoint,\n emptyCheckpoint,\n PendingWrite,\n CheckpointPendingWrite,\n CheckpointMetadata,\n All,\n BaseStore,\n AsyncBatchedStore,\n WRITES_IDX_MAP,\n BaseCache,\n CacheFullKey,\n CacheNamespace,\n} from \"@langchain/langgraph-checkpoint\";\n\nimport {\n BaseChannel,\n createCheckpoint,\n channelsFromCheckpoint,\n deltaChannelsToSnapshot,\n isDeltaChannel,\n} from \"../channels/base.js\";\nimport type {\n Call,\n CallTaskPath,\n Durability,\n PregelExecutableTask,\n PregelScratchpad,\n StreamMode,\n} from \"./types.js\";\nimport {\n isCommand,\n _isSend,\n _isOverwriteValue,\n CHECKPOINT_NAMESPACE_SEPARATOR,\n Command,\n CONFIG_KEY_CHECKPOINT_MAP,\n CONFIG_KEY_READ,\n CONFIG_KEY_RESUMING,\n CONFIG_KEY_STREAM,\n ERROR,\n ERROR_SOURCE_NODE,\n INPUT,\n INTERRUPT,\n NULL_TASK_ID,\n RESUME,\n TAG_HIDDEN,\n TASKS,\n PUSH,\n CONFIG_KEY_SCRATCHPAD,\n CONFIG_KEY_CHECKPOINT_NS,\n CHECKPOINT_NAMESPACE_END,\n CONFIG_KEY_CHECKPOINT_ID,\n CONFIG_KEY_RESUME_MAP,\n CONFIG_KEY_REPLAY_STATE,\n START,\n} from \"../constants.js\";\nimport { ReplayState } from \"./replay.js\";\nimport {\n _applyWrites,\n _prepareNextTasks,\n _prepareNodeErrorHandlerTask,\n _prepareSingleTask,\n increment,\n shouldInterrupt,\n sanitizeUntrackedValuesInSend,\n WritesProtocol,\n} from \"./algo.js\";\nimport {\n gatherIterator,\n gatherIteratorSync,\n prefixGenerator,\n} from \"../utils.js\";\nimport {\n mapCommand,\n mapInput,\n mapOutputUpdates,\n mapOutputValues,\n readChannels,\n} from \"./io.js\";\nimport {\n EmptyInputError,\n GraphInterrupt,\n isGraphInterrupt,\n} from \"../errors.js\";\nimport { getNewChannelVersions, patchConfigurable } from \"./utils/index.js\";\nimport {\n mapDebugTasks,\n mapDebugCheckpoint,\n mapDebugTaskResults,\n printStepTasks,\n} from \"./debug.js\";\nimport { PregelNode } from \"./read.js\";\nimport { LangGraphRunnableConfig } from \"./runnable_types.js\";\nimport type { RunControl } from \"./runtime.js\";\nimport {\n createDuplexStream,\n IterableReadableWritableStream,\n StreamChunkMeta,\n} from \"./stream.js\";\nimport { isXXH3 } from \"../hash.js\";\n\nconst INPUT_DONE = Symbol.for(\"INPUT_DONE\");\nconst INPUT_RESUMING = Symbol.for(\"INPUT_RESUMING\");\nconst DEFAULT_LOOP_LIMIT = 25;\n\n/**\n * Recursively assign a stable UUID to any {@link BaseMessage} (in a value, an\n * array, or an object's values) that is missing an `id`. Used so DeltaChannel\n * writes — replayed on every read — reconstruct identical message identities.\n */\nfunction ensureMessageIds(value: unknown): void {\n if (value == null || typeof value !== \"object\") return;\n if (BaseMessage.isInstance(value)) {\n const msg = value as BaseMessage;\n if (msg.id == null) {\n msg.id = uuidv4();\n if (msg.lc_kwargs != null) msg.lc_kwargs.id = msg.id;\n }\n return;\n }\n if (Array.isArray(value)) {\n for (const item of value) ensureMessageIds(item);\n return;\n }\n}\n\nexport type PregelLoopInitializeParams = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n input?: any | Command;\n config: RunnableConfig;\n checkpointer?: BaseCheckpointSaver;\n outputKeys: string | string[];\n streamKeys: string | string[];\n nodes: Record<string, PregelNode>;\n channelSpecs: Record<string, BaseChannel>;\n stream: IterableReadableWritableStream;\n store?: BaseStore;\n cache?: BaseCache<PendingWrite<string>[]>;\n interruptAfter: string[] | All;\n interruptBefore: string[] | All;\n durability: Durability;\n manager?: CallbackManagerForChainRun;\n debug: boolean;\n triggerToNodes: Record<string, string[]>;\n};\n\ntype PregelLoopParams = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n input?: any | Command;\n config: RunnableConfig;\n checkpointer?: BaseCheckpointSaver;\n checkpoint: Checkpoint;\n checkpointMetadata: CheckpointMetadata;\n checkpointPreviousVersions: Record<string, string | number>;\n checkpointPendingWrites: CheckpointPendingWrite[];\n checkpointConfig: RunnableConfig;\n channels: Record<string, BaseChannel>;\n step: number;\n stop: number;\n outputKeys: string | string[];\n streamKeys: string | string[];\n nodes: Record<string, PregelNode>;\n checkpointNamespace: string[];\n skipDoneTasks: boolean;\n isNested: boolean;\n resumeAtHead: boolean;\n manager?: CallbackManagerForChainRun;\n stream: IterableReadableWritableStream;\n store?: AsyncBatchedStore;\n cache?: BaseCache<PendingWrite<string>[]>;\n prevCheckpointConfig: RunnableConfig | undefined;\n interruptAfter: string[] | All;\n interruptBefore: string[] | All;\n durability: Durability;\n debug: boolean;\n triggerToNodes: Record<string, string[]>;\n hasPersistedParent?: boolean;\n};\n\n/**\n * Split a serialized checkpoint namespace into its path segments.\n *\n * Checkpoint namespaces are stored as a single string whose nested levels are\n * joined by {@link CHECKPOINT_NAMESPACE_SEPARATOR} (e.g. `\"parent|child\"`).\n * The root namespace — represented as `undefined` or the empty string — maps\n * to an empty array.\n *\n * @param ns - The serialized checkpoint namespace, or `undefined`.\n * @returns The namespace as an array of path segments (`[]` for the root).\n */\nfunction checkpointNamespaceFromNs(ns: string | undefined): string[] {\n if (ns === undefined || ns === \"\") return [];\n return ns.split(CHECKPOINT_NAMESPACE_SEPARATOR);\n}\n\n/**\n * Find the most deeply nested namespace recorded in a checkpoint map.\n *\n * The checkpoint map ({@link CONFIG_KEY_CHECKPOINT_MAP}) associates every\n * namespace seen on a thread with its checkpoint id. Because nested namespaces\n * are built by appending segments to their parent, a deeper namespace always\n * yields a longer key — so the longest non-empty key is the deepest one.\n *\n * Used by the loop's `#interruptStreamNamespace()` during subgraph\n * time-travel: interrupt events must be emitted against the active (deepest)\n * subgraph namespace rather than the root graph.\n *\n * @param map - The checkpoint map (namespace -> checkpoint id), or `undefined`.\n * @returns The deepest namespace as path segments, or `[]` when the map is\n * absent, empty, or only contains the root namespace.\n */\nfunction deepestCheckpointMapNamespace(\n map: Record<string, string> | undefined\n): string[] {\n if (!map) return [];\n let deepest = \"\";\n for (const key of Object.keys(map)) {\n if (key !== \"\" && key.length > deepest.length) {\n deepest = key;\n }\n }\n return checkpointNamespaceFromNs(deepest);\n}\n\nclass AsyncBatchedCache extends BaseCache<PendingWrite<string>[]> {\n protected cache: BaseCache<PendingWrite<string>[]>;\n\n private queue: Promise<unknown> = Promise.resolve();\n\n constructor(cache: BaseCache<unknown>) {\n super();\n this.cache = cache as BaseCache<PendingWrite<string>[]>;\n }\n\n async get(keys: CacheFullKey[]) {\n return this.enqueueOperation(\"get\", keys);\n }\n\n async set(\n pairs: {\n key: CacheFullKey;\n value: PendingWrite<string>[];\n ttl?: number;\n }[]\n ) {\n return this.enqueueOperation(\"set\", pairs);\n }\n\n async clear(namespaces: CacheNamespace[]) {\n return this.enqueueOperation(\"clear\", namespaces);\n }\n\n async stop() {\n await this.queue;\n }\n\n private enqueueOperation<Type extends \"get\" | \"set\" | \"clear\">(\n type: Type,\n ...args: Parameters<(typeof this.cache)[Type]>\n ) {\n const newPromise = this.queue.then(() => {\n // @ts-expect-error Tuple type warning\n return this.cache[type](...args) as Promise<\n ReturnType<(typeof this.cache)[Type]>\n >;\n });\n\n this.queue = newPromise.then(\n () => void 0,\n () => void 0\n );\n\n return newPromise;\n }\n}\n\nexport class PregelLoop {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n protected input?: any | Command;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n output: any;\n\n config: LangGraphRunnableConfig;\n\n protected checkpointer?: BaseCheckpointSaver;\n\n protected checkpointerGetNextVersion: (current: number | undefined) => number;\n\n channels: Record<string, BaseChannel>;\n\n protected checkpoint: Checkpoint;\n\n protected checkpointIdSaved: string | undefined;\n\n /**\n * Exit-mode accumulator of DeltaChannel writes across the whole run, as\n * `[step, taskId, channel, value]`. `undefined` outside \"exit\" durability.\n */\n protected _exitDeltaWrites: [number, string, string, unknown][] | undefined;\n\n /**\n * DeltaChannels that saw an Overwrite since the last checkpoint. These\n * channels are force-snapshotted at the next checkpoint so reconstruction\n * starts from the post-overwrite value and never has to replay across the\n * reset (the live `update` discards every sibling write in the overwriting\n * super-step). Cleared once the channel snapshots.\n */\n protected _deltaChannelsWithOverwrite: Set<string> = new Set();\n\n /** Whether a real checkpoint was loaded from the saver at initialization. */\n protected _hasPersistedParent = false;\n\n /** The checkpointConfig as captured at initialization (anchor for exit writes). */\n protected _initialCheckpointConfig: RunnableConfig | undefined;\n\n protected checkpointConfig: RunnableConfig;\n\n checkpointMetadata: CheckpointMetadata;\n\n protected checkpointNamespace: string[];\n\n protected checkpointPendingWrites: CheckpointPendingWrite[] = [];\n\n protected checkpointPreviousVersions: Record<string, string | number>;\n\n step: number;\n\n protected stop: number;\n\n protected durability: Durability;\n\n protected outputKeys: string | string[];\n\n protected streamKeys: string | string[];\n\n protected nodes: Record<string, PregelNode>;\n\n protected skipDoneTasks: boolean;\n\n protected prevCheckpointConfig: RunnableConfig | undefined;\n\n protected updatedChannels: Set<string> | undefined;\n\n status:\n | \"pending\"\n | \"done\"\n | \"interrupt_before\"\n | \"interrupt_after\"\n | \"out_of_steps\"\n | \"draining\" = \"pending\";\n\n /**\n * Run-scoped control surface for cooperative draining. Populated from the\n * run config. When `control.drainRequested` is true, the loop stops at the\n * next superstep boundary instead of dispatching more tasks.\n */\n control?: RunControl;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tasks: Record<string, PregelExecutableTask<any, any>> = {};\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: IterableReadableWritableStream;\n\n checkpointerPromises: Set<Promise<unknown>> = new Set();\n\n isNested: boolean;\n\n /** True when an explicit checkpoint_id targets the latest saved checkpoint. */\n protected resumeAtHead: boolean;\n\n protected _checkpointerChainedPromise: Promise<unknown> = Promise.resolve();\n\n /**\n * Track a checkpointer promise, removing it from the set on success.\n * Failed promises are kept so that Promise.all() in the finally block\n * of _streamIterator can surface the error.\n *\n * @internal\n */\n protected _trackCheckpointerPromise(promise: Promise<unknown>) {\n const tracked = promise.then(\n (value) => {\n this.checkpointerPromises.delete(tracked);\n return value;\n },\n (error) => {\n // Keep failed promises in the set so errors surface via Promise.all()\n throw error;\n }\n );\n this.checkpointerPromises.add(tracked);\n }\n\n store?: AsyncBatchedStore;\n\n cache?: AsyncBatchedCache;\n\n manager?: CallbackManagerForChainRun;\n\n interruptAfter: string[] | All;\n\n interruptBefore: string[] | All;\n\n toInterrupt: PregelExecutableTask<string, string>[] = [];\n\n debug: boolean = false;\n\n triggerToNodes: Record<string, string[]>;\n\n get isResuming() {\n let hasChannelVersions = false;\n if (START in this.checkpoint.channel_versions) {\n // For common channels, we can short-circuit the check\n hasChannelVersions = true;\n } else {\n for (const chan in this.checkpoint.channel_versions) {\n if (\n Object.prototype.hasOwnProperty.call(\n this.checkpoint.channel_versions,\n chan\n )\n ) {\n hasChannelVersions = true;\n break;\n }\n }\n }\n\n const configHasResumingFlag =\n this.config.configurable?.[CONFIG_KEY_RESUMING] !== undefined;\n const configIsResuming =\n configHasResumingFlag && this.config.configurable?.[CONFIG_KEY_RESUMING];\n\n const inputIsNullOrUndefined =\n this.input === null || this.input === undefined;\n const inputIsCommandResuming =\n isCommand(this.input) && this.input.resume != null;\n const inputIsResuming = this.input === INPUT_RESUMING;\n\n const runIdMatchesPrevious =\n !this.isNested &&\n this.config.metadata?.run_id !== undefined &&\n (this.checkpointMetadata as { run_id?: unknown })?.run_id !== undefined &&\n this.config.metadata.run_id ===\n (this.checkpointMetadata as { run_id?: unknown })?.run_id;\n\n return (\n hasChannelVersions &&\n (configIsResuming ||\n inputIsNullOrUndefined ||\n inputIsCommandResuming ||\n inputIsResuming ||\n runIdMatchesPrevious)\n );\n }\n\n get isReplaying(): boolean {\n return !this.skipDoneTasks;\n }\n\n constructor(params: PregelLoopParams) {\n this.input = params.input;\n this.checkpointer = params.checkpointer;\n // TODO: if managed values no longer needs graph we can replace with\n // managed_specs, channel_specs\n if (this.checkpointer !== undefined) {\n this.checkpointerGetNextVersion = this.checkpointer.getNextVersion.bind(\n this.checkpointer\n );\n } else {\n this.checkpointerGetNextVersion = increment;\n }\n this.checkpoint = params.checkpoint;\n this.checkpointMetadata = params.checkpointMetadata;\n this.checkpointPreviousVersions = params.checkpointPreviousVersions;\n this.channels = params.channels;\n this.checkpointPendingWrites = params.checkpointPendingWrites;\n this.step = params.step;\n this.stop = params.stop;\n this.config = params.config;\n this.checkpointConfig = params.checkpointConfig;\n this.isNested = params.isNested;\n this.resumeAtHead = params.resumeAtHead;\n this.manager = params.manager;\n this.outputKeys = params.outputKeys;\n this.streamKeys = params.streamKeys;\n this.nodes = params.nodes;\n this.skipDoneTasks = params.skipDoneTasks;\n this.store = params.store;\n this.cache = params.cache ? new AsyncBatchedCache(params.cache) : undefined;\n this.stream = params.stream;\n this.checkpointNamespace = params.checkpointNamespace;\n this.prevCheckpointConfig = params.prevCheckpointConfig;\n this.interruptAfter = params.interruptAfter;\n this.interruptBefore = params.interruptBefore;\n this.durability = params.durability;\n this.debug = params.debug;\n this.triggerToNodes = params.triggerToNodes;\n this.control = this.config.control;\n // Exit-mode delta-channel accumulator: in \"exit\" durability, per-step\n // writes are not persisted incrementally, so DeltaChannel writes would be\n // lost. Accumulate them across the run and persist (anchored to a parent\n // or stub) at exit. `undefined` outside exit mode disables capture.\n this._exitDeltaWrites =\n this.durability === \"exit\" && this.checkpointer != null ? [] : undefined;\n this._hasPersistedParent = params.hasPersistedParent ?? false;\n this._initialCheckpointConfig = params.checkpointConfig;\n this.checkpointIdSaved = params.checkpoint.id;\n }\n\n static async initialize(params: PregelLoopInitializeParams) {\n let { config, stream } = params;\n if (\n stream !== undefined &&\n config.configurable?.[CONFIG_KEY_STREAM] !== undefined\n ) {\n stream = createDuplexStream(\n stream,\n config.configurable[CONFIG_KEY_STREAM]\n );\n }\n const skipDoneTasks = config.configurable\n ? !(\"checkpoint_id\" in config.configurable)\n : true;\n\n const scratchpad = config.configurable?.[CONFIG_KEY_SCRATCHPAD] as\n | PregelScratchpad\n | undefined;\n\n if (config.configurable && scratchpad) {\n if (scratchpad.subgraphCounter > 0) {\n config = patchConfigurable(config, {\n [CONFIG_KEY_CHECKPOINT_NS]: [\n config.configurable[CONFIG_KEY_CHECKPOINT_NS],\n scratchpad.subgraphCounter.toString(),\n ].join(CHECKPOINT_NAMESPACE_SEPARATOR),\n });\n }\n\n scratchpad.subgraphCounter += 1;\n }\n\n const requestedCheckpointId = config.configurable?.checkpoint_id as\n | string\n | undefined;\n\n const isNested = CONFIG_KEY_READ in (config.configurable ?? {});\n if (\n !isNested &&\n config.configurable?.checkpoint_ns !== undefined &&\n config.configurable?.checkpoint_ns !== \"\"\n ) {\n config = patchConfigurable(config, {\n checkpoint_ns: \"\",\n checkpoint_id: undefined,\n });\n }\n let checkpointConfig = config;\n if (\n config.configurable?.checkpoint_id === undefined &&\n config.configurable?.[CONFIG_KEY_CHECKPOINT_MAP] !== undefined &&\n config.configurable?.[CONFIG_KEY_CHECKPOINT_MAP]?.[\n config.configurable?.checkpoint_ns\n ]\n ) {\n checkpointConfig = patchConfigurable(config, {\n checkpoint_id:\n config.configurable[CONFIG_KEY_CHECKPOINT_MAP][\n config.configurable?.checkpoint_ns\n ],\n });\n }\n const checkpointNamespace = checkpointNamespaceFromNs(\n config.configurable?.checkpoint_ns\n );\n\n let saved: CheckpointTuple | undefined;\n if (!params.checkpointer) {\n saved = undefined;\n } else if (checkpointConfig.configurable?.[CONFIG_KEY_CHECKPOINT_ID]) {\n saved = await params.checkpointer.getTuple(checkpointConfig);\n } else if (config.configurable?.[CONFIG_KEY_REPLAY_STATE]) {\n const replayState = config.configurable[\n CONFIG_KEY_REPLAY_STATE\n ] as ReplayState;\n saved = await replayState.getCheckpoint(\n config.configurable?.[CONFIG_KEY_CHECKPOINT_NS] ?? \"\",\n params.checkpointer,\n checkpointConfig\n );\n if (config.configurable) {\n delete config.configurable[CONFIG_KEY_RESUMING];\n }\n } else {\n saved = await params.checkpointer.getTuple(checkpointConfig);\n }\n const hasPersistedParent = saved !== undefined;\n if (!saved) {\n saved = {\n config,\n checkpoint: emptyCheckpoint(),\n metadata: { source: \"input\", step: -2, parents: {} },\n pendingWrites: [],\n };\n }\n checkpointConfig = {\n ...config,\n ...saved.config,\n configurable: {\n checkpoint_ns: \"\",\n ...config.configurable,\n ...saved.config.configurable,\n },\n };\n const prevCheckpointConfig = saved.parentConfig;\n const checkpoint = copyCheckpoint(saved.checkpoint);\n const checkpointMetadata = { ...saved.metadata } as CheckpointMetadata;\n let checkpointPendingWrites = saved.pendingWrites ?? [];\n const currentCheckpointNamespace = config.configurable?.checkpoint_ns;\n const checkpointMap = config.configurable?.[CONFIG_KEY_CHECKPOINT_MAP];\n const isDirectSubgraphTimeTravel =\n typeof currentCheckpointNamespace === \"string\" &&\n currentCheckpointNamespace !== \"\" &&\n typeof checkpointMap === \"object\" &&\n checkpointMap !== null &&\n currentCheckpointNamespace in checkpointMap;\n\n if (isDirectSubgraphTimeTravel && checkpointPendingWrites.length > 0) {\n // Direct subgraph time-travel should re-fire interrupts instead of\n // consuming stale resume values that were written during the original run.\n checkpointPendingWrites = checkpointPendingWrites.filter(\n ([, channel]) => channel !== RESUME\n );\n }\n\n let resumeAtHead = false;\n const threadId = checkpointConfig.configurable?.thread_id;\n const checkpointNs = checkpointConfig.configurable?.checkpoint_ns ?? \"\";\n if (\n params.checkpointer &&\n requestedCheckpointId &&\n typeof threadId === \"string\"\n ) {\n const latest = await params.checkpointer.getTuple({\n configurable: { thread_id: threadId, checkpoint_ns: checkpointNs },\n });\n resumeAtHead =\n latest?.config.configurable?.checkpoint_id === requestedCheckpointId &&\n checkpointMetadata.source !== \"update\" &&\n checkpointMetadata.source !== \"fork\";\n }\n\n const channels = await channelsFromCheckpoint(\n params.channelSpecs,\n checkpoint,\n {\n saver: params.checkpointer,\n config: checkpointConfig,\n }\n );\n\n const step = (checkpointMetadata.step ?? 0) + 1;\n const stop = step + (config.recursionLimit ?? DEFAULT_LOOP_LIMIT) + 1;\n const checkpointPreviousVersions = { ...checkpoint.channel_versions };\n\n const store = params.store\n ? new AsyncBatchedStore(params.store)\n : undefined;\n\n if (store) {\n // Start the store. This is a batch store, so it will run continuously\n await store.start();\n }\n return new PregelLoop({\n input: params.input,\n config,\n checkpointer: params.checkpointer,\n checkpoint,\n checkpointMetadata,\n checkpointConfig,\n prevCheckpointConfig,\n checkpointNamespace,\n channels,\n isNested,\n resumeAtHead,\n manager: params.manager,\n skipDoneTasks,\n step,\n stop,\n checkpointPreviousVersions,\n checkpointPendingWrites,\n outputKeys: params.outputKeys ?? [],\n streamKeys: params.streamKeys ?? [],\n nodes: params.nodes,\n stream,\n store,\n cache: params.cache,\n interruptAfter: params.interruptAfter,\n interruptBefore: params.interruptBefore,\n durability: params.durability,\n debug: params.debug,\n triggerToNodes: params.triggerToNodes,\n hasPersistedParent,\n });\n }\n\n protected _checkpointerPutAfterPrevious(input: {\n config: RunnableConfig;\n checkpoint: Checkpoint;\n metadata: CheckpointMetadata;\n newVersions: Record<string, string | number>;\n }) {\n this._checkpointerChainedPromise = this._checkpointerChainedPromise.then(\n () => {\n return this.checkpointer?.put(\n input.config,\n input.checkpoint,\n input.metadata,\n input.newVersions\n );\n }\n );\n this._trackCheckpointerPromise(this._checkpointerChainedPromise);\n }\n\n /**\n * Put writes for a task, to be read by the next tick.\n * @param taskId\n * @param writes\n */\n putWrites(taskId: string, writes: PendingWrite<string>[]) {\n let writesCopy = writes;\n if (writesCopy.length === 0) return;\n\n // deduplicate writes to special channels, last write wins\n if (writesCopy.every(([key]) => key in WRITES_IDX_MAP)) {\n writesCopy = Array.from(\n new Map(writesCopy.map((w) => [w[0], w])).values()\n );\n }\n\n // Check if any channels are UntrackedValue (manual loop for perf)\n let hasUntrackedChannels = false;\n for (const key in this.channels) {\n if (Object.prototype.hasOwnProperty.call(this.channels, key)) {\n const channel = this.channels[key];\n if (channel.lc_graph_name === \"UntrackedValue\") {\n hasUntrackedChannels = true;\n break;\n }\n }\n }\n\n // Sanitize writes for checkpointing: remove UntrackedValue writes and sanitize Send packets\n let writesToSave = writesCopy;\n if (hasUntrackedChannels) {\n writesToSave = writesCopy\n .filter(([c]) => {\n // Don't persist UntrackedValue channel writes\n const channel = this.channels[c];\n return !channel || channel.lc_graph_name !== \"UntrackedValue\";\n })\n .map(([c, v]) => {\n // Sanitize UntrackedValues nested within Send packets\n if (c === TASKS && _isSend(v)) {\n return [c, sanitizeUntrackedValuesInSend(v, this.channels)] as [\n string,\n unknown,\n ];\n }\n return [c, v] as [string, unknown];\n });\n }\n\n // remove existing writes for this task\n this.checkpointPendingWrites = this.checkpointPendingWrites.filter(\n (w) => w[0] !== taskId\n );\n\n // save writes\n for (const [c, v] of writesToSave) {\n this.checkpointPendingWrites.push([taskId, c, v]);\n }\n\n // Assign stable IDs to any id-less BaseMessages in DeltaChannel writes\n // before they are serialised. DeltaChannel state is reconstructed by\n // replaying these stored writes, so without stable IDs every getState()\n // replay would mint a fresh UUID and dedup/RemoveMessage would break.\n for (const [c, v] of writesToSave) {\n const channel = this.channels[c];\n if (channel != null && isDeltaChannel(channel)) {\n ensureMessageIds(v);\n }\n }\n\n const config = patchConfigurable(this.checkpointConfig, {\n [CONFIG_KEY_CHECKPOINT_NS]: this.config.configurable?.checkpoint_ns ?? \"\",\n [CONFIG_KEY_CHECKPOINT_ID]: this.checkpoint.id,\n });\n\n if (this.durability !== \"exit\" && this.checkpointer != null) {\n this._trackCheckpointerPromise(\n // Use sanitized writes for checkpointer\n this.checkpointer.putWrites(config, writesToSave, taskId)\n );\n }\n\n if (this.tasks) {\n this._outputWrites(taskId, writesCopy);\n }\n\n if (!writes.length || !this.cache || !this.tasks) {\n return;\n }\n\n // only cache tasks with a cache key\n const task = this.tasks[taskId];\n if (task == null || task.cache_key == null) {\n return;\n }\n\n // only cache successful tasks\n if (writes[0][0] === ERROR || writes[0][0] === INTERRUPT) {\n return;\n }\n\n void this.cache.set([\n {\n key: [task.cache_key.ns, task.cache_key.key],\n value: task.writes,\n ttl: task.cache_key.ttl,\n },\n ]);\n }\n\n _outputWrites(taskId: string, writes: [string, unknown][], cached = false) {\n const task = this.tasks[taskId];\n if (task !== undefined) {\n if (\n task.config !== undefined &&\n (task.config.tags ?? []).includes(TAG_HIDDEN)\n ) {\n return;\n }\n\n if (writes.length > 0) {\n if (writes[0][0] === INTERRUPT) {\n // in `algo.ts` we append a bool to the task path to indicate\n // whether or not a call was present. If so, we don't emit the\n // the interrupt as it'll be emitted by the parent.\n if (\n task.path?.[0] === PUSH &&\n task.path?.[task.path.length - 1] === true\n )\n return;\n\n const interruptWrites = writes\n .filter((w) => w[0] === INTERRUPT)\n .flatMap((w) => w[1] as string[]);\n\n this._emit([\n [\"updates\", { [INTERRUPT]: interruptWrites }],\n [\"values\", { [INTERRUPT]: interruptWrites }],\n ]);\n } else if (writes[0][0] !== ERROR) {\n this._emit(\n gatherIteratorSync(\n prefixGenerator(\n mapOutputUpdates(this.outputKeys, [[task, writes]], cached),\n \"updates\"\n )\n )\n );\n }\n }\n if (!cached) {\n this._emit(\n gatherIteratorSync(\n prefixGenerator(\n mapDebugTaskResults([[task, writes]], this.streamKeys),\n \"tasks\"\n )\n )\n );\n }\n }\n }\n\n async _matchCachedWrites() {\n if (!this.cache) return [];\n\n const matched: {\n task: PregelExecutableTask<string, string>;\n result: unknown;\n }[] = [];\n\n const serializeKey = ([ns, key]: CacheFullKey) => {\n return `ns:${ns.join(\",\")}|key:${key}`;\n };\n\n const keys: CacheFullKey[] = [];\n const keyMap: Record<string, PregelExecutableTask<string, string>> = {};\n\n for (const task of Object.values(this.tasks)) {\n if (task.cache_key != null && !task.writes.length) {\n keys.push([task.cache_key.ns, task.cache_key.key]);\n keyMap[serializeKey([task.cache_key.ns, task.cache_key.key])] = task;\n }\n }\n\n if (keys.length === 0) return [];\n const cache = await this.cache.get(keys);\n\n for (const { key, value } of cache) {\n const task = keyMap[serializeKey(key)];\n if (task != null) {\n // update the task with the cached writes\n task.writes.push(...value);\n matched.push({ task, result: value });\n }\n }\n\n return matched;\n }\n\n /**\n * Execute a single iteration of the Pregel loop.\n * Returns true if more iterations are needed.\n * @param params - The input keys to use for the tick.\n * @returns True if more iterations are needed, false otherwise.\n */\n async tick(params: { inputKeys?: string | string[] }): Promise<boolean> {\n if (this.store && !this.store.isRunning) {\n await this.store?.start();\n }\n const { inputKeys = [] } = params;\n if (this.status !== \"pending\") {\n throw new Error(\n `Cannot tick when status is no longer \"pending\". Current status: \"${this.status}\"`\n );\n }\n if (![INPUT_DONE, INPUT_RESUMING].includes(this.input)) {\n await this._first(inputKeys);\n } else if (this.toInterrupt.length > 0) {\n this.status = \"interrupt_before\";\n throw new GraphInterrupt();\n } else if (\n Object.values(this.tasks).every((task) => task.writes.length > 0)\n ) {\n const finishTaskList = Object.values(this.tasks);\n // finish superstep\n const writes = finishTaskList.flatMap((t) => t.writes);\n // All tasks have finished\n this.updatedChannels = _applyWrites(\n this.checkpoint,\n this.channels,\n finishTaskList,\n this.checkpointerGetNextVersion,\n this.triggerToNodes\n );\n // Track DeltaChannels that saw an Overwrite this super-step. They must\n // snapshot at the next checkpoint so sparse replay starts from the\n // post-overwrite value (live `update` already discarded the siblings).\n for (const [ch, v] of writes) {\n const channel = this.channels[ch];\n if (\n channel != null &&\n isDeltaChannel(channel) &&\n _isOverwriteValue(v)\n ) {\n this._deltaChannelsWithOverwrite.add(ch);\n }\n }\n // produce values output\n const valuesOutput = await gatherIterator(\n prefixGenerator(\n mapOutputValues(this.outputKeys, writes, this.channels),\n \"values\"\n )\n );\n // capture delta-channel writes for the exit-mode accumulator before\n // clearing (in \"exit\" durability they are not persisted incrementally)\n if (this._exitDeltaWrites !== undefined) {\n for (const [tid, ch, v] of this.checkpointPendingWrites) {\n const channel = this.channels[ch];\n if (channel != null && isDeltaChannel(channel)) {\n this._exitDeltaWrites.push([this.step, tid, ch, v]);\n }\n }\n }\n // clear pending writes\n this.checkpointPendingWrites = [];\n // persist the new checkpoint BEFORE emitting values, so the\n // attached `checkpoint` envelope on the values event points at\n // the fork target that captures this superstep's final state.\n await this._putCheckpoint({ source: \"loop\" });\n this._emitValuesWithCheckpointMeta(valuesOutput);\n // after execution, check if we should interrupt\n if (\n shouldInterrupt(this.checkpoint, this.interruptAfter, finishTaskList)\n ) {\n this.status = \"interrupt_after\";\n throw new GraphInterrupt();\n }\n\n // unset resuming flag\n if (this.config.configurable?.[CONFIG_KEY_RESUMING] !== undefined) {\n delete this.config.configurable?.[CONFIG_KEY_RESUMING];\n }\n } else {\n return false;\n }\n if (this.step > this.stop) {\n this.status = \"out_of_steps\";\n return false;\n }\n\n const nextTasks = _prepareNextTasks(\n this.checkpoint,\n this.checkpointPendingWrites,\n this.nodes,\n this.channels,\n this.config,\n true,\n {\n step: this.step,\n checkpointer: this.checkpointer,\n isResuming: this.isResuming,\n manager: this.manager,\n store: this.store,\n stream: this.stream,\n triggerToNodes: this.triggerToNodes,\n updatedChannels: this.updatedChannels,\n }\n );\n this.tasks = nextTasks;\n let taskList = Object.values(this.tasks);\n\n // Full-state checkpoint snapshots are expensive; skip unless a consumer\n // subscribed to \"checkpoints\" or the legacy \"debug\" wrapper mode.\n if (\n this.checkpointer &&\n (this.stream.modes.has(\"checkpoints\") || this.stream.modes.has(\"debug\"))\n ) {\n this._emit(\n await gatherIterator(\n prefixGenerator(\n mapDebugCheckpoint(\n this.checkpointConfig,\n this.channels,\n this.streamKeys,\n this.checkpointMetadata,\n taskList,\n this.checkpointPendingWrites,\n this.prevCheckpointConfig,\n this.outputKeys\n ),\n \"checkpoints\"\n )\n )\n );\n }\n\n if (taskList.length === 0) {\n this.status = \"done\";\n return false;\n }\n // Cooperative drain: the previous superstep's writes have been applied\n // and checkpointed above, and the next tasks have been prepared. If a\n // drain was requested and tasks remain, stop here (without dispatching\n // them) so the run can be resumed later from the saved checkpoint.\n if (this.control != null && this.control.drainRequested) {\n this.status = \"draining\";\n return false;\n }\n // if there are pending writes from a previous loop, apply them\n if (this.skipDoneTasks && this.checkpointPendingWrites.length > 0) {\n for (const [tid, k, v] of this.checkpointPendingWrites) {\n if (\n k === ERROR ||\n k === ERROR_SOURCE_NODE ||\n k === INTERRUPT ||\n k === RESUME\n ) {\n continue;\n }\n const task = taskList.find((t) => t.id === tid);\n if (task) {\n task.writes.push([k, v]);\n }\n }\n // On resume, re-schedule error handlers for nodes that failed in a prior\n // run (recorded via ERROR_SOURCE_NODE) before they completed handling.\n this._resumeErrorHandlersIfApplicable();\n // Re-scheduling can add handler tasks to `this.tasks`, so refresh the\n // cached task list before emitting writes and the downstream re-tick /\n // interrupt / debug checks see the newly scheduled handlers.\n taskList = Object.values(this.tasks);\n for (const task of taskList) {\n if (task.writes.length > 0) {\n this._outputWrites(task.id, task.writes, true);\n }\n }\n }\n // if all tasks have finished, re-tick\n if (taskList.every((task) => task.writes.length > 0)) {\n return this.tick({ inputKeys });\n }\n\n // Before execution, check if we should interrupt\n if (shouldInterrupt(this.checkpoint, this.interruptBefore, taskList)) {\n this.status = \"interrupt_before\";\n throw new GraphInterrupt();\n }\n\n if (this.stream.modes.has(\"tasks\") || this.stream.modes.has(\"debug\")) {\n const debugOutput = await gatherIterator(\n prefixGenerator(mapDebugTasks(taskList), \"tasks\")\n );\n this._emit(debugOutput);\n }\n\n return true;\n }\n\n async finishAndHandleError(error?: Error) {\n // persist current checkpoint and writes\n if (\n this.durability === \"exit\" &&\n // if it's a top graph\n (!this.isNested ||\n // or a nested graph with error or interrupt\n typeof error !== \"undefined\" ||\n // or a nested graph with checkpointer: true\n this.checkpointNamespace.every(\n (part) => !part.includes(CHECKPOINT_NAMESPACE_END)\n ))\n ) {\n await this._putExitDeltaWrites();\n this._putCheckpoint(this.checkpointMetadata);\n this._flushPendingWrites();\n }\n\n const suppress = this._suppressInterrupt(error);\n if (suppress || error === undefined) {\n this.output = readChannels(this.channels, this.outputKeys);\n }\n if (suppress) {\n // emit one last \"values\" event, with pending writes applied\n if (\n this.tasks !== undefined &&\n this.checkpointPendingWrites.length > 0 &&\n Object.values(this.tasks).some((task) => task.writes.length > 0)\n ) {\n this.updatedChannels = _applyWrites(\n this.checkpoint,\n this.channels,\n Object.values(this.tasks),\n this.checkpointerGetNextVersion,\n this.triggerToNodes\n );\n\n this._emitValuesWithCheckpointMeta(\n gatherIteratorSync(\n prefixGenerator(\n mapOutputValues(\n this.outputKeys,\n Object.values(this.tasks).flatMap((t) => t.writes),\n this.channels\n ),\n \"values\"\n )\n )\n );\n }\n\n // Emit INTERRUPT event (not a state snapshot — no checkpoint envelope)\n if (isGraphInterrupt(error) && !error.interrupts.length) {\n this._emit(\n [\n [\"updates\", { [INTERRUPT]: [] }],\n [\"values\", { [INTERRUPT]: [] }],\n ],\n this.#interruptStreamNamespace()\n );\n }\n }\n return suppress;\n }\n\n async acceptPush(\n task: PregelExecutableTask<string, string>,\n writeIdx: number,\n call?: Call\n ): Promise<PregelExecutableTask<string, string> | void> {\n if (\n this.interruptAfter?.length > 0 &&\n shouldInterrupt(this.checkpoint, this.interruptAfter, [task])\n ) {\n this.toInterrupt.push(task);\n return;\n }\n\n const pushed = _prepareSingleTask(\n [PUSH, task.path ?? [], writeIdx, task.id, call] as CallTaskPath,\n this.checkpoint,\n this.checkpointPendingWrites,\n this.nodes,\n this.channels,\n task.config ?? {},\n true,\n {\n step: this.step,\n checkpointer: this.checkpointer,\n manager: this.manager,\n store: this.store,\n stream: this.stream,\n }\n );\n\n if (!pushed) return;\n if (\n this.interruptBefore?.length > 0 &&\n shouldInterrupt(this.checkpoint, this.interruptBefore, [pushed])\n ) {\n this.toInterrupt.push(pushed);\n return;\n }\n\n if (this.stream.modes.has(\"tasks\") || this.stream.modes.has(\"debug\")) {\n this._emit(\n gatherIteratorSync(prefixGenerator(mapDebugTasks([pushed]), \"tasks\"))\n );\n }\n\n if (this.debug) printStepTasks(this.step, [pushed]);\n this.tasks[pushed.id] = pushed;\n if (this.skipDoneTasks) this._matchWrites({ [pushed.id]: pushed });\n\n const tasks = await this._matchCachedWrites();\n for (const { task } of tasks) {\n this._outputWrites(task.id, task.writes, true);\n }\n\n return pushed;\n }\n\n /**\n * Returns the name of the error handler node registered for `nodeName`, or\n * `undefined` if none is configured.\n */\n getErrorHandlerNode(nodeName: string): string | undefined {\n return this.nodes[nodeName]?.errorHandlerNode;\n }\n\n /**\n * Whether `nodeName` is itself an auto-generated error handler node.\n */\n isErrorHandlerNode(nodeName: string): boolean {\n return this.nodes[nodeName]?.isErrorHandler === true;\n }\n\n /**\n * Schedule a node-level error handler task for a task that failed after its\n * retry policy was exhausted. Prepares the handler task (injecting a\n * {@link NodeError}), registers it so the runner executes it within the\n * current step, and returns it (or `undefined` if no handler applies).\n *\n * The failure provenance (`ERROR` + `ERROR_SOURCE_NODE`) is checkpointed by\n * the runner via {@link PregelLoop#putWrites} so handlers observe the same\n * context after a resume.\n */\n scheduleErrorHandler(\n failedTask: PregelExecutableTask<string, string>,\n error: Error\n ): PregelExecutableTask<string, string> | undefined {\n const handlerNode = this.getErrorHandlerNode(String(failedTask.name));\n if (!handlerNode) return undefined;\n\n const handlerTask = _prepareNodeErrorHandlerTask(\n failedTask,\n handlerNode,\n error,\n this.checkpoint,\n this.checkpointPendingWrites,\n this.nodes,\n this.channels,\n failedTask.config ?? this.config,\n {\n step: this.step,\n checkpointer: this.checkpointer,\n manager: this.manager,\n store: this.store,\n stream: this.stream,\n }\n ) as PregelExecutableTask<string, string> | undefined;\n\n if (handlerTask === undefined) return undefined;\n\n this.tasks[handlerTask.id] = handlerTask;\n\n this._emit(\n gatherIteratorSync(prefixGenerator(mapDebugTasks([handlerTask]), \"tasks\"))\n );\n if (this.debug) printStepTasks(this.step, [handlerTask]);\n\n return handlerTask;\n }\n\n /**\n * On resume, re-schedule error handlers for tasks that failed in a prior run\n * but had not finished being handled. Scans pending writes for\n * `ERROR_SOURCE_NODE` markers (paired with `ERROR`), marks the originating\n * task as done (so the runner won't re-run it), and prepares a fresh handler\n * task so the runner picks it up.\n */\n protected _resumeErrorHandlersIfApplicable() {\n // Collect failed task ids with both ERROR_SOURCE_NODE and ERROR writes.\n const failed = new Map<string, Error>();\n for (const [tid, chan] of this.checkpointPendingWrites) {\n if (chan !== ERROR_SOURCE_NODE) continue;\n const errorWrite = this.checkpointPendingWrites.find(\n ([t, c]) => t === tid && c === ERROR\n );\n if (errorWrite === undefined) continue;\n const value = errorWrite[2] as { message?: string; name?: string };\n const error = new Error(value?.message ?? String(value));\n if (value?.name) error.name = value.name;\n failed.set(tid, error);\n }\n\n for (const [tid, error] of failed) {\n const task = this.tasks[tid];\n if (task === undefined) continue;\n const handlerNode = this.getErrorHandlerNode(String(task.name));\n if (!handlerNode) continue;\n // Non-empty writes => runner's `writes.length === 0` filter skips it.\n if (task.writes.length === 0) {\n task.writes.push([ERROR, { message: error.message, name: error.name }]);\n }\n this.scheduleErrorHandler(task, error);\n }\n }\n\n protected _suppressInterrupt(e?: Error): boolean {\n return isGraphInterrupt(e) && !this.isNested;\n }\n\n protected async _first(inputKeys: string | string[]) {\n /*\n * Resuming from previous checkpoint requires\n * - finding a previous checkpoint\n * - receiving null input (outer graph) or RESUMING flag (subgraph)\n */\n\n const { configurable } = this.config;\n\n // take resume value from parent\n const scratchpad = configurable?.[\n CONFIG_KEY_SCRATCHPAD\n ] as PregelScratchpad;\n\n if (scratchpad && scratchpad.nullResume !== undefined) {\n this.putWrites(NULL_TASK_ID, [[RESUME, scratchpad.nullResume]]);\n }\n\n // map command to writes\n if (isCommand(this.input)) {\n const hasResume = this.input.resume != null;\n\n if (\n this.input.resume != null &&\n typeof this.input.resume === \"object\" &&\n Object.keys(this.input.resume).every(isXXH3)\n ) {\n this.config.configurable ??= {};\n this.config.configurable[CONFIG_KEY_RESUME_MAP] = this.input.resume;\n }\n\n if (hasResume && this.checkpointer == null) {\n throw new Error(\"Cannot use Command(resume=...) without checkpointer\");\n }\n\n const writes: { [key: string]: PendingWrite[] } = {};\n\n // group writes by task id\n for (const [tid, key, value] of mapCommand(\n this.input,\n this.checkpointPendingWrites\n )) {\n writes[tid] ??= [];\n writes[tid].push([key, value]);\n }\n if (Object.keys(writes).length === 0) {\n throw new EmptyInputError(\"Received empty Command input\");\n }\n\n // save writes\n for (const [tid, ws] of Object.entries(writes)) {\n this.putWrites(tid, ws);\n }\n }\n\n // apply null writes\n const nullWrites = (this.checkpointPendingWrites ?? [])\n .filter((w) => w[0] === NULL_TASK_ID)\n .map((w) => w.slice(1)) as PendingWrite<string>[];\n if (nullWrites.length > 0) {\n _applyWrites(\n this.checkpoint,\n this.channels,\n [\n {\n name: INPUT,\n writes: nullWrites,\n triggers: [],\n },\n ],\n this.checkpointerGetNextVersion,\n this.triggerToNodes\n );\n }\n const inputIsCommand = isCommand(this.input);\n const isCommandUpdateOrGoto = inputIsCommand && nullWrites.length > 0;\n\n const isTimeTraveling =\n this.isReplaying &&\n // Time-travel to a subgraph checkpoint: the parent sets RESUMING=True\n // (it can't distinguish time-travel from resume), so we check if this\n // subgraph's own ns is in checkpoint_map.\n ((this.isNested &&\n configurable?.[CONFIG_KEY_CHECKPOINT_NS] !== undefined &&\n configurable?.[CONFIG_KEY_CHECKPOINT_NS] !== \"\" &&\n configurable?.[CONFIG_KEY_CHECKPOINT_MAP] !== undefined &&\n configurable[CONFIG_KEY_CHECKPOINT_NS] in\n configurable[CONFIG_KEY_CHECKPOINT_MAP]) ||\n !(\n (inputIsCommand && (this.input as Command).resume != null) ||\n configurable?.[CONFIG_KEY_RESUMING] === true ||\n this.resumeAtHead\n ));\n\n if (isTimeTraveling) {\n this.checkpointPendingWrites = this.checkpointPendingWrites.filter(\n (w) => w[1] !== RESUME\n );\n }\n\n const cachedIsResuming = this.isResuming;\n if (cachedIsResuming || isCommandUpdateOrGoto) {\n // One spread (O(N)) instead of O(N²) per-channel spreads. Must be a\n // new object — copyCheckpoint shallow-copies versions_seen.\n const interruptSeen: Record<string, string | number> = {\n ...this.checkpoint.versions_seen[INTERRUPT],\n };\n for (const channelName in this.channels) {\n if (!Object.prototype.hasOwnProperty.call(this.channels, channelName))\n continue;\n if (this.checkpoint.channel_versions[channelName] !== undefined) {\n interruptSeen[channelName] =\n this.checkpoint.channel_versions[channelName];\n }\n }\n this.checkpoint.versions_seen[INTERRUPT] = interruptSeen;\n\n if (\n isTimeTraveling &&\n this.checkpointMetadata.source !== \"update\" &&\n this.checkpointMetadata.source !== \"fork\"\n ) {\n this.checkpointPendingWrites = this.checkpointPendingWrites.filter(\n (w) => w[1] !== INTERRUPT\n );\n await this._putCheckpoint({ source: \"fork\" });\n }\n\n // produce values output\n const valuesOutput = await gatherIterator(\n prefixGenerator(\n mapOutputValues(this.outputKeys, true, this.channels),\n \"values\"\n )\n );\n // Preserve the original `isResuming`-first priority: when both\n // `isResuming` and `isCommandUpdateOrGoto` are true (resuming from\n // an interrupt with a Command update/goto), the resume path wins\n // and no new input checkpoint is created here.\n if (cachedIsResuming) {\n this.input = INPUT_RESUMING;\n } else if (isCommandUpdateOrGoto) {\n // Persist the input checkpoint BEFORE emitting values so the\n // attached `checkpoint` envelope points at the just-created\n // fork target. We need a new checkpoint for Command(update=...)\n // or Command(goto=...) in case the result of Command(goto=...)\n // is an interrupt. If not done, the checkpoint containing the\n // interrupt will be lost.\n await this._putCheckpoint({ source: \"input\" });\n this.input = INPUT_DONE;\n }\n // Emit after any checkpoint persistence so the `checkpoint` envelope\n // on the values event points at the fork target for the emitted state.\n this._emitValuesWithCheckpointMeta(valuesOutput);\n } else {\n // map inputs to channel updates\n const inputWrites = await gatherIterator(mapInput(inputKeys, this.input));\n if (inputWrites.length > 0) {\n const discardTasks = _prepareNextTasks(\n this.checkpoint,\n this.checkpointPendingWrites,\n this.nodes,\n this.channels,\n this.config,\n true,\n { step: this.step }\n );\n this.updatedChannels = _applyWrites(\n this.checkpoint,\n this.channels,\n (Object.values(discardTasks) as WritesProtocol[]).concat([\n {\n name: INPUT,\n writes: inputWrites as PendingWrite[],\n triggers: [],\n },\n ]),\n this.checkpointerGetNextVersion,\n this.triggerToNodes\n );\n // Input writes go through `_applyWrites` directly (above) — they never\n // enter `checkpointPendingWrites`, so the after-tick capture site does\n // not see them.\n const deltaInput = (inputWrites as PendingWrite[]).filter(([c]) => {\n const channel = this.channels[c];\n return channel != null && isDeltaChannel(channel);\n });\n // An Overwrite supplied as input must also force a snapshot.\n for (const [c, v] of deltaInput) {\n if (_isOverwriteValue(v)) this._deltaChannelsWithOverwrite.add(c);\n }\n if (deltaInput.length > 0) {\n if (this._exitDeltaWrites !== undefined) {\n // Exit mode: capture so the accumulator includes input deltas.\n for (const [c, v] of deltaInput) {\n this._exitDeltaWrites.push([this.step, NULL_TASK_ID, c, v]);\n }\n } else if (this.checkpointer != null) {\n // Non-exit: persist so sub-frequency inputs are recoverable via the\n // ancestor walk (StateGraph routes inputs through a START node whose\n // writes are persisted; this covers raw Pregel delta input channels).\n this.putWrites(NULL_TASK_ID, deltaInput);\n }\n }\n // save input checkpoint\n await this._putCheckpoint({ source: \"input\" });\n\n this.input = INPUT_DONE;\n } else if (!(CONFIG_KEY_RESUMING in (this.config.configurable ?? {}))) {\n throw new EmptyInputError(\n `Received no input writes for ${JSON.stringify(inputKeys, null, 2)}`\n );\n } else {\n // done with input\n this.input = INPUT_DONE;\n }\n }\n if (!this.isNested) {\n let replayState: ReplayState | undefined;\n // Only pass ReplayState during time-travel, not when resuming from the\n // current head with an explicit checkpoint_id (see Python _loop._first).\n if (isTimeTraveling) {\n let replayCheckpointId = this.checkpoint.id;\n if (\n (this.checkpointMetadata.source === \"update\" ||\n this.checkpointMetadata.source === \"fork\") &&\n this.prevCheckpointConfig\n ) {\n replayCheckpointId =\n this.prevCheckpointConfig.configurable?.[\n CONFIG_KEY_CHECKPOINT_ID\n ] ?? replayCheckpointId;\n }\n replayState = new ReplayState(replayCheckpointId);\n }\n this.config = patchConfigurable(this.config, {\n [CONFIG_KEY_RESUMING]: this.isResuming,\n [CONFIG_KEY_REPLAY_STATE]: replayState,\n });\n }\n }\n\n #interruptStreamNamespace(): string[] {\n const ns = this.checkpointNamespace;\n const isRootNamespace =\n ns.length === 0 || (ns.length === 1 && ns[0] === \"\");\n if (\n !isRootNamespace ||\n this.config.configurable?.[CONFIG_KEY_STREAM] === undefined\n ) {\n return ns;\n }\n const deepest = deepestCheckpointMapNamespace(\n this.config.configurable?.[CONFIG_KEY_CHECKPOINT_MAP] as\n | Record<string, string>\n | undefined\n );\n return deepest.length > 0 ? deepest : ns;\n }\n\n protected _emit(\n values: Array<[StreamMode, unknown]>,\n namespace: string[] = this.checkpointNamespace\n ) {\n for (const [mode, payload] of values) {\n if (this.stream.modes.has(mode)) {\n this.stream.push([namespace, mode, payload]);\n }\n\n // debug mode is a \"checkpoints\" or \"tasks\" wrapped in an object\n // TODO: consider deprecating this in 1.x\n if (\n (mode === \"checkpoints\" || mode === \"tasks\") &&\n this.stream.modes.has(\"debug\")\n ) {\n const step = mode === \"checkpoints\" ? this.step - 1 : this.step;\n const timestamp = new Date().toISOString();\n const type = (() => {\n if (mode === \"checkpoints\") {\n return \"checkpoint\";\n } else if (\n typeof payload === \"object\" &&\n payload != null &&\n \"result\" in payload\n ) {\n return \"task_result\";\n } else {\n return \"task\";\n }\n })();\n\n this.stream.push([\n namespace,\n \"debug\",\n { step, type, timestamp, payload },\n ]);\n }\n }\n }\n\n /**\n * Build a {@link StreamChunkMeta} describing the currently active checkpoint.\n * Emitted as a separate ``[namespace, \"checkpoints\", envelope]`` chunk before\n * the paired ``values`` chunk. Returns `undefined` if no checkpoint metadata\n * is available yet.\n */\n protected _currentCheckpointMeta(): StreamChunkMeta | undefined {\n if (!this.checkpointMetadata || !this.checkpoint?.id) return undefined;\n const parent_id = this.prevCheckpointConfig?.configurable?.checkpoint_id as\n | string\n | undefined;\n return {\n checkpoint: {\n id: this.checkpoint.id,\n ...(parent_id ? { parent_id } : {}),\n step: this.checkpointMetadata.step,\n source: this.checkpointMetadata.source,\n },\n };\n }\n\n /**\n * Emit stream entries. When checkpoint meta is available, push a lightweight\n * ``[namespace, \"checkpoints\", envelope]`` chunk before each ``values`` chunk.\n */\n protected _emitValuesWithCheckpointMeta(\n entries: [StreamMode, unknown][]\n ): void {\n const meta = this._currentCheckpointMeta();\n for (const [mode, payload] of entries) {\n if (\n mode === \"values\" &&\n meta?.checkpoint != null &&\n !this.stream.modes.has(\"checkpoints\")\n ) {\n this.stream.push([\n this.checkpointNamespace,\n \"checkpoints\",\n meta.checkpoint,\n ]);\n }\n if (this.stream.modes.has(mode)) {\n this.stream.push([this.checkpointNamespace, mode, payload]);\n }\n }\n }\n\n protected _putCheckpoint(\n inputMetadata: Omit<CheckpointMetadata, \"step\" | \"parents\">\n ) {\n const exiting = this.checkpointMetadata === inputMetadata;\n\n const doCheckpoint =\n this.checkpointer != null && (this.durability !== \"exit\" || exiting);\n\n const storeCheckpoint = (checkpoint: Checkpoint) => {\n // store the previous checkpoint config for debug events\n this.prevCheckpointConfig = this.checkpointConfig?.configurable\n ?.checkpoint_id\n ? this.checkpointConfig\n : undefined;\n\n // child graphs keep at most one checkpoint per parent checkpoint\n // this is achieved by writing child checkpoints as progress is made\n // (so that error recovery / resuming from interrupt don't lose work)\n // but doing so always with an id equal to that of the parent checkpoint\n this.checkpointConfig = patchConfigurable(this.checkpointConfig, {\n [CONFIG_KEY_CHECKPOINT_NS]:\n this.config.configurable?.checkpoint_ns ?? \"\",\n });\n\n const channelVersions = { ...this.checkpoint.channel_versions };\n const newVersions = getNewChannelVersions(\n this.checkpointPreviousVersions,\n channelVersions\n );\n this.checkpointPreviousVersions = channelVersions;\n // save it, without blocking\n // if there's a previous checkpoint save in progress, wait for it\n // ensuring checkpointers receive checkpoints in order\n void this._checkpointerPutAfterPrevious({\n config: { ...this.checkpointConfig },\n checkpoint: copyCheckpoint(checkpoint),\n metadata: { ...this.checkpointMetadata },\n newVersions,\n });\n this.checkpointConfig = {\n ...this.checkpointConfig,\n configurable: {\n ...this.checkpointConfig.configurable,\n checkpoint_id: this.checkpoint.id,\n },\n };\n };\n\n // Per-delta-channel counter bookkeeping. Each delta channel tracks a\n // [updates, supersteps] pair: `updates` increments only when the channel\n // is written this step; `supersteps` increments every superstep. The exit\n // call must NOT bump again (the last intermediate call already counted the\n // final superstep) or it would double-count.\n let newCounters: Record<string, [number, number]>;\n if (!exiting) {\n const prevCounters =\n this.checkpointMetadata.counters_since_delta_snapshot ?? {};\n newCounters = {};\n const updated = this.updatedChannels ?? new Set<string>();\n for (const chName in this.channels) {\n if (!Object.prototype.hasOwnProperty.call(this.channels, chName))\n continue;\n if (!isDeltaChannel(this.channels[chName])) continue;\n const [u, s] = prevCounters[chName] ?? [0, 0];\n newCounters[chName] = [updated.has(chName) ? u + 1 : u, s + 1];\n }\n this.checkpointMetadata = {\n ...inputMetadata,\n step: this.step,\n parents: this.config.configurable?.[CONFIG_KEY_CHECKPOINT_MAP] ?? {},\n };\n } else {\n newCounters = {\n ...(this.checkpointMetadata.counters_since_delta_snapshot ?? {}),\n };\n }\n\n const channelsToSnapshot = doCheckpoint\n ? deltaChannelsToSnapshot(this.channels, newCounters)\n : new Set<string>();\n // Force a snapshot for any delta channel that saw an Overwrite since the\n // last checkpoint, so the post-overwrite value is materialized and sparse\n // replay never has to fold across the reset.\n if (doCheckpoint) {\n for (const ch of this._deltaChannelsWithOverwrite)\n channelsToSnapshot.add(ch);\n }\n\n // create new checkpoint\n this.checkpoint = createCheckpoint(\n this.checkpoint,\n doCheckpoint ? this.channels : undefined,\n this.step,\n {\n id: exiting ? this.checkpoint.id : undefined,\n channelsToSnapshot,\n updatedChannels: this.updatedChannels,\n getNextVersion: doCheckpoint\n ? (current) =>\n this.checkpointerGetNextVersion(current as number | undefined)\n : undefined,\n }\n );\n\n // Reset counters for channels that just snapshotted, and persist the\n // non-zero remainder into metadata (or clear the field entirely).\n for (const k of channelsToSnapshot) {\n newCounters[k] = [0, 0];\n // The overwrite was just materialized into `channel_values`; stop\n // forcing a snapshot for it.\n this._deltaChannelsWithOverwrite.delete(k);\n }\n const nonZero: Record<string, [number, number]> = {};\n for (const k in newCounters) {\n if (!Object.prototype.hasOwnProperty.call(newCounters, k)) continue;\n const [u, s] = newCounters[k];\n if (u !== 0 || s !== 0) nonZero[k] = [u, s];\n }\n if (Object.keys(nonZero).length > 0) {\n this.checkpointMetadata.counters_since_delta_snapshot = nonZero;\n } else {\n delete this.checkpointMetadata.counters_since_delta_snapshot;\n }\n\n // Bail if no checkpointer\n if (doCheckpoint) storeCheckpoint(this.checkpoint);\n\n if (!exiting) {\n // increment step\n this.step += 1;\n }\n }\n\n /**\n * Stage the exit-mode accumulator of DeltaChannel writes so the final\n * checkpoint can be reconstructed. In \"exit\" durability per-step writes are\n * not persisted, so delta writes are accumulated across the run and anchored\n * here — under the saved parent, or a freshly-created stub when this is a\n * first run with no persisted parent. Channels that will snapshot in the\n * final checkpoint are excluded (their full value lives in `channel_values`).\n *\n * Must run BEFORE the final `_putCheckpoint` so the stub branch can adjust\n * `checkpointConfig` to anchor the final checkpoint on the stub.\n */\n protected async _putExitDeltaWrites(): Promise<void> {\n if (\n this._exitDeltaWrites === undefined ||\n this._exitDeltaWrites.length === 0 ||\n this.checkpointer == null ||\n this._initialCheckpointConfig === undefined\n ) {\n return;\n }\n\n const counters =\n this.checkpointMetadata.counters_since_delta_snapshot ?? {};\n const channelsToSnapshot = deltaChannelsToSnapshot(this.channels, counters);\n // Channels that saw an Overwrite are force-snapshotted by the final\n // `_putCheckpoint` (which runs after this), so their accumulated exit\n // writes must NOT also be replayed on top of that snapshot — exclude them.\n for (const ch of this._deltaChannelsWithOverwrite)\n channelsToSnapshot.add(ch);\n\n const pending = this._exitDeltaWrites.filter(\n ([, , ch]) => !channelsToSnapshot.has(ch)\n );\n if (pending.length === 0) return;\n\n let anchorConfig: RunnableConfig;\n if (this._hasPersistedParent) {\n // _initialCheckpointConfig points at the saved parent checkpoint.\n anchorConfig = this._initialCheckpointConfig;\n } else {\n // No persisted parent: create a stub empty checkpoint (no parent) and\n // anchor on it, then point the final checkpoint at the stub.\n const stubCp = emptyCheckpoint();\n stubCp.id = this.checkpointIdSaved ?? stubCp.id;\n stubCp.ts = new Date().toISOString();\n const stubPutConfig = patchConfigurable(this._initialCheckpointConfig, {\n [CONFIG_KEY_CHECKPOINT_ID]: undefined,\n });\n anchorConfig = patchConfigurable(this._initialCheckpointConfig, {\n [CONFIG_KEY_CHECKPOINT_ID]: stubCp.id,\n });\n this._trackCheckpointerPromise(\n this.checkpointer.put(\n stubPutConfig,\n stubCp,\n { source: \"loop\", step: -2, parents: {} },\n {}\n )\n );\n this.checkpointConfig = anchorConfig;\n }\n\n const anchorWriteConfig = patchConfigurable(anchorConfig, {\n [CONFIG_KEY_CHECKPOINT_NS]: this.config.configurable?.checkpoint_ns ?? \"\",\n [CONFIG_KEY_CHECKPOINT_ID]:\n anchorConfig.configurable?.[CONFIG_KEY_CHECKPOINT_ID],\n });\n\n // Group by [step, taskId]; a step-prefixed synthetic task id preserves\n // chronological super-step order under the saver's (task_id, idx) sort.\n const grouped = new Map<string, PendingWrite<string>[]>();\n const order: { key: string; step: number; tid: string }[] = [];\n for (const [step, tid, ch, v] of pending) {\n const key = `${step}\\u0000${tid}`;\n let group = grouped.get(key);\n if (group === undefined) {\n group = [];\n grouped.set(key, group);\n order.push({ key, step, tid });\n }\n group.push([ch, v]);\n }\n for (const { key, step, tid } of order) {\n const synthTid = `${String(step).padStart(8, \"0\")}-${tid}`;\n this._trackCheckpointerPromise(\n this.checkpointer.putWrites(\n anchorWriteConfig,\n grouped.get(key)!,\n synthTid\n )\n );\n }\n }\n\n protected _flushPendingWrites() {\n if (this.checkpointer == null) return;\n if (this.checkpointPendingWrites.length === 0) return;\n\n // patch config\n const config = patchConfigurable(this.checkpointConfig, {\n [CONFIG_KEY_CHECKPOINT_NS]: this.config.configurable?.checkpoint_ns ?? \"\",\n [CONFIG_KEY_CHECKPOINT_ID]: this.checkpoint.id,\n });\n\n // group writes by task id\n const byTask: Record<string, PendingWrite<string>[]> = {};\n for (const [tid, key, value] of this.checkpointPendingWrites) {\n byTask[tid] ??= [];\n byTask[tid].push([key, value]);\n }\n\n // submit writes to checkpointer\n for (const [tid, ws] of Object.entries(byTask)) {\n this._trackCheckpointerPromise(\n this.checkpointer.putWrites(config, ws, tid)\n );\n }\n }\n\n protected _matchWrites(\n tasks: Record<string, PregelExecutableTask<string, string>>\n ) {\n for (const [tid, k, v] of this.checkpointPendingWrites) {\n if (k === ERROR || k === INTERRUPT || k === RESUME) {\n continue;\n }\n const task = Object.values(tasks).find((t) => t.id === tid);\n if (task) {\n task.writes.push([k, v]);\n }\n }\n for (const task of Object.values(tasks)) {\n if (task.writes.length > 0) {\n this._outputWrites(task.id, task.writes, true);\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -82,6 +82,7 @@ var StreamProtocolMessagesHandler = class extends _langchain_core_callbacks_base
|
|
|
82
82
|
streamedRunIds = /* @__PURE__ */ new Set();
|
|
83
83
|
stableMessageIdMap = {};
|
|
84
84
|
lc_prefer_chat_model_stream_events = true;
|
|
85
|
+
awaitHandlers = true;
|
|
85
86
|
constructor(streamFn) {
|
|
86
87
|
super();
|
|
87
88
|
this.streamFn = streamFn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages-v2.cjs","names":["BaseCallbackHandler","ToolMessage","BaseMessage","BaseMessageChunk"],"sources":["../../src/pregel/messages-v2.ts"],"sourcesContent":["import { BaseCallbackHandler } from \"@langchain/core/callbacks/base\";\nimport {\n BaseMessage,\n ToolMessage,\n BaseMessageChunk,\n} from \"@langchain/core/messages\";\nimport { Serialized } from \"@langchain/core/load/serializable\";\nimport { ChatGeneration, LLMResult } from \"@langchain/core/outputs\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\n\nimport { TAG_HIDDEN, TAG_NOSTREAM } from \"../constants.js\";\nimport { StreamChunk } from \"./stream.js\";\n\ntype Meta = [string[], Record<string, unknown>];\ntype CompatibleContentBlock = { type: string; [key: string]: unknown };\n\nfunction getResponseMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"response_metadata\" in message &&\n typeof message.response_metadata === \"object\" &&\n message.response_metadata != null\n ) {\n return message.response_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction getUsageMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"usage_metadata\" in message &&\n typeof message.usage_metadata === \"object\" &&\n message.usage_metadata != null\n ) {\n return message.usage_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction startBlockFor(block: CompatibleContentBlock): CompatibleContentBlock {\n switch (block.type) {\n case \"text\":\n return { type: \"text\", text: \"\" };\n case \"reasoning\":\n return { type: \"reasoning\", reasoning: \"\" };\n case \"tool_call\":\n case \"tool_call_chunk\":\n return {\n type: \"tool_call_chunk\",\n ...(block.id != null ? { id: block.id } : {}),\n ...(block.name != null ? { name: block.name } : {}),\n args: \"\",\n };\n default:\n return block;\n }\n}\n\nfunction deltaFor(\n block: CompatibleContentBlock\n): ChatModelStreamEvent | undefined {\n switch (block.type) {\n case \"text\": {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n return text.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"text-delta\", text },\n }\n : undefined;\n }\n case \"reasoning\": {\n const reasoning =\n typeof block.reasoning === \"string\" ? block.reasoning : \"\";\n return reasoning.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"reasoning-delta\", reasoning },\n }\n : undefined;\n }\n case \"tool_call_chunk\":\n return {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: {\n type: \"block-delta\",\n fields: { ...block, type: \"tool_call_chunk\" },\n },\n };\n default:\n return undefined;\n }\n}\n\n/**\n * A callback handler that implements protocol-native stream_mode=messages.\n *\n * LangChain Core owns chat model content-block event construction. This handler\n * only captures LangGraph metadata, forwards Core events to the Pregel messages\n * channel, and emits a small non-streaming fallback for models that cannot\n * produce stream events.\n */\nexport class StreamProtocolMessagesHandler extends BaseCallbackHandler {\n name = \"StreamProtocolMessagesHandler\";\n\n streamFn: (streamChunk: StreamChunk) => void;\n\n metadatas: Record<string, Meta | undefined> = {};\n\n seen: Record<string, BaseMessage | true> = {};\n\n streamedRunIds = new Set<string>();\n\n stableMessageIdMap: Record<string, string> = {};\n\n lc_prefer_chat_model_stream_events = true;\n\n constructor(streamFn: (streamChunk: StreamChunk) => void) {\n super();\n this.streamFn = streamFn;\n }\n\n private normalizeMessageId(message: BaseMessage, runId: string | undefined) {\n let messageId = message.id;\n\n if (runId != null) {\n if (ToolMessage.isInstance(message)) {\n messageId ??= `run-${runId}-tool-${message.tool_call_id}`;\n } else {\n if (messageId == null || messageId === `run-${runId}`) {\n messageId =\n this.stableMessageIdMap[runId] ?? messageId ?? `run-${runId}`;\n }\n this.stableMessageIdMap[runId] ??= messageId;\n }\n }\n\n if (messageId !== message.id) {\n // eslint-disable-next-line no-param-reassign\n message.id = messageId;\n // eslint-disable-next-line no-param-reassign\n message.lc_kwargs.id = messageId;\n }\n\n if (message.id != null) this.seen[message.id] = message;\n return message.id;\n }\n\n private emit(meta: Meta, data: ChatModelStreamEvent, runId?: string) {\n const metadata = runId != null ? { ...meta[1], run_id: runId } : meta[1];\n this.streamFn([meta[0], \"messages\", [data, metadata]]);\n }\n\n private emitFinalMessage(\n meta: Meta,\n message: BaseMessage,\n runId: string | undefined,\n dedupe = false\n ) {\n const existingId =\n message.id ??\n (runId != null ? this.stableMessageIdMap[runId] : undefined);\n if (dedupe && existingId != null && this.seen[existingId] !== undefined) {\n return;\n }\n\n const messageId = this.normalizeMessageId(message, runId);\n const role =\n message.type === \"human\"\n ? \"human\"\n : message.type === \"system\"\n ? \"system\"\n : message.type === \"tool\"\n ? \"tool\"\n : \"ai\";\n const toolCallId =\n role === \"tool\" && ToolMessage.isInstance(message)\n ? message.tool_call_id\n : undefined;\n\n this.emit(\n meta,\n {\n event: \"message-start\",\n ...(messageId != null ? { id: messageId } : {}),\n ...(role !== \"ai\" ? ({ role } as Record<string, unknown>) : {}),\n ...(typeof toolCallId === \"string\"\n ? ({ tool_call_id: toolCallId } as Record<string, unknown>)\n : {}),\n } as ChatModelStreamEvent,\n runId\n );\n\n const contentBlocks: CompatibleContentBlock[] = Array.isArray(\n message.content\n )\n ? (message.content as CompatibleContentBlock[])\n : typeof message.content === \"string\" && message.content.length > 0\n ? [{ type: \"text\", text: message.content }]\n : [];\n\n contentBlocks.forEach((block, offset) => {\n const index = typeof block.index === \"number\" ? block.index : offset;\n this.emit(\n meta,\n {\n event: \"content-block-start\",\n index,\n content: startBlockFor(block),\n },\n runId\n );\n const delta = deltaFor({ ...block, index });\n if (delta != null) {\n this.emit(meta, delta, runId);\n }\n this.emit(\n meta,\n {\n event: \"content-block-finish\",\n index,\n content: block,\n },\n runId\n );\n });\n\n this.emit(\n meta,\n {\n event: \"message-finish\",\n ...(getUsageMetadata(message) != null\n ? { usage: getUsageMetadata(message) }\n : {}),\n ...(getResponseMetadata(message) != null\n ? { responseMetadata: getResponseMetadata(message) }\n : {}),\n },\n runId\n );\n }\n\n handleChatModelStart(\n _llm: Serialized,\n _messages: BaseMessage[][],\n runId: string,\n _parentRunId?: string,\n _extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ) {\n if (\n metadata &&\n (!tags || (!tags.includes(TAG_NOSTREAM) && !tags.includes(\"nostream\")))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n }\n }\n\n handleLLMNewToken() {\n // Core v2 stream events are forwarded via handleChatModelStreamEvent.\n }\n\n handleChatModelStreamEvent(event: ChatModelStreamEvent, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n let forwarded = event;\n if (event.event === \"message-start\") {\n this.streamedRunIds.add(runId);\n const id = event.id ?? `run-${runId}`;\n this.seen[id] = true;\n this.stableMessageIdMap[runId] ??= id;\n if (event.id == null) {\n forwarded = { ...event, id };\n }\n }\n\n this.emit(meta, forwarded, runId);\n }\n\n handleLLMEnd(output: LLMResult, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n const chatGeneration = output.generations?.[0]?.[0] as ChatGeneration;\n const message = BaseMessage.isInstance(chatGeneration?.message)\n ? chatGeneration.message\n : undefined;\n\n if (message != null) {\n if (this.streamedRunIds.has(runId)) {\n const messageId = this.normalizeMessageId(message, runId);\n if (messageId != null) this.seen[messageId] = message;\n } else {\n this.emitFinalMessage(meta, message, runId, true);\n }\n }\n\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleLLMError(_err: any, runId: string) {\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n handleChainStart(\n _chain: Serialized,\n inputs: ChainValues,\n runId: string,\n _parentRunId?: string,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runType?: string,\n name?: string\n ) {\n if (\n metadata !== undefined &&\n name === metadata.langgraph_node &&\n (tags === undefined || !tags.includes(TAG_HIDDEN))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n\n if (typeof inputs === \"object\") {\n for (const value of Object.values(inputs)) {\n if (\n (BaseMessage.isInstance(value) ||\n BaseMessageChunk.isInstance(value)) &&\n value.id !== undefined\n ) {\n this.seen[value.id] = value;\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (\n (BaseMessage.isInstance(item) ||\n BaseMessageChunk.isInstance(item)) &&\n item.id !== undefined\n ) {\n this.seen[item.id] = item;\n }\n }\n }\n }\n }\n }\n }\n\n handleChainEnd(outputs: ChainValues, runId: string) {\n const meta = this.metadatas[runId];\n delete this.metadatas[runId];\n if (meta === undefined) return;\n\n const emitMessage = (value: unknown) => {\n if (BaseMessage.isInstance(value) && !ToolMessage.isInstance(value)) {\n this.emitFinalMessage(meta, value, runId, true);\n }\n };\n\n if (BaseMessage.isInstance(outputs)) {\n emitMessage(outputs);\n } else if (Array.isArray(outputs)) {\n for (const value of outputs) emitMessage(value);\n } else if (outputs != null && typeof outputs === \"object\") {\n for (const value of Object.values(outputs)) {\n if (Array.isArray(value)) {\n for (const item of value) emitMessage(item);\n } else {\n emitMessage(value);\n }\n }\n }\n\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleChainError(_err: any, runId: string) {\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"messages-v2.cjs","names":["BaseCallbackHandler","ToolMessage","BaseMessage","BaseMessageChunk"],"sources":["../../src/pregel/messages-v2.ts"],"sourcesContent":["import { BaseCallbackHandler } from \"@langchain/core/callbacks/base\";\nimport {\n BaseMessage,\n ToolMessage,\n BaseMessageChunk,\n} from \"@langchain/core/messages\";\nimport { Serialized } from \"@langchain/core/load/serializable\";\nimport { ChatGeneration, LLMResult } from \"@langchain/core/outputs\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport { ChainValues } from \"@langchain/core/utils/types\";\n\nimport { TAG_HIDDEN, TAG_NOSTREAM } from \"../constants.js\";\nimport { StreamChunk } from \"./stream.js\";\n\ntype Meta = [string[], Record<string, unknown>];\ntype CompatibleContentBlock = { type: string; [key: string]: unknown };\n\nfunction getResponseMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"response_metadata\" in message &&\n typeof message.response_metadata === \"object\" &&\n message.response_metadata != null\n ) {\n return message.response_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction getUsageMetadata(\n message: BaseMessage\n): Record<string, unknown> | undefined {\n if (\n \"usage_metadata\" in message &&\n typeof message.usage_metadata === \"object\" &&\n message.usage_metadata != null\n ) {\n return message.usage_metadata as Record<string, unknown>;\n }\n return undefined;\n}\n\nfunction startBlockFor(block: CompatibleContentBlock): CompatibleContentBlock {\n switch (block.type) {\n case \"text\":\n return { type: \"text\", text: \"\" };\n case \"reasoning\":\n return { type: \"reasoning\", reasoning: \"\" };\n case \"tool_call\":\n case \"tool_call_chunk\":\n return {\n type: \"tool_call_chunk\",\n ...(block.id != null ? { id: block.id } : {}),\n ...(block.name != null ? { name: block.name } : {}),\n args: \"\",\n };\n default:\n return block;\n }\n}\n\nfunction deltaFor(\n block: CompatibleContentBlock\n): ChatModelStreamEvent | undefined {\n switch (block.type) {\n case \"text\": {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n return text.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"text-delta\", text },\n }\n : undefined;\n }\n case \"reasoning\": {\n const reasoning =\n typeof block.reasoning === \"string\" ? block.reasoning : \"\";\n return reasoning.length > 0\n ? {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: { type: \"reasoning-delta\", reasoning },\n }\n : undefined;\n }\n case \"tool_call_chunk\":\n return {\n event: \"content-block-delta\",\n index: typeof block.index === \"number\" ? block.index : 0,\n delta: {\n type: \"block-delta\",\n fields: { ...block, type: \"tool_call_chunk\" },\n },\n };\n default:\n return undefined;\n }\n}\n\n/**\n * A callback handler that implements protocol-native stream_mode=messages.\n *\n * LangChain Core owns chat model content-block event construction. This handler\n * only captures LangGraph metadata, forwards Core events to the Pregel messages\n * channel, and emits a small non-streaming fallback for models that cannot\n * produce stream events.\n */\nexport class StreamProtocolMessagesHandler extends BaseCallbackHandler {\n name = \"StreamProtocolMessagesHandler\";\n\n streamFn: (streamChunk: StreamChunk) => void;\n\n metadatas: Record<string, Meta | undefined> = {};\n\n seen: Record<string, BaseMessage | true> = {};\n\n streamedRunIds = new Set<string>();\n\n stableMessageIdMap: Record<string, string> = {};\n\n lc_prefer_chat_model_stream_events = true;\n\n // Dispatch this handler's callbacks inline rather than on LangChain's\n // background callback queue. The handler's only side effect is a synchronous\n // `push()` onto the run's stream, so running it inline guarantees those\n // pushes happen *during* the model/chain call — while the stream is still\n // open — instead of after the Pregel loop has returned and sealed the\n // stream. Background dispatch let a model/tool call in a nested or parallel\n // task flush its `messages` chunk after close, where `push()` silently drops\n // it; this surfaced as empty per-message streams (`sub.messages`) for\n // subagents dispatched in parallel from a single tools step.\n awaitHandlers = true;\n\n constructor(streamFn: (streamChunk: StreamChunk) => void) {\n super();\n this.streamFn = streamFn;\n }\n\n private normalizeMessageId(message: BaseMessage, runId: string | undefined) {\n let messageId = message.id;\n\n if (runId != null) {\n if (ToolMessage.isInstance(message)) {\n messageId ??= `run-${runId}-tool-${message.tool_call_id}`;\n } else {\n if (messageId == null || messageId === `run-${runId}`) {\n messageId =\n this.stableMessageIdMap[runId] ?? messageId ?? `run-${runId}`;\n }\n this.stableMessageIdMap[runId] ??= messageId;\n }\n }\n\n if (messageId !== message.id) {\n // eslint-disable-next-line no-param-reassign\n message.id = messageId;\n // eslint-disable-next-line no-param-reassign\n message.lc_kwargs.id = messageId;\n }\n\n if (message.id != null) this.seen[message.id] = message;\n return message.id;\n }\n\n private emit(meta: Meta, data: ChatModelStreamEvent, runId?: string) {\n const metadata = runId != null ? { ...meta[1], run_id: runId } : meta[1];\n this.streamFn([meta[0], \"messages\", [data, metadata]]);\n }\n\n private emitFinalMessage(\n meta: Meta,\n message: BaseMessage,\n runId: string | undefined,\n dedupe = false\n ) {\n const existingId =\n message.id ??\n (runId != null ? this.stableMessageIdMap[runId] : undefined);\n if (dedupe && existingId != null && this.seen[existingId] !== undefined) {\n return;\n }\n\n const messageId = this.normalizeMessageId(message, runId);\n const role =\n message.type === \"human\"\n ? \"human\"\n : message.type === \"system\"\n ? \"system\"\n : message.type === \"tool\"\n ? \"tool\"\n : \"ai\";\n const toolCallId =\n role === \"tool\" && ToolMessage.isInstance(message)\n ? message.tool_call_id\n : undefined;\n\n this.emit(\n meta,\n {\n event: \"message-start\",\n ...(messageId != null ? { id: messageId } : {}),\n ...(role !== \"ai\" ? ({ role } as Record<string, unknown>) : {}),\n ...(typeof toolCallId === \"string\"\n ? ({ tool_call_id: toolCallId } as Record<string, unknown>)\n : {}),\n } as ChatModelStreamEvent,\n runId\n );\n\n const contentBlocks: CompatibleContentBlock[] = Array.isArray(\n message.content\n )\n ? (message.content as CompatibleContentBlock[])\n : typeof message.content === \"string\" && message.content.length > 0\n ? [{ type: \"text\", text: message.content }]\n : [];\n\n contentBlocks.forEach((block, offset) => {\n const index = typeof block.index === \"number\" ? block.index : offset;\n this.emit(\n meta,\n {\n event: \"content-block-start\",\n index,\n content: startBlockFor(block),\n },\n runId\n );\n const delta = deltaFor({ ...block, index });\n if (delta != null) {\n this.emit(meta, delta, runId);\n }\n this.emit(\n meta,\n {\n event: \"content-block-finish\",\n index,\n content: block,\n },\n runId\n );\n });\n\n this.emit(\n meta,\n {\n event: \"message-finish\",\n ...(getUsageMetadata(message) != null\n ? { usage: getUsageMetadata(message) }\n : {}),\n ...(getResponseMetadata(message) != null\n ? { responseMetadata: getResponseMetadata(message) }\n : {}),\n },\n runId\n );\n }\n\n handleChatModelStart(\n _llm: Serialized,\n _messages: BaseMessage[][],\n runId: string,\n _parentRunId?: string,\n _extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ) {\n if (\n metadata &&\n (!tags || (!tags.includes(TAG_NOSTREAM) && !tags.includes(\"nostream\")))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n }\n }\n\n handleLLMNewToken() {\n // Core v2 stream events are forwarded via handleChatModelStreamEvent.\n }\n\n handleChatModelStreamEvent(event: ChatModelStreamEvent, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n let forwarded = event;\n if (event.event === \"message-start\") {\n this.streamedRunIds.add(runId);\n const id = event.id ?? `run-${runId}`;\n this.seen[id] = true;\n this.stableMessageIdMap[runId] ??= id;\n if (event.id == null) {\n forwarded = { ...event, id };\n }\n }\n\n this.emit(meta, forwarded, runId);\n }\n\n handleLLMEnd(output: LLMResult, runId: string) {\n const meta = this.metadatas[runId];\n if (meta === undefined) return;\n\n const chatGeneration = output.generations?.[0]?.[0] as ChatGeneration;\n const message = BaseMessage.isInstance(chatGeneration?.message)\n ? chatGeneration.message\n : undefined;\n\n if (message != null) {\n if (this.streamedRunIds.has(runId)) {\n const messageId = this.normalizeMessageId(message, runId);\n if (messageId != null) this.seen[messageId] = message;\n } else {\n this.emitFinalMessage(meta, message, runId, true);\n }\n }\n\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleLLMError(_err: any, runId: string) {\n this.streamedRunIds.delete(runId);\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n\n handleChainStart(\n _chain: Serialized,\n inputs: ChainValues,\n runId: string,\n _parentRunId?: string,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runType?: string,\n name?: string\n ) {\n if (\n metadata !== undefined &&\n name === metadata.langgraph_node &&\n (tags === undefined || !tags.includes(TAG_HIDDEN))\n ) {\n this.metadatas[runId] = [\n (metadata.langgraph_checkpoint_ns as string).split(\"|\"),\n { tags, name, ...metadata },\n ];\n\n if (typeof inputs === \"object\") {\n for (const value of Object.values(inputs)) {\n if (\n (BaseMessage.isInstance(value) ||\n BaseMessageChunk.isInstance(value)) &&\n value.id !== undefined\n ) {\n this.seen[value.id] = value;\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (\n (BaseMessage.isInstance(item) ||\n BaseMessageChunk.isInstance(item)) &&\n item.id !== undefined\n ) {\n this.seen[item.id] = item;\n }\n }\n }\n }\n }\n }\n }\n\n handleChainEnd(outputs: ChainValues, runId: string) {\n const meta = this.metadatas[runId];\n delete this.metadatas[runId];\n if (meta === undefined) return;\n\n const emitMessage = (value: unknown) => {\n if (BaseMessage.isInstance(value) && !ToolMessage.isInstance(value)) {\n this.emitFinalMessage(meta, value, runId, true);\n }\n };\n\n if (BaseMessage.isInstance(outputs)) {\n emitMessage(outputs);\n } else if (Array.isArray(outputs)) {\n for (const value of outputs) emitMessage(value);\n } else if (outputs != null && typeof outputs === \"object\") {\n for (const value of Object.values(outputs)) {\n if (Array.isArray(value)) {\n for (const item of value) emitMessage(item);\n } else {\n emitMessage(value);\n }\n }\n }\n\n delete this.stableMessageIdMap[runId];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n handleChainError(_err: any, runId: string) {\n delete this.metadatas[runId];\n delete this.stableMessageIdMap[runId];\n }\n}\n"],"mappings":"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"}
|
|
@@ -82,6 +82,7 @@ var StreamProtocolMessagesHandler = class extends BaseCallbackHandler {
|
|
|
82
82
|
streamedRunIds = /* @__PURE__ */ new Set();
|
|
83
83
|
stableMessageIdMap = {};
|
|
84
84
|
lc_prefer_chat_model_stream_events = true;
|
|
85
|
+
awaitHandlers = true;
|
|
85
86
|
constructor(streamFn) {
|
|
86
87
|
super();
|
|
87
88
|
this.streamFn = streamFn;
|