@tangle-network/agent-runtime 0.104.0 → 0.106.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/README.md +176 -42
  2. package/dist/activation-CRjVfOiy.js +203 -0
  3. package/dist/activation-CRjVfOiy.js.map +1 -0
  4. package/dist/activation-DyWB0K6E.d.ts +98 -0
  5. package/dist/agent.d.ts +216 -234
  6. package/dist/agent.js +615 -547
  7. package/dist/agent.js.map +1 -1
  8. package/dist/analyst-loop-DGdtVENg.js +517 -0
  9. package/dist/analyst-loop-DGdtVENg.js.map +1 -0
  10. package/dist/analyst-loop.d.ts +10 -43
  11. package/dist/analyst-loop.js +2 -11
  12. package/dist/backends-Dy8NujB4.js +713 -0
  13. package/dist/backends-Dy8NujB4.js.map +1 -0
  14. package/dist/candidate-execution/index.d.ts +4 -192
  15. package/dist/candidate-execution/index.js +5 -66
  16. package/dist/candidate-execution-DqMbv1rU.js +488 -0
  17. package/dist/candidate-execution-DqMbv1rU.js.map +1 -0
  18. package/dist/coder-yhVWbdWc.js +40 -0
  19. package/dist/coder-yhVWbdWc.js.map +1 -0
  20. package/dist/conversation-XucG_K3l.js +1265 -0
  21. package/dist/conversation-XucG_K3l.js.map +1 -0
  22. package/dist/conversation.d.ts +2 -804
  23. package/dist/conversation.js +2 -55
  24. package/dist/environment-provider-CfLUmKmf.js +1168 -0
  25. package/dist/environment-provider-CfLUmKmf.js.map +1 -0
  26. package/dist/environment-provider-IUGU3epE.d.ts +964 -0
  27. package/dist/environment-provider.d.ts +2 -78
  28. package/dist/environment-provider.js +2 -18
  29. package/dist/errors-DEAvWQPy.js +111 -0
  30. package/dist/errors-DEAvWQPy.js.map +1 -0
  31. package/dist/improvement-adapter-Cr5TBSji.d.ts +166 -0
  32. package/dist/improvement-cycle-C095kS_g.js +2624 -0
  33. package/dist/improvement-cycle-C095kS_g.js.map +1 -0
  34. package/dist/index-BGdxAwfO.d.ts +838 -0
  35. package/dist/index-C-FYUuFG.d.ts +193 -0
  36. package/dist/index-CbNM40xG.d.ts +140 -0
  37. package/dist/index-DruSKs3Z.d.ts +7224 -0
  38. package/dist/index-Efjb3nrQ.d.ts +671 -0
  39. package/dist/index.d.ts +14 -1134
  40. package/dist/index.js +2134 -1972
  41. package/dist/index.js.map +1 -1
  42. package/dist/intelligence.d.ts +776 -888
  43. package/dist/intelligence.js +1466 -1410
  44. package/dist/intelligence.js.map +1 -1
  45. package/dist/{kb-gate-CwHO0vz6.d.ts → kb-gate-C8z2juK8.d.ts} +33 -31
  46. package/dist/kb-gate-DpaSwXVx.js +80 -0
  47. package/dist/kb-gate-DpaSwXVx.js.map +1 -0
  48. package/dist/knowledge-Ku-mPP4f.js +433 -0
  49. package/dist/knowledge-Ku-mPP4f.js.map +1 -0
  50. package/dist/knowledge.d.ts +2 -150
  51. package/dist/knowledge.js +2 -40
  52. package/dist/local-harness-Dh8PJ0ot.d.ts +455 -0
  53. package/dist/loop-runner-bin-BXsFEUcf.d.ts +162 -0
  54. package/dist/loop-runner-bin-BwjQ1NfH.js +268 -0
  55. package/dist/loop-runner-bin-BwjQ1NfH.js.map +1 -0
  56. package/dist/loop-runner-bin.d.ts +2 -17
  57. package/dist/loop-runner-bin.js +2 -24
  58. package/dist/loops.d.ts +5 -4164
  59. package/dist/loops.js +8 -419
  60. package/dist/mcp/bin.d.ts +1 -1
  61. package/dist/mcp/bin.js +116 -146
  62. package/dist/mcp/bin.js.map +1 -1
  63. package/dist/mcp/index.d.ts +295 -437
  64. package/dist/mcp/index.js +1242 -1177
  65. package/dist/mcp/index.js.map +1 -1
  66. package/dist/mcp/memory-bin.d.ts +1 -1
  67. package/dist/mcp/memory-bin.js +37 -16
  68. package/dist/mcp/memory-bin.js.map +1 -1
  69. package/dist/memory-server-DL6cE2Ag.js +234 -0
  70. package/dist/memory-server-DL6cE2Ag.js.map +1 -0
  71. package/dist/model-resolution-Btd9iIKV.js +98 -0
  72. package/dist/model-resolution-Btd9iIKV.js.map +1 -0
  73. package/dist/openai-tools-B68JaOCx.d.ts +24 -0
  74. package/dist/openai-tools-CKLy1C7M.js +44 -0
  75. package/dist/openai-tools-CKLy1C7M.js.map +1 -0
  76. package/dist/otel-export-D34IQW1C.js +843 -0
  77. package/dist/otel-export-D34IQW1C.js.map +1 -0
  78. package/dist/platform.d.ts +188 -185
  79. package/dist/platform.js +185 -218
  80. package/dist/platform.js.map +1 -1
  81. package/dist/prepare-B53sPV7M.js +4292 -0
  82. package/dist/prepare-B53sPV7M.js.map +1 -0
  83. package/dist/primeintellect/index.d.ts +150 -147
  84. package/dist/primeintellect/index.js +626 -1004
  85. package/dist/primeintellect/index.js.map +1 -1
  86. package/dist/profiles.d.ts +296 -490
  87. package/dist/profiles.js +722 -749
  88. package/dist/profiles.js.map +1 -1
  89. package/dist/protected-model-port-BLPH5VVv.js +722 -0
  90. package/dist/protected-model-port-BLPH5VVv.js.map +1 -0
  91. package/dist/protected-model-port-BP6Z4eau.d.ts +283 -0
  92. package/dist/protected-redaction--F3v1oo8.js +200 -0
  93. package/dist/protected-redaction--F3v1oo8.js.map +1 -0
  94. package/dist/redact-D-u-rrcn.js +82 -0
  95. package/dist/redact-D-u-rrcn.js.map +1 -0
  96. package/dist/redact-kbIOjfjM.d.ts +452 -0
  97. package/dist/researcher-CoVqNhfI.js +433 -0
  98. package/dist/researcher-CoVqNhfI.js.map +1 -0
  99. package/dist/runtime-BG0BziaP.js +5408 -0
  100. package/dist/runtime-BG0BziaP.js.map +1 -0
  101. package/dist/sandbox-events-DeI5xX8P.js +316 -0
  102. package/dist/sandbox-events-DeI5xX8P.js.map +1 -0
  103. package/dist/spawn-journal-CwPvKUTa.js +456 -0
  104. package/dist/spawn-journal-CwPvKUTa.js.map +1 -0
  105. package/dist/structural-rollout-IXUEplky.js +1445 -0
  106. package/dist/structural-rollout-IXUEplky.js.map +1 -0
  107. package/dist/substrate-B0TYNrXn.js +27 -0
  108. package/dist/substrate-B0TYNrXn.js.map +1 -0
  109. package/dist/{substrate-Dyiqmd3o.d.ts → substrate-BcnuSHXm.d.ts} +57 -54
  110. package/dist/supervise-BiRutHS9.js +7321 -0
  111. package/dist/supervise-BiRutHS9.js.map +1 -0
  112. package/dist/supervisor-DTKhF-RV.js +3826 -0
  113. package/dist/supervisor-DTKhF-RV.js.map +1 -0
  114. package/dist/testing.d.ts +4 -3
  115. package/dist/testing.js +2478 -2637
  116. package/dist/testing.js.map +1 -1
  117. package/dist/tool-server-RcWgLIsL.js +141 -0
  118. package/dist/tool-server-RcWgLIsL.js.map +1 -0
  119. package/dist/trace-propagation-CJJC7SVB.js +57 -0
  120. package/dist/trace-propagation-CJJC7SVB.js.map +1 -0
  121. package/dist/types-BaIpb0XT.d.ts +492 -0
  122. package/dist/types-BevOjfTY.d.ts +765 -0
  123. package/dist/types-C9j4qg6l.d.ts +500 -0
  124. package/dist/types-Cja5OTGh.d.ts +190 -0
  125. package/dist/util-MVgdwuIS.js +145 -0
  126. package/dist/util-MVgdwuIS.js.map +1 -0
  127. package/dist/workspace-archive-BosQiotA.js +575 -0
  128. package/dist/workspace-archive-BosQiotA.js.map +1 -0
  129. package/package.json +43 -55
  130. package/skills/build-with-agent-runtime/SKILL.md +16 -9
  131. package/skills/loop-writer/SKILL.md +1 -1
  132. package/dist/activation-Cm-9MMX1.d.ts +0 -69
  133. package/dist/analyst-loop.js.map +0 -1
  134. package/dist/backends-BO4Jqoe2.d.ts +0 -134
  135. package/dist/candidate-execution/index.js.map +0 -1
  136. package/dist/chunk-2KGAN2HM.js +0 -1256
  137. package/dist/chunk-2KGAN2HM.js.map +0 -1
  138. package/dist/chunk-2QJSNOGK.js +0 -48
  139. package/dist/chunk-2QJSNOGK.js.map +0 -1
  140. package/dist/chunk-2UABGGUB.js +0 -474
  141. package/dist/chunk-2UABGGUB.js.map +0 -1
  142. package/dist/chunk-2VZYRB55.js +0 -834
  143. package/dist/chunk-2VZYRB55.js.map +0 -1
  144. package/dist/chunk-2X65HYMI.js +0 -3526
  145. package/dist/chunk-2X65HYMI.js.map +0 -1
  146. package/dist/chunk-3MDZX7YU.js +0 -125
  147. package/dist/chunk-3MDZX7YU.js.map +0 -1
  148. package/dist/chunk-3PPVCS75.js +0 -199
  149. package/dist/chunk-3PPVCS75.js.map +0 -1
  150. package/dist/chunk-5HNDYWUT.js +0 -6424
  151. package/dist/chunk-5HNDYWUT.js.map +0 -1
  152. package/dist/chunk-5IBQAPVB.js +0 -29
  153. package/dist/chunk-5IBQAPVB.js.map +0 -1
  154. package/dist/chunk-5QOB7H74.js +0 -387
  155. package/dist/chunk-5QOB7H74.js.map +0 -1
  156. package/dist/chunk-ATDFUJYI.js +0 -4728
  157. package/dist/chunk-ATDFUJYI.js.map +0 -1
  158. package/dist/chunk-B7K7V22Y.js +0 -699
  159. package/dist/chunk-B7K7V22Y.js.map +0 -1
  160. package/dist/chunk-DPEUKJRO.js +0 -27
  161. package/dist/chunk-DPEUKJRO.js.map +0 -1
  162. package/dist/chunk-FD2MBMOH.js +0 -494
  163. package/dist/chunk-FD2MBMOH.js.map +0 -1
  164. package/dist/chunk-FJI3EXU3.js +0 -2402
  165. package/dist/chunk-FJI3EXU3.js.map +0 -1
  166. package/dist/chunk-HAO4CXHP.js +0 -200
  167. package/dist/chunk-HAO4CXHP.js.map +0 -1
  168. package/dist/chunk-ISPWRSEC.js +0 -408
  169. package/dist/chunk-ISPWRSEC.js.map +0 -1
  170. package/dist/chunk-KRBFHMV6.js +0 -1228
  171. package/dist/chunk-KRBFHMV6.js.map +0 -1
  172. package/dist/chunk-L5DST3QC.js +0 -351
  173. package/dist/chunk-L5DST3QC.js.map +0 -1
  174. package/dist/chunk-M22PL4GH.js +0 -171
  175. package/dist/chunk-M22PL4GH.js.map +0 -1
  176. package/dist/chunk-NURIQBJQ.js +0 -72
  177. package/dist/chunk-NURIQBJQ.js.map +0 -1
  178. package/dist/chunk-PZZKQVQV.js +0 -52
  179. package/dist/chunk-PZZKQVQV.js.map +0 -1
  180. package/dist/chunk-Q2JSAVQ3.js +0 -671
  181. package/dist/chunk-Q2JSAVQ3.js.map +0 -1
  182. package/dist/chunk-SBTWKPVR.js +0 -5576
  183. package/dist/chunk-SBTWKPVR.js.map +0 -1
  184. package/dist/chunk-SGKPNBXE.js +0 -60
  185. package/dist/chunk-SGKPNBXE.js.map +0 -1
  186. package/dist/chunk-SNSMRT6H.js +0 -680
  187. package/dist/chunk-SNSMRT6H.js.map +0 -1
  188. package/dist/chunk-STJEHM5F.js +0 -1338
  189. package/dist/chunk-STJEHM5F.js.map +0 -1
  190. package/dist/chunk-UPWGXKXB.js +0 -254
  191. package/dist/chunk-UPWGXKXB.js.map +0 -1
  192. package/dist/chunk-YEJR7IXO.js +0 -68
  193. package/dist/chunk-YEJR7IXO.js.map +0 -1
  194. package/dist/chunk-ZXICDSAK.js +0 -907
  195. package/dist/chunk-ZXICDSAK.js.map +0 -1
  196. package/dist/completion-gate-Bv47cOnn.d.ts +0 -256
  197. package/dist/conversation.js.map +0 -1
  198. package/dist/coordination-CxtzMxSM.d.ts +0 -2570
  199. package/dist/environment-provider.js.map +0 -1
  200. package/dist/improve--2A0gK1-.d.ts +0 -440
  201. package/dist/improvement-adapter-HAZz-7vK.d.ts +0 -203
  202. package/dist/knowledge.js.map +0 -1
  203. package/dist/local-harness-CtK9dSny.d.ts +0 -175
  204. package/dist/loop-runner-bin-DUOGtvOl.d.ts +0 -207
  205. package/dist/loop-runner-bin.js.map +0 -1
  206. package/dist/loops.js.map +0 -1
  207. package/dist/openai-tools-fnj6SRVg.d.ts +0 -46
  208. package/dist/protected-model-port-DzkUY3HQ.d.ts +0 -271
  209. package/dist/sanitize-DEbPNtyI.d.ts +0 -328
  210. package/dist/structural-rollout-C4mabf87.d.ts +0 -446
  211. package/dist/supervise-7q9F5brx.d.ts +0 -379
  212. package/dist/types-BCoemcXU.d.ts +0 -802
  213. package/dist/types-BwoZWq-i.d.ts +0 -510
  214. package/dist/types-Cbp72qyu.d.ts +0 -491
  215. package/dist/types-CmYCMbFT.d.ts +0 -203
  216. package/dist/types-CvNwMzQt.d.ts +0 -957
  217. package/dist/worktree-fanout-WsOzt8qu.d.ts +0 -999
