@workerdeck/core 0.7.0 → 0.10.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/build/index.d.mts +614 -8
- package/build/index.mjs +2631 -17
- package/build/index.mjs.map +1 -1
- package/package.json +13 -4
package/build/index.d.mts
CHANGED
|
@@ -1,8 +1,49 @@
|
|
|
1
|
-
import { Options, Query, SDKMessage, SDKUserMessage, SessionMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
1
|
+
import { McpServerStatus, Options, Query, SDKMessage, SDKUserMessage, SessionMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
+
import { ApiMessage, CreateSessionRequest, EngineCapabilities, McpServerConfigWire, McpServerStatusInfo, MessageAttachment, ModelOption, PermissionMode, PermissionRequest, ProfileEngine, ProfileInfo, SdkSessionSummary, SessionEvent, SessionEventBody, SessionInfo, SessionStatus, ToolCallRequestFrame, ToolExecutionBackend, ToolExecutionOutput } from "@workerdeck/protocol";
|
|
2
3
|
import { LanguageModel, ModelMessage, Tool, ToolSet } from "ai";
|
|
3
4
|
import { SandboxEngine, SandboxVfs } from "@workerdeck/sandbox";
|
|
4
|
-
import {
|
|
5
|
+
import { Readable, Writable } from "node:stream";
|
|
5
6
|
|
|
7
|
+
//#region src/attachments.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* An attachment plus its bytes — what the host hands a runner at send time.
|
|
10
|
+
*
|
|
11
|
+
* The split matters: `data` goes into the message the engine sends and nowhere
|
|
12
|
+
* else. What the runner emits into the seq-numbered event log is the
|
|
13
|
+
* {@link MessageAttachment} half, so replay and parking stay cheap (see the
|
|
14
|
+
* protocol's note on why the bytes are not on the wire).
|
|
15
|
+
*/
|
|
16
|
+
type AttachmentInput = MessageAttachment & {
|
|
17
|
+
/** Base64, no data-URL prefix. */data: string;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* How an attachment reaches the model. Not every file can be handed to a model
|
|
21
|
+
* as itself: images and PDFs have native block types, anything textual can be
|
|
22
|
+
* inlined, and the rest has no representation at all — so uploads of it are
|
|
23
|
+
* refused at the door rather than silently dropped from the message.
|
|
24
|
+
*/
|
|
25
|
+
type AttachmentKind = 'image' | 'document' | 'text';
|
|
26
|
+
/** Strips any `; charset=…` parameter and lowercases. */
|
|
27
|
+
declare function normalizeMediaType(mediaType: string): string;
|
|
28
|
+
/** How this media type can be sent, or null if it can't be. */
|
|
29
|
+
declare function attachmentKind(mediaType: string): AttachmentKind | null;
|
|
30
|
+
/** Human-readable list for the 415 an unsupported upload gets. */
|
|
31
|
+
declare const SUPPORTED_ATTACHMENT_TYPES: string;
|
|
32
|
+
/**
|
|
33
|
+
* Anthropic content blocks for a set of attachments, in the given order.
|
|
34
|
+
*
|
|
35
|
+
* Blocks lead the message and the user's text follows: the model reads the
|
|
36
|
+
* picture, then the instruction about it. Text files are inlined in a named
|
|
37
|
+
* envelope rather than as a bare block, so "here is my config" doesn't read as
|
|
38
|
+
* something the user typed.
|
|
39
|
+
*
|
|
40
|
+
* Structurally typed — `packages/core` models Anthropic content the way
|
|
41
|
+
* `packages/protocol` does, and the caller casts into the SDK's own param type.
|
|
42
|
+
*/
|
|
43
|
+
declare function attachmentContentBlocks(attachments: readonly AttachmentInput[]): Array<Record<string, unknown>>;
|
|
44
|
+
/** Strip the bytes: the log-safe half of an attachment. */
|
|
45
|
+
declare function attachmentRef(attachment: AttachmentInput): MessageAttachment;
|
|
46
|
+
//#endregion
|
|
6
47
|
//#region src/tool-executor.d.ts
|
|
7
48
|
/**
|
|
8
49
|
* Result of one tool execution, whenever it arrives. `failed` is a normal
|
|
@@ -136,8 +177,18 @@ interface Runner {
|
|
|
136
177
|
info(): SessionInfo;
|
|
137
178
|
/** Replay buffered events with seq > afterSeq, then deliver live events. Returns unsubscribe. */
|
|
138
179
|
subscribe(listener: SessionEventListener, afterSeq?: number): () => void;
|
|
139
|
-
/** Queue a user message for the session (starts the next turn when idle).
|
|
140
|
-
|
|
180
|
+
/** Queue a user message for the session (starts the next turn when idle).
|
|
181
|
+
* `attachments` carry their bytes to the engine and their reference to the
|
|
182
|
+
* event log (see {@link AttachmentInput}). */
|
|
183
|
+
sendMessage(text: string, attachments?: readonly AttachmentInput[]): void;
|
|
184
|
+
/** Live MCP server status. Resolves undefined when the engine cannot answer
|
|
185
|
+
* (no MCP surface, or a fake query in tests); omitted entirely by engines that
|
|
186
|
+
* have no MCP at all. */
|
|
187
|
+
mcpServers?(): Promise<McpServerStatusInfo[] | undefined>;
|
|
188
|
+
/** Reconnect one MCP server by name. Throws if it fails. */
|
|
189
|
+
reconnectMcpServer?(name: string): Promise<void>;
|
|
190
|
+
/** Enable or disable one MCP server by name. Throws if it fails. */
|
|
191
|
+
setMcpServerEnabled?(name: string, enabled: boolean): Promise<void>;
|
|
141
192
|
/** Resolve a pending permission request. Returns false if the id is unknown (e.g. timed out). */
|
|
142
193
|
resolvePermission(requestId: string, decision: PermissionDecision): boolean;
|
|
143
194
|
interrupt(): Promise<void>;
|
|
@@ -204,8 +255,18 @@ declare class SessionRunner implements Runner {
|
|
|
204
255
|
info(): SessionInfo;
|
|
205
256
|
/** Begin the session. Idempotent; returns the run promise (resolves when the query ends). */
|
|
206
257
|
start(): Promise<void>;
|
|
207
|
-
/** Queue a user message for the session (starts the next turn when idle).
|
|
208
|
-
|
|
258
|
+
/** Queue a user message for the session (starts the next turn when idle).
|
|
259
|
+
*
|
|
260
|
+
* `attachments` carry their own bytes; they reach the CLI as content blocks and
|
|
261
|
+
* are logged as references. A message may be attachments alone — an empty text
|
|
262
|
+
* block is not valid API input, so the text is only added when there is some. */
|
|
263
|
+
sendMessage(text: string, attachments?: readonly AttachmentInput[]): void;
|
|
264
|
+
/** Live MCP server status, straight from the CLI. Undefined when the engine
|
|
265
|
+
* can't answer (an injected fake query in tests) — the caller 501s rather than
|
|
266
|
+
* pretending the session has no servers. */
|
|
267
|
+
mcpServers(): Promise<McpServerStatusInfo[] | undefined>;
|
|
268
|
+
reconnectMcpServer(name: string): Promise<void>;
|
|
269
|
+
setMcpServerEnabled(name: string, enabled: boolean): Promise<void>;
|
|
209
270
|
/** Resolve a pending permission request. Returns false if the id is unknown (e.g. timed out). */
|
|
210
271
|
resolvePermission(requestId: string, decision: PermissionDecision): boolean;
|
|
211
272
|
interrupt(): Promise<void>;
|
|
@@ -348,7 +409,7 @@ declare class AiSdkRunner implements Runner {
|
|
|
348
409
|
* or an already-closed/parked runner.
|
|
349
410
|
*/
|
|
350
411
|
park(): RunnerSnapshot | undefined;
|
|
351
|
-
sendMessage(text: string): void;
|
|
412
|
+
sendMessage(text: string, attachments?: readonly AttachmentInput[]): void;
|
|
352
413
|
/**
|
|
353
414
|
* Deliver the result of an external (execute-less) tool call. Appends the
|
|
354
415
|
* tool-result message and, once no calls remain pending, re-enters the loop.
|
|
@@ -837,6 +898,27 @@ declare class InputQueue implements AsyncIterable<SDKUserMessage> {
|
|
|
837
898
|
//#endregion
|
|
838
899
|
//#region src/normalize.d.ts
|
|
839
900
|
declare function toApiMessage(message: unknown): ApiMessage;
|
|
901
|
+
/**
|
|
902
|
+
* The CLI's MCP status, as `McpServerStatusInfo`.
|
|
903
|
+
*
|
|
904
|
+
* The narrowing is the point: the SDK's config object carries `env` for stdio
|
|
905
|
+
* servers and `headers` for HTTP ones, and both routinely hold API tokens. This
|
|
906
|
+
* is the one place they are dropped, so no client — dashboard, phone, or a host
|
|
907
|
+
* app reading the REST route — can turn "show me my MCP servers" into a
|
|
908
|
+
* credential dump. Only the connection's identity survives.
|
|
909
|
+
*/
|
|
910
|
+
declare function mcpStatusInfo(status: McpServerStatus): McpServerStatusInfo;
|
|
911
|
+
/** The half of the SDK's `ModelInfo` this package forwards. Structurally typed so
|
|
912
|
+
* the mapping can be unit-tested without a live query. */
|
|
913
|
+
type SdkModelInfo = {
|
|
914
|
+
value: string;
|
|
915
|
+
resolvedModel?: string;
|
|
916
|
+
displayName: string;
|
|
917
|
+
description?: string; /** Per-model reasoning efforts, when the SDK reports them (0.3.221+). */
|
|
918
|
+
supportedEffortLevels?: string[];
|
|
919
|
+
supportsEffort?: boolean;
|
|
920
|
+
};
|
|
921
|
+
declare function modelOptionsFromSdk(models: readonly SdkModelInfo[]): ModelOption[];
|
|
840
922
|
/**
|
|
841
923
|
* Map one SDKMessage to a wire-protocol event body, or null for messages the runner
|
|
842
924
|
* consumes itself (system_init and session-state changes carry runner state and are
|
|
@@ -844,5 +926,529 @@ declare function toApiMessage(message: unknown): ApiMessage;
|
|
|
844
926
|
*/
|
|
845
927
|
declare function normalizeSdkMessage(msg: SDKMessage): SessionEventBody | null;
|
|
846
928
|
//#endregion
|
|
847
|
-
|
|
929
|
+
//#region src/engines/adapter.d.ts
|
|
930
|
+
/**
|
|
931
|
+
* A probe's verdict on one profile's credentials. 'unknown' means the probe
|
|
932
|
+
* could not run at all — which is NOT evidence of a missing login and must
|
|
933
|
+
* never be surfaced as one (the `checkClaudeAuth` discipline, generalized).
|
|
934
|
+
*/
|
|
935
|
+
type EngineAvailability = {
|
|
936
|
+
available: true;
|
|
937
|
+
} | {
|
|
938
|
+
available: false;
|
|
939
|
+
reason: string;
|
|
940
|
+
} | {
|
|
941
|
+
available: 'unknown';
|
|
942
|
+
};
|
|
943
|
+
/**
|
|
944
|
+
* A model catalog shipped with the release — the answer to "what can a create
|
|
945
|
+
* form offer" with no process spawned, correct from a gateway's first request.
|
|
946
|
+
*
|
|
947
|
+
* Never contains a 'default' sentinel row (a choice, not a model — forms add
|
|
948
|
+
* their own "Profile default" row mapping to an unset model). Staleness is
|
|
949
|
+
* bounded by the release cadence: the release checklist re-runs each catalog's
|
|
950
|
+
* extraction procedure (documented in its file header) and diffs.
|
|
951
|
+
*/
|
|
952
|
+
type ModelCatalog = {
|
|
953
|
+
models: ModelOption[]; /** Source + date, for the release-checklist refresh. Not served. */
|
|
954
|
+
provenance: string;
|
|
955
|
+
};
|
|
956
|
+
type EngineRunnerRequest = {
|
|
957
|
+
config: SessionRunnerConfig;
|
|
958
|
+
profile?: ProfileInfo;
|
|
959
|
+
/** Rebuild a parked session instead of starting fresh. Engines that cannot
|
|
960
|
+
* rehydrate throw. */
|
|
961
|
+
restore?: RunnerSnapshot;
|
|
962
|
+
};
|
|
963
|
+
/**
|
|
964
|
+
* One engine, as the server consumes it: its capability record, its shipped
|
|
965
|
+
* model catalog, a credential probe, and a runner factory. The claude adapter
|
|
966
|
+
* wraps `SessionRunner` without behaviour change; the codex adapter owns the
|
|
967
|
+
* `codex app-server` integration; the provider adapter is a pseudo-adapter —
|
|
968
|
+
* its runners are built by the host's `createEngineRunner` hook, so its
|
|
969
|
+
* `createRunner` throws and the server routes around it.
|
|
970
|
+
*/
|
|
971
|
+
interface EngineAdapter {
|
|
972
|
+
readonly engine: ProfileEngine;
|
|
973
|
+
/** Must deep-equal ENGINE_CAPABILITIES[engine] — asserted by a core test, so
|
|
974
|
+
* the protocol's browser-safe defaults can never drift from the adapter. */
|
|
975
|
+
readonly capabilities: EngineCapabilities;
|
|
976
|
+
readonly catalog: ModelCatalog;
|
|
977
|
+
/**
|
|
978
|
+
* Probe whether `profile`'s credentials are usable under `env` — the full
|
|
979
|
+
* session environment the real assembly path produces, never a delta (codex
|
|
980
|
+
* replaces the child env wholesale, and a delta would strand HOME/PATH and
|
|
981
|
+
* the auth chain with it). Never rejects.
|
|
982
|
+
*/
|
|
983
|
+
checkAvailability(profile: ProfileInfo, env: Record<string, string | undefined>): Promise<EngineAvailability>;
|
|
984
|
+
/** Build a Runner. Throwing fails the create (session POST 500s, job fails). */
|
|
985
|
+
createRunner(request: EngineRunnerRequest): Runner | Promise<Runner>;
|
|
986
|
+
/**
|
|
987
|
+
* List the engine's on-disk resumable sessions (`GET /sdk-sessions`) —
|
|
988
|
+
* present exactly when the capability record's `listSessions` is true. Must
|
|
989
|
+
* not require a live session: the codex adapter answers over a short-lived
|
|
990
|
+
* `thread/list` app-server child it closes before returning; the claude
|
|
991
|
+
* adapter reads the Agent SDK's store directly. `env` follows the
|
|
992
|
+
* checkAvailability contract (the profile's complete session environment,
|
|
993
|
+
* never a delta). `dir` narrows to one project directory; `limit`/`offset`
|
|
994
|
+
* page the newest-first result.
|
|
995
|
+
*/
|
|
996
|
+
listSessions?(options: {
|
|
997
|
+
profile?: ProfileInfo;
|
|
998
|
+
env: Record<string, string | undefined>;
|
|
999
|
+
dir?: string;
|
|
1000
|
+
limit?: number;
|
|
1001
|
+
offset?: number;
|
|
1002
|
+
}): Promise<SdkSessionSummary[]>;
|
|
1003
|
+
}
|
|
1004
|
+
/** The in-repo adapter for an engine. An absent `engine` means 'claude'. */
|
|
1005
|
+
declare function getEngineAdapter(engine: ProfileEngine | undefined): EngineAdapter;
|
|
1006
|
+
//#endregion
|
|
1007
|
+
//#region src/engines/claude/adapter.d.ts
|
|
1008
|
+
/**
|
|
1009
|
+
* The Claude engine as an adapter — a thin, behaviourally inert wrapper:
|
|
1010
|
+
* `SessionRunner` unchanged, `checkClaudeAuth` as the probe, the static
|
|
1011
|
+
* catalog for create forms. Exists so catalogs, capabilities and availability
|
|
1012
|
+
* have one shape across engines; the runner itself is exactly what
|
|
1013
|
+
* `registry.prepare()` builds.
|
|
1014
|
+
*/
|
|
1015
|
+
declare const claudeAdapter: EngineAdapter;
|
|
1016
|
+
//#endregion
|
|
1017
|
+
//#region src/engines/claude/catalog.d.ts
|
|
1018
|
+
/**
|
|
1019
|
+
* The Claude engine's model catalog — what a create form offers before any
|
|
1020
|
+
* session has run.
|
|
1021
|
+
*
|
|
1022
|
+
* **Refresh procedure** (release checklist): run `supportedModels()` on a
|
|
1023
|
+
* throwaway SDK query (no tokens spent) and re-apply the shaping rules of
|
|
1024
|
+
* `modelOptionsFromSdk` (`src/normalize.ts`) at authoring time: drop the
|
|
1025
|
+
* `default` sentinel row, derive display names from resolved ids where
|
|
1026
|
+
* unambiguous, mark the newest of each family `primary`, sort by family rank.
|
|
1027
|
+
* A unit test replays the raw extraction through `modelOptionsFromSdk` and
|
|
1028
|
+
* asserts these rows match, so the rules cannot drift.
|
|
1029
|
+
*
|
|
1030
|
+
* Two things the live `capabilities` event can never offer:
|
|
1031
|
+
* - rows for **older models** the CLI no longer reports (hand-maintained, the
|
|
1032
|
+
* accepted cost of a static catalog; the CLI silently downgrades an effort a
|
|
1033
|
+
* model doesn't support, so `reasoningEfforts` is omitted on them and the
|
|
1034
|
+
* engine default set applies);
|
|
1035
|
+
* - an answer on a **cold server**. The live event still exists and remains
|
|
1036
|
+
* the in-session truth for the model switcher; this catalog is the
|
|
1037
|
+
* create-form truth.
|
|
1038
|
+
*
|
|
1039
|
+
* `defaultModel` is deliberately NOT here: a claude profile's default is the
|
|
1040
|
+
* operator's CLI config, unknowable statically.
|
|
1041
|
+
*/
|
|
1042
|
+
declare const CLAUDE_CATALOG: ModelCatalog;
|
|
1043
|
+
//#endregion
|
|
1044
|
+
//#region src/engines/codex/types.d.ts
|
|
1045
|
+
/**
|
|
1046
|
+
* Structural mirror of the slice of the `codex app-server` JSON-RPC v2 surface
|
|
1047
|
+
* this engine consumes. Local on purpose: no published client for this
|
|
1048
|
+
* protocol exists, the shapes are regenerated from the binary itself
|
|
1049
|
+
* (`codex app-server generate-json-schema --out <dir>`, verified 2026-08-05
|
|
1050
|
+
* against 0.146.0), and every open-ended axis is a plain string so a newer
|
|
1051
|
+
* binary degrades to the unknown-item path instead of a type error.
|
|
1052
|
+
*
|
|
1053
|
+
* Naming note: the v2 surface is camelCase (`aggregatedOutput`, `exitCode`,
|
|
1054
|
+
* `localImage`) where `codex exec`'s JSONL — the retired first transport, and
|
|
1055
|
+
* what OpenAI's own docs mostly show — is snake_case. The two vocabularies
|
|
1056
|
+
* look alike but are not interchangeable.
|
|
1057
|
+
*/
|
|
1058
|
+
/** `TokenUsageBreakdown` — one entry of `thread/tokenUsage/updated`. OpenAI
|
|
1059
|
+
* accounting: `inputTokens` INCLUDES the cached share (the relation the
|
|
1060
|
+
* runner's subtraction assumes, asserted in `smoke:codex`). */
|
|
1061
|
+
type AppServerTokenUsage = {
|
|
1062
|
+
inputTokens: number;
|
|
1063
|
+
cachedInputTokens: number; /** Default 0 in the schema; absent in some payloads. */
|
|
1064
|
+
cacheWriteInputTokens?: number;
|
|
1065
|
+
outputTokens: number;
|
|
1066
|
+
reasoningOutputTokens: number;
|
|
1067
|
+
totalTokens: number;
|
|
1068
|
+
};
|
|
1069
|
+
type AppServerAgentMessageItem = {
|
|
1070
|
+
id: string;
|
|
1071
|
+
type: 'agentMessage';
|
|
1072
|
+
text: string;
|
|
1073
|
+
};
|
|
1074
|
+
/** `summary` is what streams by default (`item/reasoning/summaryTextDelta`);
|
|
1075
|
+
* `content` is raw CoT and only populated when the operator's config asks. */
|
|
1076
|
+
type AppServerReasoningItem = {
|
|
1077
|
+
id: string;
|
|
1078
|
+
type: 'reasoning';
|
|
1079
|
+
content?: string[];
|
|
1080
|
+
summary?: string[];
|
|
1081
|
+
};
|
|
1082
|
+
type AppServerCommandExecutionItem = {
|
|
1083
|
+
id: string;
|
|
1084
|
+
type: 'commandExecution';
|
|
1085
|
+
command: string;
|
|
1086
|
+
aggregatedOutput?: string;
|
|
1087
|
+
exitCode?: number | null; /** 'inProgress' | 'completed' | 'failed' | 'declined' — open. */
|
|
1088
|
+
status: string;
|
|
1089
|
+
};
|
|
1090
|
+
/** v2 `kind` is an object (`{type: 'add'|'delete'|'update', move_path?}`) —
|
|
1091
|
+
* the snake_case JSONL's was a bare string; mapped defensively. */
|
|
1092
|
+
type AppServerFileChangeItem = {
|
|
1093
|
+
id: string;
|
|
1094
|
+
type: 'fileChange';
|
|
1095
|
+
changes: Array<{
|
|
1096
|
+
path: string;
|
|
1097
|
+
kind: string | {
|
|
1098
|
+
type: string;
|
|
1099
|
+
};
|
|
1100
|
+
diff?: string;
|
|
1101
|
+
}>;
|
|
1102
|
+
status: string;
|
|
1103
|
+
};
|
|
1104
|
+
type AppServerMcpToolCallItem = {
|
|
1105
|
+
id: string;
|
|
1106
|
+
type: 'mcpToolCall';
|
|
1107
|
+
server: string;
|
|
1108
|
+
tool: string;
|
|
1109
|
+
arguments: unknown;
|
|
1110
|
+
result?: unknown;
|
|
1111
|
+
error?: {
|
|
1112
|
+
message: string;
|
|
1113
|
+
} | null;
|
|
1114
|
+
status: string;
|
|
1115
|
+
};
|
|
1116
|
+
type AppServerWebSearchItem = {
|
|
1117
|
+
id: string;
|
|
1118
|
+
type: 'webSearch';
|
|
1119
|
+
query: string;
|
|
1120
|
+
};
|
|
1121
|
+
/**
|
|
1122
|
+
* A picture the model made with codex's built-in `image_gen` tool.
|
|
1123
|
+
*
|
|
1124
|
+
* `savedPath` is an absolute path on the **host** — by default under
|
|
1125
|
+
* `$CODEX_HOME/generated_images/`, or inside the workspace when the model was
|
|
1126
|
+
* told the asset belongs to the project. It is the only reference we get: the
|
|
1127
|
+
* app-server never sends the bytes, and neither do we (the event log carries
|
|
1128
|
+
* references, never base64 — see the protocol's note on attachments).
|
|
1129
|
+
*
|
|
1130
|
+
* `result` is an undocumented free-form string. Treated as untrusted length:
|
|
1131
|
+
* short values are shown, anything long enough to be an encoded image is not.
|
|
1132
|
+
*/
|
|
1133
|
+
type AppServerImageGenerationItem = {
|
|
1134
|
+
id: string;
|
|
1135
|
+
type: 'imageGeneration';
|
|
1136
|
+
status: string;
|
|
1137
|
+
revisedPrompt?: string | null;
|
|
1138
|
+
result: string;
|
|
1139
|
+
savedPath?: string;
|
|
1140
|
+
};
|
|
1141
|
+
/** The model *looked at* an image on disk (`path`, host-absolute). */
|
|
1142
|
+
type AppServerImageViewItem = {
|
|
1143
|
+
id: string;
|
|
1144
|
+
type: 'imageView';
|
|
1145
|
+
path: string;
|
|
1146
|
+
};
|
|
1147
|
+
/** The user's own message, echoed back as an item — dropped (the runner
|
|
1148
|
+
* already emitted its `user_message`). */
|
|
1149
|
+
type AppServerUserMessageItem = {
|
|
1150
|
+
id: string;
|
|
1151
|
+
type: 'userMessage';
|
|
1152
|
+
content?: unknown;
|
|
1153
|
+
};
|
|
1154
|
+
type AppServerItem = AppServerAgentMessageItem | AppServerReasoningItem | AppServerCommandExecutionItem | AppServerFileChangeItem | AppServerMcpToolCallItem | AppServerWebSearchItem | AppServerImageGenerationItem | AppServerImageViewItem | AppServerUserMessageItem;
|
|
1155
|
+
/** The `Turn` object of `turn/started` / `turn/completed`. */
|
|
1156
|
+
type AppServerTurn = {
|
|
1157
|
+
id: string; /** 'inProgress' | 'completed' | 'failed' | 'interrupted' — open. */
|
|
1158
|
+
status: string;
|
|
1159
|
+
error?: {
|
|
1160
|
+
message: string;
|
|
1161
|
+
} | null;
|
|
1162
|
+
};
|
|
1163
|
+
/**
|
|
1164
|
+
* One historical turn as `thread/resume` / `thread/read {includeTurns: true}`
|
|
1165
|
+
* return it: the same `ThreadItem` vocabulary the live `item/completed`
|
|
1166
|
+
* notifications carry (so the live mapping replays it unchanged), plus an
|
|
1167
|
+
* `itemsView` marker ('full' | 'summary' | 'notLoaded') saying how much of
|
|
1168
|
+
* `items` was actually loaded. Measured against 0.146.0: both surfaces return
|
|
1169
|
+
* 'full' items in chronological order.
|
|
1170
|
+
*/
|
|
1171
|
+
type AppServerHistoryTurn = {
|
|
1172
|
+
id: string;
|
|
1173
|
+
items?: AppServerItem[];
|
|
1174
|
+
itemsView?: string;
|
|
1175
|
+
status?: string;
|
|
1176
|
+
};
|
|
1177
|
+
/**
|
|
1178
|
+
* One `thread/list` row (the summary Thread shape — its `turns` is always
|
|
1179
|
+
* empty on list responses). Timestamps are epoch **seconds** (the protocol's
|
|
1180
|
+
* summaries want ms). `id` is what `CreateSessionRequest.resume` feeds
|
|
1181
|
+
* `thread/resume`; the row's separate `sessionId` field is not it.
|
|
1182
|
+
*/
|
|
1183
|
+
type AppServerThreadSummary = {
|
|
1184
|
+
id: string; /** Operator-set thread name, when one exists. */
|
|
1185
|
+
name?: string | null; /** First user message — the natural summary line. */
|
|
1186
|
+
preview?: string | null;
|
|
1187
|
+
createdAt?: number | null;
|
|
1188
|
+
updatedAt?: number | null;
|
|
1189
|
+
cwd?: string | null; /** Ephemeral threads are never materialized on disk — not resumable. */
|
|
1190
|
+
ephemeral?: boolean;
|
|
1191
|
+
gitInfo?: {
|
|
1192
|
+
branch?: string | null;
|
|
1193
|
+
} | null;
|
|
1194
|
+
};
|
|
1195
|
+
/** `thread/list` result: one page plus an opaque continuation cursor. */
|
|
1196
|
+
type AppServerThreadListResponse = {
|
|
1197
|
+
data?: AppServerThreadSummary[];
|
|
1198
|
+
nextCursor?: string | null;
|
|
1199
|
+
};
|
|
1200
|
+
type AppServerUserInput = {
|
|
1201
|
+
type: 'text';
|
|
1202
|
+
text: string;
|
|
1203
|
+
} | {
|
|
1204
|
+
type: 'localImage';
|
|
1205
|
+
path: string;
|
|
1206
|
+
};
|
|
1207
|
+
/**
|
|
1208
|
+
* One live `codex app-server` child as the runner consumes it. The real
|
|
1209
|
+
* implementation (`process.ts`) spawns the binary and frames JSON-RPC
|
|
1210
|
+
* over its stdio; unit tests inject a scripted one — no process, no
|
|
1211
|
+
* credentials.
|
|
1212
|
+
*/
|
|
1213
|
+
type AppServerConnection = {
|
|
1214
|
+
/** Client→server request. Rejects on a JSON-RPC error response, a dead
|
|
1215
|
+
* child, or a closed connection. */
|
|
1216
|
+
request(method: string, params?: unknown): Promise<unknown>; /** Client→server notification (fire and forget). */
|
|
1217
|
+
notify(method: string, params?: unknown): void; /** Server→client notifications. One handler (the runner). */
|
|
1218
|
+
onNotification(handler: (method: string, params: unknown) => void): void;
|
|
1219
|
+
/** Server→client REQUESTS (approvals live here): the handler's resolution is
|
|
1220
|
+
* sent back as the JSON-RPC result; a throw becomes an error response. `id`
|
|
1221
|
+
* is the wire request id — `serverRequest/resolved` names it when codex
|
|
1222
|
+
* settles a request on its own (auto-resolution), so the runner can retire
|
|
1223
|
+
* the matching pending approval instead of leaving a stale card. */
|
|
1224
|
+
onRequest(handler: (method: string, params: unknown, id: string | number) => Promise<unknown>): void;
|
|
1225
|
+
/** Fires once when the child exits or the pipe breaks — NOT on `close()`.
|
|
1226
|
+
* The message carries an exit summary and a stderr tail for diagnostics. */
|
|
1227
|
+
onClose(handler: (message: string) => void): void; /** Tear the child down (session close). Suppresses the onClose callback. */
|
|
1228
|
+
close(): void;
|
|
1229
|
+
};
|
|
1230
|
+
type AppServerConnectOptions = {
|
|
1231
|
+
/** Complete child environment — a provided spawn env replaces process.env,
|
|
1232
|
+
* never merges with it (CODEX_HOME pin already applied). */
|
|
1233
|
+
env: Record<string, string>;
|
|
1234
|
+
};
|
|
1235
|
+
/** The injectable connection factory: `connectAppServer` under the resolved
|
|
1236
|
+
* binary in production, a scripted peer in tests. */
|
|
1237
|
+
type AppServerConnectFn = (options: AppServerConnectOptions) => AppServerConnection;
|
|
1238
|
+
//#endregion
|
|
1239
|
+
//#region src/engines/codex/adapter.d.ts
|
|
1240
|
+
/**
|
|
1241
|
+
* The codex binary sessions will run: the per-platform package installed next
|
|
1242
|
+
* to `@openai/codex`, `vendor/<target-triple>/bin/codex` — the same file the
|
|
1243
|
+
* npm wrapper's own `bin/codex.js` launcher execs. Probing this binary rather
|
|
1244
|
+
* than whatever `codex` is on PATH means the availability answer is about the
|
|
1245
|
+
* executable sessions will actually run. Undefined when it can't be found;
|
|
1246
|
+
* callers degrade to 'unknown'.
|
|
1247
|
+
*/
|
|
1248
|
+
declare function resolveBundledCodexExecutable(): string | undefined;
|
|
1249
|
+
/**
|
|
1250
|
+
* CODEX_HOME's threads over ONE short-lived `codex app-server` child: the
|
|
1251
|
+
* runner's own handshake (`experimentalApi` and all — one code path, no
|
|
1252
|
+
* second vocabulary to drift), `thread/list` pages walked by cursor, child
|
|
1253
|
+
* closed before returning. Requires no live session and costs no tokens —
|
|
1254
|
+
* it is how "resume" is offered before anything is running. The `connectFn`
|
|
1255
|
+
* seam exists for the scripted-peer tests; the adapter passes the real
|
|
1256
|
+
* spawn.
|
|
1257
|
+
*/
|
|
1258
|
+
declare function listCodexSessions(options: {
|
|
1259
|
+
connectFn: AppServerConnectFn;
|
|
1260
|
+
profile?: ProfileInfo;
|
|
1261
|
+
env: Record<string, string | undefined>;
|
|
1262
|
+
dir?: string;
|
|
1263
|
+
limit?: number;
|
|
1264
|
+
offset?: number;
|
|
1265
|
+
}): Promise<SdkSessionSummary[]>;
|
|
1266
|
+
/**
|
|
1267
|
+
* OpenAI Codex as an engine: the codex CLI binary driven over its `app-server`
|
|
1268
|
+
* JSON-RPC surface — structurally the Claude engine's sibling (a local agent
|
|
1269
|
+
* binary with sessions, sandboxing and resume, resolving its own credentials
|
|
1270
|
+
* from the operator's environment). `@openai/codex` — the npm package that
|
|
1271
|
+
* carries the binary — is an **optional peer**: absent, every codex profile
|
|
1272
|
+
* reports unavailable and createRunner throws the same message, and no
|
|
1273
|
+
* consumer downloads a ~40 MB per-platform binary it never uses.
|
|
1274
|
+
*/
|
|
1275
|
+
declare const codexAdapter: EngineAdapter;
|
|
1276
|
+
//#endregion
|
|
1277
|
+
//#region src/engines/codex/catalog.d.ts
|
|
1278
|
+
/**
|
|
1279
|
+
* The Codex engine's model catalog, seeded from the binary's own embedded
|
|
1280
|
+
* presets — `@openai/codex@0.146.0` ships its model table inside the
|
|
1281
|
+
* executable, and that table (not the SDK's stale `ModelReasoningEffort`
|
|
1282
|
+
* union) is the truth about which reasoning efforts each model takes.
|
|
1283
|
+
*
|
|
1284
|
+
* **Refresh procedure** (release checklist): extract the embedded JSON from
|
|
1285
|
+
* the platform binary and diff —
|
|
1286
|
+
*
|
|
1287
|
+
* node -e 'const d=require("fs").readFileSync(process.argv[1]);
|
|
1288
|
+
* const s=d.indexOf(`{\n "models": [`);
|
|
1289
|
+
* let i=s,n=0; do{n+=(d[i]===123)-(d[i]===125);i++}while(n);
|
|
1290
|
+
* const c=JSON.parse(d.slice(s,i));
|
|
1291
|
+
* for(const m of c.models) console.log(m.slug, m.display_name,
|
|
1292
|
+
* m.visibility, m.supported_reasoning_levels.map(l=>l.effort).join(","))'\
|
|
1293
|
+
* "$(node -p 'require.resolve("@openai/codex-darwin-arm64/package.json").replace("package.json","vendor/aarch64-apple-darwin/bin/codex")')"
|
|
1294
|
+
*
|
|
1295
|
+
* Mapping decisions:
|
|
1296
|
+
* - the internal `codex-auto-review` row is dropped (the codex analogue of
|
|
1297
|
+
* dropping the CLI's `default` sentinel);
|
|
1298
|
+
* - `primary` mirrors the binary's own `visibility` field ('list' = shown in
|
|
1299
|
+
* its picker, 'hide' = its "older models"), so both UIs group the way
|
|
1300
|
+
* codex's own picker does;
|
|
1301
|
+
* - `reasoningEfforts` carries `supported_reasoning_levels` verbatim — note
|
|
1302
|
+
* `max`/`ultra` beyond the SDK union; trust the binary, keep strings open.
|
|
1303
|
+
*/
|
|
1304
|
+
declare const CODEX_CATALOG: ModelCatalog;
|
|
1305
|
+
//#endregion
|
|
1306
|
+
//#region src/engines/codex/runner.d.ts
|
|
1307
|
+
type CodexRunnerConfig = CreateSessionRequest & {
|
|
1308
|
+
/** The injectable connection factory. The codex adapter passes
|
|
1309
|
+
* `connectAppServer` under the resolved binary; unit tests pass a scripted
|
|
1310
|
+
* peer. Required — this class never spawns anything itself. */
|
|
1311
|
+
connectFn: AppServerConnectFn;
|
|
1312
|
+
/** Base environment for the codex child. Defaults to process.env. Passed to
|
|
1313
|
+
* spawn **complete** — a child env replaces, never merges. */
|
|
1314
|
+
env?: Record<string, string | undefined>; /** CODEX_HOME pin from the profile (auth, config.toml, thread storage). */
|
|
1315
|
+
codexHome?: string;
|
|
1316
|
+
/** Timeout for pending approvals when the request itself doesn't set one.
|
|
1317
|
+
* Default 300000 — the SessionRunner default. */
|
|
1318
|
+
defaultApprovalTimeoutMs?: number;
|
|
1319
|
+
/** With `resume`: replay the thread's prior turns as `replay: true` events
|
|
1320
|
+
* before anything else, so late-attaching clients get a full transcript —
|
|
1321
|
+
* the SessionRunner option, same name, same default (true). */
|
|
1322
|
+
backfillHistory?: boolean;
|
|
1323
|
+
};
|
|
1324
|
+
/**
|
|
1325
|
+
* The Codex engine, over the binary's `app-server` JSON-RPC surface: ONE
|
|
1326
|
+
* `codex app-server` child per *session* (spawned lazily, held across turns),
|
|
1327
|
+
* streaming `item/agentMessage/delta` and the reasoning deltas token-by-token
|
|
1328
|
+
* (`streaming: 'token'`). Follows `SessionRunner`'s event-log/seq/status
|
|
1329
|
+
* discipline with `AiSdkRunner`'s turn-chain (one turn at a time; sendMessage
|
|
1330
|
+
* queues). The first codex transport was `codex exec --experimental-json` (one
|
|
1331
|
+
* child per turn) — retired because its JSONL carries no partial messages, so
|
|
1332
|
+
* a turn could never stream.
|
|
1333
|
+
*
|
|
1334
|
+
* A dead child is a failed *turn*, not a failed session: the thread persists
|
|
1335
|
+
* on disk, the connection is dropped, and the next message spawns a fresh
|
|
1336
|
+
* child that `thread/resume`s the same thread id.
|
|
1337
|
+
*/
|
|
1338
|
+
declare class CodexRunner implements Runner {
|
|
1339
|
+
#private;
|
|
1340
|
+
readonly id: string;
|
|
1341
|
+
readonly createdAt: number;
|
|
1342
|
+
constructor(config: CodexRunnerConfig, id?: string);
|
|
1343
|
+
get status(): SessionStatus;
|
|
1344
|
+
get sdkSessionId(): string | undefined;
|
|
1345
|
+
get lastSeq(): number;
|
|
1346
|
+
get pendingApprovals(): PermissionRequest[];
|
|
1347
|
+
info(): SessionInfo;
|
|
1348
|
+
start(): Promise<void>;
|
|
1349
|
+
sendMessage(text: string, attachments?: readonly AttachmentInput[]): void;
|
|
1350
|
+
/** Resolve a pending approval. Returns false if the id is unknown (e.g.
|
|
1351
|
+
* timed out, or already settled by codex itself). */
|
|
1352
|
+
resolvePermission(requestId: string, decision: PermissionDecision): boolean;
|
|
1353
|
+
interrupt(): Promise<void>;
|
|
1354
|
+
setPermissionMode(mode: PermissionMode): Promise<void>;
|
|
1355
|
+
setModel(model?: string): Promise<void>;
|
|
1356
|
+
fail(message: string): void;
|
|
1357
|
+
close(reason?: 'client' | 'server' | 'error'): void;
|
|
1358
|
+
subscribe(listener: SessionEventListener, afterSeq?: number): () => void;
|
|
1359
|
+
/**
|
|
1360
|
+
* The session's MCP servers, live from the binary.
|
|
1361
|
+
*
|
|
1362
|
+
* Two sources merged, because codex splits them: `mcpServerStatus/list` says
|
|
1363
|
+
* what is configured and what each server exposes (including every tool's
|
|
1364
|
+
* full JSON Schema, which the Agent SDK does not give us), and the
|
|
1365
|
+
* `mcpServer/startupStatus/updated` notifications say which of them are
|
|
1366
|
+
* actually up.
|
|
1367
|
+
*
|
|
1368
|
+
* Answers **before the session has connected**, over a throwaway child, for
|
|
1369
|
+
* the same reason the skill list does: a codex session spawns nothing until
|
|
1370
|
+
* it has work, and a panel that said "no MCP servers configured" until the
|
|
1371
|
+
* first turn would be stating something false about the operator's config.
|
|
1372
|
+
* The request blocks until the servers are enumerated (measured: complete on
|
|
1373
|
+
* the very first call), so there is no half-populated answer to race.
|
|
1374
|
+
*
|
|
1375
|
+
* Resolves undefined only when there is genuinely nothing to say — the
|
|
1376
|
+
* session is closed, or the child could not be spoken to. The route turns
|
|
1377
|
+
* that into a 501.
|
|
1378
|
+
*
|
|
1379
|
+
* **Listing only.** There is no per-server reconnect or toggle on this
|
|
1380
|
+
* transport — hence no `reconnectMcpServer`/`setMcpServerEnabled` here, and
|
|
1381
|
+
* `ENGINE_CAPABILITIES.codex.mcpServerActions: false` so clients render the
|
|
1382
|
+
* panel read-only instead of offering buttons that cannot work.
|
|
1383
|
+
*/
|
|
1384
|
+
mcpServers(): Promise<McpServerStatusInfo[] | undefined>;
|
|
1385
|
+
}
|
|
1386
|
+
//#endregion
|
|
1387
|
+
//#region src/engines/codex/process.d.ts
|
|
1388
|
+
/**
|
|
1389
|
+
* Spawn one `codex app-server` child and frame JSON-RPC over its stdio — the
|
|
1390
|
+
* real {@link AppServerConnectFn}. The child's env is passed **complete**
|
|
1391
|
+
* (a provided spawn env replaces process.env, never merges with it), with the
|
|
1392
|
+
* profile's CODEX_HOME pin already applied by the runner.
|
|
1393
|
+
*
|
|
1394
|
+
* No spawn cwd: the working directory is a thread/turn parameter, and a cwd
|
|
1395
|
+
* that doesn't exist should fail the *turn* with codex's own error, not the
|
|
1396
|
+
* spawn.
|
|
1397
|
+
*/
|
|
1398
|
+
declare function connectAppServer(options: {
|
|
1399
|
+
executable: string;
|
|
1400
|
+
env: Record<string, string>;
|
|
1401
|
+
}): AppServerConnection;
|
|
1402
|
+
//#endregion
|
|
1403
|
+
//#region src/engines/codex/jsonrpc.d.ts
|
|
1404
|
+
/**
|
|
1405
|
+
* A JSON-RPC error response from the peer, or one we return to it. `code`
|
|
1406
|
+
* follows the JSON-RPC 2.0 reserved ranges (-32601 = method not found).
|
|
1407
|
+
*/
|
|
1408
|
+
declare class JsonRpcError extends Error {
|
|
1409
|
+
readonly code: number;
|
|
1410
|
+
constructor(code: number, message: string);
|
|
1411
|
+
}
|
|
1412
|
+
/**
|
|
1413
|
+
* JSON-RPC over a `codex app-server` child's stdio: **newline-delimited JSON**,
|
|
1414
|
+
* one message per line, and — verified against 0.146.0 — an envelope *without*
|
|
1415
|
+
* the `jsonrpc: "2.0"` field (`{id, method, params}` / `{id, result}` /
|
|
1416
|
+
* `{id, error}`; the binary's own schema marks only those required). Server→
|
|
1417
|
+
* client notifications additionally carry a top-level `emittedAtMs`, ignored
|
|
1418
|
+
* here.
|
|
1419
|
+
*
|
|
1420
|
+
* Transport only: no method knowledge, no process ownership. The process
|
|
1421
|
+
* wrapper (`process.ts`) owns the child and calls {@link fail} when it dies so
|
|
1422
|
+
* every in-flight request rejects instead of hanging.
|
|
1423
|
+
*/
|
|
1424
|
+
declare class JsonRpcStdioConnection {
|
|
1425
|
+
#private;
|
|
1426
|
+
constructor(options: {
|
|
1427
|
+
input: Readable;
|
|
1428
|
+
output: Writable;
|
|
1429
|
+
});
|
|
1430
|
+
request(method: string, params?: unknown): Promise<unknown>;
|
|
1431
|
+
notify(method: string, params?: unknown): void;
|
|
1432
|
+
onNotification(handler: (method: string, params: unknown) => void): void;
|
|
1433
|
+
onRequest(handler: (method: string, params: unknown, id: string | number) => Promise<unknown>): void;
|
|
1434
|
+
/** Reject everything in flight and refuse new traffic — the child is gone
|
|
1435
|
+
* (or the session is over). Idempotent. */
|
|
1436
|
+
fail(message: string): void;
|
|
1437
|
+
}
|
|
1438
|
+
//#endregion
|
|
1439
|
+
//#region src/engines/provider/adapter.d.ts
|
|
1440
|
+
/**
|
|
1441
|
+
* The model-agnostic provider engine as a pseudo-adapter: capabilities and an
|
|
1442
|
+
* env-var probe live here, but its runners are assembled by the host's
|
|
1443
|
+
* `createEngineRunner` hook (which is where provider credentials are resolved
|
|
1444
|
+
* and model SDKs are imported — neither belongs in this repo's import graph).
|
|
1445
|
+
* The server routes provider creates to the hook; `createRunner` here throws
|
|
1446
|
+
* so a mis-routed call fails loudly instead of quietly building nothing.
|
|
1447
|
+
*
|
|
1448
|
+
* The catalog is empty by the same token: provider model ids are operator-
|
|
1449
|
+
* declared per profile (`provider.models`), not shipped with releases.
|
|
1450
|
+
*/
|
|
1451
|
+
declare const providerAdapter: EngineAdapter;
|
|
1452
|
+
//#endregion
|
|
1453
|
+
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 };
|
|
848
1454
|
//# sourceMappingURL=index.d.mts.map
|