@tangle-network/agent-runtime 0.102.0 → 0.102.2

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.
Files changed (77) hide show
  1. package/dist/agent.d.ts +1 -1
  2. package/dist/agent.js +5 -3
  3. package/dist/agent.js.map +1 -1
  4. package/dist/analyst-loop.d.ts +1 -1
  5. package/dist/candidate-execution/index.js +5 -4
  6. package/dist/{chunk-SPCD4IQQ.js → chunk-377GOJHJ.js} +2 -2
  7. package/dist/{chunk-LKKIM5QD.js → chunk-3DW5DEKQ.js} +3 -3
  8. package/dist/{chunk-4AMAFNUD.js → chunk-7FJJUC73.js} +311 -40
  9. package/dist/chunk-7FJJUC73.js.map +1 -0
  10. package/dist/{chunk-DA7YL6I4.js → chunk-CK76OZPM.js} +3 -3
  11. package/dist/{chunk-KSBUSEUA.js → chunk-EKUMRQNR.js} +2 -2
  12. package/dist/{chunk-23Z7N5IG.js → chunk-J6V6DWWS.js} +5 -5
  13. package/dist/{chunk-AIBIRAJ6.js → chunk-KSM6GFHP.js} +2 -2
  14. package/dist/chunk-L5DST3QC.js +351 -0
  15. package/dist/chunk-L5DST3QC.js.map +1 -0
  16. package/dist/{chunk-TGDHHHH4.js → chunk-LJLG734E.js} +12 -253
  17. package/dist/chunk-LJLG734E.js.map +1 -0
  18. package/dist/{chunk-MAONWP4R.js → chunk-QCXD7NHM.js} +611 -1419
  19. package/dist/chunk-QCXD7NHM.js.map +1 -0
  20. package/dist/chunk-ROILMKDL.js +1338 -0
  21. package/dist/chunk-ROILMKDL.js.map +1 -0
  22. package/dist/{chunk-N2CEE5Q3.js → chunk-SCOHHMKU.js} +3 -3
  23. package/dist/chunk-SQ3ZJH3Y.js +3082 -0
  24. package/dist/chunk-SQ3ZJH3Y.js.map +1 -0
  25. package/dist/chunk-UPWGXKXB.js +254 -0
  26. package/dist/chunk-UPWGXKXB.js.map +1 -0
  27. package/dist/{chunk-KVJQV342.js → chunk-ZUCUAFVF.js} +26 -1778
  28. package/dist/chunk-ZUCUAFVF.js.map +1 -0
  29. package/dist/{completion-gate-C80jiRfN.d.ts → completion-gate-C6dhVN-N.d.ts} +2 -2
  30. package/dist/{coordination-BFE3Den7.d.ts → coordination-D9l_YmwW.d.ts} +6 -6
  31. package/dist/environment-provider.d.ts +2 -2
  32. package/dist/{improve-CIml6hT3.d.ts → improve-B40dRu0X.d.ts} +40 -19
  33. package/dist/index.d.ts +329 -21
  34. package/dist/index.js +541 -137
  35. package/dist/index.js.map +1 -1
  36. package/dist/intelligence.d.ts +5 -5
  37. package/dist/intelligence.js +7 -5
  38. package/dist/intelligence.js.map +1 -1
  39. package/dist/knowledge.d.ts +8 -8
  40. package/dist/knowledge.js +9 -7
  41. package/dist/{local-harness-ZqCx51u7.d.ts → local-harness-CtK9dSny.d.ts} +14 -2
  42. package/dist/{loop-runner-bin-Cn1N2rRo.d.ts → loop-runner-bin-PnWslIw4.d.ts} +2 -2
  43. package/dist/loop-runner-bin.d.ts +6 -6
  44. package/dist/loop-runner-bin.js +6 -4
  45. package/dist/loops.d.ts +231 -460
  46. package/dist/loops.js +58 -37
  47. package/dist/mcp/bin.js +2 -2
  48. package/dist/mcp/index.d.ts +184 -12
  49. package/dist/mcp/index.js +31 -9
  50. package/dist/mcp/index.js.map +1 -1
  51. package/dist/mcp/memory-bin.d.ts +1 -0
  52. package/dist/mcp/memory-bin.js +22 -0
  53. package/dist/mcp/memory-bin.js.map +1 -0
  54. package/dist/profiles.d.ts +3 -3
  55. package/dist/structural-rollout-D7xik9XR.d.ts +446 -0
  56. package/dist/{substrate-DO2GHNg2.d.ts → substrate-Dyiqmd3o.d.ts} +1 -1
  57. package/dist/{supervise-BLPI50-w.d.ts → supervise-BQdNAXtK.d.ts} +4 -4
  58. package/dist/testing.js +10 -8
  59. package/dist/testing.js.map +1 -1
  60. package/dist/{types-B3vAW0Oq.d.ts → types-CLat4bT9.d.ts} +1 -1
  61. package/dist/{types-CmnA2iL3.d.ts → types-D870JlH0.d.ts} +2 -2
  62. package/dist/{worktree-fanout-DCA3G4bO.d.ts → worktree-fanout-DsIR4d6w.d.ts} +234 -234
  63. package/package.json +4 -3
  64. package/dist/chunk-4AMAFNUD.js.map +0 -1
  65. package/dist/chunk-IKGCKPDX.js +0 -1115
  66. package/dist/chunk-IKGCKPDX.js.map +0 -1
  67. package/dist/chunk-KVJQV342.js.map +0 -1
  68. package/dist/chunk-MAONWP4R.js.map +0 -1
  69. package/dist/chunk-TGDHHHH4.js.map +0 -1
  70. package/dist/{chunk-SPCD4IQQ.js.map → chunk-377GOJHJ.js.map} +0 -0
  71. package/dist/{chunk-LKKIM5QD.js.map → chunk-3DW5DEKQ.js.map} +0 -0
  72. package/dist/{chunk-DA7YL6I4.js.map → chunk-CK76OZPM.js.map} +0 -0
  73. package/dist/{chunk-KSBUSEUA.js.map → chunk-EKUMRQNR.js.map} +0 -0
  74. package/dist/{chunk-23Z7N5IG.js.map → chunk-J6V6DWWS.js.map} +0 -0
  75. package/dist/{chunk-AIBIRAJ6.js.map → chunk-KSM6GFHP.js.map} +0 -0
  76. package/dist/{chunk-N2CEE5Q3.js.map → chunk-SCOHHMKU.js.map} +0 -0
  77. package/dist/{sanitize-BTSsdBXw.d.ts → sanitize-DEbPNtyI.d.ts} +58 -58