package/dist/agent.js CHANGED
@@ -1,598 +1,666 @@
1
- import "./chunk-ATDFUJYI.js";
2
- import "./chunk-Q2JSAVQ3.js";
3
- import {
4
- createSandboxForSpec
5
- } from "./chunk-5HNDYWUT.js";
6
- import "./chunk-DPEUKJRO.js";
7
- import "./chunk-STJEHM5F.js";
8
- import "./chunk-UPWGXKXB.js";
9
- import "./chunk-2VZYRB55.js";
10
- import "./chunk-2X65HYMI.js";
11
- import "./chunk-ISPWRSEC.js";
12
- import "./chunk-KRBFHMV6.js";
13
- import "./chunk-3MDZX7YU.js";
14
- import {
15
- mapSandboxEvent
16
- } from "./chunk-M22PL4GH.js";
17
- import {
18
- ValidationError
19
- } from "./chunk-YEJR7IXO.js";
20
-
21
- // src/agent/surfaces.ts
22
- import { existsSync, statSync } from "fs";
23
- import { isAbsolute, join, relative, resolve, sep } from "path";
1
+ import { u as ValidationError } from "./errors-DEAvWQPy.js";
2
+ import "./runtime-BG0BziaP.js";
3
+ import { r as mapSandboxEvent } from "./sandbox-events-DeI5xX8P.js";
4
+ import { Rt as createSandboxForSpec } from "./supervise-BiRutHS9.js";
5
+ import { createHash } from "node:crypto";
6
+ import { existsSync, readFileSync, statSync } from "node:fs";
7
+ import { isAbsolute, join, relative, resolve, sep } from "node:path";
8
+ import { parseFindingSubject } from "@tangle-network/agent-eval/analyst";
9
+ //#region src/agent/surfaces.ts
10
+ /**
11
+ * `AgentSurfaces` — declarative map of the mutable file/directory paths
12
+ * the self-improvement loop can edit on behalf of an agent.
13
+ *
14
+ * The substrate uses this map to resolve every parsed `FindingSubject`
15
+ * (from agent-eval) to a real on-disk path. No per-vertical glue;
16
+ * no fabricated paths; no silent `existsSync(...)` skips that hide
17
+ * misconfiguration from the operator.
18
+ *
19
+ * Surfaces are validated at `defineAgent` time — missing paths fail
20
+ * loud with a list of every offender. A surface that's not needed
21
+ * (e.g. an agent with no RAG corpora) is simply omitted; the loop
22
+ * refuses to route those subjects rather than fabricating a target.
23
+ */
24
+ /**
25
+ * Resolve a parsed `FindingSubject` to the file path the substrate
26
+ * should edit (or create) on disk.
27
+ *
28
+ * Returns `null` when:
29
+ * - the subject targets a surface the agent didn't declare
30
+ * (e.g. `rag:*` when `surfaces.rag` is undefined), OR
31
+ * - the subject is a `cluster` (failure-mode emits these as evidence,
32
+ * not actionable mutations — they don't route to a file).
33
+ *
34
+ * Returns a `ResolvedSurface` with `intent: 'create-new'` when the
35
+ * subject names a path that doesn't yet exist (e.g. a new wiki page).
36
+ * The caller chooses whether to honour the create — for tightly-managed
37
+ * surfaces like `systemPrompt` it's usually a contract violation
38
+ * (the analyst named a section that doesn't exist); for `knowledge`
39
+ * it's the whole point.
40
+ */
24
41
  function resolveSubjectPath(subject, surfaces, repoRoot) {
25
- const candidates = candidatePathsForSubject(subject, surfaces);
26
- if (candidates.length === 0) return null;
27
- for (const rel of candidates) {
28
- const abs = isAbsolute(rel) ? rel : join(repoRoot, rel);
29
- if (existsSync(abs)) {
30
- return { absolutePath: abs, repoRelativePath: rel, exists: true, intent: "edit-existing" };
31
- }
32
- }
33
- const fallback = candidates[0];
34
- const fallbackAbs = isAbsolute(fallback) ? fallback : join(repoRoot, fallback);
35
- return {
36
- absolutePath: fallbackAbs,
37
- repoRelativePath: fallback,
38
- exists: false,
39
- intent: "create-new"
40
- };
42
+ const candidates = candidatePathsForSubject(subject, surfaces);
43
+ if (candidates.length === 0) return null;
44
+ for (const rel of candidates) {
45
+ const abs = isAbsolute(rel) ? rel : join(repoRoot, rel);
46
+ if (existsSync(abs)) return {
47
+ absolutePath: abs,
48
+ repoRelativePath: rel,
49
+ exists: true,
50
+ intent: "edit-existing"
51
+ };
52
+ }
53
+ const fallback = candidates[0];
54
+ return {
55
+ absolutePath: isAbsolute(fallback) ? fallback : join(repoRoot, fallback),
56
+ repoRelativePath: fallback,
57
+ exists: false,
58
+ intent: "create-new"
59
+ };
41
60
  }
