@tangle-network/agent-runtime 0.105.0 → 0.106.1
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 +2 -2
- 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-CiOCyRHb.js +743 -0
- package/dist/backends-CiOCyRHb.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-BpLQZGPH.js +1265 -0
- package/dist/conversation-BpLQZGPH.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 -1058
- package/dist/index.js +2106 -2082
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +768 -889
- package/dist/intelligence.js +1466 -1367
- 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-CRagyuNb.js +268 -0
- package/dist/loop-runner-bin-CRagyuNb.js.map +1 -0
- package/dist/loop-runner-bin.d.ts +2 -15
- 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 -436
- 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 +149 -145
- package/dist/primeintellect/index.js +626 -1003
- 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-5zM5XxLr.js +5408 -0
- package/dist/runtime-5zM5XxLr.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 +44 -56
- package/skills/build-with-agent-runtime/SKILL.md +1 -0
- 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-2VZYRB55.js +0 -834
- package/dist/chunk-2VZYRB55.js.map +0 -1
- package/dist/chunk-3MDZX7YU.js +0 -125
- package/dist/chunk-3MDZX7YU.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-C5RTIBNZ.js +0 -48
- package/dist/chunk-C5RTIBNZ.js.map +0 -1
- package/dist/chunk-CTRA64LY.js +0 -680
- package/dist/chunk-CTRA64LY.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-H5QPIZNX.js +0 -907
- package/dist/chunk-H5QPIZNX.js.map +0 -1
- package/dist/chunk-HLKC4UYB.js +0 -3514
- package/dist/chunk-HLKC4UYB.js.map +0 -1
- package/dist/chunk-HNP72PNU.js +0 -192
- package/dist/chunk-HNP72PNU.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-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-OPVWXJ2H.js +0 -75
- package/dist/chunk-OPVWXJ2H.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-RDOAVVHY.js +0 -699
- package/dist/chunk-RDOAVVHY.js.map +0 -1
- package/dist/chunk-SGKPNBXE.js +0 -60
- package/dist/chunk-SGKPNBXE.js.map +0 -1
- package/dist/chunk-SMQXZGLZ.js +0 -351
- package/dist/chunk-SMQXZGLZ.js.map +0 -1
- package/dist/chunk-UHEZW5BU.js +0 -2918
- package/dist/chunk-UHEZW5BU.js.map +0 -1
- package/dist/chunk-UPWGXKXB.js +0 -254
- package/dist/chunk-UPWGXKXB.js.map +0 -1
- package/dist/chunk-VISA6CI3.js +0 -200
- package/dist/chunk-VISA6CI3.js.map +0 -1
- package/dist/chunk-WMTCUOQL.js +0 -474
- package/dist/chunk-WMTCUOQL.js.map +0 -1
- package/dist/chunk-WRTOVNN4.js +0 -4728
- package/dist/chunk-WRTOVNN4.js.map +0 -1
- package/dist/chunk-WSTRQZYQ.js +0 -5576
- package/dist/chunk-WSTRQZYQ.js.map +0 -1
- package/dist/chunk-XBG2W2VW.js +0 -6434
- package/dist/chunk-XBG2W2VW.js.map +0 -1
- package/dist/chunk-YEJR7IXO.js +0 -68
- package/dist/chunk-YEJR7IXO.js.map +0 -1
- package/dist/chunk-YJZA2BIK.js +0 -1338
- package/dist/chunk-YJZA2BIK.js.map +0 -1
- package/dist/completion-gate-BMy5LGoP.d.ts +0 -256
- package/dist/conversation.js.map +0 -1
- package/dist/coordination-BZZSVYpZ.d.ts +0 -2570
- package/dist/environment-provider.js.map +0 -1
- package/dist/improvement-adapter-HAZz-7vK.d.ts +0 -203
- package/dist/knowledge.js.map +0 -1
- package/dist/local-harness-BDNcl6jI.d.ts +0 -175
- package/dist/loop-runner-bin-68aoM9-7.d.ts +0 -199
- 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-B4t-OQjL.d.ts +0 -271
- package/dist/redact-BuFjxBUJ.d.ts +0 -481
- package/dist/sanitize-DEbPNtyI.d.ts +0 -328
- package/dist/structural-rollout-DEh6CEsa.d.ts +0 -446
- package/dist/supervise-4_48wwvy.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-DxhAWr5Z.d.ts +0 -999
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/mcp/kb-gate.d.ts
|
|
1
2
|
/**
|
|
2
3
|
*
|
|
3
4
|
* `createKbGate` — the valid-only knowledge-base growth gate, distilled from
|
|
@@ -22,48 +23,48 @@
|
|
|
22
23
|
*/
|
|
23
24
|
/** @experimental A fact proposed for the KB, with its grounding. */
|
|
24
25
|
interface FactCandidate {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
/** The atomic claim text. */
|
|
27
|
+
claim: string;
|
|
28
|
+
/** Optional extracted value (number or string) the claim asserts. */
|
|
29
|
+
value?: string | number;
|
|
30
|
+
/** Verbatim span lifted from the source that backs the claim. */
|
|
31
|
+
verbatimPassage: string;
|
|
32
|
+
/** The raw source text the passage must be grounded in. */
|
|
33
|
+
sourceText: string;
|
|
34
|
+
/** Where the fact claims to come from — checked for circular/self citations. */
|
|
35
|
+
citation?: string;
|
|
35
36
|
}
|
|
36
37
|
/** @experimental */
|
|
37
38
|
interface FactJudgeVerdict {
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
accept: boolean;
|
|
40
|
+
reason?: string;
|
|
40
41
|
}
|
|
41
42
|
/** @experimental A pluggable fact validator. Throw is NOT allowed — return a
|
|
42
43
|
* verdict; a thrown judge is a programmer error, not a veto. */
|
|
43
44
|
interface FactJudge {
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
name: string;
|
|
46
|
+
judge(candidate: FactCandidate): FactJudgeVerdict | Promise<FactJudgeVerdict>;
|
|
46
47
|
}
|
|
47
48
|
/** @experimental */
|
|
48
49
|
interface KbGateResult {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
accepted: boolean;
|
|
51
|
+
/** Name of the judge that vetoed; undefined when accepted. */
|
|
52
|
+
vetoedBy?: string;
|
|
53
|
+
reason?: string;
|
|
53
54
|
}
|
|
54
55
|
/** @experimental */
|
|
55
56
|
interface CreateKbGateOptions {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
/** Extra judges appended after the built-in floor (e.g. an LLM judge). */
|
|
58
|
+
judges?: FactJudge[];
|
|
59
|
+
/** Minimum verbatim-passage length. Default 12 — kills empty/stub passages. */
|
|
60
|
+
minPassageChars?: number;
|
|
61
|
+
/**
|
|
62
|
+
* Citation tokens that denote a SELF-generated artifact (e.g. `'spec'`,
|
|
63
|
+
* `'cad_params'`, `'requirements'`). A citation naming one is circular
|
|
64
|
+
* (laundering) — the fact cites a derived artifact, not a real source.
|
|
65
|
+
* Default `[]` (no circular check unless the consumer declares its kinds).
|
|
66
|
+
*/
|
|
67
|
+
selfArtifactKinds?: string[];
|
|
67
68
|
}
|
|
68
69
|
/**
|
|
69
70
|
*
|
|
@@ -74,5 +75,6 @@ interface CreateKbGateOptions {
|
|
|
74
75
|
* @experimental
|
|
75
76
|
*/
|
|
76
77
|
declare function createKbGate(options?: CreateKbGateOptions): (candidate: FactCandidate) => Promise<KbGateResult>;
|
|
77
|
-
|
|
78
|
-
export {
|
|
78
|
+
//#endregion
|
|
79
|
+
export { KbGateResult as a, FactJudgeVerdict as i, FactCandidate as n, createKbGate as o, FactJudge as r, CreateKbGateOptions as t };
|
|
80
|
+
//# sourceMappingURL=kb-gate-C8z2juK8.d.ts.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
//#region src/mcp/kb-gate.ts
|
|
2
|
+
const norm = (s) => s.toLowerCase().replace(/\s+/g, " ").trim();
|
|
3
|
+
/** Does `value` appear in the (normalized) passage — literally, comma-grouped,
|
|
4
|
+
* or in billion/million shorthand (the forms a source actually writes). */
|
|
5
|
+
function valueAppears(value, passageNorm) {
|
|
6
|
+
if (passageNorm.includes(norm(String(value)))) return true;
|
|
7
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return false;
|
|
8
|
+
const forms = [value.toLocaleString("en-US")];
|
|
9
|
+
if (Math.abs(value) >= 1e9) forms.push(`${trimZero(value / 1e9)} billion`);
|
|
10
|
+
if (Math.abs(value) >= 1e6) forms.push(`${trimZero(value / 1e6)} million`);
|
|
11
|
+
return forms.some((f) => passageNorm.includes(norm(f)));
|
|
12
|
+
}
|
|
13
|
+
function trimZero(n) {
|
|
14
|
+
return Number.isInteger(n) ? String(n) : String(Number(n.toFixed(2)));
|
|
15
|
+
}
|
|
16
|
+
/** The always-on floor judges. Order matters: cheapest / most-fundamental first. */
|
|
17
|
+
function builtinJudges(minPassageChars, selfArtifactKinds) {
|
|
18
|
+
const kinds = selfArtifactKinds.map((k) => k.toLowerCase());
|
|
19
|
+
return [
|
|
20
|
+
{
|
|
21
|
+
name: "passage-non-empty",
|
|
22
|
+
judge: (c) => c.verbatimPassage.trim().length >= minPassageChars ? { accept: true } : {
|
|
23
|
+
accept: false,
|
|
24
|
+
reason: `passage shorter than ${minPassageChars} chars`
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "passage-present",
|
|
29
|
+
judge: (c) => norm(c.sourceText).includes(norm(c.verbatimPassage)) ? { accept: true } : {
|
|
30
|
+
accept: false,
|
|
31
|
+
reason: "verbatim passage not found in source (unbacked fact)"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "value-in-passage",
|
|
36
|
+
judge: (c) => c.value === void 0 || valueAppears(c.value, norm(c.verbatimPassage)) ? { accept: true } : {
|
|
37
|
+
accept: false,
|
|
38
|
+
reason: `value ${JSON.stringify(c.value)} not present in passage`
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "no-circular-citation",
|
|
43
|
+
judge: (c) => {
|
|
44
|
+
if (!c.citation || kinds.length === 0) return { accept: true };
|
|
45
|
+
const cite = c.citation.toLowerCase();
|
|
46
|
+
const hit = kinds.find((k) => cite.includes(k));
|
|
47
|
+
return hit ? {
|
|
48
|
+
accept: false,
|
|
49
|
+
reason: `circular citation to self-generated artifact "${hit}"`
|
|
50
|
+
} : { accept: true };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* Build a fail-closed KB gate. The returned function runs the built-in floor
|
|
58
|
+
* (passage-non-empty → passage-present → value-in-passage → no-circular-citation)
|
|
59
|
+
* then any consumer judges, returning on the first veto.
|
|
60
|
+
*
|
|
61
|
+
* @experimental
|
|
62
|
+
*/
|
|
63
|
+
function createKbGate(options = {}) {
|
|
64
|
+
const judges = [...builtinJudges(options.minPassageChars ?? 12, options.selfArtifactKinds ?? []), ...options.judges ?? []];
|
|
65
|
+
return async (candidate) => {
|
|
66
|
+
for (const j of judges) {
|
|
67
|
+
const verdict = await j.judge(candidate);
|
|
68
|
+
if (!verdict.accept) return {
|
|
69
|
+
accepted: false,
|
|
70
|
+
vetoedBy: j.name,
|
|
71
|
+
reason: verdict.reason
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return { accepted: true };
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
export { createKbGate as t };
|
|
79
|
+
|
|
80
|
+
//# sourceMappingURL=kb-gate-DpaSwXVx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kb-gate-DpaSwXVx.js","names":[],"sources":["../src/mcp/kb-gate.ts"],"sourcesContent":["/**\n *\n * `createKbGate` — the valid-only knowledge-base growth gate, distilled from\n * physim's KB-research subsystem. A research-in-a-loop delegate (or any KB\n * writer) runs candidate facts through this before persisting, so the KB grows\n * with ONLY grounded facts — hallucinated, unsourced, or laundered claims are\n * vetoed at the gate.\n *\n * Fail-closed by construction: every judge must `accept`; the FIRST veto wins\n * and the fact is rejected. The non-negotiable floor (always on, can't be\n * disabled) is the **passage-present guard** — a fact's `verbatimPassage` MUST\n * literally appear in its `sourceText`. That single check kills the dominant\n * failure mode (a confident claim decoupled from any real source).\n *\n * Pure + dependency-free: it operates on fact candidates, not on a store, so it\n * composes with `@tangle-network/agent-knowledge` or any persistence layer\n * without importing it. The remediation policy (correct-on-veto vs\n * escalate-as-unverified) is the caller's — this returns the verdict; it never\n * drops a fact silently.\n *\n * @experimental\n */\n\n/** @experimental A fact proposed for the KB, with its grounding. */\nexport interface FactCandidate {\n /** The atomic claim text. */\n claim: string\n /** Optional extracted value (number or string) the claim asserts. */\n value?: string | number\n /** Verbatim span lifted from the source that backs the claim. */\n verbatimPassage: string\n /** The raw source text the passage must be grounded in. */\n sourceText: string\n /** Where the fact claims to come from — checked for circular/self citations. */\n citation?: string\n}\n\n/** @experimental */\nexport interface FactJudgeVerdict {\n accept: boolean\n reason?: string\n}\n\n/** @experimental A pluggable fact validator. Throw is NOT allowed — return a\n * verdict; a thrown judge is a programmer error, not a veto. */\nexport interface FactJudge {\n name: string\n judge(candidate: FactCandidate): FactJudgeVerdict | Promise<FactJudgeVerdict>\n}\n\n/** @experimental */\nexport interface KbGateResult {\n accepted: boolean\n /** Name of the judge that vetoed; undefined when accepted. */\n vetoedBy?: string\n reason?: string\n}\n\n/** @experimental */\nexport interface CreateKbGateOptions {\n /** Extra judges appended after the built-in floor (e.g. an LLM judge). */\n judges?: FactJudge[]\n /** Minimum verbatim-passage length. Default 12 — kills empty/stub passages. */\n minPassageChars?: number\n /**\n * Citation tokens that denote a SELF-generated artifact (e.g. `'spec'`,\n * `'cad_params'`, `'requirements'`). A citation naming one is circular\n * (laundering) — the fact cites a derived artifact, not a real source.\n * Default `[]` (no circular check unless the consumer declares its kinds).\n */\n selfArtifactKinds?: string[]\n}\n\nconst norm = (s: string): string => s.toLowerCase().replace(/\\s+/g, ' ').trim()\n\n/** Does `value` appear in the (normalized) passage — literally, comma-grouped,\n * or in billion/million shorthand (the forms a source actually writes). */\nfunction valueAppears(value: string | number, passageNorm: string): boolean {\n if (passageNorm.includes(norm(String(value)))) return true\n if (typeof value !== 'number' || !Number.isFinite(value)) return false\n const forms = [value.toLocaleString('en-US')]\n if (Math.abs(value) >= 1e9) forms.push(`${trimZero(value / 1e9)} billion`)\n if (Math.abs(value) >= 1e6) forms.push(`${trimZero(value / 1e6)} million`)\n return forms.some((f) => passageNorm.includes(norm(f)))\n}\n\nfunction trimZero(n: number): string {\n return Number.isInteger(n) ? String(n) : String(Number(n.toFixed(2)))\n}\n\n/** The always-on floor judges. Order matters: cheapest / most-fundamental first. */\nfunction builtinJudges(minPassageChars: number, selfArtifactKinds: string[]): FactJudge[] {\n const kinds = selfArtifactKinds.map((k) => k.toLowerCase())\n return [\n {\n name: 'passage-non-empty',\n judge: (c) =>\n c.verbatimPassage.trim().length >= minPassageChars\n ? { accept: true }\n : { accept: false, reason: `passage shorter than ${minPassageChars} chars` },\n },\n {\n // THE anti-hallucination floor — the passage must literally be in the source.\n name: 'passage-present',\n judge: (c) =>\n norm(c.sourceText).includes(norm(c.verbatimPassage))\n ? { accept: true }\n : { accept: false, reason: 'verbatim passage not found in source (unbacked fact)' },\n },\n {\n name: 'value-in-passage',\n judge: (c) =>\n c.value === undefined || valueAppears(c.value, norm(c.verbatimPassage))\n ? { accept: true }\n : { accept: false, reason: `value ${JSON.stringify(c.value)} not present in passage` },\n },\n {\n name: 'no-circular-citation',\n judge: (c) => {\n if (!c.citation || kinds.length === 0) return { accept: true }\n const cite = c.citation.toLowerCase()\n const hit = kinds.find((k) => cite.includes(k))\n return hit\n ? { accept: false, reason: `circular citation to self-generated artifact \"${hit}\"` }\n : { accept: true }\n },\n },\n ]\n}\n\n/**\n *\n * Build a fail-closed KB gate. The returned function runs the built-in floor\n * (passage-non-empty → passage-present → value-in-passage → no-circular-citation)\n * then any consumer judges, returning on the first veto.\n *\n * @experimental\n */\nexport function createKbGate(\n options: CreateKbGateOptions = {},\n): (candidate: FactCandidate) => Promise<KbGateResult> {\n const judges = [\n ...builtinJudges(options.minPassageChars ?? 12, options.selfArtifactKinds ?? []),\n ...(options.judges ?? []),\n ]\n return async (candidate) => {\n for (const j of judges) {\n const verdict = await j.judge(candidate)\n if (!verdict.accept) {\n return { accepted: false, vetoedBy: j.name, reason: verdict.reason }\n }\n }\n return { accepted: true }\n }\n}\n"],"mappings":";AAyEA,MAAM,QAAQ,MAAsB,EAAE,YAAY,CAAC,CAAC,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;;;AAI9E,SAAS,aAAa,OAAwB,aAA8B;CAC1E,IAAI,YAAY,SAAS,KAAK,OAAO,KAAK,CAAC,CAAC,GAAG,OAAO;CACtD,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO;CACjE,MAAM,QAAQ,CAAC,MAAM,eAAe,OAAO,CAAC;CAC5C,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK,MAAM,KAAK,GAAG,SAAS,QAAQ,GAAG,EAAE,SAAS;CACzE,IAAI,KAAK,IAAI,KAAK,KAAK,KAAK,MAAM,KAAK,GAAG,SAAS,QAAQ,GAAG,EAAE,SAAS;CACzE,OAAO,MAAM,MAAM,MAAM,YAAY,SAAS,KAAK,CAAC,CAAC,CAAC;AACxD;AAEA,SAAS,SAAS,GAAmB;CACnC,OAAO,OAAO,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,OAAO,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AACtE;;AAGA,SAAS,cAAc,iBAAyB,mBAA0C;CACxF,MAAM,QAAQ,kBAAkB,KAAK,MAAM,EAAE,YAAY,CAAC;CAC1D,OAAO;EACL;GACE,MAAM;GACN,QAAQ,MACN,EAAE,gBAAgB,KAAK,CAAC,CAAC,UAAU,kBAC/B,EAAE,QAAQ,KAAK,IACf;IAAE,QAAQ;IAAO,QAAQ,wBAAwB,gBAAgB;GAAQ;EACjF;EACA;GAEE,MAAM;GACN,QAAQ,MACN,KAAK,EAAE,UAAU,CAAC,CAAC,SAAS,KAAK,EAAE,eAAe,CAAC,IAC/C,EAAE,QAAQ,KAAK,IACf;IAAE,QAAQ;IAAO,QAAQ;GAAuD;EACxF;EACA;GACE,MAAM;GACN,QAAQ,MACN,EAAE,UAAU,KAAA,KAAa,aAAa,EAAE,OAAO,KAAK,EAAE,eAAe,CAAC,IAClE,EAAE,QAAQ,KAAK,IACf;IAAE,QAAQ;IAAO,QAAQ,SAAS,KAAK,UAAU,EAAE,KAAK,EAAE;GAAyB;EAC3F;EACA;GACE,MAAM;GACN,QAAQ,MAAM;IACZ,IAAI,CAAC,EAAE,YAAY,MAAM,WAAW,GAAG,OAAO,EAAE,QAAQ,KAAK;IAC7D,MAAM,OAAO,EAAE,SAAS,YAAY;IACpC,MAAM,MAAM,MAAM,MAAM,MAAM,KAAK,SAAS,CAAC,CAAC;IAC9C,OAAO,MACH;KAAE,QAAQ;KAAO,QAAQ,iDAAiD,IAAI;IAAG,IACjF,EAAE,QAAQ,KAAK;GACrB;EACF;CACF;AACF;;;;;;;;;AAUA,SAAgB,aACd,UAA+B,CAAC,GACqB;CACrD,MAAM,SAAS,CACb,GAAG,cAAc,QAAQ,mBAAmB,IAAI,QAAQ,qBAAqB,CAAC,CAAC,GAC/E,GAAI,QAAQ,UAAU,CAAC,CACzB;CACA,OAAO,OAAO,cAAc;EAC1B,KAAK,MAAM,KAAK,QAAQ;GACtB,MAAM,UAAU,MAAM,EAAE,MAAM,SAAS;GACvC,IAAI,CAAC,QAAQ,QACX,OAAO;IAAE,UAAU;IAAO,UAAU,EAAE;IAAM,QAAQ,QAAQ;GAAO;EAEvE;EACA,OAAO,EAAE,UAAU,KAAK;CAC1B;AACF"}
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
import { a as persistCandidateOutputArtifact, ct as omitTopLevelDigest, nt as canonicalCandidateBytes, ot as embeddedCandidateArtifact } from "./prepare-B53sPV7M.js";
|
|
2
|
+
import { i as sealAgentCandidateBundle, t as captureAgentCandidateWorkspace } from "./workspace-archive-BosQiotA.js";
|
|
3
|
+
import { t as createAgentImprovementActivationResult } from "./activation-CRjVfOiy.js";
|
|
4
|
+
import { r as researcherProfile } from "./researcher-CoVqNhfI.js";
|
|
5
|
+
import { t as supervise } from "./supervise-BiRutHS9.js";
|
|
6
|
+
import { agentCandidateKnowledgeSchema, sha256DigestSchema } from "@tangle-network/agent-interface";
|
|
7
|
+
import { realpath } from "node:fs/promises";
|
|
8
|
+
import { evaluateKnowledgeBaseReadiness, fromAgentCandidateKnowledgeRef, improveKnowledgeBase, knowledgeImprovementCandidateRef, loadKnowledgeImprovementActivationResult, promoteKnowledgeCandidate, restoreKnowledgeCandidateBaseline, toAgentCandidateKnowledgeRef, withKnowledgeImprovementComparison } from "@tangle-network/agent-knowledge";
|
|
9
|
+
//#region src/knowledge/activation.ts
|
|
10
|
+
/** Apply or restore one local knowledge candidate through the shared activation contract. */
|
|
11
|
+
function createKnowledgeImprovementActivationExecutor(options) {
|
|
12
|
+
if (!options.identity.trim()) throw new Error("knowledge activation identity is required");
|
|
13
|
+
return {
|
|
14
|
+
reconcile: async (transition) => {
|
|
15
|
+
const inspected = await inspectKnowledgeActivation(options, transition);
|
|
16
|
+
return inspected.settled ? inspected.result : void 0;
|
|
17
|
+
},
|
|
18
|
+
transition: async (transition) => {
|
|
19
|
+
if (transition.expired) throw new Error("knowledge write transition cannot run after authorization expires");
|
|
20
|
+
const inspected = await inspectKnowledgeActivation(options, transition);
|
|
21
|
+
if (inspected.settled) return inspected.result;
|
|
22
|
+
const mutationOptions = {
|
|
23
|
+
root: options.root,
|
|
24
|
+
candidate: inspected.candidate,
|
|
25
|
+
activation: {
|
|
26
|
+
activation: transition.activation,
|
|
27
|
+
attemptedAt: transition.attemptedAt,
|
|
28
|
+
identity: options.identity,
|
|
29
|
+
createResult: (receipt) => inspected.create(knowledgeMutationOutcome(receipt, inspected, transition.activation.intent))
|
|
30
|
+
},
|
|
31
|
+
...options.ownerId ? { ownerId: options.ownerId } : {},
|
|
32
|
+
...options.leaseTtlMs === void 0 ? {} : { leaseTtlMs: options.leaseTtlMs },
|
|
33
|
+
...options.now ? { now: options.now } : {},
|
|
34
|
+
...options.onState ? { onState: options.onState } : {}
|
|
35
|
+
};
|
|
36
|
+
const improvement = transition.activation.intent === "activate-candidate" ? await promoteKnowledgeCandidate(mutationOptions) : await restoreKnowledgeCandidateBaseline(mutationOptions);
|
|
37
|
+
if (!improvement.activationResult) throw new Error("knowledge mutation did not persist its shared activation result");
|
|
38
|
+
return options.results.putIfAbsent(improvement.activationResult);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
async function inspectKnowledgeActivation(options, transition) {
|
|
43
|
+
const stored = await options.results.load(transition.activation.digest);
|
|
44
|
+
if (stored !== void 0) return {
|
|
45
|
+
settled: true,
|
|
46
|
+
result: stored
|
|
47
|
+
};
|
|
48
|
+
const create = (outcome) => createAgentImprovementActivationResult(transition, {
|
|
49
|
+
completedAt: completionTime(transition, options.now),
|
|
50
|
+
outcome
|
|
51
|
+
});
|
|
52
|
+
const store = (outcome) => options.results.putIfAbsent(create(outcome));
|
|
53
|
+
if (transition.kind !== "sealed-candidate") {
|
|
54
|
+
if (transition.expired) return {
|
|
55
|
+
settled: true,
|
|
56
|
+
result: void 0
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
settled: true,
|
|
60
|
+
result: await store({
|
|
61
|
+
status: "unsupported",
|
|
62
|
+
code: "KNOWLEDGE_PROFILE_TRANSITION_UNSUPPORTED",
|
|
63
|
+
message: "The knowledge adapter accepts only sealed knowledge candidates."
|
|
64
|
+
})
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const target = supportedKnowledgeTarget(transition, options.identity);
|
|
68
|
+
if (!target) {
|
|
69
|
+
if (transition.expired) return {
|
|
70
|
+
settled: true,
|
|
71
|
+
result: void 0
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
settled: true,
|
|
75
|
+
result: await store({
|
|
76
|
+
status: "unsupported",
|
|
77
|
+
code: "KNOWLEDGE_TARGET_SET_UNSUPPORTED",
|
|
78
|
+
message: "The knowledge adapter requires exactly one matching knowledge target."
|
|
79
|
+
})
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const knowledge = transition.candidateBundle.knowledge;
|
|
83
|
+
if (!knowledge) {
|
|
84
|
+
if (transition.expired) return {
|
|
85
|
+
settled: true,
|
|
86
|
+
result: void 0
|
|
87
|
+
};
|
|
88
|
+
return {
|
|
89
|
+
settled: true,
|
|
90
|
+
result: await store({
|
|
91
|
+
status: "unsupported",
|
|
92
|
+
code: "KNOWLEDGE_CANDIDATE_MISSING",
|
|
93
|
+
message: "The measured candidate bundle does not contain a knowledge candidate."
|
|
94
|
+
})
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
const candidate = fromAgentCandidateKnowledgeRef(knowledge.candidate);
|
|
98
|
+
const expectedDigest = transition.activation.intent === "activate-candidate" ? knowledge.candidate.baseHash : knowledge.candidate.candidateHash;
|
|
99
|
+
const desiredDigest = transition.activation.intent === "activate-candidate" ? knowledge.candidate.candidateHash : knowledge.candidate.baseHash;
|
|
100
|
+
if (target.expectedBaseDigest !== expectedDigest || target.desiredDigest !== desiredDigest) {
|
|
101
|
+
if (transition.expired) return {
|
|
102
|
+
settled: true,
|
|
103
|
+
result: void 0
|
|
104
|
+
};
|
|
105
|
+
return {
|
|
106
|
+
settled: true,
|
|
107
|
+
result: await store({
|
|
108
|
+
status: "failed",
|
|
109
|
+
code: "KNOWLEDGE_TARGET_MISMATCH",
|
|
110
|
+
message: "The activation target does not match the measured knowledge candidate."
|
|
111
|
+
})
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
const durable = await loadKnowledgeImprovementActivationResult({
|
|
115
|
+
root: options.root,
|
|
116
|
+
candidate,
|
|
117
|
+
activation: transition.activation,
|
|
118
|
+
identity: options.identity
|
|
119
|
+
});
|
|
120
|
+
if (durable) return {
|
|
121
|
+
settled: true,
|
|
122
|
+
result: await options.results.putIfAbsent(durable)
|
|
123
|
+
};
|
|
124
|
+
if (transition.expired) return {
|
|
125
|
+
settled: true,
|
|
126
|
+
result: void 0
|
|
127
|
+
};
|
|
128
|
+
return {
|
|
129
|
+
settled: false,
|
|
130
|
+
target,
|
|
131
|
+
candidate,
|
|
132
|
+
expectedDigest,
|
|
133
|
+
desiredDigest,
|
|
134
|
+
create
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function supportedKnowledgeTarget(transition, identity) {
|
|
138
|
+
if (transition.targets.length !== 1) return void 0;
|
|
139
|
+
const target = transition.targets[0];
|
|
140
|
+
return target.surface === "knowledge" && target.identity === identity ? target : void 0;
|
|
141
|
+
}
|
|
142
|
+
function knowledgeMutationOutcome(receipt, inspected, intent) {
|
|
143
|
+
const expectedTarget = intent === "activate-candidate" ? "candidate" : "baseline";
|
|
144
|
+
const beforeDigest = prefixedDigest(receipt.beforeHash);
|
|
145
|
+
const afterDigest = prefixedDigest(receipt.afterHash);
|
|
146
|
+
if (receipt.target !== expectedTarget || receipt.changed !== (beforeDigest !== afterDigest) || !receipt.changed && (receipt.transactionId !== null || receipt.recovered)) throw new Error("knowledge mutation returned inconsistent state evidence");
|
|
147
|
+
if (receipt.changed) {
|
|
148
|
+
if (receipt.transactionId === null || beforeDigest !== inspected.expectedDigest || afterDigest !== inspected.desiredDigest) throw new Error("knowledge activation did not apply its authorized content transition");
|
|
149
|
+
return {
|
|
150
|
+
status: "applied",
|
|
151
|
+
transactionId: receipt.transactionId,
|
|
152
|
+
targets: [{
|
|
153
|
+
surface: inspected.target.surface,
|
|
154
|
+
identity: inspected.target.identity,
|
|
155
|
+
beforeDigest,
|
|
156
|
+
afterDigest
|
|
157
|
+
}]
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (afterDigest === inspected.desiredDigest) return {
|
|
161
|
+
status: "already-applied",
|
|
162
|
+
targets: [targetState(inspected.target, afterDigest)]
|
|
163
|
+
};
|
|
164
|
+
if (afterDigest === inspected.expectedDigest) throw new Error("knowledge activation did not attempt its authorized content transition");
|
|
165
|
+
return {
|
|
166
|
+
status: "conflict",
|
|
167
|
+
targets: [targetState(inspected.target, afterDigest)]
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function targetState(target, currentDigest) {
|
|
171
|
+
return {
|
|
172
|
+
surface: target.surface,
|
|
173
|
+
identity: target.identity,
|
|
174
|
+
currentDigest
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function prefixedDigest(hash) {
|
|
178
|
+
return sha256DigestSchema.parse(`sha256:${hash}`);
|
|
179
|
+
}
|
|
180
|
+
function completionTime(transition, now) {
|
|
181
|
+
const completedAt = (now ?? (() => /* @__PURE__ */ new Date()))().toISOString();
|
|
182
|
+
return Date.parse(completedAt) < Date.parse(transition.attemptedAt) ? transition.attemptedAt : completedAt;
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/knowledge/supervised-update.ts
|
|
186
|
+
/** Standing prompt for a supervisor that grows a shared knowledge base through spawned researchers. */
|
|
187
|
+
const RESEARCH_SUPERVISOR_SYSTEM_PROMPT = [
|
|
188
|
+
"You are a research supervisor. You do not answer the research question yourself.",
|
|
189
|
+
"You create and manage researcher workers that improve one shared knowledge base until it is ready.",
|
|
190
|
+
"",
|
|
191
|
+
"Each round:",
|
|
192
|
+
"1. Read the goal and the gaps the readiness check still reports.",
|
|
193
|
+
"2. Decompose the open work into independent sub-topics.",
|
|
194
|
+
"3. Spawn one researcher per sub-topic; split by sub-topic, never duplicate work.",
|
|
195
|
+
"4. Wait for researchers to settle, steer or re-spawn thin sub-topics, then stop when the check passes.",
|
|
196
|
+
"",
|
|
197
|
+
"Conserve the shared budget. Prefer a small number of well-scoped researchers over a large fanout that re-covers the same ground."
|
|
198
|
+
].join("\n");
|
|
199
|
+
/** Build the completion check a supervised KB update uses to stop only when the KB is ready. */
|
|
200
|
+
function knowledgeReadinessDeliverable(options) {
|
|
201
|
+
return {
|
|
202
|
+
describe: `knowledge base at ${options.root} is ready for: ${options.goal}`,
|
|
203
|
+
async check() {
|
|
204
|
+
const result = await options.readiness({
|
|
205
|
+
root: options.root,
|
|
206
|
+
goal: options.goal,
|
|
207
|
+
readinessSpecs: options.readinessSpecs,
|
|
208
|
+
readinessTaskId: options.readinessTaskId,
|
|
209
|
+
readiness: options.readinessOptions
|
|
210
|
+
});
|
|
211
|
+
return typeof result === "boolean" ? result : result.ready;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/** Create an `improveKnowledgeBase` update callback backed by runtime supervision. */
|
|
216
|
+
function createSupervisedKnowledgeUpdater(options) {
|
|
217
|
+
return (input) => runSupervisedKnowledgeUpdate({
|
|
218
|
+
...options,
|
|
219
|
+
root: input.candidateRoot ?? input.root ?? options.root,
|
|
220
|
+
goal: input.goal ?? options.goal,
|
|
221
|
+
findings: input.findings ?? options.findings,
|
|
222
|
+
metadata: {
|
|
223
|
+
...options.metadata,
|
|
224
|
+
...input.metadata
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
/** Run a runtime supervisor that updates one candidate knowledge base and stops on readiness. */
|
|
229
|
+
async function runSupervisedKnowledgeUpdate(options) {
|
|
230
|
+
const { profile: workerProfile } = researcherProfile({ harness: options.harness });
|
|
231
|
+
const baseInstructions = options.supervisorSystemPrompt ?? RESEARCH_SUPERVISOR_SYSTEM_PROMPT;
|
|
232
|
+
const workerContract = workerProfile.prompt?.systemPrompt;
|
|
233
|
+
const systemPrompt = workerContract ? `${baseInstructions}\n\nEach researcher worker you spawn follows this contract:\n${workerContract}` : baseInstructions;
|
|
234
|
+
const profile = {
|
|
235
|
+
name: "knowledge-research-supervisor",
|
|
236
|
+
model: options.supervisorModel,
|
|
237
|
+
systemPrompt
|
|
238
|
+
};
|
|
239
|
+
const supervised = await (options.runSupervised ?? supervise)(profile, formatSupervisedKnowledgeTask(options), {
|
|
240
|
+
...options.superviseOptions,
|
|
241
|
+
budget: options.budget,
|
|
242
|
+
backend: options.backend,
|
|
243
|
+
deliverable: knowledgeReadinessDeliverable(options),
|
|
244
|
+
makeWorkerAgent: options.makeWorkerAgent,
|
|
245
|
+
allowedModels: options.allowedModels
|
|
246
|
+
});
|
|
247
|
+
return {
|
|
248
|
+
applied: supervised.kind === "winner",
|
|
249
|
+
summary: supervised.kind === "winner" ? "research supervisor completed and the knowledge base passed readiness" : `research supervisor stopped without a ready knowledge base: ${supervised.reason}`,
|
|
250
|
+
supervised,
|
|
251
|
+
metadata: {
|
|
252
|
+
supervised: true,
|
|
253
|
+
root: options.root,
|
|
254
|
+
goal: options.goal,
|
|
255
|
+
result: supervised.kind
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/** Format the supervisor task with the KB root, readiness requirements, current findings, and metadata. */
|
|
260
|
+
function formatSupervisedKnowledgeTask(options) {
|
|
261
|
+
return `${[
|
|
262
|
+
`Goal: ${options.goal}`,
|
|
263
|
+
`Knowledge base root: ${options.root}`,
|
|
264
|
+
options.readinessTaskId ? `Readiness task id: ${options.readinessTaskId}` : void 0,
|
|
265
|
+
options.readinessSpecs?.length ? `Readiness specs:\n${JSON.stringify(options.readinessSpecs, null, 2)}` : void 0,
|
|
266
|
+
options.findings?.length ? `Current findings:\n${JSON.stringify(options.findings, null, 2)}` : void 0,
|
|
267
|
+
options.metadata && Object.keys(options.metadata).length > 0 ? `Metadata:\n${JSON.stringify(options.metadata, null, 2)}` : void 0
|
|
268
|
+
].filter((section) => Boolean(section)).join("\n\n")}\n\nUpdate files under the knowledge base root only. Stop when the readiness check passes.`;
|
|
269
|
+
}
|
|
270
|
+
//#endregion
|
|
271
|
+
//#region src/knowledge/improvement-job.ts
|
|
272
|
+
/** Build the default readiness check backed by `@tangle-network/agent-knowledge` validation and scoring. */
|
|
273
|
+
function createAgentKnowledgeReadinessCheck(options) {
|
|
274
|
+
return async (input) => {
|
|
275
|
+
const readiness = await evaluateKnowledgeBaseReadiness({
|
|
276
|
+
root: input.root,
|
|
277
|
+
goal: input.goal ?? options.goal,
|
|
278
|
+
readinessSpecs: input.readinessSpecs ?? options.readinessSpecs,
|
|
279
|
+
readinessTaskId: input.readinessTaskId ?? options.readinessTaskId,
|
|
280
|
+
readiness: input.readiness ?? options.readiness,
|
|
281
|
+
strict: options.strict,
|
|
282
|
+
kbQuality: options.kbQuality
|
|
283
|
+
});
|
|
284
|
+
return {
|
|
285
|
+
ready: readiness.ready,
|
|
286
|
+
summary: readiness.summary,
|
|
287
|
+
metadata: {
|
|
288
|
+
dimensions: readiness.dimensions,
|
|
289
|
+
validationOk: readiness.validation.ok,
|
|
290
|
+
kbQualityOk: readiness.kbQuality.ok,
|
|
291
|
+
blockingMissing: readiness.readiness?.report.blockingMissingRequirements.length ?? 0
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/** Produce a frozen KB candidate while leaving live knowledge content unchanged. */
|
|
297
|
+
async function runKnowledgeImprovementJob(options) {
|
|
298
|
+
const { allowedModels, backend, budget, candidateArtifacts, harness, makeWorkerAgent, onMeasurement, readinessCheck, runSupervised, supervisorModel, supervisorSystemPrompt, superviseOptions, ...knowledgeOptions } = options;
|
|
299
|
+
const startedAtMs = Date.now();
|
|
300
|
+
const startedAt = new Date(startedAtMs).toISOString();
|
|
301
|
+
const supervisedSpent = emptySpent();
|
|
302
|
+
let updateCalls = 0;
|
|
303
|
+
let updateDurationMs = 0;
|
|
304
|
+
const readiness = readinessCheck ?? createAgentKnowledgeReadinessCheck(options);
|
|
305
|
+
const updateKnowledge = createSupervisedKnowledgeUpdater({
|
|
306
|
+
root: options.root,
|
|
307
|
+
goal: options.goal,
|
|
308
|
+
readiness,
|
|
309
|
+
readinessSpecs: options.readinessSpecs,
|
|
310
|
+
readinessTaskId: options.readinessTaskId,
|
|
311
|
+
readinessOptions: options.readiness,
|
|
312
|
+
budget,
|
|
313
|
+
backend,
|
|
314
|
+
makeWorkerAgent,
|
|
315
|
+
harness,
|
|
316
|
+
supervisorModel,
|
|
317
|
+
supervisorSystemPrompt,
|
|
318
|
+
superviseOptions,
|
|
319
|
+
allowedModels,
|
|
320
|
+
runSupervised
|
|
321
|
+
});
|
|
322
|
+
const instrumentedUpdateKnowledge = async (input) => {
|
|
323
|
+
const updateStartedAt = Date.now();
|
|
324
|
+
updateCalls += 1;
|
|
325
|
+
const result = await updateKnowledge(input);
|
|
326
|
+
updateDurationMs += Date.now() - updateStartedAt;
|
|
327
|
+
addSpent(supervisedSpent, result.supervised);
|
|
328
|
+
return result;
|
|
329
|
+
};
|
|
330
|
+
const resolvedImprovement = await improveKnowledgeBase({
|
|
331
|
+
...knowledgeOptions,
|
|
332
|
+
updateKnowledge: instrumentedUpdateKnowledge
|
|
333
|
+
});
|
|
334
|
+
let knowledge;
|
|
335
|
+
if (resolvedImprovement.candidate?.status === "candidate-ready" || resolvedImprovement.candidate?.status === "promoted") knowledge = await freezeKnowledgeCandidatePair(options.root, resolvedImprovement, candidateArtifacts, knowledgeOptions.signal);
|
|
336
|
+
const finishedAtMs = Date.now();
|
|
337
|
+
const measurement = {
|
|
338
|
+
startedAt,
|
|
339
|
+
finishedAt: new Date(finishedAtMs).toISOString(),
|
|
340
|
+
durationMs: finishedAtMs - startedAtMs,
|
|
341
|
+
updateCalls,
|
|
342
|
+
updateDurationMs,
|
|
343
|
+
supervisedSpent
|
|
344
|
+
};
|
|
345
|
+
await onMeasurement?.(measurement);
|
|
346
|
+
return {
|
|
347
|
+
improvement: resolvedImprovement,
|
|
348
|
+
...knowledge ? { knowledge } : {},
|
|
349
|
+
measurement,
|
|
350
|
+
blocked: resolvedImprovement.blocked
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
/** Attach both frozen knowledge inputs to one otherwise-identical bundle pair. */
|
|
354
|
+
function buildKnowledgeImprovementExperimentBundles(bundle, knowledge) {
|
|
355
|
+
const input = omitTopLevelDigest(bundle);
|
|
356
|
+
const withSnapshot = (snapshot) => agentCandidateKnowledgeSchema.parse({
|
|
357
|
+
candidate: knowledge.reference,
|
|
358
|
+
snapshot,
|
|
359
|
+
evaluation: knowledge.evaluation
|
|
360
|
+
});
|
|
361
|
+
return Object.freeze({
|
|
362
|
+
baseline: sealAgentCandidateBundle({
|
|
363
|
+
...input,
|
|
364
|
+
knowledge: withSnapshot(knowledge.baseline)
|
|
365
|
+
}),
|
|
366
|
+
candidate: sealAgentCandidateBundle({
|
|
367
|
+
...input,
|
|
368
|
+
knowledge: withSnapshot(knowledge.candidate)
|
|
369
|
+
})
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
async function freezeKnowledgeCandidatePair(root, improvement, artifacts, signal) {
|
|
373
|
+
const candidate = knowledgeImprovementCandidateRef(improvement);
|
|
374
|
+
const candidateRef = toAgentCandidateKnowledgeRef(candidate);
|
|
375
|
+
return withKnowledgeImprovementComparison({
|
|
376
|
+
root,
|
|
377
|
+
candidate
|
|
378
|
+
}, async (comparison) => {
|
|
379
|
+
const freeze = async (target) => {
|
|
380
|
+
const executionId = `knowledge-${candidate.candidateId}-${target}`;
|
|
381
|
+
return (await captureAgentCandidateWorkspace(await realpath(comparison[target].root), { ...artifacts ? { artifactPersistence: {
|
|
382
|
+
executionId,
|
|
383
|
+
outputArtifacts: artifacts,
|
|
384
|
+
...signal ? { signal } : {}
|
|
385
|
+
} } : {} })).snapshot;
|
|
386
|
+
};
|
|
387
|
+
const evaluation = await captureKnowledgeEvidence(canonicalCandidateBytes({
|
|
388
|
+
kind: "agent-knowledge-candidate-evaluation",
|
|
389
|
+
candidate: candidateRef,
|
|
390
|
+
metric: comparison.evaluation
|
|
391
|
+
}), "knowledge-evaluation", `knowledge-${candidate.candidateId}`, artifacts, signal);
|
|
392
|
+
const baseline = await freeze("baseline");
|
|
393
|
+
const proposed = await freeze("candidate");
|
|
394
|
+
return Object.freeze({
|
|
395
|
+
reference: candidateRef,
|
|
396
|
+
evaluation,
|
|
397
|
+
baseline,
|
|
398
|
+
candidate: proposed
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
async function captureKnowledgeEvidence(bytes, purpose, executionId, artifacts, signal) {
|
|
403
|
+
if (!artifacts) return embeddedCandidateArtifact(bytes);
|
|
404
|
+
return persistCandidateOutputArtifact(artifacts, {
|
|
405
|
+
executionId,
|
|
406
|
+
purpose,
|
|
407
|
+
bytes,
|
|
408
|
+
...signal ? { signal } : {}
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
function emptySpent() {
|
|
412
|
+
return {
|
|
413
|
+
iterations: 0,
|
|
414
|
+
inputTokens: 0,
|
|
415
|
+
outputTokens: 0,
|
|
416
|
+
usdKnown: true,
|
|
417
|
+
usd: 0,
|
|
418
|
+
ms: 0
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function addSpent(target, result) {
|
|
422
|
+
const spent = result.spentTotal;
|
|
423
|
+
target.iterations += spent.iterations;
|
|
424
|
+
target.inputTokens += spent.tokens.input;
|
|
425
|
+
target.outputTokens += spent.tokens.output;
|
|
426
|
+
target.usdKnown = target.usdKnown && spent.usdKnown !== false;
|
|
427
|
+
target.usd += spent.usd;
|
|
428
|
+
target.ms += spent.ms;
|
|
429
|
+
}
|
|
430
|
+
//#endregion
|
|
431
|
+
export { createSupervisedKnowledgeUpdater as a, runSupervisedKnowledgeUpdate as c, RESEARCH_SUPERVISOR_SYSTEM_PROMPT as i, createKnowledgeImprovementActivationExecutor as l, createAgentKnowledgeReadinessCheck as n, formatSupervisedKnowledgeTask as o, runKnowledgeImprovementJob as r, knowledgeReadinessDeliverable as s, buildKnowledgeImprovementExperimentBundles as t };
|
|
432
|
+
|
|
433
|
+
//# sourceMappingURL=knowledge-Ku-mPP4f.js.map
|