nexus-ai-pro 2.22.0 → 3.0.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 +35 -2
- package/CHANGELOG.md +33 -1
- package/MIGRATING.md +151 -17
- package/README.md +11 -7
- package/SECURITY.md +2 -2
- package/dist/agent/openapi.d.ts +0 -11
- package/dist/agent/openapi.js +0 -1
- package/dist/cli/migrate.d.ts +5 -4
- package/dist/cli/migrate.js +18 -1
- package/dist/core/defaults.d.ts +12 -12
- package/dist/core/defaults.js +2 -2
- package/dist/doctor/index.js +1 -1
- package/dist/graph/checkpoint-migration.d.ts +0 -6
- package/dist/graph/index.d.ts +1 -1
- package/dist/operations/adapters.d.ts +6 -5
- package/dist/server/deployments.d.ts +2 -2
- package/dist/tracing/tracer.d.ts +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist-cjs/agent/openapi.d.ts +0 -11
- package/dist-cjs/agent/openapi.js +0 -1
- package/dist-cjs/cli/migrate.d.ts +5 -4
- package/dist-cjs/cli/migrate.js +18 -1
- package/dist-cjs/core/defaults.d.ts +12 -12
- package/dist-cjs/core/defaults.js +2 -2
- package/dist-cjs/doctor/index.js +1 -1
- package/dist-cjs/graph/checkpoint-migration.d.ts +0 -6
- package/dist-cjs/graph/index.d.ts +1 -1
- package/dist-cjs/operations/adapters.d.ts +6 -5
- package/dist-cjs/server/deployments.d.ts +2 -2
- package/dist-cjs/tracing/tracer.d.ts +2 -2
- package/dist-cjs/version.d.ts +1 -1
- package/dist-cjs/version.js +1 -1
- package/package.json +2 -1
package/API_STABILITY.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# API Stability Policy
|
|
2
2
|
|
|
3
|
-
This policy describes compatibility guarantees for `nexus-ai-pro`. The
|
|
4
|
-
with version
|
|
3
|
+
This policy describes compatibility guarantees for `nexus-ai-pro`. The 3.x guarantees apply beginning
|
|
4
|
+
with version 3.0.0, as the 2.x guarantees applied from 2.0.0 and the 1.x guarantees from 1.0.0. The sections for the 1.x stages below
|
|
5
5
|
still describe each surface; where they say "the 1.x rules", read the rules of the current major line.
|
|
6
6
|
|
|
7
7
|
## Release stages
|
|
@@ -67,6 +67,39 @@ graduation:
|
|
|
67
67
|
| Upgrade | A migration test from the previous minor |
|
|
68
68
|
| Soak | A long-running test with flat memory and no leaked handles |
|
|
69
69
|
|
|
70
|
+
## 3.0 stage (3.0.0)
|
|
71
|
+
|
|
72
|
+
3.0 is a major release. It turns on the three defaults 2.21 previewed — incremental tracing on a
|
|
73
|
+
durable trace store, the Redis operation store's dispatch index, and `hash-v2` for a deployment first
|
|
74
|
+
recorded — and removes `OpenApiTools.skipped` and `GraphCheckpointV2`, both deprecated in 2.x. Nothing
|
|
75
|
+
stored changes: checkpoints of version 1 and 2, the state store's keys, operation records, and recorded
|
|
76
|
+
deployments read as they did, and the state store's keys are read by every later 3.x.
|
|
77
|
+
`useDefaults('2.x')` and `NEXUS_DEFAULTS=2.x` keep 2.x's three defaults through 3.x.
|
|
78
|
+
[MIGRATING.md](./MIGRATING.md) covers each change. The rollout is proven against the published 2.21.0
|
|
79
|
+
package, in `tests/upgrade-3.test.ts`: a 2.21 worker and a 3.0 worker share a Redis prefix, each
|
|
80
|
+
claiming what it should and 3.0 finding the rest after one `reindex()`, and 2.21 and 3.0 replicas
|
|
81
|
+
place every thread alike, whichever records a deployment first.
|
|
82
|
+
|
|
83
|
+
Removed: `OpenApiTools.skipped`, always empty since 2.22, and `GraphCheckpointV2`, for `GraphCheckpoint`.
|
|
84
|
+
Everything else 3.0 adds is stable from the start and additive, unless this section says otherwise.
|
|
85
|
+
|
|
86
|
+
### Graduation
|
|
87
|
+
|
|
88
|
+
The studio's sign-in leaves experimental status: `oidcSignIn()`, `OidcSignInOptions`,
|
|
89
|
+
`SIGN_IN_COOKIE`, and the `/auth/login`, `/auth/callback`, and `/auth/logout` routes.
|
|
90
|
+
|
|
91
|
+
| Requirement | Evidence |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| API stability | Covered by the compatibility rules, with no planned breaking change |
|
|
94
|
+
| Conformance | Signs a person in through Dex v2.46.0, run in a container on every build, where a wrong password is kept and a reused code refused: `studio/test/signin-dex.test.ts`; every way a callback can be wrong, a token for another client among them, against a provider written from the specification: `studio/test/signin.test.ts` |
|
|
95
|
+
| Crash recovery | n/a: it keeps nothing; a session is a signed cookie, and a sign-in in progress is one the person carries |
|
|
96
|
+
| Concurrency | A sign-in begun on one replica finishes on another, and every replica sharing the secret reads the session: `studio/test/signin.test.ts` |
|
|
97
|
+
| Load | 500 reads on a sign-in session cost at most twice the same reads on a personal token: `studio/test/signin.test.ts` |
|
|
98
|
+
| Tenant isolation | A tenant from a claim reads only that tenant's sources, comments, and audit entries: `studio/test/signin.test.ts`, `studio/test/tenants.test.ts` |
|
|
99
|
+
| Security | [Review](./SECURITY.md#the-studio-and-its-accounts), reviewed for 2.22, its findings closed |
|
|
100
|
+
| Upgrade | A session sealed by 2.22.0 is read: `studio/test/signin.test.ts` |
|
|
101
|
+
| Soak | 1,000 sign-ins and their reads with flat memory: `studio/test/signin.test.ts` |
|
|
102
|
+
|
|
70
103
|
## 2.22 stage (2.22.0)
|
|
71
104
|
|
|
72
105
|
Everything 2.22 adds is stable from the start and additive, unless this section says otherwise.
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,37 @@ Notable changes to this project are recorded here. The format follows [Keep a Ch
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [3.0.0] - 2026-10-30
|
|
8
|
+
|
|
9
|
+
3.0, a major release. It turns on the three defaults 2.21 previewed, and removes the two names 2.x
|
|
10
|
+
deprecated; nothing stored changes, and `useDefaults('2.x')` keeps 2.x's defaults for an application
|
|
11
|
+
that upgrades first. [MIGRATING.md](./MIGRATING.md) covers each change, and `nexus migrate` finds what
|
|
12
|
+
it touches.
|
|
13
|
+
|
|
14
|
+
### Breaking
|
|
15
|
+
|
|
16
|
+
- **A tracer on a durable store writes as it runs.** `TracerOptions.incremental` defaults to true on a
|
|
17
|
+
store whose `durable` is not `false`: each run is written as it starts and again as it ends, so a
|
|
18
|
+
run in a process that dies is not lost, at twice the writes. A store in memory still writes at the end.
|
|
19
|
+
- **The Redis operation store keeps its dispatch index**, where the client has `zadd`, `zrem`, and
|
|
20
|
+
`zrangebyscore`, so a claim reads the same few records however long the queue. Work a worker
|
|
21
|
+
without the index queued is found once `reindex()` runs: call it once the last 2.x worker sharing the
|
|
22
|
+
prefix has stopped.
|
|
23
|
+
- **A deployment first recorded on 3.0 places threads by `hash-v2`**, which spreads sequential ids
|
|
24
|
+
evenly. A deployment already recorded keeps its strategy, so no thread moves.
|
|
25
|
+
- **`OpenApiTools.skipped` is removed.** It was always empty since every operation became a tool.
|
|
26
|
+
- **`GraphCheckpointV2` is removed**, for `GraphCheckpoint`, which it named. `nexus migrate` renames it.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **The studio's sign-in is stable.** Every build signs a person in through Dex, an OpenID Connect
|
|
31
|
+
provider run in a container: its configuration read, the code exchanged with the client secret and
|
|
32
|
+
PKCE, its ID token verified against its keys, a wrong password kept at Dex, and a used code refused.
|
|
33
|
+
`oidcSignIn()`, `OidcSignInOptions`, `SIGN_IN_COOKIE`, and the `/auth/` routes leave experimental
|
|
34
|
+
status, with their evidence in API_STABILITY.md.
|
|
35
|
+
- **Gemini's voice is in the live workflow.** It speaks a sentence in one of Gemini's voices and hears it
|
|
36
|
+
back; it graduates when that run passes.
|
|
37
|
+
|
|
7
38
|
## [2.22.0] - 2026-10-29
|
|
8
39
|
|
|
9
40
|
MCP over streamable HTTP both ways, OpenAPI tools that send each operation's credentials, tokens, keys,
|
|
@@ -3492,7 +3523,8 @@ shared policy vocabulary is in place for a future release that revisits this.
|
|
|
3492
3523
|
- URL fetching rejects unsafe private-network targets and limits response reads.
|
|
3493
3524
|
- CLI and audit findings no longer disclose detected secret values.
|
|
3494
3525
|
|
|
3495
|
-
[Unreleased]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/
|
|
3526
|
+
[Unreleased]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v3.0.0...HEAD
|
|
3527
|
+
[3.0.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.22.0...v3.0.0
|
|
3496
3528
|
[2.22.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.21.0...v2.22.0
|
|
3497
3529
|
[2.21.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.20.2...v2.21.0
|
|
3498
3530
|
[2.20.2]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.20.1...v2.20.2
|
package/MIGRATING.md
CHANGED
|
@@ -1,4 +1,138 @@
|
|
|
1
|
-
# Migrating
|
|
1
|
+
# Migrating
|
|
2
|
+
|
|
3
|
+
- [To 3.0](#migrating-to-30), from 2.x
|
|
4
|
+
- [To 2.0](#migrating-to-20), from 1.x
|
|
5
|
+
|
|
6
|
+
## Migrating to 3.0
|
|
7
|
+
|
|
8
|
+
3.0 turns on three defaults that 2.x kept opt-in, and removes two names 2.x deprecated. Nothing stored
|
|
9
|
+
changes: checkpoints, operation records, the server's state, and recorded deployments read as 2.x
|
|
10
|
+
wrote them. Most code compiles unchanged, but the three defaults change what a deployment does, so read
|
|
11
|
+
each before the upgrade reaches production.
|
|
12
|
+
|
|
13
|
+
To upgrade first and take the defaults later, keep 2.x's for now, on every replica:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { useDefaults } from 'nexus-ai-pro/config';
|
|
17
|
+
|
|
18
|
+
useDefaults('2.x'); // before creating a tracer, an operation store, or a deployment
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
or set `NEXUS_DEFAULTS=2.x` in the environment. Then `npx nexus doctor --upgrade 3.0` says what turning
|
|
22
|
+
them on would change for your deployment, and `npx nexus migrate src` finds the removed names.
|
|
23
|
+
|
|
24
|
+
| Change | The codemod | By hand |
|
|
25
|
+
| --- | --- | --- |
|
|
26
|
+
| [A tracer on a durable store writes as it runs](#a-tracer-on-a-durable-store-writes-as-it-runs) | — | Expect twice the trace writes; close abandoned runs |
|
|
27
|
+
| [The Redis operation store keeps its index](#the-redis-operation-store-keeps-its-index) | — | Call `reindex()` once no worker without the index is left |
|
|
28
|
+
| [A new deployment places threads by `hash-v2`](#a-new-deployment-places-threads-by-hash-v2) | — | Give `bucket()` the deployment's strategy |
|
|
29
|
+
| [`OpenApiTools.skipped` is removed](#openapitoolsskipped-is-removed) | Lists each read | Delete it |
|
|
30
|
+
| [`GraphCheckpointV2` is removed](#graphcheckpointv2-is-removed) | Renames it | — |
|
|
31
|
+
| [`useDefaults('3.0')` changes nothing](#usedefaults30-changes-nothing) | Lists each call | Delete it |
|
|
32
|
+
|
|
33
|
+
### A tracer on a durable store writes as it runs
|
|
34
|
+
|
|
35
|
+
`TracerOptions.incremental` defaults to true on a store whose `durable` is not `false`. Each run is
|
|
36
|
+
written when it starts and again when it ends, so a run in a process that dies stays in the store with
|
|
37
|
+
every run beneath it that finished, and a run in progress can be watched. A store in memory, such as
|
|
38
|
+
`MemoryTraceStore`, still writes each trace when its root finishes.
|
|
39
|
+
|
|
40
|
+
- A store takes twice the writes, and a JSON Lines file twice the lines, the later one winning.
|
|
41
|
+
- A run a dead process left stays `running` until `closeAbandonedRuns()` closes it. Call it when a
|
|
42
|
+
worker starts, or on a schedule.
|
|
43
|
+
- Sampling is decided when the root starts. A trace not sampled is held in memory and written at the
|
|
44
|
+
end when tail sampling keeps it, so `keepErrors` still shows every failure.
|
|
45
|
+
- A store of your own that keeps runs only in memory says `durable: false`, and is written at the end.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
// Before: 2.x wrote each trace when its root finished
|
|
49
|
+
const tracer = new Tracer({ store });
|
|
50
|
+
|
|
51
|
+
// After, to keep that
|
|
52
|
+
const tracer = new Tracer({ store, incremental: false });
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### The Redis operation store keeps its index
|
|
56
|
+
|
|
57
|
+
`RedisOperationStore` keeps queued work in a sorted set by age, and leased work in one by lease expiry,
|
|
58
|
+
wherever its client has `zadd`, `zrem`, and `zrangebyscore`. A claim then reads the same few records
|
|
59
|
+
with 100,000 operations queued as with 1,000. A client without those commands is not refused: the store
|
|
60
|
+
reads every record, as 2.x did.
|
|
61
|
+
|
|
62
|
+
A worker without the index, as every 2.x worker is unless asked, writes records without index
|
|
63
|
+
entries, so work it queues is in the index only once `reindex()` adds it. Either way works:
|
|
64
|
+
|
|
65
|
+
- **Roll 3.0 out, then reindex.** While 2.x workers run, they claim what they queued. Once the last of
|
|
66
|
+
them has stopped, call `reindex()` once, so the 3.0 workers find what was left. It is safe while
|
|
67
|
+
workers are busy.
|
|
68
|
+
- **Turn the index on first, on 2.x.** On 2.2 or later, give every worker sharing the prefix
|
|
69
|
+
`index: true`, or on 2.21 `useDefaults('3.0')`, and call `reindex()` once; 3.0 then changes nothing.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const operations = new RedisOperationStore(redis);
|
|
73
|
+
await operations.reindex(); // once no worker without the index shares the prefix
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`index: false` keeps 2.x's behaviour.
|
|
77
|
+
|
|
78
|
+
### A new deployment places threads by `hash-v2`
|
|
79
|
+
|
|
80
|
+
A deployment first recorded on 3.0 places new threads and stateless runs by `hash-v2`, which spreads
|
|
81
|
+
sequential ids, such as `user-1` to `user-500`, as evenly as random ones. A deployment already recorded
|
|
82
|
+
keeps the strategy it records, `fnv1a-v1` before 3.0, so no thread moves through the upgrade;
|
|
83
|
+
`Deployments.bucketing()` moves one when you choose to.
|
|
84
|
+
|
|
85
|
+
`bucket()` still places a key by `fnv1a-v1` unless it is given a strategy, so code that predicts where a
|
|
86
|
+
thread lands passes the deployment's:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
// Before
|
|
90
|
+
const onCanary = bucket(`support:${threadId}`) < 0.1;
|
|
91
|
+
|
|
92
|
+
// After
|
|
93
|
+
const deployment = await deployments.get('support');
|
|
94
|
+
const onCanary = bucket(`support:${threadId}`, deployment?.bucketStrategy) < 0.1;
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`bucketStrategy: 'fnv1a-v1'` on `Deployments.assistant()` keeps 2.x's strategy for a deployment not
|
|
98
|
+
yet recorded. During a rolling upgrade, the replica that first records a deployment, by its first
|
|
99
|
+
canary or split, decides its strategy, and every replica of 2.5 or later then reads it from the record;
|
|
100
|
+
pass `bucketStrategy` to choose rather than leave it to the replica.
|
|
101
|
+
|
|
102
|
+
### `OpenApiTools.skipped` is removed
|
|
103
|
+
|
|
104
|
+
Every operation of an OpenAPI document becomes a tool since 2.22, its body sent whatever its type, so
|
|
105
|
+
`skipped` was always empty. Delete each read. The codemod lists them, in files that use the OpenAPI
|
|
106
|
+
tools.
|
|
107
|
+
|
|
108
|
+
### `GraphCheckpointV2` is removed
|
|
109
|
+
|
|
110
|
+
It was another name for `GraphCheckpoint`, kept since 1.25. The codemod renames it and keeps your local
|
|
111
|
+
name:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// Before
|
|
115
|
+
import type { GraphCheckpointV2 } from 'nexus-ai-pro/graph';
|
|
116
|
+
|
|
117
|
+
// After
|
|
118
|
+
import type { GraphCheckpoint as GraphCheckpointV2 } from 'nexus-ai-pro/graph';
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### `useDefaults('3.0')` changes nothing
|
|
122
|
+
|
|
123
|
+
An application that previewed 3.0 with `useDefaults('3.0')` or `NEXUS_DEFAULTS=3.0` already runs as 3.0
|
|
124
|
+
does. The call and the variable change nothing now, and can go. `useDefaults('2.x')` and
|
|
125
|
+
`NEXUS_DEFAULTS=2.x` keep 2.x's three defaults through 3.x.
|
|
126
|
+
|
|
127
|
+
### What does not change
|
|
128
|
+
|
|
129
|
+
- Checkpoints of version 1 and 2 are read by both checkpointers and by `migrateCheckpoint()`.
|
|
130
|
+
- The server's state keys, sessions, API keys, operation records, and recorded deployments read as 2.x
|
|
131
|
+
wrote them.
|
|
132
|
+
- Every other default, and every API this guide does not name.
|
|
133
|
+
- Node.js 22 or later.
|
|
134
|
+
|
|
135
|
+
## Migrating to 2.0
|
|
2
136
|
|
|
3
137
|
2.0.0 removes what the 1.x line deprecated, and runs every call of every family through one
|
|
4
138
|
lifecycle. Most applications change only their imports, and a codemod does that.
|
|
@@ -31,7 +165,7 @@ upgrade, and work through the table.
|
|
|
31
165
|
| [Claude 4.6 onward think adaptively](#claude-46-onward-think-adaptively) | — | Nothing |
|
|
32
166
|
| [Tool calls reach providers whole](#tool-calls-reach-providers-whole) | — | Nothing |
|
|
33
167
|
|
|
34
|
-
|
|
168
|
+
### The root import keeps only the core
|
|
35
169
|
|
|
36
170
|
In 2.0, `nexus-ai-pro` exports the core client and nothing else:
|
|
37
171
|
|
|
@@ -71,7 +205,7 @@ is in the [packaging guide](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/
|
|
|
71
205
|
|
|
72
206
|
The root import now costs about 325 KB, down from 572 KB.
|
|
73
207
|
|
|
74
|
-
|
|
208
|
+
### Validators and Node types are optional
|
|
75
209
|
|
|
76
210
|
`zod`, `ajv`, `ajv-formats`, and `@types/node` are optional peer dependencies. A production install
|
|
77
211
|
is the package alone, about 5.3 MB instead of 12.3 MB.
|
|
@@ -88,7 +222,7 @@ install. A zod shape is checked through each field's own `safeParse`.
|
|
|
88
222
|
The request check in the guardrails, `SchemaValidator`, no longer uses zod. It reports the same
|
|
89
223
|
fields by the same paths; the wording of its findings changed.
|
|
90
224
|
|
|
91
|
-
|
|
225
|
+
### A response's `estimatedCost` is removed
|
|
92
226
|
|
|
93
227
|
The formatted string on a response's metadata is gone. Read the numeric cost, and format it yourself:
|
|
94
228
|
|
|
@@ -104,7 +238,7 @@ if (cost) console.log(new Intl.NumberFormat('en-US', { style: 'currency', curren
|
|
|
104
238
|
A plan's `estimatedCost`, from `ai.plan()`, is an object and stays. A custom provider that set the
|
|
105
239
|
string should drop it; `buildMeta()` fills `usage` and `cost`.
|
|
106
240
|
|
|
107
|
-
|
|
241
|
+
### Modalities say which way they flow
|
|
108
242
|
|
|
109
243
|
A model's `modalities` list mixed inputs and outputs: `vision` meant an image in, and `image` meant an
|
|
110
244
|
image out. 2.0 removes it, and the `Modality` type with it. Every entry declares `inputModalities` and
|
|
@@ -128,7 +262,7 @@ models: { registry: { 'my-model': { inputModalities: ['text', 'image'], outputMo
|
|
|
128
262
|
In routing requirements, replace `modalities` with `inputModalities` or `outputModalities`.
|
|
129
263
|
`modalitiesOf()` still reads both lists, and now requires both.
|
|
130
264
|
|
|
131
|
-
|
|
265
|
+
### Checkpoints are version 2
|
|
132
266
|
|
|
133
267
|
A checkpoint 2.x writes has a `version` of 2, an `id`, its `tasks` always spelled out, and every
|
|
134
268
|
pending question in `interrupts`. The single `interrupt` field is gone.
|
|
@@ -152,7 +286,7 @@ so a thread left waiting resumes after the upgrade.
|
|
|
152
286
|
| Build a checkpoint by hand | Use `toCheckpoint()`, which fills in the version, id, tasks, and questions |
|
|
153
287
|
| Named `GraphCheckpointV2` | It still compiles; it is now another name for `GraphCheckpoint` |
|
|
154
288
|
|
|
155
|
-
|
|
289
|
+
### Options that were never read are removed
|
|
156
290
|
|
|
157
291
|
These were accepted and ignored, and warned once per process since they were deprecated. The codemod
|
|
158
292
|
lists each one it finds.
|
|
@@ -170,11 +304,11 @@ lists each one it finds.
|
|
|
170
304
|
Delete them. Nothing changes, because nothing read them. Approval before a tool runs is
|
|
171
305
|
`interruptOn` on `createAgent()`.
|
|
172
306
|
|
|
173
|
-
|
|
307
|
+
### `ImageManagerConfig` is removed
|
|
174
308
|
|
|
175
309
|
It was another name for `ImageConfig`. The codemod renames the import and keeps your local name.
|
|
176
310
|
|
|
177
|
-
|
|
311
|
+
### Pipeline step names are a closed list
|
|
178
312
|
|
|
179
313
|
`PipelineStepName` lists the built-in stages only, so a `switch` over it can be exhaustive. A step you
|
|
180
314
|
add with `use()` is recorded as `customStep`, with its own name in `custom`.
|
|
@@ -195,7 +329,7 @@ Metrics for a custom step keep its own name as their `step` label.
|
|
|
195
329
|
`PipelineRunner` are generic over the request and the response. Both default to a completion's, so
|
|
196
330
|
existing code compiles unchanged.
|
|
197
331
|
|
|
198
|
-
|
|
332
|
+
### Streams open on their first read
|
|
199
333
|
|
|
200
334
|
`ai.stream()` returns at once. Authorization, the rate limit, guardrails, routing, and the budget run
|
|
201
335
|
when the stream is first read, so their errors come out of the loop:
|
|
@@ -216,7 +350,7 @@ Streams now get what completions always had. They are audited and counted, the c
|
|
|
216
350
|
circuit breaker apply, and the `done` chunk carries the request id and a cost priced on the routed
|
|
217
351
|
model.
|
|
218
352
|
|
|
219
|
-
|
|
353
|
+
### Every call runs through the lifecycle
|
|
220
354
|
|
|
221
355
|
Completions, streams, embeddings, voice, telephony, images, realtime sessions, graphs, agents, jobs,
|
|
222
356
|
and batches share one [lifecycle](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/docs/lifecycle.md).
|
|
@@ -244,7 +378,7 @@ To use the lifecycle, set `lifecycle` on the client: an `authorize` callback, a
|
|
|
244
378
|
`hooks`. Pass `ai.lifecycle` to graphs, agents, workflows, realtime sessions, queues, and batches to
|
|
245
379
|
make their runs operations of the client too.
|
|
246
380
|
|
|
247
|
-
|
|
381
|
+
### Responses are priced on the routed model
|
|
248
382
|
|
|
249
383
|
The client now prices each response on the model the request was routed to, as the registry names
|
|
250
384
|
it. Providers often answer with a dated snapshot name the registry does not file. In 1.x, pricing on
|
|
@@ -252,7 +386,7 @@ that echo cost the call nothing, so OpenAI responses could show a cost of 0, and
|
|
|
252
386
|
DeepSeek, and Cohere models filed under a prefix. Expect those costs to be priced in 2.0, and budgets
|
|
253
387
|
to count them. A charge the provider reports, with `basis: 'reported'`, is kept as it is.
|
|
254
388
|
|
|
255
|
-
|
|
389
|
+
### The model registry is current
|
|
256
390
|
|
|
257
391
|
The bundled registry was checked against each provider's documentation on 2026-10-02.
|
|
258
392
|
|
|
@@ -269,7 +403,7 @@ The bundled registry was checked against each provider's documentation on 2026-1
|
|
|
269
403
|
|
|
270
404
|
`describeModel()` shows what a name resolves to and when its entry was verified.
|
|
271
405
|
|
|
272
|
-
|
|
406
|
+
### Claude 4.6 onward think adaptively
|
|
273
407
|
|
|
274
408
|
From the 4.6 generation on, Claude takes adaptive thinking and an effort level, not a thinking budget.
|
|
275
409
|
After 4.6 a budget is rejected, so 1.x requests with `reasoning` failed on those models. 2.0 sends what
|
|
@@ -277,7 +411,7 @@ each model accepts, and the [core guide](docs/core.md#reasoning) has the details
|
|
|
277
411
|
your code. From 4.7 on, Claude also rejects a non-default `temperature` or `topP`, so the client
|
|
278
412
|
drops one and records a capability warning.
|
|
279
413
|
|
|
280
|
-
|
|
414
|
+
### Tool calls reach providers whole
|
|
281
415
|
|
|
282
416
|
In 1.x the OpenAI, Anthropic, and Google adapters dropped a conversation's tool calls and the ids that
|
|
283
417
|
link results to them. A real tool loop could fail on its second turn. 2.0 sends both the way each API
|
|
@@ -287,7 +421,7 @@ Two things are new beside it. A tool can return `toolOutput()`, whose text, imag
|
|
|
287
421
|
references go back as the tool message itself. And a model that produces images returns them on
|
|
288
422
|
`response.assets`.
|
|
289
423
|
|
|
290
|
-
|
|
424
|
+
### For provider authors
|
|
291
425
|
|
|
292
426
|
The provider contracts only grew:
|
|
293
427
|
|
|
@@ -298,6 +432,6 @@ The provider contracts only grew:
|
|
|
298
432
|
|
|
299
433
|
A provider written for 1.x compiles unchanged.
|
|
300
434
|
|
|
301
|
-
|
|
435
|
+
### Runtime
|
|
302
436
|
|
|
303
437
|
2.0 runs on Node 22 and newer.
|
package/README.md
CHANGED
|
@@ -345,13 +345,17 @@ Shipped so far:
|
|
|
345
345
|
- 2.22 MCP over streamable HTTP both ways, with prompts, resources, and a server's questions back to
|
|
346
346
|
the client; OpenAPI tools that send each operation's credentials; tokens, API keys, and sessions the
|
|
347
347
|
server issues; and a studio that signs people in with your identity provider and serves many
|
|
348
|
-
tenants, each seeing only its own
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
348
|
+
tenants, each seeing only its own;
|
|
349
|
+
- 3.0 the three defaults 2.21 previewed, on: tracing written as it runs, the Redis dispatch index, and
|
|
350
|
+
`hash-v2` for a new deployment, with `useDefaults('2.x')` for an application that upgrades first;
|
|
351
|
+
and the studio's sign-in, stable, proven against a real OpenID Connect provider on every build.
|
|
352
|
+
|
|
353
|
+
Upgrading from 2.x: 3.0 turns on three defaults 2.x kept opt-in, and `useDefaults('2.x')` keeps them
|
|
354
|
+
off until you are ready; from 1.x, `npx nexus migrate src --write` moves your imports.
|
|
355
|
+
[MIGRATING.md](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/MIGRATING.md) covers both.
|
|
356
|
+
Next, in 3.1, Pinecone, images, the Gemini embedding batch tier, media understanding, video, typed
|
|
357
|
+
decisions, Gemini Live, SIP, both phone providers, and Gemini's voice graduate once the live workflow
|
|
358
|
+
passes against each. The
|
|
355
359
|
[roadmap](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/ROADMAP.md) lists what comes after, in the order
|
|
356
360
|
applications ask for it.
|
|
357
361
|
|
package/SECURITY.md
CHANGED
|
@@ -281,8 +281,8 @@ Findings, each fixed in 2.5 with a test in `studio/test/security.test.ts`:
|
|
|
281
281
|
- **A proposal's pull-request link was rendered as stored.** The content security policy already
|
|
282
282
|
blocked a `javascript:` address. Only `http` and `https` links are rendered now.
|
|
283
283
|
|
|
284
|
-
Signing in and tenants, reviewed for 2.22, with tests in `studio/test/signin.test.ts
|
|
285
|
-
`studio/test/tenants.test.ts`:
|
|
284
|
+
Signing in and tenants, reviewed for 2.22, with tests in `studio/test/signin.test.ts`,
|
|
285
|
+
`studio/test/tenants.test.ts`, and, against Dex, a real provider, `studio/test/signin-dex.test.ts`:
|
|
286
286
|
- The provider's configuration must name the issuer the studio was given. An ID token must verify
|
|
287
287
|
against the provider's keys, name that issuer and the studio's client as its audience, and carry
|
|
288
288
|
the sign-in's nonce; a token for several clients must name the studio as `azp`.
|
package/dist/agent/openapi.d.ts
CHANGED
|
@@ -133,17 +133,6 @@ export interface OpenApiTools {
|
|
|
133
133
|
operations: OpenApiOperation[];
|
|
134
134
|
/** The JSON Schema of what each tool returns, by name: its first success response's. Pass it to `emulatedTools()` as `results`. */
|
|
135
135
|
results: Record<string, Record<string, unknown>>;
|
|
136
|
-
/**
|
|
137
|
-
* Operations that could not become tools, and why.
|
|
138
|
-
*
|
|
139
|
-
* @deprecated Every operation becomes a tool since 2.22, its body sent whatever its type, so this is
|
|
140
|
-
* always empty. It is removed in 3.0.
|
|
141
|
-
*/
|
|
142
|
-
skipped: Array<{
|
|
143
|
-
method: string;
|
|
144
|
-
path: string;
|
|
145
|
-
reason: string;
|
|
146
|
-
}>;
|
|
147
136
|
/** What the API sends the application, which no tool calls: its webhooks and its operations' callbacks. */
|
|
148
137
|
webhooks: OpenApiWebhook[];
|
|
149
138
|
}
|
package/dist/agent/openapi.js
CHANGED
package/dist/cli/migrate.d.ts
CHANGED
|
@@ -16,10 +16,11 @@ export interface MigrationOutcome {
|
|
|
16
16
|
notes: MigrationNote[];
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
|
-
* Migrates one file's text to
|
|
20
|
-
* subpaths, names that moved under another name keep their local name through an alias, and
|
|
21
|
-
* aliases are replaced. What cannot be rewritten safely — a namespace import of the root, a
|
|
22
|
-
* import, a read of `estimatedCost` — is reported instead
|
|
19
|
+
* Migrates one file's text to 2.0's imports and 3.0's names: names the root import drops are imported
|
|
20
|
+
* from their subpaths, names that moved under another name keep their local name through an alias, and
|
|
21
|
+
* deprecated aliases are replaced. What cannot be rewritten safely — a namespace import of the root, a
|
|
22
|
+
* dynamic import, a read of `estimatedCost` or of the OpenAPI tools' `skipped` — is reported instead
|
|
23
|
+
* of guessed at.
|
|
23
24
|
*
|
|
24
25
|
* Markdown is migrated inside its TypeScript and JavaScript code blocks only. Running it twice changes
|
|
25
26
|
* nothing the second time.
|
package/dist/cli/migrate.js
CHANGED
|
@@ -2,7 +2,10 @@ import { readdir, readFile, stat, writeFile } from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { CliUsageError, flagBool, writeJson } from './args.js';
|
|
4
4
|
import { ROOT_MOVES } from './root-moves.js';
|
|
5
|
-
const RENAMES = {
|
|
5
|
+
const RENAMES = {
|
|
6
|
+
ImageManagerConfig: 'ImageConfig',
|
|
7
|
+
GraphCheckpointV2: 'GraphCheckpoint',
|
|
8
|
+
};
|
|
6
9
|
const PACKAGE = 'nexus-ai-pro';
|
|
7
10
|
const CODE_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs']);
|
|
8
11
|
const MARKDOWN_EXTENSIONS = new Set(['.md', '.mdx']);
|
|
@@ -139,6 +142,20 @@ function migrateCode(text, lineOffset) {
|
|
|
139
142
|
message: "a response's `estimatedCost` string is removed in 2.0: read `cost.amount`, a number, and format it",
|
|
140
143
|
});
|
|
141
144
|
}
|
|
145
|
+
if (/nexus-ai-pro\/agent\/openapi|\b(?:loadOpenApiTools|openApiTools)\(/.test(text)) {
|
|
146
|
+
for (const match of text.matchAll(/\.skipped\b/g)) {
|
|
147
|
+
notes.push({
|
|
148
|
+
line: at(match.index ?? 0),
|
|
149
|
+
message: 'if this reads the OpenAPI tools, `skipped` was always empty since 2.22 and is removed in 3.0: delete the read',
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
for (const match of text.matchAll(/\buseDefaults\(\s*(['"])3\.0\1\s*\)/g)) {
|
|
154
|
+
notes.push({
|
|
155
|
+
line: at(match.index ?? 0),
|
|
156
|
+
message: "3.0's defaults are the default in 3.0: the call changes nothing, and can go",
|
|
157
|
+
});
|
|
158
|
+
}
|
|
142
159
|
for (const { pattern, message } of REMOVED_OPTIONS) {
|
|
143
160
|
for (const match of text.matchAll(pattern))
|
|
144
161
|
notes.push({ line: at(match.index ?? 0), message });
|
package/dist/core/defaults.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Which release's defaults apply where an option is left out:
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* option set explicitly always wins, under either.
|
|
2
|
+
* Which release's defaults apply where an option is left out: 3.0's, or 2.x's. 3.0 turns on three
|
|
3
|
+
* settings that 2.x kept opt-in; `2.x` keeps all three off at once, so an application can upgrade first
|
|
4
|
+
* and turn them on when it is ready. An option set explicitly always wins, under either.
|
|
6
5
|
*/
|
|
7
|
-
/** A release whose defaults apply: `
|
|
6
|
+
/** A release whose defaults apply: `3.0`, the default, or `2.x`, which keeps 2.x's three settings off. */
|
|
8
7
|
export type NexusDefaults = '2.x' | '3.0';
|
|
9
8
|
/** One default that 3.0 changes: what it is, what 2.x does, what 3.0 does, and what to do first. */
|
|
10
9
|
export interface DefaultChange {
|
|
@@ -12,23 +11,24 @@ export interface DefaultChange {
|
|
|
12
11
|
setting: string;
|
|
13
12
|
/** Where it is set. */
|
|
14
13
|
module: string;
|
|
15
|
-
/** What 2.x
|
|
14
|
+
/** What 2.x did when the option is left out, as `useDefaults('2.x')` still does. */
|
|
16
15
|
today: string;
|
|
17
|
-
/** What 3.0
|
|
16
|
+
/** What 3.0 does when it is left out. */
|
|
18
17
|
next: string;
|
|
19
18
|
/** What to do before turning it on, if anything. */
|
|
20
19
|
before: string;
|
|
21
20
|
}
|
|
22
|
-
/** The defaults 3.0 changes, each
|
|
21
|
+
/** The defaults 3.0 changes, each kept as 2.x had it by `useDefaults('2.x')`. */
|
|
23
22
|
export declare const DEFAULT_CHANGES: readonly DefaultChange[];
|
|
24
23
|
/**
|
|
25
|
-
* Chooses which release's defaults apply to everything created after it: `3.0
|
|
26
|
-
*
|
|
27
|
-
* a deployment: each reads the defaults when
|
|
24
|
+
* Chooses which release's defaults apply to everything created after it: `3.0`, the default, or `2.x`,
|
|
25
|
+
* which keeps the three settings 3.0 turns on off, for an application that upgrades before it turns them
|
|
26
|
+
* on. Call it before creating a tracer, an operation store, or a deployment: each reads the defaults when
|
|
27
|
+
* it is created. Overrides `NEXUS_DEFAULTS`.
|
|
28
28
|
*/
|
|
29
29
|
export declare function useDefaults(release: NexusDefaults): void;
|
|
30
30
|
/**
|
|
31
31
|
* The defaults in effect: as `useDefaults()` chose, else the `NEXUS_DEFAULTS` environment variable,
|
|
32
|
-
* `2.x` or `3.0`, else `
|
|
32
|
+
* `2.x` or `3.0`, else `3.0`. Throws for any other value of the variable, rather than ignore a typo.
|
|
33
33
|
*/
|
|
34
34
|
export declare function nexusDefaults(): NexusDefaults;
|
package/dist/core/defaults.js
CHANGED
|
@@ -11,7 +11,7 @@ export const DEFAULT_CHANGES = [
|
|
|
11
11
|
module: 'nexus-ai-pro/operations',
|
|
12
12
|
today: 'false: finding queued work reads every record',
|
|
13
13
|
next: 'true where the client has zadd, zrem, and zrangebyscore: queued and leased work is kept in sorted sets',
|
|
14
|
-
before: '
|
|
14
|
+
before: 'Call reindex() once no worker without the index shares the prefix: work such a worker queued is in the index only after it.',
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
setting: 'Deployments bucketStrategy',
|
|
@@ -30,7 +30,7 @@ export function nexusDefaults() {
|
|
|
30
30
|
return chosen;
|
|
31
31
|
const variable = globalThis.process?.env
|
|
32
32
|
?.NEXUS_DEFAULTS;
|
|
33
|
-
return variable === undefined || variable === '' ? '
|
|
33
|
+
return variable === undefined || variable === '' ? '3.0' : checked(variable, 'NEXUS_DEFAULTS');
|
|
34
34
|
}
|
|
35
35
|
function checked(release, where) {
|
|
36
36
|
if (release === '2.x' || release === '3.0')
|
package/dist/doctor/index.js
CHANGED
|
@@ -304,7 +304,7 @@ async function upgradeCheck(upgrade, deployment) {
|
|
|
304
304
|
return {
|
|
305
305
|
status: 'warn',
|
|
306
306
|
detail: `${findings.join('; ')}.`,
|
|
307
|
-
hint: "
|
|
307
|
+
hint: "Turn 3.0's defaults on, on every replica together: remove useDefaults('2.x') and NEXUS_DEFAULTS=2.x, which keep 2.x's.",
|
|
308
308
|
};
|
|
309
309
|
}
|
|
310
310
|
function kindOf(value) {
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import type { ChannelSchema, GraphCheckpoint, GraphCheckpointV1, GraphTask, PendingInterrupt, StoredGraphCheckpoint } from '../types/graph.js';
|
|
2
|
-
/**
|
|
3
|
-
* The 2.0 checkpoint schema under the name 1.25 gave it, so code written against 1.25 compiles.
|
|
4
|
-
*
|
|
5
|
-
* @deprecated Use `GraphCheckpoint`, which is this schema in 2.0.
|
|
6
|
-
*/
|
|
7
|
-
export type GraphCheckpointV2<S extends ChannelSchema = ChannelSchema> = GraphCheckpoint<S>;
|
|
8
2
|
/**
|
|
9
3
|
* Reads a checkpoint in the current schema from one in either schema. A custom checkpointer whose
|
|
10
4
|
* store still holds 1.x checkpoints can return them as they are, since the graph calls this on every
|
package/dist/graph/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { CompiledGraph, StateGraph, createGraph } from './graph.js';
|
|
2
|
-
export { type CheckpointDraft,
|
|
2
|
+
export { type CheckpointDraft, migrateCheckpoint, toCheckpoint, } from './checkpoint-migration.js';
|
|
3
3
|
export { appendList, appendSet, counter, lastValue, mergeObject, reducerChannel, } from './channels.js';
|
|
4
4
|
export { MemoryGraphCheckpointer, OperationStoreCheckpointer, type MemoryGraphCheckpointerOptions, type OperationStoreCheckpointerOptions, } from './checkpointer.js';
|
|
5
5
|
export { GraphDrainedError, GraphError, GraphInterrupt, GraphNodeError, GraphNodeTimeoutError, GraphNotInterruptedError, GraphStepLimitError, GraphThreadNotFoundError, GraphValidationError, interruptKey, } from './errors.js';
|
|
@@ -39,11 +39,12 @@ export interface RedisOperationStoreOptions {
|
|
|
39
39
|
* truth; an index entry only says where to look, and one that no longer matches its record is
|
|
40
40
|
* skipped and removed.
|
|
41
41
|
*
|
|
42
|
-
*
|
|
43
|
-
* worker
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* one
|
|
42
|
+
* On by default where the client has the commands it needs, and off under 2.x's defaults,
|
|
43
|
+
* `useDefaults('2.x')`. A worker without the index writes records without index entries, so what it
|
|
44
|
+
* queued is found once `reindex()` indexes what is already there: call it once no such worker
|
|
45
|
+
* shares the prefix. Needs
|
|
46
|
+
* `zadd`, `zrem`, and `zrangebyscore`; with `eval`, a record and its index entries change in one
|
|
47
|
+
* step.
|
|
47
48
|
*/
|
|
48
49
|
index?: boolean;
|
|
49
50
|
}
|
|
@@ -46,8 +46,8 @@ export interface RevisionedAssistantOptions {
|
|
|
46
46
|
/** What the assistant is, reported by the assistants endpoint. */
|
|
47
47
|
description?: string;
|
|
48
48
|
/**
|
|
49
|
-
* How the deployment places threads, when it is first recorded. Defaults to `
|
|
50
|
-
*
|
|
49
|
+
* How the deployment places threads, when it is first recorded. Defaults to `hash-v2`, and under
|
|
50
|
+
* 2.x's defaults, `useDefaults('2.x')`, to `fnv1a-v1`. A deployment already recorded keeps its own;
|
|
51
51
|
* `Deployments.bucketing()` changes it.
|
|
52
52
|
*/
|
|
53
53
|
bucketStrategy?: BucketStrategy;
|
package/dist/tracing/tracer.d.ts
CHANGED
|
@@ -33,8 +33,8 @@ export interface TracerOptions {
|
|
|
33
33
|
* run stays in the store with every run that finished, and a run in progress can be watched.
|
|
34
34
|
* Sampling is then decided when the root starts. A trace not sampled is still held in memory and
|
|
35
35
|
* written at the end when tail sampling keeps it, so `keepErrors` still shows every failure.
|
|
36
|
-
* Defaults to
|
|
37
|
-
*
|
|
36
|
+
* Defaults to true on a durable store, one whose `durable` is not `false`, and to false, which writes
|
|
37
|
+
* at the end, on one in memory and under 2.x's defaults, `useDefaults('2.x')`.
|
|
38
38
|
*/
|
|
39
39
|
incremental?: boolean;
|
|
40
40
|
/**
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const NEXUS_VERSION = '
|
|
1
|
+
export const NEXUS_VERSION = '3.0.0';
|
|
@@ -133,17 +133,6 @@ export interface OpenApiTools {
|
|
|
133
133
|
operations: OpenApiOperation[];
|
|
134
134
|
/** The JSON Schema of what each tool returns, by name: its first success response's. Pass it to `emulatedTools()` as `results`. */
|
|
135
135
|
results: Record<string, Record<string, unknown>>;
|
|
136
|
-
/**
|
|
137
|
-
* Operations that could not become tools, and why.
|
|
138
|
-
*
|
|
139
|
-
* @deprecated Every operation becomes a tool since 2.22, its body sent whatever its type, so this is
|
|
140
|
-
* always empty. It is removed in 3.0.
|
|
141
|
-
*/
|
|
142
|
-
skipped: Array<{
|
|
143
|
-
method: string;
|
|
144
|
-
path: string;
|
|
145
|
-
reason: string;
|
|
146
|
-
}>;
|
|
147
136
|
/** What the API sends the application, which no tool calls: its webhooks and its operations' callbacks. */
|
|
148
137
|
webhooks: OpenApiWebhook[];
|
|
149
138
|
}
|
|
@@ -16,10 +16,11 @@ export interface MigrationOutcome {
|
|
|
16
16
|
notes: MigrationNote[];
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
|
-
* Migrates one file's text to
|
|
20
|
-
* subpaths, names that moved under another name keep their local name through an alias, and
|
|
21
|
-
* aliases are replaced. What cannot be rewritten safely — a namespace import of the root, a
|
|
22
|
-
* import, a read of `estimatedCost` — is reported instead
|
|
19
|
+
* Migrates one file's text to 2.0's imports and 3.0's names: names the root import drops are imported
|
|
20
|
+
* from their subpaths, names that moved under another name keep their local name through an alias, and
|
|
21
|
+
* deprecated aliases are replaced. What cannot be rewritten safely — a namespace import of the root, a
|
|
22
|
+
* dynamic import, a read of `estimatedCost` or of the OpenAPI tools' `skipped` — is reported instead
|
|
23
|
+
* of guessed at.
|
|
23
24
|
*
|
|
24
25
|
* Markdown is migrated inside its TypeScript and JavaScript code blocks only. Running it twice changes
|
|
25
26
|
* nothing the second time.
|
package/dist-cjs/cli/migrate.js
CHANGED
|
@@ -10,7 +10,10 @@ const promises_1 = require("node:fs/promises");
|
|
|
10
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
11
11
|
const args_js_1 = require("./args.js");
|
|
12
12
|
const root_moves_js_1 = require("./root-moves.js");
|
|
13
|
-
const RENAMES = {
|
|
13
|
+
const RENAMES = {
|
|
14
|
+
ImageManagerConfig: 'ImageConfig',
|
|
15
|
+
GraphCheckpointV2: 'GraphCheckpoint',
|
|
16
|
+
};
|
|
14
17
|
const PACKAGE = 'nexus-ai-pro';
|
|
15
18
|
const CODE_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs']);
|
|
16
19
|
const MARKDOWN_EXTENSIONS = new Set(['.md', '.mdx']);
|
|
@@ -147,6 +150,20 @@ function migrateCode(text, lineOffset) {
|
|
|
147
150
|
message: "a response's `estimatedCost` string is removed in 2.0: read `cost.amount`, a number, and format it",
|
|
148
151
|
});
|
|
149
152
|
}
|
|
153
|
+
if (/nexus-ai-pro\/agent\/openapi|\b(?:loadOpenApiTools|openApiTools)\(/.test(text)) {
|
|
154
|
+
for (const match of text.matchAll(/\.skipped\b/g)) {
|
|
155
|
+
notes.push({
|
|
156
|
+
line: at(match.index ?? 0),
|
|
157
|
+
message: 'if this reads the OpenAPI tools, `skipped` was always empty since 2.22 and is removed in 3.0: delete the read',
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
for (const match of text.matchAll(/\buseDefaults\(\s*(['"])3\.0\1\s*\)/g)) {
|
|
162
|
+
notes.push({
|
|
163
|
+
line: at(match.index ?? 0),
|
|
164
|
+
message: "3.0's defaults are the default in 3.0: the call changes nothing, and can go",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
150
167
|
for (const { pattern, message } of REMOVED_OPTIONS) {
|
|
151
168
|
for (const match of text.matchAll(pattern))
|
|
152
169
|
notes.push({ line: at(match.index ?? 0), message });
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Which release's defaults apply where an option is left out:
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* option set explicitly always wins, under either.
|
|
2
|
+
* Which release's defaults apply where an option is left out: 3.0's, or 2.x's. 3.0 turns on three
|
|
3
|
+
* settings that 2.x kept opt-in; `2.x` keeps all three off at once, so an application can upgrade first
|
|
4
|
+
* and turn them on when it is ready. An option set explicitly always wins, under either.
|
|
6
5
|
*/
|
|
7
|
-
/** A release whose defaults apply: `
|
|
6
|
+
/** A release whose defaults apply: `3.0`, the default, or `2.x`, which keeps 2.x's three settings off. */
|
|
8
7
|
export type NexusDefaults = '2.x' | '3.0';
|
|
9
8
|
/** One default that 3.0 changes: what it is, what 2.x does, what 3.0 does, and what to do first. */
|
|
10
9
|
export interface DefaultChange {
|
|
@@ -12,23 +11,24 @@ export interface DefaultChange {
|
|
|
12
11
|
setting: string;
|
|
13
12
|
/** Where it is set. */
|
|
14
13
|
module: string;
|
|
15
|
-
/** What 2.x
|
|
14
|
+
/** What 2.x did when the option is left out, as `useDefaults('2.x')` still does. */
|
|
16
15
|
today: string;
|
|
17
|
-
/** What 3.0
|
|
16
|
+
/** What 3.0 does when it is left out. */
|
|
18
17
|
next: string;
|
|
19
18
|
/** What to do before turning it on, if anything. */
|
|
20
19
|
before: string;
|
|
21
20
|
}
|
|
22
|
-
/** The defaults 3.0 changes, each
|
|
21
|
+
/** The defaults 3.0 changes, each kept as 2.x had it by `useDefaults('2.x')`. */
|
|
23
22
|
export declare const DEFAULT_CHANGES: readonly DefaultChange[];
|
|
24
23
|
/**
|
|
25
|
-
* Chooses which release's defaults apply to everything created after it: `3.0
|
|
26
|
-
*
|
|
27
|
-
* a deployment: each reads the defaults when
|
|
24
|
+
* Chooses which release's defaults apply to everything created after it: `3.0`, the default, or `2.x`,
|
|
25
|
+
* which keeps the three settings 3.0 turns on off, for an application that upgrades before it turns them
|
|
26
|
+
* on. Call it before creating a tracer, an operation store, or a deployment: each reads the defaults when
|
|
27
|
+
* it is created. Overrides `NEXUS_DEFAULTS`.
|
|
28
28
|
*/
|
|
29
29
|
export declare function useDefaults(release: NexusDefaults): void;
|
|
30
30
|
/**
|
|
31
31
|
* The defaults in effect: as `useDefaults()` chose, else the `NEXUS_DEFAULTS` environment variable,
|
|
32
|
-
* `2.x` or `3.0`, else `
|
|
32
|
+
* `2.x` or `3.0`, else `3.0`. Throws for any other value of the variable, rather than ignore a typo.
|
|
33
33
|
*/
|
|
34
34
|
export declare function nexusDefaults(): NexusDefaults;
|
|
@@ -16,7 +16,7 @@ exports.DEFAULT_CHANGES = [
|
|
|
16
16
|
module: 'nexus-ai-pro/operations',
|
|
17
17
|
today: 'false: finding queued work reads every record',
|
|
18
18
|
next: 'true where the client has zadd, zrem, and zrangebyscore: queued and leased work is kept in sorted sets',
|
|
19
|
-
before: '
|
|
19
|
+
before: 'Call reindex() once no worker without the index shares the prefix: work such a worker queued is in the index only after it.',
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
setting: 'Deployments bucketStrategy',
|
|
@@ -35,7 +35,7 @@ function nexusDefaults() {
|
|
|
35
35
|
return chosen;
|
|
36
36
|
const variable = globalThis.process?.env
|
|
37
37
|
?.NEXUS_DEFAULTS;
|
|
38
|
-
return variable === undefined || variable === '' ? '
|
|
38
|
+
return variable === undefined || variable === '' ? '3.0' : checked(variable, 'NEXUS_DEFAULTS');
|
|
39
39
|
}
|
|
40
40
|
function checked(release, where) {
|
|
41
41
|
if (release === '2.x' || release === '3.0')
|
package/dist-cjs/doctor/index.js
CHANGED
|
@@ -343,7 +343,7 @@ async function upgradeCheck(upgrade, deployment) {
|
|
|
343
343
|
return {
|
|
344
344
|
status: 'warn',
|
|
345
345
|
detail: `${findings.join('; ')}.`,
|
|
346
|
-
hint: "
|
|
346
|
+
hint: "Turn 3.0's defaults on, on every replica together: remove useDefaults('2.x') and NEXUS_DEFAULTS=2.x, which keep 2.x's.",
|
|
347
347
|
};
|
|
348
348
|
}
|
|
349
349
|
function kindOf(value) {
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import type { ChannelSchema, GraphCheckpoint, GraphCheckpointV1, GraphTask, PendingInterrupt, StoredGraphCheckpoint } from '../types/graph.js';
|
|
2
|
-
/**
|
|
3
|
-
* The 2.0 checkpoint schema under the name 1.25 gave it, so code written against 1.25 compiles.
|
|
4
|
-
*
|
|
5
|
-
* @deprecated Use `GraphCheckpoint`, which is this schema in 2.0.
|
|
6
|
-
*/
|
|
7
|
-
export type GraphCheckpointV2<S extends ChannelSchema = ChannelSchema> = GraphCheckpoint<S>;
|
|
8
2
|
/**
|
|
9
3
|
* Reads a checkpoint in the current schema from one in either schema. A custom checkpointer whose
|
|
10
4
|
* store still holds 1.x checkpoints can return them as they are, since the graph calls this on every
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { CompiledGraph, StateGraph, createGraph } from './graph.js';
|
|
2
|
-
export { type CheckpointDraft,
|
|
2
|
+
export { type CheckpointDraft, migrateCheckpoint, toCheckpoint, } from './checkpoint-migration.js';
|
|
3
3
|
export { appendList, appendSet, counter, lastValue, mergeObject, reducerChannel, } from './channels.js';
|
|
4
4
|
export { MemoryGraphCheckpointer, OperationStoreCheckpointer, type MemoryGraphCheckpointerOptions, type OperationStoreCheckpointerOptions, } from './checkpointer.js';
|
|
5
5
|
export { GraphDrainedError, GraphError, GraphInterrupt, GraphNodeError, GraphNodeTimeoutError, GraphNotInterruptedError, GraphStepLimitError, GraphThreadNotFoundError, GraphValidationError, interruptKey, } from './errors.js';
|
|
@@ -39,11 +39,12 @@ export interface RedisOperationStoreOptions {
|
|
|
39
39
|
* truth; an index entry only says where to look, and one that no longer matches its record is
|
|
40
40
|
* skipped and removed.
|
|
41
41
|
*
|
|
42
|
-
*
|
|
43
|
-
* worker
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* one
|
|
42
|
+
* On by default where the client has the commands it needs, and off under 2.x's defaults,
|
|
43
|
+
* `useDefaults('2.x')`. A worker without the index writes records without index entries, so what it
|
|
44
|
+
* queued is found once `reindex()` indexes what is already there: call it once no such worker
|
|
45
|
+
* shares the prefix. Needs
|
|
46
|
+
* `zadd`, `zrem`, and `zrangebyscore`; with `eval`, a record and its index entries change in one
|
|
47
|
+
* step.
|
|
47
48
|
*/
|
|
48
49
|
index?: boolean;
|
|
49
50
|
}
|
|
@@ -46,8 +46,8 @@ export interface RevisionedAssistantOptions {
|
|
|
46
46
|
/** What the assistant is, reported by the assistants endpoint. */
|
|
47
47
|
description?: string;
|
|
48
48
|
/**
|
|
49
|
-
* How the deployment places threads, when it is first recorded. Defaults to `
|
|
50
|
-
*
|
|
49
|
+
* How the deployment places threads, when it is first recorded. Defaults to `hash-v2`, and under
|
|
50
|
+
* 2.x's defaults, `useDefaults('2.x')`, to `fnv1a-v1`. A deployment already recorded keeps its own;
|
|
51
51
|
* `Deployments.bucketing()` changes it.
|
|
52
52
|
*/
|
|
53
53
|
bucketStrategy?: BucketStrategy;
|
|
@@ -33,8 +33,8 @@ export interface TracerOptions {
|
|
|
33
33
|
* run stays in the store with every run that finished, and a run in progress can be watched.
|
|
34
34
|
* Sampling is then decided when the root starts. A trace not sampled is still held in memory and
|
|
35
35
|
* written at the end when tail sampling keeps it, so `keepErrors` still shows every failure.
|
|
36
|
-
* Defaults to
|
|
37
|
-
*
|
|
36
|
+
* Defaults to true on a durable store, one whose `durable` is not `false`, and to false, which writes
|
|
37
|
+
* at the end, on one in memory and under 2.x's defaults, `useDefaults('2.x')`.
|
|
38
38
|
*/
|
|
39
39
|
incremental?: boolean;
|
|
40
40
|
/**
|
package/dist-cjs/version.d.ts
CHANGED
package/dist-cjs/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexus-ai-pro",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Typed AI framework for TypeScript: provider routing and failover, durable agent graphs and workflows, retrieval over any vector store, MCP, evals, guardrails, and cost control",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist-cjs/index.js",
|
|
@@ -2204,6 +2204,7 @@
|
|
|
2204
2204
|
"express": "^5.1.0",
|
|
2205
2205
|
"nexus-ai-pro-2-0": "npm:nexus-ai-pro@^2.0.0",
|
|
2206
2206
|
"nexus-ai-pro-2-1": "npm:nexus-ai-pro@^2.1.0",
|
|
2207
|
+
"nexus-ai-pro-2-21": "npm:nexus-ai-pro@^2.21.0",
|
|
2207
2208
|
"nexus-ai-pro-2-3": "npm:nexus-ai-pro@^2.3.0",
|
|
2208
2209
|
"nexus-ai-pro-2-5": "npm:nexus-ai-pro@^2.5.0",
|
|
2209
2210
|
"nexus-ai-pro-2-7": "npm:nexus-ai-pro@^2.7.0",
|