nexus-ai-pro 1.19.0 → 1.21.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 +26 -2
- package/CHANGELOG.md +80 -1
- package/README.md +15 -29
- package/dist/cli/db.js +12 -1
- package/dist/graph/functional.d.ts +217 -0
- package/dist/graph/functional.js +431 -0
- package/dist/graph/layout.d.ts +55 -0
- package/dist/graph/layout.js +68 -0
- package/dist/graph/visualize.d.ts +32 -0
- package/dist/graph/visualize.js +59 -0
- package/dist/hallucination/retrieval.d.ts +31 -2
- package/dist/hallucination/retrieval.js +31 -14
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/ops/health.js +2 -0
- package/dist/ops/metrics.js +2 -0
- package/dist/optimizer/index.js +2 -0
- package/dist/postgres/index.d.ts +7 -3
- package/dist/postgres/index.js +8 -0
- package/dist/postgres/vectors.d.ts +46 -0
- package/dist/postgres/vectors.js +100 -0
- package/dist/providers/google.js +2 -0
- package/dist/providers/ollama.js +2 -0
- package/dist/rag/ingestion.d.ts +2 -0
- package/dist/rag/ingestion.js +1 -0
- package/dist/rag/qdrant.d.ts +65 -0
- package/dist/rag/qdrant.js +126 -0
- package/dist/security/index.d.ts +6 -4
- package/dist/security/index.js +13 -6
- package/dist/server/assistant.d.ts +11 -0
- package/dist/server/assistant.js +14 -0
- package/dist/server/runs.js +9 -4
- package/dist/sqlite/client.d.ts +63 -0
- package/dist/sqlite/client.js +52 -0
- package/dist/sqlite/index.d.ts +3 -0
- package/dist/sqlite/index.js +3 -0
- package/dist/sqlite/operations.d.ts +52 -0
- package/dist/sqlite/operations.js +111 -0
- package/dist/sqlite/store.d.ts +49 -0
- package/dist/sqlite/store.js +131 -0
- package/dist/types/server.d.ts +9 -0
- package/dist/utils/deprecation.d.ts +12 -0
- package/dist/utils/deprecation.js +17 -0
- package/dist/workflow/chains.d.ts +3 -2
- package/dist/workflow/chains.js +1 -0
- package/dist-cjs/cli/db.js +12 -1
- package/dist-cjs/graph/functional.d.ts +217 -0
- package/dist-cjs/graph/functional.js +437 -0
- package/dist-cjs/graph/layout.d.ts +55 -0
- package/dist-cjs/graph/layout.js +71 -0
- package/dist-cjs/graph/visualize.d.ts +32 -0
- package/dist-cjs/graph/visualize.js +62 -0
- package/dist-cjs/hallucination/retrieval.d.ts +31 -2
- package/dist-cjs/hallucination/retrieval.js +32 -14
- package/dist-cjs/index.d.ts +1 -1
- package/dist-cjs/index.js +5 -3
- package/dist-cjs/ops/health.js +2 -0
- package/dist-cjs/ops/metrics.js +2 -0
- package/dist-cjs/optimizer/index.js +2 -0
- package/dist-cjs/postgres/index.d.ts +7 -3
- package/dist-cjs/postgres/index.js +11 -1
- package/dist-cjs/postgres/vectors.d.ts +46 -0
- package/dist-cjs/postgres/vectors.js +105 -0
- package/dist-cjs/providers/google.js +2 -0
- package/dist-cjs/providers/ollama.js +2 -0
- package/dist-cjs/rag/ingestion.d.ts +2 -0
- package/dist-cjs/rag/ingestion.js +7 -0
- package/dist-cjs/rag/qdrant.d.ts +65 -0
- package/dist-cjs/rag/qdrant.js +131 -0
- package/dist-cjs/security/index.d.ts +6 -4
- package/dist-cjs/security/index.js +21 -10
- package/dist-cjs/server/assistant.d.ts +11 -0
- package/dist-cjs/server/assistant.js +14 -0
- package/dist-cjs/server/runs.js +9 -4
- package/dist-cjs/sqlite/client.d.ts +63 -0
- package/dist-cjs/sqlite/client.js +59 -0
- package/dist-cjs/sqlite/index.d.ts +3 -0
- package/dist-cjs/sqlite/index.js +12 -0
- package/dist-cjs/sqlite/operations.d.ts +52 -0
- package/dist-cjs/sqlite/operations.js +116 -0
- package/dist-cjs/sqlite/store.d.ts +49 -0
- package/dist-cjs/sqlite/store.js +136 -0
- package/dist-cjs/types/server.d.ts +9 -0
- package/dist-cjs/utils/deprecation.d.ts +12 -0
- package/dist-cjs/utils/deprecation.js +21 -0
- package/dist-cjs/workflow/chains.d.ts +3 -2
- package/dist-cjs/workflow/chains.js +6 -0
- package/package.json +80 -2
package/API_STABILITY.md
CHANGED
|
@@ -439,8 +439,9 @@ from the root.
|
|
|
439
439
|
that reconnects with an id never receives it again.
|
|
440
440
|
- The server is not a security boundary on its own: authentication, authorization beyond tenancy and
|
|
441
441
|
scopes, and rate limiting are the application's, through the hooks.
|
|
442
|
-
- Recovery
|
|
443
|
-
should be idempotent or
|
|
442
|
+
- Recovery repeats the step a run died in for graphs and workflows served by `graphAssistant()`, and
|
|
443
|
+
the whole run for any other assistant, so the repeated part should be idempotent or the run left at a
|
|
444
|
+
single attempt.
|
|
444
445
|
|
|
445
446
|
## Studio stage (1.19.0)
|
|
446
447
|
|
|
@@ -455,6 +456,29 @@ with nexus-ai-pro and declares the core versions it works with as a peer depende
|
|
|
455
456
|
- The access rules are a guarantee: loopback binding by default, a token on every request, the token
|
|
456
457
|
in a header for every change, and loopback hosts only unless others are allowed.
|
|
457
458
|
|
|
459
|
+
## Durable execution stage (1.21.0)
|
|
460
|
+
|
|
461
|
+
Functional workflows (`nexus-ai-pro/graph/functional`) and the SQLite adapters (`nexus-ai-pro/sqlite`)
|
|
462
|
+
are experimental in production readiness. Their contracts follow the 1.x rules.
|
|
463
|
+
|
|
464
|
+
- A workflow checkpoint is a graph checkpoint whose state holds the input, the recorded step results
|
|
465
|
+
keyed by step name and call order, and the output. That layout is stable across 1.x, so a thread
|
|
466
|
+
started by one release resumes on the next.
|
|
467
|
+
- The SQLite table layouts may gain columns in a minor release; `migrate()` adds what is missing.
|
|
468
|
+
- `ServerAssistant.recover()` and `AssistantRunContext.attempt` are optional additions: an assistant
|
|
469
|
+
without `recover()` behaves as before.
|
|
470
|
+
|
|
471
|
+
## Retrieval stores stage (1.20.0)
|
|
472
|
+
|
|
473
|
+
`PostgresVectorStore` (`nexus-ai-pro/postgres/vectors`) and `QdrantVectorStore` (`nexus-ai-pro/rag/qdrant`)
|
|
474
|
+
are experimental in production readiness. The `VectorStore` contract they share with
|
|
475
|
+
`MemoryVectorStore` follows the 1.x rules: a minor release may add optional methods and options, not
|
|
476
|
+
remove or reshape these.
|
|
477
|
+
|
|
478
|
+
- The pgvector table layout may gain columns in a minor release; `migrate()` adds what is missing.
|
|
479
|
+
- A Qdrant point id is derived from the chunk id and is stable across releases, so a collection
|
|
480
|
+
written by one version is read by the next.
|
|
481
|
+
|
|
458
482
|
## Deprecation process
|
|
459
483
|
|
|
460
484
|
Deprecated APIs are marked with `@deprecated` in declarations and described in the changelog. Removals
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,83 @@ Notable changes to this project are recorded here. The format follows [Keep a Ch
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.21.0] - 2026-09-29
|
|
8
|
+
|
|
9
|
+
Durable execution everywhere. Durability no longer requires drawing a graph, and a crash costs a
|
|
10
|
+
step rather than a run.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Functional workflows**, experimental, on `nexus-ai-pro/graph/functional`. `workflow()` makes an
|
|
15
|
+
ordinary async function durable: each `step()` records its result, so a workflow that is resumed,
|
|
16
|
+
continued, or recovered on another worker returns finished steps from its checkpoint and carries on
|
|
17
|
+
from the first that did not finish. Steps run in parallel through `Promise.all`, bounded by
|
|
18
|
+
`maxConcurrency`, with per-step retries and timeouts; `interrupt()` pauses for a person exactly as in
|
|
19
|
+
a graph node; and the checkpoints are ordinary graph checkpoints, so every checkpointer stores
|
|
20
|
+
them, `traceGraph()` records them, and `graphAssistant()` serves a workflow on the agent server.
|
|
21
|
+
- **Step-level recovery in the agent server.** A run recovered after its worker died continues from
|
|
22
|
+
the last checkpoint that run wrote — for graphs and workflows served by `graphAssistant()` — so
|
|
23
|
+
only the step in flight runs again. `AssistantRunContext.attempt` reports the attempt, and the new
|
|
24
|
+
optional `ServerAssistant.recover()` hook is how an assistant continues.
|
|
25
|
+
- **SQLite persistence** on `nexus-ai-pro/sqlite`: `SqliteOperationStore` for durable operations and,
|
|
26
|
+
through `OperationStoreCheckpointer`, graph and workflow checkpoints; and `SqliteStore` for
|
|
27
|
+
long-term memory. Both take the database you open — `node:sqlite` and `better-sqlite3` directly,
|
|
28
|
+
libSQL through `fromLibsql()` — so no driver is a dependency, and both pass the same contract tests as
|
|
29
|
+
the memory, Redis, and Postgres stores.
|
|
30
|
+
- **Diagrams as images.** `toSvg()` on `nexus-ai-pro/graph/visualize` draws a graph as a standalone,
|
|
31
|
+
escaped SVG document with no dependency. `layoutGraph()`, the layered layout underneath, moved from
|
|
32
|
+
the studio into the core visualizer, so both draw the same diagram.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- The server reads a streamed event's `output` before its `state` when it records a run's output, so a
|
|
37
|
+
workflow's return value is the run's output.
|
|
38
|
+
- `nexus-ai-pro-studio` requires nexus-ai-pro 1.21 or newer, and re-exports `layoutGraph()` from the
|
|
39
|
+
core visualizer.
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- `guardrailPolicy()`, `GUARDRAIL_POLICIES`, `calibrateSemanticInjectionClassifier()`, and
|
|
44
|
+
`SEMANTIC_INJECTION_CALIBRATION_SET` are exported from `nexus-ai-pro/security`, and the four domain
|
|
45
|
+
workflows such as `supportTriageWorkflow()` from `nexus-ai-pro/workflows`, as their guides already
|
|
46
|
+
showed. They were reachable only from the package root. A new docs check fails when a guide's
|
|
47
|
+
example imports a name from an entry point that does not export it.
|
|
48
|
+
|
|
49
|
+
## [1.20.0] - 2026-09-28
|
|
50
|
+
|
|
51
|
+
Retrieval that scales past one process. Deprecated options now say so at run time, and every guide
|
|
52
|
+
explains every export it lists.
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
|
|
56
|
+
- **Vector stores for retrieval.** `VectorStore` is a shared contract — `add()`, which replaces a chunk
|
|
57
|
+
whose id already exists, `search()`, `searchVector()` for a vector computed elsewhere, `delete()`,
|
|
58
|
+
and an exact-match metadata `filter` — with three implementations checked by one contract test:
|
|
59
|
+
- `PostgresVectorStore` on `nexus-ai-pro/postgres/vectors`, ranking with pgvector in the database,
|
|
60
|
+
with an HNSW index by default or an exact scan. `vectorStoreMigration()` gives its schema, and
|
|
61
|
+
`postgresMigration()` and `nexus db sql` include it when `vectors` is named.
|
|
62
|
+
- `QdrantVectorStore` on `nexus-ai-pro/rag/qdrant`, through Qdrant's REST API with `fetch` and Web
|
|
63
|
+
Crypto, so no Qdrant client is a dependency and it runs on edge runtimes. `migrate()` creates the
|
|
64
|
+
collection and indexes filter fields; failures raise `QdrantError`.
|
|
65
|
+
- `MemoryVectorStore`, which gains `searchVector()`, `delete()`, and the filter.
|
|
66
|
+
- Retrieval is reachable from `nexus-ai-pro/rag` — `MemoryVectorStore`, `createHashEmbeddings()`,
|
|
67
|
+
`cosineSimilarity()`, `normalizeVector()`, `matchesMetadata()`, and the types — so an application
|
|
68
|
+
that ingests and searches no longer loads the root import.
|
|
69
|
+
- **Deprecated options warn once per process** through Node's `DeprecationWarning` channel, with a
|
|
70
|
+
`NEXUS_DEP_*` code each, so `--no-deprecation` silences them and `--throw-deprecation` fails a CI
|
|
71
|
+
job on them: `GoogleProviderConfig.projectId`, `OllamaProviderConfig.timeout`,
|
|
72
|
+
`MetricsConfig.prometheus`, `HealthConfig.latencyHalfLife`, `DensificationConfig.preserveMarkdown`,
|
|
73
|
+
`InjectionDetectionConfig.sensitivity`, and `ToolPolicyConfig.requiresApproval`.
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
|
|
77
|
+
- `MemoryVectorStore.add()` replaces a chunk whose id already exists instead of storing a second
|
|
78
|
+
copy, so re-ingesting a document no longer duplicates its passages in search results.
|
|
79
|
+
- The guide check enforces that every export is explained in a guide's own text, not only named in
|
|
80
|
+
its generated reference; the five remaining guides — operations, embeddings, evaluation, images,
|
|
81
|
+
and realtime — now are. The README's limitations and production notes moved into the guides they
|
|
82
|
+
belong to.
|
|
83
|
+
|
|
7
84
|
## [1.19.0] - 2026-09-28
|
|
8
85
|
|
|
9
86
|
A studio to look at it all. `nexus-ai-pro-studio` is a separate package — so the core install never
|
|
@@ -1008,7 +1085,9 @@ shared policy vocabulary is in place for a future release that revisits this.
|
|
|
1008
1085
|
- URL fetching rejects unsafe private-network targets and limits response reads.
|
|
1009
1086
|
- CLI and audit findings no longer disclose detected secret values.
|
|
1010
1087
|
|
|
1011
|
-
[Unreleased]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v1.
|
|
1088
|
+
[Unreleased]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v1.21.0...HEAD
|
|
1089
|
+
[1.21.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v1.20.0...v1.21.0
|
|
1090
|
+
[1.20.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v1.19.0...v1.20.0
|
|
1012
1091
|
[1.19.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v1.18.0...v1.19.0
|
|
1013
1092
|
[1.18.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v1.17.0...v1.18.0
|
|
1014
1093
|
[1.17.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v1.16.0...v1.17.0
|
package/README.md
CHANGED
|
@@ -114,6 +114,7 @@ from the doc comments. The guides live in the repository, so these links go to G
|
|
|
114
114
|
| [Evaluation](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/evaluation.md) | Datasets, evaluators, experiments, comparisons with a verdict, review queues, LLM judges |
|
|
115
115
|
| [Prompts](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/prompts.md) | Typed templates, content versions, gated promotion, rollback, A/B splits, serving through outages |
|
|
116
116
|
| [Postgres](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/postgres.md) | One adapter family for operations, memory, traces, evaluation, circuits, and prompts |
|
|
117
|
+
| [SQLite](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/sqlite.md) | Durable operations, checkpoints, and memory on one machine, over any SQLite driver |
|
|
117
118
|
| [Durable operations and jobs](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/operations.md) | Operations that survive a restart, webhooks, and in-process job helpers |
|
|
118
119
|
| [Resilience and observability](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/resilience.md) | Circuit breaking, distributed rate limits, metrics, logs, and audit |
|
|
119
120
|
| [Batch tiers](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/batch.md) | The providers' discounted batch APIs, resumable from any process |
|
|
@@ -197,37 +198,22 @@ Shipped so far:
|
|
|
197
198
|
- queryable traces, an evaluation platform, and a CI gate on top of it;
|
|
198
199
|
- record and replay of provider traffic;
|
|
199
200
|
- prompt versioning: typed templates, content versions, gated promotion, and serving through outages;
|
|
201
|
+
- a self-hosted agent server, and a local studio as a separate package;
|
|
200
202
|
- per-entry-point size budgets.
|
|
201
203
|
|
|
202
|
-
Next
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
- NLI verification is an interface; bring a specialized verifier for high-confidence entailment.
|
|
216
|
-
- Guardrails reduce risk but do not replace application authorization, provider-side moderation, or
|
|
217
|
-
human review of high-impact actions.
|
|
218
|
-
- Realtime sessions are not yet routed through the metrics, audit, and rate-limit path that every
|
|
219
|
-
other family uses.
|
|
220
|
-
- The image adapters are verified against documented wire shapes; recorded live conformance for all
|
|
221
|
-
three backends is still to come, which is why the family is experimental.
|
|
222
|
-
|
|
223
|
-
## Production Notes
|
|
224
|
-
|
|
225
|
-
- Use direct or rules-based routing when model choice is already known.
|
|
226
|
-
- Keep semantic cache, semantic security, and custom hooks off latency-sensitive routes unless needed.
|
|
227
|
-
- Disable response traces with `pipeline.includeTraceInResponse = false`.
|
|
228
|
-
- Use shared adapters for distributed apps instead of process memory.
|
|
229
|
-
- Treat bundled model pricing and context metadata as defaults, not financial truth.
|
|
230
|
-
- Keep server-side authorization and provider moderation around high-risk workflows.
|
|
204
|
+
Next: durable functional workflows and step-level recovery, then retrieval and integration breadth,
|
|
205
|
+
a shared team studio, and self-managed deployment at scale, before 2.0.0 consolidates. The image
|
|
206
|
+
family leaves experimental once recorded live conformance passes on all three backends.
|
|
207
|
+
|
|
208
|
+
## Before Production
|
|
209
|
+
|
|
210
|
+
Each guide ends with its limitations. The ones worth reading first: the
|
|
211
|
+
[client guide](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/core.md#in-production) on latency, traces,
|
|
212
|
+
and shared adapters; the [security guide](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/security.md#limitations)
|
|
213
|
+
on what guardrails do not replace; and the
|
|
214
|
+
[grounding guide](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/grounding.md#limitations) on embeddings
|
|
215
|
+
and verification. Voice, telephony, images, realtime, local models, and custom providers are optional
|
|
216
|
+
layers; enable only what you use.
|
|
231
217
|
|
|
232
218
|
## Donations
|
|
233
219
|
|
package/dist/cli/db.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { postgresMigration } from '../postgres/index.js';
|
|
2
2
|
import { CliUsageError, listFlag, numberFlag } from './args.js';
|
|
3
|
-
const ADAPTERS = [
|
|
3
|
+
const ADAPTERS = [
|
|
4
|
+
'operations',
|
|
5
|
+
'store',
|
|
6
|
+
'traces',
|
|
7
|
+
'evaluation',
|
|
8
|
+
'circuits',
|
|
9
|
+
'prompts',
|
|
10
|
+
'vectors',
|
|
11
|
+
];
|
|
4
12
|
export async function runDbCommand(subcommand, { flags }) {
|
|
5
13
|
if (subcommand !== 'sql')
|
|
6
14
|
throw new CliUsageError(`Unknown db command "${subcommand ?? ''}". Use sql.`);
|
|
@@ -10,6 +18,9 @@ export async function runDbCommand(subcommand, { flags }) {
|
|
|
10
18
|
throw new CliUsageError(`Unknown adapter ${unknown.join(', ')}. Choose from ${ADAPTERS.join(', ')}.`);
|
|
11
19
|
}
|
|
12
20
|
const vectorDimensions = numberFlag(flags, 'vector-dimensions');
|
|
21
|
+
if (adapters?.includes('vectors') && vectorDimensions === undefined) {
|
|
22
|
+
throw new CliUsageError('The vectors adapter needs --vector-dimensions.');
|
|
23
|
+
}
|
|
13
24
|
process.stdout.write(postgresMigration({
|
|
14
25
|
...(adapters ? { adapters } : {}),
|
|
15
26
|
...(vectorDimensions === undefined ? {} : { vectorDimensions }),
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { GraphError } from './errors.js';
|
|
2
|
+
import type { GraphCheckpoint, GraphCheckpointer, GraphDescription, GraphEvent, GraphStatus, InterruptRequest, PendingInterrupt, RetryPolicy } from '../types/graph.js';
|
|
3
|
+
import type { Store } from '../types/store.js';
|
|
4
|
+
/** What a workflow checkpoint holds: the input, every completed step's result, and the output. */
|
|
5
|
+
export interface WorkflowState<I = unknown, O = unknown> {
|
|
6
|
+
/** The input the workflow was started with. */
|
|
7
|
+
input: I;
|
|
8
|
+
/** Each completed step's result, keyed by step name — `name#2` for the second call with a name. */
|
|
9
|
+
steps: Record<string, {
|
|
10
|
+
value?: unknown;
|
|
11
|
+
}>;
|
|
12
|
+
/** The workflow's return value, once it has completed. */
|
|
13
|
+
output?: O;
|
|
14
|
+
}
|
|
15
|
+
/** What a step's function receives. */
|
|
16
|
+
export interface StepContext {
|
|
17
|
+
/** The step's name. */
|
|
18
|
+
readonly name: string;
|
|
19
|
+
/** The key its result is recorded under: the name, or `name#n` for a repeated name. */
|
|
20
|
+
readonly key: string;
|
|
21
|
+
/** Attempt number, starting at 1. Above 1 only under a retry policy. */
|
|
22
|
+
readonly attempt: number;
|
|
23
|
+
/** Aborted when the run is cancelled or the step exceeds its timeout. */
|
|
24
|
+
readonly signal: AbortSignal;
|
|
25
|
+
}
|
|
26
|
+
/** How one step runs. */
|
|
27
|
+
export interface StepOptions {
|
|
28
|
+
/** Retries a failing attempt, overriding the workflow's default policy. */
|
|
29
|
+
retry?: RetryPolicy;
|
|
30
|
+
/** Aborts the step's signal and fails the attempt when it runs longer than this, in milliseconds. */
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
}
|
|
33
|
+
/** What a workflow function receives besides its input. */
|
|
34
|
+
export interface WorkflowContext {
|
|
35
|
+
/** The thread this run belongs to. */
|
|
36
|
+
readonly threadId: string;
|
|
37
|
+
/** Aborted when the run is cancelled. */
|
|
38
|
+
readonly signal: AbortSignal;
|
|
39
|
+
/** Long-term memory, when the workflow was created with a store. */
|
|
40
|
+
readonly store?: Store;
|
|
41
|
+
/**
|
|
42
|
+
* Runs a piece of work once per thread and records its result.
|
|
43
|
+
*
|
|
44
|
+
* When the workflow runs again, a step that already finished returns its recorded result without
|
|
45
|
+
* running. Name steps so the same call has the same name every time; a name used more than once
|
|
46
|
+
* is numbered in call order. The result must survive JSON serialization.
|
|
47
|
+
*/
|
|
48
|
+
step<T>(name: string, run: (context: StepContext) => Promise<T> | T, options?: StepOptions): Promise<T>;
|
|
49
|
+
/**
|
|
50
|
+
* Suspends the workflow until a person answers.
|
|
51
|
+
*
|
|
52
|
+
* The first time, the run stops with status `awaiting_input` and this question pending. After
|
|
53
|
+
* `resume()` supplies a value, the workflow runs again from the top — completed steps return their
|
|
54
|
+
* recorded results — and this call returns the value instead of stopping.
|
|
55
|
+
*/
|
|
56
|
+
interrupt<T = unknown>(request: InterruptRequest): T;
|
|
57
|
+
/** Sends anything to the run's `onEvent` listener as a `custom` event. Nothing is recorded. */
|
|
58
|
+
emit(data: unknown): void;
|
|
59
|
+
}
|
|
60
|
+
/** A workflow function: its input and context in, its output out. */
|
|
61
|
+
export type WorkflowFn<I, O> = (input: I, context: WorkflowContext) => Promise<O> | O;
|
|
62
|
+
/** Options for `workflow()`. */
|
|
63
|
+
export interface WorkflowOptions {
|
|
64
|
+
/** Names the workflow in checkpoints, events, and diagrams. Defaults to `workflow`. */
|
|
65
|
+
name?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Where checkpoints go. Defaults to an in-process `MemoryGraphCheckpointer`; pass a persistent one
|
|
68
|
+
* to survive restarts, or `false` to record nothing, which also disables interrupts and resume.
|
|
69
|
+
*/
|
|
70
|
+
checkpointer?: GraphCheckpointer | false;
|
|
71
|
+
/** Long-term memory handed to the function as `context.store`. */
|
|
72
|
+
store?: Store;
|
|
73
|
+
/** Default retry policy for every step. A step's own policy wins. Defaults to one attempt. */
|
|
74
|
+
retry?: RetryPolicy;
|
|
75
|
+
/** Steps that may run at once, for a workflow that starts many with `Promise.all`. Defaults to 16. */
|
|
76
|
+
maxConcurrency?: number;
|
|
77
|
+
/** Replaces the system clock, for tests. */
|
|
78
|
+
now?: () => Date;
|
|
79
|
+
}
|
|
80
|
+
/** Options for one run of a workflow. */
|
|
81
|
+
export interface WorkflowRunOptions {
|
|
82
|
+
/** Identifies the run. Reusing one continues that thread. Defaults to a generated id. */
|
|
83
|
+
threadId?: string;
|
|
84
|
+
/** Stops the run. Steps in flight see the signal. */
|
|
85
|
+
signal?: AbortSignal;
|
|
86
|
+
/** Application data recorded on every checkpoint of the run. */
|
|
87
|
+
metadata?: Record<string, unknown>;
|
|
88
|
+
/** Receives each step starting, retrying, and finishing, each checkpoint, and custom events. */
|
|
89
|
+
onEvent?: (event: GraphEvent) => void;
|
|
90
|
+
}
|
|
91
|
+
/** One event of a streamed workflow run. */
|
|
92
|
+
export type WorkflowEvent<O = unknown> = {
|
|
93
|
+
/** A step finished, or returned its recorded result. */
|
|
94
|
+
type: 'step';
|
|
95
|
+
/** Checkpoints written so far in the thread. */
|
|
96
|
+
step: number;
|
|
97
|
+
/** The step's name. */
|
|
98
|
+
name: string;
|
|
99
|
+
/** The key its result is recorded under. */
|
|
100
|
+
key: string;
|
|
101
|
+
/** True when the result came from a checkpoint and the step did not run. */
|
|
102
|
+
cached: boolean;
|
|
103
|
+
/** The workflow state after the step. */
|
|
104
|
+
state: WorkflowState<unknown, O>;
|
|
105
|
+
/** Always `running`. */
|
|
106
|
+
status: 'running';
|
|
107
|
+
} | {
|
|
108
|
+
/** The workflow returned. */
|
|
109
|
+
type: 'done';
|
|
110
|
+
/** Checkpoints written in the thread. */
|
|
111
|
+
step: number;
|
|
112
|
+
/** The final state. */
|
|
113
|
+
state: WorkflowState<unknown, O>;
|
|
114
|
+
/** Always `completed`. */
|
|
115
|
+
status: 'completed';
|
|
116
|
+
/** What the workflow returned. */
|
|
117
|
+
output: O;
|
|
118
|
+
} | {
|
|
119
|
+
/** The workflow is waiting for a person, or was stopped by its signal. */
|
|
120
|
+
type: 'interrupt';
|
|
121
|
+
/** Checkpoints written in the thread. */
|
|
122
|
+
step: number;
|
|
123
|
+
/** The state when it stopped. */
|
|
124
|
+
state: WorkflowState<unknown, O>;
|
|
125
|
+
/** `awaiting_input` for a question, `interrupted` for a cancelled run. */
|
|
126
|
+
status: 'awaiting_input' | 'interrupted';
|
|
127
|
+
/** The first pending question. */
|
|
128
|
+
interrupt?: PendingInterrupt;
|
|
129
|
+
/** Every pending question. */
|
|
130
|
+
interrupts?: PendingInterrupt[];
|
|
131
|
+
};
|
|
132
|
+
/** The outcome of a workflow run. */
|
|
133
|
+
export interface WorkflowResult<O = unknown> {
|
|
134
|
+
/** The thread the run belongs to. */
|
|
135
|
+
threadId: string;
|
|
136
|
+
/** `completed`, `awaiting_input`, or `interrupted`. A failed run throws instead. */
|
|
137
|
+
status: GraphStatus;
|
|
138
|
+
/** What the workflow returned, when it completed. */
|
|
139
|
+
output?: O;
|
|
140
|
+
/** The workflow state: input, step results, and output. */
|
|
141
|
+
state: WorkflowState<unknown, O>;
|
|
142
|
+
/** Steps whose results are recorded. */
|
|
143
|
+
steps: number;
|
|
144
|
+
/** The first pending question, when it is waiting. */
|
|
145
|
+
interrupt?: PendingInterrupt;
|
|
146
|
+
/** Every pending question. */
|
|
147
|
+
interrupts?: PendingInterrupt[];
|
|
148
|
+
}
|
|
149
|
+
/** Raised when a step outlives its `timeoutMs`. */
|
|
150
|
+
export declare class WorkflowStepTimeoutError extends GraphError {
|
|
151
|
+
/** The step. */
|
|
152
|
+
readonly stepName: string;
|
|
153
|
+
/** The limit it exceeded, in milliseconds. */
|
|
154
|
+
readonly timeoutMs: number;
|
|
155
|
+
constructor(
|
|
156
|
+
/** The step. */
|
|
157
|
+
stepName: string,
|
|
158
|
+
/** The limit it exceeded, in milliseconds. */
|
|
159
|
+
timeoutMs: number);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* A durable workflow: a function whose steps are checkpointed, so it survives interrupts, restarts,
|
|
163
|
+
* and a move to another worker. Create one with `workflow()`.
|
|
164
|
+
*/
|
|
165
|
+
export declare class Workflow<I = unknown, O = unknown> {
|
|
166
|
+
private readonly fn;
|
|
167
|
+
private readonly options;
|
|
168
|
+
/** The workflow's name. */
|
|
169
|
+
readonly name: string;
|
|
170
|
+
private readonly defaultCheckpointer;
|
|
171
|
+
private readonly now;
|
|
172
|
+
constructor(fn: WorkflowFn<I, O>, options?: WorkflowOptions);
|
|
173
|
+
/** Runs to the end, or to the first question, and returns the result. */
|
|
174
|
+
invoke(input: I, runOptions?: WorkflowRunOptions): Promise<WorkflowResult<O>>;
|
|
175
|
+
/** Runs, yielding an event as each step finishes. */
|
|
176
|
+
stream(input: I, runOptions?: WorkflowRunOptions): AsyncIterable<WorkflowEvent<O>>;
|
|
177
|
+
/** Answers the first pending question and runs on. */
|
|
178
|
+
resume(threadId: string, value: unknown, runOptions?: WorkflowRunOptions): AsyncIterable<WorkflowEvent<O>>;
|
|
179
|
+
/** Answers the first pending question, runs on, and returns the result. */
|
|
180
|
+
resumeWith(threadId: string, value: unknown, runOptions?: WorkflowRunOptions): Promise<WorkflowResult<O>>;
|
|
181
|
+
/** Answers pending questions by id and runs on. */
|
|
182
|
+
resumeInterrupts(threadId: string, answers: Record<string, unknown>, runOptions?: WorkflowRunOptions): AsyncIterable<WorkflowEvent<O>>;
|
|
183
|
+
/**
|
|
184
|
+
* Runs a thread on from its latest checkpoint: after a crash, a failure, or a cancelled run.
|
|
185
|
+
* Completed steps return their recorded results, so only unfinished work runs again.
|
|
186
|
+
*/
|
|
187
|
+
continue(threadId: string, runOptions?: WorkflowRunOptions): AsyncIterable<WorkflowEvent<O>>;
|
|
188
|
+
/** The latest checkpoint, or the one at `step`. */
|
|
189
|
+
state(threadId: string, step?: number): Promise<GraphCheckpoint | undefined>;
|
|
190
|
+
/** Every checkpoint of a thread, newest first. */
|
|
191
|
+
history(threadId: string, limit?: number): Promise<GraphCheckpoint[]>;
|
|
192
|
+
/** The workflow as a one-node graph, so diagrams and the studio can show it. */
|
|
193
|
+
describe(): GraphDescription;
|
|
194
|
+
private checkpointer;
|
|
195
|
+
private latest;
|
|
196
|
+
private fresh;
|
|
197
|
+
private waiting;
|
|
198
|
+
private answered;
|
|
199
|
+
private collect;
|
|
200
|
+
/** Runs the function against a starting checkpoint, streaming events through a queue. */
|
|
201
|
+
private execute;
|
|
202
|
+
private run;
|
|
203
|
+
private runStep;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Creates a durable workflow from a function.
|
|
207
|
+
*
|
|
208
|
+
* ```ts
|
|
209
|
+
* const refund = workflow(async (input: { orderId: string }, { step, interrupt }) => {
|
|
210
|
+
* const order = await step('load', () => orders.get(input.orderId));
|
|
211
|
+
* if (!interrupt<boolean>({ reason: `Refund ${order.total}?` })) return { refunded: false };
|
|
212
|
+
* await step('refund', () => payments.refund(order.id));
|
|
213
|
+
* return { refunded: true };
|
|
214
|
+
* }, { checkpointer });
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
export declare function workflow<I, O>(fn: WorkflowFn<I, O>, options?: WorkflowOptions): Workflow<I, O>;
|