@langchain/langgraph 1.4.21 → 1.5.1
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/base.cjs +123 -11
- package/dist/channels/base.cjs.map +1 -1
- package/dist/channels/base.d.cts +26 -4
- package/dist/channels/base.d.cts.map +1 -1
- package/dist/channels/base.d.ts +26 -4
- package/dist/channels/base.d.ts.map +1 -1
- package/dist/channels/base.js +120 -13
- package/dist/channels/base.js.map +1 -1
- package/dist/channels/binop.cjs +2 -1
- package/dist/channels/binop.cjs.map +1 -1
- package/dist/channels/binop.d.cts.map +1 -1
- package/dist/channels/binop.d.ts.map +1 -1
- package/dist/channels/binop.js +2 -1
- package/dist/channels/binop.js.map +1 -1
- package/dist/channels/index.cjs +2 -0
- package/dist/channels/index.d.cts +2 -2
- package/dist/channels/index.d.ts +2 -2
- package/dist/channels/index.js +2 -2
- package/dist/constants.cjs +14 -0
- 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 +13 -1
- package/dist/constants.js.map +1 -1
- package/dist/errors.cjs +22 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +10 -1
- package/dist/errors.d.cts.map +1 -1
- package/dist/errors.d.ts +10 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +21 -1
- package/dist/errors.js.map +1 -1
- package/dist/graph/index.cjs +1 -1
- package/dist/graph/index.js +1 -1
- package/dist/graph/messages_reducer.cjs +30 -6
- package/dist/graph/messages_reducer.cjs.map +1 -1
- package/dist/graph/messages_reducer.d.cts +4 -2
- package/dist/graph/messages_reducer.d.cts.map +1 -1
- package/dist/graph/messages_reducer.d.ts +4 -2
- package/dist/graph/messages_reducer.d.ts.map +1 -1
- package/dist/graph/messages_reducer.js +31 -8
- package/dist/graph/messages_reducer.js.map +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/interrupt.cjs +9 -1
- package/dist/interrupt.cjs.map +1 -1
- package/dist/interrupt.d.cts.map +1 -1
- package/dist/interrupt.d.ts.map +1 -1
- package/dist/interrupt.js +10 -2
- package/dist/interrupt.js.map +1 -1
- package/dist/pregel/algo.cjs +46 -45
- package/dist/pregel/algo.cjs.map +1 -1
- package/dist/pregel/algo.d.cts.map +1 -1
- package/dist/pregel/algo.d.ts.map +1 -1
- package/dist/pregel/algo.js +47 -47
- package/dist/pregel/algo.js.map +1 -1
- package/dist/pregel/checkpoint.cjs +70 -0
- package/dist/pregel/checkpoint.cjs.map +1 -0
- package/dist/pregel/checkpoint.js +67 -0
- package/dist/pregel/checkpoint.js.map +1 -0
- package/dist/pregel/debug.cjs +1 -0
- package/dist/pregel/debug.cjs.map +1 -1
- package/dist/pregel/debug.js +1 -0
- package/dist/pregel/debug.js.map +1 -1
- package/dist/pregel/index.cjs +87 -34
- 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 +91 -38
- package/dist/pregel/index.js.map +1 -1
- package/dist/pregel/loop.cjs +336 -113
- package/dist/pregel/loop.cjs.map +1 -1
- package/dist/pregel/loop.js +341 -119
- package/dist/pregel/loop.js.map +1 -1
- package/dist/pregel/runner.cjs +1 -1
- package/dist/pregel/runner.cjs.map +1 -1
- package/dist/pregel/runner.js +2 -2
- package/dist/pregel/runner.js.map +1 -1
- package/dist/state/prebuilt/messages.cjs +1 -1
- package/dist/state/prebuilt/messages.js +1 -1
- package/dist/web.cjs +3 -1
- package/dist/web.d.cts +2 -2
- package/dist/web.d.ts +2 -2
- package/dist/web.js +3 -3
- package/package.json +5 -5
package/dist/pregel/debug.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug.js","names":[],"sources":["../../src/pregel/debug.ts"],"sourcesContent":["import { RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n CheckpointMetadata,\n CheckpointPendingWrite,\n EXCLUDED_METADATA_KEYS,\n PendingWrite,\n} from \"@langchain/langgraph-checkpoint\";\nimport { BaseChannel } from \"../channels/base.js\";\nimport {\n ERROR,\n Interrupt,\n INTERRUPT,\n RETURN,\n TAG_HIDDEN,\n} from \"../constants.js\";\nimport { EmptyChannelError } from \"../errors.js\";\nimport {\n PregelExecutableTask,\n PregelTaskDescription,\n StateSnapshot,\n} from \"./types.js\";\nimport { readChannels } from \"./io.js\";\nimport { findSubgraphPregel } from \"./utils/subgraph.js\";\nimport { filterToUserTags } from \"./utils/config.js\";\n\ntype ConsoleColors = {\n start: string;\n end: string;\n};\n\ntype ConsoleColorMap = {\n [key: string]: ConsoleColors;\n};\n\nconst COLORS_MAP: ConsoleColorMap = {\n blue: {\n start: \"\\x1b[34m\",\n end: \"\\x1b[0m\",\n },\n green: {\n start: \"\\x1b[32m\",\n end: \"\\x1b[0m\",\n },\n yellow: {\n start: \"\\x1b[33;1m\",\n end: \"\\x1b[0m\",\n },\n};\n\n/**\n * Wrap some text in a color for printing to the console.\n */\nexport const wrap = (color: ConsoleColors, text: string): string =>\n `${color.start}${text}${color.end}`;\n\nexport function printCheckpoint<Value>(\n step: number,\n channels: Record<string, BaseChannel<Value>>\n) {\n console.log(\n [\n `${wrap(COLORS_MAP.blue, \"[langgraph/checkpoint]\")}`,\n `Finishing step ${step}. Channel values:\\n`,\n `\\n${JSON.stringify(\n Object.fromEntries(_readChannels<Value>(channels)),\n null,\n 2\n )}`,\n ].join(\"\")\n );\n}\n\nexport function* _readChannels<Value>(\n channels: Record<string, BaseChannel<Value>>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): IterableIterator<[string, any]> {\n for (const [name, channel] of Object.entries(channels)) {\n try {\n yield [name, channel.get()];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (error.name === EmptyChannelError.unminifiable_name) {\n // Skip the channel if it's empty\n continue;\n } else {\n throw error; // Re-throw the error if it's not an EmptyChannelError\n }\n }\n }\n}\n\n/**\n * Build the user-meaningful metadata to forward on a task's stream payload.\n *\n * Drops langgraph's internal framework keys ({@link EXCLUDED_METADATA_KEYS}) —\n * which are redundant with the task's own fields and namespace — while keeping\n * keys like `lc_agent_name`, `ls_integration`, and any user-supplied metadata.\n * Filtered config tags are folded in under `tags`, mirroring the messages\n * stream handler. Returns `undefined` when there is nothing to forward.\n */\nfunction buildTaskMetadata(\n config: RunnableConfig | undefined\n): Record<string, unknown> | undefined {\n if (config == null) return undefined;\n const metadata: Record<string, unknown> = {};\n if (config.metadata != null) {\n for (const [key, value] of Object.entries(config.metadata)) {\n if (!EXCLUDED_METADATA_KEYS.has(key)) metadata[key] = value;\n }\n }\n const filteredTags = filterToUserTags(config.tags);\n if (filteredTags != null) metadata.tags = filteredTags;\n return Object.keys(metadata).length > 0 ? metadata : undefined;\n}\n\nexport function* mapDebugTasks<N extends PropertyKey, C extends PropertyKey>(\n tasks: readonly PregelExecutableTask<N, C>[]\n) {\n for (const { id, name, input, config, triggers, writes } of tasks) {\n if (config?.tags?.includes(TAG_HIDDEN)) continue;\n\n const interrupts = writes\n .filter(([writeId, n]) => {\n return writeId === id && n === INTERRUPT;\n })\n .map(([, v]) => {\n return v;\n });\n const payload: {\n id: string;\n name: N;\n input: unknown;\n triggers: string[];\n interrupts: unknown[];\n metadata?: Record<string, unknown>;\n } = { id, name, input, triggers, interrupts };\n const metadata = buildTaskMetadata(config);\n if (metadata != null) payload.metadata = metadata;\n yield payload;\n }\n}\n\nfunction isMultipleChannelWrite(\n value: unknown\n): value is { $writes: unknown[] } {\n if (typeof value !== \"object\" || value === null) return false;\n return \"$writes\" in value && Array.isArray(value.$writes);\n}\n\nfunction mapTaskResultWrites(writes: PendingWrite<unknown>[]) {\n const result: Record<string, unknown> = {};\n\n for (const [channel, value] of writes) {\n const strChannel = String(channel);\n\n if (strChannel in result) {\n const channelWrites = isMultipleChannelWrite(result[strChannel])\n ? result[strChannel].$writes\n : [result[strChannel]];\n\n channelWrites.push(value);\n result[strChannel] = { $writes: channelWrites };\n } else {\n result[strChannel] = value;\n }\n }\n return result;\n}\n\nexport function* mapDebugTaskResults<\n N extends PropertyKey,\n C extends PropertyKey,\n>(\n tasks: readonly [PregelExecutableTask<N, C>, PendingWrite<C>[]][],\n streamChannels: PropertyKey | Array<PropertyKey>\n) {\n for (const [{ id, name, config }, writes] of tasks) {\n if (config?.tags?.includes(TAG_HIDDEN)) continue;\n yield {\n id,\n name,\n result: mapTaskResultWrites(\n writes.filter(([channel]) => {\n return Array.isArray(streamChannels)\n ? streamChannels.includes(channel)\n : channel === streamChannels;\n })\n ),\n interrupts: writes.filter((w) => w[0] === INTERRUPT).map((w) => w[1]),\n };\n }\n}\n\ntype ChannelKey = string | number | symbol;\n\nexport function* mapDebugCheckpoint<\n N extends PropertyKey,\n C extends PropertyKey,\n>(\n config: RunnableConfig,\n channels: Record<string, BaseChannel>,\n streamChannels: string | string[],\n metadata: CheckpointMetadata,\n tasks: readonly PregelExecutableTask<N, C>[],\n pendingWrites: CheckpointPendingWrite[],\n parentConfig: RunnableConfig | undefined,\n outputKeys: ChannelKey | ChannelKey[]\n) {\n function formatConfig(config: RunnableConfig) {\n // https://stackoverflow.com/a/78298178\n type CamelToSnake<\n T extends string,\n A extends string = \"\",\n > = T extends `${infer F}${infer R}`\n ? CamelToSnake<\n R,\n `${A}${F extends Lowercase<F> ? F : `_${Lowercase<F>}`}`\n >\n : A;\n\n // make sure the config is consistent with Python\n const pyConfig: Partial<\n Record<CamelToSnake<keyof RunnableConfig>, unknown>\n > = {};\n\n if (config.callbacks != null) pyConfig.callbacks = config.callbacks;\n if (config.configurable != null)\n pyConfig.configurable = config.configurable;\n if (config.maxConcurrency != null)\n pyConfig.max_concurrency = config.maxConcurrency;\n\n if (config.metadata != null) pyConfig.metadata = config.metadata;\n if (config.recursionLimit != null)\n pyConfig.recursion_limit = config.recursionLimit;\n if (config.runId != null) pyConfig.run_id = config.runId;\n if (config.runName != null) pyConfig.run_name = config.runName;\n if (config.tags != null) pyConfig.tags = config.tags;\n\n return pyConfig;\n }\n\n const parentNs = config.configurable?.checkpoint_ns;\n const taskStates: Record<string, RunnableConfig | StateSnapshot> = {};\n\n for (const task of tasks) {\n const candidates = task.subgraphs?.length ? task.subgraphs : [task.proc];\n if (!candidates.find(findSubgraphPregel)) continue;\n\n let taskNs = `${task.name as string}:${task.id}`;\n if (parentNs) taskNs = `${parentNs}|${taskNs}`;\n\n taskStates[task.id] = {\n configurable: {\n thread_id: config.configurable?.thread_id,\n checkpoint_ns: taskNs,\n },\n };\n }\n\n yield {\n config: formatConfig(config),\n values: readChannels(channels, streamChannels),\n metadata,\n next: tasks.map((task) => task.name),\n tasks: tasksWithWrites(tasks, pendingWrites, taskStates, outputKeys),\n parentConfig: parentConfig ? formatConfig(parentConfig) : undefined,\n };\n}\n\nexport function tasksWithWrites<N extends PropertyKey, C extends PropertyKey>(\n tasks: PregelTaskDescription[] | readonly PregelExecutableTask<N, C>[],\n pendingWrites: CheckpointPendingWrite[],\n states: Record<string, RunnableConfig | StateSnapshot> | undefined,\n outputKeys: ChannelKey[] | ChannelKey\n): PregelTaskDescription[] {\n return tasks.map((task): PregelTaskDescription => {\n const error = pendingWrites.find(\n ([id, n]) => id === task.id && n === ERROR\n )?.[2];\n\n const interrupts = pendingWrites\n .filter(([id, n]) => id === task.id && n === INTERRUPT)\n .map(([, , v]) => v) as Interrupt[];\n\n const result = (() => {\n if (error || interrupts.length || !pendingWrites.length) return undefined;\n\n const idx = pendingWrites.findIndex(\n ([tid, n]) => tid === task.id && n === RETURN\n );\n\n if (idx >= 0) return pendingWrites[idx][2];\n\n if (typeof outputKeys === \"string\") {\n return pendingWrites.find(\n ([tid, n]) => tid === task.id && n === outputKeys\n )?.[2];\n }\n\n if (Array.isArray(outputKeys)) {\n const results = pendingWrites\n .filter(([tid, n]) => tid === task.id && outputKeys.includes(n))\n .map(([, n, v]) => [n, v] as PendingWrite<C>);\n\n if (!results.length) return undefined;\n return mapTaskResultWrites(results);\n }\n\n return undefined;\n })();\n\n if (error) {\n return {\n id: task.id,\n name: task.name as string,\n path: task.path,\n error,\n interrupts,\n result,\n };\n }\n\n const taskState = states?.[task.id];\n return {\n id: task.id,\n name: task.name as string,\n path: task.path,\n interrupts,\n ...(taskState !== undefined ? { state: taskState } : {}),\n result,\n };\n });\n}\n\nexport function printStepCheckpoint(\n step: number,\n channels: Record<string, BaseChannel<unknown>>,\n whitelist: string[]\n): void {\n console.log(\n [\n `${wrap(COLORS_MAP.blue, `[${step}:checkpoint]`)}`,\n `\\x1b[1m State at the end of step ${step}:\\x1b[0m\\n`,\n JSON.stringify(readChannels(channels, whitelist), null, 2),\n ].join(\"\")\n );\n}\n\nexport function printStepTasks<N extends PropertyKey, C extends PropertyKey>(\n step: number,\n nextTasks: readonly PregelExecutableTask<N, C>[]\n): void {\n const nTasks = nextTasks.length;\n console.log(\n [\n `${wrap(COLORS_MAP.blue, `[${step}:tasks]`)}`,\n `\\x1b[1m Starting step ${step} with ${nTasks} task${\n nTasks === 1 ? \"\" : \"s\"\n }:\\x1b[0m\\n`,\n nextTasks\n .map(\n (task) =>\n `- ${wrap(COLORS_MAP.green, String(task.name))} -> ${JSON.stringify(\n task.input,\n null,\n 2\n )}`\n )\n .join(\"\\n\"),\n ].join(\"\")\n );\n}\n\nexport function printStepWrites(\n step: number,\n writes: PendingWrite[],\n whitelist: string[]\n): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const byChannel: Record<string, any[]> = {};\n\n for (const [channel, value] of writes) {\n if (whitelist.includes(channel)) {\n if (!byChannel[channel]) {\n byChannel[channel] = [];\n }\n byChannel[channel].push(value);\n }\n }\n\n console.log(\n [\n `${wrap(COLORS_MAP.blue, `[${step}:writes]`)}`,\n `\\x1b[1m Finished step ${step} with writes to ${\n Object.keys(byChannel).length\n } channel${Object.keys(byChannel).length !== 1 ? \"s\" : \"\"}:\\x1b[0m\\n`,\n Object.entries(byChannel)\n .map(\n ([name, vals]) =>\n `- ${wrap(COLORS_MAP.yellow, name)} -> ${vals\n .map((v) => JSON.stringify(v))\n .join(\", \")}`\n )\n .join(\"\\n\"),\n ].join(\"\")\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"debug.js","names":[],"sources":["../../src/pregel/debug.ts"],"sourcesContent":["import { RunnableConfig } from \"@langchain/core/runnables\";\nimport {\n CheckpointMetadata,\n CheckpointPendingWrite,\n EXCLUDED_METADATA_KEYS,\n PendingWrite,\n} from \"@langchain/langgraph-checkpoint\";\nimport { BaseChannel } from \"../channels/base.js\";\nimport {\n ERROR,\n Interrupt,\n INTERRUPT,\n RETURN,\n TAG_HIDDEN,\n} from \"../constants.js\";\nimport { EmptyChannelError } from \"../errors.js\";\nimport {\n PregelExecutableTask,\n PregelTaskDescription,\n StateSnapshot,\n} from \"./types.js\";\nimport { readChannels } from \"./io.js\";\nimport { findSubgraphPregel } from \"./utils/subgraph.js\";\nimport { filterToUserTags } from \"./utils/config.js\";\n\ntype ConsoleColors = {\n start: string;\n end: string;\n};\n\ntype ConsoleColorMap = {\n [key: string]: ConsoleColors;\n};\n\nconst COLORS_MAP: ConsoleColorMap = {\n blue: {\n start: \"\\x1b[34m\",\n end: \"\\x1b[0m\",\n },\n green: {\n start: \"\\x1b[32m\",\n end: \"\\x1b[0m\",\n },\n yellow: {\n start: \"\\x1b[33;1m\",\n end: \"\\x1b[0m\",\n },\n};\n\n/**\n * Wrap some text in a color for printing to the console.\n */\nexport const wrap = (color: ConsoleColors, text: string): string =>\n `${color.start}${text}${color.end}`;\n\nexport function printCheckpoint<Value>(\n step: number,\n channels: Record<string, BaseChannel<Value>>\n) {\n console.log(\n [\n `${wrap(COLORS_MAP.blue, \"[langgraph/checkpoint]\")}`,\n `Finishing step ${step}. Channel values:\\n`,\n `\\n${JSON.stringify(\n Object.fromEntries(_readChannels<Value>(channels)),\n null,\n 2\n )}`,\n ].join(\"\")\n );\n}\n\nexport function* _readChannels<Value>(\n channels: Record<string, BaseChannel<Value>>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): IterableIterator<[string, any]> {\n for (const [name, channel] of Object.entries(channels)) {\n try {\n yield [name, channel.get()];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (error: any) {\n if (error.name === EmptyChannelError.unminifiable_name) {\n // Skip the channel if it's empty\n continue;\n } else {\n throw error; // Re-throw the error if it's not an EmptyChannelError\n }\n }\n }\n}\n\n/**\n * Build the user-meaningful metadata to forward on a task's stream payload.\n *\n * Drops langgraph's internal framework keys ({@link EXCLUDED_METADATA_KEYS}) —\n * which are redundant with the task's own fields and namespace — while keeping\n * keys like `lc_agent_name`, `ls_integration`, and any user-supplied metadata.\n * Filtered config tags are folded in under `tags`, mirroring the messages\n * stream handler. Returns `undefined` when there is nothing to forward.\n */\nfunction buildTaskMetadata(\n config: RunnableConfig | undefined\n): Record<string, unknown> | undefined {\n if (config == null) return undefined;\n const metadata: Record<string, unknown> = {};\n if (config.metadata != null) {\n for (const [key, value] of Object.entries(config.metadata)) {\n if (!EXCLUDED_METADATA_KEYS.has(key)) metadata[key] = value;\n }\n }\n const filteredTags = filterToUserTags(config.tags);\n if (filteredTags != null) metadata.tags = filteredTags;\n return Object.keys(metadata).length > 0 ? metadata : undefined;\n}\n\nexport function* mapDebugTasks<N extends PropertyKey, C extends PropertyKey>(\n tasks: readonly PregelExecutableTask<N, C>[]\n) {\n for (const { id, name, input, config, triggers, writes } of tasks) {\n if (config?.tags?.includes(TAG_HIDDEN)) continue;\n\n const interrupts = writes\n .filter(([writeId, n]) => {\n return writeId === id && n === INTERRUPT;\n })\n .map(([, v]) => {\n return v;\n });\n const payload: {\n id: string;\n name: N;\n input: unknown;\n triggers: string[];\n interrupts: unknown[];\n metadata?: Record<string, unknown>;\n } = { id, name, input, triggers, interrupts };\n const metadata = buildTaskMetadata(config);\n if (metadata != null) payload.metadata = metadata;\n yield payload;\n }\n}\n\nfunction isMultipleChannelWrite(\n value: unknown\n): value is { $writes: unknown[] } {\n if (typeof value !== \"object\" || value === null) return false;\n return \"$writes\" in value && Array.isArray(value.$writes);\n}\n\nfunction mapTaskResultWrites(writes: PendingWrite<unknown>[]) {\n const result: Record<string, unknown> = {};\n\n for (const [channel, value] of writes) {\n const strChannel = String(channel);\n\n if (strChannel in result) {\n const channelWrites = isMultipleChannelWrite(result[strChannel])\n ? result[strChannel].$writes\n : [result[strChannel]];\n\n channelWrites.push(value);\n result[strChannel] = { $writes: channelWrites };\n } else {\n result[strChannel] = value;\n }\n }\n return result;\n}\n\nexport function* mapDebugTaskResults<\n N extends PropertyKey,\n C extends PropertyKey,\n>(\n tasks: readonly [PregelExecutableTask<N, C>, PendingWrite<C>[]][],\n streamChannels: PropertyKey | Array<PropertyKey>\n) {\n for (const [{ id, name, config }, writes] of tasks) {\n if (config?.tags?.includes(TAG_HIDDEN)) continue;\n yield {\n id,\n name,\n result: mapTaskResultWrites(\n writes.filter(([channel]) => {\n return Array.isArray(streamChannels)\n ? streamChannels.includes(channel)\n : channel === streamChannels;\n })\n ),\n interrupts: writes.filter((w) => w[0] === INTERRUPT).map((w) => w[1]),\n };\n }\n}\n\ntype ChannelKey = string | number | symbol;\n\nexport function* mapDebugCheckpoint<\n N extends PropertyKey,\n C extends PropertyKey,\n>(\n config: RunnableConfig,\n channels: Record<string, BaseChannel>,\n streamChannels: string | string[],\n metadata: CheckpointMetadata,\n tasks: readonly PregelExecutableTask<N, C>[],\n pendingWrites: CheckpointPendingWrite[],\n parentConfig: RunnableConfig | undefined,\n outputKeys: ChannelKey | ChannelKey[]\n) {\n function formatConfig(config: RunnableConfig) {\n // https://stackoverflow.com/a/78298178\n type CamelToSnake<\n T extends string,\n A extends string = \"\",\n > = T extends `${infer F}${infer R}`\n ? CamelToSnake<\n R,\n `${A}${F extends Lowercase<F> ? F : `_${Lowercase<F>}`}`\n >\n : A;\n\n // make sure the config is consistent with Python\n const pyConfig: Partial<\n Record<CamelToSnake<keyof RunnableConfig>, unknown>\n > = {};\n\n if (config.callbacks != null) pyConfig.callbacks = config.callbacks;\n if (config.configurable != null)\n pyConfig.configurable = config.configurable;\n if (config.maxConcurrency != null)\n pyConfig.max_concurrency = config.maxConcurrency;\n\n if (config.metadata != null) pyConfig.metadata = config.metadata;\n if (config.recursionLimit != null)\n pyConfig.recursion_limit = config.recursionLimit;\n if (config.runId != null) pyConfig.run_id = config.runId;\n if (config.runName != null) pyConfig.run_name = config.runName;\n if (config.tags != null) pyConfig.tags = config.tags;\n\n return pyConfig;\n }\n\n const parentNs = config.configurable?.checkpoint_ns;\n const taskStates: Record<string, RunnableConfig | StateSnapshot> = {};\n\n for (const task of tasks) {\n const candidates = task.subgraphs?.length ? task.subgraphs : [task.proc];\n if (!candidates.find(findSubgraphPregel)) continue;\n\n let taskNs = `${task.name as string}:${task.id}`;\n if (parentNs) taskNs = `${parentNs}|${taskNs}`;\n\n taskStates[task.id] = {\n configurable: {\n thread_id: config.configurable?.thread_id,\n checkpoint_ns: taskNs,\n },\n };\n }\n\n yield {\n config: formatConfig(config),\n values: readChannels(channels, streamChannels),\n metadata,\n next: tasks.map((task) => task.name),\n tasks: tasksWithWrites(tasks, pendingWrites, taskStates, outputKeys),\n parentConfig: parentConfig ? formatConfig(parentConfig) : undefined,\n };\n}\n\nexport function tasksWithWrites<N extends PropertyKey, C extends PropertyKey>(\n tasks: PregelTaskDescription[] | readonly PregelExecutableTask<N, C>[],\n pendingWrites: CheckpointPendingWrite[],\n states: Record<string, RunnableConfig | StateSnapshot> | undefined,\n outputKeys: ChannelKey[] | ChannelKey\n): PregelTaskDescription[] {\n return tasks.map((task): PregelTaskDescription => {\n const error = pendingWrites.find(\n ([id, n]) => id === task.id && n === ERROR\n )?.[2];\n\n const interrupts = pendingWrites\n .filter(([id, n]) => id === task.id && n === INTERRUPT)\n .map(([, , v]) => v) as Interrupt[];\n\n const result = (() => {\n if (error || interrupts.length || !pendingWrites.length) return undefined;\n\n const idx = pendingWrites.findIndex(\n ([tid, n]) => tid === task.id && n === RETURN\n );\n\n if (idx >= 0) return pendingWrites[idx][2];\n\n if (typeof outputKeys === \"string\") {\n return pendingWrites.find(\n ([tid, n]) => tid === task.id && n === outputKeys\n )?.[2];\n }\n\n if (Array.isArray(outputKeys)) {\n const results = pendingWrites\n .filter(([tid, n]) => tid === task.id && outputKeys.includes(n))\n .map(([, n, v]) => [n, v] as PendingWrite<C>);\n\n if (!results.length) return undefined;\n return mapTaskResultWrites(results);\n }\n\n return undefined;\n })();\n\n if (error) {\n return {\n id: task.id,\n name: task.name as string,\n path: task.path,\n error,\n interrupts,\n result,\n };\n }\n\n const taskState = states?.[task.id];\n return {\n id: task.id,\n name: task.name as string,\n path: task.path,\n interrupts,\n ...(taskState !== undefined ? { state: taskState } : {}),\n result,\n };\n });\n}\n\nexport function printStepCheckpoint(\n step: number,\n channels: Record<string, BaseChannel<unknown>>,\n whitelist: string[]\n): void {\n console.log(\n [\n `${wrap(COLORS_MAP.blue, `[${step}:checkpoint]`)}`,\n `\\x1b[1m State at the end of step ${step}:\\x1b[0m\\n`,\n JSON.stringify(readChannels(channels, whitelist), null, 2),\n ].join(\"\")\n );\n}\n\nexport function printStepTasks<N extends PropertyKey, C extends PropertyKey>(\n step: number,\n nextTasks: readonly PregelExecutableTask<N, C>[]\n): void {\n const nTasks = nextTasks.length;\n console.log(\n [\n `${wrap(COLORS_MAP.blue, `[${step}:tasks]`)}`,\n `\\x1b[1m Starting step ${step} with ${nTasks} task${\n nTasks === 1 ? \"\" : \"s\"\n }:\\x1b[0m\\n`,\n nextTasks\n .map(\n (task) =>\n `- ${wrap(COLORS_MAP.green, String(task.name))} -> ${JSON.stringify(\n task.input,\n null,\n 2\n )}`\n )\n .join(\"\\n\"),\n ].join(\"\")\n );\n}\n\nexport function printStepWrites(\n step: number,\n writes: PendingWrite[],\n whitelist: string[]\n): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const byChannel: Record<string, any[]> = {};\n\n for (const [channel, value] of writes) {\n if (whitelist.includes(channel)) {\n if (!byChannel[channel]) {\n byChannel[channel] = [];\n }\n byChannel[channel].push(value);\n }\n }\n\n console.log(\n [\n `${wrap(COLORS_MAP.blue, `[${step}:writes]`)}`,\n `\\x1b[1m Finished step ${step} with writes to ${\n Object.keys(byChannel).length\n } channel${Object.keys(byChannel).length !== 1 ? \"s\" : \"\"}:\\x1b[0m\\n`,\n Object.entries(byChannel)\n .map(\n ([name, vals]) =>\n `- ${wrap(COLORS_MAP.yellow, name)} -> ${vals\n .map((v) => JSON.stringify(v))\n .join(\", \")}`\n )\n .join(\"\\n\"),\n ].join(\"\")\n );\n}\n"],"mappings":"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"}
|
package/dist/pregel/index.cjs
CHANGED
|
@@ -7,6 +7,7 @@ const require_utils = require("../utils.cjs");
|
|
|
7
7
|
const require_write = require("./write.cjs");
|
|
8
8
|
const require_read = require("./read.cjs");
|
|
9
9
|
const require_callbacks = require("./callbacks.cjs");
|
|
10
|
+
const require_checkpoint = require("./checkpoint.cjs");
|
|
10
11
|
const require_runtime = require("./runtime.cjs");
|
|
11
12
|
const require_io = require("./io.cjs");
|
|
12
13
|
const require_index = require("./utils/index.cjs");
|
|
@@ -639,7 +640,7 @@ var Pregel = class extends PartialRunnable {
|
|
|
639
640
|
}
|
|
640
641
|
const checkpointNamespace = startConfig.configurable?.checkpoint_ns ?? "";
|
|
641
642
|
if (checkpointNamespace !== "" && startConfig.configurable?.["__pregel_read"] === void 0 && startConfig.configurable?.["__pregel_checkpointer"] === void 0) throw new Error(`Subgraph "${require_config.recastCheckpointNamespace(checkpointNamespace)}" not found`);
|
|
642
|
-
const updateSuperStep = async (inputConfig, updates) => {
|
|
643
|
+
const updateSuperStep = async (inputConfig, updates, isFirstSuperstep) => {
|
|
643
644
|
const config = this._ownCheckpointConfig(this.config ? (0, _langchain_core_runnables.mergeConfigs)(this.config, inputConfig) : inputConfig);
|
|
644
645
|
const saved = await checkpointer.getTuple(config);
|
|
645
646
|
const checkpoint = saved !== void 0 ? (0, _langchain_langgraph_checkpoint.copyCheckpoint)(saved.checkpoint) : (0, _langchain_langgraph_checkpoint.emptyCheckpoint)();
|
|
@@ -656,21 +657,46 @@ var Pregel = class extends PartialRunnable {
|
|
|
656
657
|
}
|
|
657
658
|
const deltaWritesVersioned = Object.values(this.channels).some(require_base.isDeltaChannel) && (saved === void 0 || require_base.isDeltaWritesVersioned(saved.metadata));
|
|
658
659
|
const versionedMetadata = deltaWritesVersioned ? { [require_base.DELTA_WRITES_VERSIONED]: true } : {};
|
|
660
|
+
const getNextVersion = (current) => checkpointer.getNextVersion(current);
|
|
661
|
+
const writtenChannels = () => new Set(Object.keys(require_index.getNewChannelVersions(checkpointPreviousVersions, checkpoint.channel_versions)));
|
|
662
|
+
const forkPending = isFirstSuperstep ? require_base.deltaChannelsWithPendingWrites(this.channels, saved?.pendingWrites) : /* @__PURE__ */ new Set();
|
|
663
|
+
const editsOlderCheckpoint = async () => isFirstSuperstep && saved !== void 0 && await require_checkpoint.checkpointSuperseded(checkpointer, config, saved);
|
|
664
|
+
const specs = this.channels;
|
|
665
|
+
const sealDeltaWrites = (writes) => {
|
|
666
|
+
for (const [ch] of require_base.deltaChannelWrites(specs, writes)) forkPending.add(String(ch));
|
|
667
|
+
};
|
|
668
|
+
const sealOverwrites = (writes) => {
|
|
669
|
+
for (const [ch, value] of require_base.deltaChannelWrites(specs, writes)) if (require_constants._isOverwriteValue(value)) forkPending.add(String(ch));
|
|
670
|
+
};
|
|
671
|
+
const loadChannels = () => require_base.channelsFromCheckpoint(this.channels, checkpoint, {
|
|
672
|
+
saver: checkpointer,
|
|
673
|
+
config: saved?.config ?? checkpointConfig,
|
|
674
|
+
deltaWritesVersioned
|
|
675
|
+
});
|
|
659
676
|
const { values, asNode } = updates[0];
|
|
660
677
|
if (values == null && asNode === void 0) {
|
|
661
678
|
if (updates.length > 1) throw new require_errors.InvalidUpdateError(`Cannot create empty checkpoint with multiple updates`);
|
|
662
|
-
|
|
679
|
+
const counters = saved === void 0 ? {} : require_checkpoint.advanceDeltaCounters(this.channels, /* @__PURE__ */ new Set(), saved.metadata?.counters_since_delta_snapshot);
|
|
680
|
+
const channels = forkPending.size > 0 || Object.entries(counters).some(([name, count]) => require_base.reachedSnapshotBound(this.channels[name], count)) ? await loadChannels() : void 0;
|
|
681
|
+
const { channelsToSnapshot, metadata: countersMetadata } = channels === void 0 ? {
|
|
682
|
+
channelsToSnapshot: /* @__PURE__ */ new Set(),
|
|
683
|
+
metadata: require_checkpoint.deltaCountersMetadata(counters)
|
|
684
|
+
} : require_checkpoint.updateStateDeltaPlan(channels, /* @__PURE__ */ new Set(), saved, checkpoint.channel_versions, deltaWritesVersioned, forkPending);
|
|
685
|
+
const nextCheckpoint = require_base.createCheckpoint(checkpoint, channels, step, {
|
|
686
|
+
channelsToSnapshot,
|
|
687
|
+
storedVersions: checkpointPreviousVersions,
|
|
688
|
+
getNextVersion,
|
|
689
|
+
triggerToNodes: this.triggerToNodes
|
|
690
|
+
});
|
|
691
|
+
return require_index.patchCheckpointMap(await checkpointer.put(checkpointConfig, nextCheckpoint, {
|
|
663
692
|
source: "update",
|
|
664
693
|
step: step + 1,
|
|
665
694
|
parents: saved?.metadata?.parents ?? {},
|
|
666
|
-
...versionedMetadata
|
|
667
|
-
|
|
695
|
+
...versionedMetadata,
|
|
696
|
+
...countersMetadata
|
|
697
|
+
}, require_index.getNewChannelVersions(checkpointPreviousVersions, nextCheckpoint.channel_versions)), saved ? saved.metadata : void 0);
|
|
668
698
|
}
|
|
669
|
-
const channels = await
|
|
670
|
-
saver: checkpointer,
|
|
671
|
-
config: saved?.config ?? checkpointConfig,
|
|
672
|
-
deltaWritesVersioned
|
|
673
|
-
});
|
|
699
|
+
const channels = await loadChannels();
|
|
674
700
|
if (values === null && asNode === "__end__") {
|
|
675
701
|
if (updates.length > 1) throw new require_errors.InvalidUpdateError(`Cannot apply multiple updates when clearing state`);
|
|
676
702
|
if (saved) {
|
|
@@ -696,14 +722,22 @@ var Pregel = class extends PartialRunnable {
|
|
|
696
722
|
}
|
|
697
723
|
require_algo._applyWrites(checkpoint, channels, Object.values(nextTasks), checkpointer.getNextVersion.bind(checkpointer), this.triggerToNodes);
|
|
698
724
|
}
|
|
699
|
-
const {
|
|
700
|
-
|
|
725
|
+
const { channelsToSnapshot, metadata: countersMetadata } = require_checkpoint.updateStateDeltaPlan(channels, writtenChannels(), saved, checkpoint.channel_versions, deltaWritesVersioned, forkPending);
|
|
726
|
+
const nextCheckpoint = require_base.createCheckpoint(checkpoint, channels, step, {
|
|
727
|
+
channelsToSnapshot,
|
|
728
|
+
storedVersions: checkpointPreviousVersions,
|
|
729
|
+
getNextVersion,
|
|
730
|
+
triggerToNodes: this.triggerToNodes
|
|
731
|
+
});
|
|
732
|
+
const { [require_base.DELTA_WRITES_VERSIONED]: _carried, counters_since_delta_snapshot: _counters, ...endMetadata } = checkpointMetadata;
|
|
733
|
+
return require_index.patchCheckpointMap(await checkpointer.put(checkpointConfig, nextCheckpoint, {
|
|
701
734
|
...endMetadata,
|
|
702
735
|
source: "update",
|
|
703
736
|
step: step + 1,
|
|
704
737
|
parents: saved?.metadata?.parents ?? {},
|
|
705
|
-
...versionedMetadata
|
|
706
|
-
|
|
738
|
+
...versionedMetadata,
|
|
739
|
+
...countersMetadata
|
|
740
|
+
}, require_index.getNewChannelVersions(checkpointPreviousVersions, nextCheckpoint.channel_versions)), saved ? saved.metadata : void 0);
|
|
707
741
|
}
|
|
708
742
|
if (asNode === "__copy__") {
|
|
709
743
|
if (updates.length > 1) throw new require_errors.InvalidUpdateError(`Cannot copy checkpoint with multiple updates`);
|
|
@@ -718,7 +752,8 @@ var Pregel = class extends PartialRunnable {
|
|
|
718
752
|
source: "fork",
|
|
719
753
|
step: step + 1,
|
|
720
754
|
parents: saved.metadata?.parents ?? {},
|
|
721
|
-
...versionedMetadata
|
|
755
|
+
...versionedMetadata,
|
|
756
|
+
...require_checkpoint.deltaCountersMetadata(saved.metadata?.counters_since_delta_snapshot ?? {})
|
|
722
757
|
}, {});
|
|
723
758
|
if (isCopyWithUpdates(values)) {
|
|
724
759
|
const nextTasks = require_algo._prepareNextTasks(nextCheckpoint, saved.pendingWrites, this.nodes, channels, nextConfig, false, { step: step + 2 });
|
|
@@ -739,7 +774,7 @@ var Pregel = class extends PartialRunnable {
|
|
|
739
774
|
});
|
|
740
775
|
return acc;
|
|
741
776
|
}, {});
|
|
742
|
-
return updateSuperStep(require_index.patchCheckpointMap(nextConfig, saved.metadata), Object.values(userGroupBy).flat());
|
|
777
|
+
return updateSuperStep(require_index.patchCheckpointMap(nextConfig, saved.metadata), Object.values(userGroupBy).flat(), false);
|
|
743
778
|
}
|
|
744
779
|
return require_index.patchCheckpointMap(nextConfig, saved.metadata);
|
|
745
780
|
}
|
|
@@ -747,20 +782,30 @@ var Pregel = class extends PartialRunnable {
|
|
|
747
782
|
if (updates.length > 1) throw new require_errors.InvalidUpdateError(`Cannot apply multiple updates when updating as input`);
|
|
748
783
|
const inputWrites = await require_utils.gatherIterator(require_io.mapInput(this.inputChannels, values));
|
|
749
784
|
if (inputWrites.length === 0) throw new require_errors.InvalidUpdateError(`Received no input writes for ${JSON.stringify(this.inputChannels, null, 2)}`);
|
|
785
|
+
require_loop.ensureDeltaMessageIds(specs, inputWrites);
|
|
786
|
+
if (await editsOlderCheckpoint()) sealDeltaWrites(inputWrites);
|
|
787
|
+
else if (saved !== void 0) await checkpointer.putWrites(checkpointConfig, inputWrites, (0, _langchain_langgraph_checkpoint.uuid5)(require_constants.INPUT, checkpoint.id));
|
|
750
788
|
require_algo._applyWrites(checkpoint, channels, [{
|
|
751
789
|
name: require_constants.INPUT,
|
|
752
790
|
writes: inputWrites,
|
|
753
791
|
triggers: []
|
|
754
792
|
}], checkpointer.getNextVersion.bind(checkpointer), this.triggerToNodes);
|
|
793
|
+
sealOverwrites(inputWrites);
|
|
755
794
|
const nextStep = saved?.metadata?.step != null ? saved.metadata.step + 1 : -1;
|
|
756
|
-
const
|
|
795
|
+
const { channelsToSnapshot, metadata: countersMetadata } = require_checkpoint.updateStateDeltaPlan(channels, writtenChannels(), saved, checkpoint.channel_versions, deltaWritesVersioned, forkPending);
|
|
796
|
+
const nextCheckpoint = require_base.createCheckpoint(checkpoint, channels, nextStep, {
|
|
797
|
+
channelsToSnapshot,
|
|
798
|
+
storedVersions: checkpointPreviousVersions,
|
|
799
|
+
getNextVersion,
|
|
800
|
+
triggerToNodes: this.triggerToNodes
|
|
801
|
+
});
|
|
802
|
+
return require_index.patchCheckpointMap(await checkpointer.put(checkpointConfig, nextCheckpoint, {
|
|
757
803
|
source: "input",
|
|
758
804
|
step: nextStep,
|
|
759
805
|
parents: saved?.metadata?.parents ?? {},
|
|
760
|
-
...versionedMetadata
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
return require_index.patchCheckpointMap(nextConfig, saved ? saved.metadata : void 0);
|
|
806
|
+
...versionedMetadata,
|
|
807
|
+
...countersMetadata
|
|
808
|
+
}, require_index.getNewChannelVersions(checkpointPreviousVersions, nextCheckpoint.channel_versions)), saved ? saved.metadata : void 0);
|
|
764
809
|
}
|
|
765
810
|
if (config.configurable?.checkpoint_id === void 0 && saved?.pendingWrites !== void 0 && saved.pendingWrites.length > 0) {
|
|
766
811
|
const nextTasks = require_algo._prepareNextTasks(checkpoint, saved.pendingWrites, this.nodes, channels, saved.config, true, {
|
|
@@ -787,7 +832,8 @@ var Pregel = class extends PartialRunnable {
|
|
|
787
832
|
});
|
|
788
833
|
if (tasks.length > 0) require_algo._applyWrites(checkpoint, channels, tasks, checkpointer.getNextVersion.bind(checkpointer), this.triggerToNodes);
|
|
789
834
|
}
|
|
790
|
-
const
|
|
835
|
+
const versionsSeen = require_base.versionsSeenWithoutBumps(checkpoint.versions_seen);
|
|
836
|
+
const nonNullVersion = Object.values(versionsSeen).map((seenVersions) => {
|
|
791
837
|
return Object.values(seenVersions);
|
|
792
838
|
}).flat().find((v) => !!v);
|
|
793
839
|
const validUpdates = [];
|
|
@@ -797,7 +843,7 @@ var Pregel = class extends PartialRunnable {
|
|
|
797
843
|
else if (asNode === void 0 && nonNullVersion === void 0) {
|
|
798
844
|
if (typeof this.inputChannels === "string" && this.nodes[this.inputChannels] !== void 0) asNode = this.inputChannels;
|
|
799
845
|
} else if (asNode === void 0) {
|
|
800
|
-
const lastSeenByNode = Object.entries(
|
|
846
|
+
const lastSeenByNode = Object.entries(versionsSeen).map(([n, seen]) => {
|
|
801
847
|
return Object.values(seen).map((v) => {
|
|
802
848
|
return [v, n];
|
|
803
849
|
});
|
|
@@ -832,6 +878,7 @@ var Pregel = class extends PartialRunnable {
|
|
|
832
878
|
proc: writers.length > 1 ? _langchain_core_runnables.RunnableSequence.from(writers, { omitSequenceTags: true }) : writers[0],
|
|
833
879
|
writes: [],
|
|
834
880
|
triggers: [require_constants.INTERRUPT],
|
|
881
|
+
path: [require_constants.INTERRUPT, i],
|
|
835
882
|
id: taskId ?? (0, _langchain_langgraph_checkpoint.uuid5)(i === 0 ? "__interrupt__" : `__interrupt__:${i}`, checkpoint.id),
|
|
836
883
|
writers: []
|
|
837
884
|
});
|
|
@@ -846,22 +893,28 @@ var Pregel = class extends PartialRunnable {
|
|
|
846
893
|
[require_constants.CONFIG_KEY_READ]: (select_, fresh_ = false) => require_algo._localRead(checkpoint, channels, task, select_, fresh_)
|
|
847
894
|
}
|
|
848
895
|
}));
|
|
849
|
-
for (const task of tasks)
|
|
896
|
+
for (const task of tasks) require_loop.ensureDeltaMessageIds(specs, task.writes);
|
|
897
|
+
if (await editsOlderCheckpoint()) for (const task of tasks) sealDeltaWrites(task.writes);
|
|
898
|
+
else for (const task of tasks) {
|
|
850
899
|
const channelWrites = task.writes.filter((w) => w[0] !== require_constants.PUSH);
|
|
851
|
-
if (saved !== void 0 && channelWrites.length > 0) await checkpointer.putWrites(checkpointConfig, channelWrites, task.id);
|
|
900
|
+
if (saved !== void 0 && channelWrites.length > 0) await checkpointer.putWrites(checkpointConfig, channelWrites, task.id, require_algo.taskPathStr(task.path));
|
|
852
901
|
}
|
|
853
902
|
require_algo._applyWrites(checkpoint, channels, tasks, checkpointer.getNextVersion.bind(checkpointer), this.triggerToNodes);
|
|
854
|
-
const
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
903
|
+
for (const task of tasks) sealOverwrites(task.writes);
|
|
904
|
+
const { channelsToSnapshot, metadata: countersMetadata } = require_checkpoint.updateStateDeltaPlan(channels, writtenChannels(), saved, checkpoint.channel_versions, deltaWritesVersioned, forkPending);
|
|
905
|
+
const nextCheckpoint = require_base.createCheckpoint(checkpoint, channels, step + 1, {
|
|
906
|
+
channelsToSnapshot,
|
|
907
|
+
storedVersions: checkpointPreviousVersions,
|
|
908
|
+
getNextVersion,
|
|
909
|
+
triggerToNodes: this.triggerToNodes
|
|
910
|
+
});
|
|
911
|
+
const nextConfig = await checkpointer.put(checkpointConfig, nextCheckpoint, {
|
|
860
912
|
source: "update",
|
|
861
913
|
step: step + 1,
|
|
862
914
|
parents: saved?.metadata?.parents ?? {},
|
|
863
|
-
...versionedMetadata
|
|
864
|
-
|
|
915
|
+
...versionedMetadata,
|
|
916
|
+
...countersMetadata
|
|
917
|
+
}, require_index.getNewChannelVersions(checkpointPreviousVersions, nextCheckpoint.channel_versions));
|
|
865
918
|
for (const task of tasks) {
|
|
866
919
|
const pushWrites = task.writes.filter((w) => w[0] === require_constants.PUSH);
|
|
867
920
|
if (pushWrites.length > 0) await checkpointer.putWrites(nextConfig, pushWrites, task.id);
|
|
@@ -869,7 +922,7 @@ var Pregel = class extends PartialRunnable {
|
|
|
869
922
|
return require_index.patchCheckpointMap(nextConfig, saved ? saved.metadata : void 0);
|
|
870
923
|
};
|
|
871
924
|
let currentConfig = startConfig;
|
|
872
|
-
for (const { updates } of supersteps) currentConfig = await updateSuperStep(currentConfig, updates);
|
|
925
|
+
for (const [i, { updates }] of supersteps.entries()) currentConfig = await updateSuperStep(currentConfig, updates, i === 0);
|
|
873
926
|
return currentConfig;
|
|
874
927
|
}
|
|
875
928
|
/**
|
|
@@ -1258,7 +1311,7 @@ var Pregel = class extends PartialRunnable {
|
|
|
1258
1311
|
try {
|
|
1259
1312
|
while (await loop.tick({ inputKeys: this.inputChannels })) {
|
|
1260
1313
|
if (emitLifecycleEvents) await emitLifecycleEvents(loop.lifecycleEvents);
|
|
1261
|
-
for (const { task } of await loop._matchCachedWrites()) loop.
|
|
1314
|
+
for (const { task } of await loop._matchCachedWrites()) loop.putWrites(task.id, task.writes, true);
|
|
1262
1315
|
if (debug) require_debug.printStepCheckpoint(loop.checkpointMetadata.step, loop.channels, this.streamChannelsList);
|
|
1263
1316
|
if (debug) require_debug.printStepTasks(loop.step, Object.values(loop.tasks));
|
|
1264
1317
|
await runner.tick({
|