@workerdeck/core 1.1.0 → 1.3.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 +8 -28
- package/build/index.mjs +72 -44
- package/build/index.mjs.map +1 -1
- package/package.json +3 -3
package/build/index.d.mts
CHANGED
|
@@ -190,6 +190,7 @@ type AiSdkRunnerConfig = Omit<CreateSessionRequest, 'cwd'> & {
|
|
|
190
190
|
memoryLimitBytes?: number;
|
|
191
191
|
};
|
|
192
192
|
executionBackend?: ToolExecutionBackend;
|
|
193
|
+
toolTitles?: Record<string, string>;
|
|
193
194
|
shouldApprove?: (call: {
|
|
194
195
|
toolName: string;
|
|
195
196
|
input: unknown;
|
|
@@ -424,6 +425,7 @@ type ToolDefinition = {
|
|
|
424
425
|
name: string;
|
|
425
426
|
trust: ToolTrust;
|
|
426
427
|
tool: Tool$1;
|
|
428
|
+
title?: string;
|
|
427
429
|
};
|
|
428
430
|
type ToolContextOptions = {
|
|
429
431
|
executor: ToolExecutor;
|
|
@@ -462,6 +464,7 @@ declare function withMcpTools(context: ToolContext, mcpTools: ToolSet$1): ToolCo
|
|
|
462
464
|
type HostToolDefinition = {
|
|
463
465
|
tool: Tool$1;
|
|
464
466
|
trust: ToolTrust;
|
|
467
|
+
title?: string;
|
|
465
468
|
};
|
|
466
469
|
declare function withHostTools(context: ToolContext, hostTools: Record<string, HostToolDefinition>, kind?: string): ToolContext;
|
|
467
470
|
//#endregion
|
|
@@ -664,7 +667,11 @@ type AppServerUserMessageItem = {
|
|
|
664
667
|
type: 'userMessage';
|
|
665
668
|
content?: unknown;
|
|
666
669
|
};
|
|
667
|
-
type
|
|
670
|
+
type AppServerContextCompactionItem = {
|
|
671
|
+
id: string;
|
|
672
|
+
type: 'contextCompaction';
|
|
673
|
+
};
|
|
674
|
+
type AppServerItem = AppServerAgentMessageItem | AppServerReasoningItem | AppServerCommandExecutionItem | AppServerFileChangeItem | AppServerMcpToolCallItem | AppServerWebSearchItem | AppServerImageGenerationItem | AppServerImageViewItem | AppServerUserMessageItem | AppServerSubAgentActivityItem | AppServerCollabAgentToolCallItem | AppServerContextCompactionItem;
|
|
668
675
|
type AppServerTurn = {
|
|
669
676
|
id: string;
|
|
670
677
|
status: string;
|
|
@@ -728,33 +735,6 @@ declare function listCodexSessions(options: {
|
|
|
728
735
|
declare const codexAdapter: EngineAdapter;
|
|
729
736
|
//#endregion
|
|
730
737
|
//#region src/engines/codex/catalog.d.ts
|
|
731
|
-
/**
|
|
732
|
-
* The Codex engine's model catalog, seeded from the binary's own embedded model
|
|
733
|
-
* table (see `provenance` for the version) — that table, not the SDK's stale
|
|
734
|
-
* `ModelReasoningEffort` union, is the truth about which reasoning efforts each
|
|
735
|
-
* model takes. Mapping decisions: the internal `codex-auto-review` row is dropped
|
|
736
|
-
* (the codex analogue of the CLI's `default` sentinel), `primary` mirrors the
|
|
737
|
-
* binary's own `visibility` field so both UIs group the way codex's picker does,
|
|
738
|
-
* and `reasoningEfforts` carries `supported_reasoning_levels` verbatim — `max`
|
|
739
|
-
* and `ultra` go beyond the SDK union, so trust the binary and keep strings open.
|
|
740
|
-
*
|
|
741
|
-
* **Refresh procedure** (release checklist): extract the embedded JSON from the
|
|
742
|
-
* platform binary and diff. The two-hop resolve is NOT optional — under pnpm's
|
|
743
|
-
* strict layout the platform package is a dependency of `@openai/codex` and
|
|
744
|
-
* resolves only from that wrapper's location (MODULE_NOT_FOUND otherwise), the
|
|
745
|
-
* same two hops `resolveBundledCodexExecutable` makes.
|
|
746
|
-
*
|
|
747
|
-
* node -e 'const d=require("fs").readFileSync(process.argv[1]);
|
|
748
|
-
* const s=d.indexOf(`{\n "models": [`);
|
|
749
|
-
* let i=s,n=0; do{n+=(d[i]===123)-(d[i]===125);i++}while(n);
|
|
750
|
-
* const c=JSON.parse(d.slice(s,i));
|
|
751
|
-
* for(const m of c.models) console.log(m.slug, m.display_name,
|
|
752
|
-
* m.visibility, m.supported_reasoning_levels.map(l=>l.effort).join(","))'\
|
|
753
|
-
* "$(node -p 'const{createRequire}=require("module");
|
|
754
|
-
* const w=require.resolve("@openai/codex/package.json");
|
|
755
|
-
* createRequire(w).resolve("@openai/codex-darwin-arm64/package.json")
|
|
756
|
-
* .replace("package.json","vendor/aarch64-apple-darwin/bin/codex")')"
|
|
757
|
-
*/
|
|
758
738
|
declare const CODEX_CATALOG: ModelCatalog;
|
|
759
739
|
//#endregion
|
|
760
740
|
//#region src/engines/codex/runner.d.ts
|
package/build/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { createHash, randomUUID } from "node:crypto";
|
|
3
3
|
import { getSessionInfo, getSessionMessages, listSessions, query } from "@anthropic-ai/claude-agent-sdk";
|
|
4
|
-
import { ENGINE_CAPABILITIES, PROTOCOL_VERSION, SUBAGENT_HISTORY, TOOL_RESULT_HEAD_CHARS, contextReading, imagePartRef, replayCoalesceKey, replayRetains, snapshotRetains, transcriptActivity, transcriptContent, transcriptProse } from "@workerdeck/protocol";
|
|
4
|
+
import { ENGINE_CAPABILITIES, PROTOCOL_VERSION, SUBAGENT_HISTORY, TOOL_RESULT_HEAD_CHARS, contextReading, imagePartRef, replayCoalesceKey, replayRetains, sanitizeToolTitle, snapshotRetains, transcriptActivity, transcriptContent, transcriptProse } from "@workerdeck/protocol";
|
|
5
5
|
import { ToolLoopAgent, generateText, isStepCount, tool } from "ai";
|
|
6
6
|
import { execFile, spawn } from "node:child_process";
|
|
7
7
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
@@ -276,11 +276,16 @@ function mcpStatusInfo(status) {
|
|
|
276
276
|
command: config?.command,
|
|
277
277
|
args: config?.args,
|
|
278
278
|
url: config?.url,
|
|
279
|
-
tools: status.tools?.map((tool) =>
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
279
|
+
tools: status.tools?.map((tool) => {
|
|
280
|
+
const probe = tool;
|
|
281
|
+
const title = probe.title ?? probe.annotations?.title;
|
|
282
|
+
return {
|
|
283
|
+
name: tool.name,
|
|
284
|
+
title: sanitizeToolTitle(typeof title === "string" ? title : void 0, tool.name),
|
|
285
|
+
description: tool.description,
|
|
286
|
+
annotations: tool.annotations
|
|
287
|
+
};
|
|
288
|
+
})
|
|
284
289
|
};
|
|
285
290
|
}
|
|
286
291
|
function defaultModelFromSdk(models) {
|
|
@@ -418,7 +423,6 @@ var EventLog = class {
|
|
|
418
423
|
get activityCount() {
|
|
419
424
|
return this.#activityCount;
|
|
420
425
|
}
|
|
421
|
-
/** The unread badge's unit — see `transcriptProse`. Folded here so a restored log recomputes it. */
|
|
422
426
|
get proseCount() {
|
|
423
427
|
return this.#proseCount;
|
|
424
428
|
}
|
|
@@ -1120,6 +1124,7 @@ var SessionRunner = class {
|
|
|
1120
1124
|
this.#turnOverWhileBlocked = false;
|
|
1121
1125
|
this.#setStatus("running");
|
|
1122
1126
|
this.#fetchCapabilities();
|
|
1127
|
+
this.#fetchToolTitles();
|
|
1123
1128
|
this.#fetchContextUsage();
|
|
1124
1129
|
this.#fetchRateLimits();
|
|
1125
1130
|
this.#fetchEngineTitle();
|
|
@@ -1153,6 +1158,16 @@ var SessionRunner = class {
|
|
|
1153
1158
|
}
|
|
1154
1159
|
}
|
|
1155
1160
|
}
|
|
1161
|
+
async #fetchToolTitles() {
|
|
1162
|
+
const servers = await this.mcpServers().catch(() => void 0);
|
|
1163
|
+
if (this.#closed || !servers) return;
|
|
1164
|
+
const titles = {};
|
|
1165
|
+
for (const server of servers) for (const tool of server.tools ?? []) if (tool.title) titles[`mcp__${server.name}__${tool.name}`] = tool.title;
|
|
1166
|
+
if (Object.keys(titles).length > 0) this.#emit({
|
|
1167
|
+
type: "tool_titles",
|
|
1168
|
+
titles
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1156
1171
|
async #fetchCapabilities() {
|
|
1157
1172
|
if (this.#capabilitiesEmitted) return;
|
|
1158
1173
|
const query = this.#query;
|
|
@@ -1477,6 +1492,7 @@ var AiSdkRunner = class {
|
|
|
1477
1492
|
start() {
|
|
1478
1493
|
if (this.#started) return this.#turnChain;
|
|
1479
1494
|
this.#started = true;
|
|
1495
|
+
this.#emitToolTitles();
|
|
1480
1496
|
if (this.#config.restore) return this.#turnChain;
|
|
1481
1497
|
this.#setStatus("idle");
|
|
1482
1498
|
if (this.#config.prompt) this.sendMessage(this.#config.prompt);
|
|
@@ -2135,6 +2151,13 @@ var AiSdkRunner = class {
|
|
|
2135
2151
|
detail
|
|
2136
2152
|
});
|
|
2137
2153
|
}
|
|
2154
|
+
#emitToolTitles() {
|
|
2155
|
+
const titles = this.#config.toolTitles;
|
|
2156
|
+
if (titles && Object.keys(titles).length > 0) this.#emit({
|
|
2157
|
+
type: "tool_titles",
|
|
2158
|
+
titles
|
|
2159
|
+
});
|
|
2160
|
+
}
|
|
2138
2161
|
#emit(body) {
|
|
2139
2162
|
this.#subscribers.emit(this.#log.append(body));
|
|
2140
2163
|
}
|
|
@@ -2667,7 +2690,7 @@ function withHostTools(context, hostTools, kind = "host tool") {
|
|
|
2667
2690
|
const definitions = [...context.definitions];
|
|
2668
2691
|
const tools = { ...context.tools };
|
|
2669
2692
|
const sandboxedToolNames = [...context.sandboxedToolNames];
|
|
2670
|
-
for (const [name, { tool: hostTool, trust }] of entries) {
|
|
2693
|
+
for (const [name, { tool: hostTool, trust, title }] of entries) {
|
|
2671
2694
|
if (name in tools) throw new Error(`${kind} '${name}' collides with an existing tool of the same name`);
|
|
2672
2695
|
const executes = typeof hostTool.execute === "function";
|
|
2673
2696
|
if (trust === "sandboxed" && executes) throw new Error(`${kind} '${name}' is declared sandboxed but has an \`execute\` — it would run in this process with full authority. Drop \`execute\` so it rides the ToolExecutor seam.`);
|
|
@@ -2675,7 +2698,8 @@ function withHostTools(context, hostTools, kind = "host tool") {
|
|
|
2675
2698
|
definitions.push({
|
|
2676
2699
|
name,
|
|
2677
2700
|
trust,
|
|
2678
|
-
tool: hostTool
|
|
2701
|
+
tool: hostTool,
|
|
2702
|
+
title
|
|
2679
2703
|
});
|
|
2680
2704
|
tools[name] = hostTool;
|
|
2681
2705
|
if (trust === "sandboxed") sandboxedToolNames.push(name);
|
|
@@ -2947,6 +2971,7 @@ function createEngineSession(options) {
|
|
|
2947
2971
|
vfs,
|
|
2948
2972
|
executor,
|
|
2949
2973
|
executableTools: context.sandboxedToolNames,
|
|
2974
|
+
toolTitles: collectToolTitles(context.definitions, options.mcp?.servers),
|
|
2950
2975
|
executionBackend: typeof options.backend === "function" ? void 0 : options.backend ?? "server",
|
|
2951
2976
|
executionLimits: options.executionLimits,
|
|
2952
2977
|
shouldApprove: options.shouldApprove,
|
|
@@ -2955,6 +2980,18 @@ function createEngineSession(options) {
|
|
|
2955
2980
|
}, options.id);
|
|
2956
2981
|
return runner;
|
|
2957
2982
|
}
|
|
2983
|
+
function collectToolTitles(definitions, servers) {
|
|
2984
|
+
const titles = {};
|
|
2985
|
+
for (const definition of definitions) {
|
|
2986
|
+
const title = sanitizeToolTitle(definition.title, definition.name);
|
|
2987
|
+
if (title) titles[definition.name] = title;
|
|
2988
|
+
}
|
|
2989
|
+
for (const server of servers ?? []) for (const tool of server.tools ?? []) {
|
|
2990
|
+
const title = sanitizeToolTitle(tool.title, tool.name);
|
|
2991
|
+
if (title) titles[`${server.name}__${tool.name}`] = title;
|
|
2992
|
+
}
|
|
2993
|
+
return Object.keys(titles).length > 0 ? titles : void 0;
|
|
2994
|
+
}
|
|
2958
2995
|
function requireDeclaredServers(profileName, declared, mcp, tools) {
|
|
2959
2996
|
if (!declared || declared.length === 0) return;
|
|
2960
2997
|
const missing = declared.filter((name) => {
|
|
@@ -2999,12 +3036,13 @@ async function connectMcpTools(servers, options = {}) {
|
|
|
2999
3036
|
});
|
|
3000
3037
|
clients.push(client);
|
|
3001
3038
|
const connected = await client.tools();
|
|
3039
|
+
const listed = await listToolRecords(client);
|
|
3002
3040
|
for (const [toolName, mcpTool] of Object.entries(connected)) tools[`${name}__${toolName}`] = mcpTool;
|
|
3003
3041
|
statuses.push({
|
|
3004
3042
|
name,
|
|
3005
3043
|
status: "connected",
|
|
3006
3044
|
...identity,
|
|
3007
|
-
tools: Object.entries(connected).map(([toolName, mcpTool]) => toToolInfo(toolName, mcpTool))
|
|
3045
|
+
tools: Object.entries(connected).map(([toolName, mcpTool]) => toToolInfo(toolName, mcpTool, listed.get(toolName)))
|
|
3008
3046
|
});
|
|
3009
3047
|
} catch (error) {
|
|
3010
3048
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -3038,11 +3076,27 @@ function describeServer(server) {
|
|
|
3038
3076
|
args: server.args
|
|
3039
3077
|
};
|
|
3040
3078
|
}
|
|
3041
|
-
function
|
|
3079
|
+
async function listToolRecords(client) {
|
|
3080
|
+
const records = /* @__PURE__ */ new Map();
|
|
3081
|
+
if (typeof client.listTools !== "function") return records;
|
|
3082
|
+
try {
|
|
3083
|
+
const listed = await client.listTools();
|
|
3084
|
+
for (const record of listed.tools ?? []) records.set(record.name, record);
|
|
3085
|
+
} catch {}
|
|
3086
|
+
return records;
|
|
3087
|
+
}
|
|
3088
|
+
function toToolInfo(name, mcpTool, record) {
|
|
3042
3089
|
const { description, inputSchema } = mcpTool ?? {};
|
|
3090
|
+
const hints = record?.annotations;
|
|
3043
3091
|
return {
|
|
3044
3092
|
name,
|
|
3093
|
+
title: sanitizeToolTitle(record?.title ?? hints?.title, name),
|
|
3045
3094
|
description: typeof description === "string" ? description : void 0,
|
|
3095
|
+
annotations: hints ? {
|
|
3096
|
+
readOnly: hints.readOnlyHint,
|
|
3097
|
+
destructive: hints.destructiveHint,
|
|
3098
|
+
openWorld: hints.openWorldHint
|
|
3099
|
+
} : void 0,
|
|
3046
3100
|
inputSchema: inputSchema?.jsonSchema
|
|
3047
3101
|
};
|
|
3048
3102
|
}
|
|
@@ -3171,18 +3225,12 @@ const claudeAdapter = {
|
|
|
3171
3225
|
};
|
|
3172
3226
|
//#endregion
|
|
3173
3227
|
//#region src/engines/codex/connect.ts
|
|
3174
|
-
/**
|
|
3175
|
-
* The operator's environment reaches the child whole — WorkerDeck resolves no credential of its
|
|
3176
|
-
* own — and the profile's CODEX_HOME is the one key it pins, last, so a profile always wins over
|
|
3177
|
-
* an inherited value. Every path that spawns or connects to an app-server goes through here.
|
|
3178
|
-
*/
|
|
3179
3228
|
function codexChildEnv(base, codexHome) {
|
|
3180
3229
|
const env = {};
|
|
3181
3230
|
for (const [key, value] of Object.entries(base)) if (value !== void 0) env[key] = value;
|
|
3182
3231
|
if (codexHome) env.CODEX_HOME = codexHome;
|
|
3183
3232
|
return env;
|
|
3184
3233
|
}
|
|
3185
|
-
/** `experimentalApi` gates the granular approval policy and there is no non-experimental fallback, so it is not per-call-site. */
|
|
3186
3234
|
const INITIALIZE_PARAMS = {
|
|
3187
3235
|
clientInfo: {
|
|
3188
3236
|
name: "workerdeck",
|
|
@@ -4903,6 +4951,13 @@ var CodexRunner = class {
|
|
|
4903
4951
|
this.#emitToolUse(id, "CodexImageView", { path: item.path }, agent);
|
|
4904
4952
|
this.#emitToolResult(id, item.path, false, void 0, agent?.toolUseId ?? null);
|
|
4905
4953
|
},
|
|
4954
|
+
contextCompaction: (_item, _active, id, agent) => {
|
|
4955
|
+
this.#emit({
|
|
4956
|
+
type: "context_compacted",
|
|
4957
|
+
uuid: id,
|
|
4958
|
+
parentToolUseId: agent?.toolUseId ?? null
|
|
4959
|
+
});
|
|
4960
|
+
},
|
|
4906
4961
|
subAgentActivity: (item, _active, id, agent) => {
|
|
4907
4962
|
if (this.#replayingHistory) {
|
|
4908
4963
|
if (item.kind !== "started") return;
|
|
@@ -5094,33 +5149,6 @@ var CodexRunner = class {
|
|
|
5094
5149
|
};
|
|
5095
5150
|
//#endregion
|
|
5096
5151
|
//#region src/engines/codex/catalog.ts
|
|
5097
|
-
/**
|
|
5098
|
-
* The Codex engine's model catalog, seeded from the binary's own embedded model
|
|
5099
|
-
* table (see `provenance` for the version) — that table, not the SDK's stale
|
|
5100
|
-
* `ModelReasoningEffort` union, is the truth about which reasoning efforts each
|
|
5101
|
-
* model takes. Mapping decisions: the internal `codex-auto-review` row is dropped
|
|
5102
|
-
* (the codex analogue of the CLI's `default` sentinel), `primary` mirrors the
|
|
5103
|
-
* binary's own `visibility` field so both UIs group the way codex's picker does,
|
|
5104
|
-
* and `reasoningEfforts` carries `supported_reasoning_levels` verbatim — `max`
|
|
5105
|
-
* and `ultra` go beyond the SDK union, so trust the binary and keep strings open.
|
|
5106
|
-
*
|
|
5107
|
-
* **Refresh procedure** (release checklist): extract the embedded JSON from the
|
|
5108
|
-
* platform binary and diff. The two-hop resolve is NOT optional — under pnpm's
|
|
5109
|
-
* strict layout the platform package is a dependency of `@openai/codex` and
|
|
5110
|
-
* resolves only from that wrapper's location (MODULE_NOT_FOUND otherwise), the
|
|
5111
|
-
* same two hops `resolveBundledCodexExecutable` makes.
|
|
5112
|
-
*
|
|
5113
|
-
* node -e 'const d=require("fs").readFileSync(process.argv[1]);
|
|
5114
|
-
* const s=d.indexOf(`{\n "models": [`);
|
|
5115
|
-
* let i=s,n=0; do{n+=(d[i]===123)-(d[i]===125);i++}while(n);
|
|
5116
|
-
* const c=JSON.parse(d.slice(s,i));
|
|
5117
|
-
* for(const m of c.models) console.log(m.slug, m.display_name,
|
|
5118
|
-
* m.visibility, m.supported_reasoning_levels.map(l=>l.effort).join(","))'\
|
|
5119
|
-
* "$(node -p 'const{createRequire}=require("module");
|
|
5120
|
-
* const w=require.resolve("@openai/codex/package.json");
|
|
5121
|
-
* createRequire(w).resolve("@openai/codex-darwin-arm64/package.json")
|
|
5122
|
-
* .replace("package.json","vendor/aarch64-apple-darwin/bin/codex")')"
|
|
5123
|
-
*/
|
|
5124
5152
|
const CODEX_CATALOG = {
|
|
5125
5153
|
provenance: "embedded model presets of @openai/codex@0.151.0 (darwin-arm64 binary), re-extracted 2026-09-02 and unchanged since 0.149.0",
|
|
5126
5154
|
models: [
|