@langchain/langgraph 1.3.6 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/channels/base.cjs +78 -2
- package/dist/channels/base.cjs.map +1 -1
- package/dist/channels/base.d.cts +35 -2
- package/dist/channels/base.d.cts.map +1 -1
- package/dist/channels/base.d.ts +35 -2
- package/dist/channels/base.d.ts.map +1 -1
- package/dist/channels/base.js +77 -4
- package/dist/channels/base.js.map +1 -1
- package/dist/channels/delta.cjs +136 -0
- package/dist/channels/delta.cjs.map +1 -0
- package/dist/channels/delta.d.cts +99 -0
- package/dist/channels/delta.d.cts.map +1 -0
- package/dist/channels/delta.d.ts +99 -0
- package/dist/channels/delta.d.ts.map +1 -0
- package/dist/channels/delta.js +136 -0
- package/dist/channels/delta.js.map +1 -0
- package/dist/channels/index.cjs +5 -0
- package/dist/channels/index.d.cts +3 -2
- package/dist/channels/index.d.ts +3 -2
- package/dist/channels/index.js +3 -2
- package/dist/constants.cjs +62 -4
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +33 -2
- package/dist/constants.d.cts.map +1 -1
- package/dist/constants.d.ts +33 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +59 -5
- package/dist/constants.js.map +1 -1
- package/dist/errors.cjs +128 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +86 -1
- package/dist/errors.d.cts.map +1 -1
- package/dist/errors.d.ts +86 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +123 -1
- package/dist/errors.js.map +1 -1
- package/dist/func/index.cjs +9 -2
- package/dist/func/index.cjs.map +1 -1
- package/dist/func/index.d.cts +14 -0
- package/dist/func/index.d.cts.map +1 -1
- package/dist/func/index.d.ts +14 -0
- package/dist/func/index.d.ts.map +1 -1
- package/dist/func/index.js +9 -2
- package/dist/func/index.js.map +1 -1
- package/dist/graph/graph.cjs +44 -7
- package/dist/graph/graph.cjs.map +1 -1
- package/dist/graph/graph.d.cts +24 -2
- package/dist/graph/graph.d.cts.map +1 -1
- package/dist/graph/graph.d.ts +24 -2
- package/dist/graph/graph.d.ts.map +1 -1
- package/dist/graph/graph.js +44 -7
- package/dist/graph/graph.js.map +1 -1
- package/dist/graph/index.d.ts +3 -3
- package/dist/graph/messages_reducer.cjs +55 -0
- package/dist/graph/messages_reducer.cjs.map +1 -1
- package/dist/graph/messages_reducer.d.cts +28 -1
- package/dist/graph/messages_reducer.d.cts.map +1 -1
- package/dist/graph/messages_reducer.d.ts +28 -1
- package/dist/graph/messages_reducer.d.ts.map +1 -1
- package/dist/graph/messages_reducer.js +56 -2
- package/dist/graph/messages_reducer.js.map +1 -1
- package/dist/graph/state.cjs +174 -7
- package/dist/graph/state.cjs.map +1 -1
- package/dist/graph/state.d.cts +193 -17
- package/dist/graph/state.d.cts.map +1 -1
- package/dist/graph/state.d.ts +193 -17
- package/dist/graph/state.d.ts.map +1 -1
- package/dist/graph/state.js +175 -8
- package/dist/graph/state.js.map +1 -1
- package/dist/graph/zod/schema.cjs +5 -0
- package/dist/graph/zod/schema.cjs.map +1 -1
- package/dist/graph/zod/schema.d.cts.map +1 -1
- package/dist/graph/zod/schema.d.ts.map +1 -1
- package/dist/graph/zod/schema.js +5 -0
- package/dist/graph/zod/schema.js.map +1 -1
- package/dist/index.cjs +11 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -8
- package/dist/index.d.ts +11 -8
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/prebuilt/react_agent_executor.d.cts +1 -1
- package/dist/pregel/algo.cjs +182 -21
- package/dist/pregel/algo.cjs.map +1 -1
- package/dist/pregel/algo.d.cts +1 -1
- package/dist/pregel/algo.d.cts.map +1 -1
- package/dist/pregel/algo.d.ts +1 -1
- package/dist/pregel/algo.d.ts.map +1 -1
- package/dist/pregel/algo.js +185 -25
- package/dist/pregel/algo.js.map +1 -1
- package/dist/pregel/call.cjs +2 -1
- package/dist/pregel/call.cjs.map +1 -1
- package/dist/pregel/call.js +2 -1
- package/dist/pregel/call.js.map +1 -1
- package/dist/pregel/index.cjs +15 -3
- 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 +17 -5
- package/dist/pregel/index.js.map +1 -1
- package/dist/pregel/loop.cjs +362 -41
- package/dist/pregel/loop.cjs.map +1 -1
- package/dist/pregel/loop.js +365 -44
- package/dist/pregel/loop.js.map +1 -1
- package/dist/pregel/messages-v2.cjs +1 -1
- package/dist/pregel/messages-v2.js +1 -1
- package/dist/pregel/messages.cjs +1 -1
- package/dist/pregel/messages.js +1 -1
- package/dist/pregel/read.cjs +15 -5
- package/dist/pregel/read.cjs.map +1 -1
- package/dist/pregel/read.d.cts +9 -0
- package/dist/pregel/read.d.cts.map +1 -1
- package/dist/pregel/read.d.ts +9 -0
- package/dist/pregel/read.d.ts.map +1 -1
- package/dist/pregel/read.js +15 -5
- package/dist/pregel/read.js.map +1 -1
- package/dist/pregel/remote-run-stream.cjs +107 -0
- package/dist/pregel/remote-run-stream.cjs.map +1 -0
- package/dist/pregel/remote-run-stream.d.cts +33 -0
- package/dist/pregel/remote-run-stream.d.cts.map +1 -0
- package/dist/pregel/remote-run-stream.d.ts +33 -0
- package/dist/pregel/remote-run-stream.d.ts.map +1 -0
- package/dist/pregel/remote-run-stream.js +107 -0
- package/dist/pregel/remote-run-stream.js.map +1 -0
- package/dist/pregel/remote.cjs +61 -1
- package/dist/pregel/remote.cjs.map +1 -1
- package/dist/pregel/remote.d.cts +17 -0
- package/dist/pregel/remote.d.cts.map +1 -1
- package/dist/pregel/remote.d.ts +17 -0
- package/dist/pregel/remote.d.ts.map +1 -1
- package/dist/pregel/remote.js +61 -1
- package/dist/pregel/remote.js.map +1 -1
- package/dist/pregel/replay.cjs +62 -0
- package/dist/pregel/replay.cjs.map +1 -0
- package/dist/pregel/replay.js +62 -0
- package/dist/pregel/replay.js.map +1 -0
- package/dist/pregel/retry.cjs +8 -6
- package/dist/pregel/retry.cjs.map +1 -1
- package/dist/pregel/retry.js +8 -6
- package/dist/pregel/retry.js.map +1 -1
- package/dist/pregel/runnable_types.d.cts +20 -0
- package/dist/pregel/runnable_types.d.cts.map +1 -1
- package/dist/pregel/runnable_types.d.ts +20 -0
- package/dist/pregel/runnable_types.d.ts.map +1 -1
- package/dist/pregel/runner.cjs +48 -7
- package/dist/pregel/runner.cjs.map +1 -1
- package/dist/pregel/runner.js +50 -9
- package/dist/pregel/runner.js.map +1 -1
- package/dist/pregel/runtime.cjs +64 -0
- package/dist/pregel/runtime.cjs.map +1 -0
- package/dist/pregel/runtime.d.cts +57 -0
- package/dist/pregel/runtime.d.cts.map +1 -0
- package/dist/pregel/runtime.d.ts +57 -0
- package/dist/pregel/runtime.d.ts.map +1 -0
- package/dist/pregel/runtime.js +64 -0
- package/dist/pregel/runtime.js.map +1 -0
- package/dist/pregel/stream.cjs +2 -0
- package/dist/pregel/stream.cjs.map +1 -1
- package/dist/pregel/stream.js +2 -0
- package/dist/pregel/stream.js.map +1 -1
- package/dist/pregel/timeout.cjs +216 -0
- package/dist/pregel/timeout.cjs.map +1 -0
- package/dist/pregel/timeout.js +216 -0
- package/dist/pregel/timeout.js.map +1 -0
- package/dist/pregel/types.cjs +3 -1
- package/dist/pregel/types.cjs.map +1 -1
- package/dist/pregel/types.d.cts +13 -0
- package/dist/pregel/types.d.cts.map +1 -1
- package/dist/pregel/types.d.ts +14 -1
- package/dist/pregel/types.d.ts.map +1 -1
- package/dist/pregel/types.js +3 -1
- package/dist/pregel/types.js.map +1 -1
- package/dist/pregel/utils/config.cjs +3 -1
- 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 +3 -1
- package/dist/pregel/utils/config.js.map +1 -1
- package/dist/pregel/utils/index.cjs +1 -0
- package/dist/pregel/utils/index.cjs.map +1 -1
- package/dist/pregel/utils/index.d.cts +6 -1
- package/dist/pregel/utils/index.d.cts.map +1 -1
- package/dist/pregel/utils/index.d.ts +6 -1
- package/dist/pregel/utils/index.d.ts.map +1 -1
- package/dist/pregel/utils/index.js +1 -0
- package/dist/pregel/utils/index.js.map +1 -1
- package/dist/pregel/utils/timeout.cjs +34 -0
- package/dist/pregel/utils/timeout.cjs.map +1 -0
- package/dist/pregel/utils/timeout.d.cts +45 -0
- package/dist/pregel/utils/timeout.d.cts.map +1 -0
- package/dist/pregel/utils/timeout.d.ts +45 -0
- package/dist/pregel/utils/timeout.d.ts.map +1 -0
- package/dist/pregel/utils/timeout.js +34 -0
- package/dist/pregel/utils/timeout.js.map +1 -0
- package/dist/stream/index.cjs +1 -0
- package/dist/stream/index.d.cts +2 -1
- package/dist/stream/index.d.ts +2 -1
- package/dist/stream/index.js +1 -0
- package/dist/stream/stream-channel.d.cts +9 -1
- package/dist/stream/stream-channel.d.cts.map +1 -1
- package/dist/stream/stream-channel.d.ts +9 -1
- package/dist/stream/stream-channel.d.ts.map +1 -1
- package/dist/stream/subscription.cjs +136 -0
- package/dist/stream/subscription.cjs.map +1 -0
- package/dist/stream/subscription.d.cts +94 -0
- package/dist/stream/subscription.d.cts.map +1 -0
- package/dist/stream/subscription.d.ts +94 -0
- package/dist/stream/subscription.d.ts.map +1 -0
- package/dist/stream/subscription.js +131 -0
- package/dist/stream/subscription.js.map +1 -0
- package/dist/stream/types.d.cts +1 -1
- package/dist/stream/types.d.ts +1 -1
- package/dist/stream.cjs +16 -0
- package/dist/stream.d.cts +5 -0
- package/dist/stream.d.ts +5 -0
- package/dist/stream.js +4 -0
- package/dist/web.cjs +11 -0
- package/dist/web.d.cts +11 -8
- package/dist/web.d.ts +11 -8
- package/dist/web.js +5 -3
- package/package.json +18 -6
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import "../constants.js";
|
|
2
|
+
//#region src/pregel/replay.ts
|
|
3
|
+
/**
|
|
4
|
+
* Tracks subgraph checkpoint loading during parent-graph time travel.
|
|
5
|
+
*
|
|
6
|
+
* When a parent replays from a historical checkpoint, nested subgraphs must
|
|
7
|
+
* load the checkpoint that existed *before* the replay point on their first
|
|
8
|
+
* visit, then fall back to normal latest-checkpoint loading on later visits
|
|
9
|
+
* within the same run.
|
|
10
|
+
*/
|
|
11
|
+
var ReplayState = class {
|
|
12
|
+
/** Parent checkpoint ID used as the `before` cursor for subgraph lookups. */
|
|
13
|
+
checkpointId;
|
|
14
|
+
#visitedNs = /* @__PURE__ */ new Set();
|
|
15
|
+
/**
|
|
16
|
+
* @param checkpointId - Checkpoint ID from the parent graph at the replay point.
|
|
17
|
+
*/
|
|
18
|
+
constructor(checkpointId) {
|
|
19
|
+
this.checkpointId = checkpointId;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Whether this is the first visit to a logical subgraph namespace in the run.
|
|
23
|
+
*
|
|
24
|
+
* Task-id suffixes are stripped so the same subgraph invoked across loop
|
|
25
|
+
* iterations shares one visit record.
|
|
26
|
+
*
|
|
27
|
+
* @param checkpointNs - Subgraph checkpoint namespace.
|
|
28
|
+
*/
|
|
29
|
+
#isFirstVisit(checkpointNs) {
|
|
30
|
+
const stableNs = checkpointNs.includes(":") ? checkpointNs.slice(0, checkpointNs.lastIndexOf(":")) : checkpointNs;
|
|
31
|
+
if (this.#visitedNs.has(stableNs)) return false;
|
|
32
|
+
this.#visitedNs.add(stableNs);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Load the checkpoint tuple for a subgraph namespace during replay.
|
|
37
|
+
*
|
|
38
|
+
* On the first visit to `checkpointNs`, returns the latest checkpoint saved
|
|
39
|
+
* before {@link ReplayState.checkpointId}. On subsequent visits, delegates to
|
|
40
|
+
* `checkpointer.getTuple` for the current config.
|
|
41
|
+
*
|
|
42
|
+
* @param checkpointNs - Subgraph checkpoint namespace.
|
|
43
|
+
* @param checkpointer - Checkpointer shared with the parent graph.
|
|
44
|
+
* @param checkpointConfig - Runnable config for the subgraph lookup.
|
|
45
|
+
* @returns The resolved checkpoint tuple, if any.
|
|
46
|
+
*/
|
|
47
|
+
async getCheckpoint(checkpointNs, checkpointer, checkpointConfig) {
|
|
48
|
+
if (this.#isFirstVisit(checkpointNs)) {
|
|
49
|
+
const results = [];
|
|
50
|
+
for await (const saved of checkpointer.list(checkpointConfig, {
|
|
51
|
+
before: { configurable: { checkpoint_id: this.checkpointId } },
|
|
52
|
+
limit: 1
|
|
53
|
+
})) results.push(saved);
|
|
54
|
+
return results.length > 0 ? results[0] : void 0;
|
|
55
|
+
}
|
|
56
|
+
return await checkpointer.getTuple(checkpointConfig) ?? void 0;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
export { ReplayState };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.js","names":["#visitedNs","#isFirstVisit"],"sources":["../../src/pregel/replay.ts"],"sourcesContent":["import type {\n BaseCheckpointSaver,\n CheckpointTuple,\n} from \"@langchain/langgraph-checkpoint\";\nimport type { RunnableConfig } from \"@langchain/core/runnables\";\nimport { CHECKPOINT_NAMESPACE_END } from \"../constants.js\";\n\n/**\n * Tracks subgraph checkpoint loading during parent-graph time travel.\n *\n * When a parent replays from a historical checkpoint, nested subgraphs must\n * load the checkpoint that existed *before* the replay point on their first\n * visit, then fall back to normal latest-checkpoint loading on later visits\n * within the same run.\n */\nexport class ReplayState {\n /** Parent checkpoint ID used as the `before` cursor for subgraph lookups. */\n checkpointId: string;\n\n #visitedNs: Set<string> = new Set();\n\n /**\n * @param checkpointId - Checkpoint ID from the parent graph at the replay point.\n */\n constructor(checkpointId: string) {\n this.checkpointId = checkpointId;\n }\n\n /**\n * Whether this is the first visit to a logical subgraph namespace in the run.\n *\n * Task-id suffixes are stripped so the same subgraph invoked across loop\n * iterations shares one visit record.\n *\n * @param checkpointNs - Subgraph checkpoint namespace.\n */\n #isFirstVisit(checkpointNs: string): boolean {\n const stableNs = checkpointNs.includes(CHECKPOINT_NAMESPACE_END)\n ? checkpointNs.slice(\n 0,\n checkpointNs.lastIndexOf(CHECKPOINT_NAMESPACE_END)\n )\n : checkpointNs;\n if (this.#visitedNs.has(stableNs)) {\n return false;\n }\n this.#visitedNs.add(stableNs);\n return true;\n }\n\n /**\n * Load the checkpoint tuple for a subgraph namespace during replay.\n *\n * On the first visit to `checkpointNs`, returns the latest checkpoint saved\n * before {@link ReplayState.checkpointId}. On subsequent visits, delegates to\n * `checkpointer.getTuple` for the current config.\n *\n * @param checkpointNs - Subgraph checkpoint namespace.\n * @param checkpointer - Checkpointer shared with the parent graph.\n * @param checkpointConfig - Runnable config for the subgraph lookup.\n * @returns The resolved checkpoint tuple, if any.\n */\n async getCheckpoint(\n checkpointNs: string,\n checkpointer: BaseCheckpointSaver,\n checkpointConfig: RunnableConfig\n ): Promise<CheckpointTuple | undefined> {\n if (this.#isFirstVisit(checkpointNs)) {\n const results: CheckpointTuple[] = [];\n for await (const saved of checkpointer.list(checkpointConfig, {\n before: {\n configurable: { checkpoint_id: this.checkpointId },\n },\n limit: 1,\n })) {\n results.push(saved);\n }\n return results.length > 0 ? results[0] : undefined;\n }\n return (await checkpointer.getTuple(checkpointConfig)) ?? undefined;\n }\n}\n"],"mappings":";;;;;;;;;;AAeA,IAAa,cAAb,MAAyB;;CAEvB;CAEA,6BAA0B,IAAI,KAAK;;;;CAKnC,YAAY,cAAsB;AAChC,OAAK,eAAe;;;;;;;;;;CAWtB,cAAc,cAA+B;EAC3C,MAAM,WAAW,aAAa,SAAA,IAAkC,GAC5D,aAAa,MACX,GACA,aAAa,YAAA,IAAqC,CACnD,GACD;AACJ,MAAI,MAAA,UAAgB,IAAI,SAAS,CAC/B,QAAO;AAET,QAAA,UAAgB,IAAI,SAAS;AAC7B,SAAO;;;;;;;;;;;;;;CAeT,MAAM,cACJ,cACA,cACA,kBACsC;AACtC,MAAI,MAAA,aAAmB,aAAa,EAAE;GACpC,MAAM,UAA6B,EAAE;AACrC,cAAW,MAAM,SAAS,aAAa,KAAK,kBAAkB;IAC5D,QAAQ,EACN,cAAc,EAAE,eAAe,KAAK,cAAc,EACnD;IACD,OAAO;IACR,CAAC,CACA,SAAQ,KAAK,MAAM;AAErB,UAAO,QAAQ,SAAS,IAAI,QAAQ,KAAK,KAAA;;AAE3C,SAAQ,MAAM,aAAa,SAAS,iBAAiB,IAAK,KAAA"}
|
package/dist/pregel/retry.cjs
CHANGED
|
@@ -2,6 +2,7 @@ const require_constants = require("../constants.cjs");
|
|
|
2
2
|
const require_errors = require("../errors.cjs");
|
|
3
3
|
const require_config = require("./utils/config.cjs");
|
|
4
4
|
const require_index = require("./utils/index.cjs");
|
|
5
|
+
const require_timeout = require("./timeout.cjs");
|
|
5
6
|
const DEFAULT_STATUS_NO_RETRY = [
|
|
6
7
|
400,
|
|
7
8
|
401,
|
|
@@ -24,7 +25,6 @@ const DEFAULT_RETRY_ON_HANDLER = (error) => {
|
|
|
24
25
|
};
|
|
25
26
|
async function _runWithRetry(pregelTask, retryPolicy, configurable, signal) {
|
|
26
27
|
const resolvedRetryPolicy = pregelTask.retry_policy ?? retryPolicy;
|
|
27
|
-
let interval = resolvedRetryPolicy !== void 0 ? resolvedRetryPolicy.initialInterval ?? 500 : 0;
|
|
28
28
|
let attempts = 0;
|
|
29
29
|
let error;
|
|
30
30
|
let result;
|
|
@@ -44,7 +44,8 @@ async function _runWithRetry(pregelTask, retryPolicy, configurable, signal) {
|
|
|
44
44
|
pregelTask.writes.splice(0, pregelTask.writes.length);
|
|
45
45
|
error = void 0;
|
|
46
46
|
try {
|
|
47
|
-
result = await pregelTask.proc.invoke(pregelTask.input,
|
|
47
|
+
if (pregelTask.timeout !== void 0) result = await require_timeout.runAttemptWithTimeout(pregelTask, config, pregelTask.timeout, (scopedConfig) => pregelTask.proc.invoke(pregelTask.input, scopedConfig));
|
|
48
|
+
else result = await pregelTask.proc.invoke(pregelTask.input, config);
|
|
48
49
|
break;
|
|
49
50
|
} catch (e) {
|
|
50
51
|
error = e;
|
|
@@ -69,11 +70,12 @@ async function _runWithRetry(pregelTask, retryPolicy, configurable, signal) {
|
|
|
69
70
|
attempts += 1;
|
|
70
71
|
if (attempts >= (resolvedRetryPolicy.maxAttempts ?? 3)) break;
|
|
71
72
|
if (!(resolvedRetryPolicy.retryOn ?? DEFAULT_RETRY_ON_HANDLER)(error)) break;
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
73
|
+
const initialInterval = resolvedRetryPolicy.initialInterval ?? 500;
|
|
74
|
+
const interval = Math.min(resolvedRetryPolicy.maxInterval ?? 128e3, initialInterval * (resolvedRetryPolicy.backoffFactor ?? 2) ** (attempts - 1));
|
|
75
|
+
const sleepMs = resolvedRetryPolicy.jitter ?? true ? interval + Math.random() * 1e3 : interval;
|
|
76
|
+
await new Promise((resolve) => setTimeout(resolve, sleepMs));
|
|
75
77
|
const errorName = error.name ?? error.constructor.unminifiable_name ?? error.constructor.name;
|
|
76
|
-
if (resolvedRetryPolicy?.logWarning ?? true) console.log(`Retrying task "${String(pregelTask.name)}" after ${
|
|
78
|
+
if (resolvedRetryPolicy?.logWarning ?? true) console.log(`Retrying task "${String(pregelTask.name)}" after ${sleepMs.toFixed(2)}ms (attempt ${attempts}) after ${errorName}: ${error}`);
|
|
77
79
|
config = require_index.patchConfigurable(config, { [require_constants.CONFIG_KEY_RESUMING]: true });
|
|
78
80
|
if (config.executionInfo != null) config.executionInfo = {
|
|
79
81
|
...config.executionInfo,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.cjs","names":["patchConfigurable","isParentCommand","Command","getParentCheckpointNamespace","isGraphBubbleUp","CONFIG_KEY_RESUMING"],"sources":["../../src/pregel/retry.ts"],"sourcesContent":["import { Command, CONFIG_KEY_RESUMING } from \"../constants.js\";\nimport { isGraphBubbleUp, isParentCommand } from \"../errors.js\";\nimport type { LangGraphRunnableConfig } from \"./runnable_types.js\";\nimport { PregelExecutableTask } from \"./types.js\";\nimport { getParentCheckpointNamespace } from \"./utils/config.js\";\nimport { patchConfigurable, type RetryPolicy } from \"./utils/index.js\";\n\nexport const DEFAULT_INITIAL_INTERVAL = 500;\nexport const DEFAULT_BACKOFF_FACTOR = 2;\nexport const DEFAULT_MAX_INTERVAL = 128000;\nexport const DEFAULT_MAX_RETRIES = 3;\n\nconst DEFAULT_STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment Required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 409, // Conflict\n];\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst DEFAULT_RETRY_ON_HANDLER = (error: any) => {\n if (\n error.message.startsWith(\"Cancel\") ||\n error.message.startsWith(\"AbortError\") ||\n error.name === \"AbortError\"\n ) {\n return false;\n }\n\n // Thrown when interrupt is called without a checkpointer\n if (error.name === \"GraphValueError\") {\n return false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n return false;\n }\n\n const status =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (error as any)?.response?.status ?? (error as any)?.status;\n if (status && DEFAULT_STATUS_NO_RETRY.includes(+status)) {\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.error?.code === \"insufficient_quota\") {\n return false;\n }\n return true;\n};\n\nexport type SettledPregelTask = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n task: PregelExecutableTask<any, any>;\n error: Error;\n signalAborted?: boolean;\n};\n\nexport async function _runWithRetry<\n N extends PropertyKey,\n C extends PropertyKey,\n>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n pregelTask: PregelExecutableTask<N, C>,\n retryPolicy?: RetryPolicy,\n configurable?: Record<string, unknown>,\n signal?: AbortSignal\n): Promise<{\n task: PregelExecutableTask<N, C>;\n result: unknown;\n error: Error | undefined;\n signalAborted?: boolean;\n}> {\n const resolvedRetryPolicy = pregelTask.retry_policy ?? retryPolicy;\n let
|
|
1
|
+
{"version":3,"file":"retry.cjs","names":["patchConfigurable","runAttemptWithTimeout","isParentCommand","Command","getParentCheckpointNamespace","isGraphBubbleUp","CONFIG_KEY_RESUMING"],"sources":["../../src/pregel/retry.ts"],"sourcesContent":["import { Command, CONFIG_KEY_RESUMING } from \"../constants.js\";\nimport { isGraphBubbleUp, isParentCommand } from \"../errors.js\";\nimport type { LangGraphRunnableConfig } from \"./runnable_types.js\";\nimport { runAttemptWithTimeout } from \"./timeout.js\";\nimport { PregelExecutableTask } from \"./types.js\";\nimport { getParentCheckpointNamespace } from \"./utils/config.js\";\nimport { patchConfigurable, type RetryPolicy } from \"./utils/index.js\";\n\nexport const DEFAULT_INITIAL_INTERVAL = 500;\nexport const DEFAULT_BACKOFF_FACTOR = 2;\nexport const DEFAULT_MAX_INTERVAL = 128000;\nexport const DEFAULT_MAX_RETRIES = 3;\nexport const DEFAULT_JITTER = true;\n\nconst DEFAULT_STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment Required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 409, // Conflict\n];\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst DEFAULT_RETRY_ON_HANDLER = (error: any) => {\n if (\n error.message.startsWith(\"Cancel\") ||\n error.message.startsWith(\"AbortError\") ||\n error.name === \"AbortError\"\n ) {\n return false;\n }\n\n // Thrown when interrupt is called without a checkpointer\n if (error.name === \"GraphValueError\") {\n return false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n return false;\n }\n\n const status =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (error as any)?.response?.status ?? (error as any)?.status;\n if (status && DEFAULT_STATUS_NO_RETRY.includes(+status)) {\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.error?.code === \"insufficient_quota\") {\n return false;\n }\n return true;\n};\n\nexport type SettledPregelTask = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n task: PregelExecutableTask<any, any>;\n error: Error;\n signalAborted?: boolean;\n};\n\nexport async function _runWithRetry<\n N extends PropertyKey,\n C extends PropertyKey,\n>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n pregelTask: PregelExecutableTask<N, C>,\n retryPolicy?: RetryPolicy,\n configurable?: Record<string, unknown>,\n signal?: AbortSignal\n): Promise<{\n task: PregelExecutableTask<N, C>;\n result: unknown;\n error: Error | undefined;\n signalAborted?: boolean;\n}> {\n const resolvedRetryPolicy = pregelTask.retry_policy ?? retryPolicy;\n let attempts = 0;\n let error;\n let result;\n\n let config: LangGraphRunnableConfig = pregelTask.config ?? {};\n if (configurable) {\n config = patchConfigurable(config, configurable);\n }\n config = { ...config, signal };\n\n const firstAttemptTime = Date.now();\n if (config.executionInfo != null) {\n config.executionInfo = {\n ...config.executionInfo,\n nodeFirstAttemptTime: firstAttemptTime,\n };\n }\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (signal?.aborted) {\n // no need to throw here - we'll throw from the runner, instead.\n // there's just no point in retrying if the user has requested an abort.\n break;\n }\n // Clear any writes from previous attempts\n pregelTask.writes.splice(0, pregelTask.writes.length);\n error = undefined;\n try {\n if (pregelTask.timeout !== undefined) {\n // Enforce a per-attempt timeout. The timer resets on each retry since\n // a fresh attempt scope is created here per iteration.\n result = await runAttemptWithTimeout(\n pregelTask as PregelExecutableTask<string, string>,\n config,\n pregelTask.timeout,\n (scopedConfig) =>\n pregelTask.proc.invoke(pregelTask.input, scopedConfig)\n );\n } else {\n result = await pregelTask.proc.invoke(pregelTask.input, config);\n }\n break;\n } catch (e: unknown) {\n error = e;\n (error as { pregelTaskId: string }).pregelTaskId = pregelTask.id;\n if (isParentCommand(error)) {\n const ns: string = config?.configurable?.checkpoint_ns;\n const cmd = error.command;\n if (cmd.graph === ns) {\n // this command is for the current graph, handle it\n for (const writer of pregelTask.writers) {\n await writer.invoke(cmd, config);\n }\n error = undefined;\n break;\n } else if (cmd.graph === Command.PARENT) {\n // this command is for the parent graph, assign it to the parent\n const parentNs = getParentCheckpointNamespace(ns);\n error.command = new Command({\n ...error.command,\n graph: parentNs,\n });\n }\n }\n if (isGraphBubbleUp(error)) {\n break;\n }\n if (resolvedRetryPolicy === undefined) {\n break;\n }\n attempts += 1;\n // check if we should give up\n if (\n attempts >= (resolvedRetryPolicy.maxAttempts ?? DEFAULT_MAX_RETRIES)\n ) {\n break;\n }\n const retryOn = resolvedRetryPolicy.retryOn ?? DEFAULT_RETRY_ON_HANDLER;\n if (!retryOn(error)) {\n break;\n }\n const initialInterval =\n resolvedRetryPolicy.initialInterval ?? DEFAULT_INITIAL_INTERVAL;\n const interval = Math.min(\n resolvedRetryPolicy.maxInterval ?? DEFAULT_MAX_INTERVAL,\n initialInterval *\n (resolvedRetryPolicy.backoffFactor ?? DEFAULT_BACKOFF_FACTOR) **\n (attempts - 1)\n );\n const sleepMs =\n (resolvedRetryPolicy.jitter ?? DEFAULT_JITTER)\n ? interval + Math.random() * 1000\n : interval;\n // sleep before retrying\n // eslint-disable-next-line no-promise-executor-return\n await new Promise((resolve) => setTimeout(resolve, sleepMs));\n // log the retry\n const errorName =\n (error as Error).name ??\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((error as Error).constructor as any).unminifiable_name ??\n (error as Error).constructor.name;\n if (resolvedRetryPolicy?.logWarning ?? true) {\n console.log(\n `Retrying task \"${String(pregelTask.name)}\" after ${sleepMs.toFixed(\n 2\n )}ms (attempt ${attempts}) after ${errorName}: ${error}`\n );\n }\n\n // signal subgraphs to resume (if available)\n config = patchConfigurable(config, { [CONFIG_KEY_RESUMING]: true });\n\n if (config.executionInfo != null) {\n config.executionInfo = {\n ...config.executionInfo,\n nodeAttempt: attempts + 1,\n nodeFirstAttemptTime: firstAttemptTime,\n };\n }\n }\n }\n return {\n task: pregelTask,\n result,\n error: error as Error | undefined,\n signalAborted: signal?.aborted,\n };\n}\n"],"mappings":"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"}
|
package/dist/pregel/retry.js
CHANGED
|
@@ -2,6 +2,7 @@ import { CONFIG_KEY_RESUMING, Command } from "../constants.js";
|
|
|
2
2
|
import { isGraphBubbleUp, isParentCommand } from "../errors.js";
|
|
3
3
|
import { getParentCheckpointNamespace } from "./utils/config.js";
|
|
4
4
|
import { patchConfigurable } from "./utils/index.js";
|
|
5
|
+
import { runAttemptWithTimeout } from "./timeout.js";
|
|
5
6
|
const DEFAULT_STATUS_NO_RETRY = [
|
|
6
7
|
400,
|
|
7
8
|
401,
|
|
@@ -24,7 +25,6 @@ const DEFAULT_RETRY_ON_HANDLER = (error) => {
|
|
|
24
25
|
};
|
|
25
26
|
async function _runWithRetry(pregelTask, retryPolicy, configurable, signal) {
|
|
26
27
|
const resolvedRetryPolicy = pregelTask.retry_policy ?? retryPolicy;
|
|
27
|
-
let interval = resolvedRetryPolicy !== void 0 ? resolvedRetryPolicy.initialInterval ?? 500 : 0;
|
|
28
28
|
let attempts = 0;
|
|
29
29
|
let error;
|
|
30
30
|
let result;
|
|
@@ -44,7 +44,8 @@ async function _runWithRetry(pregelTask, retryPolicy, configurable, signal) {
|
|
|
44
44
|
pregelTask.writes.splice(0, pregelTask.writes.length);
|
|
45
45
|
error = void 0;
|
|
46
46
|
try {
|
|
47
|
-
result = await pregelTask.proc.invoke(pregelTask.input,
|
|
47
|
+
if (pregelTask.timeout !== void 0) result = await runAttemptWithTimeout(pregelTask, config, pregelTask.timeout, (scopedConfig) => pregelTask.proc.invoke(pregelTask.input, scopedConfig));
|
|
48
|
+
else result = await pregelTask.proc.invoke(pregelTask.input, config);
|
|
48
49
|
break;
|
|
49
50
|
} catch (e) {
|
|
50
51
|
error = e;
|
|
@@ -69,11 +70,12 @@ async function _runWithRetry(pregelTask, retryPolicy, configurable, signal) {
|
|
|
69
70
|
attempts += 1;
|
|
70
71
|
if (attempts >= (resolvedRetryPolicy.maxAttempts ?? 3)) break;
|
|
71
72
|
if (!(resolvedRetryPolicy.retryOn ?? DEFAULT_RETRY_ON_HANDLER)(error)) break;
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
73
|
+
const initialInterval = resolvedRetryPolicy.initialInterval ?? 500;
|
|
74
|
+
const interval = Math.min(resolvedRetryPolicy.maxInterval ?? 128e3, initialInterval * (resolvedRetryPolicy.backoffFactor ?? 2) ** (attempts - 1));
|
|
75
|
+
const sleepMs = resolvedRetryPolicy.jitter ?? true ? interval + Math.random() * 1e3 : interval;
|
|
76
|
+
await new Promise((resolve) => setTimeout(resolve, sleepMs));
|
|
75
77
|
const errorName = error.name ?? error.constructor.unminifiable_name ?? error.constructor.name;
|
|
76
|
-
if (resolvedRetryPolicy?.logWarning ?? true) console.log(`Retrying task "${String(pregelTask.name)}" after ${
|
|
78
|
+
if (resolvedRetryPolicy?.logWarning ?? true) console.log(`Retrying task "${String(pregelTask.name)}" after ${sleepMs.toFixed(2)}ms (attempt ${attempts}) after ${errorName}: ${error}`);
|
|
77
79
|
config = patchConfigurable(config, { [CONFIG_KEY_RESUMING]: true });
|
|
78
80
|
if (config.executionInfo != null) config.executionInfo = {
|
|
79
81
|
...config.executionInfo,
|
package/dist/pregel/retry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.js","names":[],"sources":["../../src/pregel/retry.ts"],"sourcesContent":["import { Command, CONFIG_KEY_RESUMING } from \"../constants.js\";\nimport { isGraphBubbleUp, isParentCommand } from \"../errors.js\";\nimport type { LangGraphRunnableConfig } from \"./runnable_types.js\";\nimport { PregelExecutableTask } from \"./types.js\";\nimport { getParentCheckpointNamespace } from \"./utils/config.js\";\nimport { patchConfigurable, type RetryPolicy } from \"./utils/index.js\";\n\nexport const DEFAULT_INITIAL_INTERVAL = 500;\nexport const DEFAULT_BACKOFF_FACTOR = 2;\nexport const DEFAULT_MAX_INTERVAL = 128000;\nexport const DEFAULT_MAX_RETRIES = 3;\n\nconst DEFAULT_STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment Required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 409, // Conflict\n];\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst DEFAULT_RETRY_ON_HANDLER = (error: any) => {\n if (\n error.message.startsWith(\"Cancel\") ||\n error.message.startsWith(\"AbortError\") ||\n error.name === \"AbortError\"\n ) {\n return false;\n }\n\n // Thrown when interrupt is called without a checkpointer\n if (error.name === \"GraphValueError\") {\n return false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n return false;\n }\n\n const status =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (error as any)?.response?.status ?? (error as any)?.status;\n if (status && DEFAULT_STATUS_NO_RETRY.includes(+status)) {\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.error?.code === \"insufficient_quota\") {\n return false;\n }\n return true;\n};\n\nexport type SettledPregelTask = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n task: PregelExecutableTask<any, any>;\n error: Error;\n signalAborted?: boolean;\n};\n\nexport async function _runWithRetry<\n N extends PropertyKey,\n C extends PropertyKey,\n>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n pregelTask: PregelExecutableTask<N, C>,\n retryPolicy?: RetryPolicy,\n configurable?: Record<string, unknown>,\n signal?: AbortSignal\n): Promise<{\n task: PregelExecutableTask<N, C>;\n result: unknown;\n error: Error | undefined;\n signalAborted?: boolean;\n}> {\n const resolvedRetryPolicy = pregelTask.retry_policy ?? retryPolicy;\n let
|
|
1
|
+
{"version":3,"file":"retry.js","names":[],"sources":["../../src/pregel/retry.ts"],"sourcesContent":["import { Command, CONFIG_KEY_RESUMING } from \"../constants.js\";\nimport { isGraphBubbleUp, isParentCommand } from \"../errors.js\";\nimport type { LangGraphRunnableConfig } from \"./runnable_types.js\";\nimport { runAttemptWithTimeout } from \"./timeout.js\";\nimport { PregelExecutableTask } from \"./types.js\";\nimport { getParentCheckpointNamespace } from \"./utils/config.js\";\nimport { patchConfigurable, type RetryPolicy } from \"./utils/index.js\";\n\nexport const DEFAULT_INITIAL_INTERVAL = 500;\nexport const DEFAULT_BACKOFF_FACTOR = 2;\nexport const DEFAULT_MAX_INTERVAL = 128000;\nexport const DEFAULT_MAX_RETRIES = 3;\nexport const DEFAULT_JITTER = true;\n\nconst DEFAULT_STATUS_NO_RETRY = [\n 400, // Bad Request\n 401, // Unauthorized\n 402, // Payment Required\n 403, // Forbidden\n 404, // Not Found\n 405, // Method Not Allowed\n 406, // Not Acceptable\n 407, // Proxy Authentication Required\n 409, // Conflict\n];\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst DEFAULT_RETRY_ON_HANDLER = (error: any) => {\n if (\n error.message.startsWith(\"Cancel\") ||\n error.message.startsWith(\"AbortError\") ||\n error.name === \"AbortError\"\n ) {\n return false;\n }\n\n // Thrown when interrupt is called without a checkpointer\n if (error.name === \"GraphValueError\") {\n return false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.code === \"ECONNABORTED\") {\n return false;\n }\n\n const status =\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (error as any)?.response?.status ?? (error as any)?.status;\n if (status && DEFAULT_STATUS_NO_RETRY.includes(+status)) {\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if ((error as any)?.error?.code === \"insufficient_quota\") {\n return false;\n }\n return true;\n};\n\nexport type SettledPregelTask = {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n task: PregelExecutableTask<any, any>;\n error: Error;\n signalAborted?: boolean;\n};\n\nexport async function _runWithRetry<\n N extends PropertyKey,\n C extends PropertyKey,\n>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n pregelTask: PregelExecutableTask<N, C>,\n retryPolicy?: RetryPolicy,\n configurable?: Record<string, unknown>,\n signal?: AbortSignal\n): Promise<{\n task: PregelExecutableTask<N, C>;\n result: unknown;\n error: Error | undefined;\n signalAborted?: boolean;\n}> {\n const resolvedRetryPolicy = pregelTask.retry_policy ?? retryPolicy;\n let attempts = 0;\n let error;\n let result;\n\n let config: LangGraphRunnableConfig = pregelTask.config ?? {};\n if (configurable) {\n config = patchConfigurable(config, configurable);\n }\n config = { ...config, signal };\n\n const firstAttemptTime = Date.now();\n if (config.executionInfo != null) {\n config.executionInfo = {\n ...config.executionInfo,\n nodeFirstAttemptTime: firstAttemptTime,\n };\n }\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (signal?.aborted) {\n // no need to throw here - we'll throw from the runner, instead.\n // there's just no point in retrying if the user has requested an abort.\n break;\n }\n // Clear any writes from previous attempts\n pregelTask.writes.splice(0, pregelTask.writes.length);\n error = undefined;\n try {\n if (pregelTask.timeout !== undefined) {\n // Enforce a per-attempt timeout. The timer resets on each retry since\n // a fresh attempt scope is created here per iteration.\n result = await runAttemptWithTimeout(\n pregelTask as PregelExecutableTask<string, string>,\n config,\n pregelTask.timeout,\n (scopedConfig) =>\n pregelTask.proc.invoke(pregelTask.input, scopedConfig)\n );\n } else {\n result = await pregelTask.proc.invoke(pregelTask.input, config);\n }\n break;\n } catch (e: unknown) {\n error = e;\n (error as { pregelTaskId: string }).pregelTaskId = pregelTask.id;\n if (isParentCommand(error)) {\n const ns: string = config?.configurable?.checkpoint_ns;\n const cmd = error.command;\n if (cmd.graph === ns) {\n // this command is for the current graph, handle it\n for (const writer of pregelTask.writers) {\n await writer.invoke(cmd, config);\n }\n error = undefined;\n break;\n } else if (cmd.graph === Command.PARENT) {\n // this command is for the parent graph, assign it to the parent\n const parentNs = getParentCheckpointNamespace(ns);\n error.command = new Command({\n ...error.command,\n graph: parentNs,\n });\n }\n }\n if (isGraphBubbleUp(error)) {\n break;\n }\n if (resolvedRetryPolicy === undefined) {\n break;\n }\n attempts += 1;\n // check if we should give up\n if (\n attempts >= (resolvedRetryPolicy.maxAttempts ?? DEFAULT_MAX_RETRIES)\n ) {\n break;\n }\n const retryOn = resolvedRetryPolicy.retryOn ?? DEFAULT_RETRY_ON_HANDLER;\n if (!retryOn(error)) {\n break;\n }\n const initialInterval =\n resolvedRetryPolicy.initialInterval ?? DEFAULT_INITIAL_INTERVAL;\n const interval = Math.min(\n resolvedRetryPolicy.maxInterval ?? DEFAULT_MAX_INTERVAL,\n initialInterval *\n (resolvedRetryPolicy.backoffFactor ?? DEFAULT_BACKOFF_FACTOR) **\n (attempts - 1)\n );\n const sleepMs =\n (resolvedRetryPolicy.jitter ?? DEFAULT_JITTER)\n ? interval + Math.random() * 1000\n : interval;\n // sleep before retrying\n // eslint-disable-next-line no-promise-executor-return\n await new Promise((resolve) => setTimeout(resolve, sleepMs));\n // log the retry\n const errorName =\n (error as Error).name ??\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n ((error as Error).constructor as any).unminifiable_name ??\n (error as Error).constructor.name;\n if (resolvedRetryPolicy?.logWarning ?? true) {\n console.log(\n `Retrying task \"${String(pregelTask.name)}\" after ${sleepMs.toFixed(\n 2\n )}ms (attempt ${attempts}) after ${errorName}: ${error}`\n );\n }\n\n // signal subgraphs to resume (if available)\n config = patchConfigurable(config, { [CONFIG_KEY_RESUMING]: true });\n\n if (config.executionInfo != null) {\n config.executionInfo = {\n ...config.executionInfo,\n nodeAttempt: attempts + 1,\n nodeFirstAttemptTime: firstAttemptTime,\n };\n }\n }\n }\n return {\n task: pregelTask,\n result,\n error: error as Error | undefined,\n signalAborted: signal?.aborted,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RunControl } from "./runtime.cjs";
|
|
1
2
|
import { BaseStore } from "@langchain/langgraph-checkpoint";
|
|
2
3
|
import { RunnableConfig, RunnableInterface } from "@langchain/core/runnables";
|
|
3
4
|
|
|
@@ -62,10 +63,29 @@ interface Runtime<ContextType = Record<string, unknown>, InterruptType = unknown
|
|
|
62
63
|
interrupt: IsEqual<InterruptType, unknown> extends true ? (value: unknown) => unknown : InterruptType;
|
|
63
64
|
/** Abort signal to cancel the run. */
|
|
64
65
|
signal: AbortSignal;
|
|
66
|
+
/**
|
|
67
|
+
* Manually signal that the node is still making progress, resetting the
|
|
68
|
+
* `idleTimeout` of the node's {@link TimeoutPolicy} (if configured).
|
|
69
|
+
*
|
|
70
|
+
* This is a no-op when the node has no `idleTimeout` configured. It is the
|
|
71
|
+
* only progress signal when `refreshOn` is `"heartbeat"`, and is useful for
|
|
72
|
+
* long-running work that doesn't otherwise emit writes, stream events, child
|
|
73
|
+
* tasks, or callback events.
|
|
74
|
+
*/
|
|
75
|
+
heartbeat?: () => void;
|
|
65
76
|
/** Read-only execution information/metadata for the current node run. Undefined before task preparation. */
|
|
66
77
|
executionInfo?: ExecutionInfo;
|
|
67
78
|
/** Metadata injected by LangGraph Server. Undefined when running open-source LangGraph without LangSmith deployments. */
|
|
68
79
|
serverInfo?: ServerInfo;
|
|
80
|
+
/**
|
|
81
|
+
* Run-scoped control plane for cooperative draining.
|
|
82
|
+
*
|
|
83
|
+
* Populated automatically during graph runs. Nodes can read
|
|
84
|
+
* `runtime.control.drainRequested` / `drainReason`, or call
|
|
85
|
+
* `runtime.control.requestDrain()` to ask the graph to stop at the next
|
|
86
|
+
* superstep boundary. Undefined outside an active graph runtime.
|
|
87
|
+
*/
|
|
88
|
+
control?: RunControl;
|
|
69
89
|
}
|
|
70
90
|
interface LangGraphRunnableConfig<ContextType extends Record<string, any> = Record<string, any>> extends RunnableConfig<ContextType>, Partial<Runtime<ContextType, unknown, unknown>> {}
|
|
71
91
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runnable_types.d.cts","names":[],"sources":["../../src/pregel/runnable_types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"runnable_types.d.cts","names":[],"sources":["../../src/pregel/runnable_types.ts"],"mappings":";;;;;KAIK,cAAA,0CAGiB,cAAA,GAAiB,cAAA,KAErC,KAAA,EAAO,QAAA,EAEP,OAAA,EAAS,WAAA,KACN,SAAA,GAAY,OAAA,CAAQ,SAAA;AAAA,KAEpB,eAAA,sCACS,SAAA,GAAY,cAAA,CAAa,QAAA,EAAU,SAAA,CAAU,CAAA;AAAA,KAG/C,cAAA,0CAGU,cAAA,GAAiB,cAAA,IAEnC,iBAAA,CAAkB,QAAA,EAAU,SAAA,EAAW,WAAA,IACvC,cAAA,CAAa,QAAA,EAAU,SAAA,EAAW,WAAA,IAClC,eAAA,CAAgB,QAAA,EAAU,SAAA;AAAA,KAEzB,OAAA,UAAiB,CAAA,WAAY,CAAA,MAAO,CAAA,WAAY,CAAA;;UAGpC,aAAA;EAnBN;EAAA,SAqBA,YAAA;EApBc;EAAA,SAsBd,YAAA;EAtBa;EAAA,SAwBb,MAAA;EA/BT;EAAA,SAiCS,QAAA;EA/BT;EAAA,SAiCS,KAAA;EAjC4B;EAAA,SAmC5B,WAAA;EAjCT;EAAA,SAmCS,oBAAA;AAAA;;UAIM,UAAA;EApCQ;EAAA,SAsCd,WAAA;EAtCuB;EAAA,SAwCvB,OAAA;EAtCS;EAAA,SAyCT,IAAA,GAAO,MAAA;AAAA;AAAA,UAGD,OAAA,eACD,MAAA;EAId,YAAA,GAAe,WAAA;EAhD0C;EAmDzD,OAAA,GAAU,WAAA;EAnD0B;EAsDpC,KAAA,GAAQ,SAAA;EAvDW;EA0DnB,MAAA,EAAQ,OAAA,CAAQ,UAAA,2BACX,KAAA,qBACD,UAAA;EA3DH;;;;;;;;AAGH;;;;;;;;;;;EA6EE,SAAA,EAAW,OAAA,CAAQ,aAAA,2BACd,KAAA,wBACD,aAAA;EAzEF;EA4EF,MAAA,EAAQ,WAAA;EA3EoB;;;;;;;;;EAsF5B,SAAA;EAxFoB;EA2FpB,aAAA,GAAgB,aAAA;EA3FyB;EA8FzC,UAAA,GAAa,UAAA;EA7FE;;;;;;;;EAuGf,OAAA,GAAU,UAAA;AAAA;AAAA,UAGK,uBAAA,qBAEK,MAAA,gBAAsB,MAAA,uBAGxC,cAAA,CAAe,WAAA,GACf,OAAA,CAAQ,OAAA,CAAQ,WAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RunControl } from "./runtime.js";
|
|
1
2
|
import { BaseStore } from "@langchain/langgraph-checkpoint";
|
|
2
3
|
import { RunnableConfig, RunnableInterface } from "@langchain/core/runnables";
|
|
3
4
|
|
|
@@ -62,10 +63,29 @@ interface Runtime<ContextType = Record<string, unknown>, InterruptType = unknown
|
|
|
62
63
|
interrupt: IsEqual<InterruptType, unknown> extends true ? (value: unknown) => unknown : InterruptType;
|
|
63
64
|
/** Abort signal to cancel the run. */
|
|
64
65
|
signal: AbortSignal;
|
|
66
|
+
/**
|
|
67
|
+
* Manually signal that the node is still making progress, resetting the
|
|
68
|
+
* `idleTimeout` of the node's {@link TimeoutPolicy} (if configured).
|
|
69
|
+
*
|
|
70
|
+
* This is a no-op when the node has no `idleTimeout` configured. It is the
|
|
71
|
+
* only progress signal when `refreshOn` is `"heartbeat"`, and is useful for
|
|
72
|
+
* long-running work that doesn't otherwise emit writes, stream events, child
|
|
73
|
+
* tasks, or callback events.
|
|
74
|
+
*/
|
|
75
|
+
heartbeat?: () => void;
|
|
65
76
|
/** Read-only execution information/metadata for the current node run. Undefined before task preparation. */
|
|
66
77
|
executionInfo?: ExecutionInfo;
|
|
67
78
|
/** Metadata injected by LangGraph Server. Undefined when running open-source LangGraph without LangSmith deployments. */
|
|
68
79
|
serverInfo?: ServerInfo;
|
|
80
|
+
/**
|
|
81
|
+
* Run-scoped control plane for cooperative draining.
|
|
82
|
+
*
|
|
83
|
+
* Populated automatically during graph runs. Nodes can read
|
|
84
|
+
* `runtime.control.drainRequested` / `drainReason`, or call
|
|
85
|
+
* `runtime.control.requestDrain()` to ask the graph to stop at the next
|
|
86
|
+
* superstep boundary. Undefined outside an active graph runtime.
|
|
87
|
+
*/
|
|
88
|
+
control?: RunControl;
|
|
69
89
|
}
|
|
70
90
|
interface LangGraphRunnableConfig<ContextType extends Record<string, any> = Record<string, any>> extends RunnableConfig<ContextType>, Partial<Runtime<ContextType, unknown, unknown>> {}
|
|
71
91
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runnable_types.d.ts","names":[],"sources":["../../src/pregel/runnable_types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"runnable_types.d.ts","names":[],"sources":["../../src/pregel/runnable_types.ts"],"mappings":";;;;;KAIK,cAAA,0CAGiB,cAAA,GAAiB,cAAA,KAErC,KAAA,EAAO,QAAA,EAEP,OAAA,EAAS,WAAA,KACN,SAAA,GAAY,OAAA,CAAQ,SAAA;AAAA,KAEpB,eAAA,sCACS,SAAA,GAAY,cAAA,CAAa,QAAA,EAAU,SAAA,CAAU,CAAA;AAAA,KAG/C,cAAA,0CAGU,cAAA,GAAiB,cAAA,IAEnC,iBAAA,CAAkB,QAAA,EAAU,SAAA,EAAW,WAAA,IACvC,cAAA,CAAa,QAAA,EAAU,SAAA,EAAW,WAAA,IAClC,eAAA,CAAgB,QAAA,EAAU,SAAA;AAAA,KAEzB,OAAA,UAAiB,CAAA,WAAY,CAAA,MAAO,CAAA,WAAY,CAAA;;UAGpC,aAAA;EAnBN;EAAA,SAqBA,YAAA;EApBc;EAAA,SAsBd,YAAA;EAtBa;EAAA,SAwBb,MAAA;EA/BT;EAAA,SAiCS,QAAA;EA/BT;EAAA,SAiCS,KAAA;EAjC4B;EAAA,SAmC5B,WAAA;EAjCT;EAAA,SAmCS,oBAAA;AAAA;;UAIM,UAAA;EApCQ;EAAA,SAsCd,WAAA;EAtCuB;EAAA,SAwCvB,OAAA;EAtCS;EAAA,SAyCT,IAAA,GAAO,MAAA;AAAA;AAAA,UAGD,OAAA,eACD,MAAA;EAId,YAAA,GAAe,WAAA;EAhD0C;EAmDzD,OAAA,GAAU,WAAA;EAnD0B;EAsDpC,KAAA,GAAQ,SAAA;EAvDW;EA0DnB,MAAA,EAAQ,OAAA,CAAQ,UAAA,2BACX,KAAA,qBACD,UAAA;EA3DH;;;;;;;;AAGH;;;;;;;;;;;EA6EE,SAAA,EAAW,OAAA,CAAQ,aAAA,2BACd,KAAA,wBACD,aAAA;EAzEF;EA4EF,MAAA,EAAQ,WAAA;EA3EoB;;;;;;;;;EAsF5B,SAAA;EAxFoB;EA2FpB,aAAA,GAAgB,aAAA;EA3FyB;EA8FzC,UAAA,GAAa,UAAA;EA7FE;;;;;;;;EAuGf,OAAA,GAAU,UAAA;AAAA;AAAA,UAGK,uBAAA,qBAEK,MAAA,gBAAsB,MAAA,uBAGxC,cAAA,CAAe,WAAA,GACf,OAAA,CAAQ,OAAA,CAAQ,WAAA"}
|
package/dist/pregel/runner.cjs
CHANGED
|
@@ -26,6 +26,11 @@ var PregelRunner = class {
|
|
|
26
26
|
nodeFinished;
|
|
27
27
|
loop;
|
|
28
28
|
/**
|
|
29
|
+
* Exceptions already routed to a node-level error handler. Consulted when
|
|
30
|
+
* deciding whether a failed task should abort the run.
|
|
31
|
+
*/
|
|
32
|
+
handledExceptions = /* @__PURE__ */ new WeakSet();
|
|
33
|
+
/**
|
|
29
34
|
* Construct a new PregelRunner, which executes tasks from the provided PregelLoop.
|
|
30
35
|
* @param loop - The PregelLoop that produces tasks for this runner to execute.
|
|
31
36
|
*/
|
|
@@ -46,7 +51,8 @@ var PregelRunner = class {
|
|
|
46
51
|
const exceptionSignalController = new AbortController();
|
|
47
52
|
const exceptionSignal = exceptionSignalController.signal;
|
|
48
53
|
const stepTimeoutSignal = timeout ? AbortSignal.timeout(timeout) : void 0;
|
|
49
|
-
const
|
|
54
|
+
const allTasks = Object.values(this.loop.tasks);
|
|
55
|
+
const pendingTasks = allTasks.filter((t) => t.writes.length === 0);
|
|
50
56
|
const { signals, disposeCombinedSignal } = this._initializeAbortSignals({
|
|
51
57
|
exceptionSignal,
|
|
52
58
|
stepTimeoutSignal,
|
|
@@ -59,6 +65,7 @@ var PregelRunner = class {
|
|
|
59
65
|
});
|
|
60
66
|
for await (const { task, error, signalAborted } of taskStream) {
|
|
61
67
|
this._commit(task, error);
|
|
68
|
+
if (error !== void 0 && this.handledExceptions.has(error)) continue;
|
|
62
69
|
if (require_errors.isGraphInterrupt(error)) graphBubbleUp = error;
|
|
63
70
|
else if (require_errors.isGraphBubbleUp(error) && !require_errors.isGraphInterrupt(graphBubbleUp)) graphBubbleUp = error;
|
|
64
71
|
else if (error && (nodeErrors.size === 0 || !signalAborted)) {
|
|
@@ -67,10 +74,11 @@ var PregelRunner = class {
|
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
76
|
disposeCombinedSignal?.();
|
|
70
|
-
onStepWrite?.(this.loop.step,
|
|
77
|
+
onStepWrite?.(this.loop.step, allTasks.map((task) => task.writes).flat());
|
|
71
78
|
if (nodeErrors.size === 1) throw Array.from(nodeErrors)[0];
|
|
72
79
|
else if (nodeErrors.size > 1) throw new AggregateError(Array.from(nodeErrors), `Multiple errors occurred during superstep ${this.loop.step}. See the "errors" field of this exception for more details.`);
|
|
73
80
|
if (require_errors.isGraphInterrupt(graphBubbleUp)) throw graphBubbleUp;
|
|
81
|
+
if (require_errors.isGraphDrained(graphBubbleUp)) throw graphBubbleUp;
|
|
74
82
|
if (require_errors.isGraphBubbleUp(graphBubbleUp) && this.loop.isNested) throw graphBubbleUp;
|
|
75
83
|
}
|
|
76
84
|
/**
|
|
@@ -142,7 +150,22 @@ var PregelRunner = class {
|
|
|
142
150
|
barrier.wait
|
|
143
151
|
]);
|
|
144
152
|
if (settledTask === PROMISE_ADDED_SYMBOL) continue;
|
|
145
|
-
|
|
153
|
+
const settled = settledTask;
|
|
154
|
+
const { task: settledPregelTask, error: settledError } = settled;
|
|
155
|
+
if (settledError !== void 0 && !require_errors.isGraphBubbleUp(settledError) && !this.loop.isErrorHandlerNode(String(settledPregelTask.name)) && this.loop.getErrorHandlerNode(String(settledPregelTask.name)) !== void 0) {
|
|
156
|
+
const handlerTask = this.loop.scheduleErrorHandler(settledPregelTask, settledError);
|
|
157
|
+
if (handlerTask !== void 0) {
|
|
158
|
+
executingTasksMap[handlerTask.id] = require_retry._runWithRetry(handlerTask, retryPolicy, { [require_constants.CONFIG_KEY_CALL]: call?.bind(thisCall, this, handlerTask) }, signals?.composedAbortSignal).catch((error) => {
|
|
159
|
+
return {
|
|
160
|
+
task: handlerTask,
|
|
161
|
+
error,
|
|
162
|
+
signalAborted: signals?.composedAbortSignal?.aborted
|
|
163
|
+
};
|
|
164
|
+
});
|
|
165
|
+
barrier.next();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
yield settled;
|
|
146
169
|
if (listener != null) {
|
|
147
170
|
timeoutOrCancelSignal.signal?.removeEventListener("abort", listener);
|
|
148
171
|
timeoutOrCancelSignal.dispose?.();
|
|
@@ -151,6 +174,14 @@ var PregelRunner = class {
|
|
|
151
174
|
}
|
|
152
175
|
}
|
|
153
176
|
/**
|
|
177
|
+
* Whether a failed task should record {@link ERROR_SOURCE_NODE} provenance.
|
|
178
|
+
*/
|
|
179
|
+
_shouldRouteToErrorHandler(task) {
|
|
180
|
+
const name = String(task.name);
|
|
181
|
+
if (this.loop.isErrorHandlerNode(name)) return false;
|
|
182
|
+
return this.loop.getErrorHandlerNode(name) !== void 0;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
154
185
|
* Determines what writes to apply based on whether the task completed successfully, and what type of error occurred.
|
|
155
186
|
*
|
|
156
187
|
* Throws an error if the error is a {@link GraphBubbleUp} error and {@link PregelLoop}#isNested is true.
|
|
@@ -166,11 +197,20 @@ var PregelRunner = class {
|
|
|
166
197
|
if (resumes.length) interrupts.push(...resumes);
|
|
167
198
|
this.loop.putWrites(task.id, interrupts);
|
|
168
199
|
}
|
|
200
|
+
} else if (require_errors.isGraphDrained(error)) {
|
|
201
|
+
if (task.writes.length) this.loop.putWrites(task.id, task.writes);
|
|
169
202
|
} else if (require_errors.isGraphBubbleUp(error) && task.writes.length) this.loop.putWrites(task.id, task.writes);
|
|
170
|
-
else
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
203
|
+
else {
|
|
204
|
+
task.writes.push([require_constants.ERROR, {
|
|
205
|
+
message: error.message,
|
|
206
|
+
name: error.name
|
|
207
|
+
}]);
|
|
208
|
+
if (this._shouldRouteToErrorHandler(task)) {
|
|
209
|
+
task.writes.push([require_constants.ERROR_SOURCE_NODE, String(task.name)]);
|
|
210
|
+
this.handledExceptions.add(error);
|
|
211
|
+
}
|
|
212
|
+
this.loop.putWrites(task.id, task.writes);
|
|
213
|
+
}
|
|
174
214
|
else {
|
|
175
215
|
if (this.nodeFinished && (task.config?.tags == null || !task.config.tags.includes("langsmith:hidden"))) this.nodeFinished(String(task.name));
|
|
176
216
|
if (task.writes.length === 0) task.writes.push([require_constants.NO_WRITES, null]);
|
|
@@ -189,6 +229,7 @@ async function call(runner, task, func, name, input, options = {}) {
|
|
|
189
229
|
input,
|
|
190
230
|
cache: options.cache,
|
|
191
231
|
retry: options.retry,
|
|
232
|
+
timeout: options.timeout,
|
|
192
233
|
callbacks: options.callbacks
|
|
193
234
|
});
|
|
194
235
|
const nextTask = await this.scheduleTask(task, cnt, wcall);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.cjs","names":["isGraphInterrupt","isGraphBubbleUp","combineAbortSignals","patchConfigurable","CONFIG_KEY_ABORT_SIGNALS","_runWithRetry","CONFIG_KEY_CALL","INTERRUPT","RESUME","ERROR","NO_WRITES","CONFIG_KEY_SCRATCHPAD","Call","RETURN"],"sources":["../../src/pregel/runner.ts"],"sourcesContent":["import { PendingWrite } from \"@langchain/langgraph-checkpoint\";\nimport {\n Call,\n PregelAbortSignals,\n PregelExecutableTask,\n PregelScratchpad,\n} from \"./types.js\";\nimport {\n CachePolicy,\n combineAbortSignals,\n patchConfigurable,\n RetryPolicy,\n} from \"./utils/index.js\";\nimport {\n CONFIG_KEY_SCRATCHPAD,\n ERROR,\n INTERRUPT,\n RESUME,\n NO_WRITES,\n TAG_HIDDEN,\n RETURN,\n CONFIG_KEY_CALL,\n CONFIG_KEY_ABORT_SIGNALS,\n} from \"../constants.js\";\nimport { GraphBubbleUp, isGraphBubbleUp, isGraphInterrupt } from \"../errors.js\";\nimport { _runWithRetry, SettledPregelTask } from \"./retry.js\";\nimport { PregelLoop } from \"./loop.js\";\n\nconst PROMISE_ADDED_SYMBOL = Symbol.for(\"promiseAdded\");\n\nfunction createPromiseBarrier() {\n const barrier: {\n next: () => void;\n wait: Promise<unknown>;\n } = {\n next: () => void 0,\n wait: Promise.resolve(PROMISE_ADDED_SYMBOL),\n };\n\n function waitHandler(resolve: (value: typeof PROMISE_ADDED_SYMBOL) => void) {\n barrier.next = () => {\n barrier.wait = new Promise(waitHandler);\n resolve(PROMISE_ADDED_SYMBOL);\n };\n }\n barrier.wait = new Promise(waitHandler);\n return barrier;\n}\n\n/**\n * Options for the {@link PregelRunner#tick} method.\n */\nexport type TickOptions = {\n /**\n * The deadline before which all tasks must be completed.\n */\n timeout?: number;\n\n /**\n * An optional {@link AbortSignal} to cancel processing of tasks.\n */\n signal?: AbortSignal;\n\n /**\n * The {@link RetryPolicy} to use for the tick.\n */\n retryPolicy?: RetryPolicy;\n\n /**\n * An optional callback to be called after all task writes are completed.\n */\n onStepWrite?: (step: number, writes: PendingWrite[]) => void;\n\n /**\n * The maximum number of tasks to execute concurrently.\n */\n maxConcurrency?: number;\n};\n\n/**\n * Responsible for handling task execution on each tick of the {@link PregelLoop}.\n */\nexport class PregelRunner {\n private nodeFinished?: (id: string) => void;\n\n private loop: PregelLoop;\n\n /**\n * Construct a new PregelRunner, which executes tasks from the provided PregelLoop.\n * @param loop - The PregelLoop that produces tasks for this runner to execute.\n */\n constructor({\n loop,\n nodeFinished,\n }: {\n loop: PregelLoop;\n nodeFinished?: (id: string) => void;\n }) {\n this.loop = loop;\n this.nodeFinished = nodeFinished;\n }\n\n /**\n * Execute tasks from the current step of the PregelLoop.\n *\n * Note: this method does NOT call {@link PregelLoop}#tick. That must be handled externally.\n * @param options - Options for the execution.\n */\n async tick(options: TickOptions = {}) {\n const { timeout, retryPolicy, onStepWrite, maxConcurrency } = options;\n\n const nodeErrors: Set<Error> = new Set();\n let graphBubbleUp: GraphBubbleUp | undefined;\n\n const exceptionSignalController = new AbortController();\n const exceptionSignal = exceptionSignalController.signal;\n const stepTimeoutSignal = timeout\n ? AbortSignal.timeout(timeout)\n : undefined;\n\n // Start task execution\n const pendingTasks = Object.values(this.loop.tasks).filter(\n (t) => t.writes.length === 0\n );\n\n const { signals, disposeCombinedSignal } = this._initializeAbortSignals({\n exceptionSignal,\n stepTimeoutSignal,\n signal: options.signal,\n });\n\n const taskStream = this._executeTasksWithRetry(pendingTasks, {\n signals,\n retryPolicy,\n maxConcurrency,\n });\n\n for await (const { task, error, signalAborted } of taskStream) {\n this._commit(task, error);\n if (isGraphInterrupt(error)) {\n graphBubbleUp = error;\n } else if (isGraphBubbleUp(error) && !isGraphInterrupt(graphBubbleUp)) {\n graphBubbleUp = error;\n } else if (error && (nodeErrors.size === 0 || !signalAborted)) {\n /*\n * The goal here is to capture the exception that causes the graph to terminate early. In\n * theory it's possible for multiple nodes to throw, so this also handles the edge case of\n * capturing concurrent exceptions thrown before the node saw an abort. This is checked via\n * the signalAborted flag, which records the state of the abort signal at the time the node\n * execution finished.\n *\n * There is a case however where one node throws some error causing us to trigger an abort,\n * which then causes other concurrently executing nodes to throw their own AbortErrors. In\n * this case we don't care about reporting the abort errors thrown by the other nodes,\n * because they don't tell the user anything about what caused the graph execution to\n * terminate early, so we ignore them (and any other errors that occur after the node sees\n * an abort signal).\n */\n exceptionSignalController.abort();\n nodeErrors.add(error);\n }\n }\n\n disposeCombinedSignal?.();\n\n onStepWrite?.(\n this.loop.step,\n Object.values(this.loop.tasks)\n .map((task) => task.writes)\n .flat()\n );\n\n if (nodeErrors.size === 1) {\n throw Array.from(nodeErrors)[0];\n } else if (nodeErrors.size > 1) {\n throw new AggregateError(\n Array.from(nodeErrors),\n `Multiple errors occurred during superstep ${this.loop.step}. See the \"errors\" field of this exception for more details.`\n );\n }\n\n if (isGraphInterrupt(graphBubbleUp)) {\n throw graphBubbleUp;\n }\n\n if (isGraphBubbleUp(graphBubbleUp) && this.loop.isNested) {\n throw graphBubbleUp;\n }\n }\n\n /**\n * Initializes the current AbortSignals for the PregelRunner, handling the various ways that\n * AbortSignals must be chained together so that the PregelLoop can be interrupted if necessary\n * while still allowing nodes to gracefully exit.\n *\n * This method must only be called once per PregelRunner#tick. It has the side effect of updating\n * the PregelLoop#config with the new AbortSignals so they may be propagated correctly to future\n * ticks and subgraph calls.\n *\n * @param options - Options for the initialization.\n * @returns The current abort signals.\n * @internal\n */\n private _initializeAbortSignals({\n exceptionSignal,\n stepTimeoutSignal,\n signal,\n }: {\n exceptionSignal: AbortSignal;\n stepTimeoutSignal?: AbortSignal;\n signal?: AbortSignal;\n }): { signals: PregelAbortSignals; disposeCombinedSignal?: () => void } {\n const previousSignals = (this.loop.config.configurable?.[\n CONFIG_KEY_ABORT_SIGNALS\n ] ?? {}) as PregelAbortSignals;\n\n // We always inherit the external abort signal from AsyncLocalStorage,\n // since that's the only way the signal is inherited by the subgraph calls.\n const externalAbortSignal = previousSignals.externalAbortSignal ?? signal;\n\n // inherit the step timeout signal from parent graph\n const timeoutAbortSignal =\n stepTimeoutSignal ?? previousSignals.timeoutAbortSignal;\n\n const { signal: composedAbortSignal, dispose: disposeCombinedSignal } =\n combineAbortSignals(\n externalAbortSignal,\n timeoutAbortSignal,\n exceptionSignal\n );\n\n const signals: PregelAbortSignals = {\n externalAbortSignal,\n timeoutAbortSignal,\n composedAbortSignal,\n };\n\n this.loop.config = patchConfigurable(this.loop.config, {\n [CONFIG_KEY_ABORT_SIGNALS]: signals,\n });\n\n return { signals, disposeCombinedSignal };\n }\n\n /**\n * Concurrently executes tasks with the requested retry policy, yielding a {@link SettledPregelTask} for each task as it completes.\n * @param tasks - The tasks to execute.\n * @param options - Options for the execution.\n */\n private async *_executeTasksWithRetry(\n tasks: PregelExecutableTask<string, string>[],\n options?: {\n signals?: PregelAbortSignals;\n retryPolicy?: RetryPolicy;\n maxConcurrency?: number;\n }\n ): AsyncGenerator<SettledPregelTask> {\n const { retryPolicy, maxConcurrency, signals } = options ?? {};\n\n const barrier = createPromiseBarrier();\n const executingTasksMap: Record<\n string,\n Promise<{\n task: PregelExecutableTask<string, string>;\n result?: unknown;\n error?: Error;\n }>\n > = {};\n\n const thisCall = {\n executingTasksMap,\n barrier,\n retryPolicy,\n scheduleTask: async (\n task: PregelExecutableTask<string, string>,\n writeIdx: number,\n call?: Call\n ) => this.loop.acceptPush(task, writeIdx, call),\n };\n\n if (signals?.composedAbortSignal?.aborted) {\n // note: don't use throwIfAborted here because it throws a DOMException,\n // which isn't consistent with how we throw on abort below.\n throw new Error(\"Abort\");\n }\n\n let startedTasksCount = 0;\n\n let listener: (() => void) | undefined;\n const timeoutOrCancelSignal = combineAbortSignals(\n signals?.externalAbortSignal,\n signals?.timeoutAbortSignal\n );\n\n const abortPromise = timeoutOrCancelSignal.signal\n ? new Promise<never>((_resolve, reject) => {\n listener = () => reject(new Error(\"Abort\"));\n timeoutOrCancelSignal.signal?.addEventListener(\"abort\", listener, {\n once: true,\n });\n })\n : undefined;\n\n while (\n (startedTasksCount === 0 || Object.keys(executingTasksMap).length > 0) &&\n tasks.length\n ) {\n for (\n ;\n Object.values(executingTasksMap).length <\n (maxConcurrency ?? tasks.length) && startedTasksCount < tasks.length;\n startedTasksCount += 1\n ) {\n const task = tasks[startedTasksCount];\n\n executingTasksMap[task.id] = _runWithRetry(\n task,\n retryPolicy,\n { [CONFIG_KEY_CALL]: call?.bind(thisCall, this, task) },\n signals?.composedAbortSignal\n ).catch((error) => {\n return {\n task,\n error,\n signalAborted: signals?.composedAbortSignal?.aborted,\n };\n });\n }\n\n const settledTask = await Promise.race([\n ...Object.values(executingTasksMap),\n ...(abortPromise ? [abortPromise] : []),\n barrier.wait,\n ]);\n\n if (settledTask === PROMISE_ADDED_SYMBOL) {\n continue;\n }\n\n yield settledTask as SettledPregelTask;\n\n if (listener != null) {\n timeoutOrCancelSignal.signal?.removeEventListener(\"abort\", listener);\n timeoutOrCancelSignal.dispose?.();\n }\n\n delete executingTasksMap[(settledTask as SettledPregelTask).task.id];\n }\n }\n\n /**\n * Determines what writes to apply based on whether the task completed successfully, and what type of error occurred.\n *\n * Throws an error if the error is a {@link GraphBubbleUp} error and {@link PregelLoop}#isNested is true.\n *\n * @param task - The task to commit.\n * @param error - The error that occurred, if any.\n */\n private _commit(task: PregelExecutableTask<string, string>, error?: Error) {\n if (error !== undefined) {\n if (isGraphInterrupt(error)) {\n if (error.interrupts.length) {\n const interrupts: PendingWrite<string>[] = error.interrupts.map(\n (interrupt) => [INTERRUPT, interrupt]\n );\n const resumes = task.writes.filter((w) => w[0] === RESUME);\n if (resumes.length) {\n interrupts.push(...resumes);\n }\n this.loop.putWrites(task.id, interrupts);\n }\n } else if (isGraphBubbleUp(error) && task.writes.length) {\n this.loop.putWrites(task.id, task.writes);\n } else {\n this.loop.putWrites(task.id, [\n [ERROR, { message: error.message, name: error.name }],\n ]);\n }\n } else {\n if (\n this.nodeFinished &&\n (task.config?.tags == null || !task.config.tags.includes(TAG_HIDDEN))\n ) {\n this.nodeFinished(String(task.name));\n }\n\n if (task.writes.length === 0) {\n // Add no writes marker\n task.writes.push([NO_WRITES, null]);\n }\n\n // Save task writes to checkpointer\n this.loop.putWrites(task.id, task.writes);\n }\n }\n}\n\nasync function call(\n this: {\n executingTasksMap: Record<\n string,\n Promise<{\n task: PregelExecutableTask<string, string>;\n result?: unknown;\n error?: Error;\n }>\n >;\n\n barrier: {\n next: () => void;\n wait: Promise<unknown>;\n };\n\n retryPolicy?: RetryPolicy;\n\n scheduleTask: (\n task: PregelExecutableTask<string, string>,\n writeIdx: number,\n call?: Call\n ) => Promise<PregelExecutableTask<string, string> | void>;\n },\n runner: PregelRunner,\n task: PregelExecutableTask<string, string>,\n func: (...args: unknown[]) => unknown | Promise<unknown>,\n name: string,\n input: unknown,\n options: {\n retry?: RetryPolicy;\n cache?: CachePolicy;\n callbacks?: unknown;\n } = {}\n): Promise<unknown> {\n // Schedule PUSH tasks, collect promises\n const scratchpad = task.config?.configurable?.[CONFIG_KEY_SCRATCHPAD] as\n | PregelScratchpad<unknown>\n | undefined;\n\n if (!scratchpad) {\n throw new Error(\n `BUG: No scratchpad found on task ${task.name}__${task.id}`\n );\n }\n\n const cnt = scratchpad.callCounter;\n scratchpad.callCounter += 1;\n\n // schedule the next task, if the callback returns one\n const wcall = new Call({\n func,\n name,\n input,\n cache: options.cache,\n retry: options.retry,\n callbacks: options.callbacks,\n });\n const nextTask = await this.scheduleTask(task, cnt, wcall);\n if (!nextTask) return undefined;\n\n // Check if this task is already running\n const existingPromise = this.executingTasksMap[nextTask.id];\n\n if (existingPromise !== undefined) {\n // If the parent task was retried, the next task might already be running\n return existingPromise;\n }\n\n if (nextTask.writes.length > 0) {\n // If it already ran, return the result\n const returns = nextTask.writes.filter(([c]) => c === RETURN);\n const errors = nextTask.writes.filter(([c]) => c === ERROR);\n\n if (returns.length > 0) {\n // Task completed successfully\n if (returns.length === 1) return Promise.resolve(returns[0][1]);\n\n // should be unreachable\n throw new Error(\n `BUG: multiple returns found for task ${nextTask.name}__${nextTask.id}`\n );\n }\n\n if (errors.length > 0) {\n // Task failed\n if (errors.length === 1) {\n const errorValue = errors[0][1];\n const error =\n // eslint-disable-next-line no-instanceof/no-instanceof\n errorValue instanceof Error\n ? errorValue\n : new Error(String(errorValue));\n\n return Promise.reject(error);\n }\n\n // the only way this should happen is if the task executes multiple times and writes aren't cleared\n throw new Error(\n `BUG: multiple errors found for task ${nextTask.name}__${nextTask.id}`\n );\n }\n\n return undefined;\n } else {\n // Schedule the next task with retry\n const prom = _runWithRetry<string, string>(nextTask, options.retry, {\n [CONFIG_KEY_CALL]: call.bind(this, runner, nextTask),\n });\n\n this.executingTasksMap[nextTask.id] = prom;\n this.barrier.next();\n\n return prom.then(({ result, error }) => {\n if (error) return Promise.reject(error);\n return result;\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runner.cjs","names":["isGraphInterrupt","isGraphBubbleUp","isGraphDrained","combineAbortSignals","patchConfigurable","CONFIG_KEY_ABORT_SIGNALS","_runWithRetry","CONFIG_KEY_CALL","INTERRUPT","RESUME","ERROR","ERROR_SOURCE_NODE","NO_WRITES","CONFIG_KEY_SCRATCHPAD","Call","RETURN"],"sources":["../../src/pregel/runner.ts"],"sourcesContent":["import { PendingWrite } from \"@langchain/langgraph-checkpoint\";\nimport {\n Call,\n PregelAbortSignals,\n PregelExecutableTask,\n PregelScratchpad,\n} from \"./types.js\";\nimport {\n CachePolicy,\n combineAbortSignals,\n patchConfigurable,\n RetryPolicy,\n TimeoutPolicy,\n} from \"./utils/index.js\";\nimport {\n CONFIG_KEY_SCRATCHPAD,\n ERROR,\n ERROR_SOURCE_NODE,\n INTERRUPT,\n RESUME,\n NO_WRITES,\n TAG_HIDDEN,\n RETURN,\n CONFIG_KEY_CALL,\n CONFIG_KEY_ABORT_SIGNALS,\n} from \"../constants.js\";\nimport {\n GraphBubbleUp,\n isGraphBubbleUp,\n isGraphDrained,\n isGraphInterrupt,\n} from \"../errors.js\";\nimport { _runWithRetry, SettledPregelTask } from \"./retry.js\";\nimport { PregelLoop } from \"./loop.js\";\n\nconst PROMISE_ADDED_SYMBOL = Symbol.for(\"promiseAdded\");\n\nfunction createPromiseBarrier() {\n const barrier: {\n next: () => void;\n wait: Promise<unknown>;\n } = {\n next: () => void 0,\n wait: Promise.resolve(PROMISE_ADDED_SYMBOL),\n };\n\n function waitHandler(resolve: (value: typeof PROMISE_ADDED_SYMBOL) => void) {\n barrier.next = () => {\n barrier.wait = new Promise(waitHandler);\n resolve(PROMISE_ADDED_SYMBOL);\n };\n }\n barrier.wait = new Promise(waitHandler);\n return barrier;\n}\n\n/**\n * Options for the {@link PregelRunner#tick} method.\n */\nexport type TickOptions = {\n /**\n * The deadline before which all tasks must be completed.\n */\n timeout?: number;\n\n /**\n * An optional {@link AbortSignal} to cancel processing of tasks.\n */\n signal?: AbortSignal;\n\n /**\n * The {@link RetryPolicy} to use for the tick.\n */\n retryPolicy?: RetryPolicy;\n\n /**\n * An optional callback to be called after all task writes are completed.\n */\n onStepWrite?: (step: number, writes: PendingWrite[]) => void;\n\n /**\n * The maximum number of tasks to execute concurrently.\n */\n maxConcurrency?: number;\n};\n\n/**\n * Responsible for handling task execution on each tick of the {@link PregelLoop}.\n */\nexport class PregelRunner {\n private nodeFinished?: (id: string) => void;\n\n private loop: PregelLoop;\n\n /**\n * Exceptions already routed to a node-level error handler. Consulted when\n * deciding whether a failed task should abort the run.\n */\n private handledExceptions = new WeakSet<Error>();\n\n /**\n * Construct a new PregelRunner, which executes tasks from the provided PregelLoop.\n * @param loop - The PregelLoop that produces tasks for this runner to execute.\n */\n constructor({\n loop,\n nodeFinished,\n }: {\n loop: PregelLoop;\n nodeFinished?: (id: string) => void;\n }) {\n this.loop = loop;\n this.nodeFinished = nodeFinished;\n }\n\n /**\n * Execute tasks from the current step of the PregelLoop.\n *\n * Note: this method does NOT call {@link PregelLoop}#tick. That must be handled externally.\n * @param options - Options for the execution.\n */\n async tick(options: TickOptions = {}) {\n const { timeout, retryPolicy, onStepWrite, maxConcurrency } = options;\n\n const nodeErrors: Set<Error> = new Set();\n let graphBubbleUp: GraphBubbleUp | undefined;\n\n const exceptionSignalController = new AbortController();\n const exceptionSignal = exceptionSignalController.signal;\n const stepTimeoutSignal = timeout\n ? AbortSignal.timeout(timeout)\n : undefined;\n\n const allTasks = Object.values(this.loop.tasks);\n const pendingTasks = allTasks.filter((t) => t.writes.length === 0);\n\n const { signals, disposeCombinedSignal } = this._initializeAbortSignals({\n exceptionSignal,\n stepTimeoutSignal,\n signal: options.signal,\n });\n\n const taskStream = this._executeTasksWithRetry(pendingTasks, {\n signals,\n retryPolicy,\n maxConcurrency,\n });\n\n for await (const { task, error, signalAborted } of taskStream) {\n this._commit(task, error);\n if (error !== undefined && this.handledExceptions.has(error)) {\n // Routed to a node-level error handler in this tick; provenance is\n // checkpointed and the error must not abort the run.\n continue;\n }\n if (isGraphInterrupt(error)) {\n graphBubbleUp = error;\n } else if (isGraphBubbleUp(error) && !isGraphInterrupt(graphBubbleUp)) {\n graphBubbleUp = error;\n } else if (error && (nodeErrors.size === 0 || !signalAborted)) {\n /*\n * The goal here is to capture the exception that causes the graph to terminate early. In\n * theory it's possible for multiple nodes to throw, so this also handles the edge case of\n * capturing concurrent exceptions thrown before the node saw an abort. This is checked via\n * the signalAborted flag, which records the state of the abort signal at the time the node\n * execution finished.\n *\n * There is a case however where one node throws some error causing us to trigger an abort,\n * which then causes other concurrently executing nodes to throw their own AbortErrors. In\n * this case we don't care about reporting the abort errors thrown by the other nodes,\n * because they don't tell the user anything about what caused the graph execution to\n * terminate early, so we ignore them (and any other errors that occur after the node sees\n * an abort signal).\n */\n exceptionSignalController.abort();\n nodeErrors.add(error);\n }\n }\n\n disposeCombinedSignal?.();\n\n onStepWrite?.(this.loop.step, allTasks.map((task) => task.writes).flat());\n\n if (nodeErrors.size === 1) {\n throw Array.from(nodeErrors)[0];\n } else if (nodeErrors.size > 1) {\n throw new AggregateError(\n Array.from(nodeErrors),\n `Multiple errors occurred during superstep ${this.loop.step}. See the \"errors\" field of this exception for more details.`\n );\n }\n\n if (isGraphInterrupt(graphBubbleUp)) {\n throw graphBubbleUp;\n }\n\n // A cooperative drain raised by a subgraph bubbles up through the parent\n // loop (even when the parent is the top graph) so the parent stops at this\n // boundary and its checkpoint can be resumed later.\n if (isGraphDrained(graphBubbleUp)) {\n throw graphBubbleUp;\n }\n\n if (isGraphBubbleUp(graphBubbleUp) && this.loop.isNested) {\n throw graphBubbleUp;\n }\n }\n\n /**\n * Initializes the current AbortSignals for the PregelRunner, handling the various ways that\n * AbortSignals must be chained together so that the PregelLoop can be interrupted if necessary\n * while still allowing nodes to gracefully exit.\n *\n * This method must only be called once per PregelRunner#tick. It has the side effect of updating\n * the PregelLoop#config with the new AbortSignals so they may be propagated correctly to future\n * ticks and subgraph calls.\n *\n * @param options - Options for the initialization.\n * @returns The current abort signals.\n * @internal\n */\n private _initializeAbortSignals({\n exceptionSignal,\n stepTimeoutSignal,\n signal,\n }: {\n exceptionSignal: AbortSignal;\n stepTimeoutSignal?: AbortSignal;\n signal?: AbortSignal;\n }): { signals: PregelAbortSignals; disposeCombinedSignal?: () => void } {\n const previousSignals = (this.loop.config.configurable?.[\n CONFIG_KEY_ABORT_SIGNALS\n ] ?? {}) as PregelAbortSignals;\n\n // We always inherit the external abort signal from AsyncLocalStorage,\n // since that's the only way the signal is inherited by the subgraph calls.\n const externalAbortSignal = previousSignals.externalAbortSignal ?? signal;\n\n // inherit the step timeout signal from parent graph\n const timeoutAbortSignal =\n stepTimeoutSignal ?? previousSignals.timeoutAbortSignal;\n\n const { signal: composedAbortSignal, dispose: disposeCombinedSignal } =\n combineAbortSignals(\n externalAbortSignal,\n timeoutAbortSignal,\n exceptionSignal\n );\n\n const signals: PregelAbortSignals = {\n externalAbortSignal,\n timeoutAbortSignal,\n composedAbortSignal,\n };\n\n this.loop.config = patchConfigurable(this.loop.config, {\n [CONFIG_KEY_ABORT_SIGNALS]: signals,\n });\n\n return { signals, disposeCombinedSignal };\n }\n\n /**\n * Concurrently executes tasks with the requested retry policy, yielding a {@link SettledPregelTask} for each task as it completes.\n * @param tasks - The tasks to execute.\n * @param options - Options for the execution.\n */\n private async *_executeTasksWithRetry(\n tasks: PregelExecutableTask<string, string>[],\n options?: {\n signals?: PregelAbortSignals;\n retryPolicy?: RetryPolicy;\n maxConcurrency?: number;\n }\n ): AsyncGenerator<SettledPregelTask> {\n const { retryPolicy, maxConcurrency, signals } = options ?? {};\n\n const barrier = createPromiseBarrier();\n const executingTasksMap: Record<\n string,\n Promise<{\n task: PregelExecutableTask<string, string>;\n result?: unknown;\n error?: Error;\n }>\n > = {};\n\n const thisCall = {\n executingTasksMap,\n barrier,\n retryPolicy,\n scheduleTask: async (\n task: PregelExecutableTask<string, string>,\n writeIdx: number,\n call?: Call\n ) => this.loop.acceptPush(task, writeIdx, call),\n };\n\n if (signals?.composedAbortSignal?.aborted) {\n // note: don't use throwIfAborted here because it throws a DOMException,\n // which isn't consistent with how we throw on abort below.\n throw new Error(\"Abort\");\n }\n\n let startedTasksCount = 0;\n\n let listener: (() => void) | undefined;\n const timeoutOrCancelSignal = combineAbortSignals(\n signals?.externalAbortSignal,\n signals?.timeoutAbortSignal\n );\n\n const abortPromise = timeoutOrCancelSignal.signal\n ? new Promise<never>((_resolve, reject) => {\n listener = () => reject(new Error(\"Abort\"));\n timeoutOrCancelSignal.signal?.addEventListener(\"abort\", listener, {\n once: true,\n });\n })\n : undefined;\n\n while (\n (startedTasksCount === 0 || Object.keys(executingTasksMap).length > 0) &&\n tasks.length\n ) {\n for (\n ;\n Object.values(executingTasksMap).length <\n (maxConcurrency ?? tasks.length) && startedTasksCount < tasks.length;\n startedTasksCount += 1\n ) {\n const task = tasks[startedTasksCount];\n\n executingTasksMap[task.id] = _runWithRetry(\n task,\n retryPolicy,\n { [CONFIG_KEY_CALL]: call?.bind(thisCall, this, task) },\n signals?.composedAbortSignal\n ).catch((error) => {\n return {\n task,\n error,\n signalAborted: signals?.composedAbortSignal?.aborted,\n };\n });\n }\n\n const settledTask = await Promise.race([\n ...Object.values(executingTasksMap),\n ...(abortPromise ? [abortPromise] : []),\n barrier.wait,\n ]);\n\n if (settledTask === PROMISE_ADDED_SYMBOL) {\n continue;\n }\n\n const settled = settledTask as SettledPregelTask;\n const { task: settledPregelTask, error: settledError } = settled;\n\n // If the task failed (after exhausting its retry policy) and the node has\n // a registered error handler, schedule that handler to run within this\n // same tick instead of aborting the run. GraphBubbleUp errors (e.g.\n // interrupts / parent commands) are never routed to error handlers.\n if (\n settledError !== undefined &&\n !isGraphBubbleUp(settledError) &&\n !this.loop.isErrorHandlerNode(String(settledPregelTask.name)) &&\n this.loop.getErrorHandlerNode(String(settledPregelTask.name)) !==\n undefined\n ) {\n const handlerTask = this.loop.scheduleErrorHandler(\n settledPregelTask,\n settledError\n );\n if (handlerTask !== undefined) {\n executingTasksMap[handlerTask.id] = _runWithRetry(\n handlerTask,\n retryPolicy,\n { [CONFIG_KEY_CALL]: call?.bind(thisCall, this, handlerTask) },\n signals?.composedAbortSignal\n ).catch((error) => {\n return {\n task: handlerTask,\n error,\n signalAborted: signals?.composedAbortSignal?.aborted,\n };\n });\n barrier.next();\n }\n }\n\n yield settled;\n\n if (listener != null) {\n timeoutOrCancelSignal.signal?.removeEventListener(\"abort\", listener);\n timeoutOrCancelSignal.dispose?.();\n }\n\n delete executingTasksMap[(settledTask as SettledPregelTask).task.id];\n }\n }\n\n /**\n * Whether a failed task should record {@link ERROR_SOURCE_NODE} provenance.\n */\n private _shouldRouteToErrorHandler(\n task: PregelExecutableTask<string, string>\n ): boolean {\n const name = String(task.name);\n if (this.loop.isErrorHandlerNode(name)) {\n return false;\n }\n return this.loop.getErrorHandlerNode(name) !== undefined;\n }\n\n /**\n * Determines what writes to apply based on whether the task completed successfully, and what type of error occurred.\n *\n * Throws an error if the error is a {@link GraphBubbleUp} error and {@link PregelLoop}#isNested is true.\n *\n * @param task - The task to commit.\n * @param error - The error that occurred, if any.\n */\n private _commit(task: PregelExecutableTask<string, string>, error?: Error) {\n if (error !== undefined) {\n if (isGraphInterrupt(error)) {\n if (error.interrupts.length) {\n const interrupts: PendingWrite<string>[] = error.interrupts.map(\n (interrupt) => [INTERRUPT, interrupt]\n );\n const resumes = task.writes.filter((w) => w[0] === RESUME);\n if (resumes.length) {\n interrupts.push(...resumes);\n }\n this.loop.putWrites(task.id, interrupts);\n }\n } else if (isGraphDrained(error)) {\n // Cooperative drain bubbled up from a subgraph. Leave the task\n // uncommitted (unless it already produced writes) so it is\n // re-executed when the parent run resumes.\n if (task.writes.length) {\n this.loop.putWrites(task.id, task.writes);\n }\n } else if (isGraphBubbleUp(error) && task.writes.length) {\n this.loop.putWrites(task.id, task.writes);\n } else {\n task.writes.push([ERROR, { message: error.message, name: error.name }]);\n if (this._shouldRouteToErrorHandler(task)) {\n task.writes.push([ERROR_SOURCE_NODE, String(task.name)]);\n this.handledExceptions.add(error);\n }\n this.loop.putWrites(task.id, task.writes);\n }\n } else {\n if (\n this.nodeFinished &&\n (task.config?.tags == null || !task.config.tags.includes(TAG_HIDDEN))\n ) {\n this.nodeFinished(String(task.name));\n }\n\n if (task.writes.length === 0) {\n // Add no writes marker\n task.writes.push([NO_WRITES, null]);\n }\n\n // Save task writes to checkpointer\n this.loop.putWrites(task.id, task.writes);\n }\n }\n}\n\nasync function call(\n this: {\n executingTasksMap: Record<\n string,\n Promise<{\n task: PregelExecutableTask<string, string>;\n result?: unknown;\n error?: Error;\n }>\n >;\n\n barrier: {\n next: () => void;\n wait: Promise<unknown>;\n };\n\n retryPolicy?: RetryPolicy;\n\n scheduleTask: (\n task: PregelExecutableTask<string, string>,\n writeIdx: number,\n call?: Call\n ) => Promise<PregelExecutableTask<string, string> | void>;\n },\n runner: PregelRunner,\n task: PregelExecutableTask<string, string>,\n func: (...args: unknown[]) => unknown | Promise<unknown>,\n name: string,\n input: unknown,\n options: {\n retry?: RetryPolicy;\n cache?: CachePolicy;\n timeout?: TimeoutPolicy;\n callbacks?: unknown;\n } = {}\n): Promise<unknown> {\n // Schedule PUSH tasks, collect promises\n const scratchpad = task.config?.configurable?.[CONFIG_KEY_SCRATCHPAD] as\n | PregelScratchpad<unknown>\n | undefined;\n\n if (!scratchpad) {\n throw new Error(\n `BUG: No scratchpad found on task ${task.name}__${task.id}`\n );\n }\n\n const cnt = scratchpad.callCounter;\n scratchpad.callCounter += 1;\n\n // schedule the next task, if the callback returns one\n const wcall = new Call({\n func,\n name,\n input,\n cache: options.cache,\n retry: options.retry,\n timeout: options.timeout,\n callbacks: options.callbacks,\n });\n const nextTask = await this.scheduleTask(task, cnt, wcall);\n if (!nextTask) return undefined;\n\n // Check if this task is already running\n const existingPromise = this.executingTasksMap[nextTask.id];\n\n if (existingPromise !== undefined) {\n // If the parent task was retried, the next task might already be running\n return existingPromise;\n }\n\n if (nextTask.writes.length > 0) {\n // If it already ran, return the result\n const returns = nextTask.writes.filter(([c]) => c === RETURN);\n const errors = nextTask.writes.filter(([c]) => c === ERROR);\n\n if (returns.length > 0) {\n // Task completed successfully\n if (returns.length === 1) return Promise.resolve(returns[0][1]);\n\n // should be unreachable\n throw new Error(\n `BUG: multiple returns found for task ${nextTask.name}__${nextTask.id}`\n );\n }\n\n if (errors.length > 0) {\n // Task failed\n if (errors.length === 1) {\n const errorValue = errors[0][1];\n const error =\n // eslint-disable-next-line no-instanceof/no-instanceof\n errorValue instanceof Error\n ? errorValue\n : new Error(String(errorValue));\n\n return Promise.reject(error);\n }\n\n // the only way this should happen is if the task executes multiple times and writes aren't cleared\n throw new Error(\n `BUG: multiple errors found for task ${nextTask.name}__${nextTask.id}`\n );\n }\n\n return undefined;\n } else {\n // Schedule the next task with retry\n const prom = _runWithRetry<string, string>(nextTask, options.retry, {\n [CONFIG_KEY_CALL]: call.bind(this, runner, nextTask),\n });\n\n this.executingTasksMap[nextTask.id] = prom;\n this.barrier.next();\n\n return prom.then(({ result, error }) => {\n if (error) return Promise.reject(error);\n return result;\n });\n }\n}\n"],"mappings":"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"}
|