@tangle-network/agent-runtime 0.105.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 (218) hide show
  1. package/README.md +2 -2
  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 -1058
  40. package/dist/index.js +2106 -2082
  41. package/dist/index.js.map +1 -1
  42. package/dist/intelligence.d.ts +768 -889
  43. package/dist/intelligence.js +1466 -1367
  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 -15
  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 -436
  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 +149 -145
  84. package/dist/primeintellect/index.js +626 -1003
  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 -56
  130. package/skills/build-with-agent-runtime/SKILL.md +1 -0
  131. package/dist/activation-Cm-9MMX1.d.ts +0 -69
  132. package/dist/analyst-loop.js.map +0 -1
  133. package/dist/backends-BO4Jqoe2.d.ts +0 -134
  134. package/dist/candidate-execution/index.js.map +0 -1
  135. package/dist/chunk-2KGAN2HM.js +0 -1256
  136. package/dist/chunk-2KGAN2HM.js.map +0 -1
  137. package/dist/chunk-2VZYRB55.js +0 -834
  138. package/dist/chunk-2VZYRB55.js.map +0 -1
  139. package/dist/chunk-3MDZX7YU.js +0 -125
  140. package/dist/chunk-3MDZX7YU.js.map +0 -1
  141. package/dist/chunk-5IBQAPVB.js +0 -29
  142. package/dist/chunk-5IBQAPVB.js.map +0 -1
  143. package/dist/chunk-5QOB7H74.js +0 -387
  144. package/dist/chunk-5QOB7H74.js.map +0 -1
  145. package/dist/chunk-C5RTIBNZ.js +0 -48
  146. package/dist/chunk-C5RTIBNZ.js.map +0 -1
  147. package/dist/chunk-CTRA64LY.js +0 -680
  148. package/dist/chunk-CTRA64LY.js.map +0 -1
  149. package/dist/chunk-DPEUKJRO.js +0 -27
  150. package/dist/chunk-DPEUKJRO.js.map +0 -1
  151. package/dist/chunk-FD2MBMOH.js +0 -494
  152. package/dist/chunk-FD2MBMOH.js.map +0 -1
  153. package/dist/chunk-H5QPIZNX.js +0 -907
  154. package/dist/chunk-H5QPIZNX.js.map +0 -1
  155. package/dist/chunk-HLKC4UYB.js +0 -3514
  156. package/dist/chunk-HLKC4UYB.js.map +0 -1
  157. package/dist/chunk-HNP72PNU.js +0 -192
  158. package/dist/chunk-HNP72PNU.js.map +0 -1
  159. package/dist/chunk-ISPWRSEC.js +0 -408
  160. package/dist/chunk-ISPWRSEC.js.map +0 -1
  161. package/dist/chunk-KRBFHMV6.js +0 -1228
  162. package/dist/chunk-KRBFHMV6.js.map +0 -1
  163. package/dist/chunk-M22PL4GH.js +0 -171
  164. package/dist/chunk-M22PL4GH.js.map +0 -1
  165. package/dist/chunk-NURIQBJQ.js +0 -72
  166. package/dist/chunk-NURIQBJQ.js.map +0 -1
  167. package/dist/chunk-OPVWXJ2H.js +0 -75
  168. package/dist/chunk-OPVWXJ2H.js.map +0 -1
  169. package/dist/chunk-PZZKQVQV.js +0 -52
  170. package/dist/chunk-PZZKQVQV.js.map +0 -1
  171. package/dist/chunk-Q2JSAVQ3.js +0 -671
  172. package/dist/chunk-Q2JSAVQ3.js.map +0 -1
  173. package/dist/chunk-RDOAVVHY.js +0 -699
  174. package/dist/chunk-RDOAVVHY.js.map +0 -1
  175. package/dist/chunk-SGKPNBXE.js +0 -60
  176. package/dist/chunk-SGKPNBXE.js.map +0 -1
  177. package/dist/chunk-SMQXZGLZ.js +0 -351
  178. package/dist/chunk-SMQXZGLZ.js.map +0 -1
  179. package/dist/chunk-UHEZW5BU.js +0 -2918
  180. package/dist/chunk-UHEZW5BU.js.map +0 -1
  181. package/dist/chunk-UPWGXKXB.js +0 -254
  182. package/dist/chunk-UPWGXKXB.js.map +0 -1
  183. package/dist/chunk-VISA6CI3.js +0 -200
  184. package/dist/chunk-VISA6CI3.js.map +0 -1
  185. package/dist/chunk-WMTCUOQL.js +0 -474
  186. package/dist/chunk-WMTCUOQL.js.map +0 -1
  187. package/dist/chunk-WRTOVNN4.js +0 -4728
  188. package/dist/chunk-WRTOVNN4.js.map +0 -1
  189. package/dist/chunk-WSTRQZYQ.js +0 -5576
  190. package/dist/chunk-WSTRQZYQ.js.map +0 -1
  191. package/dist/chunk-XBG2W2VW.js +0 -6434
  192. package/dist/chunk-XBG2W2VW.js.map +0 -1
  193. package/dist/chunk-YEJR7IXO.js +0 -68
  194. package/dist/chunk-YEJR7IXO.js.map +0 -1
  195. package/dist/chunk-YJZA2BIK.js +0 -1338
  196. package/dist/chunk-YJZA2BIK.js.map +0 -1
  197. package/dist/completion-gate-BMy5LGoP.d.ts +0 -256
  198. package/dist/conversation.js.map +0 -1
  199. package/dist/coordination-BZZSVYpZ.d.ts +0 -2570
  200. package/dist/environment-provider.js.map +0 -1
  201. package/dist/improvement-adapter-HAZz-7vK.d.ts +0 -203
  202. package/dist/knowledge.js.map +0 -1
  203. package/dist/local-harness-BDNcl6jI.d.ts +0 -175
  204. package/dist/loop-runner-bin-68aoM9-7.d.ts +0 -199
  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-B4t-OQjL.d.ts +0 -271
  209. package/dist/redact-BuFjxBUJ.d.ts +0 -481
  210. package/dist/sanitize-DEbPNtyI.d.ts +0 -328
  211. package/dist/structural-rollout-DEh6CEsa.d.ts +0 -446
  212. package/dist/supervise-4_48wwvy.d.ts +0 -379
  213. package/dist/types-BCoemcXU.d.ts +0 -802
  214. package/dist/types-BwoZWq-i.d.ts +0 -510
  215. package/dist/types-Cbp72qyu.d.ts +0 -491
  216. package/dist/types-CmYCMbFT.d.ts +0 -203
  217. package/dist/types-CvNwMzQt.d.ts +0 -957
  218. package/dist/worktree-fanout-DxhAWr5Z.d.ts +0 -999
@@ -1,1480 +1,1579 @@
1
- import {
2
- defaultRedactor,
3
- resolveRedactor
4
- } from "./chunk-OPVWXJ2H.js";
5
- import {
6
- createProtectedAgentCandidateModelPort,
7
- exactProcessProviderAsCandidateExecutor
8
- } from "./chunk-H5QPIZNX.js";
9
- import {
10
- createAgentImprovementActivationResult,
11
- executeAgentImprovementActivation,
12
- verifyAgentImprovementActivationResult
13
- } from "./chunk-VISA6CI3.js";
14
- import {
15
- AGENT_IMPROVEMENT_PROFILE_SURFACES,
16
- AgentCandidateExperimentCellExecutionError,
17
- agentImprovementProfileSurfaceDigest,
18
- agentImprovementProfileSurfaceInput,
19
- agentImprovementTargetProfileDiffs,
20
- buildAgentImprovementActivationTargets,
21
- createAgentImprovementActivation,
22
- createAgentImprovementMeasuredComparison,
23
- createAgentImprovementProposal,
24
- createOptimizationActivationReceipt,
25
- executeAgentCandidateExperimentCell,
26
- isAgentImprovementProfileSurface,
27
- optimizationActivationReceiptFromMetadata,
28
- proposeAgentImprovement,
29
- reviewAgentImprovementProposal,
30
- runAgentCandidateExperiment,
31
- verifyAgentImprovementActivation,
32
- verifyAgentImprovementProposal,
33
- verifyAgentImprovementReview,
34
- verifyCandidateExecutionEvidence
35
- } from "./chunk-UHEZW5BU.js";
36
- import {
37
- AGENT_CANDIDATE_EXECUTION_SUPPORT,
38
- applyExactAgentProfileDiff,
39
- immutableCandidateValue,
40
- omitUndefinedObjectFields,
41
- parseAgentCandidateProfileActivation,
42
- parseExactAgentProfile
43
- } from "./chunk-WSTRQZYQ.js";
44
- import "./chunk-YJZA2BIK.js";
45
- import "./chunk-UPWGXKXB.js";
46
- import {
47
- buildLoopOtelSpans,
48
- buildRuntimeEventOtelSpans,
49
- createOtelExporter,
50
- flatOtelSpan
51
- } from "./chunk-2VZYRB55.js";
52
- import "./chunk-HLKC4UYB.js";
53
- import "./chunk-ISPWRSEC.js";
54
- import {
55
- resolveAgentEnvironmentProvider
56
- } from "./chunk-KRBFHMV6.js";
57
- import "./chunk-3MDZX7YU.js";
58
- import "./chunk-FD2MBMOH.js";
59
- import "./chunk-M22PL4GH.js";
60
- import "./chunk-YEJR7IXO.js";
61
-
62
- // src/intelligence/index.ts
1
+ import { $ as parseExactAgentProfile, K as applyExactAgentProfileDiff, Q as parseAgentCandidateProfileActivation, Z as omitUndefinedObjectFields, rt as canonicalCandidateDigest$1, st as immutableCandidateValue, u as AGENT_CANDIDATE_EXECUTION_SUPPORT } from "./prepare-B53sPV7M.js";
2
+ import { n as exactProcessProviderAsCandidateExecutor, t as createProtectedAgentCandidateModelPort } from "./protected-model-port-BLPH5VVv.js";
3
+ import { C as assertProfileImprovementTargetsShareIdentity, T as isAgentImprovementProfileSurface, _ as agentImprovementProfileSurfaceDigest, a as executeAgentCandidateExperimentCell, c as reviewAgentImprovementProposal, d as verifyAgentImprovementProposal, f as verifyAgentImprovementReview, g as AGENT_IMPROVEMENT_PROFILE_SURFACES, h as optimizationActivationReceiptFromMetadata, i as createAgentImprovementProposal, l as runAgentCandidateExperiment, m as createOptimizationActivationReceipt, n as createAgentImprovementActivation, o as proposeAgentImprovement, p as verifyCandidateExecutionEvidence, r as createAgentImprovementMeasuredComparison, t as AgentCandidateExperimentCellExecutionError, u as verifyAgentImprovementActivation, v as agentImprovementProfileSurfaceInput, w as buildAgentImprovementActivationTargets, x as agentImprovementTargetProfileDiffs } from "./improvement-cycle-C095kS_g.js";
4
+ import { r as resolveRedactor, t as defaultRedactor } from "./redact-D-u-rrcn.js";
5
+ import { n as executeAgentImprovementActivation, r as verifyAgentImprovementActivationResult, t as createAgentImprovementActivationResult } from "./activation-CRjVfOiy.js";
6
+ import { i as resolveAgentEnvironmentProvider } from "./environment-provider-CfLUmKmf.js";
7
+ import { a as createOtelExporter, i as buildRuntimeEventOtelSpans, n as buildLoopOtelSpans, s as flatOtelSpan } from "./otel-export-D34IQW1C.js";
63
8
  import { contentHash } from "@tangle-network/agent-eval";
64
-
65
- // src/intelligence/delivery.ts
66
- var defaultPlaneBaseUrl = "https://intelligence.tangle.tools";
67
- var defaultRefreshMs = 3e5;
68
- var defaultPlaneRequestTimeoutMs = 1e4;
69
- var maxPlaneErrorTextLength = 200;
9
+ import { agentProfileImprovementArmSchema, applyAgentProfileDiff } from "@tangle-network/agent-interface";
10
+ //#region src/intelligence/delivery.ts
11
+ const defaultPlaneBaseUrl = "https://intelligence.tangle.tools";
12
+ const defaultRefreshMs = 3e5;
13
+ const defaultPlaneRequestTimeoutMs = 1e4;
14
+ const maxPlaneErrorTextLength = 200;
15
+ /** Resolve the ONE Intelligence base URL — the single knob both the send and
16
+ * receive paths derive from. Env fallback: `TANGLE_INTELLIGENCE_URL`. */
70
17
  function resolveIntelligenceBaseUrl(baseUrl) {
71
- if (baseUrl) return baseUrl.replace(/\/+$/, "");
72
- if (typeof process !== "undefined" && process.env.TANGLE_INTELLIGENCE_URL) {
73
- return process.env.TANGLE_INTELLIGENCE_URL.replace(/\/+$/, "");
74
- }
75
- return defaultPlaneBaseUrl;
18
+ if (baseUrl) return baseUrl.replace(/\/+$/, "");
19
+ if (typeof process !== "undefined" && process.env.TANGLE_INTELLIGENCE_URL) return process.env.TANGLE_INTELLIGENCE_URL.replace(/\/+$/, "");
20
+ return defaultPlaneBaseUrl;
76
21
  }
77
22
  function resolveApiKey(apiKey) {
78
- if (apiKey) return apiKey;
79
- if (typeof process !== "undefined" && process.env.TANGLE_API_KEY)
80
- return process.env.TANGLE_API_KEY;
81
- return "";
23
+ if (apiKey) return apiKey;
24
+ if (typeof process !== "undefined" && process.env.TANGLE_API_KEY) return process.env.TANGLE_API_KEY;
25
+ return "";
82
26
  }
27
+ /** Make one authenticated request and retain whether the network call began. */
83
28
  async function requestPlane(input) {
84
- const doFetch = input.fetchImpl ?? globalThis.fetch;
85
- if (!doFetch) {
86
- return { succeeded: false, attempted: false, error: "no fetch implementation available" };
87
- }
88
- const apiKey = resolveApiKey(input.apiKey);
89
- if (!apiKey) {
90
- return {
91
- succeeded: false,
92
- attempted: false,
93
- error: "no apiKey (set TANGLE_API_KEY or opts.apiKey)"
94
- };
95
- }
96
- try {
97
- const response = await doFetch(`${resolveIntelligenceBaseUrl(input.baseUrl)}${input.path}`, {
98
- ...input.method === void 0 ? {} : { method: input.method },
99
- headers: {
100
- authorization: `Bearer ${apiKey}`,
101
- ...input.headers ?? {}
102
- },
103
- ...input.body === void 0 ? {} : { body: input.body },
104
- signal: AbortSignal.timeout(input.timeoutMs ?? defaultPlaneRequestTimeoutMs)
105
- });
106
- return { succeeded: true, response };
107
- } catch (err) {
108
- return {
109
- succeeded: false,
110
- attempted: true,
111
- error: err instanceof Error ? err.message : String(err)
112
- };
113
- }
29
+ const doFetch = input.fetchImpl ?? globalThis.fetch;
30
+ if (!doFetch) return {
31
+ succeeded: false,
32
+ attempted: false,
33
+ error: "no fetch implementation available"
34
+ };
35
+ const apiKey = resolveApiKey(input.apiKey);
36
+ if (!apiKey) return {
37
+ succeeded: false,
38
+ attempted: false,
39
+ error: "no apiKey (set TANGLE_API_KEY or opts.apiKey)"
40
+ };
41
+ try {
42
+ return {
43
+ succeeded: true,
44
+ response: await doFetch(`${resolveIntelligenceBaseUrl(input.baseUrl)}${input.path}`, {
45
+ ...input.method === void 0 ? {} : { method: input.method },
46
+ headers: {
47
+ authorization: `Bearer ${apiKey}`,
48
+ ...input.headers ?? {}
49
+ },
50
+ ...input.body === void 0 ? {} : { body: input.body },
51
+ signal: AbortSignal.timeout(input.timeoutMs ?? defaultPlaneRequestTimeoutMs)
52
+ })
53
+ };
54
+ } catch (err) {
55
+ return {
56
+ succeeded: false,
57
+ attempted: true,
58
+ error: err instanceof Error ? err.message : String(err)
59
+ };
60
+ }
114
61
  }
115
62
  function asRecord(value) {
116
- return value && typeof value === "object" ? value : {};
63
+ return value && typeof value === "object" ? value : {};
117
64
  }
118
65
  function capPlaneErrorText(value) {
119
- return value.slice(0, maxPlaneErrorTextLength);
66
+ return value.slice(0, maxPlaneErrorTextLength);
120
67
  }
121
68
  function toDiffProvenance(value) {
122
- const p = asRecord(value);
123
- return {
124
- version: typeof p.version === "number" ? p.version : null,
125
- lift: typeof p.lift === "string" ? p.lift : null,
126
- contentHash: typeof p.contentHash === "string" ? p.contentHash : "",
127
- promotedAt: typeof p.promotedAt === "string" ? p.promotedAt : ""
128
- };
69
+ const p = asRecord(value);
70
+ return {
71
+ version: typeof p.version === "number" ? p.version : null,
72
+ lift: typeof p.lift === "string" ? p.lift : null,
73
+ contentHash: typeof p.contentHash === "string" ? p.contentHash : "",
74
+ promotedAt: typeof p.promotedAt === "string" ? p.promotedAt : ""
75
+ };
129
76
  }
