@tangle-network/agent-knowledge 1.1.0 → 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/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-BEFAI2HO.js";
45
+ } from "./chunk-JLCQ6O7W.js";
45
46
 
46
47
  // src/events.ts
47
48
  function createKnowledgeEvent(input) {
@@ -351,13 +352,30 @@ 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;
373
+ const now = options.now ?? /* @__PURE__ */ new Date();
356
374
  const searchResultsByRequirement = {};
357
375
  const requirements = options.specs.map((spec) => {
358
376
  const results = searchKnowledge(options.index, spec.query, searchLimit);
359
377
  searchResultsByRequirement[spec.id] = results;
360
- return requirementFromSearch(spec, results);
378
+ return requirementFromSearch(options.index, spec, results, now);
361
379
  });
362
380
  const report = scoreKnowledgeReadiness({
363
381
  taskId: options.taskId,
@@ -382,13 +400,15 @@ function buildEvalKnowledgeBundle(options) {
382
400
  acquisitionPlans
383
401
  };
384
402
  }
385
- function requirementFromSearch(spec, results) {
403
+ function requirementFromSearch(index, spec, results, now) {
386
404
  const hitCount = results.length;
387
405
  const sourceIds = unique(results.flatMap((result) => result.page.sourceIds));
406
+ const sources = index.sources.filter((source) => sourceIds.includes(source.id));
388
407
  const bestScore = results[0]?.normalizedScore ?? 0;
389
408
  const sourceCoverage = spec.minSources ? Math.min(1, sourceIds.length / spec.minSources) : sourceIds.length > 0 ? 1 : 0;
390
409
  const hitCoverage = spec.minHits ? Math.min(1, hitCount / spec.minHits) : hitCount > 0 ? 1 : 0;
391
- const currentConfidence = round(Math.min(bestScore, sourceCoverage, hitCoverage));
410
+ const freshness = sourceFreshness(sources, now);
411
+ const currentConfidence = round(Math.min(bestScore, sourceCoverage, hitCoverage, freshness.score));
392
412
  return {
393
413
  id: spec.id,
394
414
  description: spec.description,
@@ -410,10 +430,42 @@ function requirementFromSearch(spec, results) {
410
430
  query: spec.query,
411
431
  hitCount,
412
432
  sourceCount: sourceIds.length,
413
- bestNormalizedScore: bestScore
433
+ bestNormalizedScore: bestScore,
434
+ expiredSourceIds: freshness.expiredSourceIds,
435
+ freshnessScore: freshness.score,
436
+ validUntil: freshness.validUntil,
437
+ lastVerifiedAt: freshness.lastVerifiedAt
414
438
  }
415
439
  };
416
440
  }
441
+ function sourceFreshness(sources, now) {
442
+ if (sources.length === 0) return { score: 0, expiredSourceIds: [] };
443
+ const validUntilValues = sources.map((source) => source.validUntil ?? stringMetadata(source.metadata, "validUntil") ?? stringMetadata(source.metadata, "expiresAt")).filter(isIsoDate);
444
+ const lastVerifiedValues = sources.map((source) => source.lastVerifiedAt ?? stringMetadata(source.metadata, "lastVerifiedAt")).filter(isIsoDate);
445
+ const expiredSourceIds = sources.filter((source) => {
446
+ const validUntil = source.validUntil ?? stringMetadata(source.metadata, "validUntil") ?? stringMetadata(source.metadata, "expiresAt");
447
+ return validUntil ? Date.parse(validUntil) <= now.getTime() : false;
448
+ }).map((source) => source.id);
449
+ return {
450
+ score: expiredSourceIds.length > 0 ? 0 : 1,
451
+ validUntil: earliestIso(validUntilValues),
452
+ lastVerifiedAt: latestIso(lastVerifiedValues),
453
+ expiredSourceIds
454
+ };
455
+ }
456
+ function stringMetadata(metadata, key) {
457
+ const value = metadata?.[key];
458
+ return typeof value === "string" ? value : void 0;
459
+ }
460
+ function isIsoDate(value) {
461
+ return Boolean(value && Number.isFinite(Date.parse(value)));
462
+ }
463
+ function earliestIso(values) {
464
+ return values.sort((a, b) => Date.parse(a) - Date.parse(b))[0];
465
+ }
466
+ function latestIso(values) {
467
+ return values.sort((a, b) => Date.parse(b) - Date.parse(a))[0];
468
+ }
417
469
  function pageIdsFromResults(results) {
418
470
  return results.map((result) => result.page.id);
419
471
  }
@@ -423,6 +475,165 @@ function unique(items) {
423
475
  function round(value) {
424
476
  return Math.round(value * 1e3) / 1e3;
425
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
+ }
426
637
  export {
427
638
  FileSystemKbStore,
428
639
  KnowledgeBaseCandidateSchema,
@@ -432,19 +643,23 @@ export {
432
643
  KnowledgeIndexSchema,
433
644
  KnowledgePageSchema,
434
645
  MemoryKbStore,
646
+ READINESS_SPEC_DEFAULTS,
435
647
  SCAFFOLD_PAGE_BASENAMES,
436
648
  SourceAnchorSchema,
437
649
  SourceRecordSchema,
438
650
  WIKILINK_REGEX,
439
651
  addSourcePath,
652
+ addSourceText,
440
653
  applyKnowledgeWriteBlocks,
441
654
  applyKnowledgeWriteBlocksFile,
442
655
  buildEvalKnowledgeBundle,
443
656
  buildKnowledgeGraph,
444
657
  buildKnowledgeIndex,
445
658
  chunkMarkdown,
659
+ createKnowledgeControlLoopAdapter,
446
660
  createKnowledgeEvent,
447
661
  createLocalDiscoveryDispatcher,
662
+ defineReadinessSpec,
448
663
  explainKnowledgeTarget,
449
664
  extractWikilinks,
450
665
  formatFrontmatter,
@@ -464,6 +679,7 @@ export {
464
679
  parseKnowledgeWriteBlocks,
465
680
  reciprocalRankFusion,
466
681
  runKnowledgeBaseOptimization,
682
+ runKnowledgeResearchLoop,
467
683
  searchKnowledge,
468
684
  sha256,
469
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}\n\nexport interface EvalKnowledgeBundleBuildResult {\n bundle: KnowledgeBundle\n report: KnowledgeReadinessReport\n requirements: KnowledgeRequirement[]\n searchResultsByRequirement: Record<string, KnowledgeSearchResult[]>\n questions: UserQuestion[]\n acquisitionPlans: DataAcquisitionPlan[]\n}\n\nexport function buildEvalKnowledgeBundle(options: BuildEvalKnowledgeBundleOptions): EvalKnowledgeBundleBuildResult {\n const searchLimit = options.searchLimit ?? 5\n const searchResultsByRequirement: Record<string, KnowledgeSearchResult[]> = {}\n const requirements = options.specs.map((spec) => {\n const results = searchKnowledge(options.index, spec.query, searchLimit)\n searchResultsByRequirement[spec.id] = results\n return requirementFromSearch(spec, results)\n })\n const report = scoreKnowledgeReadiness({\n taskId: options.taskId,\n requirements,\n userAnswers: options.userAnswers,\n evidenceIds: requirements.flatMap((requirement) => requirement.evidenceIds),\n claimIds: [],\n wikiPageIds: unique(requirements.flatMap((requirement) => pageIdsFromResults(searchResultsByRequirement[requirement.id] ?? []))),\n metadata: options.metadata,\n })\n const questions = userQuestionsForKnowledgeGaps(report.blockingMissingRequirements)\n const acquisitionPlans = acquisitionPlansForKnowledgeGaps([\n ...report.blockingMissingRequirements,\n ...report.nonBlockingGaps,\n ])\n\n return {\n bundle: report.bundle,\n report,\n requirements,\n searchResultsByRequirement,\n questions,\n acquisitionPlans,\n }\n}\n\nfunction requirementFromSearch(\n spec: KnowledgeReadinessSpec,\n results: KnowledgeSearchResult[],\n): KnowledgeRequirement {\n const hitCount = results.length\n const sourceIds = unique(results.flatMap((result) => result.page.sourceIds))\n const bestScore = results[0]?.normalizedScore ?? 0\n const sourceCoverage = spec.minSources ? Math.min(1, sourceIds.length / spec.minSources) : (sourceIds.length > 0 ? 1 : 0)\n const hitCoverage = spec.minHits ? Math.min(1, hitCount / spec.minHits) : (hitCount > 0 ? 1 : 0)\n const currentConfidence = round(Math.min(bestScore, sourceCoverage, hitCoverage))\n\n return {\n id: spec.id,\n description: spec.description,\n requiredFor: spec.requiredFor,\n category: spec.category,\n acquisitionMode: spec.acquisitionMode,\n importance: spec.importance,\n freshness: spec.freshness,\n sensitivity: spec.sensitivity,\n confidenceNeeded: spec.confidenceNeeded,\n currentConfidence,\n evidenceIds: unique([\n ...sourceIds.map((sourceId) => `source:${sourceId}`),\n ...results.map((result) => `page:${result.page.id}`),\n ]),\n fallbackPolicy: spec.fallbackPolicy ?? (spec.importance === 'blocking' ? 'block' : 'continue_with_caveat'),\n metadata: {\n ...spec.metadata,\n query: spec.query,\n hitCount,\n sourceCount: sourceIds.length,\n bestNormalizedScore: bestScore,\n },\n }\n}\n\nfunction pageIdsFromResults(results: KnowledgeSearchResult[]): string[] {\n return results.map((result) => result.page.id)\n}\n\nfunction unique<T>(items: T[]): T[] {\n return [...new Set(items)]\n}\n\nfunction round(value: number): number {\n return Math.round(value * 1000) / 1000\n}\n"],"mappings":"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","names":["writeJson"]}
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"]}
@@ -19,6 +19,10 @@ interface SourceRecord {
19
19
  contentHash: string;
20
20
  text?: string;
21
21
  anchors?: SourceAnchor[];
22
+ /** ISO timestamp after which consumers should treat this source as stale. */
23
+ validUntil?: string;
24
+ /** ISO timestamp for the last successful source freshness verification. */
25
+ lastVerifiedAt?: string;
22
26
  metadata?: Record<string, unknown>;
23
27
  createdAt: string;
24
28
  }
@@ -147,7 +151,7 @@ interface KnowledgeWriteParseResult {
147
151
  blocks: KnowledgeWriteBlock[];
148
152
  warnings: string[];
149
153
  }
150
- 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';
151
155
  interface KnowledgeEvent {
152
156
  id: string;
153
157
  type: KnowledgeEventType;
@@ -1,4 +1,4 @@
1
- import { K as KnowledgeGraphEdge, a as KnowledgeGraphNode, b as KnowledgeGraph } from '../types-CWbf3JSE.js';
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.1.0",
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": {