@tangle-network/agent-knowledge 2.0.0 → 3.0.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 +1 -1
- package/dist/benchmarks/index.d.ts +3 -3
- package/dist/{chunk-QID2QVR5.js → chunk-2BJ5JR3L.js} +246 -250
- package/dist/chunk-2BJ5JR3L.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/{index-BLxw1I_F.d.ts → index-BHQk7jOT.d.ts} +2 -2
- package/dist/index.d.ts +1279 -1277
- package/dist/index.js +3923 -3891
- package/dist/index.js.map +1 -1
- package/dist/memory/index.d.ts +3 -3
- package/dist/{types-C17sAROL.d.ts → types-6x0OpfW6.d.ts} +1 -1
- package/dist/{types-CjqPcTTK.d.ts → types-BFRyr390.d.ts} +1 -1
- package/dist/viz/index.d.ts +1 -1
- package/package.json +4 -2
- package/dist/chunk-QID2QVR5.js.map +0 -1
package/README.md
CHANGED
|
@@ -343,7 +343,7 @@ console.log(promoted.promoted)
|
|
|
343
343
|
Calling it again with the same `runId` resumes interrupted work.
|
|
344
344
|
`withKnowledgeImprovementCandidate` materializes the measured bytes in an isolated temporary directory for the callback, checks them again afterward, and removes the directory.
|
|
345
345
|
`promoteKnowledgeCandidate` applies only the frozen bytes identified by the approved candidate reference, and refuses if the live base changed.
|
|
346
|
-
The current release
|
|
346
|
+
The current release accepts one strict run-state format; incomplete runs created before 3.0 must be completed or restarted before upgrading.
|
|
347
347
|
The exact candidate workflow requires Linux; other knowledge, retrieval, and evaluation APIs remain cross-platform.
|
|
348
348
|
|
|
349
349
|
If a required phase is missing its hook, the loop throws.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '@tangle-network/agent-eval/campaign';
|
|
2
|
-
import '../types-
|
|
3
|
-
export { B as BuildRetrievalBenchmarkCasesFromQrelsOptions, I as INDUSTRY_MEMORY_BENCHMARKS, d as INDUSTRY_RAG_BENCHMARKS, K as KnowledgeAnswerBenchmarkCase, e as KnowledgeAnswerBenchmarkTaskKind, f as KnowledgeBenchmarkArtifact, g as KnowledgeBenchmarkCase, h as KnowledgeBenchmarkCaseBase, i as KnowledgeBenchmarkDistribution, j as KnowledgeBenchmarkEvaluation, k as KnowledgeBenchmarkFamily, l as KnowledgeBenchmarkReport, m as KnowledgeBenchmarkResponder, n as KnowledgeBenchmarkScenario, o as KnowledgeBenchmarkSliceSummary, p as KnowledgeBenchmarkSource, q as KnowledgeBenchmarkSpec, r as KnowledgeBenchmarkSplit, s as KnowledgeBenchmarkTaskKind, t as KnowledgeClaimMatcher, u as KnowledgeMemoryBenchmarkCase, v as KnowledgeMemoryBenchmarkTaskKind, w as KnowledgeMemoryEvent, x as KnowledgeMemoryFactMatcher, y as KnowledgeRetrievalBenchmarkCase, z as KnowledgeRetrievalBenchmarkQrel, A as KnowledgeRetrievalBenchmarkQuery, M as MemoryAdapterBenchmarkCandidate, C as MemoryAdapterBenchmarkRankingRow, V as RunKnowledgeBenchmarkSuiteOptions, W as RunKnowledgeBenchmarkSuiteResult, X as RunMemoryAdapterBenchmarkOptions, Y as RunMemoryAdapterBenchmarkResult, Z as buildFirstPartyMemoryLifecycleBenchmarkCases, _ as buildIndustryMemoryBenchmarkSmokeCases, $ as buildIndustryRagBenchmarkSmokeCases, a0 as buildKnowledgeBenchmarkScenarios, a1 as buildRetrievalBenchmarkCasesFromQrels, a4 as createInMemoryBenchmarkAdapter, a5 as createMemoryAdapterBenchmarkResponder, a6 as createNoopMemoryBenchmarkAdapter, a7 as isKnowledgeMemoryBenchmarkCase, a8 as knowledgeBenchmarkJudge, a9 as parseKnowledgeBenchmarkJsonl, aa as parseKnowledgeBenchmarkQrels, ab as renderKnowledgeBenchmarkReportMarkdown, ac as respondToIndustryMemoryBenchmarkSmokeCase, ad as respondToIndustryRagBenchmarkSmokeCase, ai as runKnowledgeBenchmarkSuite, aj as runMemoryAdapterBenchmark, al as scoreKnowledgeBenchmarkArtifact, am as scoreMemoryBenchmarkArtifact, ao as summarizeKnowledgeBenchmarkCampaign } from '../index-
|
|
4
|
-
import '../types-
|
|
2
|
+
import '../types-BFRyr390.js';
|
|
3
|
+
export { B as BuildRetrievalBenchmarkCasesFromQrelsOptions, I as INDUSTRY_MEMORY_BENCHMARKS, d as INDUSTRY_RAG_BENCHMARKS, K as KnowledgeAnswerBenchmarkCase, e as KnowledgeAnswerBenchmarkTaskKind, f as KnowledgeBenchmarkArtifact, g as KnowledgeBenchmarkCase, h as KnowledgeBenchmarkCaseBase, i as KnowledgeBenchmarkDistribution, j as KnowledgeBenchmarkEvaluation, k as KnowledgeBenchmarkFamily, l as KnowledgeBenchmarkReport, m as KnowledgeBenchmarkResponder, n as KnowledgeBenchmarkScenario, o as KnowledgeBenchmarkSliceSummary, p as KnowledgeBenchmarkSource, q as KnowledgeBenchmarkSpec, r as KnowledgeBenchmarkSplit, s as KnowledgeBenchmarkTaskKind, t as KnowledgeClaimMatcher, u as KnowledgeMemoryBenchmarkCase, v as KnowledgeMemoryBenchmarkTaskKind, w as KnowledgeMemoryEvent, x as KnowledgeMemoryFactMatcher, y as KnowledgeRetrievalBenchmarkCase, z as KnowledgeRetrievalBenchmarkQrel, A as KnowledgeRetrievalBenchmarkQuery, M as MemoryAdapterBenchmarkCandidate, C as MemoryAdapterBenchmarkRankingRow, V as RunKnowledgeBenchmarkSuiteOptions, W as RunKnowledgeBenchmarkSuiteResult, X as RunMemoryAdapterBenchmarkOptions, Y as RunMemoryAdapterBenchmarkResult, Z as buildFirstPartyMemoryLifecycleBenchmarkCases, _ as buildIndustryMemoryBenchmarkSmokeCases, $ as buildIndustryRagBenchmarkSmokeCases, a0 as buildKnowledgeBenchmarkScenarios, a1 as buildRetrievalBenchmarkCasesFromQrels, a4 as createInMemoryBenchmarkAdapter, a5 as createMemoryAdapterBenchmarkResponder, a6 as createNoopMemoryBenchmarkAdapter, a7 as isKnowledgeMemoryBenchmarkCase, a8 as knowledgeBenchmarkJudge, a9 as parseKnowledgeBenchmarkJsonl, aa as parseKnowledgeBenchmarkQrels, ab as renderKnowledgeBenchmarkReportMarkdown, ac as respondToIndustryMemoryBenchmarkSmokeCase, ad as respondToIndustryRagBenchmarkSmokeCase, ai as runKnowledgeBenchmarkSuite, aj as runMemoryAdapterBenchmark, al as scoreKnowledgeBenchmarkArtifact, am as scoreMemoryBenchmarkArtifact, ao as summarizeKnowledgeBenchmarkCampaign } from '../index-BHQk7jOT.js';
|
|
4
|
+
import '../types-6x0OpfW6.js';
|
|
5
5
|
import '@tangle-network/agent-eval/rl';
|
|
@@ -49,6 +49,94 @@ function anchorsForText(uri, text) {
|
|
|
49
49
|
return anchors;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
// src/wikilinks.ts
|
|
53
|
+
var WIKILINK_REGEX = /\[\[([^\]|]+?)(?:\|[^\]]+?)?\]\]/g;
|
|
54
|
+
function extractWikilinks(content) {
|
|
55
|
+
const links = [];
|
|
56
|
+
const regex = new RegExp(WIKILINK_REGEX.source, "g");
|
|
57
|
+
let match;
|
|
58
|
+
match = regex.exec(content);
|
|
59
|
+
while (match !== null) {
|
|
60
|
+
links.push(match[1].trim());
|
|
61
|
+
match = regex.exec(content);
|
|
62
|
+
}
|
|
63
|
+
return [...new Set(links)];
|
|
64
|
+
}
|
|
65
|
+
function normalizeLinkTarget(target) {
|
|
66
|
+
return target.trim().replace(/\.md$/i, "").toLowerCase().replace(/\s+/g, "-");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/graph.ts
|
|
70
|
+
function buildKnowledgeGraph(pages) {
|
|
71
|
+
const byId = /* @__PURE__ */ new Map();
|
|
72
|
+
const bySlug = /* @__PURE__ */ new Map();
|
|
73
|
+
for (const page of pages) {
|
|
74
|
+
byId.set(page.id, page);
|
|
75
|
+
bySlug.set(normalizeLinkTarget(page.id), page);
|
|
76
|
+
bySlug.set(normalizeLinkTarget(page.title), page);
|
|
77
|
+
bySlug.set(normalizeLinkTarget(page.path.split("/").pop().replace(/\.md$/, "")), page);
|
|
78
|
+
}
|
|
79
|
+
const incoming = /* @__PURE__ */ new Map();
|
|
80
|
+
const outgoing = /* @__PURE__ */ new Map();
|
|
81
|
+
const edgesByKey = /* @__PURE__ */ new Map();
|
|
82
|
+
for (const page of pages) {
|
|
83
|
+
outgoing.set(page.id, 0);
|
|
84
|
+
incoming.set(page.id, 0);
|
|
85
|
+
}
|
|
86
|
+
for (const page of pages) {
|
|
87
|
+
for (const raw of page.outLinks) {
|
|
88
|
+
const target = bySlug.get(normalizeLinkTarget(raw));
|
|
89
|
+
if (!target || target.id === page.id) continue;
|
|
90
|
+
const key = `${page.id}->${target.id}`;
|
|
91
|
+
const edge = edgesByKey.get(key);
|
|
92
|
+
if (edge) edge.weight += 1;
|
|
93
|
+
else
|
|
94
|
+
edgesByKey.set(key, {
|
|
95
|
+
source: page.id,
|
|
96
|
+
target: target.id,
|
|
97
|
+
weight: 1,
|
|
98
|
+
reasons: ["wikilink"]
|
|
99
|
+
});
|
|
100
|
+
outgoing.set(page.id, (outgoing.get(page.id) ?? 0) + 1);
|
|
101
|
+
incoming.set(target.id, (incoming.get(target.id) ?? 0) + 1);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
addSourceOverlapEdges(pages, edgesByKey);
|
|
105
|
+
const nodes = pages.map((page) => ({
|
|
106
|
+
id: page.id,
|
|
107
|
+
title: page.title,
|
|
108
|
+
path: page.path,
|
|
109
|
+
tags: page.tags,
|
|
110
|
+
sourceIds: page.sourceIds,
|
|
111
|
+
outDegree: outgoing.get(page.id) ?? 0,
|
|
112
|
+
inDegree: incoming.get(page.id) ?? 0
|
|
113
|
+
}));
|
|
114
|
+
return { nodes, edges: [...edgesByKey.values()].sort((a, b) => b.weight - a.weight) };
|
|
115
|
+
}
|
|
116
|
+
function addSourceOverlapEdges(pages, edges) {
|
|
117
|
+
for (let i = 0; i < pages.length; i++) {
|
|
118
|
+
for (let j = i + 1; j < pages.length; j++) {
|
|
119
|
+
const a = pages[i];
|
|
120
|
+
const b = pages[j];
|
|
121
|
+
const overlap = a.sourceIds.filter((source) => b.sourceIds.includes(source));
|
|
122
|
+
if (overlap.length === 0) continue;
|
|
123
|
+
const key = `${a.id}->${b.id}`;
|
|
124
|
+
const edge = edges.get(key);
|
|
125
|
+
if (edge) {
|
|
126
|
+
edge.weight += overlap.length * 0.5;
|
|
127
|
+
edge.reasons.push("shared-source");
|
|
128
|
+
} else {
|
|
129
|
+
edges.set(key, {
|
|
130
|
+
source: a.id,
|
|
131
|
+
target: b.id,
|
|
132
|
+
weight: overlap.length * 0.5,
|
|
133
|
+
reasons: ["shared-source"]
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
52
140
|
// src/mutation-lock.ts
|
|
53
141
|
import { AsyncLocalStorage } from "async_hooks";
|
|
54
142
|
import { mkdir as mkdir2, readFile } from "fs/promises";
|
|
@@ -341,7 +429,6 @@ var transactionEntrySchema = z.object({
|
|
|
341
429
|
afterMode: fileModeSchema.optional()
|
|
342
430
|
}).strict();
|
|
343
431
|
var transactionSchema = z.object({
|
|
344
|
-
schemaVersion: z.literal(1),
|
|
345
432
|
kind: z.literal("knowledge-file-transaction"),
|
|
346
433
|
transactionId: z.string().uuid(),
|
|
347
434
|
purpose: z.string().min(1),
|
|
@@ -349,7 +436,6 @@ var transactionSchema = z.object({
|
|
|
349
436
|
entries: z.array(transactionEntrySchema).min(1)
|
|
350
437
|
}).strict();
|
|
351
438
|
var transactionDirectionSchema = z.object({
|
|
352
|
-
schemaVersion: z.literal(1),
|
|
353
439
|
transactionId: z.string().uuid(),
|
|
354
440
|
direction: z.literal("rollback")
|
|
355
441
|
}).strict();
|
|
@@ -418,7 +504,6 @@ async function prepareKnowledgeFileTransaction(input) {
|
|
|
418
504
|
}
|
|
419
505
|
}
|
|
420
506
|
const transaction = transactionSchema.parse({
|
|
421
|
-
schemaVersion: 1,
|
|
422
507
|
kind: "knowledge-file-transaction",
|
|
423
508
|
transactionId: randomUUID2(),
|
|
424
509
|
purpose: input.purpose,
|
|
@@ -607,7 +692,6 @@ async function rollbackKnowledgeFileTransaction(input) {
|
|
|
607
692
|
const direction = await readTransactionDirection(transactionDir, transaction);
|
|
608
693
|
if (direction !== "rollback") {
|
|
609
694
|
await writeJsonDurable(join(transactionDir, "direction.json"), {
|
|
610
|
-
schemaVersion: 1,
|
|
611
695
|
transactionId: transaction.transactionId,
|
|
612
696
|
direction: "rollback"
|
|
613
697
|
});
|
|
@@ -1097,156 +1181,6 @@ function isOdd(value) {
|
|
|
1097
1181
|
return value % 2 === 1;
|
|
1098
1182
|
}
|
|
1099
1183
|
|
|
1100
|
-
// src/frontmatter.ts
|
|
1101
|
-
function parseFrontmatter(content) {
|
|
1102
|
-
const normalized = content.replace(/\r\n/g, "\n");
|
|
1103
|
-
if (!normalized.startsWith("---\n")) return { frontmatter: {}, body: normalized };
|
|
1104
|
-
const end = normalized.indexOf("\n---", 4);
|
|
1105
|
-
if (end < 0) return { frontmatter: {}, body: normalized };
|
|
1106
|
-
const raw = normalized.slice(4, end);
|
|
1107
|
-
const after = normalized.slice(end).replace(/^\n---\s*\n?/, "");
|
|
1108
|
-
return { frontmatter: parseSimpleYaml(raw), body: after };
|
|
1109
|
-
}
|
|
1110
|
-
function formatFrontmatter(frontmatter, body) {
|
|
1111
|
-
const lines = Object.entries(frontmatter).filter(([, value]) => value !== void 0).flatMap(([key, value]) => formatYamlField(key, value));
|
|
1112
|
-
if (lines.length === 0) return body;
|
|
1113
|
-
return `---
|
|
1114
|
-
${lines.join("\n")}
|
|
1115
|
-
---
|
|
1116
|
-
${body.replace(/^\n+/, "")}`;
|
|
1117
|
-
}
|
|
1118
|
-
function parseSimpleYaml(raw) {
|
|
1119
|
-
const out = {};
|
|
1120
|
-
const lines = raw.split("\n");
|
|
1121
|
-
for (let i = 0; i < lines.length; i++) {
|
|
1122
|
-
const line = lines[i];
|
|
1123
|
-
const scalar = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(line);
|
|
1124
|
-
if (!scalar) continue;
|
|
1125
|
-
const key = scalar[1];
|
|
1126
|
-
const rest = scalar[2].trim();
|
|
1127
|
-
if (rest === "") {
|
|
1128
|
-
const items = [];
|
|
1129
|
-
while (i + 1 < lines.length) {
|
|
1130
|
-
const item = /^\s*-\s*(.+?)\s*$/.exec(lines[i + 1]);
|
|
1131
|
-
if (!item) break;
|
|
1132
|
-
items.push(unquote(item[1]));
|
|
1133
|
-
i++;
|
|
1134
|
-
}
|
|
1135
|
-
out[key] = items;
|
|
1136
|
-
continue;
|
|
1137
|
-
}
|
|
1138
|
-
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
1139
|
-
out[key] = rest.slice(1, -1).split(",").map((part) => unquote(part.trim())).filter(Boolean);
|
|
1140
|
-
} else if (rest === "true" || rest === "false") {
|
|
1141
|
-
out[key] = rest === "true";
|
|
1142
|
-
} else if (/^-?\d+(?:\.\d+)?$/.test(rest)) {
|
|
1143
|
-
out[key] = Number(rest);
|
|
1144
|
-
} else {
|
|
1145
|
-
out[key] = unquote(rest);
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
return out;
|
|
1149
|
-
}
|
|
1150
|
-
function formatYamlField(key, value) {
|
|
1151
|
-
if (Array.isArray(value)) {
|
|
1152
|
-
return [`${key}:`, ...value.map((item) => ` - ${String(item)}`)];
|
|
1153
|
-
}
|
|
1154
|
-
if (typeof value === "string") return [`${key}: ${value}`];
|
|
1155
|
-
if (typeof value === "number" || typeof value === "boolean") return [`${key}: ${String(value)}`];
|
|
1156
|
-
return [`${key}: ${JSON.stringify(value)}`];
|
|
1157
|
-
}
|
|
1158
|
-
function unquote(value) {
|
|
1159
|
-
return value.replace(/^['"]|['"]$/g, "");
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
// src/wikilinks.ts
|
|
1163
|
-
var WIKILINK_REGEX = /\[\[([^\]|]+?)(?:\|[^\]]+?)?\]\]/g;
|
|
1164
|
-
function extractWikilinks(content) {
|
|
1165
|
-
const links = [];
|
|
1166
|
-
const regex = new RegExp(WIKILINK_REGEX.source, "g");
|
|
1167
|
-
let match;
|
|
1168
|
-
match = regex.exec(content);
|
|
1169
|
-
while (match !== null) {
|
|
1170
|
-
links.push(match[1].trim());
|
|
1171
|
-
match = regex.exec(content);
|
|
1172
|
-
}
|
|
1173
|
-
return [...new Set(links)];
|
|
1174
|
-
}
|
|
1175
|
-
function normalizeLinkTarget(target) {
|
|
1176
|
-
return target.trim().replace(/\.md$/i, "").toLowerCase().replace(/\s+/g, "-");
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
// src/graph.ts
|
|
1180
|
-
function buildKnowledgeGraph(pages) {
|
|
1181
|
-
const byId = /* @__PURE__ */ new Map();
|
|
1182
|
-
const bySlug = /* @__PURE__ */ new Map();
|
|
1183
|
-
for (const page of pages) {
|
|
1184
|
-
byId.set(page.id, page);
|
|
1185
|
-
bySlug.set(normalizeLinkTarget(page.id), page);
|
|
1186
|
-
bySlug.set(normalizeLinkTarget(page.title), page);
|
|
1187
|
-
bySlug.set(normalizeLinkTarget(page.path.split("/").pop().replace(/\.md$/, "")), page);
|
|
1188
|
-
}
|
|
1189
|
-
const incoming = /* @__PURE__ */ new Map();
|
|
1190
|
-
const outgoing = /* @__PURE__ */ new Map();
|
|
1191
|
-
const edgesByKey = /* @__PURE__ */ new Map();
|
|
1192
|
-
for (const page of pages) {
|
|
1193
|
-
outgoing.set(page.id, 0);
|
|
1194
|
-
incoming.set(page.id, 0);
|
|
1195
|
-
}
|
|
1196
|
-
for (const page of pages) {
|
|
1197
|
-
for (const raw of page.outLinks) {
|
|
1198
|
-
const target = bySlug.get(normalizeLinkTarget(raw));
|
|
1199
|
-
if (!target || target.id === page.id) continue;
|
|
1200
|
-
const key = `${page.id}->${target.id}`;
|
|
1201
|
-
const edge = edgesByKey.get(key);
|
|
1202
|
-
if (edge) edge.weight += 1;
|
|
1203
|
-
else
|
|
1204
|
-
edgesByKey.set(key, {
|
|
1205
|
-
source: page.id,
|
|
1206
|
-
target: target.id,
|
|
1207
|
-
weight: 1,
|
|
1208
|
-
reasons: ["wikilink"]
|
|
1209
|
-
});
|
|
1210
|
-
outgoing.set(page.id, (outgoing.get(page.id) ?? 0) + 1);
|
|
1211
|
-
incoming.set(target.id, (incoming.get(target.id) ?? 0) + 1);
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
addSourceOverlapEdges(pages, edgesByKey);
|
|
1215
|
-
const nodes = pages.map((page) => ({
|
|
1216
|
-
id: page.id,
|
|
1217
|
-
title: page.title,
|
|
1218
|
-
path: page.path,
|
|
1219
|
-
tags: page.tags,
|
|
1220
|
-
sourceIds: page.sourceIds,
|
|
1221
|
-
outDegree: outgoing.get(page.id) ?? 0,
|
|
1222
|
-
inDegree: incoming.get(page.id) ?? 0
|
|
1223
|
-
}));
|
|
1224
|
-
return { nodes, edges: [...edgesByKey.values()].sort((a, b) => b.weight - a.weight) };
|
|
1225
|
-
}
|
|
1226
|
-
function addSourceOverlapEdges(pages, edges) {
|
|
1227
|
-
for (let i = 0; i < pages.length; i++) {
|
|
1228
|
-
for (let j = i + 1; j < pages.length; j++) {
|
|
1229
|
-
const a = pages[i];
|
|
1230
|
-
const b = pages[j];
|
|
1231
|
-
const overlap = a.sourceIds.filter((source) => b.sourceIds.includes(source));
|
|
1232
|
-
if (overlap.length === 0) continue;
|
|
1233
|
-
const key = `${a.id}->${b.id}`;
|
|
1234
|
-
const edge = edges.get(key);
|
|
1235
|
-
if (edge) {
|
|
1236
|
-
edge.weight += overlap.length * 0.5;
|
|
1237
|
-
edge.reasons.push("shared-source");
|
|
1238
|
-
} else {
|
|
1239
|
-
edges.set(key, {
|
|
1240
|
-
source: a.id,
|
|
1241
|
-
target: b.id,
|
|
1242
|
-
weight: overlap.length * 0.5,
|
|
1243
|
-
reasons: ["shared-source"]
|
|
1244
|
-
});
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
1184
|
// src/schemas.ts
|
|
1251
1185
|
import { z as z2 } from "zod";
|
|
1252
1186
|
var SourceAnchorSchema = z2.object({
|
|
@@ -1370,6 +1304,68 @@ var KnowledgeBaseCandidateSchema = z2.object({
|
|
|
1370
1304
|
metadata: z2.record(z2.string(), z2.unknown()).optional()
|
|
1371
1305
|
});
|
|
1372
1306
|
|
|
1307
|
+
// src/frontmatter.ts
|
|
1308
|
+
function parseFrontmatter(content) {
|
|
1309
|
+
const normalized = content.replace(/\r\n/g, "\n");
|
|
1310
|
+
if (!normalized.startsWith("---\n")) return { frontmatter: {}, body: normalized };
|
|
1311
|
+
const end = normalized.indexOf("\n---", 4);
|
|
1312
|
+
if (end < 0) return { frontmatter: {}, body: normalized };
|
|
1313
|
+
const raw = normalized.slice(4, end);
|
|
1314
|
+
const after = normalized.slice(end).replace(/^\n---\s*\n?/, "");
|
|
1315
|
+
return { frontmatter: parseSimpleYaml(raw), body: after };
|
|
1316
|
+
}
|
|
1317
|
+
function formatFrontmatter(frontmatter, body) {
|
|
1318
|
+
const lines = Object.entries(frontmatter).filter(([, value]) => value !== void 0).flatMap(([key, value]) => formatYamlField(key, value));
|
|
1319
|
+
if (lines.length === 0) return body;
|
|
1320
|
+
return `---
|
|
1321
|
+
${lines.join("\n")}
|
|
1322
|
+
---
|
|
1323
|
+
${body.replace(/^\n+/, "")}`;
|
|
1324
|
+
}
|
|
1325
|
+
function parseSimpleYaml(raw) {
|
|
1326
|
+
const out = {};
|
|
1327
|
+
const lines = raw.split("\n");
|
|
1328
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1329
|
+
const line = lines[i];
|
|
1330
|
+
const scalar = /^([A-Za-z0-9_-]+):\s*(.*)$/.exec(line);
|
|
1331
|
+
if (!scalar) continue;
|
|
1332
|
+
const key = scalar[1];
|
|
1333
|
+
const rest = scalar[2].trim();
|
|
1334
|
+
if (rest === "") {
|
|
1335
|
+
const items = [];
|
|
1336
|
+
while (i + 1 < lines.length) {
|
|
1337
|
+
const item = /^\s*-\s*(.+?)\s*$/.exec(lines[i + 1]);
|
|
1338
|
+
if (!item) break;
|
|
1339
|
+
items.push(unquote(item[1]));
|
|
1340
|
+
i++;
|
|
1341
|
+
}
|
|
1342
|
+
out[key] = items;
|
|
1343
|
+
continue;
|
|
1344
|
+
}
|
|
1345
|
+
if (rest.startsWith("[") && rest.endsWith("]")) {
|
|
1346
|
+
out[key] = rest.slice(1, -1).split(",").map((part) => unquote(part.trim())).filter(Boolean);
|
|
1347
|
+
} else if (rest === "true" || rest === "false") {
|
|
1348
|
+
out[key] = rest === "true";
|
|
1349
|
+
} else if (/^-?\d+(?:\.\d+)?$/.test(rest)) {
|
|
1350
|
+
out[key] = Number(rest);
|
|
1351
|
+
} else {
|
|
1352
|
+
out[key] = unquote(rest);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
return out;
|
|
1356
|
+
}
|
|
1357
|
+
function formatYamlField(key, value) {
|
|
1358
|
+
if (Array.isArray(value)) {
|
|
1359
|
+
return [`${key}:`, ...value.map((item) => ` - ${String(item)}`)];
|
|
1360
|
+
}
|
|
1361
|
+
if (typeof value === "string") return [`${key}: ${value}`];
|
|
1362
|
+
if (typeof value === "number" || typeof value === "boolean") return [`${key}: ${String(value)}`];
|
|
1363
|
+
return [`${key}: ${JSON.stringify(value)}`];
|
|
1364
|
+
}
|
|
1365
|
+
function unquote(value) {
|
|
1366
|
+
return value.replace(/^['"]|['"]$/g, "");
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1373
1369
|
// src/store.ts
|
|
1374
1370
|
import { join as join3 } from "path";
|
|
1375
1371
|
function layoutFor(root) {
|
|
@@ -1869,66 +1865,31 @@ function extractSourceRefs(text) {
|
|
|
1869
1865
|
return refs;
|
|
1870
1866
|
}
|
|
1871
1867
|
|
|
1872
|
-
// src/
|
|
1873
|
-
function
|
|
1874
|
-
const
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
})),
|
|
1898
|
-
sourceFreshness,
|
|
1899
|
-
findings
|
|
1900
|
-
};
|
|
1901
|
-
}
|
|
1902
|
-
function inspectSourceFreshness(source, now) {
|
|
1903
|
-
const validUntil = source.validUntil ?? stringMetadata(source.metadata, "validUntil") ?? stringMetadata(source.metadata, "expiresAt");
|
|
1904
|
-
const lastVerifiedAt = source.lastVerifiedAt ?? stringMetadata(source.metadata, "lastVerifiedAt");
|
|
1905
|
-
const status = validUntil && Number.isFinite(Date.parse(validUntil)) ? Date.parse(validUntil) <= now.getTime() ? "expired" : "fresh" : "unknown";
|
|
1906
|
-
return { id: source.id, title: source.title, uri: source.uri, status, validUntil, lastVerifiedAt };
|
|
1907
|
-
}
|
|
1908
|
-
function explainKnowledgeTarget(index, target) {
|
|
1909
|
-
const page = index.pages.find(
|
|
1910
|
-
(candidate) => candidate.path === target || candidate.id === target || candidate.title.toLowerCase() === target.toLowerCase()
|
|
1911
|
-
);
|
|
1912
|
-
const inbound = page ? index.graph.edges.filter((edge) => edge.target === page.id).map(
|
|
1913
|
-
(edge) => index.pages.find((candidate) => candidate.id === edge.source)?.path ?? edge.source
|
|
1914
|
-
) : [];
|
|
1915
|
-
const related = page ? searchKnowledge(index, `${page.title} ${page.tags.join(" ")}`, 6).filter((result) => result.page.id !== page.id).map((result) => ({
|
|
1916
|
-
path: result.page.path,
|
|
1917
|
-
title: result.page.title,
|
|
1918
|
-
score: result.score
|
|
1919
|
-
})) : searchKnowledge(index, target, 6).map((result) => ({
|
|
1920
|
-
path: result.page.path,
|
|
1921
|
-
title: result.page.title,
|
|
1922
|
-
score: result.score
|
|
1923
|
-
}));
|
|
1924
|
-
return {
|
|
1925
|
-
target,
|
|
1926
|
-
page,
|
|
1927
|
-
sources: page ? index.sources.filter((source) => page.sourceIds.includes(source.id)).map((source) => ({ id: source.id, title: source.title, uri: source.uri })) : [],
|
|
1928
|
-
links: page?.outLinks ?? [],
|
|
1929
|
-
inbound,
|
|
1930
|
-
related
|
|
1931
|
-
};
|
|
1868
|
+
// src/validate.ts
|
|
1869
|
+
function validateKnowledgeIndex(index, options = {}) {
|
|
1870
|
+
const findings = [...lintKnowledgeIndex(index)];
|
|
1871
|
+
const parsed = KnowledgeIndexSchema.safeParse(index);
|
|
1872
|
+
if (!parsed.success) {
|
|
1873
|
+
findings.push({
|
|
1874
|
+
type: "missing-frontmatter",
|
|
1875
|
+
severity: "error",
|
|
1876
|
+
message: parsed.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ")
|
|
1877
|
+
});
|
|
1878
|
+
}
|
|
1879
|
+
if (options.strict) {
|
|
1880
|
+
for (const page of index.pages) {
|
|
1881
|
+
if (isScaffoldPath(page.path)) continue;
|
|
1882
|
+
if (!page.frontmatter.id || !page.frontmatter.title) {
|
|
1883
|
+
findings.push({
|
|
1884
|
+
type: "missing-frontmatter",
|
|
1885
|
+
severity: "error",
|
|
1886
|
+
page: page.path,
|
|
1887
|
+
message: "Strict mode requires id and title frontmatter."
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
return { ok: !findings.some((finding) => finding.severity === "error"), findings };
|
|
1932
1893
|
}
|
|
1933
1894
|
|
|
1934
1895
|
// src/write-protocol.ts
|
|
@@ -2031,37 +1992,71 @@ async function applyKnowledgeWriteBlocksFile(root, proposalPath) {
|
|
|
2031
1992
|
return applyKnowledgeWriteBlocks(root, await readFile3(proposalPath, "utf8"));
|
|
2032
1993
|
}
|
|
2033
1994
|
|
|
2034
|
-
// src/
|
|
2035
|
-
function
|
|
2036
|
-
const
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
1995
|
+
// src/metadata.ts
|
|
1996
|
+
function stringMetadata(metadata, key) {
|
|
1997
|
+
const value = metadata?.[key];
|
|
1998
|
+
return typeof value === "string" ? value : void 0;
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
// src/inspect.ts
|
|
2002
|
+
function inspectKnowledgeIndex(index, options = {}) {
|
|
2003
|
+
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
2004
|
+
const findings = lintKnowledgeIndex(index);
|
|
2005
|
+
const degree = new Map(index.graph.nodes.map((node) => [node.id, node.inDegree + node.outDegree]));
|
|
2006
|
+
const sourceFreshness = index.sources.map((source) => inspectSourceFreshness(source, now));
|
|
2007
|
+
return {
|
|
2008
|
+
pageCount: index.pages.length,
|
|
2009
|
+
sourceCount: index.sources.length,
|
|
2010
|
+
expiredSourceCount: sourceFreshness.filter((source) => source.status === "expired").length,
|
|
2011
|
+
staleSourceCount: sourceFreshness.filter((source) => source.status !== "fresh").length,
|
|
2012
|
+
edgeCount: index.graph.edges.length,
|
|
2013
|
+
findingCount: findings.length,
|
|
2014
|
+
blockingFindingCount: findings.filter((finding) => finding.severity === "error").length,
|
|
2015
|
+
topPages: [...index.pages].sort((a, b) => (degree.get(b.id) ?? 0) - (degree.get(a.id) ?? 0)).slice(0, 10).map((page) => ({
|
|
2016
|
+
path: page.path,
|
|
2017
|
+
title: page.title,
|
|
2018
|
+
degree: degree.get(page.id) ?? 0,
|
|
2019
|
+
sources: page.sourceIds.length
|
|
2020
|
+
})),
|
|
2021
|
+
sourceFreshness,
|
|
2022
|
+
findings
|
|
2023
|
+
};
|
|
2024
|
+
}
|
|
2025
|
+
function inspectSourceFreshness(source, now) {
|
|
2026
|
+
const validUntil = source.validUntil ?? stringMetadata(source.metadata, "validUntil") ?? stringMetadata(source.metadata, "expiresAt");
|
|
2027
|
+
const lastVerifiedAt = source.lastVerifiedAt ?? stringMetadata(source.metadata, "lastVerifiedAt");
|
|
2028
|
+
const status = validUntil && Number.isFinite(Date.parse(validUntil)) ? Date.parse(validUntil) <= now.getTime() ? "expired" : "fresh" : "unknown";
|
|
2029
|
+
return { id: source.id, title: source.title, uri: source.uri, status, validUntil, lastVerifiedAt };
|
|
2030
|
+
}
|
|
2031
|
+
function explainKnowledgeTarget(index, target) {
|
|
2032
|
+
const page = index.pages.find(
|
|
2033
|
+
(candidate) => candidate.path === target || candidate.id === target || candidate.title.toLowerCase() === target.toLowerCase()
|
|
2034
|
+
);
|
|
2035
|
+
const inbound = page ? index.graph.edges.filter((edge) => edge.target === page.id).map(
|
|
2036
|
+
(edge) => index.pages.find((candidate) => candidate.id === edge.source)?.path ?? edge.source
|
|
2037
|
+
) : [];
|
|
2038
|
+
const related = page ? searchKnowledge(index, `${page.title} ${page.tags.join(" ")}`, 6).filter((result) => result.page.id !== page.id).map((result) => ({
|
|
2039
|
+
path: result.page.path,
|
|
2040
|
+
title: result.page.title,
|
|
2041
|
+
score: result.score
|
|
2042
|
+
})) : searchKnowledge(index, target, 6).map((result) => ({
|
|
2043
|
+
path: result.page.path,
|
|
2044
|
+
title: result.page.title,
|
|
2045
|
+
score: result.score
|
|
2046
|
+
}));
|
|
2047
|
+
return {
|
|
2048
|
+
target,
|
|
2049
|
+
page,
|
|
2050
|
+
sources: page ? index.sources.filter((source) => page.sourceIds.includes(source.id)).map((source) => ({ id: source.id, title: source.title, uri: source.uri })) : [],
|
|
2051
|
+
links: page?.outLinks ?? [],
|
|
2052
|
+
inbound,
|
|
2053
|
+
related
|
|
2054
|
+
};
|
|
2059
2055
|
}
|
|
2060
2056
|
|
|
2061
2057
|
export {
|
|
2062
2058
|
textSourceAdapter,
|
|
2063
2059
|
mediaTypeFor,
|
|
2064
|
-
stringMetadata,
|
|
2065
2060
|
writeFileDurableWithinRoot,
|
|
2066
2061
|
writeJsonDurableWithinRoot,
|
|
2067
2062
|
renameDurable,
|
|
@@ -2075,17 +2070,15 @@ export {
|
|
|
2075
2070
|
finishKnowledgeFileTransaction,
|
|
2076
2071
|
rollbackKnowledgeFileTransaction,
|
|
2077
2072
|
assertKnowledgeMutationPath,
|
|
2073
|
+
WIKILINK_REGEX,
|
|
2074
|
+
extractWikilinks,
|
|
2075
|
+
normalizeLinkTarget,
|
|
2076
|
+
buildKnowledgeGraph,
|
|
2078
2077
|
withKnowledgeMutation,
|
|
2079
2078
|
inspectPendingKnowledgeMutation,
|
|
2080
2079
|
recoverPendingKnowledgeMutation,
|
|
2081
2080
|
withKnowledgeRead,
|
|
2082
2081
|
acquireDurableFileLock,
|
|
2083
|
-
parseFrontmatter,
|
|
2084
|
-
formatFrontmatter,
|
|
2085
|
-
WIKILINK_REGEX,
|
|
2086
|
-
extractWikilinks,
|
|
2087
|
-
normalizeLinkTarget,
|
|
2088
|
-
buildKnowledgeGraph,
|
|
2089
2082
|
SourceAnchorSchema,
|
|
2090
2083
|
SourceRecordSchema,
|
|
2091
2084
|
KnowledgePageSchema,
|
|
@@ -2094,6 +2087,8 @@ export {
|
|
|
2094
2087
|
KnowledgeIndexSchema,
|
|
2095
2088
|
KnowledgeEventSchema,
|
|
2096
2089
|
KnowledgeBaseCandidateSchema,
|
|
2090
|
+
parseFrontmatter,
|
|
2091
|
+
formatFrontmatter,
|
|
2097
2092
|
layoutFor,
|
|
2098
2093
|
SCAFFOLD_PAGE_BASENAMES,
|
|
2099
2094
|
isScaffoldPath,
|
|
@@ -2108,12 +2103,13 @@ export {
|
|
|
2108
2103
|
buildKnowledgeIndex,
|
|
2109
2104
|
writeKnowledgeIndex,
|
|
2110
2105
|
lintKnowledgeIndex,
|
|
2111
|
-
|
|
2112
|
-
explainKnowledgeTarget,
|
|
2106
|
+
validateKnowledgeIndex,
|
|
2113
2107
|
isSafeKnowledgePath,
|
|
2114
2108
|
parseKnowledgeWriteBlocks,
|
|
2115
2109
|
applyKnowledgeWriteBlocks,
|
|
2116
2110
|
applyKnowledgeWriteBlocksFile,
|
|
2117
|
-
|
|
2111
|
+
stringMetadata,
|
|
2112
|
+
inspectKnowledgeIndex,
|
|
2113
|
+
explainKnowledgeTarget
|
|
2118
2114
|
};
|
|
2119
|
-
//# sourceMappingURL=chunk-
|
|
2115
|
+
//# sourceMappingURL=chunk-2BJ5JR3L.js.map
|