@tangle-network/agent-knowledge 1.0.0 → 1.1.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 +51 -2
- package/dist/{chunk-WCUKMCAY.js → chunk-BEFAI2HO.js} +19 -3
- package/dist/chunk-BEFAI2HO.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +55 -4
- package/dist/index.js +85 -1
- package/dist/index.js.map +1 -1
- package/dist/{types-CFylueZb.d.ts → types-CWbf3JSE.d.ts} +16 -0
- package/dist/viz/index.d.ts +1 -1
- package/package.json +2 -2
- package/dist/chunk-WCUKMCAY.js.map +0 -1
package/README.md
CHANGED
|
@@ -34,13 +34,20 @@ The default layout is:
|
|
|
34
34
|
raw/
|
|
35
35
|
sources/
|
|
36
36
|
knowledge/
|
|
37
|
-
index.md
|
|
38
|
-
log.md
|
|
37
|
+
index.md # scaffold: human-navigation only, excluded from the page index
|
|
38
|
+
log.md # scaffold: human-navigation only, excluded from the page index
|
|
39
39
|
.agent-knowledge/
|
|
40
40
|
sources.json
|
|
41
41
|
index.json
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
`initKnowledgeBase` writes `knowledge/index.md` and `knowledge/log.md` for
|
|
45
|
+
authors to curate by hand. They are deliberately excluded from
|
|
46
|
+
`buildKnowledgeIndex` / `searchKnowledge` so they do not inflate page counts
|
|
47
|
+
or pollute search hits. Any nested `<dir>/index.md` or `<dir>/log.md` is
|
|
48
|
+
treated the same way. The shared predicate is `isScaffoldPath`, exported
|
|
49
|
+
from `@tangle-network/agent-knowledge`.
|
|
50
|
+
|
|
44
51
|
## Design
|
|
45
52
|
|
|
46
53
|
- Raw sources are immutable evidence.
|
|
@@ -53,7 +60,18 @@ knowledge/
|
|
|
53
60
|
- Discovery uses worker/dispatcher contracts, with a local dispatcher for dev and tests.
|
|
54
61
|
- Zod schemas define the stable wire shape.
|
|
55
62
|
- Graph/search/lint are deterministic and fast.
|
|
63
|
+
- `searchKnowledge` returns hits with three score fields. `score` and
|
|
64
|
+
`rrfScore` are the raw reciprocal-rank-fusion value (typically 0.01–0.05);
|
|
65
|
+
use them when intent matters or when fusing across queries.
|
|
66
|
+
`normalizedScore` is the same value scaled into [0, 1] relative to the top
|
|
67
|
+
hit *in this result set* (top hit = 1, others = score / topScore) — use it
|
|
68
|
+
when comparing against natural confidence thresholds. The normalization is
|
|
69
|
+
within-set ranking, not a cross-query absolute confidence.
|
|
56
70
|
- Optimization uses `@tangle-network/agent-eval` internally instead of reimplementing eval gates.
|
|
71
|
+
- `buildEvalKnowledgeBundle()` maps wiki/search evidence into
|
|
72
|
+
`agent-eval` `KnowledgeRequirement`, `KnowledgeBundle`, and
|
|
73
|
+
`KnowledgeReadinessReport` contracts so control loops can block, ask, or
|
|
74
|
+
acquire data before running an agent.
|
|
57
75
|
|
|
58
76
|
The `/viz` subpath exports graph insight helpers without UI dependencies.
|
|
59
77
|
|
|
@@ -62,3 +80,34 @@ The `/viz` subpath exports graph insight helpers without UI dependencies.
|
|
|
62
80
|
Use `runKnowledgeBaseOptimization()` when the question is whether a candidate knowledge base actually improves agent task success. The candidate is passed through `runMultiShotOptimization`, so `n=1` single-turn tasks and variable-length multi-turn traces use the same path.
|
|
63
81
|
|
|
64
82
|
Use `knowledgeReleaseReportFromOptimization()` to turn optimizer output into release confidence evidence using `agent-eval` release gates and `RunRecord` validation.
|
|
83
|
+
|
|
84
|
+
Use `buildEvalKnowledgeBundle()` before execution when the question is whether
|
|
85
|
+
the agent has enough task-world context to run:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { buildEvalKnowledgeBundle } from '@tangle-network/agent-knowledge'
|
|
89
|
+
|
|
90
|
+
const readiness = buildEvalKnowledgeBundle({
|
|
91
|
+
taskId: 'sdk-migration',
|
|
92
|
+
index,
|
|
93
|
+
specs: [{
|
|
94
|
+
id: 'repo-build-command',
|
|
95
|
+
description: 'Repository build and typecheck command',
|
|
96
|
+
query: 'build typecheck command',
|
|
97
|
+
requiredFor: ['coding'],
|
|
98
|
+
category: 'codebase_specific',
|
|
99
|
+
acquisitionMode: 'inspect_repo',
|
|
100
|
+
importance: 'blocking',
|
|
101
|
+
freshness: 'weekly',
|
|
102
|
+
sensitivity: 'public',
|
|
103
|
+
confidenceNeeded: 0.9,
|
|
104
|
+
minSources: 1,
|
|
105
|
+
}],
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
console.log(readiness.report.recommendedAction)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Pass `readiness.report` to `blockingKnowledgeEval()` from
|
|
112
|
+
`@tangle-network/agent-eval`; use `readiness.questions` and
|
|
113
|
+
`readiness.acquisitionPlans` to drive UI or connector workflows.
|
|
@@ -399,6 +399,15 @@ function layoutFor(root) {
|
|
|
399
399
|
cacheDir: join2(root, ".agent-knowledge")
|
|
400
400
|
};
|
|
401
401
|
}
|
|
402
|
+
var SCAFFOLD_PAGE_BASENAMES = ["index.md", "log.md"];
|
|
403
|
+
function isScaffoldPath(path) {
|
|
404
|
+
const normalized = path.replace(/\\/g, "/");
|
|
405
|
+
for (const basename2 of SCAFFOLD_PAGE_BASENAMES) {
|
|
406
|
+
if (normalized === `knowledge/${basename2}`) return true;
|
|
407
|
+
if (normalized.endsWith(`/${basename2}`)) return true;
|
|
408
|
+
}
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
402
411
|
async function initKnowledgeBase(root) {
|
|
403
412
|
const layout = layoutFor(root);
|
|
404
413
|
await mkdir2(layout.knowledgeDir, { recursive: true });
|
|
@@ -414,9 +423,10 @@ async function loadKnowledgePages(root) {
|
|
|
414
423
|
const files = await listMarkdownFiles(layout.knowledgeDir);
|
|
415
424
|
const pages = [];
|
|
416
425
|
for (const file of files) {
|
|
426
|
+
const rel = relative(root, file).replace(/\\/g, "/");
|
|
427
|
+
if (isScaffoldPath(rel)) continue;
|
|
417
428
|
const content = await readFile2(file, "utf8");
|
|
418
429
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
419
|
-
const rel = relative(root, file).replace(/\\/g, "/");
|
|
420
430
|
const title = stringField(frontmatter.title) ?? firstHeading(body) ?? rel.split("/").pop().replace(/\.md$/, "");
|
|
421
431
|
const sourceIds = arrayField(frontmatter.sources);
|
|
422
432
|
const tags = arrayField(frontmatter.tags);
|
|
@@ -580,9 +590,13 @@ function searchKnowledge(index, query, limit = 10) {
|
|
|
580
590
|
const graphRanked = rankByGraph(index.pages, tokenRanked);
|
|
581
591
|
const scores = reciprocalRankFusion([tokenRanked.map((p) => p.id), graphRanked.map((p) => p.id)]);
|
|
582
592
|
const byId = new Map(index.pages.map((page) => [page.id, page]));
|
|
583
|
-
|
|
593
|
+
const ranked = [...scores.entries()].map(([id, score]) => ({ page: byId.get(id), score })).filter((item) => Boolean(item.page)).sort((a, b) => b.score - a.score || a.page.path.localeCompare(b.page.path)).slice(0, limit);
|
|
594
|
+
const topScore = ranked[0]?.score ?? 0;
|
|
595
|
+
return ranked.map((item, i) => ({
|
|
584
596
|
page: item.page,
|
|
585
597
|
score: item.score,
|
|
598
|
+
rrfScore: item.score,
|
|
599
|
+
normalizedScore: topScore > 0 ? item.score / topScore : 0,
|
|
586
600
|
rank: i + 1,
|
|
587
601
|
snippet: buildSnippet(item.page.text, trimmed),
|
|
588
602
|
reasons: reasonsFor(item.page, trimmed)
|
|
@@ -843,6 +857,8 @@ export {
|
|
|
843
857
|
KnowledgeBaseCandidateSchema,
|
|
844
858
|
buildKnowledgeGraph,
|
|
845
859
|
layoutFor,
|
|
860
|
+
SCAFFOLD_PAGE_BASENAMES,
|
|
861
|
+
isScaffoldPath,
|
|
846
862
|
initKnowledgeBase,
|
|
847
863
|
loadKnowledgePages,
|
|
848
864
|
writeJson,
|
|
@@ -860,4 +876,4 @@ export {
|
|
|
860
876
|
explainKnowledgeTarget,
|
|
861
877
|
validateKnowledgeIndex
|
|
862
878
|
};
|
|
863
|
-
//# sourceMappingURL=chunk-
|
|
879
|
+
//# sourceMappingURL=chunk-BEFAI2HO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ids.ts","../src/frontmatter.ts","../src/wikilinks.ts","../src/write-protocol.ts","../src/adapters.ts","../src/proposals.ts","../src/schemas.ts","../src/graph.ts","../src/store.ts","../src/sources.ts","../src/search.ts","../src/indexer.ts","../src/lint.ts","../src/inspect.ts","../src/validate.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\n\nexport function sha256(text: string): string {\n return createHash('sha256').update(text).digest('hex')\n}\n\nexport function slugify(input: string): string {\n const out = input\n .trim()\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9\\u4e00-\\u9fff]+/g, '-')\n .replace(/^-+|-+$/g, '')\n return out || 'untitled'\n}\n\nexport function stableId(prefix: string, content: string): string {\n return `${prefix}_${sha256(content).slice(0, 16)}`\n}\n","export interface ParsedFrontmatter {\n frontmatter: Record<string, unknown>\n body: string\n}\n\nexport function parseFrontmatter(content: string): ParsedFrontmatter {\n const normalized = content.replace(/\\r\\n/g, '\\n')\n if (!normalized.startsWith('---\\n')) return { frontmatter: {}, body: normalized }\n const end = normalized.indexOf('\\n---', 4)\n if (end < 0) return { frontmatter: {}, body: normalized }\n const raw = normalized.slice(4, end)\n const after = normalized.slice(end).replace(/^\\n---\\s*\\n?/, '')\n return { frontmatter: parseSimpleYaml(raw), body: after }\n}\n\nexport function formatFrontmatter(frontmatter: Record<string, unknown>, body: string): string {\n const lines = Object.entries(frontmatter)\n .filter(([, value]) => value !== undefined)\n .flatMap(([key, value]) => formatYamlField(key, value))\n if (lines.length === 0) return body\n return `---\\n${lines.join('\\n')}\\n---\\n${body.replace(/^\\n+/, '')}`\n}\n\nfunction parseSimpleYaml(raw: string): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const lines = raw.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n const scalar = /^([A-Za-z0-9_-]+):\\s*(.*)$/.exec(line)\n if (!scalar) continue\n const key = scalar[1]!\n const rest = scalar[2]!.trim()\n if (rest === '') {\n const items: string[] = []\n while (i + 1 < lines.length) {\n const item = /^\\s*-\\s*(.+?)\\s*$/.exec(lines[i + 1]!)\n if (!item) break\n items.push(unquote(item[1]!))\n i++\n }\n out[key] = items\n continue\n }\n if (rest.startsWith('[') && rest.endsWith(']')) {\n out[key] = rest.slice(1, -1).split(',').map((part) => unquote(part.trim())).filter(Boolean)\n } else if (rest === 'true' || rest === 'false') {\n out[key] = rest === 'true'\n } else if (/^-?\\d+(?:\\.\\d+)?$/.test(rest)) {\n out[key] = Number(rest)\n } else {\n out[key] = unquote(rest)\n }\n }\n return out\n}\n\nfunction formatYamlField(key: string, value: unknown): string[] {\n if (Array.isArray(value)) {\n return [key + ':', ...value.map((item) => ` - ${String(item)}`)]\n }\n if (typeof value === 'string') return [`${key}: ${value}`]\n if (typeof value === 'number' || typeof value === 'boolean') return [`${key}: ${String(value)}`]\n return [`${key}: ${JSON.stringify(value)}`]\n}\n\nfunction unquote(value: string): string {\n return value.replace(/^['\"]|['\"]$/g, '')\n}\n","export const WIKILINK_REGEX = /\\[\\[([^\\]|]+?)(?:\\|[^\\]]+?)?\\]\\]/g\n\nexport function extractWikilinks(content: string): string[] {\n const links: string[] = []\n const regex = new RegExp(WIKILINK_REGEX.source, 'g')\n let match: RegExpExecArray | null\n while ((match = regex.exec(content)) !== null) {\n links.push(match[1]!.trim())\n }\n return [...new Set(links)]\n}\n\nexport function normalizeLinkTarget(target: string): string {\n return target.trim().replace(/\\.md$/i, '').toLowerCase().replace(/\\s+/g, '-')\n}\n","import type { KnowledgeWriteParseResult } from './types'\n\nconst OPENER_LINE = /^---\\s*FILE:\\s*(.+?)\\s*---\\s*$/i\nconst CLOSER_LINE = /^---\\s*END\\s+FILE\\s*---\\s*$/i\nconst FENCE_LINE = /^\\s{0,3}(```+|~~~+)/\n\nexport function isSafeKnowledgePath(path: string, allowedPrefixes = ['knowledge/']): boolean {\n if (typeof path !== 'string' || path.trim() === '') return false\n if (/[\\x00-\\x1f]/.test(path)) return false\n if (path.startsWith('/') || path.startsWith('\\\\')) return false\n if (/^[a-zA-Z]:/.test(path)) return false\n const normalized = path.replace(/\\\\/g, '/')\n if (normalized.split('/').some((part) => part === '..')) return false\n return allowedPrefixes.some((prefix) => normalized.startsWith(prefix))\n}\n\nexport function parseKnowledgeWriteBlocks(text: string, allowedPrefixes = ['knowledge/']): KnowledgeWriteParseResult {\n const lines = text.replace(/\\r\\n/g, '\\n').split('\\n')\n const blocks: KnowledgeWriteParseResult['blocks'] = []\n const warnings: string[] = []\n let i = 0\n\n while (i < lines.length) {\n const opener = OPENER_LINE.exec(lines[i]!)\n if (!opener) {\n i++\n continue\n }\n const path = opener[1]!.trim()\n i++\n const contentLines: string[] = []\n let fenceMarker: string | null = null\n let fenceLen = 0\n let closed = false\n\n while (i < lines.length) {\n const line = lines[i]!\n const fence = FENCE_LINE.exec(line)\n if (fence) {\n const run = fence[1]!\n const char = run[0]!\n if (fenceMarker === null) {\n fenceMarker = char\n fenceLen = run.length\n } else if (char === fenceMarker && run.length >= fenceLen) {\n fenceMarker = null\n fenceLen = 0\n }\n contentLines.push(line)\n i++\n continue\n }\n if (fenceMarker === null && CLOSER_LINE.test(line)) {\n closed = true\n i++\n break\n }\n contentLines.push(line)\n i++\n }\n\n if (!closed) {\n warnings.push(`FILE block \"${path || '(empty)'}\" was not closed before end of stream.`)\n continue\n }\n if (!isSafeKnowledgePath(path, allowedPrefixes)) {\n warnings.push(`FILE block with unsafe path \"${path}\" rejected.`)\n continue\n }\n blocks.push({ path, content: contentLines.join('\\n') })\n }\n\n return { blocks, warnings }\n}\n","import type { SourceRecord } from './types'\n\nexport interface SourceAdapterInput {\n uri: string\n bytes?: Uint8Array\n text?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface SourceAdapterOutput {\n title?: string\n mediaType?: string\n text?: string\n anchors?: SourceRecord['anchors']\n metadata?: Record<string, unknown>\n}\n\nexport interface SourceAdapter {\n id: string\n canLoad(input: SourceAdapterInput): boolean\n load(input: SourceAdapterInput): Promise<SourceAdapterOutput> | SourceAdapterOutput\n}\n\nexport const textSourceAdapter: SourceAdapter = {\n id: 'text',\n canLoad: (input) => Boolean(input.text) || /\\.(md|txt|json|csv)$/i.test(input.uri),\n load: (input) => ({\n title: input.uri.split('/').pop(),\n mediaType: mediaTypeFor(input.uri),\n text: decodeText(input),\n anchors: anchorsForText(input.uri, decodeText(input)),\n metadata: input.metadata,\n }),\n}\n\nexport function mediaTypeFor(uri: string): string {\n const lower = uri.toLowerCase()\n if (lower.endsWith('.md')) return 'text/markdown'\n if (lower.endsWith('.txt')) return 'text/plain'\n if (lower.endsWith('.json')) return 'application/json'\n if (lower.endsWith('.csv')) return 'text/csv'\n if (lower.endsWith('.pdf')) return 'application/pdf'\n return 'application/octet-stream'\n}\n\nfunction decodeText(input: SourceAdapterInput): string | undefined {\n return input.text ?? (input.bytes ? new TextDecoder().decode(input.bytes).slice(0, 200_000) : undefined)\n}\n\nfunction anchorsForText(uri: string, text: string | undefined): SourceAdapterOutput['anchors'] {\n if (!text) return []\n const lines = text.split('\\n')\n const anchors: NonNullable<SourceAdapterOutput['anchors']> = [{ id: 'all', sourceId: '', label: 'Full source', lineStart: 1, lineEnd: lines.length }]\n for (let i = 0; i < lines.length; i += 50) {\n anchors.push({\n id: `l${i + 1}`,\n sourceId: '',\n label: `${uri}:${i + 1}`,\n lineStart: i + 1,\n lineEnd: Math.min(lines.length, i + 50),\n })\n }\n return anchors\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { parseKnowledgeWriteBlocks } from './write-protocol'\n\nexport interface ApplyWriteBlocksResult {\n written: string[]\n warnings: string[]\n}\n\nexport async function applyKnowledgeWriteBlocks(\n root: string,\n proposalText: string,\n): Promise<ApplyWriteBlocksResult> {\n const parsed = parseKnowledgeWriteBlocks(proposalText)\n const written: string[] = []\n for (const block of parsed.blocks) {\n const path = join(root, block.path)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, block.content.endsWith('\\n') ? block.content : `${block.content}\\n`, 'utf8')\n written.push(block.path)\n }\n return { written, warnings: parsed.warnings }\n}\n\nexport async function applyKnowledgeWriteBlocksFile(root: string, proposalPath: string): Promise<ApplyWriteBlocksResult> {\n return applyKnowledgeWriteBlocks(root, await readFile(proposalPath, 'utf8'))\n}\n","import { z } from 'zod'\n\nexport const SourceAnchorSchema = z.object({\n id: z.string().min(1),\n sourceId: z.string().min(1),\n label: z.string().optional(),\n page: z.number().int().positive().optional(),\n lineStart: z.number().int().positive().optional(),\n lineEnd: z.number().int().positive().optional(),\n charStart: z.number().int().nonnegative().optional(),\n charEnd: z.number().int().nonnegative().optional(),\n timestampMs: z.number().nonnegative().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const SourceRecordSchema = z.object({\n id: z.string().min(1),\n uri: z.string().min(1),\n title: z.string().optional(),\n mediaType: z.string().optional(),\n contentHash: z.string().min(16),\n text: z.string().optional(),\n anchors: z.array(SourceAnchorSchema).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n createdAt: z.string().min(1),\n})\n\nexport const KnowledgePageSchema = z.object({\n id: z.string().min(1),\n path: z.string().min(1),\n title: z.string().min(1),\n text: z.string(),\n frontmatter: z.record(z.string(), z.unknown()),\n sourceIds: z.array(z.string()),\n tags: z.array(z.string()),\n outLinks: z.array(z.string()),\n})\n\nexport const KnowledgeGraphNodeSchema = z.object({\n id: z.string(),\n title: z.string(),\n path: z.string(),\n tags: z.array(z.string()),\n sourceIds: z.array(z.string()),\n outDegree: z.number().int().nonnegative(),\n inDegree: z.number().int().nonnegative(),\n})\n\nexport const KnowledgeGraphEdgeSchema = z.object({\n source: z.string(),\n target: z.string(),\n weight: z.number(),\n reasons: z.array(z.string()),\n})\n\nexport const KnowledgeIndexSchema = z.object({\n root: z.string(),\n generatedAt: z.string(),\n sources: z.array(SourceRecordSchema),\n pages: z.array(KnowledgePageSchema),\n graph: z.object({\n nodes: z.array(KnowledgeGraphNodeSchema),\n edges: z.array(KnowledgeGraphEdgeSchema),\n }),\n})\n\nexport const KnowledgeEventSchema = z.object({\n id: z.string().min(1),\n type: z.enum(['source.added', 'proposal.applied', 'index.built', 'lint.run', 'optimization.run', 'release.promoted', 'release.rejected']),\n createdAt: z.string().min(1),\n actor: z.string().optional(),\n target: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const KnowledgeBaseCandidateSchema = z.object({\n id: z.string().min(1),\n units: z.array(z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n text: z.string(),\n claims: z.array(z.object({\n id: z.string().min(1),\n text: z.string().min(1),\n refs: z.array(z.object({\n sourceId: z.string().min(1),\n anchorId: z.string().optional(),\n quote: z.string().optional(),\n })),\n confidence: z.number().min(0).max(1).optional(),\n status: z.enum(['draft', 'active', 'superseded', 'rejected']).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n })).optional(),\n relations: z.array(z.object({\n sourceId: z.string(),\n targetId: z.string(),\n predicate: z.string(),\n weight: z.number().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n })).optional(),\n sourceIds: z.array(z.string()).optional(),\n tags: z.array(z.string()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n updatedAt: z.string().optional(),\n })),\n retrievalPolicy: z.string().optional(),\n synthesisPolicy: z.string().optional(),\n questionPolicy: z.string().optional(),\n updatePolicy: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n","import type { KnowledgeGraph, KnowledgeGraphEdge, KnowledgeGraphNode, KnowledgePage } from './types'\nimport { normalizeLinkTarget } from './wikilinks'\n\nexport function buildKnowledgeGraph(pages: KnowledgePage[]): KnowledgeGraph {\n const byId = new Map<string, KnowledgePage>()\n const bySlug = new Map<string, KnowledgePage>()\n for (const page of pages) {\n byId.set(page.id, page)\n bySlug.set(normalizeLinkTarget(page.id), page)\n bySlug.set(normalizeLinkTarget(page.title), page)\n bySlug.set(normalizeLinkTarget(page.path.split('/').pop()!.replace(/\\.md$/, '')), page)\n }\n\n const incoming = new Map<string, number>()\n const outgoing = new Map<string, number>()\n const edgesByKey = new Map<string, KnowledgeGraphEdge>()\n for (const page of pages) {\n outgoing.set(page.id, 0)\n incoming.set(page.id, 0)\n }\n\n for (const page of pages) {\n for (const raw of page.outLinks) {\n const target = bySlug.get(normalizeLinkTarget(raw))\n if (!target || target.id === page.id) continue\n const key = `${page.id}->${target.id}`\n const edge = edgesByKey.get(key)\n if (edge) edge.weight += 1\n else edgesByKey.set(key, { source: page.id, target: target.id, weight: 1, reasons: ['wikilink'] })\n outgoing.set(page.id, (outgoing.get(page.id) ?? 0) + 1)\n incoming.set(target.id, (incoming.get(target.id) ?? 0) + 1)\n }\n }\n\n addSourceOverlapEdges(pages, edgesByKey)\n\n const nodes: KnowledgeGraphNode[] = pages.map((page) => ({\n id: page.id,\n title: page.title,\n path: page.path,\n tags: page.tags,\n sourceIds: page.sourceIds,\n outDegree: outgoing.get(page.id) ?? 0,\n inDegree: incoming.get(page.id) ?? 0,\n }))\n return { nodes, edges: [...edgesByKey.values()].sort((a, b) => b.weight - a.weight) }\n}\n\nfunction addSourceOverlapEdges(pages: KnowledgePage[], edges: Map<string, KnowledgeGraphEdge>): void {\n for (let i = 0; i < pages.length; i++) {\n for (let j = i + 1; j < pages.length; j++) {\n const a = pages[i]!\n const b = pages[j]!\n const overlap = a.sourceIds.filter((source) => b.sourceIds.includes(source))\n if (overlap.length === 0) continue\n const key = `${a.id}->${b.id}`\n const edge = edges.get(key)\n if (edge) {\n edge.weight += overlap.length * 0.5\n edge.reasons.push('shared-source')\n } else {\n edges.set(key, {\n source: a.id,\n target: b.id,\n weight: overlap.length * 0.5,\n reasons: ['shared-source'],\n })\n }\n }\n }\n}\n","import { mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises'\nimport { dirname, join, relative } from 'node:path'\nimport type { KnowledgePage } from './types'\nimport { parseFrontmatter } from './frontmatter'\nimport { slugify } from './ids'\nimport { extractWikilinks, normalizeLinkTarget } from './wikilinks'\n\nexport interface KnowledgeLayout {\n root: string\n knowledgeDir: string\n rawSourcesDir: string\n sourceRegistryPath: string\n indexPath: string\n logPath: string\n cacheDir: string\n}\n\nexport function layoutFor(root: string): KnowledgeLayout {\n return {\n root,\n knowledgeDir: join(root, 'knowledge'),\n rawSourcesDir: join(root, 'raw', 'sources'),\n sourceRegistryPath: join(root, '.agent-knowledge', 'sources.json'),\n indexPath: join(root, 'knowledge', 'index.md'),\n logPath: join(root, 'knowledge', 'log.md'),\n cacheDir: join(root, '.agent-knowledge'),\n }\n}\n\n/**\n * Filenames that `initKnowledgeBase` writes as human-navigation scaffolding.\n * These are excluded from the page index — they exist on disk so authors can\n * curate their vault, but they are not searchable content.\n *\n * Add new scaffold filenames here (and only here) to keep lint, validate, viz,\n * and the indexer consistent.\n */\nexport const SCAFFOLD_PAGE_BASENAMES: readonly string[] = ['index.md', 'log.md']\n\n/**\n * True when a knowledge-relative path points at a scaffold file rather than\n * authored content. Accepts both repo-relative paths (`knowledge/index.md`)\n * and any nested `<dir>/index.md` or `<dir>/log.md` (for example\n * `knowledge/concepts/index.md`) so subdirectory README-style scaffolds are\n * also excluded.\n */\nexport function isScaffoldPath(path: string): boolean {\n const normalized = path.replace(/\\\\/g, '/')\n for (const basename of SCAFFOLD_PAGE_BASENAMES) {\n if (normalized === `knowledge/${basename}`) return true\n if (normalized.endsWith(`/${basename}`)) return true\n }\n return false\n}\n\nexport async function initKnowledgeBase(root: string): Promise<KnowledgeLayout> {\n const layout = layoutFor(root)\n await mkdir(layout.knowledgeDir, { recursive: true })\n await mkdir(layout.rawSourcesDir, { recursive: true })\n await mkdir(layout.cacheDir, { recursive: true })\n await writeIfMissing(layout.indexPath, '# Knowledge Index\\n\\n')\n await writeIfMissing(layout.logPath, '# Knowledge Log\\n\\n')\n await writeIfMissing(layout.sourceRegistryPath, '{\\n \"generatedAt\": \"1970-01-01T00:00:00.000Z\",\\n \"sources\": []\\n}\\n')\n return layout\n}\n\nexport async function loadKnowledgePages(root: string): Promise<KnowledgePage[]> {\n const layout = layoutFor(root)\n const files = await listMarkdownFiles(layout.knowledgeDir)\n const pages: KnowledgePage[] = []\n for (const file of files) {\n const rel = relative(root, file).replace(/\\\\/g, '/')\n if (isScaffoldPath(rel)) continue\n const content = await readFile(file, 'utf8')\n const { frontmatter, body } = parseFrontmatter(content)\n const title = stringField(frontmatter.title) ?? firstHeading(body) ?? rel.split('/').pop()!.replace(/\\.md$/, '')\n const sourceIds = arrayField(frontmatter.sources)\n const tags = arrayField(frontmatter.tags)\n pages.push({\n id: stringField(frontmatter.id) ?? slugify(rel.replace(/^knowledge\\//, '').replace(/\\.md$/, '')),\n path: rel,\n title,\n text: body,\n frontmatter,\n sourceIds,\n tags,\n outLinks: extractWikilinks(body).map(normalizeLinkTarget),\n })\n }\n pages.sort((a, b) => a.path.localeCompare(b.path))\n return pages\n}\n\nexport async function writeJson(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(value, null, 2) + '\\n', 'utf8')\n}\n\nasync function writeIfMissing(path: string, content: string): Promise<void> {\n try {\n await stat(path)\n } catch {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, content, 'utf8')\n }\n}\n\nasync function listMarkdownFiles(root: string): Promise<string[]> {\n try {\n const entries = await readdir(root, { withFileTypes: true })\n const out: string[] = []\n for (const entry of entries) {\n const full = join(root, entry.name)\n if (entry.isDirectory()) out.push(...await listMarkdownFiles(full))\n else if (entry.isFile() && entry.name.endsWith('.md')) out.push(full)\n }\n return out\n } catch {\n return []\n }\n}\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined\n}\n\nfunction arrayField(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : []\n}\n\nfunction firstHeading(body: string): string | undefined {\n return /^#\\s+(.+)$/m.exec(body)?.[1]?.trim()\n}\n","import { copyFile, mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises'\nimport { basename, dirname, join, relative } from 'node:path'\nimport { textSourceAdapter, type SourceAdapter } from './adapters'\nimport type { SourceRecord, SourceRegistry } from './types'\nimport { sha256, slugify, stableId } from './ids'\nimport { layoutFor } from './store'\n\nexport interface AddSourceOptions {\n copyIntoRaw?: boolean\n adapters?: SourceAdapter[]\n now?: () => Date\n}\n\nexport async function loadSourceRegistry(root: string): Promise<SourceRegistry> {\n const path = sourceRegistryPath(root)\n try {\n const parsed = JSON.parse(await readFile(path, 'utf8')) as SourceRegistry\n return {\n generatedAt: typeof parsed.generatedAt === 'string' ? parsed.generatedAt : new Date(0).toISOString(),\n sources: Array.isArray(parsed.sources) ? parsed.sources : [],\n }\n } catch {\n return { generatedAt: new Date(0).toISOString(), sources: [] }\n }\n}\n\nexport async function writeSourceRegistry(root: string, registry: SourceRegistry): Promise<void> {\n const path = sourceRegistryPath(root)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(registry, null, 2) + '\\n', 'utf8')\n}\n\nexport async function addSourcePath(root: string, sourcePath: string, options: AddSourceOptions = {}): Promise<SourceRecord[]> {\n const s = await stat(sourcePath)\n if (s.isDirectory()) {\n const out: SourceRecord[] = []\n for (const file of await listFiles(sourcePath)) {\n out.push(...await addSourcePath(root, file, options))\n }\n return out\n }\n\n const layout = layoutFor(root)\n await mkdir(layout.rawSourcesDir, { recursive: true })\n const bytes = await readFile(sourcePath)\n const contentHash = sha256(bytes.toString('base64'))\n const fileName = basename(sourcePath)\n const adapters = options.adapters ?? [textSourceAdapter]\n const adapter = adapters.find((candidate) => candidate.canLoad({ uri: sourcePath, bytes }))\n const loaded = adapter ? await adapter.load({ uri: sourcePath, bytes }) : {}\n const id = stableId('src', `${contentHash}:${fileName}`)\n const targetRel = join('raw', 'sources', `${slugify(fileName.replace(/\\.[^.]+$/, ''))}-${contentHash.slice(0, 8)}${ext(fileName)}`).replace(/\\\\/g, '/')\n const targetAbs = join(root, targetRel)\n\n if (options.copyIntoRaw ?? true) {\n await mkdir(dirname(targetAbs), { recursive: true })\n await copyFile(sourcePath, targetAbs)\n }\n\n const existing = await loadSourceRegistry(root)\n const record: SourceRecord = {\n id,\n uri: targetRel,\n title: loaded.title ?? fileName,\n mediaType: loaded.mediaType ?? mediaTypeFor(fileName),\n contentHash,\n text: loaded.text ?? textPreview(fileName, bytes),\n anchors: (loaded.anchors ?? []).map((anchor) => ({ ...anchor, sourceId: id })),\n createdAt: (options.now ?? (() => new Date()))().toISOString(),\n metadata: {\n ...(loaded.metadata ?? {}),\n originalPath: sourcePath,\n sizeBytes: bytes.length,\n projectRelativePath: relative(root, sourcePath).replace(/\\\\/g, '/'),\n },\n }\n const next: SourceRegistry = {\n generatedAt: new Date().toISOString(),\n sources: [record, ...existing.sources.filter((source) => source.id !== id)],\n }\n await writeSourceRegistry(root, next)\n return [record]\n}\n\nexport function sourceRegistryPath(root: string): string {\n return join(layoutFor(root).cacheDir, 'sources.json')\n}\n\nasync function listFiles(root: string): Promise<string[]> {\n const entries = await readdir(root, { withFileTypes: true })\n const out: string[] = []\n for (const entry of entries) {\n const full = join(root, entry.name)\n if (entry.isDirectory()) out.push(...await listFiles(full))\n else if (entry.isFile()) out.push(full)\n }\n return out\n}\n\nfunction ext(fileName: string): string {\n const idx = fileName.lastIndexOf('.')\n return idx >= 0 ? fileName.slice(idx) : ''\n}\n\nfunction mediaTypeFor(fileName: string): string {\n const lower = fileName.toLowerCase()\n if (lower.endsWith('.md')) return 'text/markdown'\n if (lower.endsWith('.txt')) return 'text/plain'\n if (lower.endsWith('.json')) return 'application/json'\n if (lower.endsWith('.csv')) return 'text/csv'\n if (lower.endsWith('.pdf')) return 'application/pdf'\n return 'application/octet-stream'\n}\n\nfunction textPreview(fileName: string, bytes: Buffer): string | undefined {\n const mediaType = mediaTypeFor(fileName)\n if (!mediaType.startsWith('text/') && mediaType !== 'application/json') return undefined\n return bytes.toString('utf8').slice(0, 200_000)\n}\n","import type { KnowledgeIndex, KnowledgePage, KnowledgeSearchResult } from './types'\n\nconst RRF_K = 60\nconst STOP_WORDS = new Set(['the', 'is', 'a', 'an', 'what', 'how', 'are', 'was', 'were', 'to', 'for', 'of', 'with', 'by', 'in', 'on', 'and'])\n\nexport function searchKnowledge(index: KnowledgeIndex, query: string, limit = 10): KnowledgeSearchResult[] {\n const trimmed = query.trim()\n if (trimmed === '') return []\n const tokenRanked = rankByTokens(index.pages, trimmed)\n const graphRanked = rankByGraph(index.pages, tokenRanked)\n const scores = reciprocalRankFusion([tokenRanked.map((p) => p.id), graphRanked.map((p) => p.id)])\n const byId = new Map(index.pages.map((page) => [page.id, page]))\n\n const ranked = [...scores.entries()]\n .map(([id, score]) => ({ page: byId.get(id), score }))\n .filter((item): item is { page: KnowledgePage; score: number } => Boolean(item.page))\n .sort((a, b) => b.score - a.score || a.page.path.localeCompare(b.page.path))\n .slice(0, limit)\n\n // Normalize against the top hit so callers can compare against natural\n // [0, 1] thresholds. Raw RRF values are typically ~0.016, which reads as\n // \"no relevance\" to humans even when the result is the best available.\n // The top hit becomes 1 by definition; lower-ranked hits scale linearly.\n const topScore = ranked[0]?.score ?? 0\n\n return ranked.map((item, i) => ({\n page: item.page,\n score: item.score,\n rrfScore: item.score,\n normalizedScore: topScore > 0 ? item.score / topScore : 0,\n rank: i + 1,\n snippet: buildSnippet(item.page.text, trimmed),\n reasons: reasonsFor(item.page, trimmed),\n }))\n}\n\nexport function tokenizeQuery(query: string): string[] {\n const raw = query\n .toLowerCase()\n .split(/[\\s,,。!?、;:\"\"''()()\\-_/\\\\·~~…]+/)\n .filter((token) => token.length > 1 && !STOP_WORDS.has(token))\n const tokens: string[] = []\n for (const token of raw) {\n if (/[\\u4e00-\\u9fff\\u3400-\\u4dbf]/.test(token) && token.length > 2) {\n const chars = [...token]\n for (let i = 0; i < chars.length - 1; i++) tokens.push(chars[i]! + chars[i + 1]!)\n tokens.push(...chars)\n }\n tokens.push(token)\n }\n return [...new Set(tokens)]\n}\n\nexport function reciprocalRankFusion(rankLists: string[][], k = RRF_K): Map<string, number> {\n const scores = new Map<string, number>()\n for (const list of rankLists) {\n list.forEach((id, idx) => {\n scores.set(id, (scores.get(id) ?? 0) + 1 / (k + idx + 1))\n })\n }\n return scores\n}\n\nfunction rankByTokens(pages: KnowledgePage[], query: string): KnowledgePage[] {\n const tokens = tokenizeQuery(query)\n const effective = tokens.length > 0 ? tokens : [query.toLowerCase()]\n return pages\n .map((page) => ({ page, score: tokenScore(page, query, effective) }))\n .filter((item) => item.score > 0)\n .sort((a, b) => b.score - a.score || a.page.path.localeCompare(b.page.path))\n .map((item) => item.page)\n}\n\nfunction rankByGraph(pages: KnowledgePage[], tokenRanked: KnowledgePage[]): KnowledgePage[] {\n if (tokenRanked.length === 0) return []\n const seeds = new Set(tokenRanked.slice(0, 5).map((page) => page.id))\n return pages\n .map((page) => ({\n page,\n score: page.outLinks.filter((link) => seeds.has(link)).length + page.sourceIds.filter((source) => tokenRanked.some((seed) => seed.sourceIds.includes(source))).length,\n }))\n .filter((item) => item.score > 0)\n .sort((a, b) => b.score - a.score || a.page.path.localeCompare(b.page.path))\n .map((item) => item.page)\n}\n\nfunction tokenScore(page: KnowledgePage, query: string, tokens: string[]): number {\n const title = page.title.toLowerCase()\n const path = page.path.toLowerCase()\n const body = page.text.toLowerCase()\n const phrase = query.toLowerCase()\n let score = 0\n if (path.endsWith(`${phrase}.md`) || title === phrase) score += 200\n if (title.includes(phrase)) score += 50\n if (body.includes(phrase)) score += 20\n for (const token of tokens) {\n if (title.includes(token)) score += 5\n if (body.includes(token)) score += 1\n if (path.includes(token)) score += 3\n }\n return score\n}\n\nfunction buildSnippet(text: string, query: string): string {\n const compact = text.replace(/\\s+/g, ' ').trim()\n const idx = compact.toLowerCase().indexOf(query.toLowerCase())\n if (idx < 0) return compact.slice(0, 180)\n return compact.slice(Math.max(0, idx - 80), Math.min(compact.length, idx + query.length + 100))\n}\n\nfunction reasonsFor(page: KnowledgePage, query: string): string[] {\n const lower = `${page.title}\\n${page.text}`.toLowerCase()\n const reasons: string[] = []\n if (lower.includes(query.toLowerCase())) reasons.push('phrase')\n if (page.sourceIds.length > 0) reasons.push('sourced')\n if (page.outLinks.length > 0) reasons.push('linked')\n return reasons\n}\n","import { join } from 'node:path'\nimport type { KnowledgeIndex } from './types'\nimport { buildKnowledgeGraph } from './graph'\nimport { loadSourceRegistry } from './sources'\nimport { layoutFor, loadKnowledgePages, writeJson } from './store'\n\nexport async function buildKnowledgeIndex(root: string): Promise<KnowledgeIndex> {\n const [pages, sourceRegistry] = await Promise.all([\n loadKnowledgePages(root),\n loadSourceRegistry(root),\n ])\n const index: KnowledgeIndex = {\n root,\n generatedAt: new Date().toISOString(),\n sources: sourceRegistry.sources,\n pages,\n graph: buildKnowledgeGraph(pages),\n }\n return index\n}\n\nexport async function writeKnowledgeIndex(root: string): Promise<KnowledgeIndex> {\n const index = await buildKnowledgeIndex(root)\n await writeJson(join(layoutFor(root).cacheDir, 'index.json'), index)\n return index\n}\n","import type { KnowledgeIndex, KnowledgeLintFinding } from './types'\nimport { normalizeLinkTarget } from './wikilinks'\n\nexport function lintKnowledgeIndex(index: KnowledgeIndex): KnowledgeLintFinding[] {\n const findings: KnowledgeLintFinding[] = []\n const byTarget = new Set<string>()\n const titles = new Map<string, string[]>()\n const sourceIds = new Set(index.sources.map((source) => source.id))\n const anchorIds = new Map(index.sources.map((source) => [source.id, new Set((source.anchors ?? []).map((anchor) => anchor.id))]))\n const pageIds = new Map<string, string[]>()\n const sourceHashes = new Map<string, string[]>()\n for (const page of index.pages) {\n pageIds.set(page.id, [...(pageIds.get(page.id) ?? []), page.path])\n byTarget.add(normalizeLinkTarget(page.id))\n byTarget.add(normalizeLinkTarget(page.title))\n byTarget.add(normalizeLinkTarget(page.path.split('/').pop()!.replace(/\\.md$/, '')))\n const titleKey = page.title.toLowerCase()\n titles.set(titleKey, [...(titles.get(titleKey) ?? []), page.path])\n }\n for (const source of index.sources) {\n sourceHashes.set(source.contentHash, [...(sourceHashes.get(source.contentHash) ?? []), source.id])\n }\n\n const inbound = new Map<string, number>()\n for (const page of index.pages) inbound.set(page.id, 0)\n for (const page of index.pages) {\n if (page.outLinks.length === 0 && !isStructural(page.path)) {\n findings.push({ type: 'no-outlinks', severity: 'info', page: page.path, message: 'Page has no wikilinks to other knowledge pages.' })\n }\n for (const link of page.outLinks) {\n if (!byTarget.has(normalizeLinkTarget(link))) {\n findings.push({ type: 'broken-link', severity: 'warning', page: page.path, message: `Broken wikilink [[${link}]].` })\n }\n }\n }\n\n for (const edge of index.graph.edges) inbound.set(edge.target, (inbound.get(edge.target) ?? 0) + 1)\n for (const page of index.pages) {\n if (!isStructural(page.path) && (inbound.get(page.id) ?? 0) === 0) {\n findings.push({ type: 'orphan', severity: 'info', page: page.path, message: 'No other page links to this page.' })\n }\n if (/\\bclaim\\b/i.test(page.text) && page.sourceIds.length === 0) {\n findings.push({ type: 'uncited-claim', severity: 'warning', page: page.path, message: 'Page appears to contain claims but has no sources frontmatter.' })\n }\n for (const sourceId of page.sourceIds) {\n if (!sourceIds.has(sourceId)) {\n findings.push({ type: 'missing-source', severity: 'error', page: page.path, message: `Page cites unknown source \"${sourceId}\".`, metadata: { sourceId } })\n }\n }\n for (const ref of extractSourceRefs(page.text)) {\n if (!sourceIds.has(ref.sourceId)) {\n findings.push({ type: 'missing-source', severity: 'error', page: page.path, message: `Page cites unknown source \"${ref.sourceId}\".`, metadata: ref })\n } else if (ref.anchorId && !(anchorIds.get(ref.sourceId)?.has(ref.anchorId))) {\n findings.push({ type: 'missing-source', severity: 'error', page: page.path, message: `Page cites unknown source anchor \"${ref.sourceId}#${ref.anchorId}\".`, metadata: ref })\n }\n }\n }\n\n for (const [title, paths] of titles) {\n if (title && paths.length > 1) {\n findings.push({ type: 'duplicate-title', severity: 'warning', message: `Duplicate title \"${title}\" in ${paths.join(', ')}.`, metadata: { paths } })\n }\n }\n for (const [id, paths] of pageIds) {\n if (id && paths.length > 1) {\n findings.push({ type: 'duplicate-page-id', severity: 'error', message: `Duplicate page id \"${id}\" in ${paths.join(', ')}.`, metadata: { paths } })\n }\n }\n for (const [hash, ids] of sourceHashes) {\n if (hash && ids.length > 1) {\n findings.push({ type: 'duplicate-source-hash', severity: 'warning', message: `Duplicate source content hash across ${ids.join(', ')}.`, metadata: { sourceIds: ids } })\n }\n }\n return findings\n}\n\nfunction isStructural(path: string): boolean {\n return path.endsWith('/index.md') || path.endsWith('/log.md') || path === 'knowledge/index.md' || path === 'knowledge/log.md'\n}\n\nfunction extractSourceRefs(text: string): Array<{ sourceId: string; anchorId?: string }> {\n const refs: Array<{ sourceId: string; anchorId?: string }> = []\n const regex = /\\[\\^([A-Za-z0-9_-]+)(?:#([A-Za-z0-9_.:-]+))?\\]/g\n let match: RegExpExecArray | null\n while ((match = regex.exec(text)) !== null) {\n refs.push({ sourceId: match[1]!, anchorId: match[2] })\n }\n return refs\n}\n","import type { KnowledgeIndex, KnowledgeLintFinding, KnowledgePage } from './types'\nimport { lintKnowledgeIndex } from './lint'\nimport { searchKnowledge } from './search'\n\nexport interface KnowledgeInspection {\n pageCount: number\n sourceCount: number\n edgeCount: number\n findingCount: number\n blockingFindingCount: number\n topPages: Array<{ path: string; title: string; degree: number; sources: number }>\n findings: KnowledgeLintFinding[]\n}\n\nexport function inspectKnowledgeIndex(index: KnowledgeIndex): KnowledgeInspection {\n const findings = lintKnowledgeIndex(index)\n const degree = new Map(index.graph.nodes.map((node) => [node.id, node.inDegree + node.outDegree]))\n return {\n pageCount: index.pages.length,\n sourceCount: index.sources.length,\n edgeCount: index.graph.edges.length,\n findingCount: findings.length,\n blockingFindingCount: findings.filter((finding) => finding.severity === 'error').length,\n topPages: [...index.pages]\n .sort((a, b) => (degree.get(b.id) ?? 0) - (degree.get(a.id) ?? 0))\n .slice(0, 10)\n .map((page) => ({ path: page.path, title: page.title, degree: degree.get(page.id) ?? 0, sources: page.sourceIds.length })),\n findings,\n }\n}\n\nexport interface KnowledgeExplanation {\n target: string\n page?: KnowledgePage\n sources: Array<{ id: string; title?: string; uri: string }>\n links: string[]\n inbound: string[]\n related: Array<{ path: string; title: string; score: number }>\n}\n\nexport function explainKnowledgeTarget(index: KnowledgeIndex, target: string): KnowledgeExplanation {\n const page = index.pages.find((candidate) => candidate.path === target || candidate.id === target || candidate.title.toLowerCase() === target.toLowerCase())\n const inbound = page\n ? index.graph.edges.filter((edge) => edge.target === page.id).map((edge) => index.pages.find((candidate) => candidate.id === edge.source)?.path ?? edge.source)\n : []\n const related = page\n ? searchKnowledge(index, `${page.title} ${page.tags.join(' ')}`, 6)\n .filter((result) => result.page.id !== page.id)\n .map((result) => ({ path: result.page.path, title: result.page.title, score: result.score }))\n : searchKnowledge(index, target, 6).map((result) => ({ path: result.page.path, title: result.page.title, score: result.score }))\n return {\n target,\n page,\n sources: page ? index.sources.filter((source) => page.sourceIds.includes(source.id)).map((source) => ({ id: source.id, title: source.title, uri: source.uri })) : [],\n links: page?.outLinks ?? [],\n inbound,\n related,\n }\n}\n","import type { KnowledgeIndex, KnowledgeLintFinding } from './types'\nimport { lintKnowledgeIndex } from './lint'\nimport { KnowledgeIndexSchema } from './schemas'\n\nexport interface ValidateKnowledgeOptions {\n strict?: boolean\n}\n\nexport interface ValidateKnowledgeResult {\n ok: boolean\n findings: KnowledgeLintFinding[]\n}\n\nexport function validateKnowledgeIndex(index: KnowledgeIndex, options: ValidateKnowledgeOptions = {}): ValidateKnowledgeResult {\n const findings = [...lintKnowledgeIndex(index)]\n const parsed = KnowledgeIndexSchema.safeParse(index)\n if (!parsed.success) {\n findings.push({\n type: 'missing-frontmatter',\n severity: 'error',\n message: parsed.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('; '),\n })\n }\n if (options.strict) {\n for (const page of index.pages) {\n if (isStructuralPage(page.path)) continue\n if (!page.frontmatter.id || !page.frontmatter.title) {\n findings.push({\n type: 'missing-frontmatter',\n severity: 'error',\n page: page.path,\n message: 'Strict mode requires id and title frontmatter.',\n })\n }\n }\n }\n return { ok: !findings.some((finding) => finding.severity === 'error'), findings }\n}\n\nfunction isStructuralPage(path: string): boolean {\n return path === 'knowledge/index.md' || path === 'knowledge/log.md' || path.endsWith('/index.md') || path.endsWith('/log.md')\n}\n"],"mappings":"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","names":["mkdir","readFile","writeFile","dirname","join","join","basename","mkdir","readFile","dirname","writeFile","mkdir","readFile","readdir","stat","writeFile","dirname","join","relative","readFile","mkdir","dirname","writeFile","stat","join","mediaTypeFor","relative","readdir","join","join"]}
|
package/dist/cli.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { c as KnowledgeWriteParseResult, S as SourceRecord, d as KnowledgeEventType, e as KnowledgeEvent, f as KnowledgePage, g as KnowledgeIndex, h as SourceRegistry, b as KnowledgeGraph, i as KnowledgeSearchResult, j as KnowledgeLintFinding, k as KnowledgeBaseCandidate, l as KnowledgeRelease } from './types-
|
|
2
|
-
export { C as ClaimRef, m as KnowledgeClaim, K as KnowledgeGraphEdge, a as KnowledgeGraphNode, n as KnowledgeId, o as KnowledgePolicy, p as KnowledgeRelation, q as KnowledgeUnit, r as KnowledgeWriteBlock, s as SourceAnchor } from './types-
|
|
1
|
+
import { c as KnowledgeWriteParseResult, S as SourceRecord, d as KnowledgeEventType, e as KnowledgeEvent, f as KnowledgePage, g as KnowledgeIndex, h as SourceRegistry, b as KnowledgeGraph, i as KnowledgeSearchResult, j as KnowledgeLintFinding, k as KnowledgeBaseCandidate, l as KnowledgeRelease } from './types-CWbf3JSE.js';
|
|
2
|
+
export { C as ClaimRef, m as KnowledgeClaim, K as KnowledgeGraphEdge, a as KnowledgeGraphNode, n as KnowledgeId, o as KnowledgePolicy, p as KnowledgeRelation, q as KnowledgeUnit, r as KnowledgeWriteBlock, s as SourceAnchor } from './types-CWbf3JSE.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { MultiShotVariant, MultiShotOptimizationConfig, MultiShotRunner, MultiShotScorer, MultiShotMutateAdapter, MultiShotOptimizationResult, ReleaseConfidenceScorecard, RunRecord } from '@tangle-network/agent-eval';
|
|
4
|
+
import { MultiShotVariant, MultiShotOptimizationConfig, MultiShotRunner, MultiShotScorer, MultiShotMutateAdapter, MultiShotOptimizationResult, ReleaseConfidenceScorecard, RunRecord, KnowledgeRequirementCategory, KnowledgeAcquisitionMode, KnowledgeImportance, KnowledgeFreshness, KnowledgeSensitivity, KnowledgeRequirement, KnowledgeBundle, KnowledgeReadinessReport, UserQuestion, DataAcquisitionPlan } from '@tangle-network/agent-eval';
|
|
5
5
|
|
|
6
6
|
declare function sha256(text: string): string;
|
|
7
7
|
declare function slugify(input: string): string;
|
|
@@ -328,6 +328,23 @@ interface KnowledgeLayout {
|
|
|
328
328
|
cacheDir: string;
|
|
329
329
|
}
|
|
330
330
|
declare function layoutFor(root: string): KnowledgeLayout;
|
|
331
|
+
/**
|
|
332
|
+
* Filenames that `initKnowledgeBase` writes as human-navigation scaffolding.
|
|
333
|
+
* These are excluded from the page index — they exist on disk so authors can
|
|
334
|
+
* curate their vault, but they are not searchable content.
|
|
335
|
+
*
|
|
336
|
+
* Add new scaffold filenames here (and only here) to keep lint, validate, viz,
|
|
337
|
+
* and the indexer consistent.
|
|
338
|
+
*/
|
|
339
|
+
declare const SCAFFOLD_PAGE_BASENAMES: readonly string[];
|
|
340
|
+
/**
|
|
341
|
+
* True when a knowledge-relative path points at a scaffold file rather than
|
|
342
|
+
* authored content. Accepts both repo-relative paths (`knowledge/index.md`)
|
|
343
|
+
* and any nested `<dir>/index.md` or `<dir>/log.md` (for example
|
|
344
|
+
* `knowledge/concepts/index.md`) so subdirectory README-style scaffolds are
|
|
345
|
+
* also excluded.
|
|
346
|
+
*/
|
|
347
|
+
declare function isScaffoldPath(path: string): boolean;
|
|
331
348
|
declare function initKnowledgeBase(root: string): Promise<KnowledgeLayout>;
|
|
332
349
|
declare function loadKnowledgePages(root: string): Promise<KnowledgePage[]>;
|
|
333
350
|
declare function writeJson(path: string, value: unknown): Promise<void>;
|
|
@@ -421,4 +438,38 @@ declare function knowledgeReleaseReportFromOptimization(result: MultiShotOptimiz
|
|
|
421
438
|
minScore?: number;
|
|
422
439
|
}): KnowledgeReleaseReport;
|
|
423
440
|
|
|
424
|
-
|
|
441
|
+
interface KnowledgeReadinessSpec {
|
|
442
|
+
id: string;
|
|
443
|
+
description: string;
|
|
444
|
+
query: string;
|
|
445
|
+
requiredFor: string[];
|
|
446
|
+
category: KnowledgeRequirementCategory;
|
|
447
|
+
acquisitionMode: KnowledgeAcquisitionMode;
|
|
448
|
+
importance: KnowledgeImportance;
|
|
449
|
+
freshness: KnowledgeFreshness;
|
|
450
|
+
sensitivity: KnowledgeSensitivity;
|
|
451
|
+
confidenceNeeded: number;
|
|
452
|
+
fallbackPolicy?: KnowledgeRequirement['fallbackPolicy'];
|
|
453
|
+
minSources?: number;
|
|
454
|
+
minHits?: number;
|
|
455
|
+
metadata?: Record<string, unknown>;
|
|
456
|
+
}
|
|
457
|
+
interface BuildEvalKnowledgeBundleOptions {
|
|
458
|
+
taskId: string;
|
|
459
|
+
index: KnowledgeIndex;
|
|
460
|
+
specs: KnowledgeReadinessSpec[];
|
|
461
|
+
userAnswers?: Record<string, string>;
|
|
462
|
+
searchLimit?: number;
|
|
463
|
+
metadata?: Record<string, unknown>;
|
|
464
|
+
}
|
|
465
|
+
interface EvalKnowledgeBundleBuildResult {
|
|
466
|
+
bundle: KnowledgeBundle;
|
|
467
|
+
report: KnowledgeReadinessReport;
|
|
468
|
+
requirements: KnowledgeRequirement[];
|
|
469
|
+
searchResultsByRequirement: Record<string, KnowledgeSearchResult[]>;
|
|
470
|
+
questions: UserQuestion[];
|
|
471
|
+
acquisitionPlans: DataAcquisitionPlan[];
|
|
472
|
+
}
|
|
473
|
+
declare function buildEvalKnowledgeBundle(options: BuildEvalKnowledgeBundleOptions): EvalKnowledgeBundleBuildResult;
|
|
474
|
+
|
|
475
|
+
export { type AddSourceOptions, type ApplyWriteBlocksResult, type BuildEvalKnowledgeBundleOptions, type ChunkingOptions, type DiscoveryResult, type DiscoveryTask, type EvalKnowledgeBundleBuildResult, FileSystemKbStore, type KbStore, KnowledgeBaseCandidate, KnowledgeBaseCandidateSchema, type KnowledgeBaseVariant, type KnowledgeChunk, type KnowledgeDiscoveryDispatcher, type KnowledgeDiscoveryWorker, KnowledgeEvent, type KnowledgeEventQuery, KnowledgeEventSchema, KnowledgeEventType, type KnowledgeExplanation, KnowledgeGraph, KnowledgeGraphEdgeSchema, KnowledgeGraphNodeSchema, KnowledgeIndex, KnowledgeIndexSchema, type KnowledgeInspection, type KnowledgeLayout, KnowledgeLintFinding, type KnowledgeOptimizationConfig, KnowledgePage, KnowledgePageSchema, type KnowledgeReadinessSpec, KnowledgeRelease, type KnowledgeReleaseReport, KnowledgeSearchResult, KnowledgeWriteParseResult, MemoryKbStore, type ParsedFrontmatter, SCAFFOLD_PAGE_BASENAMES, type SourceAdapter, type SourceAdapterInput, type SourceAdapterOutput, SourceAnchorSchema, SourceRecord, SourceRecordSchema, SourceRegistry, type ValidateKnowledgeOptions, type ValidateKnowledgeResult, WIKILINK_REGEX, addSourcePath, applyKnowledgeWriteBlocks, applyKnowledgeWriteBlocksFile, buildEvalKnowledgeBundle, buildKnowledgeGraph, buildKnowledgeIndex, chunkMarkdown, createKnowledgeEvent, createLocalDiscoveryDispatcher, explainKnowledgeTarget, extractWikilinks, formatFrontmatter, initKnowledgeBase, inspectKnowledgeIndex, isSafeKnowledgePath, isScaffoldPath, knowledgeReleaseReportFromOptimization, knowledgeVariantFromCandidate, layoutFor, lintKnowledgeIndex, loadKnowledgePages, loadSourceRegistry, mediaTypeFor, normalizeLinkTarget, parseFrontmatter, parseKnowledgeWriteBlocks, reciprocalRankFusion, runKnowledgeBaseOptimization, searchKnowledge, sha256, slugify, sourceRegistryPath, stableId, stripFrontmatter, textSourceAdapter, tokenizeQuery, validateKnowledgeIndex, writeJson, writeKnowledgeIndex, writeSourceRegistry };
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
KnowledgeGraphNodeSchema,
|
|
6
6
|
KnowledgeIndexSchema,
|
|
7
7
|
KnowledgePageSchema,
|
|
8
|
+
SCAFFOLD_PAGE_BASENAMES,
|
|
8
9
|
SourceAnchorSchema,
|
|
9
10
|
SourceRecordSchema,
|
|
10
11
|
WIKILINK_REGEX,
|
|
@@ -19,6 +20,7 @@ import {
|
|
|
19
20
|
initKnowledgeBase,
|
|
20
21
|
inspectKnowledgeIndex,
|
|
21
22
|
isSafeKnowledgePath,
|
|
23
|
+
isScaffoldPath,
|
|
22
24
|
layoutFor,
|
|
23
25
|
lintKnowledgeIndex,
|
|
24
26
|
loadKnowledgePages,
|
|
@@ -39,7 +41,7 @@ import {
|
|
|
39
41
|
writeJson,
|
|
40
42
|
writeKnowledgeIndex,
|
|
41
43
|
writeSourceRegistry
|
|
42
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-BEFAI2HO.js";
|
|
43
45
|
|
|
44
46
|
// src/events.ts
|
|
45
47
|
function createKnowledgeEvent(input) {
|
|
@@ -342,6 +344,85 @@ function knowledgeReleaseReportFromOptimization(result, options = {}) {
|
|
|
342
344
|
baselineRuns: result.gate?.baselineRuns ?? []
|
|
343
345
|
};
|
|
344
346
|
}
|
|
347
|
+
|
|
348
|
+
// src/eval-readiness.ts
|
|
349
|
+
import {
|
|
350
|
+
acquisitionPlansForKnowledgeGaps,
|
|
351
|
+
scoreKnowledgeReadiness,
|
|
352
|
+
userQuestionsForKnowledgeGaps
|
|
353
|
+
} from "@tangle-network/agent-eval";
|
|
354
|
+
function buildEvalKnowledgeBundle(options) {
|
|
355
|
+
const searchLimit = options.searchLimit ?? 5;
|
|
356
|
+
const searchResultsByRequirement = {};
|
|
357
|
+
const requirements = options.specs.map((spec) => {
|
|
358
|
+
const results = searchKnowledge(options.index, spec.query, searchLimit);
|
|
359
|
+
searchResultsByRequirement[spec.id] = results;
|
|
360
|
+
return requirementFromSearch(spec, results);
|
|
361
|
+
});
|
|
362
|
+
const report = scoreKnowledgeReadiness({
|
|
363
|
+
taskId: options.taskId,
|
|
364
|
+
requirements,
|
|
365
|
+
userAnswers: options.userAnswers,
|
|
366
|
+
evidenceIds: requirements.flatMap((requirement) => requirement.evidenceIds),
|
|
367
|
+
claimIds: [],
|
|
368
|
+
wikiPageIds: unique(requirements.flatMap((requirement) => pageIdsFromResults(searchResultsByRequirement[requirement.id] ?? []))),
|
|
369
|
+
metadata: options.metadata
|
|
370
|
+
});
|
|
371
|
+
const questions = userQuestionsForKnowledgeGaps(report.blockingMissingRequirements);
|
|
372
|
+
const acquisitionPlans = acquisitionPlansForKnowledgeGaps([
|
|
373
|
+
...report.blockingMissingRequirements,
|
|
374
|
+
...report.nonBlockingGaps
|
|
375
|
+
]);
|
|
376
|
+
return {
|
|
377
|
+
bundle: report.bundle,
|
|
378
|
+
report,
|
|
379
|
+
requirements,
|
|
380
|
+
searchResultsByRequirement,
|
|
381
|
+
questions,
|
|
382
|
+
acquisitionPlans
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
function requirementFromSearch(spec, results) {
|
|
386
|
+
const hitCount = results.length;
|
|
387
|
+
const sourceIds = unique(results.flatMap((result) => result.page.sourceIds));
|
|
388
|
+
const bestScore = results[0]?.normalizedScore ?? 0;
|
|
389
|
+
const sourceCoverage = spec.minSources ? Math.min(1, sourceIds.length / spec.minSources) : sourceIds.length > 0 ? 1 : 0;
|
|
390
|
+
const hitCoverage = spec.minHits ? Math.min(1, hitCount / spec.minHits) : hitCount > 0 ? 1 : 0;
|
|
391
|
+
const currentConfidence = round(Math.min(bestScore, sourceCoverage, hitCoverage));
|
|
392
|
+
return {
|
|
393
|
+
id: spec.id,
|
|
394
|
+
description: spec.description,
|
|
395
|
+
requiredFor: spec.requiredFor,
|
|
396
|
+
category: spec.category,
|
|
397
|
+
acquisitionMode: spec.acquisitionMode,
|
|
398
|
+
importance: spec.importance,
|
|
399
|
+
freshness: spec.freshness,
|
|
400
|
+
sensitivity: spec.sensitivity,
|
|
401
|
+
confidenceNeeded: spec.confidenceNeeded,
|
|
402
|
+
currentConfidence,
|
|
403
|
+
evidenceIds: unique([
|
|
404
|
+
...sourceIds.map((sourceId) => `source:${sourceId}`),
|
|
405
|
+
...results.map((result) => `page:${result.page.id}`)
|
|
406
|
+
]),
|
|
407
|
+
fallbackPolicy: spec.fallbackPolicy ?? (spec.importance === "blocking" ? "block" : "continue_with_caveat"),
|
|
408
|
+
metadata: {
|
|
409
|
+
...spec.metadata,
|
|
410
|
+
query: spec.query,
|
|
411
|
+
hitCount,
|
|
412
|
+
sourceCount: sourceIds.length,
|
|
413
|
+
bestNormalizedScore: bestScore
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
function pageIdsFromResults(results) {
|
|
418
|
+
return results.map((result) => result.page.id);
|
|
419
|
+
}
|
|
420
|
+
function unique(items) {
|
|
421
|
+
return [...new Set(items)];
|
|
422
|
+
}
|
|
423
|
+
function round(value) {
|
|
424
|
+
return Math.round(value * 1e3) / 1e3;
|
|
425
|
+
}
|
|
345
426
|
export {
|
|
346
427
|
FileSystemKbStore,
|
|
347
428
|
KnowledgeBaseCandidateSchema,
|
|
@@ -351,12 +432,14 @@ export {
|
|
|
351
432
|
KnowledgeIndexSchema,
|
|
352
433
|
KnowledgePageSchema,
|
|
353
434
|
MemoryKbStore,
|
|
435
|
+
SCAFFOLD_PAGE_BASENAMES,
|
|
354
436
|
SourceAnchorSchema,
|
|
355
437
|
SourceRecordSchema,
|
|
356
438
|
WIKILINK_REGEX,
|
|
357
439
|
addSourcePath,
|
|
358
440
|
applyKnowledgeWriteBlocks,
|
|
359
441
|
applyKnowledgeWriteBlocksFile,
|
|
442
|
+
buildEvalKnowledgeBundle,
|
|
360
443
|
buildKnowledgeGraph,
|
|
361
444
|
buildKnowledgeIndex,
|
|
362
445
|
chunkMarkdown,
|
|
@@ -368,6 +451,7 @@ export {
|
|
|
368
451
|
initKnowledgeBase,
|
|
369
452
|
inspectKnowledgeIndex,
|
|
370
453
|
isSafeKnowledgePath,
|
|
454
|
+
isScaffoldPath,
|
|
371
455
|
knowledgeReleaseReportFromOptimization,
|
|
372
456
|
knowledgeVariantFromCandidate,
|
|
373
457
|
layoutFor,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/events.ts","../src/kb-store.ts","../src/discovery.ts","../src/chunking.ts","../src/optimization.ts","../src/release.ts"],"sourcesContent":["import type { KnowledgeEvent, KnowledgeEventType } from './types'\nimport { stableId } from './ids'\n\nexport interface KnowledgeEventQuery {\n type?: KnowledgeEventType\n target?: string\n limit?: number\n}\n\nexport function createKnowledgeEvent(input: {\n type: KnowledgeEventType\n actor?: string\n target?: string\n metadata?: Record<string, unknown>\n now?: () => Date\n}): KnowledgeEvent {\n const createdAt = (input.now ?? (() => new Date()))().toISOString()\n return {\n id: stableId('evt', `${input.type}:${input.target ?? ''}:${createdAt}:${JSON.stringify(input.metadata ?? {})}`),\n type: input.type,\n createdAt,\n actor: input.actor,\n target: input.target,\n metadata: input.metadata,\n }\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport type { KnowledgeEvent, KnowledgeIndex, KnowledgePage, SourceRecord } from './types'\nimport type { KnowledgeEventQuery } from './events'\nimport { buildKnowledgeGraph } from './graph'\n\nexport interface KbStore {\n putSource(source: SourceRecord): Promise<void>\n getSource(id: string): Promise<SourceRecord | null>\n listSources(): Promise<SourceRecord[]>\n putPage(page: KnowledgePage): Promise<void>\n getPage(idOrPath: string): Promise<KnowledgePage | null>\n listPages(): Promise<KnowledgePage[]>\n putIndex(index: KnowledgeIndex): Promise<void>\n getIndex(): Promise<KnowledgeIndex | null>\n putEvent(event: KnowledgeEvent): Promise<void>\n listEvents(query?: KnowledgeEventQuery): Promise<KnowledgeEvent[]>\n}\n\nexport class MemoryKbStore implements KbStore {\n private readonly sources = new Map<string, SourceRecord>()\n private readonly pages = new Map<string, KnowledgePage>()\n private readonly events: KnowledgeEvent[] = []\n private index: KnowledgeIndex | null = null\n\n async putSource(source: SourceRecord): Promise<void> {\n this.sources.set(source.id, clone(source))\n }\n\n async getSource(id: string): Promise<SourceRecord | null> {\n return clone(this.sources.get(id) ?? null)\n }\n\n async listSources(): Promise<SourceRecord[]> {\n return [...this.sources.values()].map(clone)\n }\n\n async putPage(page: KnowledgePage): Promise<void> {\n this.pages.set(page.id, clone(page))\n }\n\n async getPage(idOrPath: string): Promise<KnowledgePage | null> {\n return clone(this.pages.get(idOrPath) ?? [...this.pages.values()].find((page) => page.path === idOrPath) ?? null)\n }\n\n async listPages(): Promise<KnowledgePage[]> {\n return [...this.pages.values()].map(clone)\n }\n\n async putIndex(index: KnowledgeIndex): Promise<void> {\n this.index = clone(index)\n }\n\n async getIndex(): Promise<KnowledgeIndex | null> {\n if (this.index) return clone(this.index)\n const pages = await this.listPages()\n const sources = await this.listSources()\n return { root: 'memory', generatedAt: new Date().toISOString(), sources, pages, graph: buildKnowledgeGraph(pages) }\n }\n\n async putEvent(event: KnowledgeEvent): Promise<void> {\n this.events.push(clone(event))\n }\n\n async listEvents(query: KnowledgeEventQuery = {}): Promise<KnowledgeEvent[]> {\n let out = this.events\n if (query.type) out = out.filter((event) => event.type === query.type)\n if (query.target) out = out.filter((event) => event.target === query.target)\n out = [...out].sort((a, b) => a.createdAt.localeCompare(b.createdAt))\n return out.slice(-(query.limit ?? out.length)).map(clone)\n }\n}\n\nexport class FileSystemKbStore extends MemoryKbStore {\n constructor(private readonly dir: string) {\n super()\n }\n\n async putIndex(index: KnowledgeIndex): Promise<void> {\n await super.putIndex(index)\n await writeJson(join(this.dir, 'index.json'), index)\n }\n\n async getIndex(): Promise<KnowledgeIndex | null> {\n try {\n return JSON.parse(await readFile(join(this.dir, 'index.json'), 'utf8')) as KnowledgeIndex\n } catch {\n return await super.getIndex()\n }\n }\n\n async putEvent(event: KnowledgeEvent): Promise<void> {\n await super.putEvent(event)\n const events = await this.listEvents()\n await writeJson(join(this.dir, 'events.json'), events)\n }\n}\n\nasync function writeJson(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(value, null, 2) + '\\n', 'utf8')\n}\n\nfunction clone<T>(value: T): T {\n return value == null ? value : JSON.parse(JSON.stringify(value)) as T\n}\n","export interface DiscoveryTask {\n id: string\n goal: string\n query?: string\n sourceHints?: string[]\n metadata?: Record<string, unknown>\n}\n\nexport interface DiscoveryResult {\n taskId: string\n summary: string\n sourceUris?: string[]\n claims?: Array<{ text: string; sourceUri?: string; confidence?: number }>\n followUpTasks?: DiscoveryTask[]\n metadata?: Record<string, unknown>\n}\n\nexport interface KnowledgeDiscoveryWorker {\n run(task: DiscoveryTask, signal?: AbortSignal): Promise<DiscoveryResult> | DiscoveryResult\n}\n\nexport interface KnowledgeDiscoveryDispatcher {\n dispatch(tasks: DiscoveryTask[], options?: {\n concurrency?: number\n signal?: AbortSignal\n }): Promise<DiscoveryResult[]>\n}\n\nexport function createLocalDiscoveryDispatcher(worker: KnowledgeDiscoveryWorker): KnowledgeDiscoveryDispatcher {\n return {\n async dispatch(tasks, options = {}) {\n const concurrency = Math.max(1, options.concurrency ?? 4)\n const results: DiscoveryResult[] = []\n let cursor = 0\n async function runNext(): Promise<void> {\n while (cursor < tasks.length) {\n if (options.signal?.aborted) throw new Error('Discovery dispatch aborted')\n const task = tasks[cursor++]!\n results.push(await worker.run(task, options.signal))\n }\n }\n await Promise.all(Array.from({ length: Math.min(concurrency, tasks.length) }, runNext))\n return results.sort((a, b) => tasks.findIndex((task) => task.id === a.taskId) - tasks.findIndex((task) => task.id === b.taskId))\n },\n }\n}\n","export interface ChunkingOptions {\n targetChars: number\n maxChars: number\n minChars: number\n overlapChars: number\n}\n\nexport interface KnowledgeChunk {\n index: number\n text: string\n headingPath: string\n charStart: number\n charEnd: number\n oversized: boolean\n}\n\nconst DEFAULT_OPTIONS: ChunkingOptions = {\n targetChars: 1000,\n maxChars: 1500,\n minChars: 160,\n overlapChars: 180,\n}\n\nexport function chunkMarkdown(content: string, options?: Partial<ChunkingOptions>): KnowledgeChunk[] {\n const opts = normalizeOptions({ ...DEFAULT_OPTIONS, ...(options ?? {}) })\n const { body, bodyOffset } = stripFrontmatter(content)\n if (body.trim() === '') return []\n\n const sections = splitSections(body, bodyOffset)\n const chunks: KnowledgeChunk[] = []\n for (const section of sections) {\n for (const part of chunkText(section.text, opts)) {\n const start = section.start + part.start\n chunks.push({\n index: chunks.length,\n text: part.text,\n headingPath: section.headingPath,\n charStart: start,\n charEnd: start + part.text.length,\n oversized: part.text.length > opts.maxChars,\n })\n }\n }\n return chunks\n}\n\nexport function stripFrontmatter(content: string): { body: string; bodyOffset: number } {\n const normalized = content.replace(/\\r\\n/g, '\\n')\n if (!normalized.startsWith('---\\n')) return { body: normalized, bodyOffset: 0 }\n const match = /^---\\n[\\s\\S]*?\\n---\\s*\\n?/.exec(normalized)\n if (!match) return { body: normalized, bodyOffset: 0 }\n return { body: normalized.slice(match[0].length), bodyOffset: match[0].length }\n}\n\nfunction normalizeOptions(opts: ChunkingOptions): ChunkingOptions {\n if (opts.maxChars < opts.targetChars) opts.maxChars = opts.targetChars\n if (opts.overlapChars >= opts.targetChars) opts.overlapChars = Math.floor(opts.targetChars / 2)\n return opts\n}\n\ninterface Section {\n text: string\n start: number\n headingPath: string\n}\n\nfunction splitSections(body: string, bodyOffset: number): Section[] {\n const lines = body.split('\\n')\n const sections: Section[] = []\n const headings: Record<number, string> = {}\n let current: { lines: string[]; start: number; headingPath: string } = { lines: [], start: bodyOffset, headingPath: '' }\n let cursor = bodyOffset\n let fence: string | null = null\n\n const flush = () => {\n const text = current.lines.join('\\n')\n if (text.trim() !== '') sections.push({ text, start: current.start, headingPath: current.headingPath })\n }\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n const lineLen = line.length + (i < lines.length - 1 ? 1 : 0)\n const fenceMatch = /^(`{3,}|~{3,})/.exec(line)\n if (fenceMatch) {\n const marker = fenceMatch[1]!\n fence = fence === null ? marker : line.startsWith(fence) ? null : fence\n current.lines.push(line)\n cursor += lineLen\n continue\n }\n const heading = fence === null ? /^(#{1,6})\\s+(.+?)\\s*$/.exec(line) : null\n if (heading) {\n flush()\n const level = heading[1]!.length\n headings[level] = heading[2]!.trim()\n for (let next = level + 1; next <= 6; next++) delete headings[next]\n current = {\n lines: [line],\n start: cursor,\n headingPath: Object.entries(headings)\n .sort(([a], [b]) => Number(a) - Number(b))\n .map(([levelText, title]) => `${'#'.repeat(Number(levelText))} ${title}`)\n .join(' > '),\n }\n cursor += lineLen\n continue\n }\n current.lines.push(line)\n cursor += lineLen\n }\n flush()\n return sections\n}\n\nfunction chunkText(text: string, opts: ChunkingOptions): Array<{ text: string; start: number }> {\n if (text.length <= opts.targetChars) return [{ text, start: 0 }]\n const atoms = splitAtoms(text)\n const chunks: Array<{ text: string; start: number }> = []\n let buffer = ''\n let bufferStart = 0\n for (const atom of atoms) {\n if (buffer === '') bufferStart = atom.start\n if (buffer.length > 0 && buffer.length + atom.text.length > opts.targetChars) {\n chunks.push({ text: buffer.trimEnd(), start: bufferStart })\n const overlap = buffer.slice(Math.max(0, buffer.length - opts.overlapChars))\n buffer = overlap + atom.text\n bufferStart = Math.max(bufferStart, atom.start - overlap.length)\n } else {\n buffer += atom.text\n }\n }\n if (buffer.trim() !== '') chunks.push({ text: buffer.trimEnd(), start: bufferStart })\n return mergeTinyChunks(chunks, opts)\n}\n\nfunction splitAtoms(text: string): Array<{ text: string; start: number }> {\n const parts: Array<{ text: string; start: number }> = []\n const paragraphs = text.split(/(\\n\\s*\\n)/)\n let cursor = 0\n for (let i = 0; i < paragraphs.length; i += 2) {\n const paragraph = (paragraphs[i] ?? '') + (paragraphs[i + 1] ?? '')\n if (paragraph === '') continue\n parts.push({ text: paragraph, start: cursor })\n cursor += paragraph.length\n }\n return parts\n}\n\nfunction mergeTinyChunks(chunks: Array<{ text: string; start: number }>, opts: ChunkingOptions): Array<{ text: string; start: number }> {\n const out: Array<{ text: string; start: number }> = []\n for (const chunk of chunks) {\n const prev = out[out.length - 1]\n if (prev && chunk.text.length < opts.minChars && prev.text.length + chunk.text.length <= opts.maxChars) {\n prev.text = `${prev.text}\\n\\n${chunk.text}`\n } else {\n out.push({ ...chunk })\n }\n }\n return out\n}\n","import {\n runMultiShotOptimization,\n type MultiShotMutateAdapter,\n type MultiShotOptimizationConfig,\n type MultiShotOptimizationResult,\n type MultiShotRunner,\n type MultiShotScorer,\n type MultiShotVariant,\n} from '@tangle-network/agent-eval'\nimport type { KnowledgeBaseCandidate } from './types'\n\nexport type KnowledgeBaseVariant = MultiShotVariant<KnowledgeBaseCandidate>\n\nexport interface KnowledgeOptimizationConfig\n extends Omit<\n MultiShotOptimizationConfig<KnowledgeBaseCandidate>,\n 'runner' | 'scorer' | 'mutateAdapter' | 'target'\n > {\n target?: string\n runner: MultiShotRunner<KnowledgeBaseCandidate>\n scorer: MultiShotScorer<KnowledgeBaseCandidate>\n mutateAdapter: MultiShotMutateAdapter<KnowledgeBaseCandidate>\n}\n\nexport async function runKnowledgeBaseOptimization(\n config: KnowledgeOptimizationConfig,\n): Promise<MultiShotOptimizationResult<KnowledgeBaseCandidate>> {\n return runMultiShotOptimization<KnowledgeBaseCandidate>({\n ...config,\n target: config.target ?? 'agent-knowledge-base',\n })\n}\n\nexport function knowledgeVariantFromCandidate(\n candidate: KnowledgeBaseCandidate,\n options: { id?: string; label?: string; generation?: number } = {},\n): KnowledgeBaseVariant {\n return {\n id: options.id ?? candidate.id,\n label: options.label ?? candidate.id,\n generation: options.generation ?? 0,\n payload: candidate,\n }\n}\n","import {\n evaluateReleaseConfidence,\n releaseTraceEvidenceFromMultiShotTrials,\n validateRunRecord,\n type MultiShotOptimizationResult,\n type MultiShotTrialResult,\n type RunRecord,\n type ReleaseConfidenceScorecard,\n} from '@tangle-network/agent-eval'\nimport type { KnowledgeBaseCandidate, KnowledgeRelease } from './types'\nimport { stableId } from './ids'\n\nexport interface KnowledgeReleaseReport {\n release: KnowledgeRelease\n scorecard: ReleaseConfidenceScorecard\n candidateRuns: RunRecord[]\n baselineRuns: RunRecord[]\n}\n\nexport function knowledgeReleaseReportFromOptimization(\n result: MultiShotOptimizationResult<KnowledgeBaseCandidate>,\n options: {\n runRecords?: RunRecord[]\n createdAt?: string\n minScore?: number\n } = {},\n): KnowledgeReleaseReport {\n const trials = result.evolution.generations.flatMap((generation) => generation.trials) as MultiShotTrialResult[]\n const traceEvidence = releaseTraceEvidenceFromMultiShotTrials(trials)\n const runRecords = (options.runRecords ?? [\n ...(result.gate?.candidateRuns ?? []),\n ...(result.gate?.baselineRuns ?? []),\n ]).map(validateRunRecord)\n const scorecard = evaluateReleaseConfidence({\n target: 'agent-knowledge-base',\n candidateId: result.promotedVariant.id,\n baselineId: 'baseline',\n traces: traceEvidence,\n runs: runRecords,\n gateDecision: result.gate?.decision ?? null,\n thresholds: {\n requireCorpus: false,\n requireHoldout: Boolean(result.gate),\n minHoldoutRuns: result.gate ? 1 : 0,\n minSearchRuns: 1,\n minMeanScore: options.minScore ?? 0.7,\n },\n })\n const release: KnowledgeRelease = {\n id: stableId('krel', `${result.promotedVariant.id}:${options.createdAt ?? new Date().toISOString()}`),\n candidateId: result.promotedVariant.id,\n createdAt: options.createdAt ?? new Date().toISOString(),\n promoted: scorecard.status !== 'fail' && result.promotedVariant.id === result.searchBestVariant.id,\n scorecard,\n runRecordIds: runRecords.map((record) => record.runId),\n }\n return {\n release,\n scorecard,\n candidateRuns: result.gate?.candidateRuns ?? [],\n baselineRuns: result.gate?.baselineRuns ?? [],\n }\n}\n"],"mappings":"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","names":["writeJson"]}
|
|
1
|
+
{"version":3,"sources":["../src/events.ts","../src/kb-store.ts","../src/discovery.ts","../src/chunking.ts","../src/optimization.ts","../src/release.ts","../src/eval-readiness.ts"],"sourcesContent":["import type { KnowledgeEvent, KnowledgeEventType } from './types'\nimport { stableId } from './ids'\n\nexport interface KnowledgeEventQuery {\n type?: KnowledgeEventType\n target?: string\n limit?: number\n}\n\nexport function createKnowledgeEvent(input: {\n type: KnowledgeEventType\n actor?: string\n target?: string\n metadata?: Record<string, unknown>\n now?: () => Date\n}): KnowledgeEvent {\n const createdAt = (input.now ?? (() => new Date()))().toISOString()\n return {\n id: stableId('evt', `${input.type}:${input.target ?? ''}:${createdAt}:${JSON.stringify(input.metadata ?? {})}`),\n type: input.type,\n createdAt,\n actor: input.actor,\n target: input.target,\n metadata: input.metadata,\n }\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport type { KnowledgeEvent, KnowledgeIndex, KnowledgePage, SourceRecord } from './types'\nimport type { KnowledgeEventQuery } from './events'\nimport { buildKnowledgeGraph } from './graph'\n\nexport interface KbStore {\n putSource(source: SourceRecord): Promise<void>\n getSource(id: string): Promise<SourceRecord | null>\n listSources(): Promise<SourceRecord[]>\n putPage(page: KnowledgePage): Promise<void>\n getPage(idOrPath: string): Promise<KnowledgePage | null>\n listPages(): Promise<KnowledgePage[]>\n putIndex(index: KnowledgeIndex): Promise<void>\n getIndex(): Promise<KnowledgeIndex | null>\n putEvent(event: KnowledgeEvent): Promise<void>\n listEvents(query?: KnowledgeEventQuery): Promise<KnowledgeEvent[]>\n}\n\nexport class MemoryKbStore implements KbStore {\n private readonly sources = new Map<string, SourceRecord>()\n private readonly pages = new Map<string, KnowledgePage>()\n private readonly events: KnowledgeEvent[] = []\n private index: KnowledgeIndex | null = null\n\n async putSource(source: SourceRecord): Promise<void> {\n this.sources.set(source.id, clone(source))\n }\n\n async getSource(id: string): Promise<SourceRecord | null> {\n return clone(this.sources.get(id) ?? null)\n }\n\n async listSources(): Promise<SourceRecord[]> {\n return [...this.sources.values()].map(clone)\n }\n\n async putPage(page: KnowledgePage): Promise<void> {\n this.pages.set(page.id, clone(page))\n }\n\n async getPage(idOrPath: string): Promise<KnowledgePage | null> {\n return clone(this.pages.get(idOrPath) ?? [...this.pages.values()].find((page) => page.path === idOrPath) ?? null)\n }\n\n async listPages(): Promise<KnowledgePage[]> {\n return [...this.pages.values()].map(clone)\n }\n\n async putIndex(index: KnowledgeIndex): Promise<void> {\n this.index = clone(index)\n }\n\n async getIndex(): Promise<KnowledgeIndex | null> {\n if (this.index) return clone(this.index)\n const pages = await this.listPages()\n const sources = await this.listSources()\n return { root: 'memory', generatedAt: new Date().toISOString(), sources, pages, graph: buildKnowledgeGraph(pages) }\n }\n\n async putEvent(event: KnowledgeEvent): Promise<void> {\n this.events.push(clone(event))\n }\n\n async listEvents(query: KnowledgeEventQuery = {}): Promise<KnowledgeEvent[]> {\n let out = this.events\n if (query.type) out = out.filter((event) => event.type === query.type)\n if (query.target) out = out.filter((event) => event.target === query.target)\n out = [...out].sort((a, b) => a.createdAt.localeCompare(b.createdAt))\n return out.slice(-(query.limit ?? out.length)).map(clone)\n }\n}\n\nexport class FileSystemKbStore extends MemoryKbStore {\n constructor(private readonly dir: string) {\n super()\n }\n\n async putIndex(index: KnowledgeIndex): Promise<void> {\n await super.putIndex(index)\n await writeJson(join(this.dir, 'index.json'), index)\n }\n\n async getIndex(): Promise<KnowledgeIndex | null> {\n try {\n return JSON.parse(await readFile(join(this.dir, 'index.json'), 'utf8')) as KnowledgeIndex\n } catch {\n return await super.getIndex()\n }\n }\n\n async putEvent(event: KnowledgeEvent): Promise<void> {\n await super.putEvent(event)\n const events = await this.listEvents()\n await writeJson(join(this.dir, 'events.json'), events)\n }\n}\n\nasync function writeJson(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(value, null, 2) + '\\n', 'utf8')\n}\n\nfunction clone<T>(value: T): T {\n return value == null ? value : JSON.parse(JSON.stringify(value)) as T\n}\n","export interface DiscoveryTask {\n id: string\n goal: string\n query?: string\n sourceHints?: string[]\n metadata?: Record<string, unknown>\n}\n\nexport interface DiscoveryResult {\n taskId: string\n summary: string\n sourceUris?: string[]\n claims?: Array<{ text: string; sourceUri?: string; confidence?: number }>\n followUpTasks?: DiscoveryTask[]\n metadata?: Record<string, unknown>\n}\n\nexport interface KnowledgeDiscoveryWorker {\n run(task: DiscoveryTask, signal?: AbortSignal): Promise<DiscoveryResult> | DiscoveryResult\n}\n\nexport interface KnowledgeDiscoveryDispatcher {\n dispatch(tasks: DiscoveryTask[], options?: {\n concurrency?: number\n signal?: AbortSignal\n }): Promise<DiscoveryResult[]>\n}\n\nexport function createLocalDiscoveryDispatcher(worker: KnowledgeDiscoveryWorker): KnowledgeDiscoveryDispatcher {\n return {\n async dispatch(tasks, options = {}) {\n const concurrency = Math.max(1, options.concurrency ?? 4)\n const results: DiscoveryResult[] = []\n let cursor = 0\n async function runNext(): Promise<void> {\n while (cursor < tasks.length) {\n if (options.signal?.aborted) throw new Error('Discovery dispatch aborted')\n const task = tasks[cursor++]!\n results.push(await worker.run(task, options.signal))\n }\n }\n await Promise.all(Array.from({ length: Math.min(concurrency, tasks.length) }, runNext))\n return results.sort((a, b) => tasks.findIndex((task) => task.id === a.taskId) - tasks.findIndex((task) => task.id === b.taskId))\n },\n }\n}\n","export interface ChunkingOptions {\n targetChars: number\n maxChars: number\n minChars: number\n overlapChars: number\n}\n\nexport interface KnowledgeChunk {\n index: number\n text: string\n headingPath: string\n charStart: number\n charEnd: number\n oversized: boolean\n}\n\nconst DEFAULT_OPTIONS: ChunkingOptions = {\n targetChars: 1000,\n maxChars: 1500,\n minChars: 160,\n overlapChars: 180,\n}\n\nexport function chunkMarkdown(content: string, options?: Partial<ChunkingOptions>): KnowledgeChunk[] {\n const opts = normalizeOptions({ ...DEFAULT_OPTIONS, ...(options ?? {}) })\n const { body, bodyOffset } = stripFrontmatter(content)\n if (body.trim() === '') return []\n\n const sections = splitSections(body, bodyOffset)\n const chunks: KnowledgeChunk[] = []\n for (const section of sections) {\n for (const part of chunkText(section.text, opts)) {\n const start = section.start + part.start\n chunks.push({\n index: chunks.length,\n text: part.text,\n headingPath: section.headingPath,\n charStart: start,\n charEnd: start + part.text.length,\n oversized: part.text.length > opts.maxChars,\n })\n }\n }\n return chunks\n}\n\nexport function stripFrontmatter(content: string): { body: string; bodyOffset: number } {\n const normalized = content.replace(/\\r\\n/g, '\\n')\n if (!normalized.startsWith('---\\n')) return { body: normalized, bodyOffset: 0 }\n const match = /^---\\n[\\s\\S]*?\\n---\\s*\\n?/.exec(normalized)\n if (!match) return { body: normalized, bodyOffset: 0 }\n return { body: normalized.slice(match[0].length), bodyOffset: match[0].length }\n}\n\nfunction normalizeOptions(opts: ChunkingOptions): ChunkingOptions {\n if (opts.maxChars < opts.targetChars) opts.maxChars = opts.targetChars\n if (opts.overlapChars >= opts.targetChars) opts.overlapChars = Math.floor(opts.targetChars / 2)\n return opts\n}\n\ninterface Section {\n text: string\n start: number\n headingPath: string\n}\n\nfunction splitSections(body: string, bodyOffset: number): Section[] {\n const lines = body.split('\\n')\n const sections: Section[] = []\n const headings: Record<number, string> = {}\n let current: { lines: string[]; start: number; headingPath: string } = { lines: [], start: bodyOffset, headingPath: '' }\n let cursor = bodyOffset\n let fence: string | null = null\n\n const flush = () => {\n const text = current.lines.join('\\n')\n if (text.trim() !== '') sections.push({ text, start: current.start, headingPath: current.headingPath })\n }\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n const lineLen = line.length + (i < lines.length - 1 ? 1 : 0)\n const fenceMatch = /^(`{3,}|~{3,})/.exec(line)\n if (fenceMatch) {\n const marker = fenceMatch[1]!\n fence = fence === null ? marker : line.startsWith(fence) ? null : fence\n current.lines.push(line)\n cursor += lineLen\n continue\n }\n const heading = fence === null ? /^(#{1,6})\\s+(.+?)\\s*$/.exec(line) : null\n if (heading) {\n flush()\n const level = heading[1]!.length\n headings[level] = heading[2]!.trim()\n for (let next = level + 1; next <= 6; next++) delete headings[next]\n current = {\n lines: [line],\n start: cursor,\n headingPath: Object.entries(headings)\n .sort(([a], [b]) => Number(a) - Number(b))\n .map(([levelText, title]) => `${'#'.repeat(Number(levelText))} ${title}`)\n .join(' > '),\n }\n cursor += lineLen\n continue\n }\n current.lines.push(line)\n cursor += lineLen\n }\n flush()\n return sections\n}\n\nfunction chunkText(text: string, opts: ChunkingOptions): Array<{ text: string; start: number }> {\n if (text.length <= opts.targetChars) return [{ text, start: 0 }]\n const atoms = splitAtoms(text)\n const chunks: Array<{ text: string; start: number }> = []\n let buffer = ''\n let bufferStart = 0\n for (const atom of atoms) {\n if (buffer === '') bufferStart = atom.start\n if (buffer.length > 0 && buffer.length + atom.text.length > opts.targetChars) {\n chunks.push({ text: buffer.trimEnd(), start: bufferStart })\n const overlap = buffer.slice(Math.max(0, buffer.length - opts.overlapChars))\n buffer = overlap + atom.text\n bufferStart = Math.max(bufferStart, atom.start - overlap.length)\n } else {\n buffer += atom.text\n }\n }\n if (buffer.trim() !== '') chunks.push({ text: buffer.trimEnd(), start: bufferStart })\n return mergeTinyChunks(chunks, opts)\n}\n\nfunction splitAtoms(text: string): Array<{ text: string; start: number }> {\n const parts: Array<{ text: string; start: number }> = []\n const paragraphs = text.split(/(\\n\\s*\\n)/)\n let cursor = 0\n for (let i = 0; i < paragraphs.length; i += 2) {\n const paragraph = (paragraphs[i] ?? '') + (paragraphs[i + 1] ?? '')\n if (paragraph === '') continue\n parts.push({ text: paragraph, start: cursor })\n cursor += paragraph.length\n }\n return parts\n}\n\nfunction mergeTinyChunks(chunks: Array<{ text: string; start: number }>, opts: ChunkingOptions): Array<{ text: string; start: number }> {\n const out: Array<{ text: string; start: number }> = []\n for (const chunk of chunks) {\n const prev = out[out.length - 1]\n if (prev && chunk.text.length < opts.minChars && prev.text.length + chunk.text.length <= opts.maxChars) {\n prev.text = `${prev.text}\\n\\n${chunk.text}`\n } else {\n out.push({ ...chunk })\n }\n }\n return out\n}\n","import {\n runMultiShotOptimization,\n type MultiShotMutateAdapter,\n type MultiShotOptimizationConfig,\n type MultiShotOptimizationResult,\n type MultiShotRunner,\n type MultiShotScorer,\n type MultiShotVariant,\n} from '@tangle-network/agent-eval'\nimport type { KnowledgeBaseCandidate } from './types'\n\nexport type KnowledgeBaseVariant = MultiShotVariant<KnowledgeBaseCandidate>\n\nexport interface KnowledgeOptimizationConfig\n extends Omit<\n MultiShotOptimizationConfig<KnowledgeBaseCandidate>,\n 'runner' | 'scorer' | 'mutateAdapter' | 'target'\n > {\n target?: string\n runner: MultiShotRunner<KnowledgeBaseCandidate>\n scorer: MultiShotScorer<KnowledgeBaseCandidate>\n mutateAdapter: MultiShotMutateAdapter<KnowledgeBaseCandidate>\n}\n\nexport async function runKnowledgeBaseOptimization(\n config: KnowledgeOptimizationConfig,\n): Promise<MultiShotOptimizationResult<KnowledgeBaseCandidate>> {\n return runMultiShotOptimization<KnowledgeBaseCandidate>({\n ...config,\n target: config.target ?? 'agent-knowledge-base',\n })\n}\n\nexport function knowledgeVariantFromCandidate(\n candidate: KnowledgeBaseCandidate,\n options: { id?: string; label?: string; generation?: number } = {},\n): KnowledgeBaseVariant {\n return {\n id: options.id ?? candidate.id,\n label: options.label ?? candidate.id,\n generation: options.generation ?? 0,\n payload: candidate,\n }\n}\n","import {\n evaluateReleaseConfidence,\n releaseTraceEvidenceFromMultiShotTrials,\n validateRunRecord,\n type MultiShotOptimizationResult,\n type MultiShotTrialResult,\n type RunRecord,\n type ReleaseConfidenceScorecard,\n} from '@tangle-network/agent-eval'\nimport type { KnowledgeBaseCandidate, KnowledgeRelease } from './types'\nimport { stableId } from './ids'\n\nexport interface KnowledgeReleaseReport {\n release: KnowledgeRelease\n scorecard: ReleaseConfidenceScorecard\n candidateRuns: RunRecord[]\n baselineRuns: RunRecord[]\n}\n\nexport function knowledgeReleaseReportFromOptimization(\n result: MultiShotOptimizationResult<KnowledgeBaseCandidate>,\n options: {\n runRecords?: RunRecord[]\n createdAt?: string\n minScore?: number\n } = {},\n): KnowledgeReleaseReport {\n const trials = result.evolution.generations.flatMap((generation) => generation.trials) as MultiShotTrialResult[]\n const traceEvidence = releaseTraceEvidenceFromMultiShotTrials(trials)\n const runRecords = (options.runRecords ?? [\n ...(result.gate?.candidateRuns ?? []),\n ...(result.gate?.baselineRuns ?? []),\n ]).map(validateRunRecord)\n const scorecard = evaluateReleaseConfidence({\n target: 'agent-knowledge-base',\n candidateId: result.promotedVariant.id,\n baselineId: 'baseline',\n traces: traceEvidence,\n runs: runRecords,\n gateDecision: result.gate?.decision ?? null,\n thresholds: {\n requireCorpus: false,\n requireHoldout: Boolean(result.gate),\n minHoldoutRuns: result.gate ? 1 : 0,\n minSearchRuns: 1,\n minMeanScore: options.minScore ?? 0.7,\n },\n })\n const release: KnowledgeRelease = {\n id: stableId('krel', `${result.promotedVariant.id}:${options.createdAt ?? new Date().toISOString()}`),\n candidateId: result.promotedVariant.id,\n createdAt: options.createdAt ?? new Date().toISOString(),\n promoted: scorecard.status !== 'fail' && result.promotedVariant.id === result.searchBestVariant.id,\n scorecard,\n runRecordIds: runRecords.map((record) => record.runId),\n }\n return {\n release,\n scorecard,\n candidateRuns: result.gate?.candidateRuns ?? [],\n baselineRuns: result.gate?.baselineRuns ?? [],\n }\n}\n","import {\n acquisitionPlansForKnowledgeGaps,\n scoreKnowledgeReadiness,\n userQuestionsForKnowledgeGaps,\n type DataAcquisitionPlan,\n type KnowledgeAcquisitionMode,\n type KnowledgeBundle,\n type KnowledgeFreshness,\n type KnowledgeImportance,\n type KnowledgeReadinessReport,\n type KnowledgeRequirement,\n type KnowledgeRequirementCategory,\n type KnowledgeSensitivity,\n type UserQuestion,\n} from '@tangle-network/agent-eval'\nimport type { KnowledgeIndex, KnowledgeSearchResult } from './types'\nimport { searchKnowledge } from './search'\n\nexport interface KnowledgeReadinessSpec {\n id: string\n description: string\n query: string\n requiredFor: string[]\n category: KnowledgeRequirementCategory\n acquisitionMode: KnowledgeAcquisitionMode\n importance: KnowledgeImportance\n freshness: KnowledgeFreshness\n sensitivity: KnowledgeSensitivity\n confidenceNeeded: number\n fallbackPolicy?: KnowledgeRequirement['fallbackPolicy']\n minSources?: number\n minHits?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface BuildEvalKnowledgeBundleOptions {\n taskId: string\n index: KnowledgeIndex\n specs: KnowledgeReadinessSpec[]\n userAnswers?: Record<string, string>\n searchLimit?: number\n metadata?: Record<string, unknown>\n}\n\nexport interface EvalKnowledgeBundleBuildResult {\n bundle: KnowledgeBundle\n report: KnowledgeReadinessReport\n requirements: KnowledgeRequirement[]\n searchResultsByRequirement: Record<string, KnowledgeSearchResult[]>\n questions: UserQuestion[]\n acquisitionPlans: DataAcquisitionPlan[]\n}\n\nexport function buildEvalKnowledgeBundle(options: BuildEvalKnowledgeBundleOptions): EvalKnowledgeBundleBuildResult {\n const searchLimit = options.searchLimit ?? 5\n const searchResultsByRequirement: Record<string, KnowledgeSearchResult[]> = {}\n const requirements = options.specs.map((spec) => {\n const results = searchKnowledge(options.index, spec.query, searchLimit)\n searchResultsByRequirement[spec.id] = results\n return requirementFromSearch(spec, results)\n })\n const report = scoreKnowledgeReadiness({\n taskId: options.taskId,\n requirements,\n userAnswers: options.userAnswers,\n evidenceIds: requirements.flatMap((requirement) => requirement.evidenceIds),\n claimIds: [],\n wikiPageIds: unique(requirements.flatMap((requirement) => pageIdsFromResults(searchResultsByRequirement[requirement.id] ?? []))),\n metadata: options.metadata,\n })\n const questions = userQuestionsForKnowledgeGaps(report.blockingMissingRequirements)\n const acquisitionPlans = acquisitionPlansForKnowledgeGaps([\n ...report.blockingMissingRequirements,\n ...report.nonBlockingGaps,\n ])\n\n return {\n bundle: report.bundle,\n report,\n requirements,\n searchResultsByRequirement,\n questions,\n acquisitionPlans,\n }\n}\n\nfunction requirementFromSearch(\n spec: KnowledgeReadinessSpec,\n results: KnowledgeSearchResult[],\n): KnowledgeRequirement {\n const hitCount = results.length\n const sourceIds = unique(results.flatMap((result) => result.page.sourceIds))\n const bestScore = results[0]?.normalizedScore ?? 0\n const sourceCoverage = spec.minSources ? Math.min(1, sourceIds.length / spec.minSources) : (sourceIds.length > 0 ? 1 : 0)\n const hitCoverage = spec.minHits ? Math.min(1, hitCount / spec.minHits) : (hitCount > 0 ? 1 : 0)\n const currentConfidence = round(Math.min(bestScore, sourceCoverage, hitCoverage))\n\n return {\n id: spec.id,\n description: spec.description,\n requiredFor: spec.requiredFor,\n category: spec.category,\n acquisitionMode: spec.acquisitionMode,\n importance: spec.importance,\n freshness: spec.freshness,\n sensitivity: spec.sensitivity,\n confidenceNeeded: spec.confidenceNeeded,\n currentConfidence,\n evidenceIds: unique([\n ...sourceIds.map((sourceId) => `source:${sourceId}`),\n ...results.map((result) => `page:${result.page.id}`),\n ]),\n fallbackPolicy: spec.fallbackPolicy ?? (spec.importance === 'blocking' ? 'block' : 'continue_with_caveat'),\n metadata: {\n ...spec.metadata,\n query: spec.query,\n hitCount,\n sourceCount: sourceIds.length,\n bestNormalizedScore: bestScore,\n },\n }\n}\n\nfunction pageIdsFromResults(results: KnowledgeSearchResult[]): string[] {\n return results.map((result) => result.page.id)\n}\n\nfunction unique<T>(items: T[]): T[] {\n return [...new Set(items)]\n}\n\nfunction round(value: number): number {\n return Math.round(value * 1000) / 1000\n}\n"],"mappings":"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","names":["writeJson"]}
|
|
@@ -95,7 +95,23 @@ interface KnowledgeIndex {
|
|
|
95
95
|
}
|
|
96
96
|
interface KnowledgeSearchResult {
|
|
97
97
|
page: KnowledgePage;
|
|
98
|
+
/**
|
|
99
|
+
* Raw reciprocal rank fusion score. Mathematically meaningful for ordering
|
|
100
|
+
* but not on a [0, 1] confidence scale — typical absolute values are in the
|
|
101
|
+
* 0.01–0.05 range. Equal to `rrfScore`; preserved as `score` for backward
|
|
102
|
+
* compatibility with consumers built against earlier releases.
|
|
103
|
+
*/
|
|
98
104
|
score: number;
|
|
105
|
+
/** Alias of `score` — the raw RRF value. Use this when intent matters. */
|
|
106
|
+
rrfScore: number;
|
|
107
|
+
/**
|
|
108
|
+
* Score linearly normalized to [0, 1] relative to the top hit *in this
|
|
109
|
+
* result set*. The top hit is always 1 (when present); subsequent hits are
|
|
110
|
+
* `score / topScore`. Designed to match human intuition for "how confident
|
|
111
|
+
* is this match" — safe to compare against fixed thresholds. Note: this is
|
|
112
|
+
* a within-set ranking, not a cross-query absolute confidence.
|
|
113
|
+
*/
|
|
114
|
+
normalizedScore: number;
|
|
99
115
|
rank: number;
|
|
100
116
|
snippet: string;
|
|
101
117
|
reasons: string[];
|
package/dist/viz/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { K as KnowledgeGraphEdge, a as KnowledgeGraphNode, b as KnowledgeGraph } from '../types-
|
|
1
|
+
import { K as KnowledgeGraphEdge, a as KnowledgeGraphNode, b as KnowledgeGraph } from '../types-CWbf3JSE.js';
|
|
2
2
|
|
|
3
3
|
interface KnowledgeVizNode extends KnowledgeGraphNode {
|
|
4
4
|
degree: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-knowledge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Source-grounded, eval-gated knowledge growth primitives for agents.",
|
|
5
5
|
"homepage": "https://github.com/tangle-network/agent-knowledge#readme",
|
|
6
6
|
"repository": {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"typecheck": "tsc --noEmit"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@tangle-network/agent-eval": "^0.
|
|
54
|
+
"@tangle-network/agent-eval": "^0.20.0",
|
|
55
55
|
"zod": "^4.3.6"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ids.ts","../src/frontmatter.ts","../src/wikilinks.ts","../src/write-protocol.ts","../src/adapters.ts","../src/proposals.ts","../src/schemas.ts","../src/graph.ts","../src/store.ts","../src/sources.ts","../src/search.ts","../src/indexer.ts","../src/lint.ts","../src/inspect.ts","../src/validate.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\n\nexport function sha256(text: string): string {\n return createHash('sha256').update(text).digest('hex')\n}\n\nexport function slugify(input: string): string {\n const out = input\n .trim()\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9\\u4e00-\\u9fff]+/g, '-')\n .replace(/^-+|-+$/g, '')\n return out || 'untitled'\n}\n\nexport function stableId(prefix: string, content: string): string {\n return `${prefix}_${sha256(content).slice(0, 16)}`\n}\n","export interface ParsedFrontmatter {\n frontmatter: Record<string, unknown>\n body: string\n}\n\nexport function parseFrontmatter(content: string): ParsedFrontmatter {\n const normalized = content.replace(/\\r\\n/g, '\\n')\n if (!normalized.startsWith('---\\n')) return { frontmatter: {}, body: normalized }\n const end = normalized.indexOf('\\n---', 4)\n if (end < 0) return { frontmatter: {}, body: normalized }\n const raw = normalized.slice(4, end)\n const after = normalized.slice(end).replace(/^\\n---\\s*\\n?/, '')\n return { frontmatter: parseSimpleYaml(raw), body: after }\n}\n\nexport function formatFrontmatter(frontmatter: Record<string, unknown>, body: string): string {\n const lines = Object.entries(frontmatter)\n .filter(([, value]) => value !== undefined)\n .flatMap(([key, value]) => formatYamlField(key, value))\n if (lines.length === 0) return body\n return `---\\n${lines.join('\\n')}\\n---\\n${body.replace(/^\\n+/, '')}`\n}\n\nfunction parseSimpleYaml(raw: string): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const lines = raw.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n const scalar = /^([A-Za-z0-9_-]+):\\s*(.*)$/.exec(line)\n if (!scalar) continue\n const key = scalar[1]!\n const rest = scalar[2]!.trim()\n if (rest === '') {\n const items: string[] = []\n while (i + 1 < lines.length) {\n const item = /^\\s*-\\s*(.+?)\\s*$/.exec(lines[i + 1]!)\n if (!item) break\n items.push(unquote(item[1]!))\n i++\n }\n out[key] = items\n continue\n }\n if (rest.startsWith('[') && rest.endsWith(']')) {\n out[key] = rest.slice(1, -1).split(',').map((part) => unquote(part.trim())).filter(Boolean)\n } else if (rest === 'true' || rest === 'false') {\n out[key] = rest === 'true'\n } else if (/^-?\\d+(?:\\.\\d+)?$/.test(rest)) {\n out[key] = Number(rest)\n } else {\n out[key] = unquote(rest)\n }\n }\n return out\n}\n\nfunction formatYamlField(key: string, value: unknown): string[] {\n if (Array.isArray(value)) {\n return [key + ':', ...value.map((item) => ` - ${String(item)}`)]\n }\n if (typeof value === 'string') return [`${key}: ${value}`]\n if (typeof value === 'number' || typeof value === 'boolean') return [`${key}: ${String(value)}`]\n return [`${key}: ${JSON.stringify(value)}`]\n}\n\nfunction unquote(value: string): string {\n return value.replace(/^['\"]|['\"]$/g, '')\n}\n","export const WIKILINK_REGEX = /\\[\\[([^\\]|]+?)(?:\\|[^\\]]+?)?\\]\\]/g\n\nexport function extractWikilinks(content: string): string[] {\n const links: string[] = []\n const regex = new RegExp(WIKILINK_REGEX.source, 'g')\n let match: RegExpExecArray | null\n while ((match = regex.exec(content)) !== null) {\n links.push(match[1]!.trim())\n }\n return [...new Set(links)]\n}\n\nexport function normalizeLinkTarget(target: string): string {\n return target.trim().replace(/\\.md$/i, '').toLowerCase().replace(/\\s+/g, '-')\n}\n","import type { KnowledgeWriteParseResult } from './types'\n\nconst OPENER_LINE = /^---\\s*FILE:\\s*(.+?)\\s*---\\s*$/i\nconst CLOSER_LINE = /^---\\s*END\\s+FILE\\s*---\\s*$/i\nconst FENCE_LINE = /^\\s{0,3}(```+|~~~+)/\n\nexport function isSafeKnowledgePath(path: string, allowedPrefixes = ['knowledge/']): boolean {\n if (typeof path !== 'string' || path.trim() === '') return false\n if (/[\\x00-\\x1f]/.test(path)) return false\n if (path.startsWith('/') || path.startsWith('\\\\')) return false\n if (/^[a-zA-Z]:/.test(path)) return false\n const normalized = path.replace(/\\\\/g, '/')\n if (normalized.split('/').some((part) => part === '..')) return false\n return allowedPrefixes.some((prefix) => normalized.startsWith(prefix))\n}\n\nexport function parseKnowledgeWriteBlocks(text: string, allowedPrefixes = ['knowledge/']): KnowledgeWriteParseResult {\n const lines = text.replace(/\\r\\n/g, '\\n').split('\\n')\n const blocks: KnowledgeWriteParseResult['blocks'] = []\n const warnings: string[] = []\n let i = 0\n\n while (i < lines.length) {\n const opener = OPENER_LINE.exec(lines[i]!)\n if (!opener) {\n i++\n continue\n }\n const path = opener[1]!.trim()\n i++\n const contentLines: string[] = []\n let fenceMarker: string | null = null\n let fenceLen = 0\n let closed = false\n\n while (i < lines.length) {\n const line = lines[i]!\n const fence = FENCE_LINE.exec(line)\n if (fence) {\n const run = fence[1]!\n const char = run[0]!\n if (fenceMarker === null) {\n fenceMarker = char\n fenceLen = run.length\n } else if (char === fenceMarker && run.length >= fenceLen) {\n fenceMarker = null\n fenceLen = 0\n }\n contentLines.push(line)\n i++\n continue\n }\n if (fenceMarker === null && CLOSER_LINE.test(line)) {\n closed = true\n i++\n break\n }\n contentLines.push(line)\n i++\n }\n\n if (!closed) {\n warnings.push(`FILE block \"${path || '(empty)'}\" was not closed before end of stream.`)\n continue\n }\n if (!isSafeKnowledgePath(path, allowedPrefixes)) {\n warnings.push(`FILE block with unsafe path \"${path}\" rejected.`)\n continue\n }\n blocks.push({ path, content: contentLines.join('\\n') })\n }\n\n return { blocks, warnings }\n}\n","import type { SourceRecord } from './types'\n\nexport interface SourceAdapterInput {\n uri: string\n bytes?: Uint8Array\n text?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface SourceAdapterOutput {\n title?: string\n mediaType?: string\n text?: string\n anchors?: SourceRecord['anchors']\n metadata?: Record<string, unknown>\n}\n\nexport interface SourceAdapter {\n id: string\n canLoad(input: SourceAdapterInput): boolean\n load(input: SourceAdapterInput): Promise<SourceAdapterOutput> | SourceAdapterOutput\n}\n\nexport const textSourceAdapter: SourceAdapter = {\n id: 'text',\n canLoad: (input) => Boolean(input.text) || /\\.(md|txt|json|csv)$/i.test(input.uri),\n load: (input) => ({\n title: input.uri.split('/').pop(),\n mediaType: mediaTypeFor(input.uri),\n text: decodeText(input),\n anchors: anchorsForText(input.uri, decodeText(input)),\n metadata: input.metadata,\n }),\n}\n\nexport function mediaTypeFor(uri: string): string {\n const lower = uri.toLowerCase()\n if (lower.endsWith('.md')) return 'text/markdown'\n if (lower.endsWith('.txt')) return 'text/plain'\n if (lower.endsWith('.json')) return 'application/json'\n if (lower.endsWith('.csv')) return 'text/csv'\n if (lower.endsWith('.pdf')) return 'application/pdf'\n return 'application/octet-stream'\n}\n\nfunction decodeText(input: SourceAdapterInput): string | undefined {\n return input.text ?? (input.bytes ? new TextDecoder().decode(input.bytes).slice(0, 200_000) : undefined)\n}\n\nfunction anchorsForText(uri: string, text: string | undefined): SourceAdapterOutput['anchors'] {\n if (!text) return []\n const lines = text.split('\\n')\n const anchors: NonNullable<SourceAdapterOutput['anchors']> = [{ id: 'all', sourceId: '', label: 'Full source', lineStart: 1, lineEnd: lines.length }]\n for (let i = 0; i < lines.length; i += 50) {\n anchors.push({\n id: `l${i + 1}`,\n sourceId: '',\n label: `${uri}:${i + 1}`,\n lineStart: i + 1,\n lineEnd: Math.min(lines.length, i + 50),\n })\n }\n return anchors\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { parseKnowledgeWriteBlocks } from './write-protocol'\n\nexport interface ApplyWriteBlocksResult {\n written: string[]\n warnings: string[]\n}\n\nexport async function applyKnowledgeWriteBlocks(\n root: string,\n proposalText: string,\n): Promise<ApplyWriteBlocksResult> {\n const parsed = parseKnowledgeWriteBlocks(proposalText)\n const written: string[] = []\n for (const block of parsed.blocks) {\n const path = join(root, block.path)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, block.content.endsWith('\\n') ? block.content : `${block.content}\\n`, 'utf8')\n written.push(block.path)\n }\n return { written, warnings: parsed.warnings }\n}\n\nexport async function applyKnowledgeWriteBlocksFile(root: string, proposalPath: string): Promise<ApplyWriteBlocksResult> {\n return applyKnowledgeWriteBlocks(root, await readFile(proposalPath, 'utf8'))\n}\n","import { z } from 'zod'\n\nexport const SourceAnchorSchema = z.object({\n id: z.string().min(1),\n sourceId: z.string().min(1),\n label: z.string().optional(),\n page: z.number().int().positive().optional(),\n lineStart: z.number().int().positive().optional(),\n lineEnd: z.number().int().positive().optional(),\n charStart: z.number().int().nonnegative().optional(),\n charEnd: z.number().int().nonnegative().optional(),\n timestampMs: z.number().nonnegative().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const SourceRecordSchema = z.object({\n id: z.string().min(1),\n uri: z.string().min(1),\n title: z.string().optional(),\n mediaType: z.string().optional(),\n contentHash: z.string().min(16),\n text: z.string().optional(),\n anchors: z.array(SourceAnchorSchema).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n createdAt: z.string().min(1),\n})\n\nexport const KnowledgePageSchema = z.object({\n id: z.string().min(1),\n path: z.string().min(1),\n title: z.string().min(1),\n text: z.string(),\n frontmatter: z.record(z.string(), z.unknown()),\n sourceIds: z.array(z.string()),\n tags: z.array(z.string()),\n outLinks: z.array(z.string()),\n})\n\nexport const KnowledgeGraphNodeSchema = z.object({\n id: z.string(),\n title: z.string(),\n path: z.string(),\n tags: z.array(z.string()),\n sourceIds: z.array(z.string()),\n outDegree: z.number().int().nonnegative(),\n inDegree: z.number().int().nonnegative(),\n})\n\nexport const KnowledgeGraphEdgeSchema = z.object({\n source: z.string(),\n target: z.string(),\n weight: z.number(),\n reasons: z.array(z.string()),\n})\n\nexport const KnowledgeIndexSchema = z.object({\n root: z.string(),\n generatedAt: z.string(),\n sources: z.array(SourceRecordSchema),\n pages: z.array(KnowledgePageSchema),\n graph: z.object({\n nodes: z.array(KnowledgeGraphNodeSchema),\n edges: z.array(KnowledgeGraphEdgeSchema),\n }),\n})\n\nexport const KnowledgeEventSchema = z.object({\n id: z.string().min(1),\n type: z.enum(['source.added', 'proposal.applied', 'index.built', 'lint.run', 'optimization.run', 'release.promoted', 'release.rejected']),\n createdAt: z.string().min(1),\n actor: z.string().optional(),\n target: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const KnowledgeBaseCandidateSchema = z.object({\n id: z.string().min(1),\n units: z.array(z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n text: z.string(),\n claims: z.array(z.object({\n id: z.string().min(1),\n text: z.string().min(1),\n refs: z.array(z.object({\n sourceId: z.string().min(1),\n anchorId: z.string().optional(),\n quote: z.string().optional(),\n })),\n confidence: z.number().min(0).max(1).optional(),\n status: z.enum(['draft', 'active', 'superseded', 'rejected']).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n })).optional(),\n relations: z.array(z.object({\n sourceId: z.string(),\n targetId: z.string(),\n predicate: z.string(),\n weight: z.number().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n })).optional(),\n sourceIds: z.array(z.string()).optional(),\n tags: z.array(z.string()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n updatedAt: z.string().optional(),\n })),\n retrievalPolicy: z.string().optional(),\n synthesisPolicy: z.string().optional(),\n questionPolicy: z.string().optional(),\n updatePolicy: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n","import type { KnowledgeGraph, KnowledgeGraphEdge, KnowledgeGraphNode, KnowledgePage } from './types'\nimport { normalizeLinkTarget } from './wikilinks'\n\nexport function buildKnowledgeGraph(pages: KnowledgePage[]): KnowledgeGraph {\n const byId = new Map<string, KnowledgePage>()\n const bySlug = new Map<string, KnowledgePage>()\n for (const page of pages) {\n byId.set(page.id, page)\n bySlug.set(normalizeLinkTarget(page.id), page)\n bySlug.set(normalizeLinkTarget(page.title), page)\n bySlug.set(normalizeLinkTarget(page.path.split('/').pop()!.replace(/\\.md$/, '')), page)\n }\n\n const incoming = new Map<string, number>()\n const outgoing = new Map<string, number>()\n const edgesByKey = new Map<string, KnowledgeGraphEdge>()\n for (const page of pages) {\n outgoing.set(page.id, 0)\n incoming.set(page.id, 0)\n }\n\n for (const page of pages) {\n for (const raw of page.outLinks) {\n const target = bySlug.get(normalizeLinkTarget(raw))\n if (!target || target.id === page.id) continue\n const key = `${page.id}->${target.id}`\n const edge = edgesByKey.get(key)\n if (edge) edge.weight += 1\n else edgesByKey.set(key, { source: page.id, target: target.id, weight: 1, reasons: ['wikilink'] })\n outgoing.set(page.id, (outgoing.get(page.id) ?? 0) + 1)\n incoming.set(target.id, (incoming.get(target.id) ?? 0) + 1)\n }\n }\n\n addSourceOverlapEdges(pages, edgesByKey)\n\n const nodes: KnowledgeGraphNode[] = pages.map((page) => ({\n id: page.id,\n title: page.title,\n path: page.path,\n tags: page.tags,\n sourceIds: page.sourceIds,\n outDegree: outgoing.get(page.id) ?? 0,\n inDegree: incoming.get(page.id) ?? 0,\n }))\n return { nodes, edges: [...edgesByKey.values()].sort((a, b) => b.weight - a.weight) }\n}\n\nfunction addSourceOverlapEdges(pages: KnowledgePage[], edges: Map<string, KnowledgeGraphEdge>): void {\n for (let i = 0; i < pages.length; i++) {\n for (let j = i + 1; j < pages.length; j++) {\n const a = pages[i]!\n const b = pages[j]!\n const overlap = a.sourceIds.filter((source) => b.sourceIds.includes(source))\n if (overlap.length === 0) continue\n const key = `${a.id}->${b.id}`\n const edge = edges.get(key)\n if (edge) {\n edge.weight += overlap.length * 0.5\n edge.reasons.push('shared-source')\n } else {\n edges.set(key, {\n source: a.id,\n target: b.id,\n weight: overlap.length * 0.5,\n reasons: ['shared-source'],\n })\n }\n }\n }\n}\n","import { mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises'\nimport { dirname, join, relative } from 'node:path'\nimport type { KnowledgePage } from './types'\nimport { parseFrontmatter } from './frontmatter'\nimport { slugify } from './ids'\nimport { extractWikilinks, normalizeLinkTarget } from './wikilinks'\n\nexport interface KnowledgeLayout {\n root: string\n knowledgeDir: string\n rawSourcesDir: string\n sourceRegistryPath: string\n indexPath: string\n logPath: string\n cacheDir: string\n}\n\nexport function layoutFor(root: string): KnowledgeLayout {\n return {\n root,\n knowledgeDir: join(root, 'knowledge'),\n rawSourcesDir: join(root, 'raw', 'sources'),\n sourceRegistryPath: join(root, '.agent-knowledge', 'sources.json'),\n indexPath: join(root, 'knowledge', 'index.md'),\n logPath: join(root, 'knowledge', 'log.md'),\n cacheDir: join(root, '.agent-knowledge'),\n }\n}\n\nexport async function initKnowledgeBase(root: string): Promise<KnowledgeLayout> {\n const layout = layoutFor(root)\n await mkdir(layout.knowledgeDir, { recursive: true })\n await mkdir(layout.rawSourcesDir, { recursive: true })\n await mkdir(layout.cacheDir, { recursive: true })\n await writeIfMissing(layout.indexPath, '# Knowledge Index\\n\\n')\n await writeIfMissing(layout.logPath, '# Knowledge Log\\n\\n')\n await writeIfMissing(layout.sourceRegistryPath, '{\\n \"generatedAt\": \"1970-01-01T00:00:00.000Z\",\\n \"sources\": []\\n}\\n')\n return layout\n}\n\nexport async function loadKnowledgePages(root: string): Promise<KnowledgePage[]> {\n const layout = layoutFor(root)\n const files = await listMarkdownFiles(layout.knowledgeDir)\n const pages: KnowledgePage[] = []\n for (const file of files) {\n const content = await readFile(file, 'utf8')\n const { frontmatter, body } = parseFrontmatter(content)\n const rel = relative(root, file).replace(/\\\\/g, '/')\n const title = stringField(frontmatter.title) ?? firstHeading(body) ?? rel.split('/').pop()!.replace(/\\.md$/, '')\n const sourceIds = arrayField(frontmatter.sources)\n const tags = arrayField(frontmatter.tags)\n pages.push({\n id: stringField(frontmatter.id) ?? slugify(rel.replace(/^knowledge\\//, '').replace(/\\.md$/, '')),\n path: rel,\n title,\n text: body,\n frontmatter,\n sourceIds,\n tags,\n outLinks: extractWikilinks(body).map(normalizeLinkTarget),\n })\n }\n pages.sort((a, b) => a.path.localeCompare(b.path))\n return pages\n}\n\nexport async function writeJson(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(value, null, 2) + '\\n', 'utf8')\n}\n\nasync function writeIfMissing(path: string, content: string): Promise<void> {\n try {\n await stat(path)\n } catch {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, content, 'utf8')\n }\n}\n\nasync function listMarkdownFiles(root: string): Promise<string[]> {\n try {\n const entries = await readdir(root, { withFileTypes: true })\n const out: string[] = []\n for (const entry of entries) {\n const full = join(root, entry.name)\n if (entry.isDirectory()) out.push(...await listMarkdownFiles(full))\n else if (entry.isFile() && entry.name.endsWith('.md')) out.push(full)\n }\n return out\n } catch {\n return []\n }\n}\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined\n}\n\nfunction arrayField(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : []\n}\n\nfunction firstHeading(body: string): string | undefined {\n return /^#\\s+(.+)$/m.exec(body)?.[1]?.trim()\n}\n","import { copyFile, mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises'\nimport { basename, dirname, join, relative } from 'node:path'\nimport { textSourceAdapter, type SourceAdapter } from './adapters'\nimport type { SourceRecord, SourceRegistry } from './types'\nimport { sha256, slugify, stableId } from './ids'\nimport { layoutFor } from './store'\n\nexport interface AddSourceOptions {\n copyIntoRaw?: boolean\n adapters?: SourceAdapter[]\n now?: () => Date\n}\n\nexport async function loadSourceRegistry(root: string): Promise<SourceRegistry> {\n const path = sourceRegistryPath(root)\n try {\n const parsed = JSON.parse(await readFile(path, 'utf8')) as SourceRegistry\n return {\n generatedAt: typeof parsed.generatedAt === 'string' ? parsed.generatedAt : new Date(0).toISOString(),\n sources: Array.isArray(parsed.sources) ? parsed.sources : [],\n }\n } catch {\n return { generatedAt: new Date(0).toISOString(), sources: [] }\n }\n}\n\nexport async function writeSourceRegistry(root: string, registry: SourceRegistry): Promise<void> {\n const path = sourceRegistryPath(root)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(registry, null, 2) + '\\n', 'utf8')\n}\n\nexport async function addSourcePath(root: string, sourcePath: string, options: AddSourceOptions = {}): Promise<SourceRecord[]> {\n const s = await stat(sourcePath)\n if (s.isDirectory()) {\n const out: SourceRecord[] = []\n for (const file of await listFiles(sourcePath)) {\n out.push(...await addSourcePath(root, file, options))\n }\n return out\n }\n\n const layout = layoutFor(root)\n await mkdir(layout.rawSourcesDir, { recursive: true })\n const bytes = await readFile(sourcePath)\n const contentHash = sha256(bytes.toString('base64'))\n const fileName = basename(sourcePath)\n const adapters = options.adapters ?? [textSourceAdapter]\n const adapter = adapters.find((candidate) => candidate.canLoad({ uri: sourcePath, bytes }))\n const loaded = adapter ? await adapter.load({ uri: sourcePath, bytes }) : {}\n const id = stableId('src', `${contentHash}:${fileName}`)\n const targetRel = join('raw', 'sources', `${slugify(fileName.replace(/\\.[^.]+$/, ''))}-${contentHash.slice(0, 8)}${ext(fileName)}`).replace(/\\\\/g, '/')\n const targetAbs = join(root, targetRel)\n\n if (options.copyIntoRaw ?? true) {\n await mkdir(dirname(targetAbs), { recursive: true })\n await copyFile(sourcePath, targetAbs)\n }\n\n const existing = await loadSourceRegistry(root)\n const record: SourceRecord = {\n id,\n uri: targetRel,\n title: loaded.title ?? fileName,\n mediaType: loaded.mediaType ?? mediaTypeFor(fileName),\n contentHash,\n text: loaded.text ?? textPreview(fileName, bytes),\n anchors: (loaded.anchors ?? []).map((anchor) => ({ ...anchor, sourceId: id })),\n createdAt: (options.now ?? (() => new Date()))().toISOString(),\n metadata: {\n ...(loaded.metadata ?? {}),\n originalPath: sourcePath,\n sizeBytes: bytes.length,\n projectRelativePath: relative(root, sourcePath).replace(/\\\\/g, '/'),\n },\n }\n const next: SourceRegistry = {\n generatedAt: new Date().toISOString(),\n sources: [record, ...existing.sources.filter((source) => source.id !== id)],\n }\n await writeSourceRegistry(root, next)\n return [record]\n}\n\nexport function sourceRegistryPath(root: string): string {\n return join(layoutFor(root).cacheDir, 'sources.json')\n}\n\nasync function listFiles(root: string): Promise<string[]> {\n const entries = await readdir(root, { withFileTypes: true })\n const out: string[] = []\n for (const entry of entries) {\n const full = join(root, entry.name)\n if (entry.isDirectory()) out.push(...await listFiles(full))\n else if (entry.isFile()) out.push(full)\n }\n return out\n}\n\nfunction ext(fileName: string): string {\n const idx = fileName.lastIndexOf('.')\n return idx >= 0 ? fileName.slice(idx) : ''\n}\n\nfunction mediaTypeFor(fileName: string): string {\n const lower = fileName.toLowerCase()\n if (lower.endsWith('.md')) return 'text/markdown'\n if (lower.endsWith('.txt')) return 'text/plain'\n if (lower.endsWith('.json')) return 'application/json'\n if (lower.endsWith('.csv')) return 'text/csv'\n if (lower.endsWith('.pdf')) return 'application/pdf'\n return 'application/octet-stream'\n}\n\nfunction textPreview(fileName: string, bytes: Buffer): string | undefined {\n const mediaType = mediaTypeFor(fileName)\n if (!mediaType.startsWith('text/') && mediaType !== 'application/json') return undefined\n return bytes.toString('utf8').slice(0, 200_000)\n}\n","import type { KnowledgeIndex, KnowledgePage, KnowledgeSearchResult } from './types'\n\nconst RRF_K = 60\nconst STOP_WORDS = new Set(['the', 'is', 'a', 'an', 'what', 'how', 'are', 'was', 'were', 'to', 'for', 'of', 'with', 'by', 'in', 'on', 'and'])\n\nexport function searchKnowledge(index: KnowledgeIndex, query: string, limit = 10): KnowledgeSearchResult[] {\n const trimmed = query.trim()\n if (trimmed === '') return []\n const tokenRanked = rankByTokens(index.pages, trimmed)\n const graphRanked = rankByGraph(index.pages, tokenRanked)\n const scores = reciprocalRankFusion([tokenRanked.map((p) => p.id), graphRanked.map((p) => p.id)])\n const byId = new Map(index.pages.map((page) => [page.id, page]))\n\n return [...scores.entries()]\n .map(([id, score]) => ({ page: byId.get(id), score }))\n .filter((item): item is { page: KnowledgePage; score: number } => Boolean(item.page))\n .sort((a, b) => b.score - a.score || a.page.path.localeCompare(b.page.path))\n .slice(0, limit)\n .map((item, i) => ({\n page: item.page,\n score: item.score,\n rank: i + 1,\n snippet: buildSnippet(item.page.text, trimmed),\n reasons: reasonsFor(item.page, trimmed),\n }))\n}\n\nexport function tokenizeQuery(query: string): string[] {\n const raw = query\n .toLowerCase()\n .split(/[\\s,,。!?、;:\"\"''()()\\-_/\\\\·~~…]+/)\n .filter((token) => token.length > 1 && !STOP_WORDS.has(token))\n const tokens: string[] = []\n for (const token of raw) {\n if (/[\\u4e00-\\u9fff\\u3400-\\u4dbf]/.test(token) && token.length > 2) {\n const chars = [...token]\n for (let i = 0; i < chars.length - 1; i++) tokens.push(chars[i]! + chars[i + 1]!)\n tokens.push(...chars)\n }\n tokens.push(token)\n }\n return [...new Set(tokens)]\n}\n\nexport function reciprocalRankFusion(rankLists: string[][], k = RRF_K): Map<string, number> {\n const scores = new Map<string, number>()\n for (const list of rankLists) {\n list.forEach((id, idx) => {\n scores.set(id, (scores.get(id) ?? 0) + 1 / (k + idx + 1))\n })\n }\n return scores\n}\n\nfunction rankByTokens(pages: KnowledgePage[], query: string): KnowledgePage[] {\n const tokens = tokenizeQuery(query)\n const effective = tokens.length > 0 ? tokens : [query.toLowerCase()]\n return pages\n .map((page) => ({ page, score: tokenScore(page, query, effective) }))\n .filter((item) => item.score > 0)\n .sort((a, b) => b.score - a.score || a.page.path.localeCompare(b.page.path))\n .map((item) => item.page)\n}\n\nfunction rankByGraph(pages: KnowledgePage[], tokenRanked: KnowledgePage[]): KnowledgePage[] {\n if (tokenRanked.length === 0) return []\n const seeds = new Set(tokenRanked.slice(0, 5).map((page) => page.id))\n return pages\n .map((page) => ({\n page,\n score: page.outLinks.filter((link) => seeds.has(link)).length + page.sourceIds.filter((source) => tokenRanked.some((seed) => seed.sourceIds.includes(source))).length,\n }))\n .filter((item) => item.score > 0)\n .sort((a, b) => b.score - a.score || a.page.path.localeCompare(b.page.path))\n .map((item) => item.page)\n}\n\nfunction tokenScore(page: KnowledgePage, query: string, tokens: string[]): number {\n const title = page.title.toLowerCase()\n const path = page.path.toLowerCase()\n const body = page.text.toLowerCase()\n const phrase = query.toLowerCase()\n let score = 0\n if (path.endsWith(`${phrase}.md`) || title === phrase) score += 200\n if (title.includes(phrase)) score += 50\n if (body.includes(phrase)) score += 20\n for (const token of tokens) {\n if (title.includes(token)) score += 5\n if (body.includes(token)) score += 1\n if (path.includes(token)) score += 3\n }\n return score\n}\n\nfunction buildSnippet(text: string, query: string): string {\n const compact = text.replace(/\\s+/g, ' ').trim()\n const idx = compact.toLowerCase().indexOf(query.toLowerCase())\n if (idx < 0) return compact.slice(0, 180)\n return compact.slice(Math.max(0, idx - 80), Math.min(compact.length, idx + query.length + 100))\n}\n\nfunction reasonsFor(page: KnowledgePage, query: string): string[] {\n const lower = `${page.title}\\n${page.text}`.toLowerCase()\n const reasons: string[] = []\n if (lower.includes(query.toLowerCase())) reasons.push('phrase')\n if (page.sourceIds.length > 0) reasons.push('sourced')\n if (page.outLinks.length > 0) reasons.push('linked')\n return reasons\n}\n","import { join } from 'node:path'\nimport type { KnowledgeIndex } from './types'\nimport { buildKnowledgeGraph } from './graph'\nimport { loadSourceRegistry } from './sources'\nimport { layoutFor, loadKnowledgePages, writeJson } from './store'\n\nexport async function buildKnowledgeIndex(root: string): Promise<KnowledgeIndex> {\n const [pages, sourceRegistry] = await Promise.all([\n loadKnowledgePages(root),\n loadSourceRegistry(root),\n ])\n const index: KnowledgeIndex = {\n root,\n generatedAt: new Date().toISOString(),\n sources: sourceRegistry.sources,\n pages,\n graph: buildKnowledgeGraph(pages),\n }\n return index\n}\n\nexport async function writeKnowledgeIndex(root: string): Promise<KnowledgeIndex> {\n const index = await buildKnowledgeIndex(root)\n await writeJson(join(layoutFor(root).cacheDir, 'index.json'), index)\n return index\n}\n","import type { KnowledgeIndex, KnowledgeLintFinding } from './types'\nimport { normalizeLinkTarget } from './wikilinks'\n\nexport function lintKnowledgeIndex(index: KnowledgeIndex): KnowledgeLintFinding[] {\n const findings: KnowledgeLintFinding[] = []\n const byTarget = new Set<string>()\n const titles = new Map<string, string[]>()\n const sourceIds = new Set(index.sources.map((source) => source.id))\n const anchorIds = new Map(index.sources.map((source) => [source.id, new Set((source.anchors ?? []).map((anchor) => anchor.id))]))\n const pageIds = new Map<string, string[]>()\n const sourceHashes = new Map<string, string[]>()\n for (const page of index.pages) {\n pageIds.set(page.id, [...(pageIds.get(page.id) ?? []), page.path])\n byTarget.add(normalizeLinkTarget(page.id))\n byTarget.add(normalizeLinkTarget(page.title))\n byTarget.add(normalizeLinkTarget(page.path.split('/').pop()!.replace(/\\.md$/, '')))\n const titleKey = page.title.toLowerCase()\n titles.set(titleKey, [...(titles.get(titleKey) ?? []), page.path])\n }\n for (const source of index.sources) {\n sourceHashes.set(source.contentHash, [...(sourceHashes.get(source.contentHash) ?? []), source.id])\n }\n\n const inbound = new Map<string, number>()\n for (const page of index.pages) inbound.set(page.id, 0)\n for (const page of index.pages) {\n if (page.outLinks.length === 0 && !isStructural(page.path)) {\n findings.push({ type: 'no-outlinks', severity: 'info', page: page.path, message: 'Page has no wikilinks to other knowledge pages.' })\n }\n for (const link of page.outLinks) {\n if (!byTarget.has(normalizeLinkTarget(link))) {\n findings.push({ type: 'broken-link', severity: 'warning', page: page.path, message: `Broken wikilink [[${link}]].` })\n }\n }\n }\n\n for (const edge of index.graph.edges) inbound.set(edge.target, (inbound.get(edge.target) ?? 0) + 1)\n for (const page of index.pages) {\n if (!isStructural(page.path) && (inbound.get(page.id) ?? 0) === 0) {\n findings.push({ type: 'orphan', severity: 'info', page: page.path, message: 'No other page links to this page.' })\n }\n if (/\\bclaim\\b/i.test(page.text) && page.sourceIds.length === 0) {\n findings.push({ type: 'uncited-claim', severity: 'warning', page: page.path, message: 'Page appears to contain claims but has no sources frontmatter.' })\n }\n for (const sourceId of page.sourceIds) {\n if (!sourceIds.has(sourceId)) {\n findings.push({ type: 'missing-source', severity: 'error', page: page.path, message: `Page cites unknown source \"${sourceId}\".`, metadata: { sourceId } })\n }\n }\n for (const ref of extractSourceRefs(page.text)) {\n if (!sourceIds.has(ref.sourceId)) {\n findings.push({ type: 'missing-source', severity: 'error', page: page.path, message: `Page cites unknown source \"${ref.sourceId}\".`, metadata: ref })\n } else if (ref.anchorId && !(anchorIds.get(ref.sourceId)?.has(ref.anchorId))) {\n findings.push({ type: 'missing-source', severity: 'error', page: page.path, message: `Page cites unknown source anchor \"${ref.sourceId}#${ref.anchorId}\".`, metadata: ref })\n }\n }\n }\n\n for (const [title, paths] of titles) {\n if (title && paths.length > 1) {\n findings.push({ type: 'duplicate-title', severity: 'warning', message: `Duplicate title \"${title}\" in ${paths.join(', ')}.`, metadata: { paths } })\n }\n }\n for (const [id, paths] of pageIds) {\n if (id && paths.length > 1) {\n findings.push({ type: 'duplicate-page-id', severity: 'error', message: `Duplicate page id \"${id}\" in ${paths.join(', ')}.`, metadata: { paths } })\n }\n }\n for (const [hash, ids] of sourceHashes) {\n if (hash && ids.length > 1) {\n findings.push({ type: 'duplicate-source-hash', severity: 'warning', message: `Duplicate source content hash across ${ids.join(', ')}.`, metadata: { sourceIds: ids } })\n }\n }\n return findings\n}\n\nfunction isStructural(path: string): boolean {\n return path.endsWith('/index.md') || path.endsWith('/log.md') || path === 'knowledge/index.md' || path === 'knowledge/log.md'\n}\n\nfunction extractSourceRefs(text: string): Array<{ sourceId: string; anchorId?: string }> {\n const refs: Array<{ sourceId: string; anchorId?: string }> = []\n const regex = /\\[\\^([A-Za-z0-9_-]+)(?:#([A-Za-z0-9_.:-]+))?\\]/g\n let match: RegExpExecArray | null\n while ((match = regex.exec(text)) !== null) {\n refs.push({ sourceId: match[1]!, anchorId: match[2] })\n }\n return refs\n}\n","import type { KnowledgeIndex, KnowledgeLintFinding, KnowledgePage } from './types'\nimport { lintKnowledgeIndex } from './lint'\nimport { searchKnowledge } from './search'\n\nexport interface KnowledgeInspection {\n pageCount: number\n sourceCount: number\n edgeCount: number\n findingCount: number\n blockingFindingCount: number\n topPages: Array<{ path: string; title: string; degree: number; sources: number }>\n findings: KnowledgeLintFinding[]\n}\n\nexport function inspectKnowledgeIndex(index: KnowledgeIndex): KnowledgeInspection {\n const findings = lintKnowledgeIndex(index)\n const degree = new Map(index.graph.nodes.map((node) => [node.id, node.inDegree + node.outDegree]))\n return {\n pageCount: index.pages.length,\n sourceCount: index.sources.length,\n edgeCount: index.graph.edges.length,\n findingCount: findings.length,\n blockingFindingCount: findings.filter((finding) => finding.severity === 'error').length,\n topPages: [...index.pages]\n .sort((a, b) => (degree.get(b.id) ?? 0) - (degree.get(a.id) ?? 0))\n .slice(0, 10)\n .map((page) => ({ path: page.path, title: page.title, degree: degree.get(page.id) ?? 0, sources: page.sourceIds.length })),\n findings,\n }\n}\n\nexport interface KnowledgeExplanation {\n target: string\n page?: KnowledgePage\n sources: Array<{ id: string; title?: string; uri: string }>\n links: string[]\n inbound: string[]\n related: Array<{ path: string; title: string; score: number }>\n}\n\nexport function explainKnowledgeTarget(index: KnowledgeIndex, target: string): KnowledgeExplanation {\n const page = index.pages.find((candidate) => candidate.path === target || candidate.id === target || candidate.title.toLowerCase() === target.toLowerCase())\n const inbound = page\n ? index.graph.edges.filter((edge) => edge.target === page.id).map((edge) => index.pages.find((candidate) => candidate.id === edge.source)?.path ?? edge.source)\n : []\n const related = page\n ? searchKnowledge(index, `${page.title} ${page.tags.join(' ')}`, 6)\n .filter((result) => result.page.id !== page.id)\n .map((result) => ({ path: result.page.path, title: result.page.title, score: result.score }))\n : searchKnowledge(index, target, 6).map((result) => ({ path: result.page.path, title: result.page.title, score: result.score }))\n return {\n target,\n page,\n sources: page ? index.sources.filter((source) => page.sourceIds.includes(source.id)).map((source) => ({ id: source.id, title: source.title, uri: source.uri })) : [],\n links: page?.outLinks ?? [],\n inbound,\n related,\n }\n}\n","import type { KnowledgeIndex, KnowledgeLintFinding } from './types'\nimport { lintKnowledgeIndex } from './lint'\nimport { KnowledgeIndexSchema } from './schemas'\n\nexport interface ValidateKnowledgeOptions {\n strict?: boolean\n}\n\nexport interface ValidateKnowledgeResult {\n ok: boolean\n findings: KnowledgeLintFinding[]\n}\n\nexport function validateKnowledgeIndex(index: KnowledgeIndex, options: ValidateKnowledgeOptions = {}): ValidateKnowledgeResult {\n const findings = [...lintKnowledgeIndex(index)]\n const parsed = KnowledgeIndexSchema.safeParse(index)\n if (!parsed.success) {\n findings.push({\n type: 'missing-frontmatter',\n severity: 'error',\n message: parsed.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('; '),\n })\n }\n if (options.strict) {\n for (const page of index.pages) {\n if (isStructuralPage(page.path)) continue\n if (!page.frontmatter.id || !page.frontmatter.title) {\n findings.push({\n type: 'missing-frontmatter',\n severity: 'error',\n page: page.path,\n message: 'Strict mode requires id and title frontmatter.',\n })\n }\n }\n }\n return { ok: !findings.some((finding) => finding.severity === 'error'), findings }\n}\n\nfunction isStructuralPage(path: string): boolean {\n return path === 'knowledge/index.md' || path === 'knowledge/log.md' || path.endsWith('/index.md') || path.endsWith('/log.md')\n}\n"],"mappings":"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","names":["mkdir","readFile","writeFile","dirname","join","join","mkdir","readFile","dirname","writeFile","mkdir","readFile","readdir","stat","writeFile","dirname","join","relative","readFile","mkdir","dirname","writeFile","stat","join","mediaTypeFor","relative","readdir","join","join"]}
|