nexus-ai-pro 2.0.0 → 2.2.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/API_STABILITY.md +65 -0
- package/CHANGELOG.md +267 -1
- package/MIGRATING.md +1 -1
- package/README.md +17 -8
- package/dist/agent/create-agent.d.ts +9 -1
- package/dist/agent/create-agent.js +40 -1
- package/dist/cache/memory-cache.d.ts +8 -0
- package/dist/cache/memory-cache.js +9 -0
- package/dist/cache/semantic-cache.d.ts +6 -3
- package/dist/cache/semantic-cache.js +5 -2
- package/dist/cli/args.js +3 -0
- package/dist/cli/db.d.ts +16 -4
- package/dist/cli/db.js +169 -22
- package/dist/cli/doctor.d.ts +17 -0
- package/dist/cli/doctor.js +53 -0
- package/dist/cli/graph.d.ts +9 -0
- package/dist/cli/graph.js +47 -0
- package/dist/cli.js +21 -2
- package/dist/core/lifecycle.js +11 -6
- package/dist/core/nexus.d.ts +12 -2
- package/dist/core/nexus.js +106 -23
- package/dist/doctor/index.d.ts +90 -0
- package/dist/doctor/index.js +237 -0
- package/dist/evals/judge.d.ts +11 -0
- package/dist/evals/judge.js +33 -0
- package/dist/evaluate/index.d.ts +1 -0
- package/dist/evaluate/index.js +1 -0
- package/dist/evaluate/provenance.d.ts +22 -0
- package/dist/evaluate/provenance.js +10 -0
- package/dist/evaluate/run.js +20 -4
- package/dist/graph/durability.d.ts +27 -0
- package/dist/graph/durability.js +66 -0
- package/dist/graph/errors.d.ts +30 -4
- package/dist/graph/errors.js +18 -2
- package/dist/graph/event-stream.d.ts +75 -0
- package/dist/graph/event-stream.js +289 -0
- package/dist/graph/functional.d.ts +80 -7
- package/dist/graph/functional.js +138 -35
- package/dist/graph/graph.d.ts +56 -8
- package/dist/graph/graph.js +331 -49
- package/dist/graph/index.d.ts +4 -2
- package/dist/graph/index.js +3 -1
- package/dist/graph/lint.d.ts +57 -0
- package/dist/graph/lint.js +141 -0
- package/dist/graph/run-control.d.ts +28 -0
- package/dist/graph/run-control.js +26 -0
- package/dist/images/evals.js +4 -2
- package/dist/operations/adapters.d.ts +52 -4
- package/dist/operations/adapters.js +194 -7
- package/dist/operations/runner.js +14 -15
- package/dist/operations/stats.js +8 -1
- package/dist/operations/store.d.ts +5 -1
- package/dist/operations/store.js +7 -0
- package/dist/ops/circuit-breaker.d.ts +52 -0
- package/dist/ops/circuit-breaker.js +4 -0
- package/dist/ops/circuit-store.d.ts +13 -2
- package/dist/ops/circuit-store.js +68 -0
- package/dist/ops/circuit-sync.d.ts +17 -0
- package/dist/ops/circuit-sync.js +86 -0
- package/dist/ops/health.d.ts +24 -0
- package/dist/ops/health.js +38 -10
- package/dist/ops/index.d.ts +1 -1
- package/dist/ops/index.js +1 -1
- package/dist/ops/rate-limit-adapters.d.ts +23 -0
- package/dist/ops/rate-limit-adapters.js +34 -0
- package/dist/ops/rate-limiter.d.ts +14 -2
- package/dist/ops/rate-limiter.js +31 -0
- package/dist/postgres/circuits.d.ts +21 -4
- package/dist/postgres/circuits.js +65 -4
- package/dist/postgres/client.d.ts +0 -2
- package/dist/postgres/client.js +0 -4
- package/dist/postgres/evaluate.d.ts +16 -4
- package/dist/postgres/evaluate.js +17 -5
- package/dist/postgres/index.d.ts +32 -11
- package/dist/postgres/index.js +65 -31
- package/dist/postgres/migrations.d.ts +60 -0
- package/dist/postgres/migrations.js +121 -0
- package/dist/postgres/operations.d.ts +14 -3
- package/dist/postgres/operations.js +45 -15
- package/dist/postgres/prompts.d.ts +11 -2
- package/dist/postgres/prompts.js +14 -3
- package/dist/postgres/rollups.d.ts +35 -0
- package/dist/postgres/rollups.js +129 -0
- package/dist/postgres/store.d.ts +11 -2
- package/dist/postgres/store.js +14 -3
- package/dist/postgres/traces.d.ts +13 -3
- package/dist/postgres/traces.js +25 -3
- package/dist/postgres/vectors.d.ts +11 -2
- package/dist/postgres/vectors.js +14 -3
- package/dist/router/auto-router.d.ts +34 -7
- package/dist/router/auto-router.js +201 -68
- package/dist/server/assistant.d.ts +44 -0
- package/dist/server/assistant.js +39 -0
- package/dist/server/errors.d.ts +12 -0
- package/dist/server/errors.js +7 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/runs.d.ts +28 -1
- package/dist/server/runs.js +110 -14
- package/dist/sqlite/index.d.ts +16 -3
- package/dist/sqlite/index.js +16 -3
- package/dist/sqlite/migrations.d.ts +26 -0
- package/dist/sqlite/migrations.js +63 -0
- package/dist/sqlite/operations.d.ts +14 -3
- package/dist/sqlite/operations.js +42 -15
- package/dist/sqlite/store.d.ts +9 -2
- package/dist/sqlite/store.js +13 -3
- package/dist/sqlite/vectors.d.ts +11 -2
- package/dist/sqlite/vectors.js +13 -2
- package/dist/store/tenant.d.ts +12 -0
- package/dist/store/tenant.js +29 -0
- package/dist/tenancy/index.d.ts +113 -0
- package/dist/tenancy/index.js +233 -0
- package/dist/testing/record.d.ts +42 -0
- package/dist/testing/record.js +57 -5
- package/dist/tracing/index.d.ts +3 -3
- package/dist/tracing/index.js +2 -2
- package/dist/tracing/instrument.js +30 -0
- package/dist/tracing/otlp.d.ts +91 -0
- package/dist/tracing/otlp.js +124 -0
- package/dist/tracing/rollups.d.ts +100 -0
- package/dist/tracing/rollups.js +139 -0
- package/dist/tracing/stores.d.ts +17 -0
- package/dist/tracing/stores.js +23 -0
- package/dist/tracing/tracer.d.ts +50 -4
- package/dist/tracing/tracer.js +85 -6
- package/dist/types/config.d.ts +33 -2
- package/dist/types/evaluate.d.ts +37 -0
- package/dist/types/graph.d.ts +354 -9
- package/dist/types/graph.js +3 -1
- package/dist/types/messages.d.ts +5 -0
- package/dist/types/operations.d.ts +22 -2
- package/dist/types/response.d.ts +20 -0
- package/dist/types/server.d.ts +18 -0
- package/dist/types/tracing.d.ts +11 -0
- package/dist/utils/schema-migrations.d.ts +97 -0
- package/dist/utils/schema-migrations.js +91 -0
- package/dist/utils/signals.d.ts +17 -0
- package/dist/utils/signals.js +26 -0
- package/dist/utils/tenant.d.ts +14 -0
- package/dist/utils/tenant.js +16 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.js +1 -0
- package/dist-cjs/agent/create-agent.d.ts +9 -1
- package/dist-cjs/agent/create-agent.js +40 -1
- package/dist-cjs/cache/memory-cache.d.ts +8 -0
- package/dist-cjs/cache/memory-cache.js +9 -0
- package/dist-cjs/cache/semantic-cache.d.ts +6 -3
- package/dist-cjs/cache/semantic-cache.js +5 -2
- package/dist-cjs/cli/args.js +3 -0
- package/dist-cjs/cli/db.d.ts +16 -4
- package/dist-cjs/cli/db.js +200 -20
- package/dist-cjs/cli/doctor.d.ts +17 -0
- package/dist-cjs/cli/doctor.js +56 -0
- package/dist-cjs/cli/graph.d.ts +9 -0
- package/dist-cjs/cli/graph.js +50 -0
- package/dist-cjs/core/lifecycle.js +11 -6
- package/dist-cjs/core/nexus.d.ts +12 -2
- package/dist-cjs/core/nexus.js +106 -23
- package/dist-cjs/doctor/index.d.ts +90 -0
- package/dist-cjs/doctor/index.js +276 -0
- package/dist-cjs/evals/judge.d.ts +11 -0
- package/dist-cjs/evals/judge.js +33 -0
- package/dist-cjs/evaluate/index.d.ts +1 -0
- package/dist-cjs/evaluate/index.js +3 -1
- package/dist-cjs/evaluate/provenance.d.ts +22 -0
- package/dist-cjs/evaluate/provenance.js +14 -0
- package/dist-cjs/evaluate/run.js +20 -4
- package/dist-cjs/graph/durability.d.ts +27 -0
- package/dist-cjs/graph/durability.js +70 -0
- package/dist-cjs/graph/errors.d.ts +30 -4
- package/dist-cjs/graph/errors.js +20 -3
- package/dist-cjs/graph/event-stream.d.ts +75 -0
- package/dist-cjs/graph/event-stream.js +295 -0
- package/dist-cjs/graph/functional.d.ts +80 -7
- package/dist-cjs/graph/functional.js +137 -34
- package/dist-cjs/graph/graph.d.ts +56 -8
- package/dist-cjs/graph/graph.js +330 -48
- package/dist-cjs/graph/index.d.ts +4 -2
- package/dist-cjs/graph/index.js +7 -1
- package/dist-cjs/graph/lint.d.ts +57 -0
- package/dist-cjs/graph/lint.js +144 -0
- package/dist-cjs/graph/run-control.d.ts +28 -0
- package/dist-cjs/graph/run-control.js +30 -0
- package/dist-cjs/images/evals.js +4 -2
- package/dist-cjs/operations/adapters.d.ts +52 -4
- package/dist-cjs/operations/adapters.js +193 -6
- package/dist-cjs/operations/runner.js +14 -15
- package/dist-cjs/operations/stats.js +8 -1
- package/dist-cjs/operations/store.d.ts +5 -1
- package/dist-cjs/operations/store.js +7 -0
- package/dist-cjs/ops/circuit-breaker.d.ts +52 -0
- package/dist-cjs/ops/circuit-breaker.js +4 -0
- package/dist-cjs/ops/circuit-store.d.ts +13 -2
- package/dist-cjs/ops/circuit-store.js +68 -0
- package/dist-cjs/ops/circuit-sync.d.ts +17 -0
- package/dist-cjs/ops/circuit-sync.js +87 -0
- package/dist-cjs/ops/health.d.ts +24 -0
- package/dist-cjs/ops/health.js +38 -10
- package/dist-cjs/ops/index.d.ts +1 -1
- package/dist-cjs/ops/rate-limit-adapters.d.ts +23 -0
- package/dist-cjs/ops/rate-limit-adapters.js +35 -1
- package/dist-cjs/ops/rate-limiter.d.ts +14 -2
- package/dist-cjs/ops/rate-limiter.js +32 -0
- package/dist-cjs/postgres/circuits.d.ts +21 -4
- package/dist-cjs/postgres/circuits.js +98 -3
- package/dist-cjs/postgres/client.d.ts +0 -2
- package/dist-cjs/postgres/client.js +0 -5
- package/dist-cjs/postgres/evaluate.d.ts +16 -4
- package/dist-cjs/postgres/evaluate.js +50 -4
- package/dist-cjs/postgres/index.d.ts +32 -11
- package/dist-cjs/postgres/index.js +69 -20
- package/dist-cjs/postgres/migrations.d.ts +60 -0
- package/dist-cjs/postgres/migrations.js +129 -0
- package/dist-cjs/postgres/operations.d.ts +14 -3
- package/dist-cjs/postgres/operations.js +78 -14
- package/dist-cjs/postgres/prompts.d.ts +11 -2
- package/dist-cjs/postgres/prompts.js +47 -2
- package/dist-cjs/postgres/rollups.d.ts +35 -0
- package/dist-cjs/postgres/rollups.js +168 -0
- package/dist-cjs/postgres/store.d.ts +11 -2
- package/dist-cjs/postgres/store.js +47 -2
- package/dist-cjs/postgres/traces.d.ts +13 -3
- package/dist-cjs/postgres/traces.js +58 -2
- package/dist-cjs/postgres/vectors.d.ts +11 -2
- package/dist-cjs/postgres/vectors.js +47 -2
- package/dist-cjs/router/auto-router.d.ts +34 -7
- package/dist-cjs/router/auto-router.js +201 -68
- package/dist-cjs/server/assistant.d.ts +44 -0
- package/dist-cjs/server/assistant.js +39 -0
- package/dist-cjs/server/errors.d.ts +12 -0
- package/dist-cjs/server/errors.js +9 -1
- package/dist-cjs/server/index.d.ts +1 -1
- package/dist-cjs/server/index.js +2 -1
- package/dist-cjs/server/runs.d.ts +28 -1
- package/dist-cjs/server/runs.js +109 -13
- package/dist-cjs/sqlite/index.d.ts +16 -3
- package/dist-cjs/sqlite/index.js +31 -10
- package/dist-cjs/sqlite/migrations.d.ts +26 -0
- package/dist-cjs/sqlite/migrations.js +71 -0
- package/dist-cjs/sqlite/operations.d.ts +14 -3
- package/dist-cjs/sqlite/operations.js +76 -15
- package/dist-cjs/sqlite/store.d.ts +9 -2
- package/dist-cjs/sqlite/store.js +47 -3
- package/dist-cjs/sqlite/vectors.d.ts +11 -2
- package/dist-cjs/sqlite/vectors.js +47 -2
- package/dist-cjs/store/tenant.d.ts +12 -0
- package/dist-cjs/store/tenant.js +33 -0
- package/dist-cjs/tenancy/index.d.ts +113 -0
- package/dist-cjs/tenancy/index.js +250 -0
- package/dist-cjs/testing/record.d.ts +42 -0
- package/dist-cjs/testing/record.js +57 -5
- package/dist-cjs/tracing/index.d.ts +3 -3
- package/dist-cjs/tracing/index.js +4 -1
- package/dist-cjs/tracing/instrument.js +30 -0
- package/dist-cjs/tracing/otlp.d.ts +91 -0
- package/dist-cjs/tracing/otlp.js +129 -0
- package/dist-cjs/tracing/rollups.d.ts +100 -0
- package/dist-cjs/tracing/rollups.js +147 -0
- package/dist-cjs/tracing/stores.d.ts +17 -0
- package/dist-cjs/tracing/stores.js +24 -0
- package/dist-cjs/tracing/tracer.d.ts +50 -4
- package/dist-cjs/tracing/tracer.js +87 -6
- package/dist-cjs/types/config.d.ts +33 -2
- package/dist-cjs/types/evaluate.d.ts +37 -0
- package/dist-cjs/types/graph.d.ts +354 -9
- package/dist-cjs/types/graph.js +3 -1
- package/dist-cjs/types/messages.d.ts +5 -0
- package/dist-cjs/types/operations.d.ts +22 -2
- package/dist-cjs/types/response.d.ts +20 -0
- package/dist-cjs/types/server.d.ts +18 -0
- package/dist-cjs/types/tracing.d.ts +11 -0
- package/dist-cjs/utils/schema-migrations.d.ts +97 -0
- package/dist-cjs/utils/schema-migrations.js +102 -0
- package/dist-cjs/utils/signals.d.ts +17 -0
- package/dist-cjs/utils/signals.js +29 -0
- package/dist-cjs/utils/tenant.d.ts +14 -0
- package/dist-cjs/utils/tenant.js +22 -0
- package/dist-cjs/version.d.ts +5 -0
- package/dist-cjs/version.js +4 -0
- package/llms.txt +4 -3
- package/package.json +110 -2
|
@@ -5,18 +5,28 @@ exports.workflow = workflow;
|
|
|
5
5
|
const checkpointer_js_1 = require("./checkpointer.js");
|
|
6
6
|
const run_js_1 = require("../lifecycle/run.js");
|
|
7
7
|
const checkpoint_migration_js_1 = require("./checkpoint-migration.js");
|
|
8
|
+
const tenant_js_1 = require("../store/tenant.js");
|
|
8
9
|
const errors_js_1 = require("./errors.js");
|
|
9
10
|
class WorkflowStepTimeoutError extends errors_js_1.GraphError {
|
|
10
11
|
stepName;
|
|
11
12
|
timeoutMs;
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
kind;
|
|
14
|
+
constructor(stepName, timeoutMs, kind = 'run') {
|
|
15
|
+
super(kind === 'idle'
|
|
16
|
+
? `Step "${stepName}" made no progress for ${timeoutMs} ms`
|
|
17
|
+
: `Step "${stepName}" exceeded its ${timeoutMs} ms timeout`, 'WORKFLOW_STEP_TIMEOUT');
|
|
14
18
|
this.stepName = stepName;
|
|
15
19
|
this.timeoutMs = timeoutMs;
|
|
20
|
+
this.kind = kind;
|
|
16
21
|
this.name = 'WorkflowStepTimeoutError';
|
|
17
22
|
}
|
|
18
23
|
}
|
|
19
24
|
exports.WorkflowStepTimeoutError = WorkflowStepTimeoutError;
|
|
25
|
+
class WorkflowDraining extends Error {
|
|
26
|
+
constructor() {
|
|
27
|
+
super('The workflow is draining');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
20
30
|
class WorkflowSuspended extends Error {
|
|
21
31
|
pending;
|
|
22
32
|
constructor(pending) {
|
|
@@ -45,10 +55,16 @@ class Workflow {
|
|
|
45
55
|
}
|
|
46
56
|
stream(input, runOptions = {}) {
|
|
47
57
|
const threadId = runOptions.threadId ?? generatedId();
|
|
48
|
-
return this.execute(threadId, runOptions, async () =>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
return this.execute(threadId, runOptions, async () => {
|
|
59
|
+
const latest = await this.latest(threadId);
|
|
60
|
+
if (latest && runOptions.tenantId !== undefined) {
|
|
61
|
+
const owner = latest.metadata?.tenantId;
|
|
62
|
+
if (typeof owner === 'string' && owner !== runOptions.tenantId) {
|
|
63
|
+
throw new errors_js_1.GraphError(`Thread "${threadId}" cannot be used by this tenant; choose another id`, 'GRAPH_VALIDATION_ERROR');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return { ...this.fresh(threadId, input), step: latest?.step ?? 0 };
|
|
67
|
+
});
|
|
52
68
|
}
|
|
53
69
|
resume(threadId, value, runOptions = {}) {
|
|
54
70
|
return this.execute(threadId, runOptions, async () => {
|
|
@@ -142,11 +158,21 @@ class Workflow {
|
|
|
142
158
|
}
|
|
143
159
|
async run(threadId, runOptions, start, queue) {
|
|
144
160
|
const initial = await start();
|
|
161
|
+
const owner = typeof initial.metadata?.tenantId === 'string' ? initial.metadata.tenantId : undefined;
|
|
162
|
+
if (runOptions.tenantId !== undefined && owner !== undefined && owner !== runOptions.tenantId) {
|
|
163
|
+
throw new errors_js_1.GraphThreadNotFoundError(threadId);
|
|
164
|
+
}
|
|
165
|
+
const tenantId = runOptions.tenantId ?? owner;
|
|
145
166
|
const checkpointer = this.checkpointer();
|
|
146
167
|
const state = structuredClone(initial.state);
|
|
147
168
|
state.steps ??= {};
|
|
148
169
|
const resolved = { ...initial.resolved };
|
|
149
|
-
const metadata = {
|
|
170
|
+
const metadata = {
|
|
171
|
+
...initial.metadata,
|
|
172
|
+
graph: this.name,
|
|
173
|
+
...runOptions.metadata,
|
|
174
|
+
...(tenantId === undefined ? {} : { tenantId }),
|
|
175
|
+
};
|
|
150
176
|
let stepNumber = initial.step;
|
|
151
177
|
let writes = Promise.resolve();
|
|
152
178
|
const persist = (checkpoint) => {
|
|
@@ -176,11 +202,16 @@ class Workflow {
|
|
|
176
202
|
const inFlight = new Set();
|
|
177
203
|
const suspended = [];
|
|
178
204
|
let interruptIndex = 0;
|
|
205
|
+
let drained = false;
|
|
179
206
|
const limiter = new Limiter(this.options.maxConcurrency ?? 16);
|
|
207
|
+
const defaults = this.options.stepDefaults ?? {};
|
|
180
208
|
const context = {
|
|
181
209
|
threadId,
|
|
210
|
+
...(tenantId === undefined ? {} : { tenantId }),
|
|
182
211
|
signal: controller.signal,
|
|
183
|
-
...(this.options.store
|
|
212
|
+
...(this.options.store
|
|
213
|
+
? { store: tenantId === undefined ? this.options.store : (0, tenant_js_1.tenantStore)(this.options.store, tenantId) }
|
|
214
|
+
: {}),
|
|
184
215
|
step: (name, run, options = {}) => {
|
|
185
216
|
const count = (counts.get(name) ?? 0) + 1;
|
|
186
217
|
counts.set(name, count);
|
|
@@ -190,10 +221,22 @@ class Workflow {
|
|
|
190
221
|
queue.push({ type: 'step', step: stepNumber, name, key, cached: true, state: snapshot(), status: 'running' });
|
|
191
222
|
return Promise.resolve(recorded.value);
|
|
192
223
|
}
|
|
224
|
+
if (runOptions.control?.draining) {
|
|
225
|
+
drained = true;
|
|
226
|
+
return Promise.reject(new WorkflowDraining());
|
|
227
|
+
}
|
|
228
|
+
const merged = {
|
|
229
|
+
...defaults,
|
|
230
|
+
...options,
|
|
231
|
+
timeout: { ...defaults.timeout, ...options.timeout },
|
|
232
|
+
};
|
|
193
233
|
const work = limiter
|
|
194
|
-
.run(() => this.runStep(name, key, run, { ...this.options.retry, ...options.retry },
|
|
195
|
-
.then(async (value) => {
|
|
196
|
-
state.steps[key] =
|
|
234
|
+
.run(() => this.runStep(name, key, run, { ...this.options.retry, ...defaults.retry, ...options.retry }, merged, controller.signal, runOptions, stepNumber))
|
|
235
|
+
.then(async ({ value, recovered }) => {
|
|
236
|
+
state.steps[key] = {
|
|
237
|
+
...(value === undefined ? {} : { value: structuredClone(value) }),
|
|
238
|
+
...(recovered ? { recovered } : {}),
|
|
239
|
+
};
|
|
197
240
|
await persist({ state: state, next: [this.name], status: 'running' });
|
|
198
241
|
queue.push({
|
|
199
242
|
type: 'step',
|
|
@@ -267,6 +310,18 @@ class Workflow {
|
|
|
267
310
|
queue.push({ type: 'interrupt', step: stepNumber, state: snapshot(), status: 'interrupted' });
|
|
268
311
|
return;
|
|
269
312
|
}
|
|
313
|
+
if (drained && outcome.kind === 'failed') {
|
|
314
|
+
const reason = runOptions.control?.reason;
|
|
315
|
+
await persist({
|
|
316
|
+
state: state,
|
|
317
|
+
next: [this.name],
|
|
318
|
+
status: 'interrupted',
|
|
319
|
+
resolved,
|
|
320
|
+
drained: { ...(reason ? { reason } : {}), at: this.now().toISOString() },
|
|
321
|
+
});
|
|
322
|
+
await writes;
|
|
323
|
+
throw new errors_js_1.GraphDrainedError(threadId, stepNumber, reason);
|
|
324
|
+
}
|
|
270
325
|
if (outcome.kind === 'failed') {
|
|
271
326
|
const error = outcome.error;
|
|
272
327
|
await persist({
|
|
@@ -289,41 +344,87 @@ class Workflow {
|
|
|
289
344
|
}
|
|
290
345
|
async runStep(name, key, run, retry, options, signal, runOptions, step) {
|
|
291
346
|
const policy = { ...DEFAULT_RETRY, ...retry };
|
|
347
|
+
const runMs = options.timeoutMs ?? options.timeout?.runMs;
|
|
348
|
+
const idleMs = options.timeout?.idleMs;
|
|
292
349
|
for (let attempt = 1;; attempt += 1) {
|
|
293
350
|
notify(runOptions, { type: 'task_start', step, taskId: key, node: name, attempt });
|
|
294
351
|
const stepController = new AbortController();
|
|
295
352
|
const forward = () => stepController.abort(signal.reason);
|
|
296
353
|
signal.addEventListener('abort', forward, { once: true });
|
|
297
|
-
let
|
|
298
|
-
let
|
|
354
|
+
let runTimer;
|
|
355
|
+
let idleTimer;
|
|
356
|
+
let timedOut;
|
|
357
|
+
let expire = () => undefined;
|
|
358
|
+
const limits = runMs === undefined && idleMs === undefined
|
|
359
|
+
? undefined
|
|
360
|
+
: new Promise((_, reject) => {
|
|
361
|
+
expire = (error) => {
|
|
362
|
+
if (timedOut)
|
|
363
|
+
return;
|
|
364
|
+
timedOut = error;
|
|
365
|
+
reject(error);
|
|
366
|
+
stepController.abort();
|
|
367
|
+
};
|
|
368
|
+
});
|
|
369
|
+
limits?.catch(() => undefined);
|
|
370
|
+
if (runMs !== undefined)
|
|
371
|
+
runTimer = setTimeout(() => expire(new WorkflowStepTimeoutError(name, runMs)), runMs);
|
|
372
|
+
const armIdle = () => {
|
|
373
|
+
if (idleMs === undefined || timedOut)
|
|
374
|
+
return;
|
|
375
|
+
if (idleTimer)
|
|
376
|
+
clearTimeout(idleTimer);
|
|
377
|
+
idleTimer = setTimeout(() => expire(new WorkflowStepTimeoutError(name, idleMs, 'idle')), idleMs);
|
|
378
|
+
};
|
|
379
|
+
armIdle();
|
|
299
380
|
try {
|
|
300
|
-
const work = Promise.resolve(run({ name, key, attempt, signal: stepController.signal }));
|
|
301
|
-
const value =
|
|
302
|
-
? await work
|
|
303
|
-
: await Promise.race([
|
|
304
|
-
work,
|
|
305
|
-
new Promise((_, reject) => {
|
|
306
|
-
timer = setTimeout(() => {
|
|
307
|
-
timedOut = true;
|
|
308
|
-
reject(new WorkflowStepTimeoutError(name, options.timeoutMs));
|
|
309
|
-
stepController.abort();
|
|
310
|
-
}, options.timeoutMs);
|
|
311
|
-
}),
|
|
312
|
-
]);
|
|
381
|
+
const work = Promise.resolve(run({ name, key, attempt, signal: stepController.signal, heartbeat: armIdle }));
|
|
382
|
+
const value = limits ? await Promise.race([work, limits]) : await work;
|
|
313
383
|
if (timedOut)
|
|
314
|
-
throw
|
|
384
|
+
throw timedOut;
|
|
315
385
|
notify(runOptions, { type: 'task_end', step, taskId: key, node: name, update: value });
|
|
316
|
-
return value;
|
|
386
|
+
return { value };
|
|
317
387
|
}
|
|
318
388
|
catch (error) {
|
|
319
389
|
if (signal.aborted || error instanceof WorkflowSuspended)
|
|
320
390
|
throw error;
|
|
321
|
-
const failure = timedOut
|
|
391
|
+
const failure = timedOut ?? error;
|
|
322
392
|
const retryable = policy.retryOn
|
|
323
393
|
? policy.retryOn(failure, attempt)
|
|
324
|
-
: !(failure instanceof errors_js_1.GraphError) || timedOut;
|
|
325
|
-
if (attempt >= Math.max(1, policy.maxAttempts) || !retryable)
|
|
326
|
-
|
|
394
|
+
: !(failure instanceof errors_js_1.GraphError) || timedOut !== undefined;
|
|
395
|
+
if (attempt >= Math.max(1, policy.maxAttempts) || !retryable) {
|
|
396
|
+
if (!options.onError)
|
|
397
|
+
throw failure;
|
|
398
|
+
const failed = (recovered) => notify(runOptions, {
|
|
399
|
+
type: 'task_failed',
|
|
400
|
+
step,
|
|
401
|
+
taskId: key,
|
|
402
|
+
node: name,
|
|
403
|
+
attempts: attempt,
|
|
404
|
+
error: failure instanceof Error ? failure.message : String(failure),
|
|
405
|
+
recovered,
|
|
406
|
+
});
|
|
407
|
+
let value;
|
|
408
|
+
try {
|
|
409
|
+
value = await options.onError({ name, key, attempts: attempt, error: failure });
|
|
410
|
+
}
|
|
411
|
+
catch (decision) {
|
|
412
|
+
failed(false);
|
|
413
|
+
throw decision;
|
|
414
|
+
}
|
|
415
|
+
failed(true);
|
|
416
|
+
notify(runOptions, { type: 'task_end', step, taskId: key, node: name, update: value });
|
|
417
|
+
return {
|
|
418
|
+
value,
|
|
419
|
+
recovered: {
|
|
420
|
+
error: {
|
|
421
|
+
name: failure instanceof Error ? failure.name : 'Error',
|
|
422
|
+
message: failure instanceof Error ? failure.message : String(failure),
|
|
423
|
+
},
|
|
424
|
+
attempts: attempt,
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
}
|
|
327
428
|
notify(runOptions, {
|
|
328
429
|
type: 'task_retry',
|
|
329
430
|
step,
|
|
@@ -335,8 +436,10 @@ class Workflow {
|
|
|
335
436
|
await sleep(backoff(policy, attempt), signal);
|
|
336
437
|
}
|
|
337
438
|
finally {
|
|
338
|
-
if (
|
|
339
|
-
clearTimeout(
|
|
439
|
+
if (runTimer)
|
|
440
|
+
clearTimeout(runTimer);
|
|
441
|
+
if (idleTimer)
|
|
442
|
+
clearTimeout(idleTimer);
|
|
340
443
|
signal.removeEventListener('abort', forward);
|
|
341
444
|
}
|
|
342
445
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { ChannelSchema, CompileOptions, EdgeRouter, GraphCheckpoint, GraphDescription, GraphInput, GraphProgress, GraphResult, GraphRunOptions, GraphStatus, GraphStepEvent, NodeFn, NodeOptions, StateUpdate } from '../types/graph.js';
|
|
1
|
+
import type { ChannelSchema, CompileOptions, EdgeRouter, GraphCheckpoint, GraphDescription, GraphEventsOptions, GraphInput, GraphProgress, GraphResult, GraphRunOptions, GraphStatus, GraphStepEvent, NodeFn, NodeOptions, StateUpdate } from '../types/graph.js';
|
|
2
|
+
import { GraphEventStream } from './event-stream.js';
|
|
2
3
|
interface GraphNodeDefinition<S extends ChannelSchema> {
|
|
3
4
|
fn: NodeFn<S>;
|
|
4
|
-
options: NodeOptions
|
|
5
|
+
options: NodeOptions<S>;
|
|
5
6
|
}
|
|
6
7
|
/** Which channels a caller may write and read, as `createGraph()` declared them. */
|
|
7
8
|
interface GraphScope {
|
|
@@ -29,7 +30,7 @@ export declare class StateGraph<S extends ChannelSchema, I extends keyof S = key
|
|
|
29
30
|
private readonly edges;
|
|
30
31
|
constructor(channels: S, scope?: GraphScope);
|
|
31
32
|
/** Adds a node. Returns the graph, for chaining. */
|
|
32
|
-
addNode(name: string, fn: NodeFn<S>, options?: NodeOptions): this;
|
|
33
|
+
addNode(name: string, fn: NodeFn<S>, options?: NodeOptions<S>): this;
|
|
33
34
|
/** Adds an edge that always runs `to` after `from`. Returns the graph, for chaining. */
|
|
34
35
|
addEdge(from: string, to: string): this;
|
|
35
36
|
/**
|
|
@@ -55,11 +56,33 @@ export declare class CompiledGraph<S extends ChannelSchema, I extends keyof S =
|
|
|
55
56
|
private readonly store;
|
|
56
57
|
/** Loaded the first time a node that declares `cache` runs, and not before. */
|
|
57
58
|
private nodeCache;
|
|
59
|
+
/** The checkpoint writers of runs in progress, so `flush()` can wait for them. */
|
|
60
|
+
private readonly writers;
|
|
58
61
|
constructor(channels: S, nodes: Map<string, GraphNodeDefinition<S>>, edges: Array<Edge<S>>, options: CompileOptions, scope?: GraphScope);
|
|
62
|
+
/**
|
|
63
|
+
* Waits until every checkpoint written by runs in progress is in the store. Only `async` and
|
|
64
|
+
* `exit` durability leave any outstanding; a run always waits for its own before it returns.
|
|
65
|
+
*/
|
|
66
|
+
flush(): Promise<void>;
|
|
59
67
|
/** Runs to completion, to an interrupt, or to the step limit. */
|
|
60
68
|
invoke(input?: GraphInput<S, I>, runOptions?: GraphRunOptions): Promise<GraphResult<S, O>>;
|
|
61
69
|
/** Yields one event per superstep, so a caller can render progress as it happens. */
|
|
62
70
|
stream(input?: GraphInput<S, I>, runOptions?: GraphRunOptions): AsyncIterable<GraphStepEvent<S>>;
|
|
71
|
+
/**
|
|
72
|
+
* Runs the graph as one stream of typed events: the state after each superstep, each task's write,
|
|
73
|
+
* model output as nodes stream it, tool calls, task progress, checkpoints, and custom events.
|
|
74
|
+
*
|
|
75
|
+
* Iterate it for everything included, or read one projection with `messages()`, `tools()`,
|
|
76
|
+
* `values()`, or `updates()`. Each reader has its own bounded buffer, and the run waits for the
|
|
77
|
+
* slowest at the end of every superstep, so a slow reader slows the graph rather than filling
|
|
78
|
+
* memory. `result` resolves with the run's result.
|
|
79
|
+
*/
|
|
80
|
+
events(input?: GraphInput<S, I>, options?: GraphEventsOptions): GraphEventStream<S, O>;
|
|
81
|
+
/** Like `events()`, answering the question a paused thread is waiting on. */
|
|
82
|
+
resumeEvents(threadId: string, value: unknown, options?: GraphEventsOptions): GraphEventStream<S, O>;
|
|
83
|
+
/** Like `events()`, carrying a thread on from a breakpoint, a drain, or a failure. */
|
|
84
|
+
continueEvents(threadId: string, options?: GraphEventsOptions): GraphEventStream<S, O>;
|
|
85
|
+
private eventStream;
|
|
63
86
|
/**
|
|
64
87
|
* Supplies the value a node asked for and continues.
|
|
65
88
|
*
|
|
@@ -88,10 +111,17 @@ export declare class CompiledGraph<S extends ChannelSchema, I extends keyof S =
|
|
|
88
111
|
* once the rewound checkpoint is written.
|
|
89
112
|
*/
|
|
90
113
|
resumeFrom(threadId: string, step: number, runOptions?: GraphRunOptions): AsyncIterable<GraphStepEvent<S>>;
|
|
91
|
-
/**
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Latest checkpoint, or the one at `step`. With a `tenantId`, a thread another tenant owns reads
|
|
116
|
+
* as absent.
|
|
117
|
+
*/
|
|
118
|
+
state(threadId: string, step?: number, options?: {
|
|
119
|
+
tenantId?: string;
|
|
120
|
+
}): Promise<GraphCheckpoint<S> | undefined>;
|
|
121
|
+
/** Checkpoints for a thread, newest first. With a `tenantId`, another tenant's thread has none. */
|
|
122
|
+
history(threadId: string, limit?: number, options?: {
|
|
123
|
+
tenantId?: string;
|
|
124
|
+
}): Promise<Array<GraphCheckpoint<S>>>;
|
|
95
125
|
/**
|
|
96
126
|
* Wraps this graph as a node in another graph.
|
|
97
127
|
*
|
|
@@ -120,26 +150,44 @@ export declare class CompiledGraph<S extends ChannelSchema, I extends keyof S =
|
|
|
120
150
|
*/
|
|
121
151
|
updateState(threadId: string, update: StateUpdate<S>, options?: {
|
|
122
152
|
asNode?: string;
|
|
153
|
+
tenantId?: string;
|
|
123
154
|
}): Promise<GraphCheckpoint<S>>;
|
|
124
155
|
/**
|
|
125
156
|
* Copies a thread's history up to `step` into a new thread, and returns the new thread's id.
|
|
126
157
|
*
|
|
127
158
|
* Rewinding with `resumeFrom()` replaces the original timeline. A fork keeps it: both threads stay
|
|
128
159
|
* readable and runnable, so two answers to the same question can be compared side by side. Every
|
|
129
|
-
* copied checkpoint records `metadata.forkedFrom
|
|
160
|
+
* copied checkpoint records `metadata.forkedFrom`, and keeps the tenant of the thread it came from.
|
|
161
|
+
* With a `tenantId`, another tenant's thread is not found.
|
|
130
162
|
*/
|
|
131
163
|
fork(threadId: string, options?: {
|
|
132
164
|
step?: number;
|
|
133
165
|
threadId?: string;
|
|
166
|
+
tenantId?: string;
|
|
134
167
|
}): Promise<string>;
|
|
135
168
|
/**
|
|
136
169
|
* Runs the supersteps, as one operation of the compiled lifecycle when there is one. The run is
|
|
137
170
|
* admitted before its first superstep and finishes with its last, however it ends.
|
|
138
171
|
*/
|
|
139
172
|
private run;
|
|
173
|
+
/**
|
|
174
|
+
* Runs the step loop with a checkpoint writer for the run's durability mode. However the run ends,
|
|
175
|
+
* every checkpoint it handed over is in the store before this returns or throws.
|
|
176
|
+
*/
|
|
140
177
|
private runSteps;
|
|
178
|
+
private steps;
|
|
141
179
|
/** Runs one task to a verdict, applying its retry policy and timeout. */
|
|
142
180
|
private runTask;
|
|
181
|
+
/**
|
|
182
|
+
* Hands a failure to the node's `onError`, and turns what it decides into the task's result. With
|
|
183
|
+
* no handler, or for a mistake in the graph itself, the task fails as it always did.
|
|
184
|
+
*/
|
|
185
|
+
private recover;
|
|
186
|
+
/** The node's retry policy over the graph's defaults. */
|
|
187
|
+
private retryPolicy;
|
|
188
|
+
/** The node's run and idle limits over the graph's defaults. `timeout.runMs` wins over `timeoutMs`. */
|
|
189
|
+
private timeoutOf;
|
|
190
|
+
private errorHandler;
|
|
143
191
|
private runNode;
|
|
144
192
|
private loadNodeCache;
|
|
145
193
|
/** Rejects writes to channels the graph does not accept from a caller. */
|