42
61
  function candidatePathsForSubject(subject, surfaces) {
43
- switch (subject.kind) {
44
- case "knowledge.wiki":
45
- case "knowledge.stale":
46
- return optionalPath(safeJoin(surfaces.knowledge, `${subject.slug}.md`));
47
- case "knowledge.claim":
48
- return optionalPath(safeJoin(surfaces.knowledge, "claims", `${slugify(subject.topic)}.md`));
49
- case "knowledge.raw":
50
- return optionalPath(safeJoin(surfaces.knowledge, "raw", `${subject.sourceId}.md`));
51
- case "system-prompt": {
52
- const slug = slugify(subject.section);
53
- return [
54
- safeJoin(surfaces.systemPrompt, `${slug}.md`),
55
- safeJoin(surfaces.systemPrompt, slug, "SKILL.md"),
56
- safeJoin(surfaces.systemPrompt, slug, "index.md")
57
- ].filter((path) => path !== null);
58
- }
59
- case "skill": {
60
- if (!surfaces.skills) return [];
61
- return [
62
- safeJoin(surfaces.skills, subject.name, "SKILL.md"),
63
- safeJoin(surfaces.skills, `${subject.name}.md`)
64
- ].filter((path) => path !== null);
65
- }
66
- case "tool-doc":
67
- if (subject.aspect) {
68
- return optionalPath(safeJoin(surfaces.tools, subject.tool, `${slugify(subject.aspect)}.md`));
69
- }
70
- return [
71
- safeJoin(surfaces.tools, subject.tool, "README.md"),
72
- safeJoin(surfaces.tools, `${subject.tool}.md`)
73
- ].filter((path) => path !== null);
74
- case "new-tool":
75
- return optionalPath(safeJoin(surfaces.tools, subject.name, "README.md"));
76
- case "mcp":
77
- if (!surfaces.mcp) return [];
78
- return subject.tool ? optionalPath(safeJoin(surfaces.mcp, subject.server, `${subject.tool}.md`)) : [
79
- safeJoin(surfaces.mcp, `${subject.server}.json`),
80
- safeJoin(surfaces.mcp, subject.server, "README.md")
81
- ].filter((path) => path !== null);
82
- case "hook":
83
- if (!surfaces.hooks) return [];
84
- return [
85
- safeJoin(surfaces.hooks, `${subject.name}.md`),
86
- safeJoin(surfaces.hooks, `${subject.name}.json`)
87
- ].filter((path) => path !== null);
88
- case "subagent":
89
- if (!surfaces.subagents) return [];
90
- return [
91
- safeJoin(surfaces.subagents, `${subject.name}.md`),
92
- safeJoin(surfaces.subagents, `${subject.name}.yaml`),
93
- safeJoin(surfaces.subagents, `${subject.name}.json`)
94
- ].filter((path) => path !== null);
95
- case "workflow":
96
- if (!surfaces.workflows) return [];
97
- return [
98
- safeJoin(surfaces.workflows, `${subject.name}.md`),
99
- safeJoin(surfaces.workflows, `${subject.name}.yaml`),
100
- safeJoin(surfaces.workflows, `${subject.name}.json`)
101
- ].filter((path) => path !== null);
102
- case "rollout-policy":
103
- return surfaces.rolloutPolicy ? [surfaces.rolloutPolicy] : [];
104
- case "agent-profile":
105
- return surfaces.agentProfile ? [surfaces.agentProfile] : [];
106
- case "code": {
107
- if (!surfaces.code) return [];
108
- const path = safeJoin(surfaces.code, subject.path);
109
- return path ? [path] : [];
110
- }
111
- case "rag":
112
- if (!surfaces.rag) return [];
113
- return optionalPath(safeJoin(surfaces.rag, subject.corpus, `${subject.docId}.md`));
114
- case "memory":
115
- if (!surfaces.memory) return [];
116
- return optionalPath(safeJoin(surfaces.memory, `${slugify(subject.key)}.json`));
117
- case "scaffolding":
118
- if (!surfaces.scaffolding) return [];
119
- return optionalPath(safeJoin(surfaces.scaffolding, `${slugify(subject.concern)}.md`));
120
- case "output-schema":
121
- if (!surfaces.outputSchema) return [];
122
- return [surfaces.outputSchema];
123
- case "websearch.outdated":
124
- case "prior-run-summary":
125
- return [];
126
- case "cluster":
127
- return [];
128
- }
62
+ switch (subject.kind) {
63
+ case "knowledge.wiki":
64
+ case "knowledge.stale": return optionalPath(safeJoin(surfaces.knowledge, `${subject.slug}.md`));
65
+ case "knowledge.claim": return optionalPath(safeJoin(surfaces.knowledge, "claims", `${slugify(subject.topic)}.md`));
66
+ case "knowledge.raw": return optionalPath(safeJoin(surfaces.knowledge, "raw", `${subject.sourceId}.md`));
67
+ case "system-prompt": {
68
+ const slug = slugify(subject.section);
69
+ return [
70
+ safeJoin(surfaces.systemPrompt, `${slug}.md`),
71
+ safeJoin(surfaces.systemPrompt, slug, "SKILL.md"),
72
+ safeJoin(surfaces.systemPrompt, slug, "index.md")
73
+ ].filter((path) => path !== null);
74
+ }
75
+ case "skill":
76
+ if (!surfaces.skills) return [];
77
+ return [safeJoin(surfaces.skills, subject.name, "SKILL.md"), safeJoin(surfaces.skills, `${subject.name}.md`)].filter((path) => path !== null);
78
+ case "tool-doc":
79
+ if (subject.aspect) return optionalPath(safeJoin(surfaces.tools, subject.tool, `${slugify(subject.aspect)}.md`));
80
+ return [safeJoin(surfaces.tools, subject.tool, "README.md"), safeJoin(surfaces.tools, `${subject.tool}.md`)].filter((path) => path !== null);
81
+ case "new-tool": return optionalPath(safeJoin(surfaces.tools, subject.name, "README.md"));
82
+ case "mcp":
83
+ if (!surfaces.mcp) return [];
84
+ return subject.tool ? optionalPath(safeJoin(surfaces.mcp, subject.server, `${subject.tool}.md`)) : [safeJoin(surfaces.mcp, `${subject.server}.json`), safeJoin(surfaces.mcp, subject.server, "README.md")].filter((path) => path !== null);
85
+ case "hook":
86
+ if (!surfaces.hooks) return [];
87
+ return [safeJoin(surfaces.hooks, `${subject.name}.md`), safeJoin(surfaces.hooks, `${subject.name}.json`)].filter((path) => path !== null);
88
+ case "subagent":
89
+ if (!surfaces.subagents) return [];
90
+ return [
91
+ safeJoin(surfaces.subagents, `${subject.name}.md`),
92
+ safeJoin(surfaces.subagents, `${subject.name}.yaml`),
93
+ safeJoin(surfaces.subagents, `${subject.name}.json`)
94
+ ].filter((path) => path !== null);
95
+ case "workflow":
96
+ if (!surfaces.workflows) return [];
97
+ return [
98
+ safeJoin(surfaces.workflows, `${subject.name}.md`),
99
+ safeJoin(surfaces.workflows, `${subject.name}.yaml`),
100
+ safeJoin(surfaces.workflows, `${subject.name}.json`)
101
+ ].filter((path) => path !== null);
102
+ case "rollout-policy": return surfaces.rolloutPolicy ? [surfaces.rolloutPolicy] : [];
103
+ case "agent-profile": return surfaces.agentProfile ? [surfaces.agentProfile] : [];
104
+ case "code": {
105
+ if (!surfaces.code) return [];
106
+ const path = safeJoin(surfaces.code, subject.path);
107
+ return path ? [path] : [];
108
+ }
109
+ case "rag":
110
+ if (!surfaces.rag) return [];
111
+ return optionalPath(safeJoin(surfaces.rag, subject.corpus, `${subject.docId}.md`));
112
+ case "memory":
113
+ if (!surfaces.memory) return [];
114
+ return optionalPath(safeJoin(surfaces.memory, `${slugify(subject.key)}.json`));
115
+ case "scaffolding":
116
+ if (!surfaces.scaffolding) return [];
117
+ return optionalPath(safeJoin(surfaces.scaffolding, `${slugify(subject.concern)}.md`));
118
+ case "output-schema":
119
+ if (!surfaces.outputSchema) return [];
120
+ return [surfaces.outputSchema];
121
+ case "websearch.outdated":
122
+ case "prior-run-summary": return [];
123
+ case "cluster": return [];
124
+ }
129
125
  }