77
+ /**
78
+ * Deserialize the composed-endpoint response into a `CertifiedProfile`. The
79
+ * previously-dropped `agentProfileDiffs`/`capabilities`/`agentProfile` are read
80
+ * here so they round-trip to the consumer; a plane that has not yet promoted any
81
+ * diffs simply yields empty arrays / a null profile (fail-closed, never a crash).
82
+ */
130
83
  function normalizeCertifiedProfile(raw) {
131
- const r = asRecord(raw);
132
- const promptSurface = r.promptSurface ? r.promptSurface : null;
133
- const artifacts = r.artifacts ?? {};
134
- const agentProfileDiffs = Array.isArray(r.agentProfileDiffs) ? r.agentProfileDiffs.map((entry) => {
135
- const e = asRecord(entry);
136
- return { diff: e.diff, provenance: toDiffProvenance(e.provenance) };
137
- }) : [];
138
- const capabilities = Array.isArray(r.capabilities) ? r.capabilities : [];
139
- return {
140
- target: typeof r.target === "string" ? r.target : "",
141
- generatedAt: typeof r.generatedAt === "string" ? r.generatedAt : "",
142
- promptSurface,
143
- artifacts,
144
- agentProfileDiffs,
145
- capabilities,
146
- agentProfile: r.agentProfile ?? null
147
- };
84
+ const r = asRecord(raw);
85
+ const promptSurface = r.promptSurface ? r.promptSurface : null;
86
+ const artifacts = r.artifacts ?? {};
87
+ const agentProfileDiffs = Array.isArray(r.agentProfileDiffs) ? r.agentProfileDiffs.map((entry) => {
88
+ const e = asRecord(entry);
89
+ return {
90
+ diff: e.diff,
91
+ provenance: toDiffProvenance(e.provenance)
92
+ };
93
+ }) : [];
94
+ const capabilities = Array.isArray(r.capabilities) ? r.capabilities : [];
95
+ return {
96
+ target: typeof r.target === "string" ? r.target : "",
97
+ generatedAt: typeof r.generatedAt === "string" ? r.generatedAt : "",
98
+ promptSurface,
99
+ artifacts,
100
+ agentProfileDiffs,
101
+ capabilities,
102
+ agentProfile: r.agentProfile ?? null
103
+ };
148
104
  }
105
+ /**
106
+ * Pull the certified composed profile for a target. Fail-closed: a network
107
+ * error or a non-2xx returns a typed `succeeded: false` (never throws), so a
108
+ * caller can run on its base surface when Intelligence is unreachable. A 404 is
109
+ * the normal "nothing promoted yet" signal, carried as `status: 404`.
110
+ */
149
111
  async function pullCertified(opts) {
150
- const request = await requestPlane({
151
- ...opts,
152
- path: `/v1/profiles/${encodeURIComponent(opts.target)}/composed`
153
- });
154
- if (!request.succeeded) {
155
- return {
156
- succeeded: false,
157
- error: request.attempted ? `pull request failed: ${request.error}` : request.error
158
- };
159
- }
160
- const res = request.response;
161
- if (res.status === 404) {
162
- return {
163
- succeeded: false,
164
- error: "no certified artifacts promoted for target yet",
165
- status: 404
166
- };
167
- }
168
- if (!res.ok) {
169
- const body = await res.text().catch(() => "");
170
- return {
171
- succeeded: false,
172
- error: `pull ${res.status}: ${body.slice(0, 200)}`,
173
- status: res.status
174
- };
175
- }
176
- try {
177
- return { succeeded: true, value: normalizeCertifiedProfile(await res.json()) };
178
- } catch (err) {
179
- return {
180
- succeeded: false,
181
- error: `pull response parse failed: ${err instanceof Error ? err.message : String(err)}`
182
- };
183
- }
112
+ const request = await requestPlane({
113
+ ...opts,
114
+ path: `/v1/profiles/${encodeURIComponent(opts.target)}/composed`
115
+ });
116
+ if (!request.succeeded) return {
117
+ succeeded: false,
118
+ error: request.attempted ? `pull request failed: ${request.error}` : request.error
119
+ };
120
+ const res = request.response;
121
+ if (res.status === 404) return {
122
+ succeeded: false,
123
+ error: "no certified artifacts promoted for target yet",
124
+ status: 404
125
+ };
126
+ if (!res.ok) {
127
+ const body = await res.text().catch(() => "");
128
+ return {
129
+ succeeded: false,
130
+ error: `pull ${res.status}: ${body.slice(0, 200)}`,
131
+ status: res.status
132
+ };
133
+ }
134
+ try {
135
+ return {
136
+ succeeded: true,
137
+ value: normalizeCertifiedProfile(await res.json())
138
+ };
139
+ } catch (err) {
140
+ return {
141
+ succeeded: false,
142
+ error: `pull response parse failed: ${err instanceof Error ? err.message : String(err)}`
143
+ };
144
+ }
184
145
  }
146
+ /**
147
+ * Submit a completed Runtime proposal to Intelligence for product-side review.
148
+ * This never runs an experiment, approves a proposal, or applies a candidate.
149
+ * A 4xx response is a confirmed `rejected` request. Network failures, timeouts,
150
+ * 5xx responses, and invalid success responses are `unconfirmed`, so callers
151
+ * can retry the same digest because Intelligence stores proposals idempotently.
152
+ */
185
153
  async function submitAgentImprovementProposal(opts) {
186
- let proposal;
187
- try {
188
- proposal = verifyAgentImprovementProposal(opts.proposal);
189
- } catch (err) {
190
- return {
191
- succeeded: false,
192
- submission: "not-sent",
193
- error: `proposal validation failed: ${err instanceof Error ? err.message : String(err)}`
194
- };
195
- }
196
- const request = await requestPlane({
197
- ...opts,
198
- path: "/v1/improvements/proposals",
199
- method: "POST",
200
- headers: { "content-type": "application/json" },
201
- body: JSON.stringify({ proposal })
202
- });
203
- if (!request.succeeded) {
204
- return {
205
- succeeded: false,
206
- submission: request.attempted ? "unconfirmed" : "not-sent",
207
- error: request.attempted ? `proposal submission request failed: ${request.error}` : request.error
208
- };
209
- }
210
- const res = request.response;
211
- if (!res.ok) {
212
- const body = await res.text().catch(() => "");
213
- let code;
214
- let message = capPlaneErrorText(body);
215
- try {
216
- const parsed = asRecord(JSON.parse(body));
217
- if (typeof parsed.error === "string") code = capPlaneErrorText(parsed.error);
218
- if (typeof parsed.message === "string") message = capPlaneErrorText(parsed.message);
219
- } catch {
220
- }
221
- return {
222
- succeeded: false,
223
- submission: res.status >= 400 && res.status < 500 ? "rejected" : "unconfirmed",
224
- error: `proposal submission ${res.status}: ${message}`,
225
- status: res.status,
226
- ...code === void 0 ? {} : { code }
227
- };
228
- }
229
- try {
230
- const response = asRecord(await res.json());
231
- const recorded = verifyAgentImprovementProposal(response.proposal);
232
- if (recorded.digest !== proposal.digest) {
233
- return {
234
- succeeded: false,
235
- submission: "unconfirmed",
236
- error: "proposal submission returned a different proposal digest",
237
- status: res.status
238
- };
239
- }
240
- return { succeeded: true, value: recorded, status: res.status };
241
- } catch (err) {
242
- return {
243
- succeeded: false,
244
- submission: "unconfirmed",
245
- error: `proposal submission response parse failed: ${capPlaneErrorText(
246
- err instanceof Error ? err.message : String(err)
247
- )}`,
248
- status: res.status
249
- };
250
- }
251
- }
252
- var promptFoldTypes = ["prompt-surface", "skill", "instructions"];
154
+ let proposal;
155
+ try {
156
+ proposal = verifyAgentImprovementProposal(opts.proposal);
157
+ } catch (err) {
158
+ return {
159
+ succeeded: false,
160
+ submission: "not-sent",
161
+ error: `proposal validation failed: ${err instanceof Error ? err.message : String(err)}`
162
+ };
163
+ }
164
+ const request = await requestPlane({
165
+ ...opts,
166
+ path: "/v1/improvements/proposals",
167
+ method: "POST",
168
+ headers: { "content-type": "application/json" },
169
+ body: JSON.stringify({ proposal })
170
+ });
171
+ if (!request.succeeded) return {
172
+ succeeded: false,
173
+ submission: request.attempted ? "unconfirmed" : "not-sent",
174
+ error: request.attempted ? `proposal submission request failed: ${request.error}` : request.error
175
+ };
176
+ const res = request.response;
177
+ if (!res.ok) {
178
+ const body = await res.text().catch(() => "");
179
+ let code;
180
+ let message = capPlaneErrorText(body);
181
+ try {
182
+ const parsed = asRecord(JSON.parse(body));
183
+ if (typeof parsed.error === "string") code = capPlaneErrorText(parsed.error);
184
+ if (typeof parsed.message === "string") message = capPlaneErrorText(parsed.message);
185
+ } catch {}
186
+ return {
187
+ succeeded: false,
188
+ submission: res.status >= 400 && res.status < 500 ? "rejected" : "unconfirmed",
189
+ error: `proposal submission ${res.status}: ${message}`,
190
+ status: res.status,
191
+ ...code === void 0 ? {} : { code }
192
+ };
193
+ }
194
+ try {
195
+ const recorded = verifyAgentImprovementProposal(asRecord(await res.json()).proposal);
196
+ if (recorded.digest !== proposal.digest) return {
197
+ succeeded: false,
198
+ submission: "unconfirmed",
199
+ error: "proposal submission returned a different proposal digest",
200
+ status: res.status
201
+ };
202
+ return {
203
+ succeeded: true,
204
+ value: recorded,
205
+ status: res.status
206
+ };
207
+ } catch (err) {
208
+ return {
209
+ succeeded: false,
210
+ submission: "unconfirmed",
211
+ error: `proposal submission response parse failed: ${capPlaneErrorText(err instanceof Error ? err.message : String(err))}`,
212
+ status: res.status
213
+ };
214
+ }
215
+ }
216
+ /** Artifact-type buckets that fold into the system prompt, in fold order. A
217
+ * certified `context` capability whose content is free text (`instructions`)
218
+ * is delivered here so it actually reaches the agent — never bucketed into a
219
+ * type the fold then silently skips. The resolver reuses this exact set so its
220
+ * `promptAdditions` slot matches the folded prompt byte-for-byte. */
221
+ const promptFoldTypes = [
222
+ "prompt-surface",
223
+ "skill",
224
+ "instructions"
225
+ ];
226
+ /**
227
+ * Fold the certified prompt surface (and any certified prompt-folding artifacts:
228
+ * `prompt-surface` / `skill` / `instructions`) into a base system prompt under a
229
+ * marked section, so the deployed agent prompt == base + the gate-certified
230
+ * additions. Order is stable (prompt surface first, then artifact buckets in
231
+ * `promptFoldTypes` order, then by path within a bucket) so the same profile
232
+ * renders byte-identically each call. Returns `base` unchanged when there is no
233
+ * usable certified content. Reads only the prompt-folding slice of a profile.
234
+ */
253
235
  function composeCertifiedPrompt(base, certified) {
254
- if (!certified) return base;
255
- const parts = [];
256
- if (certified.promptSurface?.surface.trim()) parts.push(certified.promptSurface.surface.trim());
257
- for (const type of promptFoldTypes) {
258
- const bucket = certified.artifacts[type] ?? [];
259
- for (const a of [...bucket].sort((x, y) => (x.path ?? "").localeCompare(y.path ?? ""))) {
260
- if (a.content.trim()) parts.push(a.content.trim());
261
- }
262
- }
263
- if (parts.length === 0) return base;
264
- return `${base.trim()}
265
-
266
- ## Certified guidance (Tangle Intelligence)
267
-
268
- ${parts.join("\n\n")}`;
236
+ if (!certified) return base;
237
+ const parts = [];
238
+ if (certified.promptSurface?.surface.trim()) parts.push(certified.promptSurface.surface.trim());
239
+ for (const type of promptFoldTypes) {
240
+ const bucket = certified.artifacts[type] ?? [];
241
+ for (const a of [...bucket].sort((x, y) => (x.path ?? "").localeCompare(y.path ?? ""))) if (a.content.trim()) parts.push(a.content.trim());
242
+ }
243
+ if (parts.length === 0) return base;
244
+ return `${base.trim()}\n\n## Certified guidance (Tangle Intelligence)\n\n${parts.join("\n\n")}`;
269
245
  }
246
+ /**
247
+ * Create the cached certified-prompt source — the ONE module-scope-cache +
248
+ * coalesced-refresh + keep-last-known implementation. Product wiring uses this
249
+ * rather than hand-rolling the same lines around `pullCertified`. The
250
+ * `withIntelligence` hook rides this same source for its prompt delivery.
251
+ */
270
252
  function createCertifiedPromptSource(opts) {
271
- const refreshMs = opts.refreshMs ?? defaultRefreshMs;
272
- let certified = null;
273
- let lastPullAt = 0;
274
- let inflight = null;
275
- async function refresh() {
276
- if (Date.now() - lastPullAt < refreshMs) return;
277
- if (inflight) return inflight;
278
- inflight = (async () => {
279
- const outcome = await pullCertified(opts);
280
- lastPullAt = Date.now();
281
- if (outcome.succeeded) certified = outcome.value;
282
- })();
283
- try {
284
- await inflight;
285
- } finally {
286
- inflight = null;
287
- }
288
- }
289
- return {
290
- refresh,
291
- current: () => certified,
292
- async compose(base) {
293
- await refresh();
294
- return composeCertifiedPrompt(base, certified);
295
- }
296
- };
253
+ const refreshMs = opts.refreshMs ?? defaultRefreshMs;
254
+ let certified = null;
255
+ let lastPullAt = 0;
256
+ let inflight = null;
257
+ async function refresh() {
258
+ if (Date.now() - lastPullAt < refreshMs) return;
259
+ if (inflight) return inflight;
260
+ inflight = (async () => {
261
+ const outcome = await pullCertified(opts);
262
+ lastPullAt = Date.now();
263
+ if (outcome.succeeded) certified = outcome.value;
264
+ })();
265
+ try {
266
+ await inflight;
267
+ } finally {
268
+ inflight = null;
269
+ }
270
+ }
271
+ return {
272
+ refresh,
273
+ current: () => certified,
274
+ async compose(base) {
275
+ await refresh();
276
+ return composeCertifiedPrompt(base, certified);
277
+ }
278
+ };
297
279
  }