package/dist/index.js CHANGED
@@ -1,14 +1,26 @@
1
+ import {
2
+ DELEGATED_LOOP_MODES,
3
+ auditLoopRunner,
4
+ isDelegatedLoopMode,
5
+ parseLoopRunnerArgv,
6
+ researchLoopRunner,
7
+ runDelegatedLoop,
8
+ runLoopRunnerCli,
9
+ selfImproveLoopRunner,
10
+ worktreeLoopRunner
11
+ } from "./chunk-SCOHHMKU.js";
1
12
  import {
2
13
  FileAgentCandidateExecutionClaimStore,
3
14
  buildAgentCandidateBundle,
4
15
  createProtectedAgentCandidateModelPort,
5
16
  disposePreparedAgentCandidateExecution,
6
17
  recoverExpiredAgentCandidateExecution
7
- } from "./chunk-DA7YL6I4.js";
18
+ } from "./chunk-CK76OZPM.js";
8
19
  import {
9
20
  mcpToolsForRuntimeMcp,
10
21
  mcpToolsForRuntimeMcpSubset
11
- } from "./chunk-KSBUSEUA.js";
22
+ } from "./chunk-EKUMRQNR.js";
23
+ import "./chunk-SGKPNBXE.js";
12
24
  import {
13
25
  DEFAULT_ROUTER_BASE_URL,
14
26
  cleanModelId,
@@ -17,18 +29,6 @@ import {
17
29
  resolveRouterBaseUrl,
18
30
  validateChatModelId
19
31
  } from "./chunk-NURIQBJQ.js";
20
- import {
21
- DELEGATED_LOOP_MODES,
22
- auditLoopRunner,
23
- isDelegatedLoopMode,
24
- parseLoopRunnerArgv,
25
- researchLoopRunner,
26
- runDelegatedLoop,
27
- runLoopRunnerCli,
28
- selfImproveLoopRunner,
29
- worktreeLoopRunner
30
- } from "./chunk-N2CEE5Q3.js";
31
- import "./chunk-SGKPNBXE.js";
32
32
  import {
33
33
  CircuitBreakerState,
34
34
  CircuitOpenError,
@@ -57,8 +57,11 @@ import {
57
57
  } from "./chunk-2KGAN2HM.js";
58
58
  import {
59
59
  exactProcessProviderAsCandidateExecutor
60
- } from "./chunk-SPCD4IQQ.js";
61
- import "./chunk-MAONWP4R.js";
60
+ } from "./chunk-377GOJHJ.js";
61
+ import {
62
+ McpSpawnFault,
63
+ connectStdioMcp
64
+ } from "./chunk-QCXD7NHM.js";
62
65
  import {
63
66
  InMemoryRuntimeSessionStore,
64
67
  createIterableBackend,
@@ -79,23 +82,40 @@ import {
79
82
  knowledgeReadinessDeliverable,
80
83
  runKnowledgeImprovementJob,
81
84
  runSupervisedKnowledgeUpdate
82
- } from "./chunk-23Z7N5IG.js";
85
+ } from "./chunk-J6V6DWWS.js";
83
86
  import "./chunk-5QOB7H74.js";
84
87
  import {
85
88
  captureAgentCandidateWorkspace,
86
89
  captureAgentCandidateWorkspaceFiles,
87
90
  createAgentCandidateWorkspacePort,
88
91
  sealAgentCandidateBundle
89
- } from "./chunk-AIBIRAJ6.js";
90
- import "./chunk-LKKIM5QD.js";
92
+ } from "./chunk-KSM6GFHP.js";
93
+ import "./chunk-3DW5DEKQ.js";
91
94
  import {
92
95
  AGENTIC_PROFILE_RESOURCE_ROOT,
96
+ LIFTED_FINDING_ANALYST_ID,
97
+ ROLLOUT_POLICY_BOUNDS,
98
+ ROLLOUT_POLICY_EXTENSION,
93
99
  agenticGenerator,
100
+ applyRolloutPolicyToProfile,
94
101
  commandVerifier,
102
+ defaultBuildPrompt,
103
+ enumerateNeighborPolicies,
95
104
  improve,
96
105
  improvementDriver,
97
- rawTraceDistiller
98
- } from "./chunk-4AMAFNUD.js";
106
+ isAnalystFinding,
107
+ normalizeRolloutPolicy,
108
+ parseRolloutPolicy,
109
+ rawTraceDistiller,
110
+ rawTraceEvidenceProblem,
111
+ requiresRawTraceEvidence,
112
+ rolloutPolicyProposer,
113
+ serializeRolloutPolicy,
114
+ structuralRolloutPolicyFromProfile,
115
+ summarizeFindings,
116
+ toAnalystFindings,
117
+ worktreeChangedPaths
118
+ } from "./chunk-7FJJUC73.js";
99
119
  import {
100
120
  AGENT_CANDIDATE_EXECUTION_SUPPORT,
101
121
  CANDIDATE_KNOWLEDGE_RETRIEVAL_CONFIG_ENV,
@@ -113,14 +133,16 @@ import {
113
133
  persistCandidateOutputArtifact,
114
134
  prepareAgentCandidateExecution,
115
135
  verifyAgentCandidateBundle
116
- } from "./chunk-TGDHHHH4.js";
117
- import {
118
- composeRuntimeHooks,
119
- defineRuntimeHooks,
120
- notifyRuntimeDecisionPoint,
121
- notifyRuntimeHookEvent
122
- } from "./chunk-KVJQV342.js";
136
+ } from "./chunk-LJLG734E.js";
137
+ import "./chunk-ZUCUAFVF.js";
123
138
  import "./chunk-DPEUKJRO.js";
