@tangle-network/agent-knowledge 1.1.1 → 1.2.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 +87 -0
- package/dist/{chunk-JWGMOXAT.js → chunk-JLCQ6O7W.js} +40 -1
- package/dist/chunk-JLCQ6O7W.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +166 -4
- package/dist/index.js +182 -1
- package/dist/index.js.map +1 -1
- package/dist/{types-YkFkfwJG.d.ts → types-DTUp66Gr.d.ts} +1 -1
- package/dist/viz/index.d.ts +1 -1
- package/package.json +11 -9
- package/dist/chunk-JWGMOXAT.js.map +0 -1
package/README.md
CHANGED
|
@@ -58,6 +58,13 @@ from `@tangle-network/agent-knowledge`.
|
|
|
58
58
|
- Agent write proposals can be safely applied with `apply-write-blocks`.
|
|
59
59
|
- `KbStore` keeps storage consumer-owned; use `MemoryKbStore`, `FileSystemKbStore`, or implement D1 in the app.
|
|
60
60
|
- Discovery uses worker/dispatcher contracts, with a local dispatcher for dev and tests.
|
|
61
|
+
- `runKnowledgeResearchLoop()` provides thin loop mechanics for researcher
|
|
62
|
+
agents: ingest sources, apply safe write blocks, rebuild the index,
|
|
63
|
+
lint/validate, score readiness, and return a transcript. The agent still
|
|
64
|
+
decides what to research, what to write, and when the wiki is good enough.
|
|
65
|
+
- `createKnowledgeControlLoopAdapter()` maps those mechanics into
|
|
66
|
+
`agent-eval`'s `runAgentControlLoop()` so products can plug in their own
|
|
67
|
+
proposer, reviewer, and driver policies.
|
|
61
68
|
- Zod schemas define the stable wire shape.
|
|
62
69
|
- Graph/search/lint are deterministic and fast.
|
|
63
70
|
- `searchKnowledge` returns hits with three score fields. `score` and
|
|
@@ -111,3 +118,83 @@ console.log(readiness.report.recommendedAction)
|
|
|
111
118
|
Pass `readiness.report` to `blockingKnowledgeEval()` from
|
|
112
119
|
`@tangle-network/agent-eval`; use `readiness.questions` and
|
|
113
120
|
`readiness.acquisitionPlans` to drive UI or connector workflows.
|
|
121
|
+
|
|
122
|
+
## Research Loop
|
|
123
|
+
|
|
124
|
+
Use `runKnowledgeResearchLoop()` when an agent is acting as a researcher or
|
|
125
|
+
librarian. Keep the loop small: the package handles deterministic mechanics;
|
|
126
|
+
your agent handles judgment.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import {
|
|
130
|
+
defineReadinessSpec,
|
|
131
|
+
runKnowledgeResearchLoop,
|
|
132
|
+
} from '@tangle-network/agent-knowledge'
|
|
133
|
+
|
|
134
|
+
await runKnowledgeResearchLoop({
|
|
135
|
+
root: './kb',
|
|
136
|
+
goal: 'Build a grounded onboarding wiki for billing support',
|
|
137
|
+
readinessSpecs: [defineReadinessSpec({
|
|
138
|
+
id: 'refund-policy',
|
|
139
|
+
description: 'Refund policy grounding',
|
|
140
|
+
query: 'refund policy customer request',
|
|
141
|
+
requiredFor: ['support-agent'],
|
|
142
|
+
})],
|
|
143
|
+
async step({ iteration, index, readiness }) {
|
|
144
|
+
// Call your researcher/LLM/browser/connector workflow here.
|
|
145
|
+
if (iteration > 1 && readiness?.report.blockingMissingRequirements.length === 0) {
|
|
146
|
+
return { done: true, notes: 'ready for eval' }
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
sourceTexts: [{
|
|
150
|
+
uri: 'research://refund-policy',
|
|
151
|
+
title: 'Refund Policy Source',
|
|
152
|
+
text: 'Source text gathered by the researcher.',
|
|
153
|
+
}],
|
|
154
|
+
proposalText: [
|
|
155
|
+
'---FILE: knowledge/support/refund-policy.md---',
|
|
156
|
+
'---',
|
|
157
|
+
'id: refund-policy',
|
|
158
|
+
'title: Refund Policy',
|
|
159
|
+
'---',
|
|
160
|
+
'# Refund Policy',
|
|
161
|
+
'Grounded summary written by the researcher.',
|
|
162
|
+
'---END FILE---',
|
|
163
|
+
].join('\n'),
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
})
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
This is intentionally not a crawler, prompt framework, or agent. It is the
|
|
170
|
+
repeatable shell around one.
|
|
171
|
+
|
|
172
|
+
For full `agent-eval` control-loop integration, use
|
|
173
|
+
`createKnowledgeControlLoopAdapter()` and provide `decide` yourself:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
import { runAgentControlLoop } from '@tangle-network/agent-eval'
|
|
177
|
+
import { createKnowledgeControlLoopAdapter } from '@tangle-network/agent-knowledge'
|
|
178
|
+
|
|
179
|
+
const adapter = createKnowledgeControlLoopAdapter({
|
|
180
|
+
root: './kb',
|
|
181
|
+
goal: 'Maintain the billing support wiki',
|
|
182
|
+
readinessSpecs,
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
await runAgentControlLoop({
|
|
186
|
+
...adapter,
|
|
187
|
+
async decide({ state, evals }) {
|
|
188
|
+
if (state.previousSteps.length > 0 && evals.every((e) => e.passed)) {
|
|
189
|
+
return { type: 'stop', pass: true, reason: 'knowledge ready' }
|
|
190
|
+
}
|
|
191
|
+
const proposal = await proposerAgent(state)
|
|
192
|
+
const review = await reviewerAgent({ ...state, proposal })
|
|
193
|
+
return {
|
|
194
|
+
type: 'continue',
|
|
195
|
+
reason: review.summary,
|
|
196
|
+
action: driverPolicy({ proposal, review }),
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
})
|
|
200
|
+
```
|
|
@@ -548,6 +548,44 @@ async function addSourcePath(root, sourcePath, options = {}) {
|
|
|
548
548
|
await writeSourceRegistry(root, next);
|
|
549
549
|
return [record];
|
|
550
550
|
}
|
|
551
|
+
async function addSourceText(root, input, options = {}) {
|
|
552
|
+
const text = input.text;
|
|
553
|
+
const contentHash = sha256(text);
|
|
554
|
+
const fileName = basename(input.uri) || `${slugify(input.title ?? input.uri)}.txt`;
|
|
555
|
+
const adapterInput = { uri: input.uri, text, metadata: input.metadata };
|
|
556
|
+
const adapter = (options.adapters ?? [textSourceAdapter]).find((candidate) => candidate.canLoad(adapterInput));
|
|
557
|
+
const loaded = adapter ? await adapter.load(adapterInput) : {};
|
|
558
|
+
const id = stableId("src", `${contentHash}:${input.uri}`);
|
|
559
|
+
const targetRel = join3("raw", "sources", `${slugify(fileName.replace(/\.[^.]+$/, ""))}-${contentHash.slice(0, 8)}.txt`).replace(/\\/g, "/");
|
|
560
|
+
const targetAbs = join3(root, targetRel);
|
|
561
|
+
await mkdir3(dirname3(targetAbs), { recursive: true });
|
|
562
|
+
await writeFile3(targetAbs, text.endsWith("\n") ? text : `${text}
|
|
563
|
+
`, "utf8");
|
|
564
|
+
const existing = await loadSourceRegistry(root);
|
|
565
|
+
const record = {
|
|
566
|
+
id,
|
|
567
|
+
uri: targetRel,
|
|
568
|
+
title: input.title ?? loaded.title ?? fileName,
|
|
569
|
+
mediaType: input.mediaType ?? loaded.mediaType ?? "text/plain",
|
|
570
|
+
contentHash,
|
|
571
|
+
text: loaded.text ?? text.slice(0, 2e5),
|
|
572
|
+
anchors: (loaded.anchors ?? []).map((anchor) => ({ ...anchor, sourceId: id })),
|
|
573
|
+
validUntil: input.validUntil,
|
|
574
|
+
lastVerifiedAt: input.lastVerifiedAt,
|
|
575
|
+
createdAt: (options.now ?? (() => /* @__PURE__ */ new Date()))().toISOString(),
|
|
576
|
+
metadata: {
|
|
577
|
+
...loaded.metadata ?? {},
|
|
578
|
+
...input.metadata ?? {},
|
|
579
|
+
originalUri: input.uri,
|
|
580
|
+
sizeBytes: Buffer.byteLength(text, "utf8")
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
await writeSourceRegistry(root, {
|
|
584
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
585
|
+
sources: [record, ...existing.sources.filter((source) => source.id !== id)]
|
|
586
|
+
});
|
|
587
|
+
return record;
|
|
588
|
+
}
|
|
551
589
|
function sourceRegistryPath(root) {
|
|
552
590
|
return join3(layoutFor(root).cacheDir, "sources.json");
|
|
553
591
|
}
|
|
@@ -880,6 +918,7 @@ export {
|
|
|
880
918
|
loadSourceRegistry,
|
|
881
919
|
writeSourceRegistry,
|
|
882
920
|
addSourcePath,
|
|
921
|
+
addSourceText,
|
|
883
922
|
sourceRegistryPath,
|
|
884
923
|
searchKnowledge,
|
|
885
924
|
tokenizeQuery,
|
|
@@ -891,4 +930,4 @@ export {
|
|
|
891
930
|
explainKnowledgeTarget,
|
|
892
931
|
validateKnowledgeIndex
|
|
893
932
|
};
|
|
894
|
-
//# sourceMappingURL=chunk-
|
|
933
|
+
//# sourceMappingURL=chunk-JLCQ6O7W.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 interface AddSourceTextInput {\n uri: string\n text: string\n title?: string\n mediaType?: string\n validUntil?: string\n lastVerifiedAt?: string\n metadata?: Record<string, unknown>\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 async function addSourceText(\n root: string,\n input: AddSourceTextInput,\n options: Pick<AddSourceOptions, 'adapters' | 'now'> = {},\n): Promise<SourceRecord> {\n const text = input.text\n const contentHash = sha256(text)\n const fileName = basename(input.uri) || `${slugify(input.title ?? input.uri)}.txt`\n const adapterInput = { uri: input.uri, text, metadata: input.metadata }\n const adapter = (options.adapters ?? [textSourceAdapter]).find((candidate) => candidate.canLoad(adapterInput))\n const loaded = adapter ? await adapter.load(adapterInput) : {}\n const id = stableId('src', `${contentHash}:${input.uri}`)\n const targetRel = join('raw', 'sources', `${slugify(fileName.replace(/\\.[^.]+$/, ''))}-${contentHash.slice(0, 8)}.txt`).replace(/\\\\/g, '/')\n const targetAbs = join(root, targetRel)\n await mkdir(dirname(targetAbs), { recursive: true })\n await writeFile(targetAbs, text.endsWith('\\n') ? text : `${text}\\n`, 'utf8')\n\n const existing = await loadSourceRegistry(root)\n const record: SourceRecord = {\n id,\n uri: targetRel,\n title: input.title ?? loaded.title ?? fileName,\n mediaType: input.mediaType ?? loaded.mediaType ?? 'text/plain',\n contentHash,\n text: loaded.text ?? text.slice(0, 200_000),\n anchors: (loaded.anchors ?? []).map((anchor) => ({ ...anchor, sourceId: id })),\n validUntil: input.validUntil,\n lastVerifiedAt: input.lastVerifiedAt,\n createdAt: (options.now ?? (() => new Date()))().toISOString(),\n metadata: {\n ...(loaded.metadata ?? {}),\n ...(input.metadata ?? {}),\n originalUri: input.uri,\n sizeBytes: Buffer.byteLength(text, 'utf8'),\n },\n }\n await writeSourceRegistry(root, {\n generatedAt: new Date().toISOString(),\n sources: [record, ...existing.sources.filter((source) => source.id !== id)],\n })\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 expiredSourceCount: number\n staleSourceCount: number\n edgeCount: number\n findingCount: number\n blockingFindingCount: number\n topPages: Array<{ path: string; title: string; degree: number; sources: number }>\n sourceFreshness: SourceFreshnessInspection[]\n findings: KnowledgeLintFinding[]\n}\n\nexport interface SourceFreshnessInspection {\n id: string\n title?: string\n uri: string\n status: 'fresh' | 'expired' | 'unknown'\n validUntil?: string\n lastVerifiedAt?: string\n}\n\nexport function inspectKnowledgeIndex(index: KnowledgeIndex, options: { now?: Date } = {}): KnowledgeInspection {\n const now = options.now ?? new Date()\n const findings = lintKnowledgeIndex(index)\n const degree = new Map(index.graph.nodes.map((node) => [node.id, node.inDegree + node.outDegree]))\n const sourceFreshness = index.sources.map((source) => inspectSourceFreshness(source, now))\n return {\n pageCount: index.pages.length,\n sourceCount: index.sources.length,\n expiredSourceCount: sourceFreshness.filter((source) => source.status === 'expired').length,\n staleSourceCount: sourceFreshness.filter((source) => source.status !== 'fresh').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 sourceFreshness,\n findings,\n }\n}\n\nfunction inspectSourceFreshness(source: KnowledgeIndex['sources'][number], now: Date): SourceFreshnessInspection {\n const validUntil = source.validUntil ?? stringMetadata(source.metadata, 'validUntil') ?? stringMetadata(source.metadata, 'expiresAt')\n const lastVerifiedAt = source.lastVerifiedAt ?? stringMetadata(source.metadata, 'lastVerifiedAt')\n const status = validUntil && Number.isFinite(Date.parse(validUntil))\n ? Date.parse(validUntil) <= now.getTime() ? 'expired' : 'fresh'\n : 'unknown'\n return { id: source.id, title: source.title, uri: source.uri, status, validUntil, lastVerifiedAt }\n}\n\nfunction stringMetadata(metadata: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = metadata?.[key]\n return typeof value === 'string' ? value : undefined\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-DTUp66Gr.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-DTUp66Gr.js';
|
|
3
3
|
import { z } from 'zod';
|
|
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';
|
|
4
|
+
import { MultiShotVariant, MultiShotOptimizationConfig, MultiShotRunner, MultiShotScorer, MultiShotMutateAdapter, MultiShotOptimizationResult, ReleaseConfidenceScorecard, RunRecord, KnowledgeRequirementCategory, KnowledgeAcquisitionMode, KnowledgeImportance, KnowledgeFreshness, KnowledgeSensitivity, KnowledgeRequirement, KnowledgeBundle, KnowledgeReadinessReport, UserQuestion, DataAcquisitionPlan, ControlRuntimeConfig, ControlEvalResult } from '@tangle-network/agent-eval';
|
|
5
5
|
|
|
6
6
|
declare function sha256(text: string): string;
|
|
7
7
|
declare function slugify(input: string): string;
|
|
@@ -354,9 +354,19 @@ interface AddSourceOptions {
|
|
|
354
354
|
adapters?: SourceAdapter[];
|
|
355
355
|
now?: () => Date;
|
|
356
356
|
}
|
|
357
|
+
interface AddSourceTextInput {
|
|
358
|
+
uri: string;
|
|
359
|
+
text: string;
|
|
360
|
+
title?: string;
|
|
361
|
+
mediaType?: string;
|
|
362
|
+
validUntil?: string;
|
|
363
|
+
lastVerifiedAt?: string;
|
|
364
|
+
metadata?: Record<string, unknown>;
|
|
365
|
+
}
|
|
357
366
|
declare function loadSourceRegistry(root: string): Promise<SourceRegistry>;
|
|
358
367
|
declare function writeSourceRegistry(root: string, registry: SourceRegistry): Promise<void>;
|
|
359
368
|
declare function addSourcePath(root: string, sourcePath: string, options?: AddSourceOptions): Promise<SourceRecord[]>;
|
|
369
|
+
declare function addSourceText(root: string, input: AddSourceTextInput, options?: Pick<AddSourceOptions, 'adapters' | 'now'>): Promise<SourceRecord>;
|
|
360
370
|
declare function sourceRegistryPath(root: string): string;
|
|
361
371
|
|
|
362
372
|
declare function buildKnowledgeGraph(pages: KnowledgePage[]): KnowledgeGraph;
|
|
@@ -467,6 +477,61 @@ interface KnowledgeReadinessSpec {
|
|
|
467
477
|
minHits?: number;
|
|
468
478
|
metadata?: Record<string, unknown>;
|
|
469
479
|
}
|
|
480
|
+
/**
|
|
481
|
+
* Defaults applied by `defineReadinessSpec` when the caller omits the field.
|
|
482
|
+
*
|
|
483
|
+
* These are deliberately conservative: a domain-specific topic that an agent
|
|
484
|
+
* needs grounded to a high-confidence threshold from at least one authoritative
|
|
485
|
+
* source. Override any field to specialise (e.g. `freshness: 'daily'` for a
|
|
486
|
+
* topic that must reflect today's regulatory state).
|
|
487
|
+
*/
|
|
488
|
+
declare const READINESS_SPEC_DEFAULTS: {
|
|
489
|
+
readonly category: "domain_specific";
|
|
490
|
+
readonly acquisitionMode: "search_web";
|
|
491
|
+
readonly importance: "high";
|
|
492
|
+
readonly freshness: "monthly";
|
|
493
|
+
readonly sensitivity: "public";
|
|
494
|
+
readonly confidenceNeeded: 0.7;
|
|
495
|
+
readonly minSources: 1;
|
|
496
|
+
readonly minHits: 2;
|
|
497
|
+
};
|
|
498
|
+
/**
|
|
499
|
+
* Inputs accepted by `defineReadinessSpec`. The four fields the caller cannot
|
|
500
|
+
* sanely default (id, description, query, requiredFor) are required; everything
|
|
501
|
+
* else is optional and pulls from `READINESS_SPEC_DEFAULTS`.
|
|
502
|
+
*/
|
|
503
|
+
type DefineReadinessSpecInput = Pick<KnowledgeReadinessSpec, 'id' | 'description' | 'query' | 'requiredFor'> & Partial<Omit<KnowledgeReadinessSpec, 'id' | 'description' | 'query' | 'requiredFor'>>;
|
|
504
|
+
/**
|
|
505
|
+
* Builder that returns a fully-typed `KnowledgeReadinessSpec` from a slim input.
|
|
506
|
+
*
|
|
507
|
+
* Motivation: `KnowledgeReadinessSpec` has eleven required fields. Most of them
|
|
508
|
+
* (category, acquisition mode, importance, freshness, sensitivity, confidence
|
|
509
|
+
* threshold, source/hit minima) have a clear default for domain-specific KB
|
|
510
|
+
* topics — agents end up copy-pasting the same boilerplate across every spec.
|
|
511
|
+
* This helper collapses that boilerplate while keeping every field overridable.
|
|
512
|
+
*
|
|
513
|
+
* @example
|
|
514
|
+
* defineReadinessSpec({
|
|
515
|
+
* id: 'coop/intent-grounding',
|
|
516
|
+
* description: 'Required grounding for coop pack intent stage',
|
|
517
|
+
* query: 'flock size space ventilation predator',
|
|
518
|
+
* requiredFor: ['IntentIntakeAgent', 'requirements'],
|
|
519
|
+
* })
|
|
520
|
+
*
|
|
521
|
+
* @example // override defaults where the topic demands it
|
|
522
|
+
* defineReadinessSpec({
|
|
523
|
+
* id: 'medical/dosing',
|
|
524
|
+
* description: 'Dosing guidance for compounding pharmacy',
|
|
525
|
+
* query: 'compounding dose schedule',
|
|
526
|
+
* requiredFor: ['DosingAgent'],
|
|
527
|
+
* importance: 'blocking',
|
|
528
|
+
* freshness: 'daily',
|
|
529
|
+
* sensitivity: 'private',
|
|
530
|
+
* confidenceNeeded: 0.95,
|
|
531
|
+
* minSources: 3,
|
|
532
|
+
* })
|
|
533
|
+
*/
|
|
534
|
+
declare function defineReadinessSpec(input: DefineReadinessSpecInput): KnowledgeReadinessSpec;
|
|
470
535
|
interface BuildEvalKnowledgeBundleOptions {
|
|
471
536
|
taskId: string;
|
|
472
537
|
index: KnowledgeIndex;
|
|
@@ -486,4 +551,101 @@ interface EvalKnowledgeBundleBuildResult {
|
|
|
486
551
|
}
|
|
487
552
|
declare function buildEvalKnowledgeBundle(options: BuildEvalKnowledgeBundleOptions): EvalKnowledgeBundleBuildResult;
|
|
488
553
|
|
|
489
|
-
|
|
554
|
+
interface KnowledgeResearchLoopContext {
|
|
555
|
+
root: string;
|
|
556
|
+
goal: string;
|
|
557
|
+
iteration: number;
|
|
558
|
+
index: KnowledgeIndex;
|
|
559
|
+
lintFindings: KnowledgeLintFinding[];
|
|
560
|
+
validation: ValidateKnowledgeResult;
|
|
561
|
+
readiness?: EvalKnowledgeBundleBuildResult;
|
|
562
|
+
previousSteps: KnowledgeResearchLoopStep[];
|
|
563
|
+
signal?: AbortSignal;
|
|
564
|
+
}
|
|
565
|
+
interface KnowledgeResearchLoopDecision {
|
|
566
|
+
/**
|
|
567
|
+
* Free-form notes from the researcher. Keep this human-readable; products can
|
|
568
|
+
* store it as the research transcript.
|
|
569
|
+
*/
|
|
570
|
+
notes?: string;
|
|
571
|
+
/**
|
|
572
|
+
* Local files to register as immutable sources before applying proposals.
|
|
573
|
+
*/
|
|
574
|
+
sourcePaths?: string[];
|
|
575
|
+
/**
|
|
576
|
+
* Textual source artifacts discovered by an agent, browser worker, connector,
|
|
577
|
+
* or deep-research process.
|
|
578
|
+
*/
|
|
579
|
+
sourceTexts?: AddSourceTextInput[];
|
|
580
|
+
/**
|
|
581
|
+
* Safe write protocol text. The loop parses and applies only accepted
|
|
582
|
+
* `---FILE: knowledge/...---` blocks.
|
|
583
|
+
*/
|
|
584
|
+
proposalText?: string;
|
|
585
|
+
/**
|
|
586
|
+
* The researcher decides when the wiki is good enough. The loop deliberately
|
|
587
|
+
* does not encode a domain-specific definition of "done".
|
|
588
|
+
*/
|
|
589
|
+
done?: boolean;
|
|
590
|
+
metadata?: Record<string, unknown>;
|
|
591
|
+
}
|
|
592
|
+
interface KnowledgeResearchLoopStep {
|
|
593
|
+
iteration: number;
|
|
594
|
+
notes?: string;
|
|
595
|
+
addedSources: SourceRecord[];
|
|
596
|
+
applied?: ApplyWriteBlocksResult;
|
|
597
|
+
lintFindings: KnowledgeLintFinding[];
|
|
598
|
+
validation: ValidateKnowledgeResult;
|
|
599
|
+
readiness?: EvalKnowledgeBundleBuildResult;
|
|
600
|
+
event: KnowledgeEvent;
|
|
601
|
+
done: boolean;
|
|
602
|
+
metadata?: Record<string, unknown>;
|
|
603
|
+
}
|
|
604
|
+
interface RunKnowledgeResearchLoopOptions {
|
|
605
|
+
root: string;
|
|
606
|
+
goal: string;
|
|
607
|
+
maxIterations?: number;
|
|
608
|
+
actor?: string;
|
|
609
|
+
strict?: ValidateKnowledgeOptions['strict'];
|
|
610
|
+
readinessSpecs?: KnowledgeReadinessSpec[];
|
|
611
|
+
readinessTaskId?: string;
|
|
612
|
+
readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>;
|
|
613
|
+
sourceOptions?: Pick<AddSourceOptions, 'adapters' | 'now'>;
|
|
614
|
+
signal?: AbortSignal;
|
|
615
|
+
step(context: KnowledgeResearchLoopContext): Promise<KnowledgeResearchLoopDecision> | KnowledgeResearchLoopDecision;
|
|
616
|
+
onStep?: (step: KnowledgeResearchLoopStep) => Promise<void> | void;
|
|
617
|
+
}
|
|
618
|
+
interface KnowledgeResearchLoopResult {
|
|
619
|
+
root: string;
|
|
620
|
+
goal: string;
|
|
621
|
+
iterations: number;
|
|
622
|
+
done: boolean;
|
|
623
|
+
index: KnowledgeIndex;
|
|
624
|
+
lintFindings: KnowledgeLintFinding[];
|
|
625
|
+
validation: ValidateKnowledgeResult;
|
|
626
|
+
readiness?: EvalKnowledgeBundleBuildResult;
|
|
627
|
+
steps: KnowledgeResearchLoopStep[];
|
|
628
|
+
}
|
|
629
|
+
type KnowledgeControlLoopState = KnowledgeResearchLoopContext;
|
|
630
|
+
type KnowledgeControlLoopAction = KnowledgeResearchLoopDecision;
|
|
631
|
+
type KnowledgeControlLoopActionResult = KnowledgeResearchLoopStep;
|
|
632
|
+
interface KnowledgeControlLoopAdapterOptions {
|
|
633
|
+
root: string;
|
|
634
|
+
goal: string;
|
|
635
|
+
actor?: string;
|
|
636
|
+
strict?: ValidateKnowledgeOptions['strict'];
|
|
637
|
+
readinessSpecs?: KnowledgeReadinessSpec[];
|
|
638
|
+
readinessTaskId?: string;
|
|
639
|
+
readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>;
|
|
640
|
+
sourceOptions?: Pick<AddSourceOptions, 'adapters' | 'now'>;
|
|
641
|
+
}
|
|
642
|
+
type KnowledgeControlLoopAdapter = Pick<ControlRuntimeConfig<KnowledgeControlLoopState, KnowledgeControlLoopAction, KnowledgeControlLoopActionResult, ControlEvalResult>, 'intent' | 'observe' | 'validate' | 'act' | 'shouldStop'>;
|
|
643
|
+
/**
|
|
644
|
+
* Adapter for running knowledge growth through `agent-eval`'s generic control
|
|
645
|
+
* runtime. The caller still owns `decide`: that can be a proposer agent,
|
|
646
|
+
* reviewer agent, deterministic policy, or a composition of all three.
|
|
647
|
+
*/
|
|
648
|
+
declare function createKnowledgeControlLoopAdapter(options: KnowledgeControlLoopAdapterOptions): KnowledgeControlLoopAdapter;
|
|
649
|
+
declare function runKnowledgeResearchLoop(options: RunKnowledgeResearchLoopOptions): Promise<KnowledgeResearchLoopResult>;
|
|
650
|
+
|
|
651
|
+
export { type AddSourceOptions, type AddSourceTextInput, type ApplyWriteBlocksResult, type BuildEvalKnowledgeBundleOptions, type ChunkingOptions, type DefineReadinessSpecInput, type DiscoveryResult, type DiscoveryTask, type EvalKnowledgeBundleBuildResult, FileSystemKbStore, type KbStore, KnowledgeBaseCandidate, KnowledgeBaseCandidateSchema, type KnowledgeBaseVariant, type KnowledgeChunk, type KnowledgeControlLoopAction, type KnowledgeControlLoopActionResult, type KnowledgeControlLoopAdapter, type KnowledgeControlLoopAdapterOptions, type KnowledgeControlLoopState, 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, type KnowledgeResearchLoopContext, type KnowledgeResearchLoopDecision, type KnowledgeResearchLoopResult, type KnowledgeResearchLoopStep, KnowledgeSearchResult, KnowledgeWriteParseResult, MemoryKbStore, type ParsedFrontmatter, READINESS_SPEC_DEFAULTS, type RunKnowledgeResearchLoopOptions, SCAFFOLD_PAGE_BASENAMES, type SourceAdapter, type SourceAdapterInput, type SourceAdapterOutput, SourceAnchorSchema, type SourceFreshnessInspection, SourceRecord, SourceRecordSchema, SourceRegistry, type ValidateKnowledgeOptions, type ValidateKnowledgeResult, WIKILINK_REGEX, addSourcePath, addSourceText, applyKnowledgeWriteBlocks, applyKnowledgeWriteBlocksFile, buildEvalKnowledgeBundle, buildKnowledgeGraph, buildKnowledgeIndex, chunkMarkdown, createKnowledgeControlLoopAdapter, createKnowledgeEvent, createLocalDiscoveryDispatcher, defineReadinessSpec, explainKnowledgeTarget, extractWikilinks, formatFrontmatter, initKnowledgeBase, inspectKnowledgeIndex, isSafeKnowledgePath, isScaffoldPath, knowledgeReleaseReportFromOptimization, knowledgeVariantFromCandidate, layoutFor, lintKnowledgeIndex, loadKnowledgePages, loadSourceRegistry, mediaTypeFor, normalizeLinkTarget, parseFrontmatter, parseKnowledgeWriteBlocks, reciprocalRankFusion, runKnowledgeBaseOptimization, runKnowledgeResearchLoop, searchKnowledge, sha256, slugify, sourceRegistryPath, stableId, stripFrontmatter, textSourceAdapter, tokenizeQuery, validateKnowledgeIndex, writeJson, writeKnowledgeIndex, writeSourceRegistry };
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
SourceRecordSchema,
|
|
11
11
|
WIKILINK_REGEX,
|
|
12
12
|
addSourcePath,
|
|
13
|
+
addSourceText,
|
|
13
14
|
applyKnowledgeWriteBlocks,
|
|
14
15
|
applyKnowledgeWriteBlocksFile,
|
|
15
16
|
buildKnowledgeGraph,
|
|
@@ -41,7 +42,7 @@ import {
|
|
|
41
42
|
writeJson,
|
|
42
43
|
writeKnowledgeIndex,
|
|
43
44
|
writeSourceRegistry
|
|
44
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-JLCQ6O7W.js";
|
|
45
46
|
|
|
46
47
|
// src/events.ts
|
|
47
48
|
function createKnowledgeEvent(input) {
|
|
@@ -351,6 +352,22 @@ import {
|
|
|
351
352
|
scoreKnowledgeReadiness,
|
|
352
353
|
userQuestionsForKnowledgeGaps
|
|
353
354
|
} from "@tangle-network/agent-eval";
|
|
355
|
+
var READINESS_SPEC_DEFAULTS = {
|
|
356
|
+
category: "domain_specific",
|
|
357
|
+
acquisitionMode: "search_web",
|
|
358
|
+
importance: "high",
|
|
359
|
+
freshness: "monthly",
|
|
360
|
+
sensitivity: "public",
|
|
361
|
+
confidenceNeeded: 0.7,
|
|
362
|
+
minSources: 1,
|
|
363
|
+
minHits: 2
|
|
364
|
+
};
|
|
365
|
+
function defineReadinessSpec(input) {
|
|
366
|
+
return {
|
|
367
|
+
...READINESS_SPEC_DEFAULTS,
|
|
368
|
+
...input
|
|
369
|
+
};
|
|
370
|
+
}
|
|
354
371
|
function buildEvalKnowledgeBundle(options) {
|
|
355
372
|
const searchLimit = options.searchLimit ?? 5;
|
|
356
373
|
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
@@ -458,6 +475,165 @@ function unique(items) {
|
|
|
458
475
|
function round(value) {
|
|
459
476
|
return Math.round(value * 1e3) / 1e3;
|
|
460
477
|
}
|
|
478
|
+
|
|
479
|
+
// src/research-loop.ts
|
|
480
|
+
import {
|
|
481
|
+
blockingKnowledgeEval,
|
|
482
|
+
objectiveEval
|
|
483
|
+
} from "@tangle-network/agent-eval";
|
|
484
|
+
function createKnowledgeControlLoopAdapter(options) {
|
|
485
|
+
let initialized = false;
|
|
486
|
+
const appliedSteps = [];
|
|
487
|
+
return {
|
|
488
|
+
intent: options.goal,
|
|
489
|
+
async observe({ history, abortSignal }) {
|
|
490
|
+
if (abortSignal.aborted) throw new Error("Knowledge control loop aborted");
|
|
491
|
+
if (!initialized) {
|
|
492
|
+
await initKnowledgeBase(options.root);
|
|
493
|
+
initialized = true;
|
|
494
|
+
}
|
|
495
|
+
const index = await buildKnowledgeIndex(options.root);
|
|
496
|
+
const validation = validateKnowledgeIndex(index, { strict: options.strict });
|
|
497
|
+
const lintFindings = lintKnowledgeIndex(index);
|
|
498
|
+
const readiness = readinessFor(options, index);
|
|
499
|
+
return {
|
|
500
|
+
root: options.root,
|
|
501
|
+
goal: options.goal,
|
|
502
|
+
iteration: history.length + 1,
|
|
503
|
+
index,
|
|
504
|
+
lintFindings,
|
|
505
|
+
validation,
|
|
506
|
+
readiness,
|
|
507
|
+
previousSteps: [...appliedSteps],
|
|
508
|
+
signal: abortSignal
|
|
509
|
+
};
|
|
510
|
+
},
|
|
511
|
+
validate({ state }) {
|
|
512
|
+
const errorFindings = state.validation.findings.filter((finding) => finding.severity === "error");
|
|
513
|
+
const evals = [
|
|
514
|
+
objectiveEval({
|
|
515
|
+
id: "knowledge-valid",
|
|
516
|
+
passed: state.validation.ok,
|
|
517
|
+
severity: "critical",
|
|
518
|
+
detail: state.validation.ok ? "Knowledge index is valid." : "Knowledge index has validation errors.",
|
|
519
|
+
metadata: { findings: state.validation.findings }
|
|
520
|
+
}),
|
|
521
|
+
objectiveEval({
|
|
522
|
+
id: "knowledge-lint-errors",
|
|
523
|
+
passed: errorFindings.length === 0,
|
|
524
|
+
severity: "error",
|
|
525
|
+
detail: errorFindings.length === 0 ? "No lint errors." : `${errorFindings.length} lint error(s).`,
|
|
526
|
+
metadata: { findings: errorFindings }
|
|
527
|
+
})
|
|
528
|
+
];
|
|
529
|
+
if (state.readiness) evals.push(blockingKnowledgeEval(state.readiness.report));
|
|
530
|
+
return evals;
|
|
531
|
+
},
|
|
532
|
+
shouldStop() {
|
|
533
|
+
return { stop: false, pass: false, reason: "knowledge driver owns stop decisions" };
|
|
534
|
+
},
|
|
535
|
+
async act(action, ctx) {
|
|
536
|
+
const step = await applyKnowledgeResearchDecision(options, action, ctx.state.iteration);
|
|
537
|
+
appliedSteps.push(step);
|
|
538
|
+
return step;
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
async function runKnowledgeResearchLoop(options) {
|
|
543
|
+
const maxIterations = Math.max(1, options.maxIterations ?? 3);
|
|
544
|
+
await initKnowledgeBase(options.root);
|
|
545
|
+
const steps = [];
|
|
546
|
+
let index = await buildKnowledgeIndex(options.root);
|
|
547
|
+
let validation = validateKnowledgeIndex(index, { strict: options.strict });
|
|
548
|
+
let lintFindings = lintKnowledgeIndex(index);
|
|
549
|
+
let readiness = readinessFor(options, index);
|
|
550
|
+
let done = false;
|
|
551
|
+
for (let iteration = 1; iteration <= maxIterations; iteration++) {
|
|
552
|
+
if (options.signal?.aborted) throw new Error("Knowledge research loop aborted");
|
|
553
|
+
const decision = await options.step({
|
|
554
|
+
root: options.root,
|
|
555
|
+
goal: options.goal,
|
|
556
|
+
iteration,
|
|
557
|
+
index,
|
|
558
|
+
lintFindings,
|
|
559
|
+
validation,
|
|
560
|
+
readiness,
|
|
561
|
+
previousSteps: steps,
|
|
562
|
+
signal: options.signal
|
|
563
|
+
});
|
|
564
|
+
done = Boolean(decision.done);
|
|
565
|
+
const step = await applyKnowledgeResearchDecision(options, decision, iteration);
|
|
566
|
+
index = await buildKnowledgeIndex(options.root);
|
|
567
|
+
validation = step.validation;
|
|
568
|
+
lintFindings = step.lintFindings;
|
|
569
|
+
readiness = step.readiness;
|
|
570
|
+
steps.push(step);
|
|
571
|
+
await options.onStep?.(step);
|
|
572
|
+
if (done) break;
|
|
573
|
+
if (!step.applied && step.addedSources.length === 0) break;
|
|
574
|
+
}
|
|
575
|
+
return {
|
|
576
|
+
root: options.root,
|
|
577
|
+
goal: options.goal,
|
|
578
|
+
iterations: steps.length,
|
|
579
|
+
done,
|
|
580
|
+
index,
|
|
581
|
+
lintFindings,
|
|
582
|
+
validation,
|
|
583
|
+
readiness,
|
|
584
|
+
steps
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
async function applyKnowledgeResearchDecision(options, decision, iteration = 1) {
|
|
588
|
+
const addedSources = [];
|
|
589
|
+
for (const sourcePath of decision.sourcePaths ?? []) {
|
|
590
|
+
addedSources.push(...await addSourcePath(options.root, sourcePath, options.sourceOptions));
|
|
591
|
+
}
|
|
592
|
+
for (const sourceText of decision.sourceTexts ?? []) {
|
|
593
|
+
addedSources.push(await addSourceText(options.root, sourceText, options.sourceOptions));
|
|
594
|
+
}
|
|
595
|
+
const applied = decision.proposalText ? await applyKnowledgeWriteBlocks(options.root, decision.proposalText) : void 0;
|
|
596
|
+
const index = await buildKnowledgeIndex(options.root);
|
|
597
|
+
const validation = validateKnowledgeIndex(index, { strict: options.strict });
|
|
598
|
+
const lintFindings = lintKnowledgeIndex(index);
|
|
599
|
+
const readiness = readinessFor(options, index);
|
|
600
|
+
const done = Boolean(decision.done);
|
|
601
|
+
const event = createKnowledgeEvent({
|
|
602
|
+
type: "research.iteration",
|
|
603
|
+
actor: options.actor,
|
|
604
|
+
target: options.root,
|
|
605
|
+
metadata: {
|
|
606
|
+
goal: options.goal,
|
|
607
|
+
iteration,
|
|
608
|
+
done,
|
|
609
|
+
addedSourceCount: addedSources.length,
|
|
610
|
+
written: applied?.written,
|
|
611
|
+
warningCount: applied?.warnings.length ?? 0,
|
|
612
|
+
errorCount: validation.findings.filter((finding) => finding.severity === "error").length
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
return {
|
|
616
|
+
iteration,
|
|
617
|
+
notes: decision.notes,
|
|
618
|
+
addedSources,
|
|
619
|
+
applied,
|
|
620
|
+
lintFindings,
|
|
621
|
+
validation,
|
|
622
|
+
readiness,
|
|
623
|
+
event,
|
|
624
|
+
done,
|
|
625
|
+
metadata: decision.metadata
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
function readinessFor(options, index) {
|
|
629
|
+
if (!options.readinessSpecs?.length) return void 0;
|
|
630
|
+
return buildEvalKnowledgeBundle({
|
|
631
|
+
...options.readiness ?? {},
|
|
632
|
+
taskId: options.readinessTaskId ?? options.goal,
|
|
633
|
+
index,
|
|
634
|
+
specs: options.readinessSpecs
|
|
635
|
+
});
|
|
636
|
+
}
|
|
461
637
|
export {
|
|
462
638
|
FileSystemKbStore,
|
|
463
639
|
KnowledgeBaseCandidateSchema,
|
|
@@ -467,19 +643,23 @@ export {
|
|
|
467
643
|
KnowledgeIndexSchema,
|
|
468
644
|
KnowledgePageSchema,
|
|
469
645
|
MemoryKbStore,
|
|
646
|
+
READINESS_SPEC_DEFAULTS,
|
|
470
647
|
SCAFFOLD_PAGE_BASENAMES,
|
|
471
648
|
SourceAnchorSchema,
|
|
472
649
|
SourceRecordSchema,
|
|
473
650
|
WIKILINK_REGEX,
|
|
474
651
|
addSourcePath,
|
|
652
|
+
addSourceText,
|
|
475
653
|
applyKnowledgeWriteBlocks,
|
|
476
654
|
applyKnowledgeWriteBlocksFile,
|
|
477
655
|
buildEvalKnowledgeBundle,
|
|
478
656
|
buildKnowledgeGraph,
|
|
479
657
|
buildKnowledgeIndex,
|
|
480
658
|
chunkMarkdown,
|
|
659
|
+
createKnowledgeControlLoopAdapter,
|
|
481
660
|
createKnowledgeEvent,
|
|
482
661
|
createLocalDiscoveryDispatcher,
|
|
662
|
+
defineReadinessSpec,
|
|
483
663
|
explainKnowledgeTarget,
|
|
484
664
|
extractWikilinks,
|
|
485
665
|
formatFrontmatter,
|
|
@@ -499,6 +679,7 @@ export {
|
|
|
499
679
|
parseKnowledgeWriteBlocks,
|
|
500
680
|
reciprocalRankFusion,
|
|
501
681
|
runKnowledgeBaseOptimization,
|
|
682
|
+
runKnowledgeResearchLoop,
|
|
502
683
|
searchKnowledge,
|
|
503
684
|
sha256,
|
|
504
685
|
slugify,
|
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","../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 now?: Date\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 now = options.now ?? new Date()\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(options.index, spec, results, now)\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 index: KnowledgeIndex,\n spec: KnowledgeReadinessSpec,\n results: KnowledgeSearchResult[],\n now: Date,\n): KnowledgeRequirement {\n const hitCount = results.length\n const sourceIds = unique(results.flatMap((result) => result.page.sourceIds))\n const sources = index.sources.filter((source) => sourceIds.includes(source.id))\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 freshness = sourceFreshness(sources, now)\n const currentConfidence = round(Math.min(bestScore, sourceCoverage, hitCoverage, freshness.score))\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 expiredSourceIds: freshness.expiredSourceIds,\n freshnessScore: freshness.score,\n validUntil: freshness.validUntil,\n lastVerifiedAt: freshness.lastVerifiedAt,\n },\n }\n}\n\nfunction sourceFreshness(\n sources: KnowledgeIndex['sources'],\n now: Date,\n): { score: number; validUntil?: string; lastVerifiedAt?: string; expiredSourceIds: string[] } {\n if (sources.length === 0) return { score: 0, expiredSourceIds: [] }\n const validUntilValues = sources.map((source) => source.validUntil ?? stringMetadata(source.metadata, 'validUntil') ?? stringMetadata(source.metadata, 'expiresAt')).filter(isIsoDate)\n const lastVerifiedValues = sources.map((source) => source.lastVerifiedAt ?? stringMetadata(source.metadata, 'lastVerifiedAt')).filter(isIsoDate)\n const expiredSourceIds = sources\n .filter((source) => {\n const validUntil = source.validUntil ?? stringMetadata(source.metadata, 'validUntil') ?? stringMetadata(source.metadata, 'expiresAt')\n return validUntil ? Date.parse(validUntil) <= now.getTime() : false\n })\n .map((source) => source.id)\n return {\n score: expiredSourceIds.length > 0 ? 0 : 1,\n validUntil: earliestIso(validUntilValues),\n lastVerifiedAt: latestIso(lastVerifiedValues),\n expiredSourceIds,\n }\n}\n\nfunction stringMetadata(metadata: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = metadata?.[key]\n return typeof value === 'string' ? value : undefined\n}\n\nfunction isIsoDate(value: string | undefined): value is string {\n return Boolean(value && Number.isFinite(Date.parse(value)))\n}\n\nfunction earliestIso(values: string[]): string | undefined {\n return values.sort((a, b) => Date.parse(a) - Date.parse(b))[0]\n}\n\nfunction latestIso(values: string[]): string | undefined {\n return values.sort((a, b) => Date.parse(b) - Date.parse(a))[0]\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"]}
|
|
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","../src/research-loop.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\n/**\n * Defaults applied by `defineReadinessSpec` when the caller omits the field.\n *\n * These are deliberately conservative: a domain-specific topic that an agent\n * needs grounded to a high-confidence threshold from at least one authoritative\n * source. Override any field to specialise (e.g. `freshness: 'daily'` for a\n * topic that must reflect today's regulatory state).\n */\nexport const READINESS_SPEC_DEFAULTS = {\n category: 'domain_specific',\n acquisitionMode: 'search_web',\n importance: 'high',\n freshness: 'monthly',\n sensitivity: 'public',\n confidenceNeeded: 0.7,\n minSources: 1,\n minHits: 2,\n} as const satisfies Pick<\n KnowledgeReadinessSpec,\n 'category' | 'acquisitionMode' | 'importance' | 'freshness' | 'sensitivity' | 'confidenceNeeded' | 'minSources' | 'minHits'\n>\n\n/**\n * Inputs accepted by `defineReadinessSpec`. The four fields the caller cannot\n * sanely default (id, description, query, requiredFor) are required; everything\n * else is optional and pulls from `READINESS_SPEC_DEFAULTS`.\n */\nexport type DefineReadinessSpecInput =\n & Pick<KnowledgeReadinessSpec, 'id' | 'description' | 'query' | 'requiredFor'>\n & Partial<Omit<KnowledgeReadinessSpec, 'id' | 'description' | 'query' | 'requiredFor'>>\n\n/**\n * Builder that returns a fully-typed `KnowledgeReadinessSpec` from a slim input.\n *\n * Motivation: `KnowledgeReadinessSpec` has eleven required fields. Most of them\n * (category, acquisition mode, importance, freshness, sensitivity, confidence\n * threshold, source/hit minima) have a clear default for domain-specific KB\n * topics — agents end up copy-pasting the same boilerplate across every spec.\n * This helper collapses that boilerplate while keeping every field overridable.\n *\n * @example\n * defineReadinessSpec({\n * id: 'coop/intent-grounding',\n * description: 'Required grounding for coop pack intent stage',\n * query: 'flock size space ventilation predator',\n * requiredFor: ['IntentIntakeAgent', 'requirements'],\n * })\n *\n * @example // override defaults where the topic demands it\n * defineReadinessSpec({\n * id: 'medical/dosing',\n * description: 'Dosing guidance for compounding pharmacy',\n * query: 'compounding dose schedule',\n * requiredFor: ['DosingAgent'],\n * importance: 'blocking',\n * freshness: 'daily',\n * sensitivity: 'private',\n * confidenceNeeded: 0.95,\n * minSources: 3,\n * })\n */\nexport function defineReadinessSpec(input: DefineReadinessSpecInput): KnowledgeReadinessSpec {\n return {\n ...READINESS_SPEC_DEFAULTS,\n ...input,\n }\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 now?: Date\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 now = options.now ?? new Date()\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(options.index, spec, results, now)\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 index: KnowledgeIndex,\n spec: KnowledgeReadinessSpec,\n results: KnowledgeSearchResult[],\n now: Date,\n): KnowledgeRequirement {\n const hitCount = results.length\n const sourceIds = unique(results.flatMap((result) => result.page.sourceIds))\n const sources = index.sources.filter((source) => sourceIds.includes(source.id))\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 freshness = sourceFreshness(sources, now)\n const currentConfidence = round(Math.min(bestScore, sourceCoverage, hitCoverage, freshness.score))\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 expiredSourceIds: freshness.expiredSourceIds,\n freshnessScore: freshness.score,\n validUntil: freshness.validUntil,\n lastVerifiedAt: freshness.lastVerifiedAt,\n },\n }\n}\n\nfunction sourceFreshness(\n sources: KnowledgeIndex['sources'],\n now: Date,\n): { score: number; validUntil?: string; lastVerifiedAt?: string; expiredSourceIds: string[] } {\n if (sources.length === 0) return { score: 0, expiredSourceIds: [] }\n const validUntilValues = sources.map((source) => source.validUntil ?? stringMetadata(source.metadata, 'validUntil') ?? stringMetadata(source.metadata, 'expiresAt')).filter(isIsoDate)\n const lastVerifiedValues = sources.map((source) => source.lastVerifiedAt ?? stringMetadata(source.metadata, 'lastVerifiedAt')).filter(isIsoDate)\n const expiredSourceIds = sources\n .filter((source) => {\n const validUntil = source.validUntil ?? stringMetadata(source.metadata, 'validUntil') ?? stringMetadata(source.metadata, 'expiresAt')\n return validUntil ? Date.parse(validUntil) <= now.getTime() : false\n })\n .map((source) => source.id)\n return {\n score: expiredSourceIds.length > 0 ? 0 : 1,\n validUntil: earliestIso(validUntilValues),\n lastVerifiedAt: latestIso(lastVerifiedValues),\n expiredSourceIds,\n }\n}\n\nfunction stringMetadata(metadata: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = metadata?.[key]\n return typeof value === 'string' ? value : undefined\n}\n\nfunction isIsoDate(value: string | undefined): value is string {\n return Boolean(value && Number.isFinite(Date.parse(value)))\n}\n\nfunction earliestIso(values: string[]): string | undefined {\n return values.sort((a, b) => Date.parse(a) - Date.parse(b))[0]\n}\n\nfunction latestIso(values: string[]): string | undefined {\n return values.sort((a, b) => Date.parse(b) - Date.parse(a))[0]\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","import {\n blockingKnowledgeEval,\n objectiveEval,\n type ControlEvalResult,\n type ControlRuntimeConfig,\n} from '@tangle-network/agent-eval'\nimport { buildKnowledgeIndex } from './indexer'\nimport { lintKnowledgeIndex } from './lint'\nimport { applyKnowledgeWriteBlocks, type ApplyWriteBlocksResult } from './proposals'\nimport { initKnowledgeBase } from './store'\nimport type { KnowledgeEvent, KnowledgeIndex, KnowledgeLintFinding, SourceRecord } from './types'\nimport { createKnowledgeEvent } from './events'\nimport { validateKnowledgeIndex, type ValidateKnowledgeOptions, type ValidateKnowledgeResult } from './validate'\nimport {\n addSourcePath,\n addSourceText,\n type AddSourceTextInput,\n type AddSourceOptions,\n} from './sources'\nimport {\n buildEvalKnowledgeBundle,\n type BuildEvalKnowledgeBundleOptions,\n type EvalKnowledgeBundleBuildResult,\n type KnowledgeReadinessSpec,\n} from './eval-readiness'\n\nexport interface KnowledgeResearchLoopContext {\n root: string\n goal: string\n iteration: number\n index: KnowledgeIndex\n lintFindings: KnowledgeLintFinding[]\n validation: ValidateKnowledgeResult\n readiness?: EvalKnowledgeBundleBuildResult\n previousSteps: KnowledgeResearchLoopStep[]\n signal?: AbortSignal\n}\n\nexport interface KnowledgeResearchLoopDecision {\n /**\n * Free-form notes from the researcher. Keep this human-readable; products can\n * store it as the research transcript.\n */\n notes?: string\n /**\n * Local files to register as immutable sources before applying proposals.\n */\n sourcePaths?: string[]\n /**\n * Textual source artifacts discovered by an agent, browser worker, connector,\n * or deep-research process.\n */\n sourceTexts?: AddSourceTextInput[]\n /**\n * Safe write protocol text. The loop parses and applies only accepted\n * `---FILE: knowledge/...---` blocks.\n */\n proposalText?: string\n /**\n * The researcher decides when the wiki is good enough. The loop deliberately\n * does not encode a domain-specific definition of \"done\".\n */\n done?: boolean\n metadata?: Record<string, unknown>\n}\n\nexport interface KnowledgeResearchLoopStep {\n iteration: number\n notes?: string\n addedSources: SourceRecord[]\n applied?: ApplyWriteBlocksResult\n lintFindings: KnowledgeLintFinding[]\n validation: ValidateKnowledgeResult\n readiness?: EvalKnowledgeBundleBuildResult\n event: KnowledgeEvent\n done: boolean\n metadata?: Record<string, unknown>\n}\n\nexport interface RunKnowledgeResearchLoopOptions {\n root: string\n goal: string\n maxIterations?: number\n actor?: string\n strict?: ValidateKnowledgeOptions['strict']\n readinessSpecs?: KnowledgeReadinessSpec[]\n readinessTaskId?: string\n readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>\n sourceOptions?: Pick<AddSourceOptions, 'adapters' | 'now'>\n signal?: AbortSignal\n step(context: KnowledgeResearchLoopContext): Promise<KnowledgeResearchLoopDecision> | KnowledgeResearchLoopDecision\n onStep?: (step: KnowledgeResearchLoopStep) => Promise<void> | void\n}\n\nexport interface KnowledgeResearchLoopResult {\n root: string\n goal: string\n iterations: number\n done: boolean\n index: KnowledgeIndex\n lintFindings: KnowledgeLintFinding[]\n validation: ValidateKnowledgeResult\n readiness?: EvalKnowledgeBundleBuildResult\n steps: KnowledgeResearchLoopStep[]\n}\n\nexport type KnowledgeControlLoopState = KnowledgeResearchLoopContext\nexport type KnowledgeControlLoopAction = KnowledgeResearchLoopDecision\nexport type KnowledgeControlLoopActionResult = KnowledgeResearchLoopStep\n\nexport interface KnowledgeControlLoopAdapterOptions {\n root: string\n goal: string\n actor?: string\n strict?: ValidateKnowledgeOptions['strict']\n readinessSpecs?: KnowledgeReadinessSpec[]\n readinessTaskId?: string\n readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>\n sourceOptions?: Pick<AddSourceOptions, 'adapters' | 'now'>\n}\n\nexport type KnowledgeControlLoopAdapter = Pick<\n ControlRuntimeConfig<\n KnowledgeControlLoopState,\n KnowledgeControlLoopAction,\n KnowledgeControlLoopActionResult,\n ControlEvalResult\n >,\n 'intent' | 'observe' | 'validate' | 'act' | 'shouldStop'\n>\n\n/**\n * Adapter for running knowledge growth through `agent-eval`'s generic control\n * runtime. The caller still owns `decide`: that can be a proposer agent,\n * reviewer agent, deterministic policy, or a composition of all three.\n */\nexport function createKnowledgeControlLoopAdapter(\n options: KnowledgeControlLoopAdapterOptions,\n): KnowledgeControlLoopAdapter {\n let initialized = false\n const appliedSteps: KnowledgeResearchLoopStep[] = []\n\n return {\n intent: options.goal,\n async observe({ history, abortSignal }) {\n if (abortSignal.aborted) throw new Error('Knowledge control loop aborted')\n if (!initialized) {\n await initKnowledgeBase(options.root)\n initialized = true\n }\n const index = await buildKnowledgeIndex(options.root)\n const validation = validateKnowledgeIndex(index, { strict: options.strict })\n const lintFindings = lintKnowledgeIndex(index)\n const readiness = readinessFor(options, index)\n return {\n root: options.root,\n goal: options.goal,\n iteration: history.length + 1,\n index,\n lintFindings,\n validation,\n readiness,\n previousSteps: [...appliedSteps],\n signal: abortSignal,\n }\n },\n validate({ state }) {\n const errorFindings = state.validation.findings.filter((finding) => finding.severity === 'error')\n const evals: ControlEvalResult[] = [\n objectiveEval({\n id: 'knowledge-valid',\n passed: state.validation.ok,\n severity: 'critical',\n detail: state.validation.ok ? 'Knowledge index is valid.' : 'Knowledge index has validation errors.',\n metadata: { findings: state.validation.findings },\n }),\n objectiveEval({\n id: 'knowledge-lint-errors',\n passed: errorFindings.length === 0,\n severity: 'error',\n detail: errorFindings.length === 0 ? 'No lint errors.' : `${errorFindings.length} lint error(s).`,\n metadata: { findings: errorFindings },\n }),\n ]\n if (state.readiness) evals.push(blockingKnowledgeEval(state.readiness.report))\n return evals\n },\n shouldStop() {\n return { stop: false, pass: false, reason: 'knowledge driver owns stop decisions' }\n },\n async act(action, ctx) {\n const step = await applyKnowledgeResearchDecision(options, action, ctx.state.iteration)\n appliedSteps.push(step)\n return step\n },\n }\n}\n\nexport async function runKnowledgeResearchLoop(\n options: RunKnowledgeResearchLoopOptions,\n): Promise<KnowledgeResearchLoopResult> {\n const maxIterations = Math.max(1, options.maxIterations ?? 3)\n await initKnowledgeBase(options.root)\n const steps: KnowledgeResearchLoopStep[] = []\n let index = await buildKnowledgeIndex(options.root)\n let validation = validateKnowledgeIndex(index, { strict: options.strict })\n let lintFindings = lintKnowledgeIndex(index)\n let readiness = readinessFor(options, index)\n let done = false\n\n for (let iteration = 1; iteration <= maxIterations; iteration++) {\n if (options.signal?.aborted) throw new Error('Knowledge research loop aborted')\n const decision = await options.step({\n root: options.root,\n goal: options.goal,\n iteration,\n index,\n lintFindings,\n validation,\n readiness,\n previousSteps: steps,\n signal: options.signal,\n })\n\n done = Boolean(decision.done)\n const step = await applyKnowledgeResearchDecision(options, decision, iteration)\n index = await buildKnowledgeIndex(options.root)\n validation = step.validation\n lintFindings = step.lintFindings\n readiness = step.readiness\n steps.push(step)\n await options.onStep?.(step)\n\n if (done) break\n if (!step.applied && step.addedSources.length === 0) break\n }\n\n return {\n root: options.root,\n goal: options.goal,\n iterations: steps.length,\n done,\n index,\n lintFindings,\n validation,\n readiness,\n steps,\n }\n}\n\nasync function applyKnowledgeResearchDecision(\n options: KnowledgeControlLoopAdapterOptions,\n decision: KnowledgeResearchLoopDecision,\n iteration = 1,\n): Promise<KnowledgeResearchLoopStep> {\n const addedSources: SourceRecord[] = []\n for (const sourcePath of decision.sourcePaths ?? []) {\n addedSources.push(...await addSourcePath(options.root, sourcePath, options.sourceOptions))\n }\n for (const sourceText of decision.sourceTexts ?? []) {\n addedSources.push(await addSourceText(options.root, sourceText, options.sourceOptions))\n }\n\n const applied = decision.proposalText\n ? await applyKnowledgeWriteBlocks(options.root, decision.proposalText)\n : undefined\n\n const index = await buildKnowledgeIndex(options.root)\n const validation = validateKnowledgeIndex(index, { strict: options.strict })\n const lintFindings = lintKnowledgeIndex(index)\n const readiness = readinessFor(options, index)\n const done = Boolean(decision.done)\n const event = createKnowledgeEvent({\n type: 'research.iteration',\n actor: options.actor,\n target: options.root,\n metadata: {\n goal: options.goal,\n iteration,\n done,\n addedSourceCount: addedSources.length,\n written: applied?.written,\n warningCount: applied?.warnings.length ?? 0,\n errorCount: validation.findings.filter((finding) => finding.severity === 'error').length,\n },\n })\n\n return {\n iteration,\n notes: decision.notes,\n addedSources,\n applied,\n lintFindings,\n validation,\n readiness,\n event,\n done,\n metadata: decision.metadata,\n }\n}\n\nfunction readinessFor(\n options: KnowledgeControlLoopAdapterOptions,\n index: KnowledgeIndex,\n): EvalKnowledgeBundleBuildResult | undefined {\n if (!options.readinessSpecs?.length) return undefined\n return buildEvalKnowledgeBundle({\n ...(options.readiness ?? {}),\n taskId: options.readinessTaskId ?? options.goal,\n index,\n specs: options.readinessSpecs,\n })\n}\n"],"mappings":"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","names":["writeJson"]}
|
|
@@ -151,7 +151,7 @@ interface KnowledgeWriteParseResult {
|
|
|
151
151
|
blocks: KnowledgeWriteBlock[];
|
|
152
152
|
warnings: string[];
|
|
153
153
|
}
|
|
154
|
-
type KnowledgeEventType = 'source.added' | 'proposal.applied' | 'index.built' | 'lint.run' | 'optimization.run' | 'release.promoted' | 'release.rejected';
|
|
154
|
+
type KnowledgeEventType = 'source.added' | 'proposal.applied' | 'index.built' | 'lint.run' | 'research.iteration' | 'optimization.run' | 'release.promoted' | 'release.rejected';
|
|
155
155
|
interface KnowledgeEvent {
|
|
156
156
|
id: string;
|
|
157
157
|
type: KnowledgeEventType;
|
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-DTUp66Gr.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.2.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": {
|
|
@@ -42,6 +42,14 @@
|
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsup",
|
|
47
|
+
"dev": "tsup --watch",
|
|
48
|
+
"prepare": "tsup",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:watch": "vitest",
|
|
51
|
+
"typecheck": "tsc --noEmit"
|
|
52
|
+
},
|
|
45
53
|
"dependencies": {
|
|
46
54
|
"@tangle-network/agent-eval": "^0.20.0",
|
|
47
55
|
"zod": "^4.3.6"
|
|
@@ -56,11 +64,5 @@
|
|
|
56
64
|
"node": ">=20"
|
|
57
65
|
},
|
|
58
66
|
"license": "MIT",
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
"dev": "tsup --watch",
|
|
62
|
-
"test": "vitest run",
|
|
63
|
-
"test:watch": "vitest",
|
|
64
|
-
"typecheck": "tsc --noEmit"
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
+
"packageManager": "pnpm@10.28.0"
|
|
68
|
+
}
|
|
@@ -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\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 expiredSourceCount: number\n staleSourceCount: number\n edgeCount: number\n findingCount: number\n blockingFindingCount: number\n topPages: Array<{ path: string; title: string; degree: number; sources: number }>\n sourceFreshness: SourceFreshnessInspection[]\n findings: KnowledgeLintFinding[]\n}\n\nexport interface SourceFreshnessInspection {\n id: string\n title?: string\n uri: string\n status: 'fresh' | 'expired' | 'unknown'\n validUntil?: string\n lastVerifiedAt?: string\n}\n\nexport function inspectKnowledgeIndex(index: KnowledgeIndex, options: { now?: Date } = {}): KnowledgeInspection {\n const now = options.now ?? new Date()\n const findings = lintKnowledgeIndex(index)\n const degree = new Map(index.graph.nodes.map((node) => [node.id, node.inDegree + node.outDegree]))\n const sourceFreshness = index.sources.map((source) => inspectSourceFreshness(source, now))\n return {\n pageCount: index.pages.length,\n sourceCount: index.sources.length,\n expiredSourceCount: sourceFreshness.filter((source) => source.status === 'expired').length,\n staleSourceCount: sourceFreshness.filter((source) => source.status !== 'fresh').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 sourceFreshness,\n findings,\n }\n}\n\nfunction inspectSourceFreshness(source: KnowledgeIndex['sources'][number], now: Date): SourceFreshnessInspection {\n const validUntil = source.validUntil ?? stringMetadata(source.metadata, 'validUntil') ?? stringMetadata(source.metadata, 'expiresAt')\n const lastVerifiedAt = source.lastVerifiedAt ?? stringMetadata(source.metadata, 'lastVerifiedAt')\n const status = validUntil && Number.isFinite(Date.parse(validUntil))\n ? Date.parse(validUntil) <= now.getTime() ? 'expired' : 'fresh'\n : 'unknown'\n return { id: source.id, title: source.title, uri: source.uri, status, validUntil, lastVerifiedAt }\n}\n\nfunction stringMetadata(metadata: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = metadata?.[key]\n return typeof value === 'string' ? value : undefined\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"]}
|