la-machina-engine 0.7.3 → 0.7.5
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/dist/index.cjs +595 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +411 -44
- package/dist/index.d.ts +411 -44
- package/dist/index.js +593 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -841,6 +841,7 @@ __export(index_exports, {
|
|
|
841
841
|
EpisodicMemory: () => EpisodicMemory,
|
|
842
842
|
Hippocampus: () => Hippocampus,
|
|
843
843
|
InlineSkillSource: () => InlineSkillSource,
|
|
844
|
+
InspectWriter: () => InspectWriter,
|
|
844
845
|
LocalStorageAdapter: () => LocalStorageAdapter,
|
|
845
846
|
MAX_ATTEMPTS: () => MAX_ATTEMPTS,
|
|
846
847
|
McpClient: () => McpClient,
|
|
@@ -848,6 +849,7 @@ __export(index_exports, {
|
|
|
848
849
|
McpManager: () => McpManager,
|
|
849
850
|
McpProtocolError: () => McpProtocolError,
|
|
850
851
|
McpTimeoutError: () => McpTimeoutError,
|
|
852
|
+
NULL_INSPECT_WRITER: () => NULL_INSPECT_WRITER,
|
|
851
853
|
NodeBackgroundExecutor: () => NodeBackgroundExecutor,
|
|
852
854
|
NotImplementedError: () => NotImplementedError,
|
|
853
855
|
PlanSchema: () => PlanSchema,
|
|
@@ -1022,6 +1024,10 @@ var DEFAULTS = {
|
|
|
1022
1024
|
enableRollback: true,
|
|
1023
1025
|
maxPlanSteps: 20,
|
|
1024
1026
|
agentMaxTurns: 15
|
|
1027
|
+
},
|
|
1028
|
+
inspect: {
|
|
1029
|
+
enabled: true,
|
|
1030
|
+
redactBaseURL: false
|
|
1025
1031
|
}
|
|
1026
1032
|
};
|
|
1027
1033
|
|
|
@@ -1257,6 +1263,11 @@ var RunnerConfigResolved = import_zod.z.object({
|
|
|
1257
1263
|
url: import_zod.z.string().url(),
|
|
1258
1264
|
secret: import_zod.z.string().min(1, "runner.secret cannot be empty")
|
|
1259
1265
|
}).strict();
|
|
1266
|
+
var InspectConfigResolved = import_zod.z.object({
|
|
1267
|
+
enabled: import_zod.z.boolean(),
|
|
1268
|
+
redactBaseURL: import_zod.z.boolean()
|
|
1269
|
+
}).strict();
|
|
1270
|
+
var InspectConfigUser = InspectConfigResolved.partial();
|
|
1260
1271
|
var ResolvedConfigSchema = import_zod.z.object({
|
|
1261
1272
|
model: ModelConfigResolved,
|
|
1262
1273
|
storage: StorageConfigResolved,
|
|
@@ -1275,7 +1286,8 @@ var ResolvedConfigSchema = import_zod.z.object({
|
|
|
1275
1286
|
orchestrator: OrchestratorConfigResolved,
|
|
1276
1287
|
runner: RunnerConfigResolved.optional(),
|
|
1277
1288
|
api: ApiConfigResolved.optional(),
|
|
1278
|
-
knowledge: KnowledgeConfigResolved.optional()
|
|
1289
|
+
knowledge: KnowledgeConfigResolved.optional(),
|
|
1290
|
+
inspect: InspectConfigResolved
|
|
1279
1291
|
}).strict();
|
|
1280
1292
|
var R2ConfigUser = R2ConfigResolved.partial();
|
|
1281
1293
|
var ModelConfigUser = ModelConfigResolved.partial();
|
|
@@ -1352,7 +1364,8 @@ var UserConfigSchema = import_zod.z.object({
|
|
|
1352
1364
|
orchestrator: OrchestratorConfigUser.optional(),
|
|
1353
1365
|
runner: RunnerConfigUser.optional(),
|
|
1354
1366
|
api: ApiConfigUser.optional(),
|
|
1355
|
-
knowledge: KnowledgeConfigUser.optional()
|
|
1367
|
+
knowledge: KnowledgeConfigUser.optional(),
|
|
1368
|
+
inspect: InspectConfigUser.optional()
|
|
1356
1369
|
}).strict();
|
|
1357
1370
|
|
|
1358
1371
|
// src/config/merge.ts
|
|
@@ -1817,7 +1830,11 @@ var AnthropicClient = class {
|
|
|
1817
1830
|
messages: request.messages,
|
|
1818
1831
|
stream: true,
|
|
1819
1832
|
...request.system !== void 0 ? { system: request.system } : {},
|
|
1820
|
-
...request.tools !== void 0 ? { tools: request.tools } : {}
|
|
1833
|
+
...request.tools !== void 0 ? { tools: request.tools } : {},
|
|
1834
|
+
// Plan 025 — `'required'` maps to Anthropic's `tool_choice: { type: 'any' }`,
|
|
1835
|
+
// which forces the model to call SOME tool but doesn't pin which.
|
|
1836
|
+
// `'auto'` is the SDK default — omit to let it through unchanged.
|
|
1837
|
+
...request.toolChoice === "required" ? { tool_choice: { type: "any" } } : {}
|
|
1821
1838
|
};
|
|
1822
1839
|
const requestOptions = {};
|
|
1823
1840
|
if (betas.length > 0) {
|
|
@@ -1999,6 +2016,9 @@ var AISdkAdapter = class {
|
|
|
1999
2016
|
tools,
|
|
2000
2017
|
...request.maxTokens !== void 0 ? { maxOutputTokens: request.maxTokens } : {},
|
|
2001
2018
|
...request.temperature !== void 0 ? { temperature: request.temperature } : {},
|
|
2019
|
+
// Plan 025 — pass through `'required'` so the AI SDK forwards it
|
|
2020
|
+
// to the provider as that provider's "force tool call" flag.
|
|
2021
|
+
...request.toolChoice === "required" ? { toolChoice: "required" } : {},
|
|
2002
2022
|
maxRetries: this.options.maxRetries ?? 2
|
|
2003
2023
|
});
|
|
2004
2024
|
for await (const event of result.fullStream) {
|
|
@@ -2618,6 +2638,17 @@ function ensureToolResultPairing(messages) {
|
|
|
2618
2638
|
return messages;
|
|
2619
2639
|
}
|
|
2620
2640
|
|
|
2641
|
+
// src/engine/lastTurnGuard.ts
|
|
2642
|
+
init_cjs_shims();
|
|
2643
|
+
var LAST_TURN_INSTRUCTION_JSON = "SYSTEM NOTE: This is your final allowed turn. Emit ONLY the JSON object that satisfies the output schema in the system prompt. Do not call any more tools. Do not write any explanation, narration, or markdown \u2014 only the raw JSON.";
|
|
2644
|
+
var LAST_TURN_INSTRUCTION_TEXT = "SYSTEM NOTE: This is your final allowed turn. Stop calling tools and deliver your final answer now. The next turn will not happen.";
|
|
2645
|
+
function lastTurnInstruction(outputFormat) {
|
|
2646
|
+
return outputFormat === "json" ? LAST_TURN_INSTRUCTION_JSON : LAST_TURN_INSTRUCTION_TEXT;
|
|
2647
|
+
}
|
|
2648
|
+
function shouldInjectLastTurnInstruction(opts) {
|
|
2649
|
+
return opts.turnCount + 1 === opts.maxTurns;
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2621
2652
|
// src/compact/compactor.ts
|
|
2622
2653
|
init_cjs_shims();
|
|
2623
2654
|
|
|
@@ -3007,6 +3038,30 @@ function isSubagentPausedError(err) {
|
|
|
3007
3038
|
}
|
|
3008
3039
|
|
|
3009
3040
|
// src/engine/agentLoop.ts
|
|
3041
|
+
async function emitInspectTurn(args) {
|
|
3042
|
+
const writer = args.inspect;
|
|
3043
|
+
if (writer === void 0) return;
|
|
3044
|
+
const completedAt = Date.now();
|
|
3045
|
+
const cacheCreate = args.endTokens.cacheCreationInput !== void 0 ? args.endTokens.cacheCreationInput - (args.startTokens.cacheCreationInput ?? 0) : void 0;
|
|
3046
|
+
const cacheRead = args.endTokens.cacheReadInput !== void 0 ? args.endTokens.cacheReadInput - (args.startTokens.cacheReadInput ?? 0) : void 0;
|
|
3047
|
+
const delta = {
|
|
3048
|
+
input: args.endTokens.input - args.startTokens.input,
|
|
3049
|
+
output: args.endTokens.output - args.startTokens.output,
|
|
3050
|
+
...cacheCreate !== void 0 ? { cacheCreationInput: cacheCreate } : {},
|
|
3051
|
+
...cacheRead !== void 0 ? { cacheReadInput: cacheRead } : {}
|
|
3052
|
+
};
|
|
3053
|
+
await writer.appendTurn({
|
|
3054
|
+
turn: args.turn,
|
|
3055
|
+
startedAt: args.startedAt,
|
|
3056
|
+
completedAt,
|
|
3057
|
+
durationMs: completedAt - args.startedAt,
|
|
3058
|
+
tokensUsed: delta,
|
|
3059
|
+
stopReason: args.stopReason,
|
|
3060
|
+
toolCallsCount: args.toolCallsCount,
|
|
3061
|
+
...cacheCreate !== void 0 ? { cacheCreationInput: cacheCreate } : {},
|
|
3062
|
+
...cacheRead !== void 0 ? { cacheReadInput: cacheRead } : {}
|
|
3063
|
+
});
|
|
3064
|
+
}
|
|
3010
3065
|
var DEFAULT_COMPACTION = {
|
|
3011
3066
|
strategy: "drop-middle",
|
|
3012
3067
|
threshold: 0.85,
|
|
@@ -3049,6 +3104,8 @@ async function agentLoop(options) {
|
|
|
3049
3104
|
};
|
|
3050
3105
|
for (; ; ) {
|
|
3051
3106
|
compactedThisTurn = false;
|
|
3107
|
+
const turnStartedAt = Date.now();
|
|
3108
|
+
const turnStartTokens = { ...ctx.getTokensUsed() };
|
|
3052
3109
|
if (options.runSignal?.aborted === true) {
|
|
3053
3110
|
return failed(new RunTimeoutError(options.runTimeoutMs ?? 0), transcript);
|
|
3054
3111
|
}
|
|
@@ -3058,6 +3115,12 @@ async function agentLoop(options) {
|
|
|
3058
3115
|
if (options.tokenBudget !== void 0) {
|
|
3059
3116
|
const used = ctx.getTokensUsed();
|
|
3060
3117
|
if (used.input + used.output >= options.tokenBudget) {
|
|
3118
|
+
await options.inspect?.appendEvent({
|
|
3119
|
+
type: "budget_hit",
|
|
3120
|
+
totalTokens: used.input + used.output,
|
|
3121
|
+
budget: options.tokenBudget,
|
|
3122
|
+
ts: Date.now()
|
|
3123
|
+
});
|
|
3061
3124
|
return {
|
|
3062
3125
|
status: "done",
|
|
3063
3126
|
output: lastAssistantText || "[Token budget exhausted]",
|
|
@@ -3109,15 +3172,37 @@ async function agentLoop(options) {
|
|
|
3109
3172
|
const toolCalls = [];
|
|
3110
3173
|
let stopReason = null;
|
|
3111
3174
|
let turnUsage = { input: 0, output: 0 };
|
|
3175
|
+
let messagesForApi = messages;
|
|
3176
|
+
if (shouldInjectLastTurnInstruction({
|
|
3177
|
+
turnCount: ctx.getTurnCount(),
|
|
3178
|
+
maxTurns: ctx.getMaxTurns()
|
|
3179
|
+
})) {
|
|
3180
|
+
const instruction = lastTurnInstruction(options.outputFormat);
|
|
3181
|
+
messagesForApi = [
|
|
3182
|
+
...messages,
|
|
3183
|
+
{
|
|
3184
|
+
role: "user",
|
|
3185
|
+
content: [{ type: "text", text: instruction }]
|
|
3186
|
+
}
|
|
3187
|
+
];
|
|
3188
|
+
await options.inspect?.appendEvent({
|
|
3189
|
+
type: "last_turn_guard",
|
|
3190
|
+
turn: ctx.getTurnCount(),
|
|
3191
|
+
outputFormat: options.outputFormat ?? "text",
|
|
3192
|
+
instruction,
|
|
3193
|
+
ts: Date.now()
|
|
3194
|
+
});
|
|
3195
|
+
}
|
|
3112
3196
|
const normalizedMessages = normalizeMessages(
|
|
3113
|
-
|
|
3197
|
+
messagesForApi
|
|
3114
3198
|
);
|
|
3115
3199
|
try {
|
|
3116
3200
|
for await (const event of client.streamMessage({
|
|
3117
3201
|
messages: normalizedMessages,
|
|
3118
3202
|
system,
|
|
3119
3203
|
tools: anthropicTools,
|
|
3120
|
-
...escalatedMaxTokens !== void 0 ? { maxTokens: escalatedMaxTokens } : {}
|
|
3204
|
+
...escalatedMaxTokens !== void 0 ? { maxTokens: escalatedMaxTokens } : {},
|
|
3205
|
+
...options.toolChoice !== void 0 ? { toolChoice: options.toolChoice } : {}
|
|
3121
3206
|
})) {
|
|
3122
3207
|
const handled = consumeEvent(event);
|
|
3123
3208
|
if (handled.text !== void 0) textBlocks.push(handled.text);
|
|
@@ -3141,6 +3226,13 @@ async function agentLoop(options) {
|
|
|
3141
3226
|
system
|
|
3142
3227
|
});
|
|
3143
3228
|
if (emergency.compacted) {
|
|
3229
|
+
await options.inspect?.appendEvent({
|
|
3230
|
+
type: "compaction_413",
|
|
3231
|
+
turn: ctx.getTurnCount(),
|
|
3232
|
+
droppedMessages: messages.length - emergency.messages.length,
|
|
3233
|
+
strategy: compactionConfig.strategy,
|
|
3234
|
+
ts: Date.now()
|
|
3235
|
+
});
|
|
3144
3236
|
ctx.rehydrate({
|
|
3145
3237
|
messages: emergency.messages,
|
|
3146
3238
|
turnCount: ctx.getTurnCount(),
|
|
@@ -3168,6 +3260,14 @@ async function agentLoop(options) {
|
|
|
3168
3260
|
}
|
|
3169
3261
|
const retryAfter = err instanceof RateLimitError && err.retryAfterMs ? err.retryAfterMs : BASE_BACKOFF_MS * Math.pow(2, apiRetryCount - 1);
|
|
3170
3262
|
const delay = Math.min(retryAfter, 3e4);
|
|
3263
|
+
await options.inspect?.appendEvent({
|
|
3264
|
+
type: "api_retry",
|
|
3265
|
+
turn: ctx.getTurnCount(),
|
|
3266
|
+
status: err instanceof Error && "status" in err ? err.status ?? null : null,
|
|
3267
|
+
attempt: apiRetryCount,
|
|
3268
|
+
delayMs: delay,
|
|
3269
|
+
ts: Date.now()
|
|
3270
|
+
});
|
|
3171
3271
|
await new Promise((r) => setTimeout(r, delay));
|
|
3172
3272
|
continue;
|
|
3173
3273
|
}
|
|
@@ -3319,6 +3419,15 @@ async function agentLoop(options) {
|
|
|
3319
3419
|
apiRetryCount = 0;
|
|
3320
3420
|
consecutive529 = 0;
|
|
3321
3421
|
await ctx.endTurn();
|
|
3422
|
+
await emitInspectTurn({
|
|
3423
|
+
inspect: options.inspect,
|
|
3424
|
+
turn: ctx.getTurnCount() - 1,
|
|
3425
|
+
startedAt: turnStartedAt,
|
|
3426
|
+
startTokens: turnStartTokens,
|
|
3427
|
+
endTokens: ctx.getTokensUsed(),
|
|
3428
|
+
stopReason,
|
|
3429
|
+
toolCallsCount: toolCallsToDispatch.length
|
|
3430
|
+
});
|
|
3322
3431
|
await fireProgress("idle");
|
|
3323
3432
|
if (options.postTurnHooks && options.postTurnHooks.length > 0) {
|
|
3324
3433
|
await dispatchHooks(options.postTurnHooks, {
|
|
@@ -3350,6 +3459,15 @@ async function agentLoop(options) {
|
|
|
3350
3459
|
continue;
|
|
3351
3460
|
}
|
|
3352
3461
|
await ctx.endTurn();
|
|
3462
|
+
await emitInspectTurn({
|
|
3463
|
+
inspect: options.inspect,
|
|
3464
|
+
turn: ctx.getTurnCount() - 1,
|
|
3465
|
+
startedAt: turnStartedAt,
|
|
3466
|
+
startTokens: turnStartTokens,
|
|
3467
|
+
endTokens: ctx.getTokensUsed(),
|
|
3468
|
+
stopReason,
|
|
3469
|
+
toolCallsCount: 0
|
|
3470
|
+
});
|
|
3353
3471
|
if (options.postTurnHooks && options.postTurnHooks.length > 0) {
|
|
3354
3472
|
await dispatchHooks(options.postTurnHooks, {
|
|
3355
3473
|
runId: ctx.runId,
|
|
@@ -3376,11 +3494,25 @@ async function agentLoop(options) {
|
|
|
3376
3494
|
if (!maxTokensEscalated) {
|
|
3377
3495
|
maxTokensEscalated = true;
|
|
3378
3496
|
escalatedMaxTokens = ESCALATED_MAX_TOKENS;
|
|
3497
|
+
await options.inspect?.appendEvent({
|
|
3498
|
+
type: "recovery_max_tokens",
|
|
3499
|
+
turn: ctx.getTurnCount(),
|
|
3500
|
+
attempt: 0,
|
|
3501
|
+
escalatedTo: ESCALATED_MAX_TOKENS,
|
|
3502
|
+
ts: Date.now()
|
|
3503
|
+
});
|
|
3379
3504
|
continue;
|
|
3380
3505
|
}
|
|
3381
3506
|
if (recoveryCount < MAX_OUTPUT_TOKENS_RECOVERY_LIMIT) {
|
|
3382
3507
|
recoveryCount++;
|
|
3383
3508
|
escalatedMaxTokens = void 0;
|
|
3509
|
+
await options.inspect?.appendEvent({
|
|
3510
|
+
type: "recovery_max_tokens",
|
|
3511
|
+
turn: ctx.getTurnCount(),
|
|
3512
|
+
attempt: recoveryCount,
|
|
3513
|
+
escalatedTo: 0,
|
|
3514
|
+
ts: Date.now()
|
|
3515
|
+
});
|
|
3384
3516
|
await ctx.addUserMessage(
|
|
3385
3517
|
"Output token limit hit. Resume directly \u2014 no apology, no recap of what you were doing. Pick up mid-thought if that is where the cut happened. Break remaining work into smaller pieces."
|
|
3386
3518
|
);
|
|
@@ -3668,6 +3800,9 @@ var RunContext = class {
|
|
|
3668
3800
|
getTurnCount() {
|
|
3669
3801
|
return this.turnCount;
|
|
3670
3802
|
}
|
|
3803
|
+
getMaxTurns() {
|
|
3804
|
+
return this.maxTurns;
|
|
3805
|
+
}
|
|
3671
3806
|
getTokensUsed() {
|
|
3672
3807
|
return this.tokensUsed;
|
|
3673
3808
|
}
|
|
@@ -4692,6 +4827,7 @@ function createSendMessageTool(options) {
|
|
|
4692
4827
|
|
|
4693
4828
|
// src/engine/engine.ts
|
|
4694
4829
|
init_contract();
|
|
4830
|
+
var import_zod_to_json_schema4 = require("zod-to-json-schema");
|
|
4695
4831
|
|
|
4696
4832
|
// src/tools/fileEdit.ts
|
|
4697
4833
|
init_cjs_shims();
|
|
@@ -9657,6 +9793,227 @@ var TranscriptReader = class {
|
|
|
9657
9793
|
}
|
|
9658
9794
|
};
|
|
9659
9795
|
|
|
9796
|
+
// src/engine/runToolFilter.ts
|
|
9797
|
+
init_cjs_shims();
|
|
9798
|
+
function applyRunToolFilter(registry, options) {
|
|
9799
|
+
const stripAll = options.toolChoice === "none" || options.tools !== void 0 && options.tools.length === 0;
|
|
9800
|
+
if (stripAll) {
|
|
9801
|
+
if (options.toolChoice === "required") {
|
|
9802
|
+
throw new EngineError(
|
|
9803
|
+
"ERR_TOOL_CHOICE_CONFLICT",
|
|
9804
|
+
"toolChoice: 'required' is incompatible with an empty tool set (received tools: [] or toolChoice: 'none')."
|
|
9805
|
+
);
|
|
9806
|
+
}
|
|
9807
|
+
for (const tool of registry.list()) {
|
|
9808
|
+
registry.unregister(tool.name);
|
|
9809
|
+
}
|
|
9810
|
+
return;
|
|
9811
|
+
}
|
|
9812
|
+
if (options.tools === void 0) return;
|
|
9813
|
+
const allow = new Set(options.tools);
|
|
9814
|
+
for (const tool of registry.list()) {
|
|
9815
|
+
if (!allow.has(tool.name)) registry.unregister(tool.name);
|
|
9816
|
+
}
|
|
9817
|
+
if (options.toolChoice === "required" && registry.count() === 0) {
|
|
9818
|
+
throw new EngineError(
|
|
9819
|
+
"ERR_TOOL_CHOICE_CONFLICT",
|
|
9820
|
+
"toolChoice: 'required' was requested but no tools matched the per-run allowlist after applying config filters."
|
|
9821
|
+
);
|
|
9822
|
+
}
|
|
9823
|
+
}
|
|
9824
|
+
|
|
9825
|
+
// src/inspect/writer.ts
|
|
9826
|
+
init_cjs_shims();
|
|
9827
|
+
var InspectWriter = class {
|
|
9828
|
+
storage;
|
|
9829
|
+
logger;
|
|
9830
|
+
enabled;
|
|
9831
|
+
/** Subdirectory holding all inspect files. Constant per writer. */
|
|
9832
|
+
dir;
|
|
9833
|
+
constructor(opts) {
|
|
9834
|
+
this.storage = opts.storage;
|
|
9835
|
+
if (opts.logger !== void 0) this.logger = opts.logger;
|
|
9836
|
+
this.enabled = opts.enabled;
|
|
9837
|
+
this.dir = `${opts.logPath}/inspect`;
|
|
9838
|
+
}
|
|
9839
|
+
/**
|
|
9840
|
+
* Write the eight start-snapshot files atomically (well, sequentially —
|
|
9841
|
+
* R2 has no multi-object atomic; failures partially-write and the
|
|
9842
|
+
* fail-soft path logs each one).
|
|
9843
|
+
*/
|
|
9844
|
+
async writeStartSnapshot(input) {
|
|
9845
|
+
if (!this.enabled) return;
|
|
9846
|
+
await this.safeWrite("system-prompt.txt", input.systemPrompt);
|
|
9847
|
+
await this.safeWriteJson("tools.json", input.tools);
|
|
9848
|
+
await this.safeWriteJson("run-options.json", input.runOptions);
|
|
9849
|
+
await this.safeWriteJson("model-config.json", input.modelConfig);
|
|
9850
|
+
if (input.skills !== void 0) {
|
|
9851
|
+
await this.safeWriteJson("skills.json", input.skills);
|
|
9852
|
+
}
|
|
9853
|
+
if (input.mcpServers !== void 0) {
|
|
9854
|
+
await this.safeWriteJson("mcp-servers.json", input.mcpServers);
|
|
9855
|
+
}
|
|
9856
|
+
if (input.apiServices !== void 0) {
|
|
9857
|
+
await this.safeWriteJson("api-services.json", input.apiServices);
|
|
9858
|
+
}
|
|
9859
|
+
if (input.knowledge !== void 0) {
|
|
9860
|
+
await this.safeWriteJson("knowledge-scope.json", input.knowledge);
|
|
9861
|
+
}
|
|
9862
|
+
}
|
|
9863
|
+
/** Append one event line to events.jsonl. */
|
|
9864
|
+
async appendEvent(event) {
|
|
9865
|
+
if (!this.enabled) return;
|
|
9866
|
+
await this.safeAppend("events.jsonl", JSON.stringify(event) + "\n");
|
|
9867
|
+
}
|
|
9868
|
+
/** Append one row to turns.jsonl. */
|
|
9869
|
+
async appendTurn(row) {
|
|
9870
|
+
if (!this.enabled) return;
|
|
9871
|
+
await this.safeAppend("turns.jsonl", JSON.stringify(row) + "\n");
|
|
9872
|
+
}
|
|
9873
|
+
/** Write the terminal `tools-summary.json` once at run end. */
|
|
9874
|
+
async writeToolsSummary(summary) {
|
|
9875
|
+
if (!this.enabled) return;
|
|
9876
|
+
await this.safeWriteJson("tools-summary.json", summary);
|
|
9877
|
+
}
|
|
9878
|
+
// ---------- private fail-soft helpers ----------
|
|
9879
|
+
async safeWrite(name, content) {
|
|
9880
|
+
try {
|
|
9881
|
+
await this.storage.writeFile(`${this.dir}/${name}`, content);
|
|
9882
|
+
} catch (err) {
|
|
9883
|
+
this.logFailure("writeFile", name, err);
|
|
9884
|
+
}
|
|
9885
|
+
}
|
|
9886
|
+
async safeWriteJson(name, value) {
|
|
9887
|
+
try {
|
|
9888
|
+
await this.storage.writeFile(`${this.dir}/${name}`, JSON.stringify(value, null, 2));
|
|
9889
|
+
} catch (err) {
|
|
9890
|
+
this.logFailure("writeFile (json)", name, err);
|
|
9891
|
+
}
|
|
9892
|
+
}
|
|
9893
|
+
async safeAppend(name, line) {
|
|
9894
|
+
try {
|
|
9895
|
+
await this.storage.appendFile(`${this.dir}/${name}`, line);
|
|
9896
|
+
} catch (err) {
|
|
9897
|
+
this.logFailure("appendFile", name, err);
|
|
9898
|
+
}
|
|
9899
|
+
}
|
|
9900
|
+
logFailure(op, name, err) {
|
|
9901
|
+
if (this.logger === void 0) return;
|
|
9902
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
9903
|
+
this.logger.warn?.("inspect-writer failed", {
|
|
9904
|
+
op,
|
|
9905
|
+
file: `${this.dir}/${name}`,
|
|
9906
|
+
error: msg
|
|
9907
|
+
});
|
|
9908
|
+
}
|
|
9909
|
+
};
|
|
9910
|
+
var NULL_INSPECT_WRITER = {
|
|
9911
|
+
writeStartSnapshot: async () => void 0,
|
|
9912
|
+
appendEvent: async () => void 0,
|
|
9913
|
+
appendTurn: async () => void 0,
|
|
9914
|
+
writeToolsSummary: async () => void 0
|
|
9915
|
+
};
|
|
9916
|
+
|
|
9917
|
+
// src/inspect/scrub.ts
|
|
9918
|
+
init_cjs_shims();
|
|
9919
|
+
var import_zod_to_json_schema3 = require("zod-to-json-schema");
|
|
9920
|
+
function scrubModelConfig(cfg, opts = { redactBaseURL: false }) {
|
|
9921
|
+
const out = {
|
|
9922
|
+
schemaVersion: 1,
|
|
9923
|
+
provider: cfg.provider,
|
|
9924
|
+
modelId: cfg.modelId
|
|
9925
|
+
};
|
|
9926
|
+
if (!opts.redactBaseURL && cfg.baseURL !== void 0) out.baseURL = cfg.baseURL;
|
|
9927
|
+
if (cfg.temperature !== void 0) out.temperature = cfg.temperature;
|
|
9928
|
+
if (cfg.maxTokens !== void 0) out.maxTokens = cfg.maxTokens;
|
|
9929
|
+
if (cfg.maxRetries !== void 0) out.maxRetries = cfg.maxRetries;
|
|
9930
|
+
return out;
|
|
9931
|
+
}
|
|
9932
|
+
function scrubRunOptions(opts) {
|
|
9933
|
+
const out = {
|
|
9934
|
+
schemaVersion: 1,
|
|
9935
|
+
runId: opts.runId ?? "",
|
|
9936
|
+
nodeId: opts.nodeId,
|
|
9937
|
+
task: opts.task
|
|
9938
|
+
};
|
|
9939
|
+
if (opts.maxTurns !== void 0) out.maxTurns = opts.maxTurns;
|
|
9940
|
+
if (opts.outputFormat !== void 0) out.outputFormat = opts.outputFormat;
|
|
9941
|
+
if (opts.outputSchema !== void 0) out.outputSchema = serializeOutputSchema(opts.outputSchema);
|
|
9942
|
+
if (opts.tools !== void 0) out.tools = [...opts.tools];
|
|
9943
|
+
if (opts.toolChoice !== void 0) out.toolChoice = opts.toolChoice;
|
|
9944
|
+
if (opts.tokenBudget !== void 0) out.tokenBudget = opts.tokenBudget;
|
|
9945
|
+
if (opts.knowledge !== void 0) {
|
|
9946
|
+
const k = {};
|
|
9947
|
+
if (opts.knowledge.folders !== void 0) k.folders = [...opts.knowledge.folders];
|
|
9948
|
+
if (opts.knowledge.external !== void 0) {
|
|
9949
|
+
k.external = opts.knowledge.external.map((e) => {
|
|
9950
|
+
const link = { url: e.url };
|
|
9951
|
+
if (e.description !== void 0) link.description = e.description;
|
|
9952
|
+
return link;
|
|
9953
|
+
});
|
|
9954
|
+
}
|
|
9955
|
+
out.knowledge = k;
|
|
9956
|
+
}
|
|
9957
|
+
if (opts.api !== void 0 && opts.api.services !== void 0) {
|
|
9958
|
+
out.api = {
|
|
9959
|
+
services: opts.api.services.map((s) => {
|
|
9960
|
+
const svc = { name: s.name };
|
|
9961
|
+
if (s.description !== void 0) svc.description = s.description;
|
|
9962
|
+
if (s.baseUrl !== void 0) svc.baseUrl = s.baseUrl;
|
|
9963
|
+
return svc;
|
|
9964
|
+
})
|
|
9965
|
+
};
|
|
9966
|
+
}
|
|
9967
|
+
if (opts.skills !== void 0) {
|
|
9968
|
+
out.skills = opts.skills.map((s) => ({
|
|
9969
|
+
name: s.name,
|
|
9970
|
+
description: s.description ?? "",
|
|
9971
|
+
hasBody: "body" in s && typeof s.body === "string",
|
|
9972
|
+
hasUrl: "url" in s && typeof s.url === "string"
|
|
9973
|
+
}));
|
|
9974
|
+
}
|
|
9975
|
+
if (opts.compaction !== void 0) out.compaction = opts.compaction;
|
|
9976
|
+
if (opts.context !== void 0) out.context = { ...opts.context };
|
|
9977
|
+
return out;
|
|
9978
|
+
}
|
|
9979
|
+
function serializeOutputSchema(schema) {
|
|
9980
|
+
if (schema === null || typeof schema !== "object") return schema;
|
|
9981
|
+
const candidate = schema;
|
|
9982
|
+
if (candidate._def !== void 0 && typeof candidate.safeParse === "function") {
|
|
9983
|
+
try {
|
|
9984
|
+
return (0, import_zod_to_json_schema3.zodToJsonSchema)(schema, {
|
|
9985
|
+
target: "jsonSchema7",
|
|
9986
|
+
$refStrategy: "none"
|
|
9987
|
+
});
|
|
9988
|
+
} catch {
|
|
9989
|
+
return { error: "failed to serialize Zod schema for inspect" };
|
|
9990
|
+
}
|
|
9991
|
+
}
|
|
9992
|
+
return schema;
|
|
9993
|
+
}
|
|
9994
|
+
function scrubSkills(skills) {
|
|
9995
|
+
return {
|
|
9996
|
+
schemaVersion: 1,
|
|
9997
|
+
skills: skills.map((s) => ({
|
|
9998
|
+
name: s.name,
|
|
9999
|
+
description: s.description ?? "",
|
|
10000
|
+
hasPages: s.hasPages ?? false
|
|
10001
|
+
}))
|
|
10002
|
+
};
|
|
10003
|
+
}
|
|
10004
|
+
function scrubApiServices(services) {
|
|
10005
|
+
return {
|
|
10006
|
+
schemaVersion: 1,
|
|
10007
|
+
services: services.map((s) => {
|
|
10008
|
+
const out = { name: s.name };
|
|
10009
|
+
if (s.description !== void 0) out.description = s.description;
|
|
10010
|
+
if (s.baseUrl !== void 0) out.baseUrl = s.baseUrl;
|
|
10011
|
+
if (s.methods !== void 0) out.methods = s.methods.map((m) => m.name);
|
|
10012
|
+
return out;
|
|
10013
|
+
})
|
|
10014
|
+
};
|
|
10015
|
+
}
|
|
10016
|
+
|
|
9660
10017
|
// src/engine/rehydrate.ts
|
|
9661
10018
|
init_cjs_shims();
|
|
9662
10019
|
function rebuildMessagesFromEntries(entries) {
|
|
@@ -10133,6 +10490,38 @@ var Engine = class {
|
|
|
10133
10490
|
...knowledgeRuntime !== void 0 ? { knowledge: knowledgeRuntime } : {},
|
|
10134
10491
|
...this.internals.fetch !== void 0 ? { fetch: this.internals.fetch } : {}
|
|
10135
10492
|
});
|
|
10493
|
+
applyRunToolFilter(registry, options);
|
|
10494
|
+
const inspect = this.buildInspectWriter(storage.workspace, logPath);
|
|
10495
|
+
await inspect.writeStartSnapshot({
|
|
10496
|
+
systemPrompt,
|
|
10497
|
+
tools: this.snapshotTools(registry, mcpTools),
|
|
10498
|
+
runOptions: scrubRunOptions({ ...options, runId }),
|
|
10499
|
+
modelConfig: scrubModelConfig(
|
|
10500
|
+
{
|
|
10501
|
+
provider: this.config.model.provider,
|
|
10502
|
+
modelId: this.config.model.modelId,
|
|
10503
|
+
...this.config.model.baseURL !== void 0 ? { baseURL: this.config.model.baseURL } : {},
|
|
10504
|
+
...this.config.model.temperature !== void 0 ? { temperature: this.config.model.temperature } : {},
|
|
10505
|
+
...this.config.model.maxTokens !== void 0 ? { maxTokens: this.config.model.maxTokens } : {},
|
|
10506
|
+
...this.config.model.maxRetries !== void 0 ? { maxRetries: this.config.model.maxRetries } : {}
|
|
10507
|
+
},
|
|
10508
|
+
{ redactBaseURL: this.config.inspect.redactBaseURL }
|
|
10509
|
+
),
|
|
10510
|
+
...skillList !== void 0 ? { skills: scrubSkills(skillList) } : {},
|
|
10511
|
+
...mcpTools.length > 0 ? { mcpServers: this.snapshotMcpServers(mcpTools) } : {},
|
|
10512
|
+
...apiConfig !== void 0 && apiConfig.services.length > 0 ? { apiServices: scrubApiServices(apiConfig.services) } : {},
|
|
10513
|
+
...knowledgeRuntime !== void 0 ? {
|
|
10514
|
+
knowledge: {
|
|
10515
|
+
schemaVersion: 1,
|
|
10516
|
+
folders: [...knowledgeRuntime.folders],
|
|
10517
|
+
external: knowledgeRuntime.external.map((e) => {
|
|
10518
|
+
const link = { url: e.url };
|
|
10519
|
+
if (e.description !== void 0) link.description = e.description;
|
|
10520
|
+
return link;
|
|
10521
|
+
})
|
|
10522
|
+
}
|
|
10523
|
+
} : {}
|
|
10524
|
+
});
|
|
10136
10525
|
const writer = new TranscriptWriter({
|
|
10137
10526
|
storage: storage.workspace,
|
|
10138
10527
|
logPath,
|
|
@@ -10187,7 +10576,17 @@ var Engine = class {
|
|
|
10187
10576
|
...runTimeout.signal !== void 0 ? { runSignal: runTimeout.signal, runTimeoutMs: this.config.execution.runTimeoutMs } : {},
|
|
10188
10577
|
...gate !== void 0 ? { gateBeforeTool: gate } : {},
|
|
10189
10578
|
..._internal?.handoffToRunner === true ? { handoffToRunner: true } : {},
|
|
10190
|
-
...offloadConfig !== void 0 ? { toolResultOffload: offloadConfig } : {}
|
|
10579
|
+
...offloadConfig !== void 0 ? { toolResultOffload: offloadConfig } : {},
|
|
10580
|
+
// Plan 025 — output mode + tool-choice plumbed down so the
|
|
10581
|
+
// last-turn guard picks the right instruction text and the
|
|
10582
|
+
// model adapter can pass `'required'` to the provider. `'none'`
|
|
10583
|
+
// is already handled above by stripping the tool list, so the
|
|
10584
|
+
// loop only ever sees `'auto'` or `'required'`.
|
|
10585
|
+
...options.outputFormat !== void 0 ? { outputFormat: options.outputFormat } : {},
|
|
10586
|
+
...options.toolChoice === "required" ? { toolChoice: "required" } : {},
|
|
10587
|
+
// Plan 026 — pass the inspect writer so the loop can append
|
|
10588
|
+
// events / per-turn rows. Disabled-mode writer is a no-op.
|
|
10589
|
+
inspect
|
|
10191
10590
|
});
|
|
10192
10591
|
const result = await this.finalizeResult(loopResult, writer, logPath, {
|
|
10193
10592
|
...options.outputFormat !== void 0 ? { outputFormat: options.outputFormat } : {},
|
|
@@ -10195,6 +10594,7 @@ var Engine = class {
|
|
|
10195
10594
|
});
|
|
10196
10595
|
this.logRunEnd(log, runId, options.nodeId, result);
|
|
10197
10596
|
await this.firePostRunHook(runId, options.nodeId, result, ctx, logPath);
|
|
10597
|
+
await this.writeInspectToolsSummary(inspect, storage.workspace, logPath);
|
|
10198
10598
|
const capabilitiesMissing = ctx.getCapabilitiesMissing();
|
|
10199
10599
|
return toResponse(result, {
|
|
10200
10600
|
runId,
|
|
@@ -10280,6 +10680,43 @@ var Engine = class {
|
|
|
10280
10680
|
...knowledgeRuntime !== void 0 ? { knowledge: knowledgeRuntime } : {},
|
|
10281
10681
|
...this.internals.fetch !== void 0 ? { fetch: this.internals.fetch } : {}
|
|
10282
10682
|
});
|
|
10683
|
+
const inspect = this.buildInspectWriter(storage.workspace, logPath);
|
|
10684
|
+
await inspect.writeStartSnapshot({
|
|
10685
|
+
systemPrompt,
|
|
10686
|
+
tools: this.snapshotTools(registry, mcpTools),
|
|
10687
|
+
runOptions: scrubRunOptions({
|
|
10688
|
+
runId: snapshot.runId,
|
|
10689
|
+
nodeId: snapshot.nodeId,
|
|
10690
|
+
task: "[resumed run \u2014 original task in transcript]",
|
|
10691
|
+
...options.outputFormat !== void 0 ? { outputFormat: options.outputFormat } : {},
|
|
10692
|
+
...options.outputSchema !== void 0 ? { outputSchema: options.outputSchema } : {}
|
|
10693
|
+
}),
|
|
10694
|
+
modelConfig: scrubModelConfig(
|
|
10695
|
+
{
|
|
10696
|
+
provider: this.config.model.provider,
|
|
10697
|
+
modelId: this.config.model.modelId,
|
|
10698
|
+
...this.config.model.baseURL !== void 0 ? { baseURL: this.config.model.baseURL } : {},
|
|
10699
|
+
...this.config.model.temperature !== void 0 ? { temperature: this.config.model.temperature } : {},
|
|
10700
|
+
...this.config.model.maxTokens !== void 0 ? { maxTokens: this.config.model.maxTokens } : {},
|
|
10701
|
+
...this.config.model.maxRetries !== void 0 ? { maxRetries: this.config.model.maxRetries } : {}
|
|
10702
|
+
},
|
|
10703
|
+
{ redactBaseURL: this.config.inspect.redactBaseURL }
|
|
10704
|
+
),
|
|
10705
|
+
...skillList !== void 0 ? { skills: scrubSkills(skillList) } : {},
|
|
10706
|
+
...mcpTools.length > 0 ? { mcpServers: this.snapshotMcpServers(mcpTools) } : {},
|
|
10707
|
+
...apiConfig !== void 0 && apiConfig.services.length > 0 ? { apiServices: scrubApiServices(apiConfig.services) } : {},
|
|
10708
|
+
...knowledgeRuntime !== void 0 ? {
|
|
10709
|
+
knowledge: {
|
|
10710
|
+
schemaVersion: 1,
|
|
10711
|
+
folders: [...knowledgeRuntime.folders],
|
|
10712
|
+
external: knowledgeRuntime.external.map((e) => {
|
|
10713
|
+
const link = { url: e.url };
|
|
10714
|
+
if (e.description !== void 0) link.description = e.description;
|
|
10715
|
+
return link;
|
|
10716
|
+
})
|
|
10717
|
+
}
|
|
10718
|
+
} : {}
|
|
10719
|
+
});
|
|
10283
10720
|
const priorState = await loadWriterState(storage.workspace, logPath);
|
|
10284
10721
|
const writer = new TranscriptWriter({
|
|
10285
10722
|
storage: storage.workspace,
|
|
@@ -10369,7 +10806,10 @@ ${inputJson}
|
|
|
10369
10806
|
...runTimeout.signal !== void 0 ? { runSignal: runTimeout.signal, runTimeoutMs: this.config.execution.runTimeoutMs } : {},
|
|
10370
10807
|
...gate !== void 0 ? { gateBeforeTool: gate } : {},
|
|
10371
10808
|
..._internal?.handoffToRunner === true ? { handoffToRunner: true } : {},
|
|
10372
|
-
...offloadConfig !== void 0 ? { toolResultOffload: offloadConfig } : {}
|
|
10809
|
+
...offloadConfig !== void 0 ? { toolResultOffload: offloadConfig } : {},
|
|
10810
|
+
// Plan 026 — append resume's events / per-turn rows to the
|
|
10811
|
+
// existing inspect/ logs.
|
|
10812
|
+
inspect
|
|
10373
10813
|
});
|
|
10374
10814
|
const result = await this.finalizeResult(loopResult, writer, logPath, {
|
|
10375
10815
|
...options.outputFormat !== void 0 ? { outputFormat: options.outputFormat } : {},
|
|
@@ -10377,6 +10817,7 @@ ${inputJson}
|
|
|
10377
10817
|
});
|
|
10378
10818
|
this.logRunEnd(log, snapshot.runId, snapshot.nodeId, result);
|
|
10379
10819
|
await this.firePostRunHook(snapshot.runId, snapshot.nodeId, result, ctx, logPath);
|
|
10820
|
+
await this.writeInspectToolsSummary(inspect, storage.workspace, logPath);
|
|
10380
10821
|
const capabilitiesMissing = ctx.getCapabilitiesMissing();
|
|
10381
10822
|
return toResponse(result, {
|
|
10382
10823
|
runId: snapshot.runId,
|
|
@@ -11220,7 +11661,147 @@ ${inputJson}
|
|
|
11220
11661
|
...this.internals.fetch !== void 0 ? { fetch: this.internals.fetch } : {}
|
|
11221
11662
|
});
|
|
11222
11663
|
}
|
|
11664
|
+
// Plan 026 — inspect-bundle helpers ----------------------------
|
|
11665
|
+
buildInspectWriter(storage, logPath) {
|
|
11666
|
+
const inspect = this.config.inspect;
|
|
11667
|
+
return new InspectWriter({
|
|
11668
|
+
storage,
|
|
11669
|
+
logPath,
|
|
11670
|
+
enabled: inspect.enabled
|
|
11671
|
+
});
|
|
11672
|
+
}
|
|
11673
|
+
/**
|
|
11674
|
+
* Snapshot the live ToolRegistry into the inspect-bundle shape.
|
|
11675
|
+
* Tool source is inferred by name: MCP tools have the
|
|
11676
|
+
* `mcp__{server}__{tool}` prefix; everything else is core.
|
|
11677
|
+
*/
|
|
11678
|
+
snapshotTools(registry, mcpTools) {
|
|
11679
|
+
const mcpNameSet = new Set(mcpTools.map((t) => t.name));
|
|
11680
|
+
return {
|
|
11681
|
+
schemaVersion: 1,
|
|
11682
|
+
tools: registry.list().map((t) => {
|
|
11683
|
+
const out = {
|
|
11684
|
+
name: t.name,
|
|
11685
|
+
description: t.description ?? "",
|
|
11686
|
+
inputSchema: this.toolInputSchemaToJson(t),
|
|
11687
|
+
source: mcpNameSet.has(t.name) ? "mcp" : "core",
|
|
11688
|
+
...t.isCapabilityStub === true ? { isCapabilityStub: true } : {}
|
|
11689
|
+
};
|
|
11690
|
+
return out;
|
|
11691
|
+
})
|
|
11692
|
+
};
|
|
11693
|
+
}
|
|
11694
|
+
/** Convert a Zod input schema to JSON Schema for persistence. */
|
|
11695
|
+
toolInputSchemaToJson(t) {
|
|
11696
|
+
const raw = t.inputSchema;
|
|
11697
|
+
if (raw === void 0 || raw === null) return {};
|
|
11698
|
+
const candidate = raw;
|
|
11699
|
+
if (typeof candidate === "object" && candidate._def !== void 0 && typeof candidate.safeParse === "function") {
|
|
11700
|
+
try {
|
|
11701
|
+
const json2 = (0, import_zod_to_json_schema4.zodToJsonSchema)(raw, {
|
|
11702
|
+
target: "jsonSchema7",
|
|
11703
|
+
$refStrategy: "none"
|
|
11704
|
+
});
|
|
11705
|
+
return json2;
|
|
11706
|
+
} catch {
|
|
11707
|
+
return {};
|
|
11708
|
+
}
|
|
11709
|
+
}
|
|
11710
|
+
return raw;
|
|
11711
|
+
}
|
|
11712
|
+
/**
|
|
11713
|
+
* Plan 026 — aggregate `tools-summary.json` from the persisted
|
|
11714
|
+
* transcript shards. Walks meta.json for shard count, reads each
|
|
11715
|
+
* shard, counts every tool_use block by name. Best-effort; the
|
|
11716
|
+
* InspectWriter swallows write failures.
|
|
11717
|
+
*/
|
|
11718
|
+
async writeInspectToolsSummary(inspect, storage, logPath) {
|
|
11719
|
+
const counts = /* @__PURE__ */ new Map();
|
|
11720
|
+
let total = 0;
|
|
11721
|
+
try {
|
|
11722
|
+
const metaRaw = await storage.readFile(`${logPath}/meta.json`);
|
|
11723
|
+
if (!metaRaw) return;
|
|
11724
|
+
const meta = JSON.parse(metaRaw);
|
|
11725
|
+
const shardCount = meta.shardCount ?? 0;
|
|
11726
|
+
for (let i = 0; i < shardCount; i++) {
|
|
11727
|
+
const name = `${String(i).padStart(6, "0")}.jsonl`;
|
|
11728
|
+
const text2 = await storage.readFile(`${logPath}/${name}`);
|
|
11729
|
+
if (!text2) continue;
|
|
11730
|
+
for (const line of text2.split("\n")) {
|
|
11731
|
+
if (!line) continue;
|
|
11732
|
+
try {
|
|
11733
|
+
const entry = JSON.parse(line);
|
|
11734
|
+
if (entry.type !== "assistant") continue;
|
|
11735
|
+
const content = entry.message?.content;
|
|
11736
|
+
if (!Array.isArray(content)) continue;
|
|
11737
|
+
for (const block of content) {
|
|
11738
|
+
const b = block;
|
|
11739
|
+
if (b.type === "tool_use" && typeof b.name === "string") {
|
|
11740
|
+
counts.set(b.name, (counts.get(b.name) ?? 0) + 1);
|
|
11741
|
+
total++;
|
|
11742
|
+
}
|
|
11743
|
+
}
|
|
11744
|
+
} catch {
|
|
11745
|
+
}
|
|
11746
|
+
}
|
|
11747
|
+
}
|
|
11748
|
+
} catch {
|
|
11749
|
+
return;
|
|
11750
|
+
}
|
|
11751
|
+
await inspect.writeToolsSummary({
|
|
11752
|
+
schemaVersion: 1,
|
|
11753
|
+
tools: [...counts.entries()].map(([name, callCount]) => ({ name, callCount })).sort((a, b) => b.callCount - a.callCount),
|
|
11754
|
+
totalCalls: total
|
|
11755
|
+
});
|
|
11756
|
+
}
|
|
11757
|
+
/**
|
|
11758
|
+
* Snapshot the resolved MCP servers. Right now `mcpManager.getTools()`
|
|
11759
|
+
* returns the flat tool list; we group them by server-name prefix to
|
|
11760
|
+
* recover which server exposed which tool.
|
|
11761
|
+
*/
|
|
11762
|
+
snapshotMcpServers(mcpTools) {
|
|
11763
|
+
const byServer = /* @__PURE__ */ new Map();
|
|
11764
|
+
for (const t of mcpTools) {
|
|
11765
|
+
const m = t.name.match(/^mcp__([^_]+)__(.+)$/);
|
|
11766
|
+
const server = m?.[1] ?? "unknown";
|
|
11767
|
+
const list = byServer.get(server) ?? [];
|
|
11768
|
+
list.push(t.name);
|
|
11769
|
+
byServer.set(server, list);
|
|
11770
|
+
}
|
|
11771
|
+
const declaredMap = this.config.mcp.servers;
|
|
11772
|
+
return {
|
|
11773
|
+
schemaVersion: 1,
|
|
11774
|
+
servers: [...byServer.entries()].map(([name, tools]) => {
|
|
11775
|
+
const declared = declaredMap[name];
|
|
11776
|
+
const out = {
|
|
11777
|
+
name,
|
|
11778
|
+
// If the server isn't in the declared map (synthetic / dynamic),
|
|
11779
|
+
// default to 'http' as a best-effort label.
|
|
11780
|
+
type: declared?.type ?? "http",
|
|
11781
|
+
state: "connected",
|
|
11782
|
+
tools
|
|
11783
|
+
};
|
|
11784
|
+
if (declared !== void 0) {
|
|
11785
|
+
if (declared.type === "stdio") {
|
|
11786
|
+
out.command = declared.command;
|
|
11787
|
+
out.args = [...declared.args];
|
|
11788
|
+
} else {
|
|
11789
|
+
out.url = declared.url;
|
|
11790
|
+
if (declared.headers !== void 0) {
|
|
11791
|
+
out.headers = redactHeadersInline(declared.headers);
|
|
11792
|
+
}
|
|
11793
|
+
}
|
|
11794
|
+
}
|
|
11795
|
+
return out;
|
|
11796
|
+
})
|
|
11797
|
+
};
|
|
11798
|
+
}
|
|
11223
11799
|
};
|
|
11800
|
+
function redactHeadersInline(headers) {
|
|
11801
|
+
const out = {};
|
|
11802
|
+
for (const k of Object.keys(headers)) out[k] = "<redacted>";
|
|
11803
|
+
return out;
|
|
11804
|
+
}
|
|
11224
11805
|
function buildToolRegistry(options) {
|
|
11225
11806
|
const {
|
|
11226
11807
|
config,
|
|
@@ -11411,6 +11992,11 @@ init_retry();
|
|
|
11411
11992
|
init_snapshot();
|
|
11412
11993
|
init_synthesize();
|
|
11413
11994
|
init_types();
|
|
11995
|
+
|
|
11996
|
+
// src/inspect/index.ts
|
|
11997
|
+
init_cjs_shims();
|
|
11998
|
+
|
|
11999
|
+
// src/index.ts
|
|
11414
12000
|
var ENGINE_VERSION = "0.0.0";
|
|
11415
12001
|
function initEngine(user = {}) {
|
|
11416
12002
|
let resolved;
|
|
@@ -11450,6 +12036,7 @@ function resolveApiKey(config) {
|
|
|
11450
12036
|
EpisodicMemory,
|
|
11451
12037
|
Hippocampus,
|
|
11452
12038
|
InlineSkillSource,
|
|
12039
|
+
InspectWriter,
|
|
11453
12040
|
LocalStorageAdapter,
|
|
11454
12041
|
MAX_ATTEMPTS,
|
|
11455
12042
|
McpClient,
|
|
@@ -11457,6 +12044,7 @@ function resolveApiKey(config) {
|
|
|
11457
12044
|
McpManager,
|
|
11458
12045
|
McpProtocolError,
|
|
11459
12046
|
McpTimeoutError,
|
|
12047
|
+
NULL_INSPECT_WRITER,
|
|
11460
12048
|
NodeBackgroundExecutor,
|
|
11461
12049
|
NotImplementedError,
|
|
11462
12050
|
PlanSchema,
|