130
126
  function safeJoin(root, ...children) {
131
- if (children.some((child) => child.includes("\0") || isAbsolute(child))) return null;
132
- const rootAbsolute = resolve(root);
133
- const targetAbsolute = resolve(rootAbsolute, ...children);
134
- const escaped = relative(rootAbsolute, targetAbsolute);
135
- if (escaped === ".." || escaped.startsWith(`..${sep}`) || isAbsolute(escaped)) return null;
136
- return join(root, ...children);
127
+ if (children.some((child) => child.includes("\0") || isAbsolute(child))) return null;
128
+ const rootAbsolute = resolve(root);
129
+ const escaped = relative(rootAbsolute, resolve(rootAbsolute, ...children));
130
+ if (escaped === ".." || escaped.startsWith(`..${sep}`) || isAbsolute(escaped)) return null;
131
+ return join(root, ...children);
137
132
  }
138
133
  function optionalPath(path) {
139
- return path ? [path] : [];
134
+ return path ? [path] : [];
140
135
  }
141
136
  function slugify(s) {
142
- return s.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 200) || "untitled";
137
+ return s.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 200) || "untitled";
143
138
  }
139
+ /** Validate an `AgentSurfaces` map on disk — missing paths fail loud at `defineAgent` time instead of silently skipping self-improvement edits. */
144
140
  function validateSurfaces(surfaces, repoRoot) {
145
- const issues = [];
146
- const dirSurfaces = [
147
- "systemPrompt",
148
- "tools",
149
- "personas",
150
- "knowledge"
151
- ];
152
- const fileSurfaces = ["rubric"];
153
- const optionalDirSurfaces = [
154
- "scaffolding",
155
- "memory",
156
- "rag",
157
- "skills",
158
- "mcp",
159
- "hooks",
160
- "subagents",
161
- "workflows",
162
- "code"
163
- ];
164
- const optionalFileSurfaces = [
165
- "outputSchema",
166
- "rolloutPolicy",
167
- "agentProfile"
168
- ];
169
- for (const key of dirSurfaces) {
170
- const p = surfaces[key];
171
- if (!p) {
172
- issues.push({ surface: key, path: "", reason: "missing" });
173
- continue;
174
- }
175
- const abs = isAbsolute(p) ? p : join(repoRoot, p);
176
- if (!existsSync(abs)) {
177
- issues.push({ surface: key, path: p, reason: "missing" });
178
- } else if (!statSync(abs).isDirectory()) {
179
- issues.push({ surface: key, path: p, reason: "not-directory" });
180
- }
181
- }
182
- for (const key of fileSurfaces) {
183
- const p = surfaces[key];
184
- if (!p) {
185
- issues.push({ surface: key, path: "", reason: "missing" });
186
- continue;
187
- }
188
- const abs = isAbsolute(p) ? p : join(repoRoot, p);
189
- if (!existsSync(abs)) {
190
- issues.push({ surface: key, path: p, reason: "missing" });
191
- } else if (!statSync(abs).isFile()) {
192
- issues.push({ surface: key, path: p, reason: "not-file" });
193
- }
194
- }
195
- for (const key of [...optionalDirSurfaces, ...optionalFileSurfaces]) {
196
- const p = surfaces[key];
197
- if (p === void 0) continue;
198
- const abs = isAbsolute(p) ? p : join(repoRoot, p);
199
- if (!existsSync(abs)) {
200
- issues.push({ surface: key, path: p, reason: "missing" });
201
- continue;
202
- }
203
- const expectedDirectory = optionalDirSurfaces.includes(key);
204
- if (expectedDirectory && !statSync(abs).isDirectory()) {
205
- issues.push({ surface: key, path: p, reason: "not-directory" });
206
- } else if (!expectedDirectory && !statSync(abs).isFile()) {
207
- issues.push({ surface: key, path: p, reason: "not-file" });
208
- }
209
- }
210
- return issues;
141
+ const issues = [];
142
+ const dirSurfaces = [
143
+ "systemPrompt",
144
+ "tools",
145
+ "personas",
146
+ "knowledge"
147
+ ];
148
+ const fileSurfaces = ["rubric"];
149
+ const optionalDirSurfaces = [
150
+ "scaffolding",
151
+ "memory",
152
+ "rag",
153
+ "skills",
154
+ "mcp",
155
+ "hooks",
156
+ "subagents",
157
+ "workflows",
158
+ "code"
159
+ ];
160
+ const optionalFileSurfaces = [
161
+ "outputSchema",
162
+ "rolloutPolicy",
163
+ "agentProfile"
164
+ ];
165
+ for (const key of dirSurfaces) {
166
+ const p = surfaces[key];
167
+ if (!p) {
168
+ issues.push({
169
+ surface: key,
170
+ path: "",
171
+ reason: "missing"
172
+ });
173
+ continue;
174
+ }
175
+ const abs = isAbsolute(p) ? p : join(repoRoot, p);
176
+ if (!existsSync(abs)) issues.push({
177
+ surface: key,
178
+ path: p,
179
+ reason: "missing"
180
+ });
181
+ else if (!statSync(abs).isDirectory()) issues.push({
182
+ surface: key,
183
+ path: p,
184
+ reason: "not-directory"
185
+ });
186
+ }
187
+ for (const key of fileSurfaces) {
188
+ const p = surfaces[key];
189
+ if (!p) {
190
+ issues.push({
191
+ surface: key,
192
+ path: "",
193
+ reason: "missing"
194
+ });
195
+ continue;
196
+ }
197
+ const abs = isAbsolute(p) ? p : join(repoRoot, p);
198
+ if (!existsSync(abs)) issues.push({
199
+ surface: key,
200
+ path: p,
201
+ reason: "missing"
202
+ });
203
+ else if (!statSync(abs).isFile()) issues.push({
204
+ surface: key,
205
+ path: p,
206
+ reason: "not-file"
207
+ });
208
+ }
209
+ for (const key of [...optionalDirSurfaces, ...optionalFileSurfaces]) {
210
+ const p = surfaces[key];
211
+ if (p === void 0) continue;
212
+ const abs = isAbsolute(p) ? p : join(repoRoot, p);
213
+ if (!existsSync(abs)) {
214
+ issues.push({
215
+ surface: key,
216
+ path: p,
217
+ reason: "missing"
218
+ });
219
+ continue;
220
+ }
221
+ const expectedDirectory = optionalDirSurfaces.includes(key);
222
+ if (expectedDirectory && !statSync(abs).isDirectory()) issues.push({
223
+ surface: key,
224
+ path: p,
225
+ reason: "not-directory"
226
+ });
227
+ else if (!expectedDirectory && !statSync(abs).isFile()) issues.push({
228
+ surface: key,
229
+ path: p,
230
+ reason: "not-file"
231
+ });
232
+ }
233
+ return issues;
211
234
  }
