nexus-ai-pro 2.21.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 +98 -2
- package/CHANGELOG.md +165 -1
- package/MIGRATING.md +151 -17
- package/README.md +15 -7
- package/SECURITY.md +16 -2
- package/dist/agent/openapi.d.ts +88 -13
- package/dist/agent/openapi.js +527 -32
- 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/core/secure-stream.js +4 -1
- package/dist/decisions/completion.js +2 -2
- package/dist/decisions/typesafe.d.ts +11 -3
- package/dist/decisions/typesafe.js +28 -9
- package/dist/doctor/index.js +1 -1
- package/dist/embeddings/adapters.d.ts +1 -1
- package/dist/embeddings/adapters.js +3 -3
- package/dist/embeddings/batch-google.d.ts +27 -8
- package/dist/embeddings/batch-google.js +112 -36
- package/dist/embeddings/batch-mock.js +1 -1
- package/dist/embeddings/batch.js +10 -4
- package/dist/embeddings/engine.js +14 -13
- package/dist/embeddings/index.d.ts +1 -1
- package/dist/embeddings/inputs.d.ts +26 -3
- package/dist/embeddings/inputs.js +84 -5
- package/dist/embeddings/mock.js +1 -1
- package/dist/embeddings/models.js +39 -4
- package/dist/graph/checkpoint-migration.d.ts +0 -6
- package/dist/graph/index.d.ts +1 -1
- package/dist/loaders/csv.d.ts +23 -1
- package/dist/loaders/csv.js +125 -72
- package/dist/loaders/index.d.ts +7 -2
- package/dist/loaders/input.d.ts +6 -0
- package/dist/loaders/input.js +42 -1
- package/dist/loaders/json.d.ts +14 -3
- package/dist/loaders/json.js +171 -20
- package/dist/loaders/web.d.ts +55 -0
- package/dist/loaders/web.js +20 -1
- package/dist/mcp/client.d.ts +54 -5
- package/dist/mcp/client.js +171 -20
- package/dist/mcp/http.d.ts +45 -0
- package/dist/mcp/http.js +233 -0
- package/dist/mcp/index.d.ts +4 -2
- package/dist/mcp/index.js +3 -1
- package/dist/mcp/protocol.d.ts +107 -0
- package/dist/mcp/sampling.d.ts +41 -0
- package/dist/mcp/sampling.js +52 -0
- package/dist/mcp/server.d.ts +96 -14
- package/dist/mcp/server.js +274 -59
- package/dist/models/data.js +20 -1
- package/dist/operations/adapters.d.ts +6 -5
- package/dist/protocols/a2a-grpc.js +10 -3
- package/dist/protocols/a2a-signing.d.ts +65 -0
- package/dist/protocols/a2a-signing.js +133 -0
- package/dist/protocols/a2a.d.ts +14 -0
- package/dist/protocols/a2a.js +44 -8
- package/dist/providers/cohere.js +16 -2
- package/dist/providers/google.js +7 -1
- package/dist/providers/ollama.d.ts +1 -1
- package/dist/providers/ollama.js +35 -27
- package/dist/providers/openai.js +6 -2
- package/dist/rag/pinecone.d.ts +63 -2
- package/dist/rag/pinecone.js +80 -0
- package/dist/realtime/conversation.js +18 -0
- package/dist/realtime/gemini-live.transport.d.ts +28 -3
- package/dist/realtime/gemini-live.transport.js +170 -32
- package/dist/realtime/session.d.ts +2 -0
- package/dist/realtime/session.js +19 -4
- package/dist/realtime/types.d.ts +35 -3
- package/dist/security/output-guard.js +4 -1
- package/dist/server/auth.d.ts +263 -2
- package/dist/server/auth.js +432 -5
- package/dist/server/deployments.d.ts +2 -2
- package/dist/telephony/index.d.ts +1 -1
- package/dist/telephony/manager.d.ts +8 -1
- package/dist/telephony/manager.js +13 -0
- package/dist/telephony/providers/telnyx.d.ts +18 -5
- package/dist/telephony/providers/telnyx.js +44 -7
- package/dist/telephony/providers/twilio.d.ts +3 -1
- package/dist/telephony/providers/twilio.js +16 -0
- package/dist/tracing/tracer.d.ts +2 -2
- package/dist/types/embeddings.d.ts +47 -5
- package/dist/types/messages.d.ts +7 -0
- package/dist/types/principal.d.ts +1 -1
- package/dist/types/response.d.ts +5 -0
- package/dist/types/telephony.d.ts +38 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/voice/providers/google.d.ts +44 -0
- package/dist/voice/providers/google.js +215 -0
- package/dist-cjs/agent/openapi.d.ts +88 -13
- package/dist-cjs/agent/openapi.js +529 -32
- 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/core/secure-stream.js +4 -1
- package/dist-cjs/decisions/completion.js +2 -2
- package/dist-cjs/decisions/typesafe.d.ts +11 -3
- package/dist-cjs/decisions/typesafe.js +28 -9
- package/dist-cjs/doctor/index.js +1 -1
- package/dist-cjs/embeddings/adapters.d.ts +1 -1
- package/dist-cjs/embeddings/adapters.js +3 -3
- package/dist-cjs/embeddings/batch-google.d.ts +27 -8
- package/dist-cjs/embeddings/batch-google.js +112 -36
- package/dist-cjs/embeddings/batch-mock.js +1 -1
- package/dist-cjs/embeddings/batch.js +9 -3
- package/dist-cjs/embeddings/engine.js +13 -12
- package/dist-cjs/embeddings/index.d.ts +1 -1
- package/dist-cjs/embeddings/inputs.d.ts +26 -3
- package/dist-cjs/embeddings/inputs.js +89 -5
- package/dist-cjs/embeddings/mock.js +1 -1
- package/dist-cjs/embeddings/models.js +39 -4
- package/dist-cjs/graph/checkpoint-migration.d.ts +0 -6
- package/dist-cjs/graph/index.d.ts +1 -1
- package/dist-cjs/loaders/csv.d.ts +23 -1
- package/dist-cjs/loaders/csv.js +126 -71
- package/dist-cjs/loaders/index.d.ts +7 -2
- package/dist-cjs/loaders/input.d.ts +6 -0
- package/dist-cjs/loaders/input.js +43 -1
- package/dist-cjs/loaders/json.d.ts +14 -3
- package/dist-cjs/loaders/json.js +170 -19
- package/dist-cjs/loaders/web.d.ts +55 -0
- package/dist-cjs/loaders/web.js +21 -1
- package/dist-cjs/mcp/client.d.ts +54 -5
- package/dist-cjs/mcp/client.js +171 -20
- package/dist-cjs/mcp/http.d.ts +45 -0
- package/dist-cjs/mcp/http.js +236 -0
- package/dist-cjs/mcp/index.d.ts +4 -2
- package/dist-cjs/mcp/index.js +5 -1
- package/dist-cjs/mcp/protocol.d.ts +107 -0
- package/dist-cjs/mcp/sampling.d.ts +41 -0
- package/dist-cjs/mcp/sampling.js +55 -0
- package/dist-cjs/mcp/server.d.ts +96 -14
- package/dist-cjs/mcp/server.js +273 -58
- package/dist-cjs/models/data.js +20 -1
- package/dist-cjs/operations/adapters.d.ts +6 -5
- package/dist-cjs/protocols/a2a-grpc.js +10 -3
- package/dist-cjs/protocols/a2a-signing.d.ts +65 -0
- package/dist-cjs/protocols/a2a-signing.js +140 -0
- package/dist-cjs/protocols/a2a.d.ts +14 -0
- package/dist-cjs/protocols/a2a.js +49 -9
- package/dist-cjs/providers/cohere.js +16 -2
- package/dist-cjs/providers/google.js +7 -1
- package/dist-cjs/providers/ollama.d.ts +1 -1
- package/dist-cjs/providers/ollama.js +35 -27
- package/dist-cjs/providers/openai.js +6 -2
- package/dist-cjs/rag/pinecone.d.ts +63 -2
- package/dist-cjs/rag/pinecone.js +81 -0
- package/dist-cjs/realtime/conversation.js +18 -0
- package/dist-cjs/realtime/gemini-live.transport.d.ts +28 -3
- package/dist-cjs/realtime/gemini-live.transport.js +170 -32
- package/dist-cjs/realtime/session.d.ts +2 -0
- package/dist-cjs/realtime/session.js +19 -4
- package/dist-cjs/realtime/types.d.ts +35 -3
- package/dist-cjs/security/output-guard.js +4 -1
- package/dist-cjs/server/auth.d.ts +263 -2
- package/dist-cjs/server/auth.js +437 -5
- package/dist-cjs/server/deployments.d.ts +2 -2
- package/dist-cjs/telephony/index.d.ts +1 -1
- package/dist-cjs/telephony/manager.d.ts +8 -1
- package/dist-cjs/telephony/manager.js +13 -0
- package/dist-cjs/telephony/providers/telnyx.d.ts +18 -5
- package/dist-cjs/telephony/providers/telnyx.js +44 -7
- package/dist-cjs/telephony/providers/twilio.d.ts +3 -1
- package/dist-cjs/telephony/providers/twilio.js +16 -0
- package/dist-cjs/tracing/tracer.d.ts +2 -2
- package/dist-cjs/types/embeddings.d.ts +47 -5
- package/dist-cjs/types/messages.d.ts +7 -0
- package/dist-cjs/types/principal.d.ts +1 -1
- package/dist-cjs/types/response.d.ts +5 -0
- package/dist-cjs/types/telephony.d.ts +38 -0
- package/dist-cjs/version.d.ts +1 -1
- package/dist-cjs/version.js +1 -1
- package/dist-cjs/voice/providers/google.d.ts +44 -0
- package/dist-cjs/voice/providers/google.js +252 -0
- package/llms.txt +1 -1
- package/package.json +18 -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,102 @@ 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
|
+
|
|
103
|
+
## 2.22 stage (2.22.0)
|
|
104
|
+
|
|
105
|
+
Everything 2.22 adds is stable from the start and additive, unless this section says otherwise.
|
|
106
|
+
|
|
107
|
+
New and stable: `StreamChunk.logprobs`; in `nexus-ai-pro/protocols/a2a`, `signA2aCard()`,
|
|
108
|
+
`verifyA2aCard()`, `canonicalA2aCard()`, `A2aCardSignatureError`, `A2aCardSigner`, `A2aCardKeyResolver`,
|
|
109
|
+
`A2aSignatureAlgorithm`, `A2aJsonWebKey`, `A2aCryptoKey`, `A2aServerOptions.sign`, and
|
|
110
|
+
`A2aClientOptions.verifyCard`, which `A2aGrpcClientOptions` takes too; in `nexus-ai-pro/mcp`,
|
|
111
|
+
`mcpHttpHandler()`, `McpHttpOptions`, `McpHttpHandler`, `samplingFrom()`, `McpSamplingOptions`,
|
|
112
|
+
`McpSamplingClient`, `McpServerPrompt`, `McpPromptArgument`, `McpPromptMessage`, `McpServerResource`,
|
|
113
|
+
the server's `registerPrompt()`, `registerResource()`, `resourceUpdated()`, `createMessage()`,
|
|
114
|
+
`elicit()`, `listRoots()`, and `onRootsChanged()`, the client's `sampling`, `elicitation`, and `roots`
|
|
115
|
+
options, `onPromptsChanged()`, `onResourcesChanged()`, `onResourceUpdated()`, `subscribeResource()`,
|
|
116
|
+
`unsubscribeResource()`, and `rootsChanged()`, `HttpClientOptions.listen`, the protocol types
|
|
117
|
+
`McpSamplingRequest`, `McpSamplingResult`, `McpSamplingMessage`, `McpSamplingContent`,
|
|
118
|
+
`McpModelPreferences`, `McpElicitationRequest`, `McpElicitationResult`, `McpRoot`, and
|
|
119
|
+
`McpCallerRequests`, and `ToolContext.mcp`; in `nexus-ai-pro/agent/openapi`, `swaggerToOpenApi()`,
|
|
120
|
+
`bundleOpenApiDocument()`, `OpenApiBundleOptions`, `OpenApiCredential`, `OpenApiWebhook`,
|
|
121
|
+
`OpenApiToolsOptions.credentials`, `OpenApiOperation.security`, `OpenApiTools.webhooks`, and
|
|
122
|
+
`loadOpenApiTools()`'s `references`, `maxDocuments`, and `maxBytes`; in `nexus-ai-pro/server/auth`,
|
|
123
|
+
`createJwtSigner()`, `JwtSigner`, `JwtSignerOptions`, `JwtSignOptions`, `generateJwtKey()`,
|
|
124
|
+
`jwksHandler()`, `createApiKeyStore()`, `ApiKeyStore`, `ApiKeyStoreOptions`, `ApiKeyRecord`,
|
|
125
|
+
`IssuedApiKey`, `ApiKeyIssueOptions`, `createSessions()`, `Sessions`, `SessionOptions`,
|
|
126
|
+
`SessionCookieOptions`, `SessionRecord`, and `StartedSession`, and the principal method `session`; in
|
|
127
|
+
`nexus-ai-pro/rag/pinecone`, `PineconeVectorStore.create()`, `ensurePineconeIndex()`,
|
|
128
|
+
`PineconeIndexOptions`, `PineconeIndex`, and `PineconeCreateOptions`, experimental with the store;
|
|
129
|
+
`TypeSafeDecisionProviderOptions.pictures`; and in `nexus-ai-pro/embeddings`, `EmbeddingVideoPart`, the
|
|
130
|
+
modality `video`, `EmbeddingMeta.unpricedMedia`, and `EmbeddingModelCapabilities`'
|
|
131
|
+
`costPerAudioSecond`, `costPerVideoFrame`, `videoFrames`, `maxAudioSeconds`, and `maxVideoSeconds`; in
|
|
132
|
+
the loaders, `FileInput`'s stream form, `CsvRowParser`, `JsonLoaderOptions.recordsAt`,
|
|
133
|
+
`WebLoaderOptions.render` and `renderBelow`, `browserRenderer()`, `WebPageRenderer`, `WebPageToRender`,
|
|
134
|
+
`RenderingBrowser`, and `BrowserRendererOptions`; in the realtime family, `ImageItem`, the `message.image`
|
|
135
|
+
event, and `RealtimeConversationOptions.recordImages`; in telephony, `TelephonyGatherResult`,
|
|
136
|
+
`EndGatherRequest`, `parseGatherResult()` and `endGather()` on the manager and the providers, and
|
|
137
|
+
`TelnyxTelephonyProviderConfig.transcriptionEngine`; in the studio, `StudioOptions.tenantSources`,
|
|
138
|
+
`StudioUser.tenant`, `StudioAuditEntry.tenant`, `StudioComment.tenant`, `StudioAuditQuery`,
|
|
139
|
+
`HeaderAuthOptions.tenant`, `BearerAuthOptions.tenant`, `StudioSignIn`, and `StudioOptions.signIn`.
|
|
140
|
+
Experimental: in the studio, `oidcSignIn()`, `OidcSignInOptions`, `SIGN_IN_COOKIE`, and the
|
|
141
|
+
`/auth/` routes, until a sign-in against a live provider is recorded; `nexus-ai-pro/voice/google`,
|
|
142
|
+
`GoogleVoiceProvider` and `GoogleVoiceProviderConfig`, until a live run is recorded.
|
|
143
|
+
The state store keys and sessions are kept in, under `nexus/server`, is read by every later 2.x.
|
|
144
|
+
|
|
145
|
+
Changed on purpose: an answer the output guard changes or blocks keeps no `logprobs`, streamed or
|
|
146
|
+
not; a typed decision of a model that reports the chosen token alone is sampled; an Ollama stream
|
|
147
|
+
honours `stop`. An MCP server declares prompts and resource subscriptions at `initialize` whatever it
|
|
148
|
+
was given, and serves every transport connected to it rather than the last; a tool it runs gets a
|
|
149
|
+
`signal` and `mcp` in its context. The HTTP client transport returns from `send()` before a streamed
|
|
150
|
+
answer ends, sends `mcp-protocol-version`, and sends a `DELETE` when closed with a session. OpenAPI
|
|
151
|
+
tools are made of operations with any request body, where those with a body other than JSON or a form
|
|
152
|
+
were skipped, and of Swagger 2.0 documents, which were refused; `loadOpenApiTools()` reads no more of
|
|
153
|
+
a document than `maxBytes`. With `credentials` given, an operation whose security cannot be met fails
|
|
154
|
+
before it is sent.
|
|
155
|
+
|
|
156
|
+
A TypeSafe AI request with pictures is multipart unless `pictures: 'base64'`, and its size is counted
|
|
157
|
+
in bytes. gemini-embedding-2's audio and video are priced, where they cost nothing before, and audio
|
|
158
|
+
past 180 seconds or video past 120 is refused before the call. A Google embedding batch over 20 MB is
|
|
159
|
+
sent as a file, where it was refused. Gemini Live acts on `updateSession()`, which it ignored. A
|
|
160
|
+
realtime record holds the images sent, as `image` items, which a consumer that switches on every item
|
|
161
|
+
type meets for the first time. A Telnyx gather for speech transcribes the caller, where it was
|
|
162
|
+
refused.
|
|
163
|
+
|
|
164
|
+
Deprecated: `OpenApiTools.skipped`, always empty, is removed in 3.0.
|
|
165
|
+
|
|
70
166
|
## 2.21 stage (2.21.0)
|
|
71
167
|
|
|
72
168
|
Everything 2.21 adds is stable from the start and additive, unless this section says otherwise.
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,168 @@ 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
|
+
|
|
38
|
+
## [2.22.0] - 2026-10-29
|
|
39
|
+
|
|
40
|
+
MCP over streamable HTTP both ways, OpenAPI tools that send each operation's credentials, tokens, keys,
|
|
41
|
+
and sessions the server issues, and a studio that signs people in and serves many tenants; with signed
|
|
42
|
+
A2A cards, embeddings of video, loaders that stream, Gemini's voice, and the kernel in Firefox and
|
|
43
|
+
WebKit.
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
- **Log probabilities from a stream.** Each `text` chunk's `StreamChunk.logprobs` holds its tokens'
|
|
48
|
+
log probabilities, from OpenAI's Chat Completions and Responses API, Gemini, Ollama, and Cohere, so
|
|
49
|
+
the chunks' together are what `complete()` reports.
|
|
50
|
+
- Cohere reports log probabilities, `complete()` and streamed: a piece of text at a time, each piece's
|
|
51
|
+
the sum of its tokens', with no alternatives.
|
|
52
|
+
- **MCP both ways.** A server offers prompts (`McpServerPrompt`, `registerPrompt()`), resources a client
|
|
53
|
+
subscribes to (`resourceUpdated()`), and tells every client each list's changes; a tool it runs may ask
|
|
54
|
+
the client that called it for a completion from its model, an answer from its person, or its roots,
|
|
55
|
+
through `context.mcp`, and is stopped when the client cancels it. A client answers a server's
|
|
56
|
+
`sampling`, `elicitation`, and `roots` with handlers of its own, `samplingFrom()` answering with
|
|
57
|
+
the application's own model, and hears each list change and each resource it subscribed to.
|
|
58
|
+
- **MCP over streamable HTTP, both ways.** `mcpHttpHandler()` serves an `McpServer` as a Web handler:
|
|
59
|
+
a session per client, a stream of events per request carrying the server's progress and questions
|
|
60
|
+
before its answer, a `GET` stream for what it sends of its own accord, `DELETE` to end a session, and
|
|
61
|
+
a request from another origin refused. The client's HTTP transport reads a stream as it comes, so a
|
|
62
|
+
question in the middle of a call arrives in time, listens on a `GET` stream with `listen`, sends the
|
|
63
|
+
protocol version, and ends its session on `close()`. The nightly interoperability run drives the
|
|
64
|
+
server with `@modelcontextprotocol/sdk`'s own client: its tools, a completion asked mid-call, its
|
|
65
|
+
progress, a prompt, and a subscribed resource's change.
|
|
66
|
+
- **Signed A2A cards.** `signA2aCard()` and `verifyA2aCard()`, with `canonicalA2aCard()`, sign and check
|
|
67
|
+
a card as protocol 1.0 does, a flattened JWS over its canonical form, which is the A2A project's SDK's
|
|
68
|
+
form: a card either signs, the other verifies. A handler's `sign` signs every card it serves, each
|
|
69
|
+
tenant's and the extended card included, and a client's `verifyCard` makes no call until a signature
|
|
70
|
+
on the card holds. ES256, ES384, ES512, RS256, RS384, RS512, PS256, PS384, PS512, and Ed25519, by the
|
|
71
|
+
Web Crypto API alone. The nightly interoperability run checks both directions against `@a2a-js/sdk`.
|
|
72
|
+
- **OpenAPI credentials.** Tools read from an OpenAPI document send the credentials each operation's
|
|
73
|
+
security asks for, from `credentials` given by scheme name, or chosen per call: an API key in a
|
|
74
|
+
header, query parameter, or cookie; HTTP Basic, bearer, or another HTTP scheme; and an OAuth 2.0 or
|
|
75
|
+
OpenID Connect token, held, or fetched by the client-credentials flow for the operation's scopes and
|
|
76
|
+
kept until a minute before it expires. An operation whose alternatives none can be met fails before
|
|
77
|
+
anything is sent, naming them. Each `OpenApiOperation` carries its `security`.
|
|
78
|
+
- **Swagger 2.0, and references to other documents.** A Swagger 2.0 document is read as the OpenAPI 3.0
|
|
79
|
+
one it describes, which `swaggerToOpenApi()` returns. `bundleOpenApiDocument()` reads in the other
|
|
80
|
+
documents a document's references name, on its own origin by default, or as `references` allows,
|
|
81
|
+
within `maxDocuments` and `maxBytes`; `loadOpenApiTools()` does so itself.
|
|
82
|
+
- OpenAPI tools send a multipart form, its file fields given as base64, a text or XML body, and a body
|
|
83
|
+
of bytes, such as an image, so every operation becomes a tool. `webhooks` lists what the API sends
|
|
84
|
+
the application, its webhooks and its operations' callbacks, each with its JSON body's schema.
|
|
85
|
+
- **Tokens, keys, and sessions the server issues.** `createJwtSigner()` issues tokens with a secret, a
|
|
86
|
+
PEM or JWK private key, or a Web Crypto key pair, and `issue()` writes a principal under the claim
|
|
87
|
+
names `jwtAuth()` reads back; `generateJwtKey()` makes a key, and `jwksHandler()` publishes the
|
|
88
|
+
public halves, for a rotation that refuses no live token. `createApiKeyStore()` issues, rotates with
|
|
89
|
+
a grace period, and revokes API keys, kept as hashes in the server's state store with when each was
|
|
90
|
+
last used. `createSessions()` signs browsers in after a sign-in of the application's own: an
|
|
91
|
+
`HttpOnly`, `Secure`, `SameSite=Lax` cookie of a random secret whose hash alone is kept, an idle
|
|
92
|
+
and a total lifetime, sign-out here or everywhere, and a request from another site's page refused.
|
|
93
|
+
- **A Pinecone store makes its own index.** `PineconeVectorStore.create()` creates a serverless index
|
|
94
|
+
with the cosine metric and the store's width, or uses one of that name that fits, waits until it is
|
|
95
|
+
ready, and returns a store over its host; `ensurePineconeIndex()` does the first part alone.
|
|
96
|
+
- TypeSafe AI is sent a decision's pictures as parts of a multipart request, as bytes, so three
|
|
97
|
+
pictures of 10 MiB fit in the 32 MiB a request holds; `TypeSafeDecisionProviderOptions.pictures`
|
|
98
|
+
set to `base64` sends them within the JSON, as before.
|
|
99
|
+
- **Embeddings of video, and audio and video priced by length.** An `EmbeddingVideoPart` holds a video
|
|
100
|
+
by its bytes, base64, or a URL, such as a Files API URI, and gemini-embedding-2 embeds it. Audio is
|
|
101
|
+
priced by the second and video by the frame the model takes, one a second and at most 32 on
|
|
102
|
+
gemini-embedding-2, at $0.00016 a second and $0.00079 a frame, each length read from the media's own
|
|
103
|
+
headers; a budget counts them before the call. Media longer than a model's `maxAudioSeconds` or
|
|
104
|
+
`maxVideoSeconds` is refused before it is sent, and media whose length cannot be read is counted in
|
|
105
|
+
`unpricedMedia`. A registry data file sets these prices and limits too, each checked when it loads.
|
|
106
|
+
- A Google embedding batch over 20 MB, up to 2 GB, is uploaded as a JSONL file through the Files API, and
|
|
107
|
+
its results are read from the file the batch writes, matched to their inputs by key.
|
|
108
|
+
- **CSV and JSON stream through.** `loadCsv()` and `loadJson()` read a file as it arrives and yield each
|
|
109
|
+
row or record as soon as it is read: a path in chunks, or a `FileInput` that is now also a stream,
|
|
110
|
+
such as a response's body. `CsvRowParser` parses CSV a piece at a time, and `recordsAt` names the
|
|
111
|
+
array of records inside a JSON document, such as `data.items`, read item by item. A file larger than
|
|
112
|
+
memory goes to the store a batch at a time.
|
|
113
|
+
- **Pages built by script.** `loadWebPages()` takes a `render` of the application's own for a page
|
|
114
|
+
whose text a script builds, and `browserRenderer()` makes one from a Playwright or Puppeteer browser,
|
|
115
|
+
with no browser a dependency of the package.
|
|
116
|
+
- **Gemini voice.** `GoogleVoiceProvider`, on `nexus-ai-pro/voice/google`, speaks in Gemini's voices, as
|
|
117
|
+
WAV or raw PCM, whichever its model answers with, directed by a system instruction that is never
|
|
118
|
+
spoken; and transcribes with a text model that hears the audio, inline or by a Files API URI, guided
|
|
119
|
+
by its language and the names it may hold. Experimental until a live run is recorded.
|
|
120
|
+
- **Gemini Live changes its setup mid-call.** `updateSession()` on Gemini Live sets the session up again
|
|
121
|
+
between turns, on a new socket resumed from the latest handle: instructions, voice, language,
|
|
122
|
+
modalities, tools, turn detection, the model, and Gemini's own setup fields. What is sent meanwhile
|
|
123
|
+
waits, and the conversation carries on.
|
|
124
|
+
- **Images in the realtime record.** An image sent in a realtime conversation is kept as an `ImageItem`,
|
|
125
|
+
with its digest and, unless `recordImages` is `digest`, the image, and a resumed session gives it
|
|
126
|
+
back to the model. Video frames are not kept.
|
|
127
|
+
- **Telnyx gathers speech.** A gather that listens for speech on Telnyx transcribes the caller's side of
|
|
128
|
+
the call, with its prompts spoken and keys still taken, until `endGather()`. `parseGatherResult()`
|
|
129
|
+
reads what a gather collected on either provider, Twilio's `SpeechResult` and `Digits` or Telnyx's
|
|
130
|
+
`call.transcription` and `call.gather.ended`, as one `TelephonyGatherResult`.
|
|
131
|
+
- **The studio signs people in, and serves many tenants.** `oidcSignIn()` signs people in with any
|
|
132
|
+
OpenID Connect provider, with no proxy in front: the code flow with PKCE, a state, and a nonce, the ID
|
|
133
|
+
token verified against the provider's keys, and a signed session cookie that replicas share, with
|
|
134
|
+
sign-out at the provider too. A person's `tenant`, from a claim, a header, or the users file, picks
|
|
135
|
+
the sources they read, from `tenantSources`; they see their tenant's comments and audit entries
|
|
136
|
+
alone, and their page token is bound to it.
|
|
137
|
+
- **The kernel in Firefox and WebKit.** The portable kernel's own tests, the file Node.js, Deno, Bun,
|
|
138
|
+
and the edge runtime run, now run in a browser page too, in headless Chromium on every build and in
|
|
139
|
+
Firefox and WebKit, Safari's engine, in CI, with a graph, an agent with a streaming tool, and AG-UI.
|
|
140
|
+
- **Cohere's Embed 5.** `embed-v5.0-pro` and `embed-v5.0-fast` are in the registry, with their
|
|
141
|
+
sizes from 256 to 2,048, 128,000 tokens, and images. Cohere publishes no per-token price for them,
|
|
142
|
+
so they are registered without one.
|
|
143
|
+
|
|
144
|
+
### Changed
|
|
145
|
+
|
|
146
|
+
- A TypeSafe AI request with pictures is multipart by default, and its 32 MiB is counted in bytes, not
|
|
147
|
+
characters, so a state of text outside ASCII is refused before it is sent rather than by the API.
|
|
148
|
+
- `loadCsv()` and `loadJson()` yield their first document before the rest of the file is read; a JSON
|
|
149
|
+
file whose array of records is cut short is refused as such, after the records before the cut.
|
|
150
|
+
- An OpenAPI operation with a multipart or other non-JSON body becomes a tool, where it was skipped; a
|
|
151
|
+
Swagger 2.0 document is read, where it was refused; and `loadOpenApiTools()` refuses a document over
|
|
152
|
+
`maxBytes`, 5 MB by default, reading no further.
|
|
153
|
+
|
|
154
|
+
### Deprecated
|
|
155
|
+
|
|
156
|
+
- `OpenApiTools.skipped`, always empty now that every operation becomes a tool. It is removed in 3.0.
|
|
157
|
+
|
|
158
|
+
### Fixed
|
|
159
|
+
|
|
160
|
+
- **An answer the output guard redacts keeps no log probabilities.** They name the tokens the model
|
|
161
|
+
wrote, so a redacted address or connection string was still spelled out in `response.logprobs`; now
|
|
162
|
+
they are dropped wherever the guard changes or blocks the text, streamed or not.
|
|
163
|
+
- The Google embedding batch adapter reads inline results under the name Google's API reference gives
|
|
164
|
+
them, `inlinedResponses`, as well as its clients' name.
|
|
165
|
+
- A typed decision asked of a model that reports only the chosen token's log probability, with no
|
|
166
|
+
alternatives, is sampled, where it was read as certain.
|
|
167
|
+
- An Ollama stream stops at the request's `stop` sequences, as a call does.
|
|
168
|
+
|
|
7
169
|
## [2.21.0] - 2026-10-26
|
|
8
170
|
|
|
9
171
|
Typed decisions about pictures, compatibility records gathered from community adapters' own CI, and
|
|
@@ -3361,7 +3523,9 @@ shared policy vocabulary is in place for a future release that revisits this.
|
|
|
3361
3523
|
- URL fetching rejects unsafe private-network targets and limits response reads.
|
|
3362
3524
|
- CLI and audit findings no longer disclose detected secret values.
|
|
3363
3525
|
|
|
3364
|
-
[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
|
|
3528
|
+
[2.22.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.21.0...v2.22.0
|
|
3365
3529
|
[2.21.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.20.2...v2.21.0
|
|
3366
3530
|
[2.20.2]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.20.1...v2.20.2
|
|
3367
3531
|
[2.20.1]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.20.0...v2.20.1
|
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
|
@@ -341,13 +341,21 @@ Shipped so far:
|
|
|
341
341
|
evaluated with nothing sent, and one A2A handler serving many tenants, each seeing only its own;
|
|
342
342
|
- 2.21 typed decisions about pictures, a yes or no, a choice, a score, or a box around something in
|
|
343
343
|
one, from TypeSafe AI's Jev or any vision model; community adapters' compatibility records gathered
|
|
344
|
-
from their own CI, a failing one turning red; and 3.0's defaults behind one switch today
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
344
|
+
from their own CI, a failing one turning red; and 3.0's defaults behind one switch today;
|
|
345
|
+
- 2.22 MCP over streamable HTTP both ways, with prompts, resources, and a server's questions back to
|
|
346
|
+
the client; OpenAPI tools that send each operation's credentials; tokens, API keys, and sessions the
|
|
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
|
+
- 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
|
|
351
359
|
[roadmap](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/ROADMAP.md) lists what comes after, in the order
|
|
352
360
|
applications ask for it.
|
|
353
361
|
|
package/SECURITY.md
CHANGED
|
@@ -281,9 +281,23 @@ 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`, and, against Dex, a real provider, `studio/test/signin-dex.test.ts`:
|
|
286
|
+
- The provider's configuration must name the issuer the studio was given. An ID token must verify
|
|
287
|
+
against the provider's keys, name that issuer and the studio's client as its audience, and carry
|
|
288
|
+
the sign-in's nonce; a token for several clients must name the studio as `azp`.
|
|
289
|
+
- The state, nonce, and PKCE verifier travel in a cookie signed for that purpose alone, for ten
|
|
290
|
+
minutes, so a callback from another browser, a late one, or a changed one is refused, and a sign-in
|
|
291
|
+
cookie is never taken as a session.
|
|
292
|
+
- The page to come back to is always a path on the studio, never another site.
|
|
293
|
+
- A tenant's people read only what `tenantSources` gives for their tenant. The studio itself keeps
|
|
294
|
+
comments and audit entries to their tenant, whatever the store does, and binds the page token to it.
|
|
295
|
+
`headerAuth()` with a tenant header refuses a request that lacks it.
|
|
296
|
+
|
|
284
297
|
Documented limitations, which the studio guide states:
|
|
285
|
-
-
|
|
286
|
-
|
|
298
|
+
- Someone without a tenant reads the studio's own sources, the operators' view.
|
|
299
|
+
- A session is a signed cookie, so one person's cannot be ended before it expires; rotating the
|
|
300
|
+
sign-in secret signs everyone out. Signing out is a plain link, which another site can follow.
|
|
287
301
|
- A page token stays valid while the secret, the user, and their role do. Rotate `secret` to revoke
|
|
288
302
|
every page at once.
|
|
289
303
|
- Someone without a session who opens another person's personal link is signed in as that person.
|