@tangle-network/agent-runtime 0.104.0 → 0.106.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +176 -42
- package/dist/activation-CRjVfOiy.js +203 -0
- package/dist/activation-CRjVfOiy.js.map +1 -0
- package/dist/activation-DyWB0K6E.d.ts +98 -0
- package/dist/agent.d.ts +216 -234
- package/dist/agent.js +615 -547
- package/dist/agent.js.map +1 -1
- package/dist/analyst-loop-DGdtVENg.js +517 -0
- package/dist/analyst-loop-DGdtVENg.js.map +1 -0
- package/dist/analyst-loop.d.ts +10 -43
- package/dist/analyst-loop.js +2 -11
- package/dist/backends-Dy8NujB4.js +713 -0
- package/dist/backends-Dy8NujB4.js.map +1 -0
- package/dist/candidate-execution/index.d.ts +4 -192
- package/dist/candidate-execution/index.js +5 -66
- package/dist/candidate-execution-DqMbv1rU.js +488 -0
- package/dist/candidate-execution-DqMbv1rU.js.map +1 -0
- package/dist/coder-yhVWbdWc.js +40 -0
- package/dist/coder-yhVWbdWc.js.map +1 -0
- package/dist/conversation-XucG_K3l.js +1265 -0
- package/dist/conversation-XucG_K3l.js.map +1 -0
- package/dist/conversation.d.ts +2 -804
- package/dist/conversation.js +2 -55
- package/dist/environment-provider-CfLUmKmf.js +1168 -0
- package/dist/environment-provider-CfLUmKmf.js.map +1 -0
- package/dist/environment-provider-IUGU3epE.d.ts +964 -0
- package/dist/environment-provider.d.ts +2 -78
- package/dist/environment-provider.js +2 -18
- package/dist/errors-DEAvWQPy.js +111 -0
- package/dist/errors-DEAvWQPy.js.map +1 -0
- package/dist/improvement-adapter-Cr5TBSji.d.ts +166 -0
- package/dist/improvement-cycle-C095kS_g.js +2624 -0
- package/dist/improvement-cycle-C095kS_g.js.map +1 -0
- package/dist/index-BGdxAwfO.d.ts +838 -0
- package/dist/index-C-FYUuFG.d.ts +193 -0
- package/dist/index-CbNM40xG.d.ts +140 -0
- package/dist/index-DruSKs3Z.d.ts +7224 -0
- package/dist/index-Efjb3nrQ.d.ts +671 -0
- package/dist/index.d.ts +14 -1134
- package/dist/index.js +2134 -1972
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +776 -888
- package/dist/intelligence.js +1466 -1410
- package/dist/intelligence.js.map +1 -1
- package/dist/{kb-gate-CwHO0vz6.d.ts → kb-gate-C8z2juK8.d.ts} +33 -31
- package/dist/kb-gate-DpaSwXVx.js +80 -0
- package/dist/kb-gate-DpaSwXVx.js.map +1 -0
- package/dist/knowledge-Ku-mPP4f.js +433 -0
- package/dist/knowledge-Ku-mPP4f.js.map +1 -0
- package/dist/knowledge.d.ts +2 -150
- package/dist/knowledge.js +2 -40
- package/dist/local-harness-Dh8PJ0ot.d.ts +455 -0
- package/dist/loop-runner-bin-BXsFEUcf.d.ts +162 -0
- package/dist/loop-runner-bin-BwjQ1NfH.js +268 -0
- package/dist/loop-runner-bin-BwjQ1NfH.js.map +1 -0
- package/dist/loop-runner-bin.d.ts +2 -17
- package/dist/loop-runner-bin.js +2 -24
- package/dist/loops.d.ts +5 -4164
- package/dist/loops.js +8 -419
- package/dist/mcp/bin.d.ts +1 -1
- package/dist/mcp/bin.js +116 -146
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +295 -437
- package/dist/mcp/index.js +1242 -1177
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/memory-bin.d.ts +1 -1
- package/dist/mcp/memory-bin.js +37 -16
- package/dist/mcp/memory-bin.js.map +1 -1
- package/dist/memory-server-DL6cE2Ag.js +234 -0
- package/dist/memory-server-DL6cE2Ag.js.map +1 -0
- package/dist/model-resolution-Btd9iIKV.js +98 -0
- package/dist/model-resolution-Btd9iIKV.js.map +1 -0
- package/dist/openai-tools-B68JaOCx.d.ts +24 -0
- package/dist/openai-tools-CKLy1C7M.js +44 -0
- package/dist/openai-tools-CKLy1C7M.js.map +1 -0
- package/dist/otel-export-D34IQW1C.js +843 -0
- package/dist/otel-export-D34IQW1C.js.map +1 -0
- package/dist/platform.d.ts +188 -185
- package/dist/platform.js +185 -218
- package/dist/platform.js.map +1 -1
- package/dist/prepare-B53sPV7M.js +4292 -0
- package/dist/prepare-B53sPV7M.js.map +1 -0
- package/dist/primeintellect/index.d.ts +150 -147
- package/dist/primeintellect/index.js +626 -1004
- package/dist/primeintellect/index.js.map +1 -1
- package/dist/profiles.d.ts +296 -490
- package/dist/profiles.js +722 -749
- package/dist/profiles.js.map +1 -1
- package/dist/protected-model-port-BLPH5VVv.js +722 -0
- package/dist/protected-model-port-BLPH5VVv.js.map +1 -0
- package/dist/protected-model-port-BP6Z4eau.d.ts +283 -0
- package/dist/protected-redaction--F3v1oo8.js +200 -0
- package/dist/protected-redaction--F3v1oo8.js.map +1 -0
- package/dist/redact-D-u-rrcn.js +82 -0
- package/dist/redact-D-u-rrcn.js.map +1 -0
- package/dist/redact-kbIOjfjM.d.ts +452 -0
- package/dist/researcher-CoVqNhfI.js +433 -0
- package/dist/researcher-CoVqNhfI.js.map +1 -0
- package/dist/runtime-BG0BziaP.js +5408 -0
- package/dist/runtime-BG0BziaP.js.map +1 -0
- package/dist/sandbox-events-DeI5xX8P.js +316 -0
- package/dist/sandbox-events-DeI5xX8P.js.map +1 -0
- package/dist/spawn-journal-CwPvKUTa.js +456 -0
- package/dist/spawn-journal-CwPvKUTa.js.map +1 -0
- package/dist/structural-rollout-IXUEplky.js +1445 -0
- package/dist/structural-rollout-IXUEplky.js.map +1 -0
- package/dist/substrate-B0TYNrXn.js +27 -0
- package/dist/substrate-B0TYNrXn.js.map +1 -0
- package/dist/{substrate-Dyiqmd3o.d.ts → substrate-BcnuSHXm.d.ts} +57 -54
- package/dist/supervise-BiRutHS9.js +7321 -0
- package/dist/supervise-BiRutHS9.js.map +1 -0
- package/dist/supervisor-DTKhF-RV.js +3826 -0
- package/dist/supervisor-DTKhF-RV.js.map +1 -0
- package/dist/testing.d.ts +4 -3
- package/dist/testing.js +2478 -2637
- package/dist/testing.js.map +1 -1
- package/dist/tool-server-RcWgLIsL.js +141 -0
- package/dist/tool-server-RcWgLIsL.js.map +1 -0
- package/dist/trace-propagation-CJJC7SVB.js +57 -0
- package/dist/trace-propagation-CJJC7SVB.js.map +1 -0
- package/dist/types-BaIpb0XT.d.ts +492 -0
- package/dist/types-BevOjfTY.d.ts +765 -0
- package/dist/types-C9j4qg6l.d.ts +500 -0
- package/dist/types-Cja5OTGh.d.ts +190 -0
- package/dist/util-MVgdwuIS.js +145 -0
- package/dist/util-MVgdwuIS.js.map +1 -0
- package/dist/workspace-archive-BosQiotA.js +575 -0
- package/dist/workspace-archive-BosQiotA.js.map +1 -0
- package/package.json +43 -55
- package/skills/build-with-agent-runtime/SKILL.md +16 -9
- package/skills/loop-writer/SKILL.md +1 -1
- package/dist/activation-Cm-9MMX1.d.ts +0 -69
- package/dist/analyst-loop.js.map +0 -1
- package/dist/backends-BO4Jqoe2.d.ts +0 -134
- package/dist/candidate-execution/index.js.map +0 -1
- package/dist/chunk-2KGAN2HM.js +0 -1256
- package/dist/chunk-2KGAN2HM.js.map +0 -1
- package/dist/chunk-2QJSNOGK.js +0 -48
- package/dist/chunk-2QJSNOGK.js.map +0 -1
- package/dist/chunk-2UABGGUB.js +0 -474
- package/dist/chunk-2UABGGUB.js.map +0 -1
- package/dist/chunk-2VZYRB55.js +0 -834
- package/dist/chunk-2VZYRB55.js.map +0 -1
- package/dist/chunk-2X65HYMI.js +0 -3526
- package/dist/chunk-2X65HYMI.js.map +0 -1
- package/dist/chunk-3MDZX7YU.js +0 -125
- package/dist/chunk-3MDZX7YU.js.map +0 -1
- package/dist/chunk-3PPVCS75.js +0 -199
- package/dist/chunk-3PPVCS75.js.map +0 -1
- package/dist/chunk-5HNDYWUT.js +0 -6424
- package/dist/chunk-5HNDYWUT.js.map +0 -1
- package/dist/chunk-5IBQAPVB.js +0 -29
- package/dist/chunk-5IBQAPVB.js.map +0 -1
- package/dist/chunk-5QOB7H74.js +0 -387
- package/dist/chunk-5QOB7H74.js.map +0 -1
- package/dist/chunk-ATDFUJYI.js +0 -4728
- package/dist/chunk-ATDFUJYI.js.map +0 -1
- package/dist/chunk-B7K7V22Y.js +0 -699
- package/dist/chunk-B7K7V22Y.js.map +0 -1
- package/dist/chunk-DPEUKJRO.js +0 -27
- package/dist/chunk-DPEUKJRO.js.map +0 -1
- package/dist/chunk-FD2MBMOH.js +0 -494
- package/dist/chunk-FD2MBMOH.js.map +0 -1
- package/dist/chunk-FJI3EXU3.js +0 -2402
- package/dist/chunk-FJI3EXU3.js.map +0 -1
- package/dist/chunk-HAO4CXHP.js +0 -200
- package/dist/chunk-HAO4CXHP.js.map +0 -1
- package/dist/chunk-ISPWRSEC.js +0 -408
- package/dist/chunk-ISPWRSEC.js.map +0 -1
- package/dist/chunk-KRBFHMV6.js +0 -1228
- package/dist/chunk-KRBFHMV6.js.map +0 -1
- package/dist/chunk-L5DST3QC.js +0 -351
- package/dist/chunk-L5DST3QC.js.map +0 -1
- package/dist/chunk-M22PL4GH.js +0 -171
- package/dist/chunk-M22PL4GH.js.map +0 -1
- package/dist/chunk-NURIQBJQ.js +0 -72
- package/dist/chunk-NURIQBJQ.js.map +0 -1
- package/dist/chunk-PZZKQVQV.js +0 -52
- package/dist/chunk-PZZKQVQV.js.map +0 -1
- package/dist/chunk-Q2JSAVQ3.js +0 -671
- package/dist/chunk-Q2JSAVQ3.js.map +0 -1
- package/dist/chunk-SBTWKPVR.js +0 -5576
- package/dist/chunk-SBTWKPVR.js.map +0 -1
- package/dist/chunk-SGKPNBXE.js +0 -60
- package/dist/chunk-SGKPNBXE.js.map +0 -1
- package/dist/chunk-SNSMRT6H.js +0 -680
- package/dist/chunk-SNSMRT6H.js.map +0 -1
- package/dist/chunk-STJEHM5F.js +0 -1338
- package/dist/chunk-STJEHM5F.js.map +0 -1
- package/dist/chunk-UPWGXKXB.js +0 -254
- package/dist/chunk-UPWGXKXB.js.map +0 -1
- package/dist/chunk-YEJR7IXO.js +0 -68
- package/dist/chunk-YEJR7IXO.js.map +0 -1
- package/dist/chunk-ZXICDSAK.js +0 -907
- package/dist/chunk-ZXICDSAK.js.map +0 -1
- package/dist/completion-gate-Bv47cOnn.d.ts +0 -256
- package/dist/conversation.js.map +0 -1
- package/dist/coordination-CxtzMxSM.d.ts +0 -2570
- package/dist/environment-provider.js.map +0 -1
- package/dist/improve--2A0gK1-.d.ts +0 -440
- package/dist/improvement-adapter-HAZz-7vK.d.ts +0 -203
- package/dist/knowledge.js.map +0 -1
- package/dist/local-harness-CtK9dSny.d.ts +0 -175
- package/dist/loop-runner-bin-DUOGtvOl.d.ts +0 -207
- package/dist/loop-runner-bin.js.map +0 -1
- package/dist/loops.js.map +0 -1
- package/dist/openai-tools-fnj6SRVg.d.ts +0 -46
- package/dist/protected-model-port-DzkUY3HQ.d.ts +0 -271
- package/dist/sanitize-DEbPNtyI.d.ts +0 -328
- package/dist/structural-rollout-C4mabf87.d.ts +0 -446
- package/dist/supervise-7q9F5brx.d.ts +0 -379
- package/dist/types-BCoemcXU.d.ts +0 -802
- package/dist/types-BwoZWq-i.d.ts +0 -510
- package/dist/types-Cbp72qyu.d.ts +0 -491
- package/dist/types-CmYCMbFT.d.ts +0 -203
- package/dist/types-CvNwMzQt.d.ts +0 -957
- package/dist/worktree-fanout-WsOzt8qu.d.ts +0 -999
package/dist/intelligence.js
CHANGED
|
@@ -1,1523 +1,1579 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "./
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
verifyAgentImprovementActivationResult
|
|
9
|
-
} from "./chunk-HAO4CXHP.js";
|
|
10
|
-
import {
|
|
11
|
-
AGENT_IMPROVEMENT_PROFILE_SURFACES,
|
|
12
|
-
AgentCandidateExperimentCellExecutionError,
|
|
13
|
-
agentImprovementProfileSurfaceDigest,
|
|
14
|
-
agentImprovementProfileSurfaceInput,
|
|
15
|
-
agentImprovementTargetProfileDiffs,
|
|
16
|
-
buildAgentImprovementActivationTargets,
|
|
17
|
-
createAgentImprovementActivation,
|
|
18
|
-
createAgentImprovementMeasuredComparison,
|
|
19
|
-
createAgentImprovementProposal,
|
|
20
|
-
executeAgentCandidateExperimentCell,
|
|
21
|
-
isAgentImprovementProfileSurface,
|
|
22
|
-
proposeAgentImprovement,
|
|
23
|
-
reviewAgentImprovementProposal,
|
|
24
|
-
runAgentCandidateExperiment,
|
|
25
|
-
verifyAgentImprovementActivation,
|
|
26
|
-
verifyAgentImprovementProposal,
|
|
27
|
-
verifyAgentImprovementReview,
|
|
28
|
-
verifyCandidateExecutionEvidence
|
|
29
|
-
} from "./chunk-FJI3EXU3.js";
|
|
30
|
-
import {
|
|
31
|
-
AGENT_CANDIDATE_EXECUTION_SUPPORT,
|
|
32
|
-
applyExactAgentProfileDiff,
|
|
33
|
-
immutableCandidateValue,
|
|
34
|
-
omitUndefinedObjectFields,
|
|
35
|
-
parseAgentCandidateProfileActivation,
|
|
36
|
-
parseExactAgentProfile
|
|
37
|
-
} from "./chunk-SBTWKPVR.js";
|
|
38
|
-
import "./chunk-STJEHM5F.js";
|
|
39
|
-
import "./chunk-UPWGXKXB.js";
|
|
40
|
-
import {
|
|
41
|
-
buildLoopOtelSpans,
|
|
42
|
-
buildRuntimeEventOtelSpans,
|
|
43
|
-
createOtelExporter,
|
|
44
|
-
flatOtelSpan
|
|
45
|
-
} from "./chunk-2VZYRB55.js";
|
|
46
|
-
import "./chunk-2X65HYMI.js";
|
|
47
|
-
import "./chunk-ISPWRSEC.js";
|
|
48
|
-
import {
|
|
49
|
-
resolveAgentEnvironmentProvider
|
|
50
|
-
} from "./chunk-KRBFHMV6.js";
|
|
51
|
-
import "./chunk-3MDZX7YU.js";
|
|
52
|
-
import "./chunk-FD2MBMOH.js";
|
|
53
|
-
import "./chunk-M22PL4GH.js";
|
|
54
|
-
import "./chunk-YEJR7IXO.js";
|
|
55
|
-
|
|
56
|
-
// 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";
|
|
57
8
|
import { contentHash } from "@tangle-network/agent-eval";
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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`. */
|
|
64
17
|
function resolveIntelligenceBaseUrl(baseUrl) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
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;
|
|
70
21
|
}
|
|
71
22
|
function resolveApiKey(apiKey) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return "";
|
|
23
|
+
if (apiKey) return apiKey;
|
|
24
|
+
if (typeof process !== "undefined" && process.env.TANGLE_API_KEY) return process.env.TANGLE_API_KEY;
|
|
25
|
+
return "";
|
|
76
26
|
}
|
|
27
|
+
/** Make one authenticated request and retain whether the network call began. */
|
|
77
28
|
async function requestPlane(input) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
+
}
|
|
108
61
|
}
|
|
109
62
|
function asRecord(value) {
|
|
110
|
-
|
|
63
|
+
return value && typeof value === "object" ? value : {};
|
|
111
64
|
}
|
|
112
65
|
function capPlaneErrorText(value) {
|
|
113
|
-
|
|
66
|
+
return value.slice(0, maxPlaneErrorTextLength);
|
|
114
67
|
}
|
|
115
68
|
function toDiffProvenance(value) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
+
};
|
|
123
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
|
+
*/
|
|
124
83
|
function normalizeCertifiedProfile(raw) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
+
};
|
|
142
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
|
+
*/
|
|
143
111
|
async function pullCertified(opts) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
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
|
+
}
|
|
178
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
|
+
*/
|
|
179
153
|
async function submitAgentImprovementProposal(opts) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
+
*/
|
|
247
235
|
function composeCertifiedPrompt(base, certified) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (parts.length === 0) return base;
|
|
258
|
-
return `${base.trim()}
|
|
259
|
-
|
|
260
|
-
## Certified guidance (Tangle Intelligence)
|
|
261
|
-
|
|
262
|
-
${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")}`;
|
|
263
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
|
+
*/
|
|
264
252
|
function createCertifiedPromptSource(opts) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
+
};
|
|
291
279
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
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
|
+
}
|
|
330
318
|
};
|
|
331
|
-
|
|
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
|
+
*/
|
|
332
334
|
function resolveEffort(tier, overrides) {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
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
|
+
};
|
|
340
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
|
+
*/
|
|
341
349
|
function isIntelligenceOff(settings) {
|
|
342
|
-
|
|
350
|
+
return settings.analysts === false && settings.corpus === "off" && settings.fanout <= 1 && settings.loops === false && settings.intelligenceBudgetUsd === 0;
|
|
343
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
|
+
*/
|
|
344
363
|
function compileEffort(settings) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
364
|
+
return {
|
|
365
|
+
withAnalyst: settings.analysts,
|
|
366
|
+
fanout: settings.fanout,
|
|
367
|
+
withLoops: settings.loops,
|
|
368
|
+
intelligenceBudgetUsd: settings.intelligenceBudgetUsd
|
|
369
|
+
};
|
|
351
370
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
/\b(?:sk|pk|rk|ak)[-_][A-Za-z0-9_-]{12,}/g,
|
|
361
|
-
/\bgh[pousr]_[A-Za-z0-9]{20,}/g,
|
|
362
|
-
// AWS access key ids.
|
|
363
|
-
/\bAKIA[0-9A-Z]{16}\b/g,
|
|
364
|
-
// PEM private-key blocks.
|
|
365
|
-
/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,
|
|
366
|
-
// Email addresses.
|
|
367
|
-
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g
|
|
368
|
-
];
|
|
369
|
-
function scrubString(input) {
|
|
370
|
-
let out = input;
|
|
371
|
-
for (const pattern of valuePatterns) {
|
|
372
|
-
out = out.replace(pattern, redactedMarker);
|
|
373
|
-
}
|
|
374
|
-
return out;
|
|
375
|
-
}
|
|
376
|
-
function defaultRedactor(value) {
|
|
377
|
-
return walk(value, /* @__PURE__ */ new WeakSet(), 0);
|
|
378
|
-
}
|
|
379
|
-
var maxDepth = 32;
|
|
380
|
-
function walk(value, seen, depth) {
|
|
381
|
-
if (depth > maxDepth) return "[truncated]";
|
|
382
|
-
if (typeof value === "string") return scrubString(value);
|
|
383
|
-
if (value === null || typeof value !== "object") return value;
|
|
384
|
-
if (seen.has(value)) return "[circular]";
|
|
385
|
-
seen.add(value);
|
|
386
|
-
if (Array.isArray(value)) {
|
|
387
|
-
return value.map((item) => walk(item, seen, depth + 1));
|
|
388
|
-
}
|
|
389
|
-
const out = {};
|
|
390
|
-
for (const [key, v] of Object.entries(value)) {
|
|
391
|
-
if (secretKeyPattern.test(key)) {
|
|
392
|
-
out[key] = redactedMarker;
|
|
393
|
-
continue;
|
|
394
|
-
}
|
|
395
|
-
out[key] = walk(v, seen, depth + 1);
|
|
396
|
-
}
|
|
397
|
-
return out;
|
|
398
|
-
}
|
|
399
|
-
function resolveRedactor(redact) {
|
|
400
|
-
if (redact === false) return (value) => value;
|
|
401
|
-
return redact ?? defaultRedactor;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// 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
|
+
*/
|
|
405
379
|
var CapabilityNotAdmittedError = class extends Error {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
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
|
+
}
|
|
414
388
|
};
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
389
|
+
const provenanceFromArtifact = (a) => ({
|
|
390
|
+
contentHash: a.contentHash,
|
|
391
|
+
version: a.version,
|
|
392
|
+
lift: a.lift,
|
|
393
|
+
promotedAt: a.promotedAt,
|
|
394
|
+
sourcePath: a.path
|
|
421
395
|
});
|
|
422
|
-
|
|
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
|
+
*/
|
|
423
408
|
function inferCapability(type, a) {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
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
|
+
};
|
|
494
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
|
+
*/
|
|
495
504
|
function manifestFromProfile(profile) {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
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
|
+
};
|
|
520
536
|
}
|
|
521
537
|
function tryParseJson(s) {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
538
|
+
try {
|
|
539
|
+
return JSON.parse(s);
|
|
540
|
+
} catch {
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
527
543
|
}
|
|
528
544
|
function isStringRecord(v) {
|
|
529
|
-
|
|
545
|
+
return typeof v === "object" && v !== null && !Array.isArray(v) && Object.values(v).every((x) => typeof x === "string");
|
|
530
546
|
}
|
|
531
547
|
function isJsonSchema(v) {
|
|
532
|
-
|
|
548
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
533
549
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
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
|
+
})
|
|
548
569
|
});
|
|
570
|
+
/** Execute one signed experiment cell through any declared exact-process provider. */
|
|
549
571
|
function createExactProcessCandidateExperimentExecutor(options) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
});
|
|
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
|
+
});
|
|
581
602
|
}
|
|
603
|
+
/** Compose host-owned execution ports with protected model access for one exact-process run. */
|
|
582
604
|
function createProtectedExactProcessCandidateExperimentExecutor(options) {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
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
|
+
});
|
|
596
621
|
}
|
|
597
|
-
|
|
598
|
-
|
|
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
|
+
*/
|
|
599
629
|
function prepareAgentImprovementProfileActivation(input) {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
if (missing.length > 0) {
|
|
607
|
-
return immutableCandidateValue({ status: "missing", identities: missing });
|
|
608
|
-
}
|
|
609
|
-
const currentProfiles = new Map(
|
|
610
|
-
identities.map((identity) => {
|
|
611
|
-
const profile = input.currentByIdentity.get(identity);
|
|
612
|
-
if (!profile) throw new Error(`missing agent profile ${identity}`);
|
|
613
|
-
const label = `agent profile activation ${identity}`;
|
|
614
|
-
return [identity, parseExactAgentProfile(omitUndefinedObjectFields(profile, label), label)];
|
|
615
|
-
})
|
|
616
|
-
);
|
|
617
|
-
const current = input.targets.map((target) => {
|
|
618
|
-
const profile = currentProfiles.get(target.identity);
|
|
619
|
-
if (!profile) throw new Error(`missing agent profile ${target.identity}`);
|
|
620
|
-
return {
|
|
621
|
-
target,
|
|
622
|
-
currentDigest: agentImprovementProfileSurfaceDigest(profile, target.surface)
|
|
623
|
-
};
|
|
624
|
-
});
|
|
625
|
-
const states = current.map(({ target, currentDigest }) => ({
|
|
626
|
-
surface: target.surface,
|
|
627
|
-
identity: target.identity,
|
|
628
|
-
currentDigest
|
|
629
|
-
}));
|
|
630
|
-
if (current.every(({ target, currentDigest }) => currentDigest === target.desiredDigest)) {
|
|
631
|
-
return immutableCandidateValue({ status: "already-applied", targets: states });
|
|
632
|
-
}
|
|
633
|
-
if (current.some(({ target, currentDigest }) => currentDigest !== target.expectedBaseDigest)) {
|
|
634
|
-
return immutableCandidateValue({ status: "conflict", targets: states });
|
|
635
|
-
}
|
|
636
|
-
const profiles = /* @__PURE__ */ new Map();
|
|
637
|
-
for (const identity of identities) {
|
|
638
|
-
const currentProfile = currentProfiles.get(identity);
|
|
639
|
-
if (!currentProfile) throw new Error(`missing agent profile ${identity}`);
|
|
640
|
-
const profile = input.targets.filter((target) => target.identity === identity).flatMap(
|
|
641
|
-
(target) => agentImprovementTargetProfileDiffs(target, {
|
|
642
|
-
id: `${target.identity}:${target.desiredDigest}`,
|
|
643
|
-
metadata: { identity }
|
|
644
|
-
})
|
|
645
|
-
).reduce(
|
|
646
|
-
(value, diff) => applyExactAgentProfileDiff(value, diff, `agent profile activation ${identity}`),
|
|
647
|
-
currentProfile
|
|
648
|
-
);
|
|
649
|
-
profiles.set(identity, immutableCandidateValue(profile));
|
|
650
|
-
}
|
|
651
|
-
for (const target of input.targets) {
|
|
652
|
-
const profile = profiles.get(target.identity);
|
|
653
|
-
if (!profile || agentImprovementProfileSurfaceDigest(profile, target.surface) !== target.desiredDigest) {
|
|
654
|
-
throw new Error(
|
|
655
|
-
`agent profile activation did not produce ${target.identity}:${target.surface}`
|
|
656
|
-
);
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
return immutableCandidateValue({
|
|
660
|
-
status: "apply",
|
|
661
|
-
replacements: identities.map((identity) => {
|
|
662
|
-
const profile = profiles.get(identity);
|
|
663
|
-
if (!profile) throw new Error(`missing prepared agent profile ${identity}`);
|
|
664
|
-
return { identity, profile };
|
|
665
|
-
}),
|
|
666
|
-
targets: input.targets.map((target) => ({
|
|
667
|
-
surface: target.surface,
|
|
668
|
-
identity: target.identity,
|
|
669
|
-
beforeDigest: target.expectedBaseDigest,
|
|
670
|
-
afterDigest: target.desiredDigest
|
|
671
|
-
}))
|
|
672
|
-
});
|
|
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);
|
|
673
636
|
}
|
|
674
|
-
|
|
675
|
-
|
|
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
|
|
676
780
|
function emptyAccumulator() {
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
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
|
+
};
|
|
690
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
|
+
*/
|
|
691
804
|
async function composeCertifiedProfile(base, manifest, ctx = {}) {
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
if (teardown) await teardown();
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
};
|
|
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
|
+
};
|
|
732
841
|
}
|
|
733
842
|
function baseSurface(systemPrompt, promptSurface) {
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
};
|
|
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
|
+
};
|
|
753
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`). */
|
|
754
865
|
function collectPromptAdditions(promptSurface, contextArtifacts) {
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
}
|
|
763
|
-
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;
|
|
764
873
|
}
|
|
765
874
|
async function resolveCapability(cap, ctx, acc) {
|
|
766
|
-
|
|
875
|
+
await resolveBinding(cap, cap.binding, ctx, acc);
|
|
767
876
|
}
|
|
768
877
|
async function resolveBinding(cap, binding, ctx, acc) {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
);
|
|
795
|
-
case "memory-store":
|
|
796
|
-
throw new CapabilityNotAdmittedError(
|
|
797
|
-
binding.kind,
|
|
798
|
-
cap.id,
|
|
799
|
-
"memory-store admission is gated on the E3 score-superiority bar (memory/e3-certified-memory-verdict)"
|
|
800
|
-
);
|
|
801
|
-
case "wasm":
|
|
802
|
-
throw new CapabilityNotAdmittedError(
|
|
803
|
-
binding.kind,
|
|
804
|
-
cap.id,
|
|
805
|
-
"wasm is an extension-point arm, not yet admitted"
|
|
806
|
-
);
|
|
807
|
-
case "a2a":
|
|
808
|
-
throw new CapabilityNotAdmittedError(
|
|
809
|
-
binding.kind,
|
|
810
|
-
cap.id,
|
|
811
|
-
"a2a is an extension-point arm, not yet admitted"
|
|
812
|
-
);
|
|
813
|
-
}
|
|
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
|
+
}
|
|
814
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. */
|
|
815
907
|
function resolveInline(cap, binding, acc) {
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
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);
|
|
826
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. */
|
|
827
922
|
function registerInlineTool(cap, content, acc) {
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
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);
|
|
840
935
|
}
|
|
936
|
+
/** file → a workspace file mount (+ a prompt fold when the file is context). */
|
|
841
937
|
function resolveFile(cap, binding, acc) {
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
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);
|
|
849
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. */
|
|
850
948
|
function resolveMcp(cap, binding, acc) {
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
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
|
+
});
|
|
857
955
|
}
|
|
858
956
|
function mcpServerFromBinding(binding, cap) {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
metadata
|
|
878
|
-
};
|
|
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
|
+
};
|
|
879
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. */
|
|
880
978
|
function resolveHttp(cap, binding, ctx, acc) {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
...method === "GET" ? {} : { body: JSON.stringify(args) }
|
|
916
|
-
});
|
|
917
|
-
if (!res.ok) {
|
|
918
|
-
const body = await res.text().catch(() => "");
|
|
919
|
-
throw new Error(`capability '${cap.id}': http ${res.status}: ${body.slice(0, 200)}`);
|
|
920
|
-
}
|
|
921
|
-
return res.text();
|
|
922
|
-
});
|
|
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
|
+
});
|
|
923
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). */
|
|
924
1016
|
function resolveSandboxCode(cap, binding, ctx, acc) {
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
throw new Error(
|
|
941
|
-
`capability '${cap.id}': sandbox-code binding requires ResolveCtx.runSandboxCode`
|
|
942
|
-
);
|
|
943
|
-
}
|
|
944
|
-
return ctx.runSandboxCode(binding.code, binding.entry, args, task);
|
|
945
|
-
});
|
|
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
|
+
});
|
|
946
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
|
+
*/
|
|
947
1039
|
async function resolveProcessOnInfra(cap, binding, ctx, acc, visited) {
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
const provisioned = await ctx.provisionHost(
|
|
968
|
-
binding.host,
|
|
969
|
-
binding.inner,
|
|
970
|
-
hostCostTag(cap, binding.host)
|
|
971
|
-
);
|
|
972
|
-
acc.teardowns.push(() => provisioned.teardown());
|
|
973
|
-
if (provisioned.mcpConnection) {
|
|
974
|
-
const serverName = cap.iface.surface === "mcp" ? cap.iface.serverName : cap.id;
|
|
975
|
-
acc.mcpConnections[serverName] = provisioned.mcpConnection;
|
|
976
|
-
acc.mcpCapability.set(serverName, {
|
|
977
|
-
capabilityId: cap.id,
|
|
978
|
-
certifiedNames: cap.iface.surface === "mcp" ? cap.iface.toolset ?? [] : []
|
|
979
|
-
});
|
|
980
|
-
}
|
|
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
|
+
}
|
|
981
1059
|
}
|
|
982
1060
|
function hostCostTag(cap, host) {
|
|
983
|
-
|
|
1061
|
+
return host.costTag ?? `capability/${cap.id}`;
|
|
984
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
|
+
*/
|
|
985
1076
|
async function driftDropTools(acc, ctx) {
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
if (!setsEqual(new Set(live), new Set(info.certifiedNames))) {
|
|
1007
|
-
delete acc.mcpConnections[serverName];
|
|
1008
|
-
acc.mcpCapability.delete(serverName);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
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
|
+
}
|
|
1011
1097
|
}
|
|
1012
1098
|
function setsEqual(a, b) {
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1099
|
+
if (a.size !== b.size) return false;
|
|
1100
|
+
for (const x of a) if (!b.has(x)) return false;
|
|
1101
|
+
return true;
|
|
1016
1102
|
}
|
|
1017
1103
|
function inlineContent(cap, ref) {
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
`capability '${cap.id}': content ref '${ref.kind}' is not inline \u2014 wire a content fetcher to resolve it`
|
|
1021
|
-
);
|
|
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`);
|
|
1022
1106
|
}
|
|
1023
1107
|
function pushContextArtifact(acc, cap, content) {
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
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
|
+
});
|
|
1035
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`. */
|
|
1036
1124
|
function contextArtifactType(cap) {
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
}
|
|
1040
|
-
return "instructions";
|
|
1125
|
+
if (cap.iface.surface === "context") return cap.iface.kind === "instructions" ? "instructions" : cap.iface.kind;
|
|
1126
|
+
return "instructions";
|
|
1041
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. */
|
|
1042
1134
|
function contextArtifactPath(cap) {
|
|
1043
|
-
|
|
1135
|
+
return cap.provenance.sourcePath;
|
|
1044
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. */
|
|
1045
1140
|
async function composeCertifiedProfileFromWire(base, profile, ctx = {}) {
|
|
1046
|
-
|
|
1047
|
-
|
|
1141
|
+
if (!profile) return composeCertifiedProfile(base, null, ctx);
|
|
1142
|
+
return composeCertifiedProfile(base, manifestFromProfile(profile), ctx);
|
|
1048
1143
|
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
import { applyAgentProfileDiff } from "@tangle-network/agent-interface";
|
|
1144
|
+
//#endregion
|
|
1145
|
+
//#region src/intelligence/with-intelligence.ts
|
|
1052
1146
|
function summarizeRuntimeEvents(events) {
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
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;
|
|
1080
1176
|
}
|
|
1081
1177
|
function runError(cause) {
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
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
|
+
};
|
|
1091
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
|
+
*/
|
|
1092
1200
|
function withIntelligence(agent, config) {
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
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;
|
|
1183
1298
|
}
|
|
1184
|
-
|
|
1185
|
-
|
|
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
|
+
*/
|
|
1186
1321
|
function resolveEffortConfig(effort) {
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1322
|
+
if (effort === void 0) return resolveEffort(defaultEffortTier);
|
|
1323
|
+
if (typeof effort === "string") return resolveEffort(effort);
|
|
1324
|
+
return resolveEffort(effort.tier, effort.overrides);
|
|
1190
1325
|
}
|
|
1191
1326
|
function freshTraceId() {
|
|
1192
|
-
|
|
1327
|
+
return randomHex(32);
|
|
1193
1328
|
}
|
|
1194
1329
|
function freshRunId() {
|
|
1195
|
-
|
|
1330
|
+
return `run-${randomHex(16)}`;
|
|
1196
1331
|
}
|
|
1332
|
+
/** Serialize a redacted value without dropping customer trace content. */
|
|
1197
1333
|
function serializeJson(value) {
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
}
|
|
1207
|
-
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;
|
|
1208
1342
|
}
|
|
1209
1343
|
function addPayloadAttributes(labels, key, value, includeFullPayload) {
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
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;
|
|
1214
1348
|
}
|
|
1215
1349
|
function randomHex(chars) {
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
|
|
1221
|
-
}
|
|
1222
|
-
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);
|
|
1223
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
|
+
*/
|
|
1224
1361
|
function createIntelligenceClient(config) {
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
const hasRepo = Boolean(config.repo?.owner && config.repo?.name && config.repo?.baseBranch);
|
|
1443
|
-
const hasChecks = Boolean(config.checks && config.checks.length > 0);
|
|
1444
|
-
const hasSurfaces = Boolean(config.surfaces && config.surfaces.length > 0);
|
|
1445
|
-
const prMissing = [];
|
|
1446
|
-
if (!hasChecks) prMissing.push("checks");
|
|
1447
|
-
if (!hasSurfaces) prMissing.push("surfaces");
|
|
1448
|
-
if (!hasRepo) prMissing.push("repo");
|
|
1449
|
-
const recommendMissing = [];
|
|
1450
|
-
if (intelligenceOff) recommendMissing.push("effort above off");
|
|
1451
|
-
return {
|
|
1452
|
-
project: config.project,
|
|
1453
|
-
effort,
|
|
1454
|
-
// Send ships only with a tenant key — the honest "will export actually
|
|
1455
|
-
// land" signal (the base URL always resolves to the plane default).
|
|
1456
|
-
exportConfigured: Boolean(apiKey),
|
|
1457
|
-
modes: {
|
|
1458
|
-
observe: { ready: true, missing: [] },
|
|
1459
|
-
recommend: {
|
|
1460
|
-
ready: recommendMissing.length === 0,
|
|
1461
|
-
missing: recommendMissing
|
|
1462
|
-
},
|
|
1463
|
-
pr: { ready: prMissing.length === 0, missing: prMissing }
|
|
1464
|
-
}
|
|
1465
|
-
};
|
|
1466
|
-
},
|
|
1467
|
-
async flush() {
|
|
1468
|
-
const ex = getExporter();
|
|
1469
|
-
if (!ex) return;
|
|
1470
|
-
try {
|
|
1471
|
-
await ex.flush();
|
|
1472
|
-
} catch {
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
};
|
|
1476
|
-
}
|
|
1477
|
-
export {
|
|
1478
|
-
AGENT_IMPROVEMENT_PROFILE_SURFACES,
|
|
1479
|
-
AgentCandidateExperimentCellExecutionError,
|
|
1480
|
-
CapabilityNotAdmittedError,
|
|
1481
|
-
agentImprovementProfileSurfaceDigest,
|
|
1482
|
-
agentImprovementProfileSurfaceInput,
|
|
1483
|
-
agentImprovementTargetProfileDiffs,
|
|
1484
|
-
buildAgentImprovementActivationTargets,
|
|
1485
|
-
compileEffort,
|
|
1486
|
-
composeCertifiedProfile,
|
|
1487
|
-
composeCertifiedProfileFromWire,
|
|
1488
|
-
composeCertifiedPrompt,
|
|
1489
|
-
createAgentImprovementActivation,
|
|
1490
|
-
createAgentImprovementActivationResult,
|
|
1491
|
-
createAgentImprovementMeasuredComparison,
|
|
1492
|
-
createAgentImprovementProposal,
|
|
1493
|
-
createCertifiedPromptSource,
|
|
1494
|
-
createExactProcessCandidateExperimentExecutor,
|
|
1495
|
-
createIntelligenceClient,
|
|
1496
|
-
createProtectedExactProcessCandidateExperimentExecutor,
|
|
1497
|
-
defaultEffortTier,
|
|
1498
|
-
defaultRedactor,
|
|
1499
|
-
exactProcessCandidateExperimentExecutionSupport,
|
|
1500
|
-
executeAgentCandidateExperimentCell,
|
|
1501
|
-
executeAgentImprovementActivation,
|
|
1502
|
-
isAgentImprovementProfileSurface,
|
|
1503
|
-
isIntelligenceOff,
|
|
1504
|
-
manifestFromProfile,
|
|
1505
|
-
normalizeCertifiedProfile,
|
|
1506
|
-
parseAgentCandidateProfileActivation as parseCandidateProfileMaterialization,
|
|
1507
|
-
prepareAgentImprovementProfileActivation,
|
|
1508
|
-
proposeAgentImprovement,
|
|
1509
|
-
pullCertified,
|
|
1510
|
-
resolveEffort,
|
|
1511
|
-
resolveIntelligenceBaseUrl,
|
|
1512
|
-
resolveRedactor,
|
|
1513
|
-
reviewAgentImprovementProposal,
|
|
1514
|
-
runAgentCandidateExperiment,
|
|
1515
|
-
submitAgentImprovementProposal,
|
|
1516
|
-
verifyAgentImprovementActivation,
|
|
1517
|
-
verifyAgentImprovementActivationResult,
|
|
1518
|
-
verifyAgentImprovementProposal,
|
|
1519
|
-
verifyAgentImprovementReview,
|
|
1520
|
-
verifyCandidateExecutionEvidence,
|
|
1521
|
-
withIntelligence
|
|
1522
|
-
};
|
|
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
|
+
|
|
1523
1579
|
//# sourceMappingURL=intelligence.js.map
|