@workerdeck/core 0.13.0 → 0.16.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/README.md +74 -6
- package/build/index.d.mts +200 -38
- package/build/index.mjs +758 -288
- package/build/index.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -88,26 +88,64 @@ supports — no CLI process, no config directory. `createEngineSession()` assemb
|
|
|
88
88
|
the capability-scoped tool set, and the executor that runs tool calls.
|
|
89
89
|
|
|
90
90
|
```ts
|
|
91
|
+
import variant from '@jitl/quickjs-ng-wasmfile-release-asyncify'
|
|
92
|
+
import { loadEngine } from '@workerdeck/sandbox'
|
|
91
93
|
import { createEngineSession, QuickJsExecutor } from '@workerdeck/core'
|
|
92
94
|
|
|
95
|
+
// Server-side, the WASM guest is loaded once for the process and shared by every
|
|
96
|
+
// session. The variant package is a peer dependency you install yourself — core
|
|
97
|
+
// does not pick one for you, because the browser build and the server build are
|
|
98
|
+
// different artifacts and only you know which side this is.
|
|
99
|
+
const executor = new QuickJsExecutor({ engine: await loadEngine(variant), defaultTimeoutMs: 15_000 })
|
|
100
|
+
|
|
93
101
|
const runner = createEngineSession({
|
|
94
102
|
config: { ...createSessionRequest, languageModel: anthropic('claude-sonnet-5') },
|
|
95
|
-
selectExecutor: () =>
|
|
103
|
+
selectExecutor: () => executor,
|
|
96
104
|
capabilities: { webFetch: {} }, // backends, not grants
|
|
105
|
+
seedVfs: { '/README.md': 'scratch space' },
|
|
97
106
|
})
|
|
98
107
|
```
|
|
99
108
|
|
|
100
|
-
|
|
109
|
+
Three seams matter here:
|
|
101
110
|
|
|
102
111
|
- **Capabilities are grants, wired separately from backends.** `createToolContext` builds the tool
|
|
103
112
|
set from what a profile grants (`fs_*`, `eval_script`, `web_search`, `download`, `web_fetch`,
|
|
104
113
|
`deliver_file`) over what the host actually wired. There is no shell and no host filesystem: the
|
|
105
114
|
files a session sees are an in-memory scratch VFS. Every tool is typed `sandboxed` or
|
|
106
115
|
`authoritative`, and only sandboxed calls may leave the server.
|
|
107
|
-
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
116
|
+
- **Your own tools go in at a stated trust level.** `tools: { name: { tool, trust } }` is the seam
|
|
117
|
+
for anything that is neither a built-in capability nor MCP. `authoritative` means it runs here
|
|
118
|
+
with this process's authority and must declare `execute`; `sandboxed` means it rides the executor
|
|
119
|
+
seam and must *not*. Both contradictions are refused at assembly rather than at runtime, because
|
|
120
|
+
a sandboxed tool that quietly ran in-process would defeat the only thing sandboxing it was for.
|
|
121
|
+
- **`ToolExecutor` decides where code runs**, and that is a real architectural choice — see below.
|
|
122
|
+
|
|
123
|
+
### Which executor?
|
|
124
|
+
|
|
125
|
+
| | `QuickJsExecutor` (in-process) | `BrowserBridgeExecutor` (the tab) | `DeferredExecutor` |
|
|
126
|
+
|---|---|---|---|
|
|
127
|
+
| Runs where | this Node process, WASM guest | the attached client | wherever you send it |
|
|
128
|
+
| Needs a client attached | no | **yes** | no |
|
|
129
|
+
| Data locality | data must reach the server | client-held data never leaves the tab | n/a |
|
|
130
|
+
| Trust | you own both sides | results are **untrusted input** — the sandboxed party answers | depends |
|
|
131
|
+
| Latency | in-process | a WS round trip | unbounded (the session parks) |
|
|
132
|
+
|
|
133
|
+
The question to ask is **where the data the loop reasons over already lives**:
|
|
134
|
+
|
|
135
|
+
- In your database or on your disk → in-process. Pushing execution into the tab buys nothing and
|
|
136
|
+
hands an executor to the party you are sandboxing against.
|
|
137
|
+
- In the user's browser — a document they are editing, a file they dropped, something you would
|
|
138
|
+
rather not receive at all → the bridge. This is the case it exists for.
|
|
139
|
+
- Somewhere that answers in minutes or hours (a queue, a human, a build) → deferred, and let the
|
|
140
|
+
session park.
|
|
141
|
+
|
|
142
|
+
Two constraints that decide it for you regardless: an **unattended job** has no attached client, so
|
|
143
|
+
the bridge is not available to it; and a bridged result is by definition produced by the sandboxed
|
|
144
|
+
party, so nothing authoritative may ever be routed there.
|
|
145
|
+
|
|
146
|
+
An executor is chosen per *call*, not per session (`selectExecutor` runs at assembly, but a routing
|
|
147
|
+
executor may keep `eval_script` in-process and defer a long-running tool), which is what lets one
|
|
148
|
+
session mix all three.
|
|
111
149
|
|
|
112
150
|
## Work that outlives the runner
|
|
113
151
|
|
|
@@ -127,6 +165,36 @@ selectExecutor: () => new DeferredExecutor({
|
|
|
127
165
|
for you — a `SessionStore` plus `POST /executions/:id/result` — but the mechanism is here, and works
|
|
128
166
|
with no server at all.
|
|
129
167
|
|
|
168
|
+
## Rules you cannot infer from the types
|
|
169
|
+
|
|
170
|
+
Things the compiler will not tell you, each of which has cost someone real time:
|
|
171
|
+
|
|
172
|
+
- **A declared MCP server that never connected is refused, not degraded.** If a profile's
|
|
173
|
+
`session.mcpServers` names a server and it isn't there, `createEngineSession` throws. The old
|
|
174
|
+
behaviour — start anyway, minus those tools — produced a session that reported perfectly healthy
|
|
175
|
+
while the agent apologised its way through every request that needed it. Pass
|
|
176
|
+
`connectMcpTools(servers, { required: true })` to fail at connect time instead, and hand the
|
|
177
|
+
resulting connection over as `mcp` (not just `mcp.tools`) so the check is exact.
|
|
178
|
+
- **A stateless MCP server must answer `GET` with 405.** The client opens the SSE stream with a
|
|
179
|
+
`GET` before it sends anything. Mounted under a framework's default 404, the whole connect fails
|
|
180
|
+
with an error that names neither the method nor the route.
|
|
181
|
+
- **Never seed the VFS by hand on a restore.** Use `seedVfs`, which is ignored when
|
|
182
|
+
`config.restore` is set. Building `config.vfs` yourself still works and still wins — and then
|
|
183
|
+
overwriting the files the parked turn wrote is yours to avoid.
|
|
184
|
+
- **Forward the host's `id`.** `createEngineSession({ id })` is how a session comes back as
|
|
185
|
+
*itself* across a gateway restart. Dropping it strands every client's route and unread mark, and
|
|
186
|
+
the rebuild is refused.
|
|
187
|
+
- **`onClose` runs on park as well as close.** Parking releases the same resources; a disposer that
|
|
188
|
+
assumes the session is over will close an MCP connection the woken session still needs to rebuild.
|
|
189
|
+
- **Authoritative tools are never bridged.** `withMcpTools` marks everything authoritative by
|
|
190
|
+
construction. If you want a host tool the tab may run, declare it `sandboxed` in `tools` — and
|
|
191
|
+
then treat its results as untrusted input, because the tab produced them.
|
|
192
|
+
- **Never make a tool's operation depend on a field being absent.** "Create when `id` is missing,
|
|
193
|
+
overwrite when it is present" is the shape that breaks: models send `""` — and, observed live,
|
|
194
|
+
`" "` — rather than omitting, and some providers mark every property required so the model
|
|
195
|
+
*cannot* omit. `z.string().min(1).optional()` does not save it (a space has length 1). Split it
|
|
196
|
+
into two tools with required arguments, and trim-and-blank-check optional strings inside `run`.
|
|
197
|
+
|
|
130
198
|
## Also exported
|
|
131
199
|
|
|
132
200
|
`InputQueue` (the push-based `AsyncIterable` bridging `sendMessage()` into the SDK's streaming
|
package/build/index.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { McpServerStatus, Options, Query, SDKMessage, SDKUserMessage, SessionMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
1
|
+
import { McpServerStatus, Options, Query, SDKMessage, SDKSessionInfo, SDKUserMessage, SessionMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
2
2
|
import { ApiMessage, CreateSessionRequest, EngineCapabilities, McpServerConfigWire, McpServerStatusInfo, MessageAttachment, ModelOption, PermissionMode, PermissionRequest, ProfileEngine, ProfileInfo, SdkSessionSummary, SessionEvent, SessionEventBody, SessionInfo, SessionStatus, ToolCallRequestFrame, ToolExecutionBackend, ToolExecutionOutput } from "@workerdeck/protocol";
|
|
3
|
-
import { LanguageModel, ModelMessage, Tool, ToolSet } from "ai";
|
|
3
|
+
import { LanguageModel, LanguageModel as LanguageModel$1, ModelMessage, Tool, Tool as Tool$1, ToolSet, ToolSet as ToolSet$1 } from "ai";
|
|
4
4
|
import { SandboxEngine, SandboxVfs } from "@workerdeck/sandbox";
|
|
5
5
|
import { Readable, Writable } from "node:stream";
|
|
6
6
|
|
|
7
|
-
//#region src/attachments.d.ts
|
|
7
|
+
//#region src/lib/attachments.d.ts
|
|
8
8
|
/**
|
|
9
9
|
* An attachment plus its bytes — what the host hands a runner at send time.
|
|
10
10
|
*
|
|
@@ -44,7 +44,7 @@ declare function attachmentContentBlocks(attachments: readonly AttachmentInput[]
|
|
|
44
44
|
/** Strip the bytes: the log-safe half of an attachment. */
|
|
45
45
|
declare function attachmentRef(attachment: AttachmentInput): MessageAttachment;
|
|
46
46
|
//#endregion
|
|
47
|
-
//#region src/tool-executor.d.ts
|
|
47
|
+
//#region src/executors/tool-executor.d.ts
|
|
48
48
|
/**
|
|
49
49
|
* Result of one tool execution, whenever it arrives. `failed` is a normal
|
|
50
50
|
* outcome the agent loop adapts to — not an exception.
|
|
@@ -175,8 +175,19 @@ interface Runner {
|
|
|
175
175
|
/** Begin the session. Idempotent; returns the run promise (resolves when the run ends). */
|
|
176
176
|
start(): Promise<void>;
|
|
177
177
|
info(): SessionInfo;
|
|
178
|
-
/** Replay buffered events with seq > afterSeq, then deliver live events. Returns unsubscribe.
|
|
179
|
-
|
|
178
|
+
/** Replay buffered events with seq > afterSeq, then deliver live events. Returns unsubscribe.
|
|
179
|
+
*
|
|
180
|
+
* `coalesceReplay` drops state readings superseded later in the same replay —
|
|
181
|
+
* the fifty stale context/rate-limit polls a long session accumulates, which
|
|
182
|
+
* a client otherwise applies one by one and *renders*, counting its usage
|
|
183
|
+
* meters up through the session's history on every attach. Opt-in, and the
|
|
184
|
+
* default must stay off: it is only sound for a consumer whose handling of
|
|
185
|
+
* those events is last-write-wins, and `parking.ts` — which subscribes from
|
|
186
|
+
* seq 0 — branches on `status_changed` instead. Live events are never
|
|
187
|
+
* affected; this touches the buffered replay alone. */
|
|
188
|
+
subscribe(listener: SessionEventListener, afterSeq?: number, options?: {
|
|
189
|
+
coalesceReplay?: boolean;
|
|
190
|
+
}): () => void;
|
|
180
191
|
/** Queue a user message for the session (starts the next turn when idle).
|
|
181
192
|
* `attachments` carry their bytes to the engine and their reference to the
|
|
182
193
|
* event log (see {@link AttachmentInput}). */
|
|
@@ -221,7 +232,7 @@ interface Runner {
|
|
|
221
232
|
close(reason?: 'client' | 'server' | 'error'): void;
|
|
222
233
|
}
|
|
223
234
|
//#endregion
|
|
224
|
-
//#region src/runner.d.ts
|
|
235
|
+
//#region src/engines/claude/runner.d.ts
|
|
225
236
|
type QueryFn = (params: {
|
|
226
237
|
prompt: AsyncIterable<SDKUserMessage>;
|
|
227
238
|
options?: Options;
|
|
@@ -229,6 +240,9 @@ type QueryFn = (params: {
|
|
|
229
240
|
type HistoryFn = (sdkSessionId: string, options: {
|
|
230
241
|
dir?: string;
|
|
231
242
|
}) => Promise<SessionMessage[]>;
|
|
243
|
+
type SessionInfoFn = (sdkSessionId: string, options: {
|
|
244
|
+
dir?: string;
|
|
245
|
+
}) => Promise<SDKSessionInfo | undefined>;
|
|
232
246
|
type SessionRunnerConfig = CreateSessionRequest & {
|
|
233
247
|
/** Injectable query implementation (tests, instrumentation). Defaults to the SDK's query(). */queryFn?: QueryFn; /** Environment for the spawned Claude Code process. Defaults to process.env. */
|
|
234
248
|
env?: Record<string, string | undefined>;
|
|
@@ -239,6 +253,10 @@ type SessionRunnerConfig = CreateSessionRequest & {
|
|
|
239
253
|
* starts, so late-attaching clients get a full transcript. Default true. */
|
|
240
254
|
backfillHistory?: boolean; /** Injectable history reader (tests). Defaults to the SDK's getSessionMessages. */
|
|
241
255
|
historyFn?: HistoryFn;
|
|
256
|
+
/** Injectable session-metadata reader (tests). Defaults to the SDK's
|
|
257
|
+
* getSessionInfo — the only place the CLI's own session title is readable
|
|
258
|
+
* from, since no message on the stream carries it. */
|
|
259
|
+
sessionInfoFn?: SessionInfoFn;
|
|
242
260
|
};
|
|
243
261
|
/**
|
|
244
262
|
* One live Agent SDK session: owns the query() call, the streaming input queue, the
|
|
@@ -287,22 +305,33 @@ declare class SessionRunner implements Runner {
|
|
|
287
305
|
/**
|
|
288
306
|
* Replay buffered events with seq > afterSeq, then deliver live events.
|
|
289
307
|
* Returns an unsubscribe function.
|
|
308
|
+
*
|
|
309
|
+
* Replay honours the reset watermark: transcript content below the latest
|
|
310
|
+
* `conversation_reset` is skipped (the reducer would clear it again anyway,
|
|
311
|
+
* and a pre-reset client that never learned the reducer's case would render
|
|
312
|
+
* a conversation the engine has discarded), while state-bearing events —
|
|
313
|
+
* which are emitted once and never again — always replay. The reset event
|
|
314
|
+
* itself replays (the skip is strictly-below), which is what clears a
|
|
315
|
+
* reconnecting client still holding pre-reset rows; superseded resets are
|
|
316
|
+
* content below the newer one and are skipped with what they cleared.
|
|
290
317
|
*/
|
|
291
|
-
subscribe(listener: SessionEventListener, afterSeq?: number
|
|
318
|
+
subscribe(listener: SessionEventListener, afterSeq?: number, options?: {
|
|
319
|
+
coalesceReplay?: boolean;
|
|
320
|
+
}): () => void;
|
|
292
321
|
}
|
|
293
322
|
//#endregion
|
|
294
|
-
//#region src/
|
|
323
|
+
//#region src/engines/provider/runner.d.ts
|
|
295
324
|
/** `cwd` is optional for this engine: the loop has no host-filesystem coupling
|
|
296
325
|
* (tools get scoped VFS handles instead). Defaults to process.cwd() for display. */
|
|
297
326
|
type AiSdkRunnerConfig = Omit<CreateSessionRequest, 'cwd'> & {
|
|
298
327
|
cwd?: string;
|
|
299
328
|
/** AI SDK language model instance (or gateway model id string). Provider
|
|
300
329
|
* resolution from profiles happens host-side; core takes the resolved model. */
|
|
301
|
-
languageModel: LanguageModel;
|
|
330
|
+
languageModel: LanguageModel$1;
|
|
302
331
|
/** Tools available to the loop. Tools WITHOUT `execute` halt the loop when
|
|
303
332
|
* called; their calls surface via `pendingToolCalls` and are answered with
|
|
304
333
|
* `resolveToolCall()`, which re-enters the loop by message-state replay. */
|
|
305
|
-
tools?: ToolSet; /** System prompt (AI SDK v7 `instructions`). */
|
|
334
|
+
tools?: ToolSet$1; /** System prompt (AI SDK v7 `instructions`). */
|
|
306
335
|
instructions?: string; /** Max loop steps per turn. Default 20. */
|
|
307
336
|
maxSteps?: number;
|
|
308
337
|
/**
|
|
@@ -320,7 +349,19 @@ type AiSdkRunnerConfig = Omit<CreateSessionRequest, 'cwd'> & {
|
|
|
320
349
|
memoryLimitBytes?: number;
|
|
321
350
|
}; /** Which backend the executor represents, for `execution_dispatched` events. */
|
|
322
351
|
executionBackend?: ToolExecutionBackend; /** Swap models mid-session (`set_model`). Unset = setModel() is rejected. */
|
|
323
|
-
resolveModel?: (modelId: string | undefined) => LanguageModel;
|
|
352
|
+
resolveModel?: (modelId: string | undefined) => LanguageModel$1;
|
|
353
|
+
/**
|
|
354
|
+
* Live MCP status for this session, when the host wired MCP at all. Unlike
|
|
355
|
+
* the CLI engines — which ask their binary — this engine's MCP is entirely
|
|
356
|
+
* host-assembled, so the host is the only party that can answer. Unset means
|
|
357
|
+
* "no MCP here", which reads as an empty list rather than an error: a session
|
|
358
|
+
* with no servers is a fact, not a missing feature.
|
|
359
|
+
*
|
|
360
|
+
* Named apart from the inherited `mcpServers` request field on purpose —
|
|
361
|
+
* that one is the *wire configuration* a client asked for, this one is what
|
|
362
|
+
* the host actually connected.
|
|
363
|
+
*/
|
|
364
|
+
reportMcpServers?: () => Promise<McpServerStatusInfo[] | undefined>;
|
|
324
365
|
/** Called once when the session closes — release per-session resources the
|
|
325
366
|
* host attached (an MCP connection, a watcher). Errors are swallowed. Also
|
|
326
367
|
* runs when the session parks: parking releases the same resources. */
|
|
@@ -444,19 +485,30 @@ declare class AiSdkRunner implements Runner {
|
|
|
444
485
|
setModel(model?: string): Promise<void>;
|
|
445
486
|
fail(message: string): void;
|
|
446
487
|
close(reason?: 'client' | 'server' | 'error'): void;
|
|
447
|
-
subscribe(listener: SessionEventListener, afterSeq?: number
|
|
488
|
+
subscribe(listener: SessionEventListener, afterSeq?: number, options?: {
|
|
489
|
+
coalesceReplay?: boolean;
|
|
490
|
+
}): () => void;
|
|
448
491
|
/**
|
|
449
492
|
* Deliver the result of an execution this runner dispatched. Used by the host
|
|
450
493
|
* when a backend settled out-of-band (a browser bridge answering later, a
|
|
451
494
|
* deferred executor). Idempotent by executionId.
|
|
452
495
|
*/
|
|
453
496
|
settleExecution(executionId: string, result: ToolExecutionResult): boolean;
|
|
497
|
+
/**
|
|
498
|
+
* This session's MCP servers, as the host assembled them.
|
|
499
|
+
*
|
|
500
|
+
* Always answers — an empty list when no MCP was wired — because the
|
|
501
|
+
* alternative (undefined, which the server turns into a 501) says "this
|
|
502
|
+
* engine cannot tell you", and this engine can: the host that built the
|
|
503
|
+
* session is the only party who knows, and it has been asked.
|
|
504
|
+
*/
|
|
505
|
+
mcpServers(): Promise<McpServerStatusInfo[] | undefined>;
|
|
454
506
|
/** Host-facing rename: writes `meta.title`, which `#title()` prefers. Clearing
|
|
455
507
|
* it (undefined) restores the derived title. The engine is never told. */
|
|
456
508
|
setTitle(title: string | undefined): void;
|
|
457
509
|
}
|
|
458
510
|
//#endregion
|
|
459
|
-
//#region src/claude
|
|
511
|
+
//#region src/engines/claude/auth.d.ts
|
|
460
512
|
/**
|
|
461
513
|
* Credential presence for one Claude Code environment, as the CLI itself reports
|
|
462
514
|
* it. 'unknown' means the check could not run at all (no binary, a CLI too old
|
|
@@ -494,7 +546,7 @@ declare function checkClaudeAuth(env: Record<string, string | undefined>, option
|
|
|
494
546
|
timeoutMs?: number;
|
|
495
547
|
}): Promise<ClaudeAuthStatus>;
|
|
496
548
|
//#endregion
|
|
497
|
-
//#region src/quickjs-executor.d.ts
|
|
549
|
+
//#region src/executors/quickjs-executor.d.ts
|
|
498
550
|
/** Resolve a URL to text for the guest. Runs host-side with host authority —
|
|
499
551
|
* this is where a credential may be attached, never inside the sandbox. */
|
|
500
552
|
type HostFetch = (url: string, signal: AbortSignal) => Promise<string>;
|
|
@@ -527,7 +579,7 @@ declare class QuickJsExecutor implements ToolExecutor {
|
|
|
527
579
|
* (not the bare parent). Only http(s) — no file:, data:, or other schemes. */
|
|
528
580
|
declare function isHostAllowed(url: string, allowedHosts: string[]): boolean;
|
|
529
581
|
//#endregion
|
|
530
|
-
//#region src/pending-registry.d.ts
|
|
582
|
+
//#region src/lib/pending-registry.d.ts
|
|
531
583
|
/**
|
|
532
584
|
* One registry for every request that leaves the runner and must come back:
|
|
533
585
|
* permission approvals, browser-bridged tool calls, and deferred executions.
|
|
@@ -589,7 +641,7 @@ declare class PendingRequestRegistry {
|
|
|
589
641
|
cancelAll(reason: string, error: string, kind?: PendingKind): number;
|
|
590
642
|
}
|
|
591
643
|
//#endregion
|
|
592
|
-
//#region src/browser-bridge-executor.d.ts
|
|
644
|
+
//#region src/executors/browser-bridge-executor.d.ts
|
|
593
645
|
/** Answer a bridged call, as delivered by the client over the wire. */
|
|
594
646
|
type BridgeAnswer = {
|
|
595
647
|
output: ToolExecutionOutput;
|
|
@@ -643,7 +695,7 @@ declare class BrowserBridgeExecutor implements ToolExecutor {
|
|
|
643
695
|
/** Map a registry outcome onto the executor's result contract. */
|
|
644
696
|
declare function toExecutionResult(outcome: PendingOutcome<BridgeAnswer>): ToolExecutionResult;
|
|
645
697
|
//#endregion
|
|
646
|
-
//#region src/deferred-executor.d.ts
|
|
698
|
+
//#region src/executors/deferred-executor.d.ts
|
|
647
699
|
/** A dispatched execution, as handed to the backend that will run it. */
|
|
648
700
|
type DeferredDispatch = {
|
|
649
701
|
/** Correlation id. The result is delivered under it — `POST
|
|
@@ -693,7 +745,7 @@ declare class DeferredExecutor implements ToolExecutor {
|
|
|
693
745
|
dispatch(call: ToolExecutionCall): Promise<ToolExecutionDispatch>;
|
|
694
746
|
}
|
|
695
747
|
//#endregion
|
|
696
|
-
//#region src/web-fetch.d.ts
|
|
748
|
+
//#region src/engines/provider/web-fetch.d.ts
|
|
697
749
|
/**
|
|
698
750
|
* `web_fetch` backend, close to Claude Code's original WebFetch: fetch a URL,
|
|
699
751
|
* convert HTML to markdown, and (optionally) digest it with a model against the
|
|
@@ -739,7 +791,7 @@ declare function isPrivateAddress(address: string): boolean;
|
|
|
739
791
|
*/
|
|
740
792
|
declare function htmlToMarkdown(html: string): string;
|
|
741
793
|
//#endregion
|
|
742
|
-
//#region src/tools.d.ts
|
|
794
|
+
//#region src/engines/provider/tools.d.ts
|
|
743
795
|
/**
|
|
744
796
|
* How much authority a tool carries, which decides where it may run.
|
|
745
797
|
*
|
|
@@ -755,7 +807,7 @@ type ToolDefinition = {
|
|
|
755
807
|
trust: ToolTrust;
|
|
756
808
|
/** The AI SDK tool. Sandboxed tools are declared WITHOUT `execute` so the loop
|
|
757
809
|
* hands them to the ToolExecutor seam rather than running them inline. */
|
|
758
|
-
tool: Tool;
|
|
810
|
+
tool: Tool$1;
|
|
759
811
|
};
|
|
760
812
|
type ToolContextOptions = {
|
|
761
813
|
/** Executor for sandboxed tools. Selected per call by the host (browser bridge
|
|
@@ -795,7 +847,7 @@ type ToolContextOptions = {
|
|
|
795
847
|
/** Everything a session's tools need, plus the tool set to hand the runner. */
|
|
796
848
|
type ToolContext = {
|
|
797
849
|
vfs: SandboxVfs;
|
|
798
|
-
tools: ToolSet;
|
|
850
|
+
tools: ToolSet$1;
|
|
799
851
|
definitions: ToolDefinition[]; /** Names the loop must not execute inline (they go through the executor). */
|
|
800
852
|
sandboxedToolNames: string[];
|
|
801
853
|
};
|
|
@@ -811,9 +863,38 @@ type ToolContext = {
|
|
|
811
863
|
declare function createToolContext(options: ToolContextOptions): ToolContext;
|
|
812
864
|
/** Add host-side MCP tools to a context. They are ALWAYS authoritative: they run
|
|
813
865
|
* server-side with server credentials, and must never be handed to a browser. */
|
|
814
|
-
declare function withMcpTools(context: ToolContext, mcpTools: ToolSet): ToolContext;
|
|
866
|
+
declare function withMcpTools(context: ToolContext, mcpTools: ToolSet$1): ToolContext;
|
|
867
|
+
/** A tool the host supplies, with the trust level it is to run at. */
|
|
868
|
+
type HostToolDefinition = {
|
|
869
|
+
tool: Tool$1;
|
|
870
|
+
/**
|
|
871
|
+
* Where this tool may run. `authoritative` tools execute inline in the
|
|
872
|
+
* gateway and MUST declare `execute`; `sandboxed` ones must NOT, because the
|
|
873
|
+
* loop hands them to the {@link ToolExecutor} seam instead — which is what
|
|
874
|
+
* makes them bridgeable to an untrusted tab.
|
|
875
|
+
*/
|
|
876
|
+
trust: ToolTrust;
|
|
877
|
+
};
|
|
878
|
+
/**
|
|
879
|
+
* Add host-supplied tools to a context at an explicit trust level.
|
|
880
|
+
*
|
|
881
|
+
* The trust level is the whole point of the seam: {@link withMcpTools} can only
|
|
882
|
+
* produce authoritative tools, so a host tool that *should* be sandboxed — and
|
|
883
|
+
* therefore executable in the browser tab that asked for it — had no way to be
|
|
884
|
+
* expressed at all. Here the host says which it is, and the contradictions are
|
|
885
|
+
* refused rather than silently resolved:
|
|
886
|
+
*
|
|
887
|
+
* - a `sandboxed` tool carrying `execute` would run inline in this process with
|
|
888
|
+
* the gateway's ambient authority, which is exactly what sandboxing it was
|
|
889
|
+
* meant to prevent;
|
|
890
|
+
* - an `authoritative` tool *without* `execute` would park the turn on a call no
|
|
891
|
+
* executor claims, and the session would simply stop.
|
|
892
|
+
*/
|
|
893
|
+
declare function withHostTools(context: ToolContext, hostTools: Record<string, HostToolDefinition>, /** What to call these in error messages ('MCP tool', 'host tool'). */
|
|
894
|
+
|
|
895
|
+
kind?: string): ToolContext;
|
|
815
896
|
//#endregion
|
|
816
|
-
//#region src/
|
|
897
|
+
//#region src/engines/provider/session.d.ts
|
|
817
898
|
type EngineSessionOptions = {
|
|
818
899
|
/** Resolved session config (profile defaults already applied). */config: AiSdkRunnerConfig; /** The profile that selected this engine, when there was one. */
|
|
819
900
|
profile?: ProfileInfo;
|
|
@@ -822,7 +903,7 @@ type EngineSessionOptions = {
|
|
|
822
903
|
* this so core never imports a provider SDK and never reads credentials —
|
|
823
904
|
* they come from the operator's environment, exactly like the Claude chain.
|
|
824
905
|
*/
|
|
825
|
-
resolveModel: (profile: ProfileInfo | undefined, config: AiSdkRunnerConfig) => LanguageModel;
|
|
906
|
+
resolveModel: (profile: ProfileInfo | undefined, config: AiSdkRunnerConfig) => LanguageModel$1;
|
|
826
907
|
/**
|
|
827
908
|
* Executor for sandboxed tools. Return the browser bridge when a client is
|
|
828
909
|
* attached and the server sandbox otherwise; the seam makes them
|
|
@@ -849,10 +930,38 @@ type EngineSessionOptions = {
|
|
|
849
930
|
* Default true — set false to withhold it. */
|
|
850
931
|
deliverFiles?: boolean;
|
|
851
932
|
};
|
|
933
|
+
/**
|
|
934
|
+
* A live MCP connection from {@link connectMcpTools} — the preferred way to
|
|
935
|
+
* hand MCP to a session, and the only one that can fail loudly.
|
|
936
|
+
*
|
|
937
|
+
* With this set, the session knows *which servers connected*, so two things
|
|
938
|
+
* that were previously silent become impossible: a profile naming a server
|
|
939
|
+
* that never connected refuses to build (see {@link mcpTools} for what that
|
|
940
|
+
* used to look like), and `runner.mcpServers()` answers `GET
|
|
941
|
+
* /sessions/:id/mcp` with the real per-server status instead of 501.
|
|
942
|
+
*/
|
|
943
|
+
mcp?: McpConnection;
|
|
852
944
|
/** Authoritative tools that run server-side with server credentials (MCP).
|
|
853
945
|
* Never bridged to a client. Namespaced `<server>__<tool>` by
|
|
854
|
-
* {@link connectMcpTools}, which is how a profile grants servers by name.
|
|
855
|
-
|
|
946
|
+
* {@link connectMcpTools}, which is how a profile grants servers by name.
|
|
947
|
+
*
|
|
948
|
+
* The bare tool set, for a host assembling one itself. Prefer {@link mcp}:
|
|
949
|
+
* a tool set alone cannot distinguish "this server connected and exposes no
|
|
950
|
+
* tools" from "this server never connected", so the check here has to be the
|
|
951
|
+
* cruder one — a declared server contributing no tools is refused. */
|
|
952
|
+
mcpTools?: ToolSet$1;
|
|
953
|
+
/**
|
|
954
|
+
* Extra host tools, each at an explicit trust level (see
|
|
955
|
+
* {@link withHostTools}). This is the seam for a tool that is neither one of
|
|
956
|
+
* the built-in capabilities nor MCP — including a **sandboxed** one, which
|
|
957
|
+
* `mcpTools` cannot express because everything in it is authoritative by
|
|
958
|
+
* construction.
|
|
959
|
+
*
|
|
960
|
+
* A sandboxed tool here rides the same {@link ToolExecutor} seam
|
|
961
|
+
* `eval_script` does, so it executes wherever `selectExecutor` points — an
|
|
962
|
+
* in-process QuickJS guest, or the browser tab that asked the question.
|
|
963
|
+
*/
|
|
964
|
+
tools?: Record<string, HostToolDefinition>;
|
|
856
965
|
/** Extra instructions prepended to the session's system prompt. Overridden by
|
|
857
966
|
* the profile's `session.instructions` when it declares one. */
|
|
858
967
|
instructions?: string;
|
|
@@ -860,6 +969,26 @@ type EngineSessionOptions = {
|
|
|
860
969
|
timeoutMs?: number;
|
|
861
970
|
memoryLimitBytes?: number;
|
|
862
971
|
};
|
|
972
|
+
/**
|
|
973
|
+
* Initial scratch-filesystem contents for a **new** session, and the safe way
|
|
974
|
+
* to seed one: it is ignored outright when `config.restore` is set, because a
|
|
975
|
+
* rehydrated session brings back the files its parked turn already wrote and
|
|
976
|
+
* seeding over them destroys exactly the work that was preserved.
|
|
977
|
+
*
|
|
978
|
+
* (Hand-building `config.vfs` still works and still wins — but then the
|
|
979
|
+
* `restore ? undefined : createVfs(...)` dance is yours to get right.)
|
|
980
|
+
*/
|
|
981
|
+
seedVfs?: Record<string, string>;
|
|
982
|
+
/**
|
|
983
|
+
* Build the session under this id rather than minting one.
|
|
984
|
+
*
|
|
985
|
+
* Forward the server's `EngineRunnerContext.id` here, always: it is set when
|
|
986
|
+
* the gateway is rehydrating a session across a restart, and a runner that
|
|
987
|
+
* ignores it comes back as a *different* session — the rebuild is refused,
|
|
988
|
+
* and every client's route and unread watermark is stranded. Ignored when
|
|
989
|
+
* `config.restore` is present, which carries its own id.
|
|
990
|
+
*/
|
|
991
|
+
id?: string;
|
|
863
992
|
};
|
|
864
993
|
/**
|
|
865
994
|
* Assemble a model-agnostic session: provider model, capability-scoped tools,
|
|
@@ -875,7 +1004,14 @@ type EngineSessionOptions = {
|
|
|
875
1004
|
*/
|
|
876
1005
|
declare function createEngineSession(options: EngineSessionOptions): AiSdkRunner;
|
|
877
1006
|
type McpConnection = {
|
|
878
|
-
tools: ToolSet;
|
|
1007
|
+
tools: ToolSet$1;
|
|
1008
|
+
/**
|
|
1009
|
+
* One entry per configured server, connected or not — the truth a session was
|
|
1010
|
+
* assembled against. Handed to {@link createEngineSession} as `mcp`, it is
|
|
1011
|
+
* what `GET /sessions/:id/mcp` answers with and what makes a half-connected
|
|
1012
|
+
* session refuse to build rather than run degraded.
|
|
1013
|
+
*/
|
|
1014
|
+
servers: McpServerStatusInfo[];
|
|
879
1015
|
close: () => Promise<void>;
|
|
880
1016
|
};
|
|
881
1017
|
/**
|
|
@@ -884,17 +1020,32 @@ type McpConnection = {
|
|
|
884
1020
|
* Server-side only, with server credentials: these tools are authoritative and
|
|
885
1021
|
* must never be bridged to a browser. `@ai-sdk/mcp` is imported lazily and is an
|
|
886
1022
|
* optional dependency — an operator who wires no MCP servers never needs it.
|
|
1023
|
+
*
|
|
1024
|
+
* **A stateless MCP server must answer `GET` with 405.** The client opens the
|
|
1025
|
+
* SSE stream with a `GET` before it sends anything, and a POST-only server
|
|
1026
|
+
* mounted under a framework's default 404 makes the whole connect fail with an
|
|
1027
|
+
* error that names neither the method nor the route. This is the single most
|
|
1028
|
+
* common way an otherwise-correct MCP mount fails.
|
|
887
1029
|
*/
|
|
888
|
-
declare function connectMcpTools(servers: Record<string, McpServerConfigWire>,
|
|
889
|
-
/** `onError` may fire more than once for a single server: transport-level
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
options?: {
|
|
1030
|
+
declare function connectMcpTools(servers: Record<string, McpServerConfigWire>, options?: {
|
|
1031
|
+
/** `onError` may fire more than once for a single server: transport-level
|
|
1032
|
+
* failures surface through the client's own uncaught-error channel as well as
|
|
1033
|
+
* the connect failure. Treat it as a report, not a count. */
|
|
894
1034
|
onError?: (name: string, error: unknown) => void;
|
|
1035
|
+
/**
|
|
1036
|
+
* Reject if any server fails to connect, after closing the ones that did.
|
|
1037
|
+
*
|
|
1038
|
+
* Off by default, which is right for an operator's fleet — one unreachable
|
|
1039
|
+
* server should not take a whole gateway's sessions down. Turn it **on**
|
|
1040
|
+
* when the servers are the app's own: an embedder who mounts one wiki server
|
|
1041
|
+
* and gets a session without it has a session that cannot do its job, and
|
|
1042
|
+
* finding that out at connect time beats finding it out from a transcript
|
|
1043
|
+
* where the agent apologises.
|
|
1044
|
+
*/
|
|
1045
|
+
required?: boolean;
|
|
895
1046
|
}): Promise<McpConnection>;
|
|
896
1047
|
//#endregion
|
|
897
|
-
//#region src/input-queue.d.ts
|
|
1048
|
+
//#region src/lib/input-queue.d.ts
|
|
898
1049
|
/**
|
|
899
1050
|
* Push-based single-consumer AsyncIterable bridging imperative sendMessage() calls
|
|
900
1051
|
* into the streaming `prompt` the Agent SDK consumes.
|
|
@@ -906,7 +1057,7 @@ declare class InputQueue implements AsyncIterable<SDKUserMessage> {
|
|
|
906
1057
|
[Symbol.asyncIterator](): AsyncIterator<SDKUserMessage>;
|
|
907
1058
|
}
|
|
908
1059
|
//#endregion
|
|
909
|
-
//#region src/normalize.d.ts
|
|
1060
|
+
//#region src/lib/normalize.d.ts
|
|
910
1061
|
declare function toApiMessage(message: unknown): ApiMessage;
|
|
911
1062
|
/**
|
|
912
1063
|
* The CLI's MCP status, as `McpServerStatusInfo`.
|
|
@@ -969,6 +1120,15 @@ type EngineRunnerRequest = {
|
|
|
969
1120
|
/** Rebuild a parked session instead of starting fresh. Engines that cannot
|
|
970
1121
|
* rehydrate throw. */
|
|
971
1122
|
restore?: RunnerSnapshot;
|
|
1123
|
+
/**
|
|
1124
|
+
* Adopt this session id instead of minting one. For rehydrating a session
|
|
1125
|
+
* across a gateway restart: the transcript comes back from the *engine's* own
|
|
1126
|
+
* store via `config.resume`, but every client keys its watermarks, unread
|
|
1127
|
+
* counts and routes on the WorkerDeck id, so that id has to survive too
|
|
1128
|
+
* (`SessionInfo.id` is documented as stable across resumes). A `restore`
|
|
1129
|
+
* carries its own id in the snapshot and does not need this.
|
|
1130
|
+
*/
|
|
1131
|
+
id?: string;
|
|
972
1132
|
};
|
|
973
1133
|
/**
|
|
974
1134
|
* One engine, as the server consumes it: its capability record, its shipped
|
|
@@ -1368,7 +1528,9 @@ declare class CodexRunner implements Runner {
|
|
|
1368
1528
|
setModel(model?: string): Promise<void>;
|
|
1369
1529
|
fail(message: string): void;
|
|
1370
1530
|
close(reason?: 'client' | 'server' | 'error'): void;
|
|
1371
|
-
subscribe(listener: SessionEventListener, afterSeq?: number
|
|
1531
|
+
subscribe(listener: SessionEventListener, afterSeq?: number, options?: {
|
|
1532
|
+
coalesceReplay?: boolean;
|
|
1533
|
+
}): () => void;
|
|
1372
1534
|
/**
|
|
1373
1535
|
* The session's MCP servers, live from the binary.
|
|
1374
1536
|
*
|
|
@@ -1463,5 +1625,5 @@ declare class JsonRpcStdioConnection {
|
|
|
1463
1625
|
*/
|
|
1464
1626
|
declare const providerAdapter: EngineAdapter;
|
|
1465
1627
|
//#endregion
|
|
1466
|
-
export { AiSdkRunner, type AiSdkRunnerConfig, type AiSdkSessionState, type AppServerConnectFn, type AppServerConnectOptions, type AppServerConnection, type AppServerHistoryTurn, type AppServerItem, type AppServerThreadListResponse, type AppServerThreadSummary, type AppServerTokenUsage, type AppServerTurn, type AppServerUserInput, type AttachmentInput, type AttachmentKind, type BridgeAnswer, BrowserBridgeExecutor, type BrowserBridgeExecutorOptions, CLAUDE_CATALOG, CODEX_CATALOG, type ClaudeAuthProbe, type ClaudeAuthStatus, CodexRunner, type CodexRunnerConfig, type DeferredDispatch, DeferredExecutor, type DeferredExecutorOptions, type EngineAdapter, type EngineAvailability, type EngineRunnerRequest, type EngineSessionOptions, type HistoryFn, type HostFetch, InputQueue, JsonRpcError, JsonRpcStdioConnection, type McpConnection, type ModelCatalog, type ParkedExecution, type PendingEntry, type PendingKind, type PendingOutcome, PendingRequestRegistry, type PendingToolCall, type PermissionDecision, type QueryFn, QuickJsExecutor, type QuickJsExecutorOptions, type RegisterOptions, type Runner, type RunnerSnapshot, SUPPORTED_ATTACHMENT_TYPES, type SessionEventListener, SessionRunner, type SessionRunnerConfig, type SettledBy, type ToolCallOutput, type ToolContext, type ToolContextOptions, type ToolDefinition, type ToolExecutionCall, type ToolExecutionDispatch, type ToolExecutionResult, type ToolExecutor, type ToolTrust, type WebFetchDigest, type WebFetchFn, type WebFetchOptions, type WebFetchResult, attachmentContentBlocks, attachmentKind, attachmentRef, checkClaudeAuth, claudeAdapter, codexAdapter, connectAppServer, connectMcpTools, createEngineSession, createToolContext, createWebFetch, getEngineAdapter, htmlToMarkdown, isHostAllowed, isPrivateAddress, listCodexSessions, mcpStatusInfo, modelOptionsFromSdk, normalizeMediaType, normalizeSdkMessage, providerAdapter, resolveBundledClaudeExecutable, resolveBundledCodexExecutable, toApiMessage, toExecutionResult, withMcpTools };
|
|
1628
|
+
export { AiSdkRunner, type AiSdkRunnerConfig, type AiSdkSessionState, type AppServerConnectFn, type AppServerConnectOptions, type AppServerConnection, type AppServerHistoryTurn, type AppServerItem, type AppServerThreadListResponse, type AppServerThreadSummary, type AppServerTokenUsage, type AppServerTurn, type AppServerUserInput, type AttachmentInput, type AttachmentKind, type BridgeAnswer, BrowserBridgeExecutor, type BrowserBridgeExecutorOptions, CLAUDE_CATALOG, CODEX_CATALOG, type ClaudeAuthProbe, type ClaudeAuthStatus, CodexRunner, type CodexRunnerConfig, type DeferredDispatch, DeferredExecutor, type DeferredExecutorOptions, type EngineAdapter, type EngineAvailability, type EngineRunnerRequest, type EngineSessionOptions, type HistoryFn, type HostFetch, type HostToolDefinition, InputQueue, JsonRpcError, JsonRpcStdioConnection, type LanguageModel, type McpConnection, type ModelCatalog, type ParkedExecution, type PendingEntry, type PendingKind, type PendingOutcome, PendingRequestRegistry, type PendingToolCall, type PermissionDecision, type QueryFn, QuickJsExecutor, type QuickJsExecutorOptions, type RegisterOptions, type Runner, type RunnerSnapshot, SUPPORTED_ATTACHMENT_TYPES, type SessionEventListener, SessionRunner, type SessionRunnerConfig, type SettledBy, type Tool, type ToolCallOutput, type ToolContext, type ToolContextOptions, type ToolDefinition, type ToolExecutionCall, type ToolExecutionDispatch, type ToolExecutionResult, type ToolExecutor, type ToolSet, type ToolTrust, type WebFetchDigest, type WebFetchFn, type WebFetchOptions, type WebFetchResult, attachmentContentBlocks, attachmentKind, attachmentRef, checkClaudeAuth, claudeAdapter, codexAdapter, connectAppServer, connectMcpTools, createEngineSession, createToolContext, createWebFetch, getEngineAdapter, htmlToMarkdown, isHostAllowed, isPrivateAddress, listCodexSessions, mcpStatusInfo, modelOptionsFromSdk, normalizeMediaType, normalizeSdkMessage, providerAdapter, resolveBundledClaudeExecutable, resolveBundledCodexExecutable, toApiMessage, toExecutionResult, withHostTools, withMcpTools };
|
|
1467
1629
|
//# sourceMappingURL=index.d.mts.map
|