nexus-ai-pro 2.21.0 → 2.22.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 +63 -0
- package/CHANGELOG.md +133 -1
- package/README.md +6 -2
- package/SECURITY.md +16 -2
- package/dist/agent/openapi.d.ts +94 -8
- package/dist/agent/openapi.js +528 -32
- 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/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/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/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/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/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 +94 -8
- package/dist-cjs/agent/openapi.js +530 -32
- 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/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/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/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/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/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 +17 -1
package/API_STABILITY.md
CHANGED
|
@@ -67,6 +67,69 @@ 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
|
+
## 2.22 stage (2.22.0)
|
|
71
|
+
|
|
72
|
+
Everything 2.22 adds is stable from the start and additive, unless this section says otherwise.
|
|
73
|
+
|
|
74
|
+
New and stable: `StreamChunk.logprobs`; in `nexus-ai-pro/protocols/a2a`, `signA2aCard()`,
|
|
75
|
+
`verifyA2aCard()`, `canonicalA2aCard()`, `A2aCardSignatureError`, `A2aCardSigner`, `A2aCardKeyResolver`,
|
|
76
|
+
`A2aSignatureAlgorithm`, `A2aJsonWebKey`, `A2aCryptoKey`, `A2aServerOptions.sign`, and
|
|
77
|
+
`A2aClientOptions.verifyCard`, which `A2aGrpcClientOptions` takes too; in `nexus-ai-pro/mcp`,
|
|
78
|
+
`mcpHttpHandler()`, `McpHttpOptions`, `McpHttpHandler`, `samplingFrom()`, `McpSamplingOptions`,
|
|
79
|
+
`McpSamplingClient`, `McpServerPrompt`, `McpPromptArgument`, `McpPromptMessage`, `McpServerResource`,
|
|
80
|
+
the server's `registerPrompt()`, `registerResource()`, `resourceUpdated()`, `createMessage()`,
|
|
81
|
+
`elicit()`, `listRoots()`, and `onRootsChanged()`, the client's `sampling`, `elicitation`, and `roots`
|
|
82
|
+
options, `onPromptsChanged()`, `onResourcesChanged()`, `onResourceUpdated()`, `subscribeResource()`,
|
|
83
|
+
`unsubscribeResource()`, and `rootsChanged()`, `HttpClientOptions.listen`, the protocol types
|
|
84
|
+
`McpSamplingRequest`, `McpSamplingResult`, `McpSamplingMessage`, `McpSamplingContent`,
|
|
85
|
+
`McpModelPreferences`, `McpElicitationRequest`, `McpElicitationResult`, `McpRoot`, and
|
|
86
|
+
`McpCallerRequests`, and `ToolContext.mcp`; in `nexus-ai-pro/agent/openapi`, `swaggerToOpenApi()`,
|
|
87
|
+
`bundleOpenApiDocument()`, `OpenApiBundleOptions`, `OpenApiCredential`, `OpenApiWebhook`,
|
|
88
|
+
`OpenApiToolsOptions.credentials`, `OpenApiOperation.security`, `OpenApiTools.webhooks`, and
|
|
89
|
+
`loadOpenApiTools()`'s `references`, `maxDocuments`, and `maxBytes`; in `nexus-ai-pro/server/auth`,
|
|
90
|
+
`createJwtSigner()`, `JwtSigner`, `JwtSignerOptions`, `JwtSignOptions`, `generateJwtKey()`,
|
|
91
|
+
`jwksHandler()`, `createApiKeyStore()`, `ApiKeyStore`, `ApiKeyStoreOptions`, `ApiKeyRecord`,
|
|
92
|
+
`IssuedApiKey`, `ApiKeyIssueOptions`, `createSessions()`, `Sessions`, `SessionOptions`,
|
|
93
|
+
`SessionCookieOptions`, `SessionRecord`, and `StartedSession`, and the principal method `session`; in
|
|
94
|
+
`nexus-ai-pro/rag/pinecone`, `PineconeVectorStore.create()`, `ensurePineconeIndex()`,
|
|
95
|
+
`PineconeIndexOptions`, `PineconeIndex`, and `PineconeCreateOptions`, experimental with the store;
|
|
96
|
+
`TypeSafeDecisionProviderOptions.pictures`; and in `nexus-ai-pro/embeddings`, `EmbeddingVideoPart`, the
|
|
97
|
+
modality `video`, `EmbeddingMeta.unpricedMedia`, and `EmbeddingModelCapabilities`'
|
|
98
|
+
`costPerAudioSecond`, `costPerVideoFrame`, `videoFrames`, `maxAudioSeconds`, and `maxVideoSeconds`; in
|
|
99
|
+
the loaders, `FileInput`'s stream form, `CsvRowParser`, `JsonLoaderOptions.recordsAt`,
|
|
100
|
+
`WebLoaderOptions.render` and `renderBelow`, `browserRenderer()`, `WebPageRenderer`, `WebPageToRender`,
|
|
101
|
+
`RenderingBrowser`, and `BrowserRendererOptions`; in the realtime family, `ImageItem`, the `message.image`
|
|
102
|
+
event, and `RealtimeConversationOptions.recordImages`; in telephony, `TelephonyGatherResult`,
|
|
103
|
+
`EndGatherRequest`, `parseGatherResult()` and `endGather()` on the manager and the providers, and
|
|
104
|
+
`TelnyxTelephonyProviderConfig.transcriptionEngine`; in the studio, `StudioOptions.tenantSources`,
|
|
105
|
+
`StudioUser.tenant`, `StudioAuditEntry.tenant`, `StudioComment.tenant`, `StudioAuditQuery`,
|
|
106
|
+
`HeaderAuthOptions.tenant`, `BearerAuthOptions.tenant`, `StudioSignIn`, and `StudioOptions.signIn`.
|
|
107
|
+
Experimental: in the studio, `oidcSignIn()`, `OidcSignInOptions`, `SIGN_IN_COOKIE`, and the
|
|
108
|
+
`/auth/` routes, until a sign-in against a live provider is recorded; `nexus-ai-pro/voice/google`,
|
|
109
|
+
`GoogleVoiceProvider` and `GoogleVoiceProviderConfig`, until a live run is recorded.
|
|
110
|
+
The state store keys and sessions are kept in, under `nexus/server`, is read by every later 2.x.
|
|
111
|
+
|
|
112
|
+
Changed on purpose: an answer the output guard changes or blocks keeps no `logprobs`, streamed or
|
|
113
|
+
not; a typed decision of a model that reports the chosen token alone is sampled; an Ollama stream
|
|
114
|
+
honours `stop`. An MCP server declares prompts and resource subscriptions at `initialize` whatever it
|
|
115
|
+
was given, and serves every transport connected to it rather than the last; a tool it runs gets a
|
|
116
|
+
`signal` and `mcp` in its context. The HTTP client transport returns from `send()` before a streamed
|
|
117
|
+
answer ends, sends `mcp-protocol-version`, and sends a `DELETE` when closed with a session. OpenAPI
|
|
118
|
+
tools are made of operations with any request body, where those with a body other than JSON or a form
|
|
119
|
+
were skipped, and of Swagger 2.0 documents, which were refused; `loadOpenApiTools()` reads no more of
|
|
120
|
+
a document than `maxBytes`. With `credentials` given, an operation whose security cannot be met fails
|
|
121
|
+
before it is sent.
|
|
122
|
+
|
|
123
|
+
A TypeSafe AI request with pictures is multipart unless `pictures: 'base64'`, and its size is counted
|
|
124
|
+
in bytes. gemini-embedding-2's audio and video are priced, where they cost nothing before, and audio
|
|
125
|
+
past 180 seconds or video past 120 is refused before the call. A Google embedding batch over 20 MB is
|
|
126
|
+
sent as a file, where it was refused. Gemini Live acts on `updateSession()`, which it ignored. A
|
|
127
|
+
realtime record holds the images sent, as `image` items, which a consumer that switches on every item
|
|
128
|
+
type meets for the first time. A Telnyx gather for speech transcribes the caller, where it was
|
|
129
|
+
refused.
|
|
130
|
+
|
|
131
|
+
Deprecated: `OpenApiTools.skipped`, always empty, is removed in 3.0.
|
|
132
|
+
|
|
70
133
|
## 2.21 stage (2.21.0)
|
|
71
134
|
|
|
72
135
|
Everything 2.21 adds is stable from the start and additive, unless this section says otherwise.
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,137 @@ Notable changes to this project are recorded here. The format follows [Keep a Ch
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [2.22.0] - 2026-10-29
|
|
8
|
+
|
|
9
|
+
MCP over streamable HTTP both ways, OpenAPI tools that send each operation's credentials, tokens, keys,
|
|
10
|
+
and sessions the server issues, and a studio that signs people in and serves many tenants; with signed
|
|
11
|
+
A2A cards, embeddings of video, loaders that stream, Gemini's voice, and the kernel in Firefox and
|
|
12
|
+
WebKit.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **Log probabilities from a stream.** Each `text` chunk's `StreamChunk.logprobs` holds its tokens'
|
|
17
|
+
log probabilities, from OpenAI's Chat Completions and Responses API, Gemini, Ollama, and Cohere, so
|
|
18
|
+
the chunks' together are what `complete()` reports.
|
|
19
|
+
- Cohere reports log probabilities, `complete()` and streamed: a piece of text at a time, each piece's
|
|
20
|
+
the sum of its tokens', with no alternatives.
|
|
21
|
+
- **MCP both ways.** A server offers prompts (`McpServerPrompt`, `registerPrompt()`), resources a client
|
|
22
|
+
subscribes to (`resourceUpdated()`), and tells every client each list's changes; a tool it runs may ask
|
|
23
|
+
the client that called it for a completion from its model, an answer from its person, or its roots,
|
|
24
|
+
through `context.mcp`, and is stopped when the client cancels it. A client answers a server's
|
|
25
|
+
`sampling`, `elicitation`, and `roots` with handlers of its own, `samplingFrom()` answering with
|
|
26
|
+
the application's own model, and hears each list change and each resource it subscribed to.
|
|
27
|
+
- **MCP over streamable HTTP, both ways.** `mcpHttpHandler()` serves an `McpServer` as a Web handler:
|
|
28
|
+
a session per client, a stream of events per request carrying the server's progress and questions
|
|
29
|
+
before its answer, a `GET` stream for what it sends of its own accord, `DELETE` to end a session, and
|
|
30
|
+
a request from another origin refused. The client's HTTP transport reads a stream as it comes, so a
|
|
31
|
+
question in the middle of a call arrives in time, listens on a `GET` stream with `listen`, sends the
|
|
32
|
+
protocol version, and ends its session on `close()`. The nightly interoperability run drives the
|
|
33
|
+
server with `@modelcontextprotocol/sdk`'s own client: its tools, a completion asked mid-call, its
|
|
34
|
+
progress, a prompt, and a subscribed resource's change.
|
|
35
|
+
- **Signed A2A cards.** `signA2aCard()` and `verifyA2aCard()`, with `canonicalA2aCard()`, sign and check
|
|
36
|
+
a card as protocol 1.0 does, a flattened JWS over its canonical form, which is the A2A project's SDK's
|
|
37
|
+
form: a card either signs, the other verifies. A handler's `sign` signs every card it serves, each
|
|
38
|
+
tenant's and the extended card included, and a client's `verifyCard` makes no call until a signature
|
|
39
|
+
on the card holds. ES256, ES384, ES512, RS256, RS384, RS512, PS256, PS384, PS512, and Ed25519, by the
|
|
40
|
+
Web Crypto API alone. The nightly interoperability run checks both directions against `@a2a-js/sdk`.
|
|
41
|
+
- **OpenAPI credentials.** Tools read from an OpenAPI document send the credentials each operation's
|
|
42
|
+
security asks for, from `credentials` given by scheme name, or chosen per call: an API key in a
|
|
43
|
+
header, query parameter, or cookie; HTTP Basic, bearer, or another HTTP scheme; and an OAuth 2.0 or
|
|
44
|
+
OpenID Connect token, held, or fetched by the client-credentials flow for the operation's scopes and
|
|
45
|
+
kept until a minute before it expires. An operation whose alternatives none can be met fails before
|
|
46
|
+
anything is sent, naming them. Each `OpenApiOperation` carries its `security`.
|
|
47
|
+
- **Swagger 2.0, and references to other documents.** A Swagger 2.0 document is read as the OpenAPI 3.0
|
|
48
|
+
one it describes, which `swaggerToOpenApi()` returns. `bundleOpenApiDocument()` reads in the other
|
|
49
|
+
documents a document's references name, on its own origin by default, or as `references` allows,
|
|
50
|
+
within `maxDocuments` and `maxBytes`; `loadOpenApiTools()` does so itself.
|
|
51
|
+
- OpenAPI tools send a multipart form, its file fields given as base64, a text or XML body, and a body
|
|
52
|
+
of bytes, such as an image, so every operation becomes a tool. `webhooks` lists what the API sends
|
|
53
|
+
the application, its webhooks and its operations' callbacks, each with its JSON body's schema.
|
|
54
|
+
- **Tokens, keys, and sessions the server issues.** `createJwtSigner()` issues tokens with a secret, a
|
|
55
|
+
PEM or JWK private key, or a Web Crypto key pair, and `issue()` writes a principal under the claim
|
|
56
|
+
names `jwtAuth()` reads back; `generateJwtKey()` makes a key, and `jwksHandler()` publishes the
|
|
57
|
+
public halves, for a rotation that refuses no live token. `createApiKeyStore()` issues, rotates with
|
|
58
|
+
a grace period, and revokes API keys, kept as hashes in the server's state store with when each was
|
|
59
|
+
last used. `createSessions()` signs browsers in after a sign-in of the application's own: an
|
|
60
|
+
`HttpOnly`, `Secure`, `SameSite=Lax` cookie of a random secret whose hash alone is kept, an idle
|
|
61
|
+
and a total lifetime, sign-out here or everywhere, and a request from another site's page refused.
|
|
62
|
+
- **A Pinecone store makes its own index.** `PineconeVectorStore.create()` creates a serverless index
|
|
63
|
+
with the cosine metric and the store's width, or uses one of that name that fits, waits until it is
|
|
64
|
+
ready, and returns a store over its host; `ensurePineconeIndex()` does the first part alone.
|
|
65
|
+
- TypeSafe AI is sent a decision's pictures as parts of a multipart request, as bytes, so three
|
|
66
|
+
pictures of 10 MiB fit in the 32 MiB a request holds; `TypeSafeDecisionProviderOptions.pictures`
|
|
67
|
+
set to `base64` sends them within the JSON, as before.
|
|
68
|
+
- **Embeddings of video, and audio and video priced by length.** An `EmbeddingVideoPart` holds a video
|
|
69
|
+
by its bytes, base64, or a URL, such as a Files API URI, and gemini-embedding-2 embeds it. Audio is
|
|
70
|
+
priced by the second and video by the frame the model takes, one a second and at most 32 on
|
|
71
|
+
gemini-embedding-2, at $0.00016 a second and $0.00079 a frame, each length read from the media's own
|
|
72
|
+
headers; a budget counts them before the call. Media longer than a model's `maxAudioSeconds` or
|
|
73
|
+
`maxVideoSeconds` is refused before it is sent, and media whose length cannot be read is counted in
|
|
74
|
+
`unpricedMedia`. A registry data file sets these prices and limits too, each checked when it loads.
|
|
75
|
+
- A Google embedding batch over 20 MB, up to 2 GB, is uploaded as a JSONL file through the Files API, and
|
|
76
|
+
its results are read from the file the batch writes, matched to their inputs by key.
|
|
77
|
+
- **CSV and JSON stream through.** `loadCsv()` and `loadJson()` read a file as it arrives and yield each
|
|
78
|
+
row or record as soon as it is read: a path in chunks, or a `FileInput` that is now also a stream,
|
|
79
|
+
such as a response's body. `CsvRowParser` parses CSV a piece at a time, and `recordsAt` names the
|
|
80
|
+
array of records inside a JSON document, such as `data.items`, read item by item. A file larger than
|
|
81
|
+
memory goes to the store a batch at a time.
|
|
82
|
+
- **Pages built by script.** `loadWebPages()` takes a `render` of the application's own for a page
|
|
83
|
+
whose text a script builds, and `browserRenderer()` makes one from a Playwright or Puppeteer browser,
|
|
84
|
+
with no browser a dependency of the package.
|
|
85
|
+
- **Gemini voice.** `GoogleVoiceProvider`, on `nexus-ai-pro/voice/google`, speaks in Gemini's voices, as
|
|
86
|
+
WAV or raw PCM, whichever its model answers with, directed by a system instruction that is never
|
|
87
|
+
spoken; and transcribes with a text model that hears the audio, inline or by a Files API URI, guided
|
|
88
|
+
by its language and the names it may hold. Experimental until a live run is recorded.
|
|
89
|
+
- **Gemini Live changes its setup mid-call.** `updateSession()` on Gemini Live sets the session up again
|
|
90
|
+
between turns, on a new socket resumed from the latest handle: instructions, voice, language,
|
|
91
|
+
modalities, tools, turn detection, the model, and Gemini's own setup fields. What is sent meanwhile
|
|
92
|
+
waits, and the conversation carries on.
|
|
93
|
+
- **Images in the realtime record.** An image sent in a realtime conversation is kept as an `ImageItem`,
|
|
94
|
+
with its digest and, unless `recordImages` is `digest`, the image, and a resumed session gives it
|
|
95
|
+
back to the model. Video frames are not kept.
|
|
96
|
+
- **Telnyx gathers speech.** A gather that listens for speech on Telnyx transcribes the caller's side of
|
|
97
|
+
the call, with its prompts spoken and keys still taken, until `endGather()`. `parseGatherResult()`
|
|
98
|
+
reads what a gather collected on either provider, Twilio's `SpeechResult` and `Digits` or Telnyx's
|
|
99
|
+
`call.transcription` and `call.gather.ended`, as one `TelephonyGatherResult`.
|
|
100
|
+
- **The studio signs people in, and serves many tenants.** `oidcSignIn()` signs people in with any
|
|
101
|
+
OpenID Connect provider, with no proxy in front: the code flow with PKCE, a state, and a nonce, the ID
|
|
102
|
+
token verified against the provider's keys, and a signed session cookie that replicas share, with
|
|
103
|
+
sign-out at the provider too. A person's `tenant`, from a claim, a header, or the users file, picks
|
|
104
|
+
the sources they read, from `tenantSources`; they see their tenant's comments and audit entries
|
|
105
|
+
alone, and their page token is bound to it.
|
|
106
|
+
- **The kernel in Firefox and WebKit.** The portable kernel's own tests, the file Node.js, Deno, Bun,
|
|
107
|
+
and the edge runtime run, now run in a browser page too, in headless Chromium on every build and in
|
|
108
|
+
Firefox and WebKit, Safari's engine, in CI, with a graph, an agent with a streaming tool, and AG-UI.
|
|
109
|
+
- **Cohere's Embed 5.** `embed-v5.0-pro` and `embed-v5.0-fast` are in the registry, with their
|
|
110
|
+
sizes from 256 to 2,048, 128,000 tokens, and images. Cohere publishes no per-token price for them,
|
|
111
|
+
so they are registered without one.
|
|
112
|
+
|
|
113
|
+
### Changed
|
|
114
|
+
|
|
115
|
+
- A TypeSafe AI request with pictures is multipart by default, and its 32 MiB is counted in bytes, not
|
|
116
|
+
characters, so a state of text outside ASCII is refused before it is sent rather than by the API.
|
|
117
|
+
- `loadCsv()` and `loadJson()` yield their first document before the rest of the file is read; a JSON
|
|
118
|
+
file whose array of records is cut short is refused as such, after the records before the cut.
|
|
119
|
+
- An OpenAPI operation with a multipart or other non-JSON body becomes a tool, where it was skipped; a
|
|
120
|
+
Swagger 2.0 document is read, where it was refused; and `loadOpenApiTools()` refuses a document over
|
|
121
|
+
`maxBytes`, 5 MB by default, reading no further.
|
|
122
|
+
|
|
123
|
+
### Deprecated
|
|
124
|
+
|
|
125
|
+
- `OpenApiTools.skipped`, always empty now that every operation becomes a tool. It is removed in 3.0.
|
|
126
|
+
|
|
127
|
+
### Fixed
|
|
128
|
+
|
|
129
|
+
- **An answer the output guard redacts keeps no log probabilities.** They name the tokens the model
|
|
130
|
+
wrote, so a redacted address or connection string was still spelled out in `response.logprobs`; now
|
|
131
|
+
they are dropped wherever the guard changes or blocks the text, streamed or not.
|
|
132
|
+
- The Google embedding batch adapter reads inline results under the name Google's API reference gives
|
|
133
|
+
them, `inlinedResponses`, as well as its clients' name.
|
|
134
|
+
- A typed decision asked of a model that reports only the chosen token's log probability, with no
|
|
135
|
+
alternatives, is sampled, where it was read as certain.
|
|
136
|
+
- An Ollama stream stops at the request's `stop` sequences, as a call does.
|
|
137
|
+
|
|
7
138
|
## [2.21.0] - 2026-10-26
|
|
8
139
|
|
|
9
140
|
Typed decisions about pictures, compatibility records gathered from community adapters' own CI, and
|
|
@@ -3361,7 +3492,8 @@ shared policy vocabulary is in place for a future release that revisits this.
|
|
|
3361
3492
|
- URL fetching rejects unsafe private-network targets and limits response reads.
|
|
3362
3493
|
- CLI and audit findings no longer disclose detected secret values.
|
|
3363
3494
|
|
|
3364
|
-
[Unreleased]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.
|
|
3495
|
+
[Unreleased]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.22.0...HEAD
|
|
3496
|
+
[2.22.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.21.0...v2.22.0
|
|
3365
3497
|
[2.21.0]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.20.2...v2.21.0
|
|
3366
3498
|
[2.20.2]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.20.1...v2.20.2
|
|
3367
3499
|
[2.20.1]: https://github.com/mkhitar-abrahamyan/nexus-ai/compare/v2.20.0...v2.20.1
|
package/README.md
CHANGED
|
@@ -341,11 +341,15 @@ 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
|
|
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.
|
|
345
349
|
|
|
346
350
|
Upgrading from 1.x: `npx nexus migrate src --write` moves your imports, and
|
|
347
351
|
[MIGRATING.md](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/MIGRATING.md) covers the rest.
|
|
348
|
-
Next, in 2.
|
|
352
|
+
Next, in 2.23, Pinecone, images, the Gemini embedding batch tier, media understanding, video, typed
|
|
349
353
|
decisions, Gemini Live, SIP, and both phone providers graduate once the live workflow passes against
|
|
350
354
|
each. The
|
|
351
355
|
[roadmap](https://github.com/mkhitar-abrahamyan/nexus-ai/blob/main/ROADMAP.md) lists what comes after, in the order
|
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` and
|
|
285
|
+
`studio/test/tenants.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.
|
package/dist/agent/openapi.d.ts
CHANGED
|
@@ -44,6 +44,38 @@ export interface OpenApiOperation {
|
|
|
44
44
|
tags: string[];
|
|
45
45
|
/** What it does to the service, read from its method: `read` for GET, HEAD, OPTIONS, and TRACE, `destructive` for DELETE, and `write` for the rest. */
|
|
46
46
|
access: 'read' | 'write' | 'destructive';
|
|
47
|
+
/**
|
|
48
|
+
* The security it asks for, as the document writes it: alternatives, any one of which will do, each
|
|
49
|
+
* the schemes it needs at once with their scopes. Empty when it asks for none.
|
|
50
|
+
*/
|
|
51
|
+
security: Array<Record<string, string[]>>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A credential for one of the API's security schemes: the API key, bearer token, or access token as
|
|
55
|
+
* text or `{ token }`; `{ username, password }` for HTTP basic; or `{ clientId, clientSecret }` for an
|
|
56
|
+
* OAuth 2.0 client-credentials flow, whose token is fetched and kept until it expires.
|
|
57
|
+
*/
|
|
58
|
+
export type OpenApiCredential = string | {
|
|
59
|
+
token: string;
|
|
60
|
+
} | {
|
|
61
|
+
username: string;
|
|
62
|
+
password: string;
|
|
63
|
+
} | {
|
|
64
|
+
clientId: string;
|
|
65
|
+
clientSecret: string;
|
|
66
|
+
};
|
|
67
|
+
/** A request or callback the API sends to the application, which no tool calls: its name and the body it carries. */
|
|
68
|
+
export interface OpenApiWebhook {
|
|
69
|
+
/** The webhook's name, or the operation and callback it belongs to. */
|
|
70
|
+
name: string;
|
|
71
|
+
/** `webhook` for one of the document's webhooks, `callback` for an operation's callback. */
|
|
72
|
+
source: 'webhook' | 'callback';
|
|
73
|
+
/** The HTTP method it arrives with, in capitals. */
|
|
74
|
+
method: string;
|
|
75
|
+
/** For a callback, the expression that names where it is sent, such as `{$request.body#/callbackUrl}`. */
|
|
76
|
+
expression?: string;
|
|
77
|
+
/** The JSON Schema of the body it carries, when it carries JSON. */
|
|
78
|
+
body?: Record<string, unknown>;
|
|
47
79
|
}
|
|
48
80
|
/** What a tool's headers are chosen from: the operation, and the call's context. */
|
|
49
81
|
export interface OpenApiHeadersRequest {
|
|
@@ -79,6 +111,15 @@ export interface OpenApiToolsOptions {
|
|
|
79
111
|
maxResponseBytes?: number;
|
|
80
112
|
/** Replaces the global `fetch`. */
|
|
81
113
|
fetch?: typeof globalThis.fetch;
|
|
114
|
+
/**
|
|
115
|
+
* Credentials for the API's own security schemes, by the name the document gives each, or a
|
|
116
|
+
* function choosing one per call, such as by its tenant. Each call sends those its operation asks
|
|
117
|
+
* for: the first of its alternatives every scheme of which has a credential, as an API key in its
|
|
118
|
+
* header, query, or cookie, HTTP basic or bearer, or an OAuth 2.0 or OpenID Connect token. With
|
|
119
|
+
* credentials given, a call whose operation asks for schemes none of which has one fails before it
|
|
120
|
+
* is sent. They win over `headers`.
|
|
121
|
+
*/
|
|
122
|
+
credentials?: Readonly<Record<string, OpenApiCredential | ((request: OpenApiHeadersRequest) => OpenApiCredential | Promise<OpenApiCredential>)>>;
|
|
82
123
|
}
|
|
83
124
|
/** An API's operations as tools, with what each returns. */
|
|
84
125
|
export interface OpenApiTools {
|
|
@@ -92,19 +133,26 @@ export interface OpenApiTools {
|
|
|
92
133
|
operations: OpenApiOperation[];
|
|
93
134
|
/** The JSON Schema of what each tool returns, by name: its first success response's. Pass it to `emulatedTools()` as `results`. */
|
|
94
135
|
results: Record<string, Record<string, unknown>>;
|
|
95
|
-
/**
|
|
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
|
+
*/
|
|
96
142
|
skipped: Array<{
|
|
97
143
|
method: string;
|
|
98
144
|
path: string;
|
|
99
145
|
reason: string;
|
|
100
146
|
}>;
|
|
147
|
+
/** What the API sends the application, which no tool calls: its webhooks and its operations' callbacks. */
|
|
148
|
+
webhooks: OpenApiWebhook[];
|
|
101
149
|
}
|
|
102
150
|
/** Why an API could not be read into tools, or a call to it failed. */
|
|
103
151
|
export declare class OpenApiError extends Error {
|
|
104
152
|
/**
|
|
105
153
|
* `OPENAPI_INVALID` for a malformed document or call, `OPENAPI_UNSUPPORTED` for one these tools
|
|
106
|
-
* cannot read, such as Swagger 2
|
|
107
|
-
* for a call the API refused or did not answer.
|
|
154
|
+
* cannot read, such as Swagger 1.2 or a reference outside the document not bundled first, and
|
|
155
|
+
* `OPENAPI_REQUEST` for a call the API refused or did not answer.
|
|
108
156
|
*/
|
|
109
157
|
readonly code: 'OPENAPI_INVALID' | 'OPENAPI_UNSUPPORTED' | 'OPENAPI_REQUEST';
|
|
110
158
|
/** The HTTP status the API answered with, when it did. */
|
|
@@ -112,8 +160,8 @@ export declare class OpenApiError extends Error {
|
|
|
112
160
|
constructor(message: string,
|
|
113
161
|
/**
|
|
114
162
|
* `OPENAPI_INVALID` for a malformed document or call, `OPENAPI_UNSUPPORTED` for one these tools
|
|
115
|
-
* cannot read, such as Swagger 2
|
|
116
|
-
* for a call the API refused or did not answer.
|
|
163
|
+
* cannot read, such as Swagger 1.2 or a reference outside the document not bundled first, and
|
|
164
|
+
* `OPENAPI_REQUEST` for a call the API refused or did not answer.
|
|
117
165
|
*/
|
|
118
166
|
code: 'OPENAPI_INVALID' | 'OPENAPI_UNSUPPORTED' | 'OPENAPI_REQUEST',
|
|
119
167
|
/** The HTTP status the API answered with, when it did. */
|
|
@@ -124,7 +172,10 @@ export declare class OpenApiError extends Error {
|
|
|
124
172
|
* method and path; described by its summary; its path, query, and header parameters, and the fields
|
|
125
173
|
* of a JSON body, as the tool's parameters. Each declares `api.read`, `api.write`, or
|
|
126
174
|
* `api.destructive` with the API's name and its own, as its method says, and `network` for the
|
|
127
|
-
* API's host when it runs. References within the document are followed; one outside it is refused
|
|
175
|
+
* API's host when it runs. References within the document are followed; one outside it is refused
|
|
176
|
+
* here, and followed by `loadOpenApiTools()` or `bundleOpenApiDocument()`. A Swagger 2.0 document is
|
|
177
|
+
* read as the OpenAPI 3 document it describes. Each call sends the credentials its operation's
|
|
178
|
+
* security asks for, from `credentials`.
|
|
128
179
|
*
|
|
129
180
|
* ```ts
|
|
130
181
|
* const shop = openApiTools(JSON.parse(await readFile('shop.openapi.json', 'utf8')), {
|
|
@@ -135,5 +186,40 @@ export declare class OpenApiError extends Error {
|
|
|
135
186
|
* ```
|
|
136
187
|
*/
|
|
137
188
|
export declare function openApiTools(document: OpenApiDocument | string, options?: OpenApiToolsOptions): OpenApiTools;
|
|
138
|
-
/**
|
|
139
|
-
|
|
189
|
+
/**
|
|
190
|
+
* Fetches an OpenAPI document, as JSON, and reads it into tools, resolving its servers against where
|
|
191
|
+
* it came from, and following its references to other documents on the same origin, or as
|
|
192
|
+
* `references` allows.
|
|
193
|
+
*/
|
|
194
|
+
export declare function loadOpenApiTools(url: string, options?: OpenApiToolsOptions & Pick<OpenApiBundleOptions, 'references' | 'maxDocuments' | 'maxBytes'>): Promise<OpenApiTools>;
|
|
195
|
+
/**
|
|
196
|
+
* A Swagger 2.0 document as the OpenAPI 3.0 document it describes: its host, base path, and schemes
|
|
197
|
+
* as a server; its definitions, parameters, responses, and security definitions as components; a
|
|
198
|
+
* body parameter, and form data, as a request body of what it consumes; and each response's schema as
|
|
199
|
+
* content of what it produces. Every reference is moved with what it names.
|
|
200
|
+
*/
|
|
201
|
+
export declare function swaggerToOpenApi(swagger: Record<string, unknown>): OpenApiDocument;
|
|
202
|
+
/** Options for `bundleOpenApiDocument()`. */
|
|
203
|
+
export interface OpenApiBundleOptions {
|
|
204
|
+
/** Where the document came from: references outside it are read relative to it. */
|
|
205
|
+
documentUrl: string;
|
|
206
|
+
/**
|
|
207
|
+
* Which documents a reference may name: `same-origin`, the default, only those on the document's
|
|
208
|
+
* own origin; `any`, any HTTP or HTTPS URL; or a function deciding each. A document never makes the
|
|
209
|
+
* tools fetch where it was not allowed to.
|
|
210
|
+
*/
|
|
211
|
+
references?: 'same-origin' | 'any' | ((url: string) => boolean);
|
|
212
|
+
/** The most documents read, the first included. Defaults to 50. */
|
|
213
|
+
maxDocuments?: number;
|
|
214
|
+
/** The largest document read, the first included, in bytes. Defaults to 5 MB. */
|
|
215
|
+
maxBytes?: number;
|
|
216
|
+
/** Replaces the global `fetch`. */
|
|
217
|
+
fetch?: typeof globalThis.fetch;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* The document with every reference outside it read in its place: each other document fetched, as
|
|
221
|
+
* JSON, relative to the one that names it, its own references followed the same way, and a reference
|
|
222
|
+
* back to one still being read left as a description. `loadOpenApiTools()` does this before reading the
|
|
223
|
+
* document into tools.
|
|
224
|
+
*/
|
|
225
|
+
export declare function bundleOpenApiDocument(document: OpenApiDocument, options: OpenApiBundleOptions): Promise<OpenApiDocument>;
|