298
-
299
- // src/intelligence/effort.ts
300
- var presets = {
301
- off: {
302
- analysts: false,
303
- corpus: "off",
304
- fanout: 1,
305
- loops: false,
306
- intelligenceBudgetUsd: 0
307
- },
308
- eco: {
309
- analysts: true,
310
- corpus: "read",
311
- fanout: 1,
312
- loops: false,
313
- intelligenceBudgetUsd: 0.25
314
- },
315
- standard: {
316
- analysts: true,
317
- corpus: "read-write",
318
- fanout: 3,
319
- loops: true,
320
- intelligenceBudgetUsd: 2
321
- },
322
- thorough: {
323
- analysts: true,
324
- corpus: "read-write",
325
- fanout: 5,
326
- loops: true,
327
- intelligenceBudgetUsd: 10
328
- },
329
- max: {
330
- analysts: true,
331
- corpus: "read-write",
332
- fanout: 8,
333
- loops: true,
334
- intelligenceBudgetUsd: null
335
- }
280
+ //#endregion
281
+ //#region src/intelligence/effort.ts
282
+ const presets = {
283
+ off: {
284
+ analysts: false,
285
+ corpus: "off",
286
+ fanout: 1,
287
+ loops: false,
288
+ intelligenceBudgetUsd: 0
289
+ },
290
+ eco: {
291
+ analysts: true,
292
+ corpus: "read",
293
+ fanout: 1,
294
+ loops: false,
295
+ intelligenceBudgetUsd: .25
296
+ },
297
+ standard: {
298
+ analysts: true,
299
+ corpus: "read-write",
300
+ fanout: 3,
301
+ loops: true,
302
+ intelligenceBudgetUsd: 2
303
+ },
304
+ thorough: {
305
+ analysts: true,
306
+ corpus: "read-write",
307
+ fanout: 5,
308
+ loops: true,
309
+ intelligenceBudgetUsd: 10
310
+ },
311
+ max: {
312
+ analysts: true,
313
+ corpus: "read-write",
314
+ fanout: 8,
315
+ loops: true,
316
+ intelligenceBudgetUsd: null
317
+ }
336
318
  };
337
- var defaultEffortTier = "standard";
319
+ /** The default tier when a client declares no effort. `'standard'` turns
320
+ * intelligence on with sensible knobs; opt down to `'off'`/`'eco'` or up to
321
+ * `'thorough'`/`'max'`. */
322
+ const defaultEffortTier = "standard";
323
+ /**
324
+ * Compile a named tier (plus optional per-field overrides) into the flat
325
+ * `EffortSettings` the wrapper reads. Pure: same inputs → same object, no I/O,
326
+ * no execution. Fails loud on an unknown tier rather than silently defaulting —
327
+ * a typo'd tier must not quietly grant or deny intelligence.
328
+ *
329
+ * Invariant preserved for the billing floor: `resolveEffort('off')` always
330
+ * yields `intelligenceBudgetUsd: 0` with every intelligence knob off UNLESS the
331
+ * caller explicitly overrides a field — overriding off is an opt-in the caller
332
+ * owns, not a default the composer leaks.
333
+ */
338
334
  function resolveEffort(tier, overrides) {
339
- const preset = presets[tier];
340
- if (!preset) {
341
- throw new Error(
342
- `resolveEffort: unknown effort tier ${JSON.stringify(tier)} (expected one of ${Object.keys(presets).map((t) => `'${t}'`).join(", ")})`
343
- );
344
- }
345
- return { ...preset, ...overrides ?? {} };
335
+ const preset = presets[tier];
336
+ if (!preset) throw new Error(`resolveEffort: unknown effort tier ${JSON.stringify(tier)} (expected one of ${Object.keys(presets).map((t) => `'${t}'`).join(", ")})`);
337
+ return {
338
+ ...preset,
339
+ ...overrides ?? {}
340
+ };
346
341
  }
342
+ /**
343
+ * True when these settings admit NO intelligence spawn — the passthrough
344
+ * predicate the wrapper branches on. Every intelligence axis must be off:
345
+ * analysts disabled, corpus off, no breadth, no loops, and a zero intelligence
346
+ * budget. A caller who overrides any one of these back on is no longer at the
347
+ * OFF floor and the wrapper treats them as an intelligence-enabled run.
348
+ */
347
349
  function isIntelligenceOff(settings) {
348
- return settings.analysts === false && settings.corpus === "off" && settings.fanout <= 1 && settings.loops === false && settings.intelligenceBudgetUsd === 0;
350
+ return settings.analysts === false && settings.corpus === "off" && settings.fanout <= 1 && settings.loops === false && settings.intelligenceBudgetUsd === 0;
349
351
  }
352
+ /**
353
+ * Compile resolved `EffortSettings` into the orchestration overrides above. Pure: same
354
+ * input → same object, no I/O, no execution, no construction. It is the single place that
355
+ * maps the effort axes onto the run-config knobs, so no `if (effort)` leaks into the
356
+ * supervise kernel — the kernel stays effort-blind, the caller reads these flags once.
357
+ *
358
+ * `off`/`eco` (`analysts: false`) compile to `withAnalyst: false` ⇒ the caller omits the
359
+ * analyst and the run degrades to the dormant base agent rather than throwing. `fanout: 1`
360
+ * (no breadth) at `off`; `withLoops: false` no-ops the improvement cycle. `standard`+
361
+ * compile to `withAnalyst: true`, the tier's `fanout`, and `withLoops: true`.
362
+ */
350
363
  function compileEffort(settings) {
351
- return {
352
- withAnalyst: settings.analysts,
353
- fanout: settings.fanout,
354
- withLoops: settings.loops,
355
- intelligenceBudgetUsd: settings.intelligenceBudgetUsd
356
- };
364
+ return {
365
+ withAnalyst: settings.analysts,
366
+ fanout: settings.fanout,
367
+ withLoops: settings.loops,
368
+ intelligenceBudgetUsd: settings.intelligenceBudgetUsd
369
+ };
357
370
  }
358
-
359
- // src/intelligence/capability.ts
371
+ //#endregion
372
+ //#region src/intelligence/capability.ts
373
+ /**
374
+ * A binding kind whose resolver case is typed but not yet admitted (rag-index,
375
+ * memory-store, wasm, a2a). Thrown by the resolver — NEVER faked into a working
376
+ * surface. The TYPE arms exist so the union is closed against the spec; the
377
+ * resolver grows them later behind their lifecycle + admission gate.
378
+ */
360
379
  var CapabilityNotAdmittedError = class extends Error {
361
- kind;
362
- capabilityId;
363
- constructor(kind, capabilityId, reason) {
364
- super(`capability '${capabilityId}': binding '${kind}' not admitted \u2014 ${reason}`);
365
- this.name = "CapabilityNotAdmittedError";
366
- this.kind = kind;
367
- this.capabilityId = capabilityId;
368
- }
380
+ kind;
381
+ capabilityId;
382
+ constructor(kind, capabilityId, reason) {
383
+ super(`capability '${capabilityId}': binding '${kind}' not admitted ${reason}`);
384
+ this.name = "CapabilityNotAdmittedError";
385
+ this.kind = kind;
386
+ this.capabilityId = capabilityId;
387
+ }
369
388
  };
370
- var provenanceFromArtifact = (a) => ({
371
- contentHash: a.contentHash,
372
- version: a.version,
373
- lift: a.lift,
374
- promotedAt: a.promotedAt,
375
- sourcePath: a.path
389
+ const provenanceFromArtifact = (a) => ({
390
+ contentHash: a.contentHash,
391
+ version: a.version,
392
+ lift: a.lift,
393
+ promotedAt: a.promotedAt,
394
+ sourcePath: a.path
376
395
  });
377
- var contextKindForType = (type) => type === "prompt-surface" || type === "skill" ? type : "instructions";
396
+ const contextKindForType = (type) => type === "prompt-surface" || type === "skill" ? type : "instructions";
397
+ /**
398
+ * Heuristic shape-inference for a non-context artifact. The plane stores
399
+ * `artifactType` as a free string today, so a tool/mcp-shaped artifact arrives
400
+ * as opaque content. We infer the narrowest binding that is always-valid:
401
+ * - a parseable OpenAI-tool JSON (`{ name, parameters, url? }`) → an `http`
402
+ * tool when it carries a `url`, else an inline `tool` definition;
403
+ * - a parseable MCP-server JSON (`{ command }` or `{ url, transport }`) → the
404
+ * matching strict mcp binding;
405
+ * - anything else → `context`/inline (the fail-safe — the bytes still reach the
406
+ * agent as prompt context, never dropped).
407
+ */
378
408
  function inferCapability(type, a) {
379
- const id = `${type}:${a.path ?? a.index}`;
380
- const provenance = provenanceFromArtifact(a);
381
- const parsed = tryParseJson(a.content);
382
- if (parsed && typeof parsed === "object") {
383
- const obj = parsed;
384
- if (typeof obj.command === "string") {
385
- return {
386
- id,
387
- iface: { surface: "mcp", serverName: String(obj.name ?? type) },
388
- binding: {
389
- kind: "mcp-stdio",
390
- command: obj.command,
391
- ...Array.isArray(obj.args) ? { args: obj.args.map(String) } : {},
392
- ...isStringRecord(obj.env) ? { env: obj.env } : {},
393
- ...typeof obj.cwd === "string" ? { cwd: obj.cwd } : {}
394
- },
395
- auth: { mode: "none" },
396
- provenance
397
- };
398
- }
399
- if (typeof obj.url === "string" && (obj.transport === "http" || obj.transport === "sse")) {
400
- return {
401
- id,
402
- iface: { surface: "mcp", serverName: String(obj.name ?? type) },
403
- binding: {
404
- kind: "mcp-remote",
405
- url: obj.url,
406
- transport: obj.transport,
407
- ...isStringRecord(obj.headers) ? { headers: obj.headers } : {}
408
- },
409
- auth: { mode: "none" },
410
- provenance
411
- };
412
- }
413
- if (typeof obj.name === "string" && isJsonSchema(obj.parameters)) {
414
- const iface = {
415
- surface: "tool",
416
- name: obj.name,
417
- ...typeof obj.description === "string" ? { description: obj.description } : {},
418
- parameters: obj.parameters
419
- };
420
- if (typeof obj.url === "string") {
421
- return {
422
- id,
423
- iface,
424
- binding: {
425
- kind: "http",
426
- url: obj.url,
427
- ...typeof obj.method === "string" ? { method: obj.method } : {}
428
- },
429
- auth: { mode: "none" },
430
- provenance
431
- };
432
- }
433
- return {
434
- id,
435
- iface,
436
- binding: { kind: "inline", content: { kind: "inline", content: a.content } },
437
- auth: { mode: "none" },
438
- provenance
439
- };
440
- }
441
- }
442
- return {
443
- id,
444
- iface: { surface: "context", kind: "instructions", name: a.path ?? type },
445
- binding: { kind: "inline", content: { kind: "inline", content: a.content } },
446
- auth: { mode: "none" },
447
- provenance
448
- };
409
+ const id = `${type}:${a.path ?? a.index}`;
410
+ const provenance = provenanceFromArtifact(a);
411
+ const parsed = tryParseJson(a.content);
412
+ if (parsed && typeof parsed === "object") {
413
+ const obj = parsed;
414
+ if (typeof obj.command === "string") return {
415
+ id,
416
+ iface: {
417
+ surface: "mcp",
418
+ serverName: String(obj.name ?? type)
419
+ },
420
+ binding: {
421
+ kind: "mcp-stdio",
422
+ command: obj.command,
423
+ ...Array.isArray(obj.args) ? { args: obj.args.map(String) } : {},
424
+ ...isStringRecord(obj.env) ? { env: obj.env } : {},
425
+ ...typeof obj.cwd === "string" ? { cwd: obj.cwd } : {}
426
+ },
427
+ auth: { mode: "none" },
428
+ provenance
429
+ };
430
+ if (typeof obj.url === "string" && (obj.transport === "http" || obj.transport === "sse")) return {
431
+ id,
432
+ iface: {
433
+ surface: "mcp",
434
+ serverName: String(obj.name ?? type)
435
+ },
436
+ binding: {
437
+ kind: "mcp-remote",
438
+ url: obj.url,
439
+ transport: obj.transport,
440
+ ...isStringRecord(obj.headers) ? { headers: obj.headers } : {}
441
+ },
442
+ auth: { mode: "none" },
443
+ provenance
444
+ };
445
+ if (typeof obj.name === "string" && isJsonSchema(obj.parameters)) {
446
+ const iface = {
447
+ surface: "tool",
448
+ name: obj.name,
449
+ ...typeof obj.description === "string" ? { description: obj.description } : {},
450
+ parameters: obj.parameters
451
+ };
452
+ if (typeof obj.url === "string") return {
453
+ id,
454
+ iface,
455
+ binding: {
456
+ kind: "http",
457
+ url: obj.url,
458
+ ...typeof obj.method === "string" ? { method: obj.method } : {}
459
+ },
460
+ auth: { mode: "none" },
461
+ provenance
462
+ };
463
+ return {
464
+ id,
465
+ iface,
466
+ binding: {
467
+ kind: "inline",
468
+ content: {
469
+ kind: "inline",
470
+ content: a.content
471
+ }
472
+ },
473
+ auth: { mode: "none" },
474
+ provenance
475
+ };
476
+ }
477
+ }
478
+ return {
479
+ id,
480
+ iface: {
481
+ surface: "context",
482
+ kind: "instructions",
483
+ name: a.path ?? type
484
+ },
485
+ binding: {
486
+ kind: "inline",
487
+ content: {
488
+ kind: "inline",
489
+ content: a.content
490
+ }
491
+ },
492
+ auth: { mode: "none" },
493
+ provenance
494
+ };
449
495
  }
496
+ /**
497
+ * Lower the EXISTING plane wire (`CertifiedProfile`) into a `CapabilityManifest`.
498
+ * `prompt-surface`/`skill` artifacts → `context`/inline capabilities (the
499
+ * shipped fold, generalized); any other artifact type → best-effort binding
500
+ * inference. `promptSurface` is carried through so
501
+ * the resolver folds it first, exactly as `composeCertifiedPrompt` does today.
502
+ * This delivers the spine against today's wire before the plane changes.
503
+ */
450
504
  function manifestFromProfile(profile) {
451
- const capabilities = [];
452
- for (const type of Object.keys(profile.artifacts).sort()) {
453
- const bucket = profile.artifacts[type] ?? [];
454
- const sorted = [...bucket].map((a, index) => ({ ...a, index })).sort((x, y) => (x.path ?? "").localeCompare(y.path ?? ""));
455
- for (const a of sorted) {
456
- if (type === "prompt-surface" || type === "skill") {
457
- capabilities.push({
458
- id: `${type}:${a.path ?? a.index}`,
459
- iface: { surface: "context", kind: contextKindForType(type), name: a.path ?? type },
460
- binding: { kind: "inline", content: { kind: "inline", content: a.content } },
461
- auth: { mode: "none" },
462
- provenance: provenanceFromArtifact(a)
463
- });
464
- } else {
465
- capabilities.push(inferCapability(type, a));
466
- }
467
- }
468
- }
469
- return {
470
- target: profile.target,
471
- generatedAt: profile.generatedAt,
472
- promptSurface: profile.promptSurface,
473
- capabilities
474
- };
505
+ const capabilities = [];
506
+ for (const type of Object.keys(profile.artifacts).sort()) {
507
+ const sorted = [...profile.artifacts[type] ?? []].map((a, index) => ({
508
+ ...a,
509
+ index
510
+ })).sort((x, y) => (x.path ?? "").localeCompare(y.path ?? ""));
511
+ for (const a of sorted) if (type === "prompt-surface" || type === "skill") capabilities.push({
512
+ id: `${type}:${a.path ?? a.index}`,
513
+ iface: {
514
+ surface: "context",
515
+ kind: contextKindForType(type),
516
+ name: a.path ?? type
517
+ },
518
+ binding: {
519
+ kind: "inline",
520
+ content: {
521
+ kind: "inline",
522
+ content: a.content
523
+ }
524
+ },
525
+ auth: { mode: "none" },
526
+ provenance: provenanceFromArtifact(a)
527
+ });
528
+ else capabilities.push(inferCapability(type, a));
529
+ }
530
+ return {
531
+ target: profile.target,
532
+ generatedAt: profile.generatedAt,
533
+ promptSurface: profile.promptSurface,
534
+ capabilities
535
+ };
475
536
  }
476
537
  function tryParseJson(s) {
477
- try {
478
- return JSON.parse(s);
479
- } catch {
480
- return void 0;
481
- }
538
+ try {
539
+ return JSON.parse(s);
540
+ } catch {
541
+ return;
542
+ }
482
543
  }
483
544
  function isStringRecord(v) {
484
- return typeof v === "object" && v !== null && !Array.isArray(v) && Object.values(v).every((x) => typeof x === "string");
545
+ return typeof v === "object" && v !== null && !Array.isArray(v) && Object.values(v).every((x) => typeof x === "string");
485
546
  }
486
547
  function isJsonSchema(v) {
487
- return typeof v === "object" && v !== null && !Array.isArray(v);
548
+ return typeof v === "object" && v !== null && !Array.isArray(v);
488
549
  }
489
-
490
- // src/intelligence/exact-process-candidate.ts
491
- var exactProcessCandidateExperimentExecutionSupport = Object.freeze({
492
- outcomes: Object.freeze(["output"]),
493
- outputMediaTypes: Object.freeze(["text/*", "application/json", "*+json"]),
494
- code: Object.freeze(["disabled"]),
495
- memory: Object.freeze(["disabled"]),
496
- knowledge: true,
497
- profile: AGENT_CANDIDATE_EXECUTION_SUPPORT.profile,
498
- isolation: Object.freeze({
499
- freshEnvironment: true,
500
- exactProcess: true,
501
- egress: Object.freeze(["blocked", "strict"])
502
- })
550
+ //#endregion
551
+ //#region src/intelligence/exact-process-candidate.ts
552
+ /** Candidate surfaces implemented by the neutral exact-process executor. */
553
+ const exactProcessCandidateExperimentExecutionSupport = Object.freeze({
554
+ outcomes: Object.freeze(["output"]),
555
+ outputMediaTypes: Object.freeze([
556
+ "text/*",
557
+ "application/json",
558
+ "*+json"
559
+ ]),
560
+ code: Object.freeze(["disabled"]),
561
+ memory: Object.freeze(["disabled"]),
562
+ knowledge: true,
563
+ profile: AGENT_CANDIDATE_EXECUTION_SUPPORT.profile,
564
+ isolation: Object.freeze({
565
+ freshEnvironment: true,
566
+ exactProcess: true,
567
+ egress: Object.freeze(["blocked", "strict"])
568
+ })
503
569
  });
570
+ /** Execute one signed experiment cell through any declared exact-process provider. */
504
571
  function createExactProcessCandidateExperimentExecutor(options) {
505
- const provider = resolveAgentEnvironmentProvider(options.provider, options.providerRegistry);
506
- const executor = exactProcessProviderAsCandidateExecutor({
507
- provider,
508
- resources: options.resources,
509
- ...options.providerOptions ? { providerOptions: options.providerOptions } : {},
510
- ...options.provisionTimeoutMs === void 0 ? {} : { provisionTimeoutMs: options.provisionTimeoutMs },
511
- ...options.recoveryRetentionMs === void 0 ? {} : { recoveryRetentionMs: options.recoveryRetentionMs }
512
- });
513
- return Object.freeze({
514
- executor,
515
- async execute(input) {
516
- return await executeAgentCandidateExperimentCell({
517
- ...input,
518
- attempt: input.attempt ?? 1,
519
- executionId: input.executionId,
520
- executionRoots: input.executionRoots,
521
- stagingRoots: input.stagingRoots,
522
- ports: options.ports,
523
- ...input.preparation ? { preparation: input.preparation } : {},
524
- execution: {
525
- executor,
526
- grader: options.grader,
527
- outputArtifacts: options.outputArtifacts,
528
- traceStore: options.traceStore,
529
- claimStore: options.claimStore,
530
- ...options.cleanupTimeoutMs === void 0 ? {} : { cleanupTimeoutMs: options.cleanupTimeoutMs },
531
- ...options.resultTimeoutMs === void 0 ? {} : { resultTimeoutMs: options.resultTimeoutMs }
532
- }
533
- });
534
- }
535
- });
572
+ const executor = exactProcessProviderAsCandidateExecutor({
573
+ provider: resolveAgentEnvironmentProvider(options.provider, options.providerRegistry),
574
+ resources: options.resources,
575
+ ...options.providerOptions ? { providerOptions: options.providerOptions } : {},
576
+ ...options.provisionTimeoutMs === void 0 ? {} : { provisionTimeoutMs: options.provisionTimeoutMs },
577
+ ...options.recoveryRetentionMs === void 0 ? {} : { recoveryRetentionMs: options.recoveryRetentionMs }
578
+ });
579
+ return Object.freeze({
580
+ executor,
581
+ async execute(input) {
582
+ return await executeAgentCandidateExperimentCell({
583
+ ...input,
584
+ attempt: input.attempt ?? 1,
585
+ executionId: input.executionId,
586
+ executionRoots: input.executionRoots,
587
+ stagingRoots: input.stagingRoots,
588
+ ports: options.ports,
589
+ ...input.preparation ? { preparation: input.preparation } : {},
590
+ execution: {
591
+ executor,
592
+ grader: options.grader,
593
+ outputArtifacts: options.outputArtifacts,
594
+ traceStore: options.traceStore,
595
+ claimStore: options.claimStore,
596
+ ...options.cleanupTimeoutMs === void 0 ? {} : { cleanupTimeoutMs: options.cleanupTimeoutMs },
597
+ ...options.resultTimeoutMs === void 0 ? {} : { resultTimeoutMs: options.resultTimeoutMs }
598
+ }
599
+ });
600
+ }
601
+ });
536
602
  }
603
+ /** Compose host-owned execution ports with protected model access for one exact-process run. */
537
604
  function createProtectedExactProcessCandidateExperimentExecutor(options) {
538
- const { hostPorts, model, ...exactProcess } = options;
539
- const ports = Object.freeze({
540
- ...hostPorts,
541
- models: createProtectedAgentCandidateModelPort(model)
542
- });
543
- const execution = createExactProcessCandidateExperimentExecutor({
544
- ...exactProcess,
545
- ports
546
- });
547
- return Object.freeze({
548
- ...execution,
549
- recoveryPorts: Object.freeze({ models: ports.models, memory: ports.memory })
550
- });
605
+ const { hostPorts, model, ...exactProcess } = options;
606
+ const ports = Object.freeze({
607
+ ...hostPorts,
608
+ models: createProtectedAgentCandidateModelPort(model)
609
+ });
610
+ const execution = createExactProcessCandidateExperimentExecutor({
611
+ ...exactProcess,
612
+ ports
613
+ });
614
+ return Object.freeze({
615
+ ...execution,
616
+ recoveryPorts: Object.freeze({
617
+ models: ports.models,
618
+ memory: ports.memory
619
+ })
620
+ });
551
621
  }
552
-
553
- // src/intelligence/profile-activation.ts
622
+ //#endregion
623
+ //#region src/intelligence/profile-activation.ts
624
+ /**
625
+ * Compare product-owned profiles with an exact measured transition and prepare
626
+ * all-or-none replacements. The product owns locking, persistence, and retained
627
+ * state; Runtime owns the profile diff semantics and digest checks.
628
+ */
554
629
  function prepareAgentImprovementProfileActivation(input) {
555
- const targetKeys = input.targets.map((target) => `${target.identity}\0${target.surface}`);
556
- if (new Set(targetKeys).size !== targetKeys.length) {
557
- throw new Error("agent profile activation repeats a target");
558
- }
559
- const identities = [...new Set(input.targets.map((target) => target.identity))].sort();
560
- const missing = identities.filter((identity) => !input.currentByIdentity.has(identity));
561
- if (missing.length > 0) {
562
- return immutableCandidateValue({ status: "missing", identities: missing });
563
- }
564
- const currentProfiles = new Map(
565
- identities.map((identity) => {
566
- const profile = input.currentByIdentity.get(identity);
567
- if (!profile) throw new Error(`missing agent profile ${identity}`);
568
- const label = `agent profile activation ${identity}`;
569
- return [identity, parseExactAgentProfile(omitUndefinedObjectFields(profile, label), label)];
570
- })
571
- );
572
- const current = input.targets.map((target) => {
573
- const profile = currentProfiles.get(target.identity);
574
- if (!profile) throw new Error(`missing agent profile ${target.identity}`);
575
- return {
576
- target,
577
- currentDigest: agentImprovementProfileSurfaceDigest(profile, target.surface)
578
- };
579
- });
580
- const states = current.map(({ target, currentDigest }) => ({
581
- surface: target.surface,
582
- identity: target.identity,
583
- currentDigest
584
- }));
585
- if (current.every(({ target, currentDigest }) => currentDigest === target.desiredDigest)) {
586
- return immutableCandidateValue({ status: "already-applied", targets: states });
587
- }
588
- if (current.some(({ target, currentDigest }) => currentDigest !== target.expectedBaseDigest)) {
589
- return immutableCandidateValue({ status: "conflict", targets: states });
590
- }
591
- const profiles = /* @__PURE__ */ new Map();
592
- for (const identity of identities) {
593
- const currentProfile = currentProfiles.get(identity);
594
- if (!currentProfile) throw new Error(`missing agent profile ${identity}`);
595
- const profile = input.targets.filter((target) => target.identity === identity).flatMap(
596
- (target) => agentImprovementTargetProfileDiffs(target, {
597
- id: `${target.identity}:${target.desiredDigest}`,
598
- metadata: { identity }
599
- })
600
- ).reduce(
601
- (value, diff) => applyExactAgentProfileDiff(value, diff, `agent profile activation ${identity}`),
602
- currentProfile
603
- );
604
- profiles.set(identity, immutableCandidateValue(profile));
605
- }
606
- for (const target of input.targets) {
607
- const profile = profiles.get(target.identity);
608
- if (!profile || agentImprovementProfileSurfaceDigest(profile, target.surface) !== target.desiredDigest) {
609
- throw new Error(
610
- `agent profile activation did not produce ${target.identity}:${target.surface}`
611
- );
612
- }
613
- }
614
- return immutableCandidateValue({
615
- status: "apply",
616
- replacements: identities.map((identity) => {
617
- const profile = profiles.get(identity);
618
- if (!profile) throw new Error(`missing prepared agent profile ${identity}`);
619
- return { identity, profile };
620
- }),
621
- targets: input.targets.map((target) => ({
622
- surface: target.surface,
623
- identity: target.identity,
624
- beforeDigest: target.expectedBaseDigest,
625
- afterDigest: target.desiredDigest
626
- }))
627
- });
630
+ const targets = "profileTransition" in input ? profileTargets(input.profileTransition.targets) : input.targets;
631
+ assertUniqueProfileTargets(targets);
632
+ const current = readCurrentProfiles(input.currentByIdentity, targets);
633
+ if ("status" in current) return immutableCandidateValue(current);
634
+ if ("profileTransition" in input) return prepareProfileImprovementActivation(input, targets, current);
635
+ return prepareSurfaceReplacementActivation(targets, current);
628
636
  }
629
-
630
- // src/intelligence/resolver.ts
637
+ function prepareSurfaceReplacementActivation(targets, currentProfiles) {
638
+ const current = targets.map((target) => {
639
+ const profile = currentProfiles.byIdentity.get(target.identity);
640
+ if (!profile) throw new Error(`missing agent profile ${target.identity}`);
641
+ return {
642
+ target,
643
+ currentDigest: agentImprovementProfileSurfaceDigest(profile, target.surface)
644
+ };
645
+ });
646
+ const states = targetStates(current);
647
+ if (current.every(({ target, currentDigest }) => currentDigest === target.desiredDigest)) return immutableCandidateValue({
648
+ status: "already-applied",
649
+ targets: states
650
+ });
651
+ if (current.some(({ target, currentDigest }) => currentDigest !== target.expectedBaseDigest)) return immutableCandidateValue({
652
+ status: "conflict",
653
+ targets: states
654
+ });
655
+ const profiles = /* @__PURE__ */ new Map();
656
+ for (const identity of currentProfiles.identities) {
657
+ const currentProfile = currentProfiles.byIdentity.get(identity);
658
+ if (!currentProfile) throw new Error(`missing agent profile ${identity}`);
659
+ const profile = targets.filter((target) => target.identity === identity).flatMap((target) => agentImprovementTargetProfileDiffs(target, {
660
+ id: `${target.identity}:${target.desiredDigest}`,
661
+ metadata: { identity }
662
+ })).reduce((value, diff) => applyExactAgentProfileDiff(value, diff, `agent profile activation ${identity}`), currentProfile);
663
+ profiles.set(identity, immutableCandidateValue(profile));
664
+ }
665
+ for (const target of targets) {
666
+ const profile = profiles.get(target.identity);
667
+ if (!profile || agentImprovementProfileSurfaceDigest(profile, target.surface) !== target.desiredDigest) throw new Error(`agent profile activation did not produce ${target.identity}:${target.surface}`);
668
+ }
669
+ return appliedProfileReplacement(currentProfiles.identities, profiles, targets);
670
+ }
671
+ function prepareProfileImprovementActivation(input, targets, currentProfiles) {
672
+ const transition = input.profileTransition;
673
+ assertProfileTransitionTargets(transition, targets);
674
+ const current = targets.map((target) => {
675
+ const profile = currentProfiles.byIdentity.get(target.identity);
676
+ if (!profile) throw new Error(`missing agent profile ${target.identity}`);
677
+ return {
678
+ target,
679
+ currentDigest: profileStateDigest(input.stateDigest, target.identity, profile)
680
+ };
681
+ });
682
+ const states = targetStates(current);
683
+ if (current.every(({ currentDigest }) => currentDigest === transition.desiredStateDigest)) return immutableCandidateValue({
684
+ status: "already-applied",
685
+ targets: states
686
+ });
687
+ if (current.some(({ currentDigest }) => currentDigest !== transition.sourceStateDigest)) return immutableCandidateValue({
688
+ status: "conflict",
689
+ targets: states
690
+ });
691
+ const profiles = /* @__PURE__ */ new Map();
692
+ for (const identity of currentProfiles.identities) {
693
+ const currentProfile = currentProfiles.byIdentity.get(identity);
694
+ if (!currentProfile) throw new Error(`missing agent profile ${identity}`);
695
+ const profile = transition.operation.kind === "apply-change" ? transition.operation.changes.reduce((value, diff) => applyExactAgentProfileDiff(value, diff, `profile improvement activation ${identity}`), currentProfile) : restoreProfileState(input.resolveState, identity, transition.desiredStateDigest);
696
+ if (!profile) return immutableCandidateValue({
697
+ status: "unavailable",
698
+ code: "PROFILE_STATE_UNAVAILABLE",
699
+ identities: currentProfiles.identities,
700
+ requiredStateDigest: transition.desiredStateDigest
701
+ });
702
+ const parsed = parseExactAgentProfile(omitUndefinedObjectFields(profile, `profile improvement activation ${identity}`), `profile improvement activation ${identity}`);
703
+ if (profileStateDigest(input.stateDigest, identity, parsed) !== transition.desiredStateDigest) throw new Error(`profile improvement activation did not produce ${identity}`);
704
+ profiles.set(identity, immutableCandidateValue(parsed));
705
+ }
706
+ return appliedProfileReplacement(currentProfiles.identities, profiles, targets);
707
+ }
708
+ function restoreProfileState(resolveState, identity, stateDigest) {
709
+ return resolveState?.({
710
+ identity,
711
+ stateDigest
712
+ });
713
+ }
714
+ function assertProfileTransitionTargets(transition, targets) {
715
+ assertProfileImprovementTargetsShareIdentity(targets);
716
+ const operationDigest = canonicalCandidateDigest$1(transition.operation);
717
+ if (targets.some((target) => target.expectedBaseDigest !== transition.sourceStateDigest || target.desiredDigest !== transition.desiredStateDigest || canonicalCandidateDigest$1(target.desiredInput) !== operationDigest)) throw new Error("profile improvement targets do not match their transition");
718
+ }
719
+ function appliedProfileReplacement(identities, profiles, targets) {
720
+ return immutableCandidateValue({
721
+ status: "apply",
722
+ replacements: identities.map((identity) => {
723
+ const profile = profiles.get(identity);
724
+ if (!profile) throw new Error(`missing prepared agent profile ${identity}`);
725
+ return {
726
+ identity,
727
+ profile
728
+ };
729
+ }),
730
+ targets: targets.map((target) => ({
731
+ surface: target.surface,
732
+ identity: target.identity,
733
+ beforeDigest: target.expectedBaseDigest,
734
+ afterDigest: target.desiredDigest
735
+ }))
736
+ });
737
+ }
738
+ function targetStates(current) {
739
+ if (!current[0]) throw new Error("agent profile activation requires a target");
740
+ return current.map(({ target, currentDigest }) => ({
741
+ surface: target.surface,
742
+ identity: target.identity,
743
+ currentDigest
744
+ }));
745
+ }
746
+ function profileStateDigest(stateDigest, identity, profile) {
747
+ return agentProfileImprovementArmSchema.parse({ stateDigest: stateDigest({
748
+ identity,
749
+ profile
750
+ }) }).stateDigest;
751
+ }
752
+ function readCurrentProfiles(currentByIdentity, targets) {
753
+ const identities = [...new Set(targets.map((target) => target.identity))].sort();
754
+ const missing = identities.filter((identity) => !currentByIdentity.has(identity));
755
+ if (missing.length > 0) return {
756
+ status: "missing",
757
+ identities: missing
758
+ };
759
+ return {
760
+ identities,
761
+ byIdentity: new Map(identities.map((identity) => {
762
+ const profile = currentByIdentity.get(identity);
763
+ if (!profile) throw new Error(`missing agent profile ${identity}`);
764
+ const label = `agent profile activation ${identity}`;
765
+ return [identity, parseExactAgentProfile(omitUndefinedObjectFields(profile, label), label)];
766
+ }))
767
+ };
768
+ }
769
+ function profileTargets(targets) {
770
+ if (!targets.every((target) => isAgentImprovementProfileSurface(target.surface))) throw new Error("agent profile activation contains an unsupported surface");
771
+ if (!targets[0]) throw new Error("agent profile activation requires a target");
772
+ return targets;
773
+ }
774
+ function assertUniqueProfileTargets(targets) {
775
+ const targetKeys = targets.map((target) => `${target.identity}\u0000${target.surface}`);
776
+ if (new Set(targetKeys).size !== targetKeys.length) throw new Error("agent profile activation repeats a target");
777
+ }
778
+ //#endregion
779
+ //#region src/intelligence/resolver.ts
631
780
  function emptyAccumulator() {
632
- return {
633
- tools: [],
634
- executors: /* @__PURE__ */ new Map(),
635
- mcpConnections: {},
636
- contextArtifacts: {},
637
- files: [],
638
- retrieval: [],
639
- hooks: [],
640
- subagents: [],
641
- teardowns: [],
642
- toolCapabilityId: /* @__PURE__ */ new Map(),
643
- mcpCapability: /* @__PURE__ */ new Map()
644
- };
781
+ return {
782
+ tools: [],
783
+ executors: /* @__PURE__ */ new Map(),
784
+ mcpConnections: {},
785
+ contextArtifacts: {},
786
+ files: [],
787
+ retrieval: [],
788
+ hooks: [],
789
+ subagents: [],
790
+ teardowns: [],
791
+ toolCapabilityId: /* @__PURE__ */ new Map(),
792
+ mcpCapability: /* @__PURE__ */ new Map()
793
+ };
645
794
  }
795
+ /**
796
+ * Compose a certified profile into a uniform `ResolvedSurface`. Additive over
797
+ * `composeCertifiedPrompt`: the inline/context fold is delegated to
798
+ * `composeCertifiedPrompt` so the byte-stable ordering (prompt surface first,
799
+ * then type alphabetic, then path locale-compare) is reused EXACTLY — the
800
+ * prompt-only path is a strict subset of this.
801
+ *
802
+ * Fail-closed: a `null` manifest returns the base surface only.
803
+ */
646
804
  async function composeCertifiedProfile(base, manifest, ctx = {}) {
647
- if (!manifest || manifest.capabilities.length === 0) {
648
- return baseSurface(base.systemPrompt, manifest?.promptSurface ?? null);
649
- }
650
- const acc = emptyAccumulator();
651
- for (const cap of manifest.capabilities) {
652
- try {
653
- await resolveCapability(cap, ctx, acc);
654
- } catch (err) {
655
- if (err instanceof CapabilityNotAdmittedError) throw err;
656
- ctx.onDrop?.(cap.id, err instanceof Error ? err : new Error(String(err)));
657
- }
658
- }
659
- await driftDropTools(acc, ctx);
660
- const promptAdditions = collectPromptAdditions(manifest.promptSurface, acc.contextArtifacts);
661
- const systemPrompt = composeCertifiedPrompt(base.systemPrompt, {
662
- promptSurface: manifest.promptSurface,
663
- artifacts: acc.contextArtifacts
664
- });
665
- const teardowns = acc.teardowns;
666
- return {
667
- tools: acc.tools,
668
- async execute(name, args, task) {
669
- const fn = acc.executors.get(name);
670
- if (!fn) throw new Error(`composeCertifiedProfile.execute: unknown tool '${name}'`);
671
- return fn(args, task);
672
- },
673
- mcpConnections: acc.mcpConnections,
674
- promptAdditions,
675
- files: acc.files,
676
- retrieval: acc.retrieval,
677
- hooks: acc.hooks,
678
- subagents: acc.subagents,
679
- systemPrompt,
680
- async dispose() {
681
- for (let i = teardowns.length - 1; i >= 0; i -= 1) {
682
- const teardown = teardowns[i];
683
- if (teardown) await teardown();
684
- }
685
- }
686
- };
805
+ if (!manifest || manifest.capabilities.length === 0) return baseSurface(base.systemPrompt, manifest?.promptSurface ?? null);
806
+ const acc = emptyAccumulator();
807
+ for (const cap of manifest.capabilities) try {
808
+ await resolveCapability(cap, ctx, acc);
809
+ } catch (err) {
810
+ if (err instanceof CapabilityNotAdmittedError) throw err;
811
+ ctx.onDrop?.(cap.id, err instanceof Error ? err : new Error(String(err)));
812
+ }
813
+ await driftDropTools(acc, ctx);
814
+ const promptAdditions = collectPromptAdditions(manifest.promptSurface, acc.contextArtifacts);
815
+ const systemPrompt = composeCertifiedPrompt(base.systemPrompt, {
816
+ promptSurface: manifest.promptSurface,
817
+ artifacts: acc.contextArtifacts
818
+ });
819
+ const teardowns = acc.teardowns;
820
+ return {
821
+ tools: acc.tools,
822
+ async execute(name, args, task) {
823
+ const fn = acc.executors.get(name);
824
+ if (!fn) throw new Error(`composeCertifiedProfile.execute: unknown tool '${name}'`);
825
+ return fn(args, task);
826
+ },
827
+ mcpConnections: acc.mcpConnections,
828
+ promptAdditions,
829
+ files: acc.files,
830
+ retrieval: acc.retrieval,
831
+ hooks: acc.hooks,
832
+ subagents: acc.subagents,
833
+ systemPrompt,
834
+ async dispose() {
835
+ for (let i = teardowns.length - 1; i >= 0; i -= 1) {
836
+ const teardown = teardowns[i];
837
+ if (teardown) await teardown();
838
+ }
839
+ }
840
+ };
687
841
  }
688
842
  function baseSurface(systemPrompt, promptSurface) {
689
- const folded = composeCertifiedPrompt(systemPrompt, {
690
- promptSurface,
691
- artifacts: {}
692
- });
693
- return {
694
- tools: [],
695
- async execute(name) {
696
- throw new Error(`composeCertifiedProfile.execute: unknown tool '${name}'`);
697
- },
698
- mcpConnections: {},
699
- promptAdditions: collectPromptAdditions(promptSurface, {}),
700
- files: [],
701
- retrieval: [],
702
- hooks: [],
703
- subagents: [],
704
- systemPrompt: folded,
705
- async dispose() {
706
- }
707
- };
843
+ const folded = composeCertifiedPrompt(systemPrompt, {
844
+ promptSurface,
845
+ artifacts: {}
846
+ });
847
+ return {
848
+ tools: [],
849
+ async execute(name) {
850
+ throw new Error(`composeCertifiedProfile.execute: unknown tool '${name}'`);
851
+ },
852
+ mcpConnections: {},
853
+ promptAdditions: collectPromptAdditions(promptSurface, {}),
854
+ files: [],
855
+ retrieval: [],
856
+ hooks: [],
857
+ subagents: [],
858
+ systemPrompt: folded,
859
+ async dispose() {}
860
+ };
708
861
  }
862
+ /** The byte-stable prompt additions a viewer/debugger can inspect — the same
863
+ * parts `composeCertifiedPrompt` joins into the folded prompt, in the same fold
864
+ * order (`promptFoldTypes`). */
709
865
  function collectPromptAdditions(promptSurface, contextArtifacts) {
710
- const parts = [];
711
- if (promptSurface?.surface.trim()) parts.push(promptSurface.surface.trim());
712
- for (const type of promptFoldTypes) {
713
- const bucket = contextArtifacts[type] ?? [];
714
- for (const a of [...bucket].sort((x, y) => (x.path ?? "").localeCompare(y.path ?? ""))) {
715
- if (a.content.trim()) parts.push(a.content.trim());
716
- }
717
- }
718
- return parts;
866
+ const parts = [];
867
+ if (promptSurface?.surface.trim()) parts.push(promptSurface.surface.trim());
868
+ for (const type of promptFoldTypes) {
869
+ const bucket = contextArtifacts[type] ?? [];
870
+ for (const a of [...bucket].sort((x, y) => (x.path ?? "").localeCompare(y.path ?? ""))) if (a.content.trim()) parts.push(a.content.trim());
871
+ }
872
+ return parts;
719
873
  }
720
874
  async function resolveCapability(cap, ctx, acc) {
721
- await resolveBinding(cap, cap.binding, ctx, acc);
875
+ await resolveBinding(cap, cap.binding, ctx, acc);
722
876
  }
723
877
  async function resolveBinding(cap, binding, ctx, acc) {
724
- switch (binding.kind) {
725
- case "inline":
726
- resolveInline(cap, binding, acc);
727
- return;
728
- case "file":
729
- resolveFile(cap, binding, acc);
730
- return;
731
- case "http":
732
- resolveHttp(cap, binding, ctx, acc);
733
- return;
734
- case "mcp-stdio":
735
- case "mcp-remote":
736
- resolveMcp(cap, binding, acc);
737
- return;
738
- case "sandbox-code":
739
- resolveSandboxCode(cap, binding, ctx, acc);
740
- return;
741
- case "process-on-infra":
742
- await resolveProcessOnInfra(cap, binding, ctx, acc, /* @__PURE__ */ new Set());
743
- return;
744
- case "rag-index":
745
- throw new CapabilityNotAdmittedError(
746
- binding.kind,
747
- cap.id,
748
- "rag retrieval lift must clear the E3 score-superiority admission bar before a store is trusted (memory/e3-certified-memory-verdict)"
749
- );
750
- case "memory-store":
751
- throw new CapabilityNotAdmittedError(
752
- binding.kind,
753
- cap.id,
754
- "memory-store admission is gated on the E3 score-superiority bar (memory/e3-certified-memory-verdict)"
755
- );
756
- case "wasm":
757
- throw new CapabilityNotAdmittedError(
758
- binding.kind,
759
- cap.id,
760
- "wasm is an extension-point arm, not yet admitted"
761
- );
762
- case "a2a":
763
- throw new CapabilityNotAdmittedError(
764
- binding.kind,
765
- cap.id,
766
- "a2a is an extension-point arm, not yet admitted"
767
- );
768
- }
878
+ switch (binding.kind) {
879
+ case "inline":
880
+ resolveInline(cap, binding, acc);
881
+ return;
882
+ case "file":
883
+ resolveFile(cap, binding, acc);
884
+ return;
885
+ case "http":
886
+ resolveHttp(cap, binding, ctx, acc);
887
+ return;
888
+ case "mcp-stdio":
889
+ case "mcp-remote":
890
+ resolveMcp(cap, binding, acc);
891
+ return;
892
+ case "sandbox-code":
893
+ resolveSandboxCode(cap, binding, ctx, acc);
894
+ return;
895
+ case "process-on-infra":
896
+ await resolveProcessOnInfra(cap, binding, ctx, acc, /* @__PURE__ */ new Set());
897
+ return;
898
+ case "rag-index": throw new CapabilityNotAdmittedError(binding.kind, cap.id, "rag retrieval lift must clear the E3 score-superiority admission bar before a store is trusted (memory/e3-certified-memory-verdict)");
899
+ case "memory-store": throw new CapabilityNotAdmittedError(binding.kind, cap.id, "memory-store admission is gated on the E3 score-superiority bar (memory/e3-certified-memory-verdict)");
900
+ case "wasm": throw new CapabilityNotAdmittedError(binding.kind, cap.id, "wasm is an extension-point arm, not yet admitted");
901
+ case "a2a": throw new CapabilityNotAdmittedError(binding.kind, cap.id, "a2a is an extension-point arm, not yet admitted");
902
+ }
769
903
  }
904
+ /** inline → a context artifact (prompt-surface/skill folded) or an inline tool
905
+ * def. Context capabilities feed the byte-stable prompt fold; an inline `tool`
906
+ * interface registers a host-side tool whose body is the inlined JSON spec. */
770
907
  function resolveInline(cap, binding, acc) {
771
- const content = inlineContent(cap, binding.content);
772
- if (cap.iface.surface === "context") {
773
- pushContextArtifact(acc, cap, content);
774
- return;
775
- }
776
- if (cap.iface.surface === "tool") {
777
- registerInlineTool(cap, content, acc);
778
- return;
779
- }
780
- pushContextArtifact(acc, cap, content);
908
+ const content = inlineContent(cap, binding.content);
909
+ if (cap.iface.surface === "context") {
910
+ pushContextArtifact(acc, cap, content);
911
+ return;
912
+ }
913
+ if (cap.iface.surface === "tool") {
914
+ registerInlineTool(cap, content, acc);
915
+ return;
916
+ }
917
+ pushContextArtifact(acc, cap, content);
781
918
  }
919
+ /** An inline `tool` interface registers a host-side `ToolSpec` whose body is the
920
+ * static inlined content (a fixed response / canned handler). Its `execute`
921
+ * returns the content verbatim — the agent calls it like any other tool. */
782
922
  function registerInlineTool(cap, content, acc) {
783
- if (cap.iface.surface !== "tool") return;
784
- const iface = cap.iface;
785
- acc.tools.push({
786
- type: "function",
787
- function: {
788
- name: iface.name,
789
- ...iface.description ? { description: iface.description } : {},
790
- parameters: iface.parameters
791
- }
792
- });
793
- acc.toolCapabilityId.set(iface.name, cap.id);
794
- acc.executors.set(iface.name, async () => content);
923
+ if (cap.iface.surface !== "tool") return;
924
+ const iface = cap.iface;
925
+ acc.tools.push({
926
+ type: "function",
927
+ function: {
928
+ name: iface.name,
929
+ ...iface.description ? { description: iface.description } : {},
930
+ parameters: iface.parameters
931
+ }
932
+ });
933
+ acc.toolCapabilityId.set(iface.name, cap.id);
934
+ acc.executors.set(iface.name, async () => content);
795
935
  }
936
+ /** file → a workspace file mount (+ a prompt fold when the file is context). */
796
937
  function resolveFile(cap, binding, acc) {
797
- const content = inlineContent(cap, binding.content);
798
- acc.files.push({
799
- path: binding.path,
800
- content,
801
- ...binding.executable ? { executable: true } : {}
802
- });
803
- if (cap.iface.surface === "context") pushContextArtifact(acc, cap, content);
938
+ const content = inlineContent(cap, binding.content);
939
+ acc.files.push({
940
+ path: binding.path,
941
+ content,
942
+ ...binding.executable ? { executable: true } : {}
943
+ });
944
+ if (cap.iface.surface === "context") pushContextArtifact(acc, cap, content);
804
945
  }
946
+ /** mcp-stdio/mcp-remote → an `AgentProfileMcpServer`. The strict discriminated
947
+ * union widens to the SDK's flat shape — an always-valid lowering, no translation. */
805
948
  function resolveMcp(cap, binding, acc) {
806
- const serverName = cap.iface.surface === "mcp" ? cap.iface.serverName : cap.id;
807
- acc.mcpConnections[serverName] = mcpServerFromBinding(binding, cap);
808
- acc.mcpCapability.set(serverName, {
809
- capabilityId: cap.id,
810
- certifiedNames: cap.iface.surface === "mcp" ? cap.iface.toolset ?? [] : []
811
- });
949
+ const serverName = cap.iface.surface === "mcp" ? cap.iface.serverName : cap.id;
950
+ acc.mcpConnections[serverName] = mcpServerFromBinding(binding, cap);
951
+ acc.mcpCapability.set(serverName, {
952
+ capabilityId: cap.id,
953
+ certifiedNames: cap.iface.surface === "mcp" ? cap.iface.toolset ?? [] : []
954
+ });
812
955
  }
813
956
  function mcpServerFromBinding(binding, cap) {
814
- const metadata = { capabilityId: cap.id };
815
- if (cap.iface.surface === "mcp" && cap.iface.toolset) metadata.tools = cap.iface.toolset;
816
- if (binding.kind === "mcp-stdio") {
817
- return {
818
- transport: "stdio",
819
- command: binding.command,
820
- ...binding.args ? { args: binding.args } : {},
821
- ...binding.env ? { env: binding.env } : {},
822
- ...binding.cwd ? { cwd: binding.cwd } : {},
823
- enabled: true,
824
- metadata
825
- };
826
- }
827
- return {
828
- transport: binding.transport,
829
- url: binding.url,
830
- ...binding.headers ? { headers: binding.headers } : {},
831
- enabled: true,
832
- metadata
833
- };
957
+ const metadata = { capabilityId: cap.id };
958
+ if (cap.iface.surface === "mcp" && cap.iface.toolset) metadata.tools = cap.iface.toolset;
959
+ if (binding.kind === "mcp-stdio") return {
960
+ transport: "stdio",
961
+ command: binding.command,
962
+ ...binding.args ? { args: binding.args } : {},
963
+ ...binding.env ? { env: binding.env } : {},
964
+ ...binding.cwd ? { cwd: binding.cwd } : {},
965
+ enabled: true,
966
+ metadata
967
+ };
968
+ return {
969
+ transport: binding.transport,
970
+ url: binding.url,
971
+ ...binding.headers ? { headers: binding.headers } : {},
972
+ enabled: true,
973
+ metadata
974
+ };
834
975
  }
976
+ /** http → a `ToolSpec` + a host-side fetch `execute`. THE host seam: an http
977
+ * tool is callable in-process, never injected into a sandbox profile. */
835
978
  function resolveHttp(cap, binding, ctx, acc) {
836
- if (cap.iface.surface !== "tool") {
837
- throw new Error(`capability '${cap.id}': http binding requires a 'tool' interface`);
838
- }
839
- const iface = cap.iface;
840
- acc.tools.push({
841
- type: "function",
842
- function: {
843
- name: iface.name,
844
- ...iface.description ? { description: iface.description } : {},
845
- parameters: iface.parameters
846
- }
847
- });
848
- acc.toolCapabilityId.set(iface.name, cap.id);
849
- const method = binding.method ?? "POST";
850
- const auth = binding.auth ?? cap.auth;
851
- acc.executors.set(iface.name, async (args) => {
852
- const doFetch = ctx.fetchImpl ?? globalThis.fetch;
853
- if (!doFetch) throw new Error(`capability '${cap.id}': no fetch implementation for http tool`);
854
- const headers = { "content-type": "application/json" };
855
- if (auth.mode !== "none") {
856
- if (!ctx.resolveSecret) {
857
- throw new Error(
858
- `capability '${cap.id}': http auth '${auth.mode}' requires ResolveCtx.resolveSecret`
859
- );
860
- }
861
- const secret = await ctx.resolveSecret(auth, ctx.tenant);
862
- if (!secret.succeeded) {
863
- throw new Error(`capability '${cap.id}': secret resolution failed \u2014 ${secret.error}`);
864
- }
865
- headers.authorization = `Bearer ${secret.value}`;
866
- }
867
- const res = await doFetch(binding.url, {
868
- method,
869
- headers,
870
- ...method === "GET" ? {} : { body: JSON.stringify(args) }
871
- });
872
- if (!res.ok) {
873
- const body = await res.text().catch(() => "");
874
- throw new Error(`capability '${cap.id}': http ${res.status}: ${body.slice(0, 200)}`);
875
- }
876
- return res.text();
877
- });
979
+ if (cap.iface.surface !== "tool") throw new Error(`capability '${cap.id}': http binding requires a 'tool' interface`);
980
+ const iface = cap.iface;
981
+ acc.tools.push({
982
+ type: "function",
983
+ function: {
984
+ name: iface.name,
985
+ ...iface.description ? { description: iface.description } : {},
986
+ parameters: iface.parameters
987
+ }
988
+ });
989
+ acc.toolCapabilityId.set(iface.name, cap.id);
990
+ const method = binding.method ?? "POST";
991
+ const auth = binding.auth ?? cap.auth;
992
+ acc.executors.set(iface.name, async (args) => {
993
+ const doFetch = ctx.fetchImpl ?? globalThis.fetch;
994
+ if (!doFetch) throw new Error(`capability '${cap.id}': no fetch implementation for http tool`);
995
+ const headers = { "content-type": "application/json" };
996
+ if (auth.mode !== "none") {
997
+ if (!ctx.resolveSecret) throw new Error(`capability '${cap.id}': http auth '${auth.mode}' requires ResolveCtx.resolveSecret`);
998
+ const secret = await ctx.resolveSecret(auth, ctx.tenant);
999
+ if (!secret.succeeded) throw new Error(`capability '${cap.id}': secret resolution failed — ${secret.error}`);
1000
+ headers.authorization = `Bearer ${secret.value}`;
1001
+ }
1002
+ const res = await doFetch(binding.url, {
1003
+ method,
1004
+ headers,
1005
+ ...method === "GET" ? {} : { body: JSON.stringify(args) }
1006
+ });
1007
+ if (!res.ok) {
1008
+ const body = await res.text().catch(() => "");
1009
+ throw new Error(`capability '${cap.id}': http ${res.status}: ${body.slice(0, 200)}`);
1010
+ }
1011
+ return res.text();
1012
+ });
878
1013
  }
1014
+ /** sandbox-code → a host-side tool whose body runs per-call in a box, via the
1015
+ * injected `runSandboxCode` (the host owns the sandbox client). */
879
1016
  function resolveSandboxCode(cap, binding, ctx, acc) {
880
- if (cap.iface.surface !== "tool") {
881
- throw new Error(`capability '${cap.id}': sandbox-code binding requires a 'tool' interface`);
882
- }
883
- const iface = cap.iface;
884
- acc.tools.push({
885
- type: "function",
886
- function: {
887
- name: iface.name,
888
- ...iface.description ? { description: iface.description } : {},
889
- parameters: iface.parameters
890
- }
891
- });
892
- acc.toolCapabilityId.set(iface.name, cap.id);
893
- acc.executors.set(iface.name, async (args, task) => {
894
- if (!ctx.runSandboxCode) {
895
- throw new Error(
896
- `capability '${cap.id}': sandbox-code binding requires ResolveCtx.runSandboxCode`
897
- );
898
- }
899
- return ctx.runSandboxCode(binding.code, binding.entry, args, task);
900
- });
1017
+ if (cap.iface.surface !== "tool") throw new Error(`capability '${cap.id}': sandbox-code binding requires a 'tool' interface`);
1018
+ const iface = cap.iface;
1019
+ acc.tools.push({
1020
+ type: "function",
1021
+ function: {
1022
+ name: iface.name,
1023
+ ...iface.description ? { description: iface.description } : {},
1024
+ parameters: iface.parameters
1025
+ }
1026
+ });
1027
+ acc.toolCapabilityId.set(iface.name, cap.id);
1028
+ acc.executors.set(iface.name, async (args, task) => {
1029
+ if (!ctx.runSandboxCode) throw new Error(`capability '${cap.id}': sandbox-code binding requires ResolveCtx.runSandboxCode`);
1030
+ return ctx.runSandboxCode(binding.code, binding.entry, args, task);
1031
+ });
901
1032
  }
1033
+ /**
1034
+ * process-on-infra → provision the host FIRST (depth-first), then resolve the
1035
+ * inner binding inside it. The injected `provisionHost` owns `createExecutor`;
1036
+ * this resolver wires the returned connection + teardown (reverse dep order) and
1037
+ * the cost tag. A `visited` set guards against a self-referential host cycle.
1038
+ */
902
1039
  async function resolveProcessOnInfra(cap, binding, ctx, acc, visited) {
903
- if (visited.has(binding)) {
904
- throw new Error(`capability '${cap.id}': process-on-infra cycle detected`);
905
- }
906
- visited.add(binding);
907
- if (!ctx.provisionHost) {
908
- throw new Error(
909
- `capability '${cap.id}': process-on-infra binding requires ResolveCtx.provisionHost`
910
- );
911
- }
912
- if (binding.inner.kind === "process-on-infra") {
913
- const outer = await ctx.provisionHost(
914
- binding.host,
915
- binding.inner,
916
- hostCostTag(cap, binding.host)
917
- );
918
- acc.teardowns.push(() => outer.teardown());
919
- await resolveProcessOnInfra(cap, binding.inner, ctx, acc, visited);
920
- return;
921
- }
922
- const provisioned = await ctx.provisionHost(
923
- binding.host,
924
- binding.inner,
925
- hostCostTag(cap, binding.host)
926
- );
927
- acc.teardowns.push(() => provisioned.teardown());
928
- if (provisioned.mcpConnection) {
929
- const serverName = cap.iface.surface === "mcp" ? cap.iface.serverName : cap.id;
930
- acc.mcpConnections[serverName] = provisioned.mcpConnection;
931
- acc.mcpCapability.set(serverName, {
932
- capabilityId: cap.id,
933
- certifiedNames: cap.iface.surface === "mcp" ? cap.iface.toolset ?? [] : []
934
- });
935
- }
1040
+ if (visited.has(binding)) throw new Error(`capability '${cap.id}': process-on-infra cycle detected`);
1041
+ visited.add(binding);
1042
+ if (!ctx.provisionHost) throw new Error(`capability '${cap.id}': process-on-infra binding requires ResolveCtx.provisionHost`);
1043
+ if (binding.inner.kind === "process-on-infra") {
1044
+ const outer = await ctx.provisionHost(binding.host, binding.inner, hostCostTag(cap, binding.host));
1045
+ acc.teardowns.push(() => outer.teardown());
1046
+ await resolveProcessOnInfra(cap, binding.inner, ctx, acc, visited);
1047
+ return;
1048
+ }
1049
+ const provisioned = await ctx.provisionHost(binding.host, binding.inner, hostCostTag(cap, binding.host));
1050
+ acc.teardowns.push(() => provisioned.teardown());
1051
+ if (provisioned.mcpConnection) {
1052
+ const serverName = cap.iface.surface === "mcp" ? cap.iface.serverName : cap.id;
1053
+ acc.mcpConnections[serverName] = provisioned.mcpConnection;
1054
+ acc.mcpCapability.set(serverName, {
1055
+ capabilityId: cap.id,
1056
+ certifiedNames: cap.iface.surface === "mcp" ? cap.iface.toolset ?? [] : []
1057
+ });
1058
+ }
936
1059
  }
937
1060
  function hostCostTag(cap, host) {
938
- return host.costTag ?? `capability/${cap.id}`;
1061
+ return host.costTag ?? `capability/${cap.id}`;
939
1062
  }
1063
+ /**
1064
+ * Post-resolve drift check (fail-closed): a resolved surface's LIVE tool names
1065
+ * must equal the certified interface — mismatch → drop. The only callable tools
1066
+ * are gate-blessed ones. Two enforcement layers:
1067
+ * 1. host-side parity — every registered tool keeps a matching executor and
1068
+ * vice-versa (a half-wired tool, e.g. one whose provision failed, is
1069
+ * removed rather than exposed);
1070
+ * 2. live-name equality (when `ctx.probeLiveToolNames` is wired) — for each
1071
+ * host tool the live name must contain the certified name; for each mcp
1072
+ * server the live `tools/list` must equal the certified `toolset`.
1073
+ * A drop removes BOTH the tool spec and its executor (host) or the connection
1074
+ * (mcp); a capability that lost its drift check never reaches the agent.
1075
+ */
940
1076
  async function driftDropTools(acc, ctx) {
941
- const specNames = new Set(acc.tools.map((t) => t.function.name));
942
- for (const name of acc.executors.keys()) {
943
- if (!specNames.has(name)) acc.executors.delete(name);
944
- }
945
- acc.tools = acc.tools.filter((t) => acc.executors.has(t.function.name));
946
- if (!ctx.probeLiveToolNames) return;
947
- const droppedTools = /* @__PURE__ */ new Set();
948
- for (const tool of acc.tools) {
949
- const capId = acc.toolCapabilityId.get(tool.function.name);
950
- if (!capId) continue;
951
- const live = await ctx.probeLiveToolNames(capId);
952
- if (!live.includes(tool.function.name)) droppedTools.add(tool.function.name);
953
- }
954
- for (const name of droppedTools) {
955
- acc.executors.delete(name);
956
- }
957
- acc.tools = acc.tools.filter((t) => !droppedTools.has(t.function.name));
958
- for (const [serverName, info] of acc.mcpCapability) {
959
- if (info.certifiedNames.length === 0) continue;
960
- const live = await ctx.probeLiveToolNames(info.capabilityId);
961
- if (!setsEqual(new Set(live), new Set(info.certifiedNames))) {
962
- delete acc.mcpConnections[serverName];
963
- acc.mcpCapability.delete(serverName);
964
- }
965
- }
1077
+ const specNames = new Set(acc.tools.map((t) => t.function.name));
1078
+ for (const name of acc.executors.keys()) if (!specNames.has(name)) acc.executors.delete(name);
1079
+ acc.tools = acc.tools.filter((t) => acc.executors.has(t.function.name));
1080
+ if (!ctx.probeLiveToolNames) return;
1081
+ const droppedTools = /* @__PURE__ */ new Set();
1082
+ for (const tool of acc.tools) {
1083
+ const capId = acc.toolCapabilityId.get(tool.function.name);
1084
+ if (!capId) continue;
1085
+ if (!(await ctx.probeLiveToolNames(capId)).includes(tool.function.name)) droppedTools.add(tool.function.name);
1086
+ }
1087
+ for (const name of droppedTools) acc.executors.delete(name);
1088
+ acc.tools = acc.tools.filter((t) => !droppedTools.has(t.function.name));
1089
+ for (const [serverName, info] of acc.mcpCapability) {
1090
+ if (info.certifiedNames.length === 0) continue;
1091
+ const live = await ctx.probeLiveToolNames(info.capabilityId);
1092
+ if (!setsEqual(new Set(live), new Set(info.certifiedNames))) {
1093
+ delete acc.mcpConnections[serverName];
1094
+ acc.mcpCapability.delete(serverName);
1095
+ }
1096
+ }
966
1097
  }
967
1098
  function setsEqual(a, b) {
968
- if (a.size !== b.size) return false;
969
- for (const x of a) if (!b.has(x)) return false;
970
- return true;
1099
+ if (a.size !== b.size) return false;
1100
+ for (const x of a) if (!b.has(x)) return false;
1101
+ return true;
971
1102
  }
972
1103
  function inlineContent(cap, ref) {
973
- if (ref.kind === "inline") return ref.content;
974
- throw new Error(
975
- `capability '${cap.id}': content ref '${ref.kind}' is not inline \u2014 wire a content fetcher to resolve it`
976
- );
1104
+ if (ref.kind === "inline") return ref.content;
1105
+ throw new Error(`capability '${cap.id}': content ref '${ref.kind}' is not inline — wire a content fetcher to resolve it`);
977
1106
  }
978
1107
  function pushContextArtifact(acc, cap, content) {
979
- const type = contextArtifactType(cap);
980
- const bucket = acc.contextArtifacts[type] ?? [];
981
- acc.contextArtifacts[type] = bucket;
982
- bucket.push({
983
- path: contextArtifactPath(cap),
984
- content,
985
- contentHash: cap.provenance.contentHash,
986
- version: cap.provenance.version,
987
- lift: cap.provenance.lift,
988
- promotedAt: cap.provenance.promotedAt
989
- });
1108
+ const type = contextArtifactType(cap);
1109
+ const bucket = acc.contextArtifacts[type] ?? [];
1110
+ acc.contextArtifacts[type] = bucket;
1111
+ bucket.push({
1112
+ path: contextArtifactPath(cap),
1113
+ content,
1114
+ contentHash: cap.provenance.contentHash,
1115
+ version: cap.provenance.version,
1116
+ lift: cap.provenance.lift,
1117
+ promotedAt: cap.provenance.promotedAt
1118
+ });
990
1119
  }
1120
+ /** Map a context capability onto the artifact-type bucket `composeCertifiedPrompt`
1121
+ * folds. The `prompt-surface`/`skill`/`instructions` buckets all fold into the
1122
+ * prompt (see `promptFoldTypes`), so context bytes always reach the agent; a
1123
+ * non-context surface lowered here as the fail-safe folds as `instructions`. */
991
1124
  function contextArtifactType(cap) {
992
- if (cap.iface.surface === "context") {
993
- return cap.iface.kind === "instructions" ? "instructions" : cap.iface.kind;
994
- }
995
- return "instructions";
1125
+ if (cap.iface.surface === "context") return cap.iface.kind === "instructions" ? "instructions" : cap.iface.kind;
1126
+ return "instructions";
996
1127
  }
1128
+ /** The artifact's byte-stable fold sort key — the ORIGINAL source path,
1129
+ * including `null`, round-tripped through provenance. The resolver folds in
1130
+ * `composeCertifiedPrompt` order (sort by `path ?? ''`), so `null` is
1131
+ * load-bearing and must survive the manifest→resolve→fold trip unchanged. This
1132
+ * is deliberately NOT `iface.name` (display only) — conflating the two flips
1133
+ * the fold order against the gate-certified reference. */
997
1134
  function contextArtifactPath(cap) {
998
- return cap.provenance.sourcePath;
1135
+ return cap.provenance.sourcePath;
999
1136
  }
1137
+ /** Lower a plane `CertifiedProfile` straight into a `ResolvedSurface` via
1138
+ * `manifestFromProfile` — the convenience the shipped pull lane calls when it
1139
+ * already holds a `CertifiedProfile` (today's wire) rather than a manifest. */
1000
1140
  async function composeCertifiedProfileFromWire(base, profile, ctx = {}) {
1001
- if (!profile) return composeCertifiedProfile(base, null, ctx);
1002
- return composeCertifiedProfile(base, manifestFromProfile(profile), ctx);
1141
+ if (!profile) return composeCertifiedProfile(base, null, ctx);
1142
+ return composeCertifiedProfile(base, manifestFromProfile(profile), ctx);
1003
1143
  }
1004
-
1005
- // src/intelligence/with-intelligence.ts
1006
- import { applyAgentProfileDiff } from "@tangle-network/agent-interface";
1144
+ //#endregion
1145
+ //#region src/intelligence/with-intelligence.ts
1007
1146
  function summarizeRuntimeEvents(events) {
1008
- const summary = { inferenceUsd: 0, inputTokens: 0, outputTokens: 0 };
1009
- for (const event of events) {
1010
- if ("session" in event && event.session) summary.sessionId = event.session.id;
1011
- if (event.type === "llm_call") {
1012
- summary.model = event.model;
1013
- summary.inferenceUsd += event.costUsd ?? 0;
1014
- summary.inputTokens += event.tokensIn ?? 0;
1015
- summary.outputTokens += event.tokensOut ?? 0;
1016
- } else if (event.type === "backend_error") {
1017
- summary.success = false;
1018
- summary.error = {
1019
- name: event.error?.kind ?? "BackendError",
1020
- message: event.message,
1021
- ...event.error?.status !== void 0 ? { code: String(event.error.status) } : {}
1022
- };
1023
- } else if (event.type === "final") {
1024
- summary.success = event.status === "completed";
1025
- if (event.error) {
1026
- summary.error = {
1027
- name: event.error.kind,
1028
- message: event.error.message,
1029
- ...event.error.status !== void 0 ? { code: String(event.error.status) } : {}
1030
- };
1031
- }
1032
- }
1033
- }
1034
- return summary;
1147
+ const summary = {
1148
+ inferenceUsd: 0,
1149
+ inputTokens: 0,
1150
+ outputTokens: 0
1151
+ };
1152
+ for (const event of events) {
1153
+ if ("session" in event && event.session) summary.sessionId = event.session.id;
1154
+ if (event.type === "llm_call") {
1155
+ summary.model = event.model;
1156
+ summary.inferenceUsd += event.costUsd ?? 0;
1157
+ summary.inputTokens += event.tokensIn ?? 0;
1158
+ summary.outputTokens += event.tokensOut ?? 0;
1159
+ } else if (event.type === "backend_error") {
1160
+ summary.success = false;
1161
+ summary.error = {
1162
+ name: event.error?.kind ?? "BackendError",
1163
+ message: event.message,
1164
+ ...event.error?.status !== void 0 ? { code: String(event.error.status) } : {}
1165
+ };
1166
+ } else if (event.type === "final") {
1167
+ summary.success = event.status === "completed";
1168
+ if (event.error) summary.error = {
1169
+ name: event.error.kind,
1170
+ message: event.error.message,
1171
+ ...event.error.status !== void 0 ? { code: String(event.error.status) } : {}
1172
+ };
1173
+ }
1174
+ }
1175
+ return summary;
1035
1176
  }
1036
1177
  function runError(cause) {
1037
- if (cause instanceof Error) {
1038
- const code = cause.code;
1039
- return {
1040
- name: cause.name || "Error",
1041
- message: cause.message,
1042
- ...typeof code === "string" || typeof code === "number" ? { code: String(code) } : {}
1043
- };
1044
- }
1045
- return { name: "Error", message: String(cause) };
1178
+ if (cause instanceof Error) {
1179
+ const code = cause.code;
1180
+ return {
1181
+ name: cause.name || "Error",
1182
+ message: cause.message,
1183
+ ...typeof code === "string" || typeof code === "number" ? { code: String(code) } : {}
1184
+ };
1185
+ }
1186
+ return {
1187
+ name: "Error",
1188
+ message: String(cause)
1189
+ };
1046
1190
  }
1191
+ /**
1192
+ * Wrap an agent so it (a) RECEIVES the tenant's certified profile — the prompt
1193
+ * surface to fold and the promoted profile diffs as proposals — and (b) SENDS a
1194
+ * typed {@link RunRecord} per call to the plane. The pull is cached and refreshed
1195
+ * at most every `refreshMs`; a failed pull is fail-closed (the agent runs on its
1196
+ * base surface, never breaks because Intelligence is unreachable). The send is
1197
+ * best-effort — an export failure never fails the agent's turn — while an error
1198
+ * thrown by the agent itself propagates unchanged.
1199
+ */
1047
1200
  function withIntelligence(agent, config) {
1048
- const client = createIntelligenceClient(config);
1049
- const target = config.target ?? config.project;
1050
- const source = createCertifiedPromptSource({
1051
- target,
1052
- ...config.apiKey !== void 0 ? { apiKey: config.apiKey } : {},
1053
- ...config.baseUrl !== void 0 ? { baseUrl: config.baseUrl } : {},
1054
- ...config.timeoutMs !== void 0 ? { timeoutMs: config.timeoutMs } : {},
1055
- ...config.fetchImpl !== void 0 ? { fetchImpl: config.fetchImpl } : {},
1056
- ...config.refreshMs !== void 0 ? { refreshMs: config.refreshMs } : {}
1057
- });
1058
- const currentProposals = () => source.current()?.agentProfileDiffs ?? [];
1059
- let lastSignal = "";
1060
- function signalProposals() {
1061
- const proposals = currentProposals();
1062
- if (proposals.length === 0) return;
1063
- const sig = proposals.map((p) => p.provenance.contentHash).join("|");
1064
- if (sig === lastSignal) return;
1065
- lastSignal = sig;
1066
- config.onProposals?.(proposals);
1067
- }
1068
- async function refresh() {
1069
- await source.refresh();
1070
- signalProposals();
1071
- }
1072
- const wrapped = (async (input) => {
1073
- const runId = client.freshRunId();
1074
- const traceId = client.freshTraceId();
1075
- const startedAt = Date.now();
1076
- await refresh();
1077
- const certified = source.current();
1078
- const proposals = currentProposals();
1079
- const report = {};
1080
- const applied = {
1081
- runId,
1082
- traceId,
1083
- certified,
1084
- composePrompt: (base) => composeCertifiedPrompt(base, certified),
1085
- proposals,
1086
- applyProfile: (base) => proposals.reduce((profile, p) => applyAgentProfileDiff(profile, p.diff), base),
1087
- record: (r) => Object.assign(report, r)
1088
- };
1089
- function exportCompleted(output, caught) {
1090
- const completedAt = Date.now();
1091
- const eventSummary = summarizeRuntimeEvents(report.runtimeEvents ?? []);
1092
- const error = report.error ?? (caught !== void 0 ? runError(caught) : eventSummary.error);
1093
- const tokens = report.tokens ?? (eventSummary.inputTokens > 0 || eventSummary.outputTokens > 0 ? { input: eventSummary.inputTokens, output: eventSummary.outputTokens } : void 0);
1094
- const profile = report.profile ?? config.profile;
1095
- const record = {
1096
- runId,
1097
- traceId,
1098
- project: config.project,
1099
- target,
1100
- input,
1101
- output,
1102
- outcome: {
1103
- success: report.success ?? (caught !== void 0 ? false : eventSummary.success ?? error === void 0),
1104
- ...report.score !== void 0 ? { score: report.score } : {},
1105
- usage: {
1106
- inferenceUsd: report.usage?.inferenceUsd ?? report.costUsd ?? eventSummary.inferenceUsd,
1107
- intelligenceUsd: report.usage?.intelligenceUsd ?? 0
1108
- }
1109
- },
1110
- timing: { startedAt, completedAt, durationMs: completedAt - startedAt },
1111
- ...report.model ?? eventSummary.model ? { model: report.model ?? eventSummary.model } : {},
1112
- ...report.provider !== void 0 ? { provider: report.provider } : {},
1113
- ...report.loopEvents !== void 0 ? { loopEvents: report.loopEvents } : {},
1114
- ...report.runtimeEvents !== void 0 ? { runtimeEvents: report.runtimeEvents } : {},
1115
- ...profile !== void 0 ? { profile } : {},
1116
- ...report.sessionId ?? eventSummary.sessionId ? { sessionId: report.sessionId ?? eventSummary.sessionId } : {},
1117
- ...report.harness ?? profile?.harness ? { harness: report.harness ?? profile?.harness } : {},
1118
- ...report.commitSha ?? config.commitSha ? { commitSha: report.commitSha ?? config.commitSha } : {},
1119
- ...tokens !== void 0 ? { tokens } : {},
1120
- ...error !== void 0 ? { error } : {},
1121
- ...report.candidateExecution !== void 0 ? { candidateExecution: report.candidateExecution } : {}
1122
- };
1123
- client.exportRunRecord(record);
1124
- }
1125
- try {
1126
- const output = await agent(input, applied);
1127
- exportCompleted(output);
1128
- return output;
1129
- } catch (cause) {
1130
- exportCompleted(void 0, cause);
1131
- throw cause;
1132
- }
1133
- });
1134
- wrapped.refresh = refresh;
1135
- wrapped.proposals = currentProposals;
1136
- wrapped.flush = client.flush;
1137
- return wrapped;
1201
+ const client = createIntelligenceClient(config);
1202
+ const target = config.target ?? config.project;
1203
+ const source = createCertifiedPromptSource({
1204
+ target,
1205
+ ...config.apiKey !== void 0 ? { apiKey: config.apiKey } : {},
1206
+ ...config.baseUrl !== void 0 ? { baseUrl: config.baseUrl } : {},
1207
+ ...config.timeoutMs !== void 0 ? { timeoutMs: config.timeoutMs } : {},
1208
+ ...config.fetchImpl !== void 0 ? { fetchImpl: config.fetchImpl } : {},
1209
+ ...config.refreshMs !== void 0 ? { refreshMs: config.refreshMs } : {}
1210
+ });
1211
+ const currentProposals = () => source.current()?.agentProfileDiffs ?? [];
1212
+ let lastSignal = "";
1213
+ function signalProposals() {
1214
+ const proposals = currentProposals();
1215
+ if (proposals.length === 0) return;
1216
+ const sig = proposals.map((p) => p.provenance.contentHash).join("|");
1217
+ if (sig === lastSignal) return;
1218
+ lastSignal = sig;
1219
+ config.onProposals?.(proposals);
1220
+ }
1221
+ async function refresh() {
1222
+ await source.refresh();
1223
+ signalProposals();
1224
+ }
1225
+ const wrapped = (async (input) => {
1226
+ const runId = client.freshRunId();
1227
+ const traceId = client.freshTraceId();
1228
+ const startedAt = Date.now();
1229
+ await refresh();
1230
+ const certified = source.current();
1231
+ const proposals = currentProposals();
1232
+ const report = {};
1233
+ const applied = {
1234
+ runId,
1235
+ traceId,
1236
+ certified,
1237
+ composePrompt: (base) => composeCertifiedPrompt(base, certified),
1238
+ proposals,
1239
+ applyProfile: (base) => proposals.reduce((profile, p) => applyAgentProfileDiff(profile, p.diff), base),
1240
+ record: (r) => Object.assign(report, r)
1241
+ };
1242
+ function exportCompleted(output, caught) {
1243
+ const completedAt = Date.now();
1244
+ const eventSummary = summarizeRuntimeEvents(report.runtimeEvents ?? []);
1245
+ const error = report.error ?? (caught !== void 0 ? runError(caught) : eventSummary.error);
1246
+ const tokens = report.tokens ?? (eventSummary.inputTokens > 0 || eventSummary.outputTokens > 0 ? {
1247
+ input: eventSummary.inputTokens,
1248
+ output: eventSummary.outputTokens
1249
+ } : void 0);
1250
+ const profile = report.profile ?? config.profile;
1251
+ const record = {
1252
+ runId,
1253
+ traceId,
1254
+ project: config.project,
1255
+ target,
1256
+ input,
1257
+ output,
1258
+ outcome: {
1259
+ success: report.success ?? (caught !== void 0 ? false : eventSummary.success ?? error === void 0),
1260
+ ...report.score !== void 0 ? { score: report.score } : {},
1261
+ usage: {
1262
+ inferenceUsd: report.usage?.inferenceUsd ?? report.costUsd ?? eventSummary.inferenceUsd,
1263
+ intelligenceUsd: report.usage?.intelligenceUsd ?? 0
1264
+ }
1265
+ },
1266
+ timing: {
1267
+ startedAt,
1268
+ completedAt,
1269
+ durationMs: completedAt - startedAt
1270
+ },
1271
+ ...report.model ?? eventSummary.model ? { model: report.model ?? eventSummary.model } : {},
1272
+ ...report.provider !== void 0 ? { provider: report.provider } : {},
1273
+ ...report.loopEvents !== void 0 ? { loopEvents: report.loopEvents } : {},
1274
+ ...report.runtimeEvents !== void 0 ? { runtimeEvents: report.runtimeEvents } : {},
1275
+ ...profile !== void 0 ? { profile } : {},
1276
+ ...report.sessionId ?? eventSummary.sessionId ? { sessionId: report.sessionId ?? eventSummary.sessionId } : {},
1277
+ ...report.harness ?? profile?.harness ? { harness: report.harness ?? profile?.harness } : {},
1278
+ ...report.commitSha ?? config.commitSha ? { commitSha: report.commitSha ?? config.commitSha } : {},
1279
+ ...tokens !== void 0 ? { tokens } : {},
1280
+ ...error !== void 0 ? { error } : {},
1281
+ ...report.candidateExecution !== void 0 ? { candidateExecution: report.candidateExecution } : {}
1282
+ };
1283
+ client.exportRunRecord(record);
1284
+ }
1285
+ try {
1286
+ const output = await agent(input, applied);
1287
+ exportCompleted(output);
1288
+ return output;
1289
+ } catch (cause) {
1290
+ exportCompleted(void 0, cause);
1291
+ throw cause;
1292
+ }
1293
+ });
1294
+ wrapped.refresh = refresh;
1295
+ wrapped.proposals = currentProposals;
1296
+ wrapped.flush = client.flush;
1297
+ return wrapped;
1138
1298
  }
1139
-
1140
- // src/intelligence/index.ts
1299
+ //#endregion
1300
+ //#region src/intelligence/index.ts
1301
+ /**
1302
+ *
1303
+ * Tangle Intelligence SDK — trace capture plus reviewable improvement.
1304
+ *
1305
+ * The client keeps live-agent trace delivery best-effort. The separate
1306
+ * improvement-cycle exports analyze completed traces, run a signed baseline
1307
+ * versus candidate experiment, bind review to its result, and activate only
1308
+ * the exact measured candidate.
1309
+ *
1310
+ * 1. OBSERVE — wrap a generic agent and export one trace span per call to
1311
+ * Tangle Intelligence, swallowing every export failure so a live agent
1312
+ * never fails because Intelligence is down.
1313
+ * 2. MODE 0 / OFF — at `effort: 'off'`, run the agent as PURE PASSTHROUGH
1314
+ * (zero intelligence spawns) with best-effort telemetry still on. The
1315
+ * exported trace tags usage by class `{ inferenceUsd, intelligenceUsd }`,
1316
+ * and at OFF `intelligenceUsd` is provably `0` — the mechanism that proves
1317
+ * an OFF customer paid inference-only.
1318
+ *
1319
+ * @experimental
1320
+ */
1141
1321
  function resolveEffortConfig(effort) {
1142
- if (effort === void 0) return resolveEffort(defaultEffortTier);
1143
- if (typeof effort === "string") return resolveEffort(effort);
1144
- return resolveEffort(effort.tier, effort.overrides);
1322
+ if (effort === void 0) return resolveEffort(defaultEffortTier);
1323
+ if (typeof effort === "string") return resolveEffort(effort);
1324
+ return resolveEffort(effort.tier, effort.overrides);
1145
1325
  }
1146
1326
  function freshTraceId() {
1147
- return randomHex(32);
1327
+ return randomHex(32);
1148
1328
  }
1149
1329
  function freshRunId() {
1150
- return `run-${randomHex(16)}`;
1330
+ return `run-${randomHex(16)}`;
1151
1331
  }
1332
+ /** Serialize a redacted value without dropping customer trace content. */
1152
1333
  function serializeJson(value) {
1153
- let s;
1154
- if (typeof value === "string") s = value;
1155
- else {
1156
- try {
1157
- s = JSON.stringify(value) ?? String(value);
1158
- } catch {
1159
- s = String(value);
1160
- }
1161
- }
1162
- return s;
1334
+ let s;
1335
+ if (typeof value === "string") s = value;
1336
+ else try {
1337
+ s = JSON.stringify(value) ?? String(value);
1338
+ } catch {
1339
+ s = String(value);
1340
+ }
1341
+ return s;
1163
1342
  }
1164
1343
  function addPayloadAttributes(labels, key, value, includeFullPayload) {
1165
- const serialized = serializeJson(value);
1166
- labels[`${key}_hash`] = contentHash(serialized);
1167
- labels[`${key}_bytes`] = Buffer.byteLength(serialized, "utf8");
1168
- if (includeFullPayload) labels[key] = serialized;
1344
+ const serialized = serializeJson(value);
1345
+ labels[`${key}_hash`] = contentHash(serialized);
1346
+ labels[`${key}_bytes`] = Buffer.byteLength(serialized, "utf8");
1347
+ if (includeFullPayload) labels[key] = serialized;
1169
1348
  }
1170
1349
  function randomHex(chars) {
1171
- const bytes = new Uint8Array(Math.ceil(chars / 2));
1172
- if (typeof globalThis.crypto?.getRandomValues === "function") {
1173
- globalThis.crypto.getRandomValues(bytes);
1174
- } else {
1175
- for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
1176
- }
1177
- return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, chars);
1350
+ const bytes = new Uint8Array(Math.ceil(chars / 2));
1351
+ if (typeof globalThis.crypto?.getRandomValues === "function") globalThis.crypto.getRandomValues(bytes);
1352
+ else for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
1353
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, chars);
1178
1354
  }
1355
+ /**
1356
+ * Create an Observe-mode Intelligence client. Resolves effort, the base URL, and
1357
+ * the redactor up front; the exporter is built lazily and is `undefined` when no
1358
+ * `apiKey` is present (send becomes a no-op — the ingest requires a tenant key,
1359
+ * and best-effort export must never spam an unauthenticated plane).
1360
+ */
1179
1361
  function createIntelligenceClient(config) {
1180
- if (!config.project) {
1181
- throw new Error("createIntelligenceClient: `project` is required");
1182
- }
1183
- const effort = resolveEffortConfig(config.effort);
1184
- const intelligenceOff = isIntelligenceOff(effort);
1185
- const redactor = resolveRedactor(config.redact);
1186
- const includeFullPayload = config.payloadAttributes === "full";
1187
- const apiKey = config.apiKey ?? (typeof process !== "undefined" ? process.env.TANGLE_API_KEY : void 0);
1188
- const otlpEndpoint = `${resolveIntelligenceBaseUrl(config.baseUrl)}/v1/otlp`;
1189
- let exporter;
1190
- let exporterResolved = false;
1191
- function getExporter() {
1192
- if (exporterResolved) return exporter;
1193
- exporterResolved = true;
1194
- if (!apiKey) return void 0;
1195
- exporter = createOtelExporter({
1196
- endpoint: otlpEndpoint,
1197
- headers: { authorization: `Bearer ${apiKey}` },
1198
- serviceName: config.project,
1199
- resourceAttributes: { "tangle.project": config.project }
1200
- });
1201
- return exporter;
1202
- }
1203
- function exportTrace(meta, outcome, output) {
1204
- const ex = getExporter();
1205
- if (!ex) return;
1206
- try {
1207
- const labels = {
1208
- project: config.project,
1209
- "tangle.effort.intelligence_off": outcome.intelligenceOff,
1210
- "tangle.usage.inference_usd": outcome.usage.inferenceUsd,
1211
- "tangle.usage.intelligence_usd": outcome.usage.intelligenceUsd,
1212
- ...meta.model ? { "gen_ai.request.model": meta.model } : {},
1213
- ...meta.provider ? { "provider.name": meta.provider } : {},
1214
- ...typeof outcome.success === "boolean" ? { "tangle.outcome.success": outcome.success } : {},
1215
- ...typeof outcome.score === "number" ? { "tangle.outcome.score": outcome.score } : {},
1216
- ...meta.labels ?? {}
1217
- };
1218
- const redactedInput = meta.input !== void 0 ? redactor(meta.input) : void 0;
1219
- const redactedOutput = output !== void 0 ? redactor(output) : void 0;
1220
- if (redactedInput !== void 0) {
1221
- addPayloadAttributes(labels, "tangle.input", redactedInput, includeFullPayload);
1222
- }
1223
- if (redactedOutput !== void 0) {
1224
- addPayloadAttributes(labels, "tangle.output", redactedOutput, includeFullPayload);
1225
- }
1226
- ex.exportSpan(
1227
- flatOtelSpan(
1228
- "tangle.intelligence.run",
1229
- { "tangle.runId": outcome.runId, ...labels },
1230
- outcome.traceId,
1231
- Date.now()
1232
- )
1233
- );
1234
- } catch {
1235
- }
1236
- }
1237
- function exportRunRecord(record) {
1238
- const ex = getExporter();
1239
- if (!ex) return record.traceId;
1240
- try {
1241
- const intelligenceUsd = intelligenceOff ? 0 : record.outcome.usage.intelligenceUsd;
1242
- const repository = record.repository ?? (config.repo ? `${config.repo.owner}/${config.repo.name}` : void 0);
1243
- const labels = {
1244
- project: record.project,
1245
- "tangle.target": record.target,
1246
- "tangle.effort.intelligence_off": intelligenceOff,
1247
- "tangle.usage.inference_usd": record.outcome.usage.inferenceUsd,
1248
- "tangle.usage.intelligence_usd": intelligenceUsd,
1249
- ...record.model ? { "gen_ai.request.model": record.model } : {},
1250
- ...record.provider ? { "provider.name": record.provider } : {},
1251
- ...record.sessionId ? {
1252
- "tangle.sessionId": record.sessionId,
1253
- "gen_ai.conversation.id": record.sessionId
1254
- } : {},
1255
- ...record.harness ? { "tangle.agent.harness": record.harness } : {},
1256
- ...repository ? { "vcs.repository.name": repository } : {},
1257
- ...record.commitSha ? { "vcs.ref.head.revision": record.commitSha } : {},
1258
- ...record.timing ? {
1259
- "tangle.started_at_ms": record.timing.startedAt,
1260
- "tangle.completed_at_ms": record.timing.completedAt,
1261
- "tangle.duration_ms": record.timing.durationMs
1262
- } : {},
1263
- ...record.tokens ? {
1264
- "gen_ai.usage.input_tokens": record.tokens.input,
1265
- "gen_ai.usage.output_tokens": record.tokens.output,
1266
- ...record.tokens.cachedInput !== void 0 ? { "gen_ai.usage.cache_read_input_tokens": record.tokens.cachedInput } : {},
1267
- ...record.tokens.reasoning !== void 0 ? { "gen_ai.usage.reasoning_tokens": record.tokens.reasoning } : {}
1268
- } : {},
1269
- ...typeof record.outcome.success === "boolean" ? { "tangle.outcome.success": record.outcome.success } : {},
1270
- ...typeof record.outcome.score === "number" ? { "tangle.outcome.score": record.outcome.score } : {},
1271
- ...record.error ? {
1272
- "error.type": record.error.code ?? record.error.name,
1273
- "error.message": serializeJson(redactor(record.error.message))
1274
- } : {},
1275
- ...record.runtimeEvents ? { "tangle.runtime.event_count": record.runtimeEvents.length } : {},
1276
- ...record.candidateExecution ? {
1277
- "tangle.candidate.bundle_digest": record.candidateExecution.receipt.bundleDigest,
1278
- "tangle.candidate.experiment_digest": record.candidateExecution.materializationReceipt.executionPlan.material.runCell.experimentDigest,
1279
- "tangle.candidate.execution_id": record.candidateExecution.materializationReceipt.executionPlan.material.executionId,
1280
- "tangle.candidate.execution_plan_digest": record.candidateExecution.receipt.executionPlanDigest,
1281
- "tangle.candidate.materialization_receipt_digest": record.candidateExecution.receipt.materializationReceiptDigest,
1282
- "tangle.candidate.succeeded": record.candidateExecution.receipt.termination.kind === "exit" && record.candidateExecution.receipt.termination.exitCode === 0 && record.candidateExecution.receipt.benchmarkResult.material.passed,
1283
- "tangle.candidate.run_receipt_digest": record.candidateExecution.receipt.digest
1284
- } : {}
1285
- };
1286
- if (record.profile) {
1287
- addPayloadAttributes(
1288
- labels,
1289
- "tangle.agent.profile",
1290
- redactor(record.profile),
1291
- includeFullPayload
1292
- );
1293
- if (record.profile.name) labels["gen_ai.agent.name"] = record.profile.name;
1294
- }
1295
- const redactedInput = record.input !== void 0 ? redactor(record.input) : void 0;
1296
- const redactedOutput = record.output !== void 0 ? redactor(record.output) : void 0;
1297
- if (redactedInput !== void 0) {
1298
- addPayloadAttributes(labels, "tangle.input", redactedInput, includeFullPayload);
1299
- }
1300
- if (redactedOutput !== void 0) {
1301
- addPayloadAttributes(labels, "tangle.output", redactedOutput, includeFullPayload);
1302
- }
1303
- const now = Date.now();
1304
- const runSpan = flatOtelSpan(
1305
- "tangle.intelligence.run",
1306
- { "tangle.runId": record.runId, ...labels },
1307
- record.traceId,
1308
- record.timing?.startedAt ?? now,
1309
- void 0,
1310
- record.timing?.completedAt ?? now
1311
- );
1312
- ex.exportSpan(runSpan);
1313
- if (record.runtimeEvents && record.runtimeEvents.length > 0) {
1314
- const spans = buildRuntimeEventOtelSpans(
1315
- record.runtimeEvents,
1316
- record.traceId,
1317
- runSpan.spanId,
1318
- { ...config.runtimeTelemetry, redact: redactor }
1319
- );
1320
- for (const span of spans) ex.exportSpan(span);
1321
- }
1322
- if (record.loopEvents && record.loopEvents.length > 0) {
1323
- const spans = buildLoopOtelSpans(
1324
- record.loopEvents,
1325
- record.traceId,
1326
- runSpan.spanId
1327
- );
1328
- for (const span of spans) ex.exportSpan(span);
1329
- }
1330
- } catch {
1331
- }
1332
- return record.traceId;
1333
- }
1334
- return {
1335
- project: config.project,
1336
- effort,
1337
- exportRunRecord,
1338
- freshRunId,
1339
- freshTraceId,
1340
- async traceRun(meta, fn) {
1341
- const runId = meta.runId ?? freshRunId();
1342
- const traceId = meta.traceId ?? freshTraceId();
1343
- let recordedOutput;
1344
- const usage = { inferenceUsd: 0, intelligenceUsd: 0 };
1345
- let success;
1346
- let score;
1347
- const trace = {
1348
- recordOutput(output) {
1349
- recordedOutput = output;
1350
- },
1351
- recordOutcome(outcome2) {
1352
- if (typeof outcome2.success === "boolean") success = outcome2.success;
1353
- if (typeof outcome2.score === "number") score = outcome2.score;
1354
- if (outcome2.usage) {
1355
- if (typeof outcome2.usage.inferenceUsd === "number") {
1356
- usage.inferenceUsd = outcome2.usage.inferenceUsd;
1357
- }
1358
- if (typeof outcome2.usage.intelligenceUsd === "number") {
1359
- usage.intelligenceUsd = outcome2.usage.intelligenceUsd;
1360
- }
1361
- } else if (typeof outcome2.costUsd === "number") {
1362
- usage.inferenceUsd = outcome2.costUsd;
1363
- }
1364
- }
1365
- };
1366
- const result = await fn(trace);
1367
- if (intelligenceOff) usage.intelligenceUsd = 0;
1368
- const outcome = {
1369
- runId,
1370
- traceId,
1371
- project: config.project,
1372
- effort,
1373
- intelligenceOff,
1374
- ...success !== void 0 ? { success } : {},
1375
- ...score !== void 0 ? { score } : {},
1376
- usage
1377
- };
1378
- exportTrace(meta, outcome, recordedOutput);
1379
- return result;
1380
- },
1381
- recordTrace(events, meta) {
1382
- const traceId = meta?.traceId ?? freshTraceId();
1383
- const ex = getExporter();
1384
- if (!ex || events.length === 0) return traceId;
1385
- try {
1386
- const spans = buildLoopOtelSpans(
1387
- events,
1388
- traceId,
1389
- meta?.rootParentSpanId
1390
- );
1391
- for (const span of spans) ex.exportSpan(span);
1392
- } catch {
1393
- }
1394
- return traceId;
1395
- },
1396
- doctor() {
1397
- const hasRepo = Boolean(config.repo?.owner && config.repo?.name && config.repo?.baseBranch);
1398
- const hasChecks = Boolean(config.checks && config.checks.length > 0);
1399
- const hasSurfaces = Boolean(config.surfaces && config.surfaces.length > 0);
1400
- const prMissing = [];
1401
- if (!hasChecks) prMissing.push("checks");
1402
- if (!hasSurfaces) prMissing.push("surfaces");
1403
- if (!hasRepo) prMissing.push("repo");
1404
- const recommendMissing = [];
1405
- if (intelligenceOff) recommendMissing.push("effort above off");
1406
- return {
1407
- project: config.project,
1408
- effort,
1409
- // Send ships only with a tenant key — the honest "will export actually
1410
- // land" signal (the base URL always resolves to the plane default).
1411
- exportConfigured: Boolean(apiKey),
1412
- modes: {
1413
- observe: { ready: true, missing: [] },
1414
- recommend: {
1415
- ready: recommendMissing.length === 0,
1416
- missing: recommendMissing
1417
- },
1418
- pr: { ready: prMissing.length === 0, missing: prMissing }
1419
- }
1420
- };
1421
- },
1422
- async flush() {
1423
- const ex = getExporter();
1424
- if (!ex) return;
1425
- try {
1426
- await ex.flush();
1427
- } catch {
1428
- }
1429
- }
1430
- };
1431
- }
1432
- export {
1433
- AGENT_IMPROVEMENT_PROFILE_SURFACES,
1434
- AgentCandidateExperimentCellExecutionError,
1435
- CapabilityNotAdmittedError,
1436
- agentImprovementProfileSurfaceDigest,
1437
- agentImprovementProfileSurfaceInput,
1438
- agentImprovementTargetProfileDiffs,
1439
- buildAgentImprovementActivationTargets,
1440
- compileEffort,
1441
- composeCertifiedProfile,
1442
- composeCertifiedProfileFromWire,
1443
- composeCertifiedPrompt,
1444
- createAgentImprovementActivation,
1445
- createAgentImprovementActivationResult,
1446
- createAgentImprovementMeasuredComparison,
1447
- createAgentImprovementProposal,
1448
- createCertifiedPromptSource,
1449
- createExactProcessCandidateExperimentExecutor,
1450
- createIntelligenceClient,
1451
- createOptimizationActivationReceipt,
1452
- createProtectedExactProcessCandidateExperimentExecutor,
1453
- defaultEffortTier,
1454
- defaultRedactor,
1455
- exactProcessCandidateExperimentExecutionSupport,
1456
- executeAgentCandidateExperimentCell,
1457
- executeAgentImprovementActivation,
1458
- isAgentImprovementProfileSurface,
1459
- isIntelligenceOff,
1460
- manifestFromProfile,
1461
- normalizeCertifiedProfile,
1462
- optimizationActivationReceiptFromMetadata,
1463
- parseAgentCandidateProfileActivation as parseCandidateProfileMaterialization,
1464
- prepareAgentImprovementProfileActivation,
1465
- proposeAgentImprovement,
1466
- pullCertified,
1467
- resolveEffort,
1468
- resolveIntelligenceBaseUrl,
1469
- resolveRedactor,
1470
- reviewAgentImprovementProposal,
1471
- runAgentCandidateExperiment,
1472
- submitAgentImprovementProposal,
1473
- verifyAgentImprovementActivation,
1474
- verifyAgentImprovementActivationResult,
1475
- verifyAgentImprovementProposal,
1476
- verifyAgentImprovementReview,
1477
- verifyCandidateExecutionEvidence,
1478
- withIntelligence
1479
- };
1362
+ if (!config.project) throw new Error("createIntelligenceClient: `project` is required");
1363
+ const effort = resolveEffortConfig(config.effort);
1364
+ const intelligenceOff = isIntelligenceOff(effort);
1365
+ const redactor = resolveRedactor(config.redact);
1366
+ const includeFullPayload = config.payloadAttributes === "full";
1367
+ const apiKey = config.apiKey ?? (typeof process !== "undefined" ? process.env.TANGLE_API_KEY : void 0);
1368
+ const otlpEndpoint = `${resolveIntelligenceBaseUrl(config.baseUrl)}/v1/otlp`;
1369
+ let exporter;
1370
+ let exporterResolved = false;
1371
+ function getExporter() {
1372
+ if (exporterResolved) return exporter;
1373
+ exporterResolved = true;
1374
+ if (!apiKey) return void 0;
1375
+ exporter = createOtelExporter({
1376
+ endpoint: otlpEndpoint,
1377
+ headers: { authorization: `Bearer ${apiKey}` },
1378
+ serviceName: config.project,
1379
+ resourceAttributes: { "tangle.project": config.project }
1380
+ });
1381
+ return exporter;
1382
+ }
1383
+ function exportTrace(meta, outcome, output) {
1384
+ const ex = getExporter();
1385
+ if (!ex) return;
1386
+ try {
1387
+ const labels = {
1388
+ project: config.project,
1389
+ "tangle.effort.intelligence_off": outcome.intelligenceOff,
1390
+ "tangle.usage.inference_usd": outcome.usage.inferenceUsd,
1391
+ "tangle.usage.intelligence_usd": outcome.usage.intelligenceUsd,
1392
+ ...meta.model ? { "gen_ai.request.model": meta.model } : {},
1393
+ ...meta.provider ? { "provider.name": meta.provider } : {},
1394
+ ...typeof outcome.success === "boolean" ? { "tangle.outcome.success": outcome.success } : {},
1395
+ ...typeof outcome.score === "number" ? { "tangle.outcome.score": outcome.score } : {},
1396
+ ...meta.labels ?? {}
1397
+ };
1398
+ const redactedInput = meta.input !== void 0 ? redactor(meta.input) : void 0;
1399
+ const redactedOutput = output !== void 0 ? redactor(output) : void 0;
1400
+ if (redactedInput !== void 0) addPayloadAttributes(labels, "tangle.input", redactedInput, includeFullPayload);
1401
+ if (redactedOutput !== void 0) addPayloadAttributes(labels, "tangle.output", redactedOutput, includeFullPayload);
1402
+ ex.exportSpan(flatOtelSpan("tangle.intelligence.run", {
1403
+ "tangle.runId": outcome.runId,
1404
+ ...labels
1405
+ }, outcome.traceId, Date.now()));
1406
+ } catch {}
1407
+ }
1408
+ function exportRunRecord(record) {
1409
+ const ex = getExporter();
1410
+ if (!ex) return record.traceId;
1411
+ try {
1412
+ const intelligenceUsd = intelligenceOff ? 0 : record.outcome.usage.intelligenceUsd;
1413
+ const repository = record.repository ?? (config.repo ? `${config.repo.owner}/${config.repo.name}` : void 0);
1414
+ const labels = {
1415
+ project: record.project,
1416
+ "tangle.target": record.target,
1417
+ "tangle.effort.intelligence_off": intelligenceOff,
1418
+ "tangle.usage.inference_usd": record.outcome.usage.inferenceUsd,
1419
+ "tangle.usage.intelligence_usd": intelligenceUsd,
1420
+ ...record.model ? { "gen_ai.request.model": record.model } : {},
1421
+ ...record.provider ? { "provider.name": record.provider } : {},
1422
+ ...record.sessionId ? {
1423
+ "tangle.sessionId": record.sessionId,
1424
+ "gen_ai.conversation.id": record.sessionId
1425
+ } : {},
1426
+ ...record.harness ? { "tangle.agent.harness": record.harness } : {},
1427
+ ...repository ? { "vcs.repository.name": repository } : {},
1428
+ ...record.commitSha ? { "vcs.ref.head.revision": record.commitSha } : {},
1429
+ ...record.timing ? {
1430
+ "tangle.started_at_ms": record.timing.startedAt,
1431
+ "tangle.completed_at_ms": record.timing.completedAt,
1432
+ "tangle.duration_ms": record.timing.durationMs
1433
+ } : {},
1434
+ ...record.tokens ? {
1435
+ "gen_ai.usage.input_tokens": record.tokens.input,
1436
+ "gen_ai.usage.output_tokens": record.tokens.output,
1437
+ ...record.tokens.cachedInput !== void 0 ? { "gen_ai.usage.cache_read_input_tokens": record.tokens.cachedInput } : {},
1438
+ ...record.tokens.reasoning !== void 0 ? { "gen_ai.usage.reasoning_tokens": record.tokens.reasoning } : {}
1439
+ } : {},
1440
+ ...typeof record.outcome.success === "boolean" ? { "tangle.outcome.success": record.outcome.success } : {},
1441
+ ...typeof record.outcome.score === "number" ? { "tangle.outcome.score": record.outcome.score } : {},
1442
+ ...record.error ? {
1443
+ "error.type": record.error.code ?? record.error.name,
1444
+ "error.message": serializeJson(redactor(record.error.message))
1445
+ } : {},
1446
+ ...record.runtimeEvents ? { "tangle.runtime.event_count": record.runtimeEvents.length } : {},
1447
+ ...record.candidateExecution ? {
1448
+ "tangle.candidate.bundle_digest": record.candidateExecution.receipt.bundleDigest,
1449
+ "tangle.candidate.experiment_digest": record.candidateExecution.materializationReceipt.executionPlan.material.runCell.experimentDigest,
1450
+ "tangle.candidate.execution_id": record.candidateExecution.materializationReceipt.executionPlan.material.executionId,
1451
+ "tangle.candidate.execution_plan_digest": record.candidateExecution.receipt.executionPlanDigest,
1452
+ "tangle.candidate.materialization_receipt_digest": record.candidateExecution.receipt.materializationReceiptDigest,
1453
+ "tangle.candidate.succeeded": record.candidateExecution.receipt.termination.kind === "exit" && record.candidateExecution.receipt.termination.exitCode === 0 && record.candidateExecution.receipt.benchmarkResult.material.passed,
1454
+ "tangle.candidate.run_receipt_digest": record.candidateExecution.receipt.digest
1455
+ } : {}
1456
+ };
1457
+ if (record.profile) {
1458
+ addPayloadAttributes(labels, "tangle.agent.profile", redactor(record.profile), includeFullPayload);
1459
+ if (record.profile.name) labels["gen_ai.agent.name"] = record.profile.name;
1460
+ }
1461
+ const redactedInput = record.input !== void 0 ? redactor(record.input) : void 0;
1462
+ const redactedOutput = record.output !== void 0 ? redactor(record.output) : void 0;
1463
+ if (redactedInput !== void 0) addPayloadAttributes(labels, "tangle.input", redactedInput, includeFullPayload);
1464
+ if (redactedOutput !== void 0) addPayloadAttributes(labels, "tangle.output", redactedOutput, includeFullPayload);
1465
+ const now = Date.now();
1466
+ const runSpan = flatOtelSpan("tangle.intelligence.run", {
1467
+ "tangle.runId": record.runId,
1468
+ ...labels
1469
+ }, record.traceId, record.timing?.startedAt ?? now, void 0, record.timing?.completedAt ?? now);
1470
+ ex.exportSpan(runSpan);
1471
+ if (record.runtimeEvents && record.runtimeEvents.length > 0) {
1472
+ const spans = buildRuntimeEventOtelSpans(record.runtimeEvents, record.traceId, runSpan.spanId, {
1473
+ ...config.runtimeTelemetry,
1474
+ redact: redactor
1475
+ });
1476
+ for (const span of spans) ex.exportSpan(span);
1477
+ }
1478
+ if (record.loopEvents && record.loopEvents.length > 0) {
1479
+ const spans = buildLoopOtelSpans(record.loopEvents, record.traceId, runSpan.spanId);
1480
+ for (const span of spans) ex.exportSpan(span);
1481
+ }
1482
+ } catch {}
1483
+ return record.traceId;
1484
+ }
1485
+ return {
1486
+ project: config.project,
1487
+ effort,
1488
+ exportRunRecord,
1489
+ freshRunId,
1490
+ freshTraceId,
1491
+ async traceRun(meta, fn) {
1492
+ const runId = meta.runId ?? freshRunId();
1493
+ const traceId = meta.traceId ?? freshTraceId();
1494
+ let recordedOutput;
1495
+ const usage = {
1496
+ inferenceUsd: 0,
1497
+ intelligenceUsd: 0
1498
+ };
1499
+ let success;
1500
+ let score;
1501
+ const result = await fn({
1502
+ recordOutput(output) {
1503
+ recordedOutput = output;
1504
+ },
1505
+ recordOutcome(outcome) {
1506
+ if (typeof outcome.success === "boolean") success = outcome.success;
1507
+ if (typeof outcome.score === "number") score = outcome.score;
1508
+ if (outcome.usage) {
1509
+ if (typeof outcome.usage.inferenceUsd === "number") usage.inferenceUsd = outcome.usage.inferenceUsd;
1510
+ if (typeof outcome.usage.intelligenceUsd === "number") usage.intelligenceUsd = outcome.usage.intelligenceUsd;
1511
+ } else if (typeof outcome.costUsd === "number") usage.inferenceUsd = outcome.costUsd;
1512
+ }
1513
+ });
1514
+ if (intelligenceOff) usage.intelligenceUsd = 0;
1515
+ exportTrace(meta, {
1516
+ runId,
1517
+ traceId,
1518
+ project: config.project,
1519
+ effort,
1520
+ intelligenceOff,
1521
+ ...success !== void 0 ? { success } : {},
1522
+ ...score !== void 0 ? { score } : {},
1523
+ usage
1524
+ }, recordedOutput);
1525
+ return result;
1526
+ },
1527
+ recordTrace(events, meta) {
1528
+ const traceId = meta?.traceId ?? freshTraceId();
1529
+ const ex = getExporter();
1530
+ if (!ex || events.length === 0) return traceId;
1531
+ try {
1532
+ const spans = buildLoopOtelSpans(events, traceId, meta?.rootParentSpanId);
1533
+ for (const span of spans) ex.exportSpan(span);
1534
+ } catch {}
1535
+ return traceId;
1536
+ },
1537
+ doctor() {
1538
+ const hasRepo = Boolean(config.repo?.owner && config.repo?.name && config.repo?.baseBranch);
1539
+ const hasChecks = Boolean(config.checks && config.checks.length > 0);
1540
+ const hasSurfaces = Boolean(config.surfaces && config.surfaces.length > 0);
1541
+ const prMissing = [];
1542
+ if (!hasChecks) prMissing.push("checks");
1543
+ if (!hasSurfaces) prMissing.push("surfaces");
1544
+ if (!hasRepo) prMissing.push("repo");
1545
+ const recommendMissing = [];
1546
+ if (intelligenceOff) recommendMissing.push("effort above off");
1547
+ return {
1548
+ project: config.project,
1549
+ effort,
1550
+ exportConfigured: Boolean(apiKey),
1551
+ modes: {
1552
+ observe: {
1553
+ ready: true,
1554
+ missing: []
1555
+ },
1556
+ recommend: {
1557
+ ready: recommendMissing.length === 0,
1558
+ missing: recommendMissing
1559
+ },
1560
+ pr: {
1561
+ ready: prMissing.length === 0,
1562
+ missing: prMissing
1563
+ }
1564
+ }
1565
+ };
1566
+ },
1567
+ async flush() {
1568
+ const ex = getExporter();
1569
+ if (!ex) return;
1570
+ try {
1571
+ await ex.flush();
1572
+ } catch {}
1573
+ }
1574
+ };
1575
+ }
1576
+ //#endregion
1577
+ export { AGENT_IMPROVEMENT_PROFILE_SURFACES, AgentCandidateExperimentCellExecutionError, CapabilityNotAdmittedError, agentImprovementProfileSurfaceDigest, agentImprovementProfileSurfaceInput, agentImprovementTargetProfileDiffs, buildAgentImprovementActivationTargets, compileEffort, composeCertifiedProfile, composeCertifiedProfileFromWire, composeCertifiedPrompt, createAgentImprovementActivation, createAgentImprovementActivationResult, createAgentImprovementMeasuredComparison, createAgentImprovementProposal, createCertifiedPromptSource, createExactProcessCandidateExperimentExecutor, createIntelligenceClient, createOptimizationActivationReceipt, createProtectedExactProcessCandidateExperimentExecutor, defaultEffortTier, defaultRedactor, exactProcessCandidateExperimentExecutionSupport, executeAgentCandidateExperimentCell, executeAgentImprovementActivation, isAgentImprovementProfileSurface, isIntelligenceOff, manifestFromProfile, normalizeCertifiedProfile, optimizationActivationReceiptFromMetadata, parseAgentCandidateProfileActivation as parseCandidateProfileMaterialization, prepareAgentImprovementProfileActivation, proposeAgentImprovement, pullCertified, resolveEffort, resolveIntelligenceBaseUrl, resolveRedactor, reviewAgentImprovementProposal, runAgentCandidateExperiment, submitAgentImprovementProposal, verifyAgentImprovementActivation, verifyAgentImprovementActivationResult, verifyAgentImprovementProposal, verifyAgentImprovementReview, verifyCandidateExecutionEvidence, withIntelligence };
1578
+
1480
1579
  //# sourceMappingURL=intelligence.js.map