139
+ import {
140
+ buildDriverSystem,
141
+ optimizerMethod,
142
+ researchDriverNote,
143
+ strategyAuthorMethod
144
+ } from "./chunk-ROILMKDL.js";
145
+ import "./chunk-UPWGXKXB.js";
124
146
  import {
125
147
  INTELLIGENCE_WIRE_VERSION,
126
148
  buildLoopOtelSpans,
@@ -135,7 +157,14 @@ import {
135
157
  sanitizeKnowledgeReadinessReport,
136
158
  sanitizeRuntimeStreamEvent
137
159
  } from "./chunk-2VZYRB55.js";
138
- import "./chunk-IKGCKPDX.js";
160
+ import {
161
+ composeRuntimeHooks,
162
+ defineRuntimeHooks,
163
+ notifyRuntimeDecisionPoint,
164
+ notifyRuntimeHookEvent,
165
+ runBrainLoop,
166
+ runLocalHarness
167
+ } from "./chunk-SQ3ZJH3Y.js";
139
168
  import "./chunk-IMSNJSXH.js";
140
169
  import "./chunk-M6MD6JBS.js";
141
170
  import "./chunk-3MDZX7YU.js";
@@ -248,130 +277,483 @@ function findingLines(findings) {
248
277
  }
249
278
  function toolBuildPrompt(args) {
250
279
  return [
251
- "You are building a new TOOL for this codebase to address the gaps below.",
252
- "Write the tool as a small, self-contained module PLUS tests that exercise it.",
253
- "The tool must compile and its tests must pass \u2014 they will be run automatically;",
254
- "if verification fails you will get the error and another attempt. Do not commit;",
255
- "leave the changes in the working tree.",
280
+ "You are building a new TOOL for this codebase \u2014 a capability the agent measurably lacks,",
281
+ "evidenced by the failure findings at the bottom. The tool is an experiment: after it is",
282
+ "built and verified, its marginal lift is measured on held-out tasks, and only a real lift",
283
+ "promotes it.",
284
+ "",
285
+ optimizerMethod,
286
+ "",
287
+ "THE SURFACE \u2014 what a deliverable tool looks like here:",
288
+ "- ONE small, self-contained module PLUS tests that exercise its contract (what callers rely",
289
+ " on), not its internals. The tests are the experiment for sub-goal correctness \u2014 write the",
290
+ " test that would fail if your hypothesis about the gap were wrong.",
291
+ "- It must compile and its tests must pass \u2014 they run automatically; on failure you get the",
292
+ " verifier output and another attempt, resuming on top of your own edits (fix in place, do",
293
+ " not start over).",
294
+ "- Match the codebase grain: reuse its existing helpers, style, and test framework; a tool",
295
+ " that fights the codebase is the wrong tool even if it passes.",
296
+ "- Do not commit; leave the changes in the working tree.",
256
297
  "",
257
- "Gaps the tool should close:",
298
+ "FINDINGS \u2014 ranked evidence from real failed runs (the gaps the tool must close):",
258
299
  ...findingLines(args.findings)
259
300
  ].join("\n");
260
301
  }
261
302
  function mcpBuildPrompt(args) {
262
303
  return [
263
- "You are building a new MCP SERVER (Model Context Protocol) that exposes",
264
- "tool(s) addressing the gaps below, so any harness can mount it.",
265
- "Requirements that WILL be checked by booting the server:",
304
+ "You are building a new MCP SERVER (Model Context Protocol) exposing tool(s) that close the",
305
+ "capability gaps evidenced by the failure findings at the bottom, so any harness can mount",
306
+ "them. The server is an experiment: after it is built and boot-verified, its marginal lift is",
307
+ "measured on held-out tasks, and only a real lift promotes it.",
308
+ "",
309
+ optimizerMethod,
310
+ "",
311
+ "RESEARCH FIRST \u2014 ADOPT BEFORE BUILD: you may discover and ADOPT an existing external MCP",
312
+ "server if it fits the gaps better than building one. Registries and vendor docs list",
313
+ "maintained servers for most common capabilities (web search, fetch, GitHub, filesystems,",
314
+ "databases). To adopt, deliver a short adoption note instead of an implementation: the",
315
+ "server's launch command or HTTP endpoint, and the API key it needs BY NAME (e.g.",
316
+ "EXA_API_KEY) \u2014 never a key value; provisioning injects the value at materialize time. If",
317
+ "your environment has no web access, decide from what you already know and say so.",
318
+ "",
319
+ "THE SURFACE \u2014 what a deliverable MCP server looks like here (checked by BOOTING it):",
266
320
  "- it starts over stdio and answers the MCP `initialize` handshake,",
267
- "- `tools/list` returns at least one tool with a valid input schema.",
268
- "Newline-delimited JSON-RPC 2.0, protocol version 2024-11-05. Include a start",
269
- "command (e.g. a package.json `start` script or a clear entrypoint). If the",
270
- "boot-and-probe fails you will get the error and another attempt. Do not",
271
- "commit; leave the changes in the working tree.",
321
+ "- `tools/list` returns at least one tool with a valid input schema,",
322
+ "- newline-delimited JSON-RPC 2.0, protocol version 2024-11-05,",
323
+ "- a clear start command (a package.json `start` script or an obvious entrypoint).",
324
+ "Design the tool surface for the FINDINGS, not for generality: each exposed tool should map to",
325
+ "a named failure mechanism, with a description that tells the agent when to reach for it (a",
326
+ "tool the agent never calls measures zero). If the boot-and-probe fails you get the error and",
327
+ "another attempt, resuming on top of your own edits. Do not commit; leave the changes in the",
328
+ "working tree.",
272
329
  "",
273
- "Capabilities the server should provide:",
330
+ "FINDINGS \u2014 ranked evidence from real failed runs (the capabilities the server must provide):",
274
331
  ...findingLines(args.findings)
275
332
  ].join("\n");
276
333
  }
277
334
 
278
- // src/improvement/mcp-serve-verifier.ts
279
- import { spawn } from "child_process";
280
- import { createInterface } from "readline";
281
- var PROTOCOL_VERSION = "2024-11-05";
282
- function mcpServeVerifier(spec) {
283
- const timeoutMs = spec.timeoutMs ?? 3e4;
284
- const minTools = spec.minTools ?? 1;
285
- return (worktreePath) => new Promise((resolve, reject) => {
286
- const child = spawn(spec.command, spec.args ?? [], {
287
- cwd: worktreePath,
288
- stdio: ["pipe", "pipe", "pipe"],
289
- env: { ...process.env, ...spec.env }
290
- });
291
- const stderr = [];
292
- let settled = false;
293
- let nextId = 1;
294
- const initId = nextId++;
295
- let listId = -1;
296
- const settle = (fn) => {
297
- if (settled) return;
298
- settled = true;
299
- clearTimeout(timer);
300
- rl.close();
301
- child.kill("SIGKILL");
302
- fn();
303
- };
304
- const withStderr = (msg) => stderr.length > 0 ? `${msg}
305
- stderr:
306
- ${stderr.join("").slice(-2e3)}` : msg;
307
- const pass = () => settle(() => resolve({ ok: true }));
308
- const failCandidate = (msg) => settle(() => resolve({ ok: false, feedback: withStderr(msg) }));
309
- const setupFault = (err) => settle(() => reject(err));
310
- const failStdin = (err) => failCandidate(`writing to MCP server stdin failed: ${err.message}`);
311
- const send = (msg) => {
312
- try {
313
- child.stdin.write(`${JSON.stringify(msg)}
314
- `);
315
- return true;
316
- } catch (err) {
317
- failStdin(err);
318
- return false;
335
+ // src/improvement/campaign-otlp.ts
336
+ import { readdirSync, readFileSync } from "fs";
337
+ import { basename, dirname, join, resolve } from "path";
338
+ import { OPENINFERENCE_SPAN_KIND } from "@tangle-network/agent-eval/traces";
339
+ var MAX_WALK_DEPTH = 4;
340
+ function campaignCellSpansToOtlp(content, cell, opts = {}) {
341
+ const records = parseCampaignSpans(content, cell.cellId);
342
+ if (records.length === 0) return [];
343
+ const serviceName = opts.serviceName ?? "campaign";
344
+ const key = cell.cellKey ?? cell.cellId;
345
+ const traceId = foldTo32Hex(key);
346
+ const rootSpanId = foldTo16Hex(`${key}::root`);
347
+ const startMs = Math.min(...records.map((r) => r.startMs));
348
+ const endMs = Math.max(...records.map((r) => r.startMs + (r.durationMs ?? 0)));
349
+ const anyError = records.some((r) => r.error !== void 0);
350
+ const resource = {
351
+ attributes: {
352
+ "service.name": serviceName,
353
+ "campaign.cell_id": cell.cellId,
354
+ ...cell.cellKey ? { "campaign.cell_dir": cell.cellKey } : {}
355
+ }
356
+ };
357
+ const lines = [
358
+ JSON.stringify({
359
+ trace_id: traceId,
360
+ span_id: rootSpanId,
361
+ parent_span_id: "",
362
+ name: `cell.${cell.cellId}`,
363
+ start_time: msToIso(startMs),
364
+ end_time: msToIso(endMs),
365
+ status: anyError ? { code: "STATUS_CODE_ERROR", message: "one or more spans errored" } : { code: "STATUS_CODE_OK", message: "" },
366
+ resource,
367
+ attributes: {
368
+ [OPENINFERENCE_SPAN_KIND]: "AGENT",
369
+ "agent.name": cell.cellId
319
370
  }
320
- };
321
- child.on("error", (err) => {
322
- const code = err.code;
323
- setupFault(
324
- code === "ENOENT" ? new Error(
325
- `mcpServeVerifier: '${spec.command}' not found in PATH (setup bug, not a failed candidate)`
326
- ) : new Error(`mcpServeVerifier: '${spec.command}' failed to spawn: ${err.message}`)
327
- );
328
- });
329
- child.on("exit", (code, signal) => {
330
- failCandidate(`MCP server exited (code ${code}, signal ${signal}) before serving`);
371
+ })
372
+ ];
373
+ for (let i = 0; i < records.length; i++) {
374
+ const r = records[i];
375
+ lines.push(
376
+ JSON.stringify({
377
+ trace_id: traceId,
378
+ span_id: foldTo16Hex(`${key}::${i}`),
379
+ parent_span_id: rootSpanId,
380
+ name: r.name,
381
+ start_time: msToIso(r.startMs),
382
+ end_time: msToIso(r.startMs + (r.durationMs ?? 0)),
383
+ status: r.error === void 0 ? { code: "STATUS_CODE_OK", message: "" } : { code: "STATUS_CODE_ERROR", message: r.error },
384
+ resource,
385
+ attributes: r.attributes
386
+ })
387
+ );
388
+ }
389
+ return lines;
390
+ }
391
+ function convertCampaignDirToOtlp(dir, opts = {}) {
392
+ const root = resolve(dir);
393
+ const files = findSpansFiles(root, MAX_WALK_DEPTH);
394
+ const lines = [];
395
+ for (const file of files) {
396
+ let content;
397
+ try {
398
+ content = readFileSync(file, "utf8");
399
+ } catch {
400
+ continue;
401
+ }
402
+ const cellDir = dirname(file);
403
+ lines.push(
404
+ ...campaignCellSpansToOtlp(content, { cellId: basename(cellDir), cellKey: cellDir }, opts)
405
+ );
406
+ }
407
+ return lines.length > 0 ? `${lines.join("\n")}
408
+ ` : "";
409
+ }
410
+ function campaignTraceResolver(opts) {
411
+ return (ctx) => {
412
+ const priorDir = ctx.generation <= 0 ? join(opts.runDir, "baseline") : join(opts.runDir, `gen-${ctx.generation - 1}`);
413
+ const prior = convertCampaignDirToOtlp(priorDir, opts);
414
+ if (prior) return prior;
415
+ return convertCampaignDirToOtlp(opts.runDir, opts);
416
+ };
417
+ }
418
+ function parseCampaignSpans(content, cellId) {
419
+ const out = [];
420
+ for (const line of content.split("\n")) {
421
+ const trimmed = line.trim();
422
+ if (!trimmed) continue;
423
+ let raw;
424
+ try {
425
+ raw = JSON.parse(trimmed);
426
+ } catch {
427
+ continue;
428
+ }
429
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) continue;
430
+ const o = raw;
431
+ if (typeof o.name !== "string" || typeof o.startMs !== "number") continue;
432
+ const attributes = { "campaign.cell_id": cellId };
433
+ for (const [k, v] of Object.entries(o)) {
434
+ if (k === "name" || k === "cellId" || k === "startMs" || k === "durationMs") continue;
435
+ attributes[k] = v;
436
+ }
437
+ out.push({
438
+ name: o.name,
439
+ cellId,
440
+ startMs: o.startMs,
441
+ ...typeof o.durationMs === "number" ? { durationMs: o.durationMs } : {},
442
+ attributes,
443
+ ...typeof o.error === "string" ? { error: o.error } : {}
331
444
  });
332
- child.stdin.on("error", failStdin);
333
- child.stderr.on("data", (d) => stderr.push(String(d)));
334
- const rl = createInterface({ input: child.stdout });
335
- rl.on("line", (line) => {
336
- let msg;
337
- try {
338
- msg = JSON.parse(line);
339
- } catch {
340
- return;
341
- }
342
- if (!msg || typeof msg !== "object") return;
343
- if (msg.id === initId) {
344
- if (msg.error) return failCandidate(`initialize errored: ${JSON.stringify(msg.error)}`);
345
- if (!send({ jsonrpc: "2.0", method: "notifications/initialized" })) return;
346
- listId = nextId++;
347
- send({ jsonrpc: "2.0", id: listId, method: "tools/list" });
348
- return;
349
- }
350
- if (msg.id === listId) {
351
- if (msg.error) return failCandidate(`tools/list errored: ${JSON.stringify(msg.error)}`);
352
- const tools = msg.result?.tools;
353
- if (!Array.isArray(tools)) return failCandidate("tools/list result has no tools array");
354
- if (tools.length < minTools) {
355
- return failCandidate(`tools/list returned ${tools.length} tool(s), need >= ${minTools}`);
445
+ }
446
+ return out;
447
+ }
448
+ function findSpansFiles(dir, depth) {
449
+ const out = [];
450
+ let entries;
451
+ try {
452
+ entries = readdirSync(dir, { withFileTypes: true });
453
+ } catch {
454
+ return out;
455
+ }
456
+ for (const entry of entries) {
457
+ const full = join(dir, entry.name);
458
+ if (entry.isFile() && entry.name === "spans.jsonl") {
459
+ out.push(full);
460
+ } else if (depth > 0 && entry.isDirectory() && !entry.isSymbolicLink()) {
461
+ out.push(...findSpansFiles(full, depth - 1));
462
+ }
463
+ }
464
+ return out.sort();
465
+ }
466
+ function msToIso(ms) {
467
+ return Number.isFinite(ms) && ms > 0 ? new Date(ms).toISOString() : (/* @__PURE__ */ new Date(0)).toISOString();
468
+ }
469
+ function foldTo16Hex(s) {
470
+ const a = fnv1a(s);
471
+ const b = fnv1a(`${s}::salt`);
472
+ return a + b;
473
+ }
474
+ function foldTo32Hex(s) {
475
+ return foldTo16Hex(s) + foldTo16Hex(`${s}::trace`);
476
+ }
477
+ function fnv1a(s) {
478
+ let h = 2166136261;
479
+ for (let i = 0; i < s.length; i++) {
480
+ h ^= s.charCodeAt(i);
481
+ h = Math.imul(h, 16777619) >>> 0;
482
+ }
483
+ return h.toString(16).padStart(8, "0");
484
+ }
485
+
486
+ // src/improvement/driver-loop-generator.ts
487
+ import { spawnSync } from "child_process";
488
+ import { readFileSync as readFileSync2, statSync } from "fs";
489
+ import { resolve as resolve2, sep } from "path";
490
+ var workerOutputTailChars = 2e3;
491
+ var diffMaxChars = 6e3;
492
+ var readFileDefaultBytes = 8192;
493
+ var researchResultMaxChars = 8e3;
494
+ function driverLoopGenerator(opts) {
495
+ const harness = opts.harness ?? "claude";
496
+ const buildPrompt = opts.buildPrompt ?? defaultBuildPrompt;
497
+ const run = opts.runHarness ?? runLocalHarness;
498
+ const changed = opts.changedPaths ?? worktreeChangedPaths;
499
+ const readDiff = opts.readDiff ?? worktreeDiff;
500
+ const verify = opts.verify;
501
+ return {
502
+ kind: `driver-loop:${harness}`,
503
+ async generate({ worktreePath, report, findings, maxShots, signal }) {
504
+ signal.throwIfAborted();
505
+ const briefing = buildPrompt({ report, findings });
506
+ const needsRawTraceEvidence = requiresRawTraceEvidence(findings);
507
+ const sessionCap = Math.max(1, maxShots);
508
+ let sessionsUsed = 0;
509
+ const groundVerify = async () => {
510
+ signal.throwIfAborted();
511
+ if (changed(worktreePath).length === 0) {
512
+ return { ok: false, feedback: "the working tree has no changes \u2014 nothing to verify" };
513
+ }
514
+ if (needsRawTraceEvidence) {
515
+ const problem = rawTraceEvidenceProblem(worktreePath, findings);
516
+ if (problem) return { ok: false, feedback: problem };
517
+ }
518
+ if (!verify) {
519
+ return { ok: true, feedback: "no verifier configured: a dirty tree is the candidate" };
356
520
  }
357
- return pass();
521
+ const result = await verify(worktreePath, signal);
522
+ signal.throwIfAborted();
523
+ return result;
524
+ };
525
+ const execute = async (name, args) => {
526
+ signal.throwIfAborted();
527
+ switch (name) {
528
+ case "run_worker": {
529
+ const instruction = typeof args.instruction === "string" ? args.instruction.trim() : "";
530
+ if (instruction.length === 0) {
531
+ return "error: run_worker requires a non-empty `instruction`";
532
+ }
533
+ if (sessionsUsed >= sessionCap) {
534
+ return `error: worker-session budget exhausted (${sessionsUsed}/${sessionCap} used). Inspect and verify what exists, then stop with your final assessment.`;
535
+ }
536
+ sessionsUsed += 1;
537
+ const result = await run({
538
+ harness,
539
+ cwd: worktreePath,
540
+ taskPrompt: instruction,
541
+ ...opts.timeoutMs !== void 0 ? { timeoutMs: opts.timeoutMs } : {},
542
+ signal
543
+ });
544
+ signal.throwIfAborted();
545
+ if (result.aborted) {
546
+ throw new Error("driverLoopGenerator: worker session was cancelled by the caller");
547
+ }
548
+ return JSON.stringify({
549
+ session: `${sessionsUsed}/${sessionCap}`,
550
+ exitCode: result.exitCode,
551
+ timedOut: result.timedOut,
552
+ aborted: result.aborted ?? false,
553
+ killedBySignal: result.killedBySignal,
554
+ durationMs: result.durationMs,
555
+ changedPaths: changed(worktreePath),
556
+ stdoutTail: tail(result.stdout, workerOutputTailChars),
557
+ stderrTail: tail(result.stderr, workerOutputTailChars)
558
+ });
559
+ }
560
+ case "inspect_worktree": {
561
+ const paths = changed(worktreePath);
562
+ const diff = truncate(readDiff(worktreePath), diffMaxChars);
563
+ return JSON.stringify({
564
+ changedPaths: paths,
565
+ diff: diff.length > 0 ? diff : "(no tracked-file diff \u2014 new files are untracked; read_file them)"
566
+ });
567
+ }
568
+ case "read_file":
569
+ return readWorktreeFile(worktreePath, args);
570
+ case "research": {
571
+ if (!opts.research) return "error: research tool is not provisioned in this run";
572
+ const query = typeof args.query === "string" ? args.query.trim() : "";
573
+ if (query.length === 0) return "error: research requires a non-empty `query`";
574
+ const result = await opts.research(query);
575
+ signal.throwIfAborted();
576
+ return truncate(result, researchResultMaxChars);
577
+ }
578
+ case "run_verifier": {
579
+ const result = await groundVerify();
580
+ return JSON.stringify({
581
+ ok: result.ok,
582
+ feedback: truncate(result.feedback ?? "", 4e3)
583
+ });
584
+ }
585
+ default:
586
+ return `error: unknown tool: ${name}`;
587
+ }
588
+ };
589
+ await runBrainLoop({
590
+ chat: opts.brain,
591
+ tools: opts.research ? [...driverToolSpecs, researchToolSpec] : driverToolSpecs,
592
+ execute,
593
+ initialMessages: [
594
+ {
595
+ role: "system",
596
+ content: opts.research ? `${buildDriverSystem}
597
+
598
+ ${researchDriverNote}` : buildDriverSystem
599
+ },
600
+ {
601
+ role: "user",
602
+ content: [
603
+ `THE BUILD BRIEF (the contract your workers must satisfy \u2014 fold what each needs into its instruction; workers never see this brief):`,
604
+ "",
605
+ briefing,
606
+ "",
607
+ `Worker-session budget: ${sessionCap}. The worktree is a fresh checkout at ${worktreePath}.`
608
+ ].join("\n")
609
+ }
610
+ ],
611
+ maxTurns: opts.maxTurns ?? Math.max(8, 2 + sessionCap * 3),
612
+ hooks: { stopBefore: () => signal.aborted }
613
+ });
614
+ signal.throwIfAborted();
615
+ const verdict = await groundVerify();
616
+ signal.throwIfAborted();
617
+ if (!verdict.ok) return { applied: false, summary: "" };
618
+ return { applied: true, summary: summarizeFindings(findings) };
619
+ }
620
+ };
621
+ }
622
+ var driverToolSpecs = [
623
+ {
624
+ type: "function",
625
+ function: {
626
+ name: "run_worker",
627
+ description: "Run ONE coding-harness session in the worktree with your instruction as its entire goal. The worktree persists between sessions. Sessions are capped \u2014 author each instruction richly (outcome, context, placement, the check it is held to).",
628
+ parameters: {
629
+ type: "object",
630
+ properties: {
631
+ instruction: {
632
+ type: "string",
633
+ description: "The complete, self-contained goal for this worker session."
634
+ }
635
+ },
636
+ required: ["instruction"]
358
637
  }
359
- });
360
- const timer = setTimeout(
361
- () => failCandidate(`MCP server did not complete the handshake within ${timeoutMs}ms`),
362
- timeoutMs
638
+ }
639
+ },
640
+ {
641
+ type: "function",
642
+ function: {
643
+ name: "inspect_worktree",
644
+ description: "Current git state of the worktree: changed paths + the tracked-file diff (truncated). New untracked files show in changedPaths only \u2014 read_file them.",
645
+ parameters: { type: "object", properties: {} }
646
+ }
647
+ },
648
+ {
649
+ type: "function",
650
+ function: {
651
+ name: "read_file",
652
+ description: "Read one file from the worktree (paths are worktree-relative).",
653
+ parameters: {
654
+ type: "object",
655
+ properties: {
656
+ path: { type: "string", description: "Worktree-relative file path." },
657
+ maxBytes: { type: "number", description: "Byte cap (default 8192)." }
658
+ },
659
+ required: ["path"]
660
+ }
661
+ }
662
+ },
663
+ {
664
+ type: "function",
665
+ function: {
666
+ name: "run_verifier",
667
+ description: "Run the intrinsic check of the surface (compile+tests / boot-and-probe). Its result \u2014 not your judgment \u2014 decides whether the candidate is kept.",
668
+ parameters: { type: "object", properties: {} }
669
+ }
670
+ }
671
+ ];
672
+ var researchToolSpec = {
673
+ type: "function",
674
+ function: {
675
+ name: "research",
676
+ description: "Search external sources (MCP registries, vendor docs) for an EXISTING server that closes the capability gap \u2014 the adopt-not-build check. Returns text findings.",
677
+ parameters: {
678
+ type: "object",
679
+ properties: {
680
+ query: { type: "string", description: "What capability / server to search for." }
681
+ },
682
+ required: ["query"]
683
+ }
684
+ }
685
+ };
686
+ function worktreeDiff(worktreePath) {
687
+ const result = spawnSync("git", ["diff"], { cwd: worktreePath, encoding: "utf-8" });
688
+ if (result.error) {
689
+ throw new Error(
690
+ `driverLoopGenerator: git diff failed to spawn in ${worktreePath}: ${result.error.message}`
691
+ );
692
+ }
693
+ if (result.status !== 0) {
694
+ throw new Error(
695
+ `driverLoopGenerator: git diff exited ${result.status} in ${worktreePath}: ${result.stderr.trim()}`
363
696
  );
364
- send({
365
- jsonrpc: "2.0",
366
- id: initId,
367
- method: "initialize",
368
- params: {
369
- protocolVersion: PROTOCOL_VERSION,
370
- capabilities: {},
371
- clientInfo: { name: "agent-runtime-mcp-verify", version: "0" }
697
+ }
698
+ return result.stdout;
699
+ }
700
+ function readWorktreeFile(worktreePath, args) {
701
+ const rel = typeof args.path === "string" ? args.path : "";
702
+ if (rel.length === 0) return "error: read_file requires `path`";
703
+ const root = resolve2(worktreePath);
704
+ const target = resolve2(root, rel);
705
+ if (target !== root && !target.startsWith(root + sep)) {
706
+ return `error: path escapes the worktree: ${rel}`;
707
+ }
708
+ const maxBytes = typeof args.maxBytes === "number" && args.maxBytes > 0 ? Math.min(args.maxBytes, 65536) : readFileDefaultBytes;
709
+ try {
710
+ const size = statSync(target).size;
711
+ const body = readFileSync2(target, "utf-8").slice(0, maxBytes);
712
+ return size > maxBytes ? `${body}
713
+ \u2026 (${size - maxBytes} bytes truncated)` : body;
714
+ } catch (e) {
715
+ return `error: ${e instanceof Error ? e.message : String(e)}`;
716
+ }
717
+ }
718
+ function tail(s, n) {
719
+ const trimmed = s.trim();
720
+ return trimmed.length <= n ? trimmed : `\u2026${trimmed.slice(-n)}`;
721
+ }
722
+ function truncate(s, n) {
723
+ return s.length <= n ? s : `${s.slice(0, n - 1)}\u2026`;
724
+ }
725
+
726
+ // src/improvement/mcp-serve-verifier.ts
727
+ function mcpServeVerifier(spec) {
728
+ const minTools = spec.minTools ?? 1;
729
+ return async (worktreePath) => {
730
+ let conn;
731
+ try {
732
+ conn = await connectStdioMcp({
733
+ command: spec.command,
734
+ ...spec.args ? { args: spec.args } : {},
735
+ cwd: worktreePath,
736
+ ...spec.env ? { env: spec.env } : {},
737
+ ...spec.timeoutMs !== void 0 ? { timeoutMs: spec.timeoutMs } : {}
738
+ });
739
+ } catch (err) {
740
+ if (err instanceof McpSpawnFault) {
741
+ throw new Error(`mcpServeVerifier: ${err.message}`);
372
742
  }
373
- });
374
- });
743
+ return { ok: false, feedback: err instanceof Error ? err.message : String(err) };
744
+ }
745
+ try {
746
+ if (conn.tools.length < minTools) {
747
+ return {
748
+ ok: false,
749
+ feedback: `tools/list returned ${conn.tools.length} tool(s), need >= ${minTools}`
750
+ };
751
+ }
752
+ return { ok: true };
753
+ } finally {
754
+ await conn.close();
755
+ }
756
+ };
375
757
  }
376
758
 
377
759
  // src/improvement/profile-diff-proposer.ts
@@ -439,7 +821,7 @@ function parseSerializedProfile(surface) {
439
821
  }
440
822
 
441
823
  // src/improvement/reflective-generator.ts
442
- import { spawnSync } from "child_process";
824
+ import { spawnSync as spawnSync2 } from "child_process";
443
825
  function reflectiveGenerator(opts) {
444
826
  return {
445
827
  kind: "reflective",
@@ -457,7 +839,7 @@ function reflectiveGenerator(opts) {
457
839
  };
458
840
  }
459
841
  function applyPatch(patch, cwd) {
460
- const result = spawnSync("git", ["apply", "--whitespace=fix", "-p0", "-"], {
842
+ const result = spawnSync2("git", ["apply", "--whitespace=fix", "-p0", "-"], {
461
843
  cwd,
462
844
  input: patch,
463
845
  encoding: "utf-8"
@@ -1540,22 +1922,29 @@ export {
1540
1922
  InMemoryConversationJournal,
1541
1923
  InMemoryRuntimeSessionStore,
1542
1924
  JudgeError,
1925
+ LIFTED_FINDING_ANALYST_ID,
1543
1926
  NotFoundError,
1544
1927
  PlannerError,
1545
1928
  RESEARCH_SUPERVISOR_SYSTEM_PROMPT,
1929
+ ROLLOUT_POLICY_BOUNDS,
1930
+ ROLLOUT_POLICY_EXTENSION,
1546
1931
  RuntimeRunStateError,
1547
1932
  SqlConversationJournal,
1548
1933
  ValidationError,
1549
1934
  agenticGenerator,
1550
1935
  applyExactAgentProfileDiff,
1936
+ applyRolloutPolicyToProfile,
1551
1937
  applyRunRecordDefaults,
1552
1938
  auditLoopRunner,
1553
1939
  buildAgentCandidateBundle,
1940
+ buildDriverSystem,
1554
1941
  buildForwardHeaders,
1555
1942
  buildKnowledgeImprovementExperimentBundles,
1556
1943
  buildLoopOtelSpans,
1557
1944
  buildLoopSpanNodes,
1558
1945
  buildRuntimeEventOtelSpans,
1946
+ campaignCellSpansToOtlp,
1947
+ campaignTraceResolver,
1559
1948
  candidateExecutionClaim,
1560
1949
  candidateKnowledgeExecutionPaths,
1561
1950
  captureAgentCandidateWorkspace,
@@ -1564,6 +1953,7 @@ export {
1564
1953
  commandVerifier,
1565
1954
  composeRuntimeHooks,
1566
1955
  computeBackoff,
1956
+ convertCampaignDirToOtlp,
1567
1957
  createAgentCandidateWorkspacePort,
1568
1958
  createAgentKnowledgeReadinessCheck,
1569
1959
  createConversationBackend,
@@ -1578,19 +1968,24 @@ export {
1578
1968
  createSupervisedKnowledgeUpdater,
1579
1969
  d1ToSqlAdapter,
1580
1970
  decideKnowledgeReadiness,
1971
+ defaultBuildPrompt,
1581
1972
  defaultIsRetryable,
1582
1973
  defineConversation,
1583
1974
  defineRuntimeHooks,
1584
1975
  deriveExecutionId,
1585
1976
  disposePreparedAgentCandidateExecution,
1977
+ driverLoopGenerator,
1978
+ enumerateNeighborPolicies,
1586
1979
  exactProcessProviderAsCandidateExecutor,
1587
1980
  executePreparedAgentCandidate,
1588
1981
  exportEvalRuns,
1982
+ findingLines,
1589
1983
  formatSupervisedKnowledgeTask,
1590
1984
  getModels,
1591
1985
  handleChatTurn,
1592
1986
  improve,
1593
1987
  improvementDriver,
1988
+ isAnalystFinding,
1594
1989
  isDelegatedLoopMode,
1595
1990
  isDepthExceeded,
1596
1991
  knowledgeReadinessDeliverable,
@@ -1600,11 +1995,14 @@ export {
1600
1995
  mcpServeVerifier,
1601
1996
  mcpToolsForRuntimeMcp,
1602
1997
  mcpToolsForRuntimeMcpSubset,
1998
+ normalizeRolloutPolicy,
1603
1999
  notifyRuntimeDecisionPoint,
1604
2000
  notifyRuntimeHookEvent,
2001
+ optimizerMethod,
1605
2002
  parseExactAgentProfile,
1606
2003
  parseExactAgentProfileDiff,
1607
2004
  parseLoopRunnerArgv,
2005
+ parseRolloutPolicy,
1608
2006
  persistCandidateOutputArtifact,
1609
2007
  prepareAgentCandidateExecution,
1610
2008
  profileDiffProposer,
@@ -1613,10 +2011,12 @@ export {
1613
2011
  readinessServerSentEvent,
1614
2012
  recoverExpiredAgentCandidateExecution,
1615
2013
  reflectiveGenerator,
2014
+ researchDriverNote,
1616
2015
  researchLoopRunner,
1617
2016
  resolveAgentBackend,
1618
2017
  resolveChatModel,
1619
2018
  resolveRouterBaseUrl,
2019
+ rolloutPolicyProposer,
1620
2020
  runAgentTask,
1621
2021
  runAgentTaskStream,
1622
2022
  runConversation,
@@ -1634,10 +2034,14 @@ export {
1634
2034
  sanitizeRuntimeStreamEvent,
1635
2035
  sealAgentCandidateBundle,
1636
2036
  selfImproveLoopRunner,
2037
+ serializeRolloutPolicy,
1637
2038
  sleep,
1638
2039
  slugifySpeaker,
1639
2040
  startRuntimeRun,
2041
+ strategyAuthorMethod,
1640
2042
  streamToolLoop,
2043
+ structuralRolloutPolicyFromProfile,
2044
+ toAnalystFindings,
1641
2045
  toolBuildPrompt,
1642
2046
  turnId,
1643
2047
  validateChatModelId,