235
+ /** Format a list of surface validation issues into a human-readable error string. */
212
236
  function renderSurfaceIssues(issues, repoRoot) {
213
- if (issues.length === 0) return "";
214
- const lines = issues.map(
215
- (i) => ` - ${i.surface}: ${i.path ? `"${i.path}"` : "<not set>"} (${i.reason})`
216
- );
217
- return [
218
- `Agent surface validation failed against repoRoot=${repoRoot}:`,
219
- ...lines,
220
- "",
221
- "Fix the manifest: every required surface must point at an existing",
222
- "directory (systemPrompt / tools / personas / knowledge) or file",
223
- "(rubric). Optional surfaces (scaffolding / memory / rag / outputSchema)",
224
- "may be omitted; the loop will reject findings targeting omitted",
225
- "surfaces rather than fabricating a path."
226
- ].join("\n");
237
+ if (issues.length === 0) return "";
238
+ const lines = issues.map((i) => ` - ${i.surface}: ${i.path ? `"${i.path}"` : "<not set>"} (${i.reason})`);
239
+ return [
240
+ `Agent surface validation failed against repoRoot=${repoRoot}:`,
241
+ ...lines,
242
+ "",
243
+ "Fix the manifest: every required surface must point at an existing",
244
+ "directory (systemPrompt / tools / personas / knowledge) or file",
245
+ "(rubric). Optional surfaces (scaffolding / memory / rag / outputSchema)",
246
+ "may be omitted; the loop will reject findings targeting omitted",
247
+ "surfaces rather than fabricating a path."
248
+ ].join("\n");
227
249
  }
228
-
229
- // src/agent/define-agent.ts
250
+ //#endregion
251
+ //#region src/agent/define-agent.ts
252
+ /**
253
+ * Stub for agents whose `runtime.act` is not yet wired to the substrate's
254
+ * eval path. Preserves the streaming contract (empty event stream + a
255
+ * rejected `output` promise that tells the caller exactly what to fix).
256
+ *
257
+ * Per-vertical manifests usually start with this stub and replace it with
258
+ * the agent's real streaming runtime (`runChatTurn` or equivalent) once
259
+ * the eval path consumes the manifest end-to-end.
260
+ */
230
261
  function unimplementedAgentRun(reason = "AgentRuntime.act is not yet wired for this manifest") {
231
- return {
232
- events: (async function* empty() {
233
- })(),
234
- output: Promise.reject(new Error(reason))
235
- };
262
+ return {
263
+ events: (async function* empty() {})(),
264
+ output: Promise.reject(new Error(reason))
265
+ };
236
266
  }
267
+ /**
268
+ * Drain `act`'s `events` into an array AND await its `output`. Useful for
269
+ * eval / outcome-measurement code paths that don't care about live
270
+ * rendering. The events array is preserved so the substrate can inspect
271
+ * tool calls / readiness / questions retrospectively.
272
+ *
273
+ * IMPORTANT: chat-centric UX MUST NOT call this — it defeats streaming
274
+ * (no incremental render). Use `for await (const ev of invocation.events)`
275
+ * directly in the chat surface.
276
+ */
237
277
  async function collectAgentRun(invocation) {
238
- const events = [];
239
- for await (const ev of invocation.events) events.push(ev);
240
- const output = await invocation.output;
241
- return { events, output };
278
+ const events = [];
279
+ for await (const ev of invocation.events) events.push(ev);
280
+ return {
281
+ events,
282
+ output: await invocation.output
283
+ };
242
284
  }
285
+ /** Thrown when `defineAgent` finds a required surface missing on disk. */
243
286
  var AgentManifestError = class extends Error {
244
- constructor(message, agentId, issues = []) {
245
- super(message);
246
- this.agentId = agentId;
247
- this.issues = issues;
248
- this.name = "AgentManifestError";
249
- }
250
- agentId;
251
- issues;
287
+ agentId;
288
+ issues;
289
+ constructor(message, agentId, issues = []) {
290
+ super(message);
291
+ this.agentId = agentId;
292
+ this.issues = issues;
293
+ this.name = "AgentManifestError";
294
+ }
252
295
  };
296
+ /**
297
+ * Construct a validated agent manifest. Throws `AgentManifestError`
298
+ * if any required surface is missing on disk.
299
+ *
300
+ * Generics: pass your persona / output types if you want narrowed
301
+ * `runtime.act` signatures:
302
+ * `defineAgent<TaxPersona, TaxRunOutput>({ ... })`
303
+ *
304
+ * Most callers don't need the generics — the substrate operates on
305
+ * `unknown` payloads internally and the manifest's `score` /
306
+ * `runtime.act` see the typed shapes via TypeScript inference at
307
+ * the call site.
308
+ */
253
309
  function defineAgent(manifest) {
254
- if (!manifest.id || manifest.id.trim().length === 0) {
255
- throw new AgentManifestError("defineAgent: `id` is required", manifest.id ?? "");
256
- }
257
- if (!manifest.repoRoot || manifest.repoRoot.trim().length === 0) {
258
- throw new AgentManifestError("defineAgent: `repoRoot` is required", manifest.id);
259
- }
260
- const issues = validateSurfaces(manifest.surfaces, manifest.repoRoot);
261
- if (issues.length > 0) {
262
- throw new AgentManifestError(
263
- renderSurfaceIssues(issues, manifest.repoRoot),
264
- manifest.id,
265
- issues
266
- );
267
- }
268
- const total = manifest.rubric.dimensions.reduce((acc, d) => acc + d.weight, 0);
269
- if (manifest.rubric.dimensions.length > 0 && (total < 0.5 || total > 1.5)) {
270
- throw new AgentManifestError(
271
- `defineAgent(${manifest.id}): rubric dimension weights sum to ${total.toFixed(3)} \u2014 should be ~1.0`,
272
- manifest.id
273
- );
274
- }
275
- return manifest;
310
+ if (!manifest.id || manifest.id.trim().length === 0) throw new AgentManifestError("defineAgent: `id` is required", manifest.id ?? "");
311
+ if (!manifest.repoRoot || manifest.repoRoot.trim().length === 0) throw new AgentManifestError("defineAgent: `repoRoot` is required", manifest.id);
312
+ const issues = validateSurfaces(manifest.surfaces, manifest.repoRoot);
313
+ if (issues.length > 0) throw new AgentManifestError(renderSurfaceIssues(issues, manifest.repoRoot), manifest.id, issues);
314
+ const total = manifest.rubric.dimensions.reduce((acc, d) => acc + d.weight, 0);
315
+ if (manifest.rubric.dimensions.length > 0 && (total < .5 || total > 1.5)) throw new AgentManifestError(`defineAgent(${manifest.id}): rubric dimension weights sum to ${total.toFixed(3)} — should be ~1.0`, manifest.id);
316
+ return manifest;
276
317
  }
