la-machina-engine 0.7.5 → 0.7.6
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 +173 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +173 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3165,6 +3165,19 @@ async function agentLoop(options) {
|
|
|
3165
3165
|
});
|
|
3166
3166
|
if (compactResult.compacted) {
|
|
3167
3167
|
messages = compactResult.messages;
|
|
3168
|
+
const used = ctx.getTokensUsed();
|
|
3169
|
+
const total = used.input + used.output;
|
|
3170
|
+
const ratio = total / contextLimit;
|
|
3171
|
+
const dropped = compactResult.result?.dropped ?? 0;
|
|
3172
|
+
await options.inspect?.appendEvent({
|
|
3173
|
+
type: "compaction_threshold",
|
|
3174
|
+
turn: ctx.getTurnCount(),
|
|
3175
|
+
ratio,
|
|
3176
|
+
threshold: compactionConfig.threshold,
|
|
3177
|
+
strategy: compactResult.result?.strategy ?? compactionConfig.strategy,
|
|
3178
|
+
dropped,
|
|
3179
|
+
ts: Date.now()
|
|
3180
|
+
});
|
|
3168
3181
|
}
|
|
3169
3182
|
await fireProgress("streaming");
|
|
3170
3183
|
const textBlocks = [];
|
|
@@ -3350,16 +3363,31 @@ async function agentLoop(options) {
|
|
|
3350
3363
|
const firstTool = toolCallsToDispatch[0]?.name;
|
|
3351
3364
|
await fireProgress("tool_dispatch", firstTool);
|
|
3352
3365
|
const streamExec = new StreamingToolExecutor(executor);
|
|
3366
|
+
let anyConcurrent = false;
|
|
3353
3367
|
for (const call of toolCallsToDispatch) {
|
|
3354
3368
|
const tool = options.registry?.get(call.name);
|
|
3355
3369
|
const safe = tool?.isConcurrencySafe?.(call.input) ?? false;
|
|
3370
|
+
if (safe) anyConcurrent = true;
|
|
3356
3371
|
streamExec.addTool(call.id, call.name, call.input, safe);
|
|
3357
3372
|
}
|
|
3373
|
+
await options.inspect?.appendEvent({
|
|
3374
|
+
type: "tool_batch",
|
|
3375
|
+
turn: ctx.getTurnCount(),
|
|
3376
|
+
toolNames: toolCallsToDispatch.map((c) => c.name),
|
|
3377
|
+
concurrent: anyConcurrent && toolCallsToDispatch.length > 1,
|
|
3378
|
+
ts: Date.now()
|
|
3379
|
+
});
|
|
3358
3380
|
try {
|
|
3359
3381
|
for await (const { id, result } of streamExec.results()) {
|
|
3360
3382
|
const missing = result.metadata?.capabilityMissing;
|
|
3361
3383
|
if (typeof missing === "string") {
|
|
3362
3384
|
ctx.recordCapabilityMissing(missing);
|
|
3385
|
+
await options.inspect?.appendEvent({
|
|
3386
|
+
type: "capability_stub",
|
|
3387
|
+
turn: ctx.getTurnCount(),
|
|
3388
|
+
toolName: missing,
|
|
3389
|
+
ts: Date.now()
|
|
3390
|
+
});
|
|
3363
3391
|
}
|
|
3364
3392
|
const call = toolCallsToDispatch.find((c) => c.id === id);
|
|
3365
3393
|
let contentForTranscript;
|
|
@@ -4508,25 +4536,45 @@ If omitted, defaults to "${defaultAgent.name}".`;
|
|
|
4508
4536
|
const lastAssistant = [...parentMsgs].reverse().find((m) => m.role === "assistant");
|
|
4509
4537
|
const assistantContent = lastAssistant ? Array.isArray(lastAssistant.content) ? lastAssistant.content : [] : [];
|
|
4510
4538
|
const forkedMsgs = buildForkedMessages(taskDescription, assistantContent);
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4539
|
+
let result2;
|
|
4540
|
+
try {
|
|
4541
|
+
result2 = await runAgent({
|
|
4542
|
+
agentId: spawn2.agentId,
|
|
4543
|
+
description: taskDescription,
|
|
4544
|
+
storage: options.storage,
|
|
4545
|
+
client: options.client,
|
|
4546
|
+
registry: options.childRegistry,
|
|
4547
|
+
parentLogPath: options.parentLogPath,
|
|
4548
|
+
system: options.system,
|
|
4549
|
+
// inherit parent's system prompt
|
|
4550
|
+
maxTurns: options.maxTurns,
|
|
4551
|
+
contextLimit: options.contextLimit,
|
|
4552
|
+
turnTimeoutMs: options.turnTimeoutMs,
|
|
4553
|
+
flushPolicy: options.flushPolicy,
|
|
4554
|
+
idleFlushMs: options.idleFlushMs,
|
|
4555
|
+
// Fork: prepend parent messages + forked messages
|
|
4556
|
+
prependMessages: [...parentMsgs, ...forkedMsgs],
|
|
4557
|
+
...options.gateBeforeTool !== void 0 ? { gateBeforeTool: options.gateBeforeTool } : {},
|
|
4558
|
+
...options.toolResultOffload !== void 0 ? { toolResultOffload: options.toolResultOffload } : {}
|
|
4559
|
+
});
|
|
4560
|
+
await options.inspect?.appendEvent({
|
|
4561
|
+
type: "subagent_spawn_attempt",
|
|
4562
|
+
agentId: spawn2.agentId,
|
|
4563
|
+
subagentType: "fork",
|
|
4564
|
+
success: true,
|
|
4565
|
+
ts: Date.now()
|
|
4566
|
+
});
|
|
4567
|
+
} catch (err) {
|
|
4568
|
+
await options.inspect?.appendEvent({
|
|
4569
|
+
type: "subagent_spawn_attempt",
|
|
4570
|
+
agentId: spawn2.agentId,
|
|
4571
|
+
subagentType: "fork",
|
|
4572
|
+
success: false,
|
|
4573
|
+
error: err instanceof Error ? err.message : String(err),
|
|
4574
|
+
ts: Date.now()
|
|
4575
|
+
});
|
|
4576
|
+
throw err;
|
|
4577
|
+
}
|
|
4530
4578
|
handlePausedResult(result2, spawn2.agentId, "fork");
|
|
4531
4579
|
const t2 = result2;
|
|
4532
4580
|
options.subagentRegistry.setStatus(spawn2.agentId, t2.isError ? "stopped" : "completed");
|
|
@@ -4580,7 +4628,7 @@ If omitted, defaults to "${defaultAgent.name}".`;
|
|
|
4580
4628
|
const shouldRunAsync = run_in_background === true || options.coordinatorMode === true;
|
|
4581
4629
|
if (shouldRunAsync) {
|
|
4582
4630
|
options.subagentRegistry.setBackground(spawn.agentId);
|
|
4583
|
-
const bgPromise = runAgent(runOpts).then((result2) => {
|
|
4631
|
+
const bgPromise = runAgent(runOpts).then(async (result2) => {
|
|
4584
4632
|
if (result2.kind !== "terminal") {
|
|
4585
4633
|
options.subagentRegistry.setStatus(spawn.agentId, "stopped");
|
|
4586
4634
|
options.subagentRegistry.setBackgroundResult(spawn.agentId, {
|
|
@@ -4589,6 +4637,14 @@ If omitted, defaults to "${defaultAgent.name}".`;
|
|
|
4589
4637
|
isError: true,
|
|
4590
4638
|
description: taskDescription
|
|
4591
4639
|
});
|
|
4640
|
+
await options.inspect?.appendEvent({
|
|
4641
|
+
type: "subagent_spawn_attempt",
|
|
4642
|
+
agentId: spawn.agentId,
|
|
4643
|
+
subagentType: typeName ?? "unknown",
|
|
4644
|
+
success: false,
|
|
4645
|
+
error: "background subagent paused (pause not supported for async)",
|
|
4646
|
+
ts: Date.now()
|
|
4647
|
+
});
|
|
4592
4648
|
return;
|
|
4593
4649
|
}
|
|
4594
4650
|
options.subagentRegistry.setStatus(
|
|
@@ -4601,7 +4657,15 @@ If omitted, defaults to "${defaultAgent.name}".`;
|
|
|
4601
4657
|
isError: result2.isError,
|
|
4602
4658
|
description: taskDescription
|
|
4603
4659
|
});
|
|
4604
|
-
|
|
4660
|
+
await options.inspect?.appendEvent({
|
|
4661
|
+
type: "subagent_spawn_attempt",
|
|
4662
|
+
agentId: spawn.agentId,
|
|
4663
|
+
subagentType: typeName ?? "unknown",
|
|
4664
|
+
success: !result2.isError,
|
|
4665
|
+
...result2.isError ? { error: "child returned isError" } : {},
|
|
4666
|
+
ts: Date.now()
|
|
4667
|
+
});
|
|
4668
|
+
}).catch(async (err) => {
|
|
4605
4669
|
options.subagentRegistry.setStatus(spawn.agentId, "stopped");
|
|
4606
4670
|
options.subagentRegistry.setBackgroundResult(spawn.agentId, {
|
|
4607
4671
|
agentId: spawn.agentId,
|
|
@@ -4609,6 +4673,14 @@ If omitted, defaults to "${defaultAgent.name}".`;
|
|
|
4609
4673
|
isError: true,
|
|
4610
4674
|
description: taskDescription
|
|
4611
4675
|
});
|
|
4676
|
+
await options.inspect?.appendEvent({
|
|
4677
|
+
type: "subagent_spawn_attempt",
|
|
4678
|
+
agentId: spawn.agentId,
|
|
4679
|
+
subagentType: typeName ?? "unknown",
|
|
4680
|
+
success: false,
|
|
4681
|
+
error: err instanceof Error ? err.message : String(err),
|
|
4682
|
+
ts: Date.now()
|
|
4683
|
+
});
|
|
4612
4684
|
});
|
|
4613
4685
|
options.subagentRegistry.setBackgroundPromise(spawn.agentId, bgPromise);
|
|
4614
4686
|
return {
|
|
@@ -4624,7 +4696,27 @@ Use SendMessage with to: '${spawn.agentId}' to communicate with this agent.`,
|
|
|
4624
4696
|
}
|
|
4625
4697
|
};
|
|
4626
4698
|
}
|
|
4627
|
-
|
|
4699
|
+
let result;
|
|
4700
|
+
try {
|
|
4701
|
+
result = await runAgent(runOpts);
|
|
4702
|
+
await options.inspect?.appendEvent({
|
|
4703
|
+
type: "subagent_spawn_attempt",
|
|
4704
|
+
agentId: spawn.agentId,
|
|
4705
|
+
subagentType: typeName ?? "unknown",
|
|
4706
|
+
success: true,
|
|
4707
|
+
ts: Date.now()
|
|
4708
|
+
});
|
|
4709
|
+
} catch (err) {
|
|
4710
|
+
await options.inspect?.appendEvent({
|
|
4711
|
+
type: "subagent_spawn_attempt",
|
|
4712
|
+
agentId: spawn.agentId,
|
|
4713
|
+
subagentType: typeName ?? "unknown",
|
|
4714
|
+
success: false,
|
|
4715
|
+
error: err instanceof Error ? err.message : String(err),
|
|
4716
|
+
ts: Date.now()
|
|
4717
|
+
});
|
|
4718
|
+
throw err;
|
|
4719
|
+
}
|
|
4628
4720
|
handlePausedResult(result, spawn.agentId, typeName);
|
|
4629
4721
|
const t = result;
|
|
4630
4722
|
options.subagentRegistry.setStatus(spawn.agentId, t.isError ? "stopped" : "completed");
|
|
@@ -6959,7 +7051,7 @@ init_contract();
|
|
|
6959
7051
|
function mcpToolName(serverName, toolName) {
|
|
6960
7052
|
return `mcp__${serverName}__${toolName}`;
|
|
6961
7053
|
}
|
|
6962
|
-
function adaptMcpTool(client, serverName, def) {
|
|
7054
|
+
function adaptMcpTool(client, serverName, def, opts) {
|
|
6963
7055
|
const registeredName = mcpToolName(serverName, def.name);
|
|
6964
7056
|
return defineTool({
|
|
6965
7057
|
name: registeredName,
|
|
@@ -6969,6 +7061,9 @@ function adaptMcpTool(client, serverName, def) {
|
|
|
6969
7061
|
// bypassing Zod-to-JSON-Schema conversion (which would produce `{}`
|
|
6970
7062
|
// for our `z.unknown()` Zod schema).
|
|
6971
7063
|
anthropicSchemaOverride: def.inputSchema,
|
|
7064
|
+
// Plan 027 — stdio servers spawn subprocesses; flag so the engine's
|
|
7065
|
+
// capability-stub wrapper can swap them on Workers.
|
|
7066
|
+
...opts.transport === "stdio" ? { requiresNode: true } : {},
|
|
6972
7067
|
execute: async (input) => {
|
|
6973
7068
|
try {
|
|
6974
7069
|
const result = await client.callTool(def.name, input);
|
|
@@ -7012,6 +7107,8 @@ var McpManager = class {
|
|
|
7012
7107
|
this.logger = logger;
|
|
7013
7108
|
this.servers = Object.entries(config.servers).map(([name, serverConfig]) => ({
|
|
7014
7109
|
name,
|
|
7110
|
+
// Plan 027 — capture transport for the stdio-handoff wiring.
|
|
7111
|
+
transport: serverConfig.type,
|
|
7015
7112
|
client: new McpClient({
|
|
7016
7113
|
serverName: name,
|
|
7017
7114
|
config: serverConfig,
|
|
@@ -7151,7 +7248,9 @@ var McpManager = class {
|
|
|
7151
7248
|
try {
|
|
7152
7249
|
await server.client.connect();
|
|
7153
7250
|
const defs = server.client.listTools();
|
|
7154
|
-
server.tools = defs.map(
|
|
7251
|
+
server.tools = defs.map(
|
|
7252
|
+
(def) => adaptMcpTool(server.client, server.name, def, { transport: server.transport })
|
|
7253
|
+
);
|
|
7155
7254
|
server.state = "connected";
|
|
7156
7255
|
this.pendingConnected.push(server.name);
|
|
7157
7256
|
} catch (err) {
|
|
@@ -10472,6 +10571,7 @@ var Engine = class {
|
|
|
10472
10571
|
systemPrompt += "\n\n" + buildSchemaPrompt(options.outputSchema);
|
|
10473
10572
|
}
|
|
10474
10573
|
const gate = this.resolveGate();
|
|
10574
|
+
const inspect = this.buildInspectWriter(storage.workspace, logPath);
|
|
10475
10575
|
const registry = buildToolRegistry({
|
|
10476
10576
|
config: this.config,
|
|
10477
10577
|
storage,
|
|
@@ -10483,6 +10583,7 @@ var Engine = class {
|
|
|
10483
10583
|
agents,
|
|
10484
10584
|
mcpTools,
|
|
10485
10585
|
memory,
|
|
10586
|
+
inspect,
|
|
10486
10587
|
...this.config.hooks.propagateGateToSubagents === true && gate !== void 0 ? { subagentGate: gate } : {},
|
|
10487
10588
|
...skillSource !== void 0 ? { skillSource } : {},
|
|
10488
10589
|
...apiConfig !== void 0 ? { apiConfig } : {},
|
|
@@ -10491,7 +10592,6 @@ var Engine = class {
|
|
|
10491
10592
|
...this.internals.fetch !== void 0 ? { fetch: this.internals.fetch } : {}
|
|
10492
10593
|
});
|
|
10493
10594
|
applyRunToolFilter(registry, options);
|
|
10494
|
-
const inspect = this.buildInspectWriter(storage.workspace, logPath);
|
|
10495
10595
|
await inspect.writeStartSnapshot({
|
|
10496
10596
|
systemPrompt,
|
|
10497
10597
|
tools: this.snapshotTools(registry, mcpTools),
|
|
@@ -10588,10 +10688,16 @@ var Engine = class {
|
|
|
10588
10688
|
// events / per-turn rows. Disabled-mode writer is a no-op.
|
|
10589
10689
|
inspect
|
|
10590
10690
|
});
|
|
10591
|
-
const result = await this.finalizeResult(
|
|
10592
|
-
|
|
10593
|
-
|
|
10594
|
-
|
|
10691
|
+
const result = await this.finalizeResult(
|
|
10692
|
+
loopResult,
|
|
10693
|
+
writer,
|
|
10694
|
+
logPath,
|
|
10695
|
+
{
|
|
10696
|
+
...options.outputFormat !== void 0 ? { outputFormat: options.outputFormat } : {},
|
|
10697
|
+
...options.outputSchema !== void 0 ? { outputSchema: options.outputSchema } : {}
|
|
10698
|
+
},
|
|
10699
|
+
inspect
|
|
10700
|
+
);
|
|
10595
10701
|
this.logRunEnd(log, runId, options.nodeId, result);
|
|
10596
10702
|
await this.firePostRunHook(runId, options.nodeId, result, ctx, logPath);
|
|
10597
10703
|
await this.writeInspectToolsSummary(inspect, storage.workspace, logPath);
|
|
@@ -10662,6 +10768,7 @@ var Engine = class {
|
|
|
10662
10768
|
systemPrompt += "\n\n" + buildSchemaPrompt(options.outputSchema);
|
|
10663
10769
|
}
|
|
10664
10770
|
const gate = this.resolveGate();
|
|
10771
|
+
const inspect = this.buildInspectWriter(storage.workspace, logPath);
|
|
10665
10772
|
const registry = buildToolRegistry({
|
|
10666
10773
|
config: this.config,
|
|
10667
10774
|
storage,
|
|
@@ -10673,6 +10780,7 @@ var Engine = class {
|
|
|
10673
10780
|
agents,
|
|
10674
10781
|
mcpTools,
|
|
10675
10782
|
memory,
|
|
10783
|
+
inspect,
|
|
10676
10784
|
...this.config.hooks.propagateGateToSubagents === true && gate !== void 0 ? { subagentGate: gate } : {},
|
|
10677
10785
|
...skillSource !== void 0 ? { skillSource } : {},
|
|
10678
10786
|
...apiConfig !== void 0 ? { apiConfig } : {},
|
|
@@ -10680,7 +10788,6 @@ var Engine = class {
|
|
|
10680
10788
|
...knowledgeRuntime !== void 0 ? { knowledge: knowledgeRuntime } : {},
|
|
10681
10789
|
...this.internals.fetch !== void 0 ? { fetch: this.internals.fetch } : {}
|
|
10682
10790
|
});
|
|
10683
|
-
const inspect = this.buildInspectWriter(storage.workspace, logPath);
|
|
10684
10791
|
await inspect.writeStartSnapshot({
|
|
10685
10792
|
systemPrompt,
|
|
10686
10793
|
tools: this.snapshotTools(registry, mcpTools),
|
|
@@ -10811,10 +10918,16 @@ ${inputJson}
|
|
|
10811
10918
|
// existing inspect/ logs.
|
|
10812
10919
|
inspect
|
|
10813
10920
|
});
|
|
10814
|
-
const result = await this.finalizeResult(
|
|
10815
|
-
|
|
10816
|
-
|
|
10817
|
-
|
|
10921
|
+
const result = await this.finalizeResult(
|
|
10922
|
+
loopResult,
|
|
10923
|
+
writer,
|
|
10924
|
+
logPath,
|
|
10925
|
+
{
|
|
10926
|
+
...options.outputFormat !== void 0 ? { outputFormat: options.outputFormat } : {},
|
|
10927
|
+
...options.outputSchema !== void 0 ? { outputSchema: options.outputSchema } : {}
|
|
10928
|
+
},
|
|
10929
|
+
inspect
|
|
10930
|
+
);
|
|
10818
10931
|
this.logRunEnd(log, snapshot.runId, snapshot.nodeId, result);
|
|
10819
10932
|
await this.firePostRunHook(snapshot.runId, snapshot.nodeId, result, ctx, logPath);
|
|
10820
10933
|
await this.writeInspectToolsSummary(inspect, storage.workspace, logPath);
|
|
@@ -11465,7 +11578,7 @@ ${inputJson}
|
|
|
11465
11578
|
};
|
|
11466
11579
|
await dispatchHooks(this.config.hooks.postRun, event);
|
|
11467
11580
|
}
|
|
11468
|
-
async finalizeResult(loopResult, writer, _logPath, jsonOptions) {
|
|
11581
|
+
async finalizeResult(loopResult, writer, _logPath, jsonOptions, inspect) {
|
|
11469
11582
|
if (loopResult.status === "done") {
|
|
11470
11583
|
await writer.setStatus("done");
|
|
11471
11584
|
let data;
|
|
@@ -11474,10 +11587,27 @@ ${inputJson}
|
|
|
11474
11587
|
if (parsed.ok) {
|
|
11475
11588
|
if (jsonOptions.outputSchema) {
|
|
11476
11589
|
const validated = validateOutput(parsed.value, jsonOptions.outputSchema);
|
|
11477
|
-
|
|
11590
|
+
if (validated.ok) {
|
|
11591
|
+
data = validated.data;
|
|
11592
|
+
} else {
|
|
11593
|
+
await inspect?.appendEvent({
|
|
11594
|
+
type: "json_parse_failure",
|
|
11595
|
+
turn: loopResult.turns,
|
|
11596
|
+
validationError: validated.error,
|
|
11597
|
+
ts: Date.now()
|
|
11598
|
+
});
|
|
11599
|
+
data = void 0;
|
|
11600
|
+
}
|
|
11478
11601
|
} else {
|
|
11479
11602
|
data = parsed.value;
|
|
11480
11603
|
}
|
|
11604
|
+
} else {
|
|
11605
|
+
await inspect?.appendEvent({
|
|
11606
|
+
type: "json_parse_failure",
|
|
11607
|
+
turn: loopResult.turns,
|
|
11608
|
+
parseError: parsed.error ?? "unknown parse error",
|
|
11609
|
+
ts: Date.now()
|
|
11610
|
+
});
|
|
11481
11611
|
}
|
|
11482
11612
|
}
|
|
11483
11613
|
return {
|
|
@@ -11955,7 +12085,10 @@ function buildToolRegistry(options) {
|
|
|
11955
12085
|
agents,
|
|
11956
12086
|
coordinatorMode: isCoordinatorMode(config),
|
|
11957
12087
|
...subagentGate !== void 0 ? { gateBeforeTool: subagentGate } : {},
|
|
11958
|
-
...options.toolResultOffload !== void 0 ? { toolResultOffload: options.toolResultOffload } : {}
|
|
12088
|
+
...options.toolResultOffload !== void 0 ? { toolResultOffload: options.toolResultOffload } : {},
|
|
12089
|
+
// Plan 026 — Agent tool emits subagent_spawn_attempt to the
|
|
12090
|
+
// parent's events.jsonl on each runAgent call (success and failure).
|
|
12091
|
+
...options.inspect !== void 0 ? { inspect: options.inspect } : {}
|
|
11959
12092
|
});
|
|
11960
12093
|
if (!disabled.has("Agent") && (wantAll || enabled.has("Agent"))) {
|
|
11961
12094
|
registry.register(agentTool);
|
|
@@ -11971,8 +12104,9 @@ function buildToolRegistry(options) {
|
|
|
11971
12104
|
for (const tool of mcpTools) {
|
|
11972
12105
|
if (disabled.has(tool.name)) continue;
|
|
11973
12106
|
if (wantAll || enabled.has(tool.name)) {
|
|
11974
|
-
|
|
11975
|
-
|
|
12107
|
+
const wrapped = withCapabilityCheck(tool, spawnAvailable);
|
|
12108
|
+
registry.register(wrapped);
|
|
12109
|
+
childRegistry.register(wrapped);
|
|
11976
12110
|
}
|
|
11977
12111
|
}
|
|
11978
12112
|
if (!disabled.has("ToolSearch") && (wantAll || enabled.has("ToolSearch"))) {
|