277
-
278
- // src/agent/improvement-adapter.ts
279
- import { createHash } from "crypto";
280
- import { readFileSync } from "fs";
281
- import { parseFindingSubject } from "@tangle-network/agent-eval/analyst";
282
- var DEFAULT_CREATE_KINDS = [
283
- "knowledge.wiki",
284
- "knowledge.claim",
285
- "knowledge.raw",
286
- "new-tool"
318
+ //#endregion
319
+ //#region src/agent/improvement-adapter.ts
320
+ /**
321
+ * Surface improvement proposer resolves analyst findings into LLM-drafted
322
+ * candidate patches without changing the caller's repository.
323
+ *
324
+ * The proposer parses each finding's `subject` via
325
+ * `parseFindingSubject` (agent-eval), resolves it to a real file path
326
+ * via the agent's `AgentSurfaces`, reads the current content, and asks
327
+ * an LLM to draft a unified-diff patch given the finding + current
328
+ * content + per-kind editing-discipline rules.
329
+ *
330
+ * Fail-loud rules:
331
+ * - Findings whose subject doesn't parse → counted in `errors`.
332
+ * - Findings whose subject targets an undeclared surface → counted in
333
+ * `errors` with the offending kind in the message.
334
+ * - Findings whose target path doesn't exist AND the kind isn't a
335
+ * create-new variant (`new-tool`, `knowledge.wiki`) → counted in
336
+ * `errors` with the resolved path in the message.
337
+ * - LLM drafts that fail JSON-schema validation → counted in
338
+ * `errors` with the schema issue.
339
+ *
340
+ * No silent skips. Every dropped finding has a recorded reason the
341
+ * loop's report surfaces.
342
+ */
343
+ const DEFAULT_CREATE_KINDS = [
344
+ "knowledge.wiki",
345
+ "knowledge.claim",
346
+ "knowledge.raw",
347
+ "new-tool"
287
348
  ];
349
+ /** Resolve each finding to a real surface and draft a detached patch candidate. */
288
350
  function createSurfaceImprovementProposer(opts) {
289
- const allowCreate = opts.allowCreateForKinds ?? DEFAULT_CREATE_KINDS;
290
- return {
291
- async proposeFromFindings(findings) {
292
- const edits = [];
293
- const errors = [];
294
- let skipped = 0;
295
- for (const f of findings) {
296
- const subject = parseFindingSubject(f.subject);
297
- if (subject === null) {
298
- if (f.subject !== void 0) {
299
- errors.push({
300
- findingId: f.finding_id,
301
- subject: f.subject,
302
- message: "subject does not parse against the finding-subject grammar"
303
- });
304
- } else {
305
- skipped += 1;
306
- }
307
- continue;
308
- }
309
- if (subject.kind === "cluster") {
310
- skipped += 1;
311
- continue;
312
- }
313
- if (subject.kind.startsWith("knowledge.")) {
314
- skipped += 1;
315
- continue;
316
- }
317
- const target = resolveSubjectPath(subject, opts.surfaces, opts.repoRoot);
318
- if (target === null) {
319
- errors.push({
320
- findingId: f.finding_id,
321
- subject: f.subject ?? "",
322
- message: `subject kind "${subject.kind}" targets an undeclared surface; declare it in AgentSurfaces or stop emitting this subject`
323
- });
324
- continue;
325
- }
326
- if (target.intent === "create-new" && !allowCreate.includes(subject.kind)) {
327
- errors.push({
328
- findingId: f.finding_id,
329
- subject: f.subject ?? "",
330
- message: `target ${target.repoRelativePath} does not exist; the kind "${subject.kind}" requires an existing target (analyst named a section that isn't in the codebase)`
331
- });
332
- continue;
333
- }
334
- const currentContent = target.exists ? readFileSync(target.absolutePath, "utf-8") : "";
335
- let draft;
336
- try {
337
- draft = await opts.draftPatch({ finding: f, subject, target, currentContent });
338
- } catch (err) {
339
- errors.push({
340
- findingId: f.finding_id,
341
- subject: f.subject ?? "",
342
- message: `draftPatch threw: ${err instanceof Error ? err.message : String(err)}`
343
- });
344
- continue;
345
- }
346
- if (draft.patch.trim().length === 0) {
347
- skipped += 1;
348
- continue;
349
- }
350
- edits.push({
351
- id: `imp-${f.finding_id}`,
352
- sourceFindingId: f.finding_id,
353
- subject,
354
- target,
355
- baseSha256: sha256(currentContent),
356
- patch: draft.patch,
357
- summary: draft.summary,
358
- rationale: draft.rationale,
359
- confidence: f.confidence,
360
- severity: f.severity
361
- });
362
- }
363
- return { edits, skipped, errors };
364
- }
365
- };
351
+ const allowCreate = opts.allowCreateForKinds ?? DEFAULT_CREATE_KINDS;
352
+ return { async proposeFromFindings(findings) {
353
+ const edits = [];
354
+ const errors = [];
355
+ let skipped = 0;
356
+ for (const f of findings) {
357
+ const subject = parseFindingSubject(f.subject);
358
+ if (subject === null) {
359
+ if (f.subject !== void 0) errors.push({
360
+ findingId: f.finding_id,
361
+ subject: f.subject,
362
+ message: "subject does not parse against the finding-subject grammar"
363
+ });
364
+ else skipped += 1;
365
+ continue;
366
+ }
367
+ if (subject.kind === "cluster") {
368
+ skipped += 1;
369
+ continue;
370
+ }
371
+ if (subject.kind.startsWith("knowledge.")) {
372
+ skipped += 1;
373
+ continue;
374
+ }
375
+ const target = resolveSubjectPath(subject, opts.surfaces, opts.repoRoot);
376
+ if (target === null) {
377
+ errors.push({
378
+ findingId: f.finding_id,
379
+ subject: f.subject ?? "",
380
+ message: `subject kind "${subject.kind}" targets an undeclared surface; declare it in AgentSurfaces or stop emitting this subject`
381
+ });
382
+ continue;
383
+ }
384
+ if (target.intent === "create-new" && !allowCreate.includes(subject.kind)) {
385
+ errors.push({
386
+ findingId: f.finding_id,
387
+ subject: f.subject ?? "",
388
+ message: `target ${target.repoRelativePath} does not exist; the kind "${subject.kind}" requires an existing target (analyst named a section that isn't in the codebase)`
389
+ });
390
+ continue;
391
+ }
392
+ const currentContent = target.exists ? readFileSync(target.absolutePath, "utf-8") : "";
393
+ let draft;
394
+ try {
395
+ draft = await opts.draftPatch({
396
+ finding: f,
397
+ subject,
398
+ target,
399
+ currentContent
400
+ });
401
+ } catch (err) {
402
+ errors.push({
403
+ findingId: f.finding_id,
404
+ subject: f.subject ?? "",
405
+ message: `draftPatch threw: ${err instanceof Error ? err.message : String(err)}`
406
+ });
407
+ continue;
408
+ }
409
+ if (draft.patch.trim().length === 0) {
410
+ skipped += 1;
411
+ continue;
412
+ }
413
+ edits.push({
414
+ id: `imp-${f.finding_id}`,
415
+ sourceFindingId: f.finding_id,
416
+ subject,
417
+ target,
418
+ baseSha256: sha256(currentContent),
419
+ patch: draft.patch,
420
+ summary: draft.summary,
421
+ rationale: draft.rationale,
422
+ confidence: f.confidence,
423
+ severity: f.severity
424
+ });
425
+ }
426
+ return {
427
+ edits,
428
+ skipped,
429
+ errors
430
+ };
431
+ } };
366
432
  }
367
433
  function sha256(s) {
368
- return createHash("sha256").update(s, "utf-8").digest("hex");
434
+ return createHash("sha256").update(s, "utf-8").digest("hex");
369
435
  }
370
-
371
- // src/agent/profile-materialization.ts
372
- var AGENT_PROFILE_MATERIALIZATION_AXES = [
373
- "identity",
374
- "name",
375
- "model",
376
- "prompt",
377
- "systemPrompt",
378
- "instructions",
379
- "resources",
380
- "files",
381
- "resourceInstructions",
382
- "skills",
383
- "resourceTools",
384
- "resourceAgents",
385
- "commands",
386
- "tools",
387
- "permissions",
388
- "mcp",
389
- "mcpConnections",
390
- "connections",
391
- "subagents",
392
- "hooks",
393
- "modes",
394
- "confidential",
395
- "metadata",
396
- "extensions"
436
+ //#endregion
437
+ //#region src/agent/profile-materialization.ts
438
+ /** Known AgentProfile axes a run path may or may not carry into execution. */
439
+ const AGENT_PROFILE_MATERIALIZATION_AXES = [
440
+ "identity",
441
+ "name",
442
+ "model",
443
+ "prompt",
444
+ "systemPrompt",
445
+ "instructions",
446
+ "resources",
447
+ "files",
448
+ "resourceInstructions",
449
+ "skills",
450
+ "resourceTools",
451
+ "resourceAgents",
452
+ "commands",
453
+ "tools",
454
+ "permissions",
455
+ "mcp",
456
+ "mcpConnections",
457
+ "connections",
458
+ "subagents",
459
+ "hooks",
460
+ "modes",
461
+ "confidential",
462
+ "metadata",
463
+ "extensions"
397
464
  ];
398
- var KNOWN_AXIS_SET = new Set(AGENT_PROFILE_MATERIALIZATION_AXES);
399
- var AXIS_PARENTS = {
400
- name: "identity",
401
- systemPrompt: "prompt",
402
- instructions: "prompt",
403
- files: "resources",
404
- resourceInstructions: "resources",
405
- skills: "resources",
406
- resourceTools: "resources",
407
- resourceAgents: "resources",
408
- commands: "resources",
409
- mcpConnections: "mcp"
465
+ const KNOWN_AXIS_SET = new Set(AGENT_PROFILE_MATERIALIZATION_AXES);
466
+ const AXIS_PARENTS = {
467
+ name: "identity",
468
+ systemPrompt: "prompt",
469
+ instructions: "prompt",
470
+ files: "resources",
471
+ resourceInstructions: "resources",
472
+ skills: "resources",
473
+ resourceTools: "resources",
474
+ resourceAgents: "resources",
475
+ commands: "resources",
476
+ mcpConnections: "mcp"
410
477
  };
411
- var sandboxActProfileMaterialization = defineProfileMaterializationContract({
412
- name: "createSandboxAct",
413
- axes: [
414
- "identity",
415
- "model",
416
- "prompt",
417
- "resources",
418
- "tools",
419
- "permissions",
420
- "mcp",
421
- "connections",
422
- "subagents",
423
- "hooks",
424
- "modes",
425
- "confidential",
426
- "metadata",
427
- "extensions"
428
- ]
478
+ /** Materialization contract for `createSandboxAct`, which forwards the full AgentProfile. */
479
+ const sandboxActProfileMaterialization = defineProfileMaterializationContract({
480
+ name: "createSandboxAct",
481
+ axes: [
482
+ "identity",
483
+ "model",
484
+ "prompt",
485
+ "resources",
486
+ "tools",
487
+ "permissions",
488
+ "mcp",
489
+ "connections",
490
+ "subagents",
491
+ "hooks",
492
+ "modes",
493
+ "confidential",
494
+ "metadata",
495
+ "extensions"
496
+ ]
429
497
  });
430
- var promptOnlyProfileMaterialization = defineProfileMaterializationContract({
431
- name: "prompt-only-message",
432
- axes: ["prompt"]
498
+ /** Materialization contract for a run path that only injects prompt text. */
499
+ const promptOnlyProfileMaterialization = defineProfileMaterializationContract({
500
+ name: "prompt-only-message",
501
+ axes: ["prompt"]
433
502
  });
434
- var promptResourceProfileMaterialization = defineProfileMaterializationContract({
435
- name: "prompt-resource-attachment",
436
- axes: ["prompt", "resources"]
503
+ /** Materialization contract for a run path that injects prompt text plus inline resources. */
504
+ const promptResourceProfileMaterialization = defineProfileMaterializationContract({
505
+ name: "prompt-resource-attachment",
506
+ axes: ["prompt", "resources"]
437
507
  });
508
+ /** Define the profile axes a concrete run path actually carries into execution. */
438
509
  function defineProfileMaterializationContract(options) {
439
- const name = options.name.trim();
440
- if (!name) {
441
- throw new ValidationError("defineProfileMaterializationContract: name is required");
442
- }
443
- return {
444
- name,
445
- axes: normalizeAxes(options.axes, `${name}.axes`)
446
- };
510
+ const name = options.name.trim();
511
+ if (!name) throw new ValidationError("defineProfileMaterializationContract: name is required");
512
+ return {
513
+ name,
514
+ axes: normalizeAxes(options.axes, `${name}.axes`)
515
+ };
447
516
  }
517
+ /** Return every changed profile axis that the selected run path would drop. */
448
518
  function validateProfileMaterialization(options) {
449
- const changedAxes = normalizeAxes(options.changedAxes, "changedAxes");
450
- const supported = new Set(
451
- normalizeAxes(options.contract.axes, `${options.contract.name}.axes`)
452
- );
453
- const issues = [];
454
- for (const axis of changedAxes) {
455
- if (isAxisSupported(axis, supported)) continue;
456
- issues.push({
457
- contract: options.contract.name,
458
- axis,
459
- reason: "unsupported-axis",
460
- supportedAxes: [...supported]
461
- });
462
- }
463
- return issues;
519
+ const changedAxes = normalizeAxes(options.changedAxes, "changedAxes");
520
+ const supported = new Set(normalizeAxes(options.contract.axes, `${options.contract.name}.axes`));
521
+ const issues = [];
522
+ for (const axis of changedAxes) {
523
+ if (isAxisSupported(axis, supported)) continue;
524
+ issues.push({
525
+ contract: options.contract.name,
526
+ axis,
527
+ reason: "unsupported-axis",
528
+ supportedAxes: [...supported]
529
+ });
530
+ }
531
+ return issues;
464
532
  }
533
+ /** Throw when a candidate changes axes the selected run path cannot carry. */
465
534
  function assertProfileMaterialization(options) {
466
- const issues = validateProfileMaterialization(options);
467
- if (issues.length === 0) return;
468
- throw new ValidationError(renderProfileMaterializationIssues(issues, options.context));
535
+ const issues = validateProfileMaterialization(options);
536
+ if (issues.length === 0) return;
537
+ throw new ValidationError(renderProfileMaterializationIssues(issues, options.context));
469
538
  }
539
+ /** Format profile-axis drop issues into a concise operator-facing error. */
470
540
  function renderProfileMaterializationIssues(issues, context) {
471
- if (issues.length === 0) return "";
472
- const contract = issues[0]?.contract ?? "<unknown>";
473
- const prefix = context ? `${context}: ` : "";
474
- const droppedAxes = issues.map((issue) => issue.axis).join(", ");
475
- const supportedAxes = issues[0]?.supportedAxes.join(", ") || "<none>";
476
- return [
477
- `${prefix}profile materialization would drop axis changes on "${contract}": ${droppedAxes}.`,
478
- `Supported axes: ${supportedAxes}.`,
479
- "Use a run path that carries those AgentProfile axes, or remove them from the candidate."
480
- ].join("\n");
541
+ if (issues.length === 0) return "";
542
+ const contract = issues[0]?.contract ?? "<unknown>";
543
+ const prefix = context ? `${context}: ` : "";
544
+ const droppedAxes = issues.map((issue) => issue.axis).join(", ");
545
+ const supportedAxes = issues[0]?.supportedAxes.join(", ") || "<none>";
546
+ return [
547
+ `${prefix}profile materialization would drop axis changes on "${contract}": ${droppedAxes}.`,
548
+ `Supported axes: ${supportedAxes}.`,
549
+ "Use a run path that carries those AgentProfile axes, or remove them from the candidate."
550
+ ].join("\n");
481
551
  }
482
552
  function normalizeAxes(axes, label) {
483
- const out = [];
484
- const seen = /* @__PURE__ */ new Set();
485
- for (const raw of axes) {
486
- const axis = normalizeAxis(raw, label);
487
- if (seen.has(axis)) continue;
488
- seen.add(axis);
489
- out.push(axis);
490
- }
491
- return out;
553
+ const out = [];
554
+ const seen = /* @__PURE__ */ new Set();
555
+ for (const raw of axes) {
556
+ const axis = normalizeAxis(raw, label);
557
+ if (seen.has(axis)) continue;
558
+ seen.add(axis);
559
+ out.push(axis);
560
+ }
561
+ return out;
492
562
  }
493
563
  function normalizeAxis(raw, label) {
494
- if (typeof raw !== "string") {
495
- throw new ValidationError(`${label}: profile axis must be a string`);
496
- }
497
- const axis = raw.trim();
498
- if (!axis) {
499
- throw new ValidationError(`${label}: profile axis must be non-empty`);
500
- }
501
- if (!KNOWN_AXIS_SET.has(axis) && !axis.startsWith("custom:")) {
502
- throw new ValidationError(
503
- `${label}: unknown profile axis "${axis}". Use a known axis or custom:<name>.`
504
- );
505
- }
506
- return axis;
564
+ if (typeof raw !== "string") throw new ValidationError(`${label}: profile axis must be a string`);
565
+ const axis = raw.trim();
566
+ if (!axis) throw new ValidationError(`${label}: profile axis must be non-empty`);
567
+ if (!KNOWN_AXIS_SET.has(axis) && !axis.startsWith("custom:")) throw new ValidationError(`${label}: unknown profile axis "${axis}". Use a known axis or custom:<name>.`);
568
+ return axis;
507
569
  }
508
570
  function isAxisSupported(axis, supported) {
509
- if (supported.has(axis)) return true;
510
- let parent = AXIS_PARENTS[axis];
511
- while (parent) {
512
- if (supported.has(parent)) return true;
513
- parent = AXIS_PARENTS[parent];
514
- }
515
- return false;
571
+ if (supported.has(axis)) return true;
572
+ let parent = AXIS_PARENTS[axis];
573
+ while (parent) {
574
+ if (supported.has(parent)) return true;
575
+ parent = AXIS_PARENTS[parent];
576
+ }
577
+ return false;
516
578
  }
517
-
518
- // src/agent/sandbox-act.ts
579
+ //#endregion
580
+ //#region src/agent/sandbox-act.ts
581
+ /**
582
+ * Build an `AgentRuntime.act` implementation backed by a single prod-profile
583
+ * sandbox run. The returned function honours the `act` contract: it returns
584
+ * synchronously with a live `events` iterator and an `output` promise that
585
+ * resolves only after the iterator drains.
586
+ */
519
587
  function createSandboxAct(options) {
520
- assertProfileMaterialization({
521
- contract: sandboxActProfileMaterialization,
522
- changedAxes: options.requiredProfileAxes ?? [],
523
- context: "createSandboxAct"
524
- });
525
- const mapEvent = options.mapEvent ?? mapSandboxEvent;
526
- return (persona, ctx) => {
527
- const profile = applyComposeOverrides(options.baseProfile, options.compose?.(persona));
528
- const agentRunName = options.name ?? profile.name ?? "agent";
529
- const message = options.buildPrompt(persona);
530
- const signal = ctx.signal ?? new AbortController().signal;
531
- const raw = [];
532
- let settle;
533
- let fail;
534
- const output = new Promise((resolve2, reject) => {
535
- settle = resolve2;
536
- fail = reject;
537
- });
538
- output.catch(() => {
539
- });
540
- const spec = {
541
- profile,
542
- taskToPrompt: () => message,
543
- name: agentRunName,
544
- ...options.sandboxOverrides ? { sandboxOverrides: options.sandboxOverrides } : {}
545
- };
546
- async function* events() {
547
- try {
548
- const box = await createSandboxForSpec(options.sandboxClient, spec, signal);
549
- for await (const event of box.streamPrompt(message, { signal })) {
550
- raw.push(event);
551
- const mapped = mapEvent(event, { agentRunName });
552
- if (mapped) yield mapped;
553
- }
554
- settle(options.output.parse(raw));
555
- } catch (err) {
556
- fail(err);
557
- throw err;
558
- }
559
- }
560
- return { events: events(), output };
561
- };
588
+ assertProfileMaterialization({
589
+ contract: sandboxActProfileMaterialization,
590
+ changedAxes: options.requiredProfileAxes ?? [],
591
+ context: "createSandboxAct"
592
+ });
593
+ const mapEvent = options.mapEvent ?? mapSandboxEvent;
594
+ return (persona, ctx) => {
595
+ const profile = applyComposeOverrides(options.baseProfile, options.compose?.(persona));
596
+ const agentRunName = options.name ?? profile.name ?? "agent";
597
+ const message = options.buildPrompt(persona);
598
+ const signal = ctx.signal ?? new AbortController().signal;
599
+ const raw = [];
600
+ let settle;
601
+ let fail;
602
+ const output = new Promise((resolve, reject) => {
603
+ settle = resolve;
604
+ fail = reject;
605
+ });
606
+ output.catch(() => {});
607
+ const spec = {
608
+ profile,
609
+ taskToPrompt: () => message,
610
+ name: agentRunName,
611
+ ...options.sandboxOverrides ? { sandboxOverrides: options.sandboxOverrides } : {}
612
+ };
613
+ async function* events() {
614
+ try {
615
+ const box = await createSandboxForSpec(options.sandboxClient, spec, signal);
616
+ for await (const event of box.streamPrompt(message, { signal })) {
617
+ raw.push(event);
618
+ const mapped = mapEvent(event, { agentRunName });
619
+ if (mapped) yield mapped;
620
+ }
621
+ settle(options.output.parse(raw));
622
+ } catch (err) {
623
+ fail(err);
624
+ throw err;
625
+ }
626
+ }
627
+ return {
628
+ events: events(),
629
+ output
630
+ };
631
+ };
562
632
  }
633
+ /** Overlay the per-persona overrides onto the base profile. Each slot merges over the base; an
634
+ * absent override leaves the base profile untouched. */
563
635
  function applyComposeOverrides(base, overrides) {
564
- if (!overrides) return base;
565
- const prompt = overrides.systemPrompt ? { ...base.prompt, systemPrompt: overrides.systemPrompt } : base.prompt;
566
- const mergedTools = overrides.tools ? { ...base.tools ?? {}, ...overrides.tools } : base.tools;
567
- const mergedMcp = overrides.mcpConnections ? { ...base.mcp ?? {}, ...overrides.mcpConnections } : base.mcp;
568
- const baseFiles = base.resources?.files ?? [];
569
- const mergedFiles = overrides.extraFiles?.length ? [...baseFiles, ...overrides.extraFiles] : [...baseFiles];
570
- return {
571
- ...base,
572
- name: overrides.name ?? base.name,
573
- prompt,
574
- ...mergedTools ? { tools: mergedTools } : {},
575
- ...mergedMcp ? { mcp: mergedMcp } : {},
576
- resources: { ...base.resources, files: mergedFiles }
577
- };
636
+ if (!overrides) return base;
637
+ const prompt = overrides.systemPrompt ? {
638
+ ...base.prompt,
639
+ systemPrompt: overrides.systemPrompt
640
+ } : base.prompt;
641
+ const mergedTools = overrides.tools ? {
642
+ ...base.tools ?? {},
643
+ ...overrides.tools
644
+ } : base.tools;
645
+ const mergedMcp = overrides.mcpConnections ? {
646
+ ...base.mcp ?? {},
647
+ ...overrides.mcpConnections
648
+ } : base.mcp;
649
+ const baseFiles = base.resources?.files ?? [];
650
+ const mergedFiles = overrides.extraFiles?.length ? [...baseFiles, ...overrides.extraFiles] : [...baseFiles];
651
+ return {
652
+ ...base,
653
+ name: overrides.name ?? base.name,
654
+ prompt,
655
+ ...mergedTools ? { tools: mergedTools } : {},
656
+ ...mergedMcp ? { mcp: mergedMcp } : {},
657
+ resources: {
658
+ ...base.resources,
659
+ files: mergedFiles
660
+ }
661
+ };
578
662
  }
579
- export {
580
- AGENT_PROFILE_MATERIALIZATION_AXES,
581
- AgentManifestError,
582
- assertProfileMaterialization,
583
- collectAgentRun,
584
- createSandboxAct,
585
- createSurfaceImprovementProposer,
586
- defineAgent,
587
- defineProfileMaterializationContract,
588
- promptOnlyProfileMaterialization,
589
- promptResourceProfileMaterialization,
590
- renderProfileMaterializationIssues,
591
- renderSurfaceIssues,
592
- resolveSubjectPath,
593
- sandboxActProfileMaterialization,
594
- unimplementedAgentRun,
595
- validateProfileMaterialization,
596
- validateSurfaces
597
- };
663
+ //#endregion
664
+ export { AGENT_PROFILE_MATERIALIZATION_AXES, AgentManifestError, assertProfileMaterialization, collectAgentRun, createSandboxAct, createSurfaceImprovementProposer, defineAgent, defineProfileMaterializationContract, promptOnlyProfileMaterialization, promptResourceProfileMaterialization, renderProfileMaterializationIssues, renderSurfaceIssues, resolveSubjectPath, sandboxActProfileMaterialization, unimplementedAgentRun, validateProfileMaterialization, validateSurfaces };
665
+
598
666
  //# sourceMappingURL=agent.js.map