@tangle-network/agent-knowledge 19.1.5 → 20.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -2
- package/README.md +17 -91
- package/dist/benchmarks/index.d.ts +2 -2
- package/dist/benchmarks/index.js +2 -2
- package/dist/benchmarks-jir3ZP-M.js +162 -0
- package/dist/benchmarks-jir3ZP-M.js.map +1 -0
- package/dist/cli.js +2 -3
- package/dist/cli.js.map +1 -1
- package/dist/index-BhvSH4E4.d.ts +512 -0
- package/dist/index-BhvSH4E4.d.ts.map +1 -0
- package/dist/index-OAxtm6is.d.ts +9 -0
- package/dist/index-OAxtm6is.d.ts.map +1 -0
- package/dist/index.d.ts +197 -1332
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +561 -3653
- package/dist/index.js.map +1 -1
- package/dist/{inspect-C6c4zuKp.js → inspect-CMigdsD5.js} +282 -24
- package/dist/inspect-CMigdsD5.js.map +1 -0
- package/dist/memory/index.d.ts +3 -3
- package/dist/memory/index.js +3 -3
- package/dist/memory-BH6oT1Qe.js +2728 -0
- package/dist/memory-BH6oT1Qe.js.map +1 -0
- package/dist/source-record-CdWvzvO6.js +39 -0
- package/dist/source-record-CdWvzvO6.js.map +1 -0
- package/dist/types-BWV_Fvp7.d.ts +224 -0
- package/dist/types-BWV_Fvp7.d.ts.map +1 -0
- package/dist/{types-m2QB86fF.d.ts → types-BekdNwGD.d.ts} +4 -19
- package/dist/types-BekdNwGD.d.ts.map +1 -0
- package/dist/viz/index.d.ts +1 -1
- package/docs/architecture.md +2 -30
- package/docs/eval/investment-material-facts.md +2 -0
- package/docs/results/research-driving.md +8 -8
- package/docs/verified-research-ab.md +12 -10
- package/package.json +6 -12
- package/skills/build-with-agent-knowledge/SKILL.md +2 -15
- package/dist/benchmarks-BjXxjAke.js +0 -2824
- package/dist/benchmarks-BjXxjAke.js.map +0 -1
- package/dist/index-Bh9wLd0_.d.ts +0 -1097
- package/dist/index-Bh9wLd0_.d.ts.map +0 -1
- package/dist/index-DZeFm-BP.d.ts +0 -680
- package/dist/index-DZeFm-BP.d.ts.map +0 -1
- package/dist/inspect-C6c4zuKp.js.map +0 -1
- package/dist/memory-CUk1mgPY.js +0 -5778
- package/dist/memory-CUk1mgPY.js.map +0 -1
- package/dist/search-BBr5eUyT.js +0 -275
- package/dist/search-BBr5eUyT.js.map +0 -1
- package/dist/sources/index.d.ts +0 -376
- package/dist/sources/index.d.ts.map +0 -1
- package/dist/sources/index.js +0 -615
- package/dist/sources/index.js.map +0 -1
- package/dist/types-m2QB86fF.d.ts.map +0 -1
- package/docs/eval/rag-eval-roadmap.md +0 -123
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 20.0.1
|
|
4
|
+
|
|
5
|
+
Qualify Eval 0.210 and 0.211 for packed consumers and official GEPA/SkillOpt integration.
|
|
6
|
+
Retain Eval 0.209 and develop against 0.211.2, the first Eval release that prices `gpt-6-luna`.
|
|
7
|
+
|
|
8
|
+
## 20.0.0
|
|
9
|
+
|
|
10
|
+
Require Interface 3 and Eval 0.209, the first Eval release on Interface 3, so a consumer installs one Interface copy alongside Core 0.10.3.
|
|
11
|
+
Knowledge 19 remains the release for Interface 2 and Eval 0.201 through 0.208.
|
|
12
|
+
Remove the web research drivers, which no consumer imported, and the TCloud dependency only they used.
|
|
13
|
+
Knowledge no longer browses or calls models itself; supply research through `runKnowledgeResearchLoop` callbacks or `@tangle-network/agent-runtime`.
|
|
14
|
+
Removed: `runVerifiedResearchLoop`, `createWebResearchWorker`, `createVerifyingResearchDriver`, `createTangleRouterClient`, `RouterError`, `createAdaptiveResearchDriver`, `createCollectionResearchDriver`, `createResearchDrivingDriver`, `createPersistentResearchDrivingDriver`, `createClaimGroundingVerifier`, `createClaimDecorator`, the cited-claim helpers, the investment-thesis set, task, and material-facts metric, and their types.
|
|
15
|
+
`groundClaimInText`, claim ledgers, `TrackedClaim`, store formats, and every other public operation are unchanged.
|
|
16
|
+
The verified-research paper and its results remain as a historical record linked to the last commit with that code.
|
|
17
|
+
Remove the memory experiment, memory improvement, and benchmark-suite runners, which no consumer imported: `runAgentMemoryExperiment`, `runAgentMemoryLearningExperiment`, `runAgentMemoryImprovement`, `runKnowledgeBenchmarkSuite`, `runMemoryAdapterBenchmark`, the industry benchmark catalogs, qrels import, benchmark scoring, and their run-lease, cost, and comparison types.
|
|
18
|
+
Compare memory providers on product tasks with Agent Eval.
|
|
19
|
+
Memory adapters, branches, holdout, lifecycle bounds, play memory tools, and the `/benchmarks` in-memory and no-op adapters are unchanged.
|
|
20
|
+
Remove the `/sources` entry point and the unused authority adapters behind it (Cornell LII, IRS publications, state Secretary of State, polite HTTP fetch, HTML extraction), plus `detectChanges` and the freshness stores. No consumer imported them.
|
|
21
|
+
The source registry (`addSourceText`, `addSourcePath`, `loadSourceRegistry`), source adapters such as `textSourceAdapter`, and readiness freshness scoring are unchanged.
|
|
22
|
+
Remove unused root APIs: `optimizeKnowledgeBasePolicy`, `improveSelectedKnowledgeCandidate`, `buildKnowledgeRelationGraph` with its queries and schemas, `knowledgeCitationAuditFindings`, `planInvalidationPropagation`, `formatKnowledgeInvalidationProposal`, `calibrateRagAnswerJudge`, and `createRagAnswerQualityHook`.
|
|
23
|
+
`improveKnowledgeBase`, `buildKnowledgeGraph`, citation resolution and audit, the lint `cites-invalidated` warning, and RAG answer scoring are unchanged.
|
|
24
|
+
|
|
1
25
|
## 19.1.5
|
|
2
26
|
|
|
3
27
|
Publish the Eval 0.208 qualification. The play-memory tests gave their fixture Hindsight a 10 ms ingestion deadline on every path; on a loaded self-hosted runner a write that completes at once missed it and the 19.1.4 publish failed. Success paths now get 10 s; only the unresolved-path test keeps 10 ms.
|
|
@@ -57,8 +81,6 @@ Write transactions retain the host actor and run identity, with unknown authors
|
|
|
57
81
|
Knowledge tools retain prior and new page bytes by default; applications can explicitly disable history.
|
|
58
82
|
Lower-level proposal writers can select the same conditional-write contract.
|
|
59
83
|
|
|
60
|
-
# Changelog
|
|
61
|
-
|
|
62
84
|
## 18.0.0 — 2026-09-29
|
|
63
85
|
|
|
64
86
|
Require Eval 0.201 through 0.203, Interface 2.15, and TCloud 0.8.
|
package/README.md
CHANGED
|
@@ -9,16 +9,15 @@ Supply application callbacks for those decisions, or use `@tangle-network/agent-
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
pnpm add @tangle-network/agent-knowledge
|
|
12
|
+
pnpm add @tangle-network/agent-knowledge @tangle-network/agent-eval@0.211.2 @tangle-network/agent-interface@3.0.0
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
Requires Node.js 22.12 or later and Interface
|
|
15
|
+
Requires Node.js 22.12 or later and Interface 3.
|
|
16
16
|
|
|
17
|
-
Eval 0.
|
|
18
|
-
Package and official optimizer checks exercise each
|
|
17
|
+
Eval 0.209 through 0.211 is supported; 0.209 is the first Eval release on Interface 3.
|
|
18
|
+
Package and official optimizer checks exercise each minor; development uses 0.211.2, the first release that prices `gpt-6-luna`.
|
|
19
19
|
These releases use Core 0.10, Trace Contract 2, and Zod 4.6.5.
|
|
20
|
-
Knowledge 19
|
|
21
|
-
Use Knowledge 17 with older Eval releases.
|
|
20
|
+
Use Knowledge 19 with Interface 2 and Eval 0.201 through 0.208, and Knowledge 17 with older Eval releases.
|
|
22
21
|
|
|
23
22
|
## Choose an API
|
|
24
23
|
|
|
@@ -30,11 +29,8 @@ Use Knowledge 17 with older Eval releases.
|
|
|
30
29
|
| Prove what knowledge was visible, retrieved, and selected for use | `createKnowledgeRetrievalReceipt`, `createKnowledgeUseReceipt` | package root |
|
|
31
30
|
| Improve a live knowledge base without editing it in place | `improveKnowledgeBase` | package root |
|
|
32
31
|
| Optimize retrieval or a complete RAG configuration | `runRetrievalImprovementLoop`, `runRagOptimization` | package root |
|
|
33
|
-
| Optimize a KB maintenance policy | `optimizeKnowledgeBasePolicy` | package root |
|
|
34
32
|
| Run retrieval, research, answer checks, and promotion as one process | `runRagKnowledgeImprovementLoop` | package root |
|
|
35
|
-
|
|
|
36
|
-
| Read from external authorities | `KnowledgeSource` and source adapters | `/sources` |
|
|
37
|
-
| Run retrieval, answer, KB, or memory benchmark cases | `runKnowledgeBenchmarkSuite` | `/benchmarks` |
|
|
33
|
+
| Connect a memory provider or branch its state | `AgentMemoryAdapter`, `createAgentMemoryBranch` | `/memory` |
|
|
38
34
|
| Use live research or coding agents | `runKnowledgeImprovementJob` | `@tangle-network/agent-runtime` |
|
|
39
35
|
|
|
40
36
|
## Create and search a knowledge base
|
|
@@ -91,7 +87,6 @@ Pass `refresh: 'always'` to rebuild its index before every query, or call `inval
|
|
|
91
87
|
Use `asRetrievalEvalRetriever()` to send the same search path into retrieval tests.
|
|
92
88
|
|
|
93
89
|
`knowledgePageRelations(pages)` lists the labeled relations between pages (`wikilink`, `citation`, `shared-source`, `contradicts`), and `buildKnowledgeGraph` collapses them into the weighted page graph stored in the index.
|
|
94
|
-
For caller-defined provenance (runs, claims, models, any predicate), `buildKnowledgeRelationGraph({ nodes, relations })` keeps one edge per `(sourceId, targetId, predicate)`, refuses a conflicting repeat or an undeclared endpoint, and `neighbors`, `walk`, and `isReachable` query it by predicate and direction; `KnowledgeRelationGraphSchema` round-trips a persisted graph with its metadata.
|
|
95
90
|
|
|
96
91
|
Pages live under `knowledge/` unless you name another root-relative directory.
|
|
97
92
|
`loadKnowledgePages`, `buildKnowledgeIndex`, `writeKnowledgeIndex`, `applyKnowledgeWriteBlocks`, `createFileSystemSearchProvider`, and `createRunScopedStores` all take one `pagesDirectory` option (`KnowledgePagesOptions`), so a store laid out as `kb/pages/<line>/` is read, indexed, searched, chained, and written through the same value.
|
|
@@ -282,19 +277,9 @@ const receipt = createKnowledgeRetrievalReceipt({
|
|
|
282
277
|
`excludeInvalidated` defaults to **true** here, the opposite of `searchKnowledge`: a brief offers every page it names with an id ready to cite, so a refuted page in it invites a run to build on a dead claim.
|
|
283
278
|
`maxChars` bounds the brief, and a page whose line does not fit is left out of `text`, `hits`, `citationIds`, and `results` alike, so all four always describe one identical set.
|
|
284
279
|
|
|
285
|
-
##
|
|
280
|
+
## Invalidated pages
|
|
286
281
|
|
|
287
|
-
A page whose own evidence refuted it carries an `invalidation`.
|
|
288
|
-
|
|
289
|
-
```ts
|
|
290
|
-
const plan = planInvalidationPropagation(originatedPages(await loadKnowledgePages(root)))
|
|
291
|
-
if (plan.stamps.length > 0) {
|
|
292
|
-
await applyKnowledgeWriteBlocks(root, formatKnowledgeInvalidationProposal(plan))
|
|
293
|
-
}
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
Each stamped page records `citesInvalidated: [ids]` in its frontmatter, and nothing else changes.
|
|
297
|
-
The plan is a diff, so a second pass over an already stamped store produces no mutation, and a citation whose target was revalidated has its stamp removed.
|
|
282
|
+
A page whose own evidence refuted it carries an `invalidation`.
|
|
298
283
|
`agent-knowledge lint` reports a `cites-invalidated` warning for every live citation into a refuted page, and `searchKnowledge(index, query, { excludeInvalidated: true })` drops the refuted pages from a result set.
|
|
299
284
|
The default stays `false`: a caller reading history needs them.
|
|
300
285
|
|
|
@@ -382,9 +367,7 @@ Use the narrowest API that matches the job:
|
|
|
382
367
|
|---|---|
|
|
383
368
|
| `runRetrievalImprovementLoop` | Runs one complete `OptimizationMethod` over serialized retrieval configuration. |
|
|
384
369
|
| `runRagOptimization` | Optimizes retrieval and answer behavior as one serialized RAG configuration. |
|
|
385
|
-
| `optimizeKnowledgeBasePolicy` | Optimizes a KB maintenance policy, then applies only the selected policy to an isolated candidate. |
|
|
386
370
|
| `scoreKnowledgeBaseIndex` | Measures KB structure, citations, source freshness, and configured quality thresholds. |
|
|
387
|
-
| `createRagAnswerQualityHook` | Adapts answer-quality checks such as support, relevance, citations, and abstention. |
|
|
388
371
|
| `runRagKnowledgeImprovementLoop` | Connects retrieval tuning, gap diagnosis, source acquisition, KB updates, answer checks, and a promotion decision. |
|
|
389
372
|
| `improveKnowledgeBase` | Adds resumable state, isolated candidates, exact promotion, and conflict detection around that process. |
|
|
390
373
|
|
|
@@ -433,7 +416,7 @@ Official external methods must report observed package identity.
|
|
|
433
416
|
Custom in-process methods have no external package identity, so their behavior must be covered by `executionRef`.
|
|
434
417
|
Treat `accountingComplete: false` as incomplete evidence for activation.
|
|
435
418
|
|
|
436
|
-
Retrieval, RAG, serialized-candidate
|
|
419
|
+
Retrieval, RAG, and serialized-candidate optimization accept Eval's optional `claim` and `finalEvidence` options.
|
|
437
420
|
Use `claim.independentUnit` to group questions from the same source.
|
|
438
421
|
A `new-units` claim requires separate source units for development and final evaluation.
|
|
439
422
|
Results retain scenario scores, source-unit scores, and both observation counts.
|
|
@@ -452,7 +435,6 @@ Only answer evaluation, the terminal promotion decision, and the returned result
|
|
|
452
435
|
Answer-quality evidence must name at least two final scenario IDs, immutable dataset and evaluator references, non-empty finite metrics, and observed cost accounting.
|
|
453
436
|
Promotion also requires `answerQualityCostCeiling`.
|
|
454
437
|
|
|
455
|
-
`calibrateRagAnswerJudge()` checks supplied strong and weak fixtures; it does not measure an evaluator's error rates.
|
|
456
438
|
For evaluator admission, use `auditEvaluator()` from `@tangle-network/agent-eval/meta-eval` with actual judgments of independently verified controls.
|
|
457
439
|
The application must enforce evaluator and auditor separation and retain evidence for the labels.
|
|
458
440
|
|
|
@@ -462,75 +444,16 @@ The application must enforce evaluator and auditor separation and retain evidenc
|
|
|
462
444
|
The package is not a memory database.
|
|
463
445
|
Install the provider you use, create its client, and pass that client to the adapter.
|
|
464
446
|
|
|
465
|
-
The memory APIs support scoped reads and writes
|
|
466
|
-
|
|
467
|
-
`runAgentMemoryImprovement` accepts a complete `OptimizationMethod`, evaluates each serialized configuration in an isolated provider branch, and activates only a winner that passes a separate final comparison.
|
|
468
|
-
Set `implementationRef` to `git:<40 lowercase hex>` or `sha256:<64 lowercase hex>` covering the installed implementation, method configuration, candidate construction, execution behavior, and external configuration so incompatible state cannot resume.
|
|
469
|
-
The run records one immutable candidate reference for each memory configuration and refuses cached results if that reference changes.
|
|
470
|
-
Critical dimensions use Eval's deciding interval and observation minimum.
|
|
471
|
-
Missing, insufficient, or indeterminate safety evidence holds activation.
|
|
472
|
-
An interval that crosses the safety margin remains uncertain; it is not reported as an observed regression.
|
|
473
|
-
Set `significance.independentUnitByScenarioId` when final sequences share a source unit.
|
|
474
|
-
The run captures this mapping before execution and binds it to resume identity.
|
|
475
|
-
Paired repetitions retain their coverage without increasing the independent-unit count.
|
|
476
|
-
Each improvement candidate declares a maximum for one sequence and one recovery attempt.
|
|
477
|
-
The adapter must enforce that maximum with its provider before starting external work.
|
|
478
|
-
The adapter callback must call `recordExternalCost()` with each observed charge.
|
|
479
|
-
Positive external work without a receipt is recorded as incomplete cost accounting, not as the configured maximum.
|
|
480
|
-
Use `0` only for a free local path.
|
|
481
|
-
Paid memory improvement defaults to a zero-dollar total limit; set `maxTotalCostUsd` and `maximumEvaluationCostUsd` before enabling paid work.
|
|
482
|
-
|
|
483
|
-
Use `runAgentMemoryLearningExperiment` to measure whether retained memory helps across ordered steps:
|
|
484
|
-
|
|
485
|
-
```ts
|
|
486
|
-
import { runAgentMemoryLearningExperiment } from '@tangle-network/agent-knowledge/memory'
|
|
487
|
-
|
|
488
|
-
const result = await runAgentMemoryLearningExperiment({
|
|
489
|
-
experimentId: 'support-memory',
|
|
490
|
-
runDir: 'support-memory',
|
|
491
|
-
candidates: [memoryCandidate],
|
|
492
|
-
sequences,
|
|
493
|
-
seed: 42,
|
|
494
|
-
reps: 5,
|
|
495
|
-
armOrder: 'stateful-first',
|
|
496
|
-
costCeiling: 10,
|
|
497
|
-
})
|
|
498
|
-
|
|
499
|
-
console.log(result.comparison.gain)
|
|
500
|
-
```
|
|
501
|
-
|
|
502
|
-
The function runs matched stateful and stateless arms with the same immutable candidate, tasks, executor, policy, seed, and repetitions.
|
|
503
|
-
The stateless arm clears declared scopes between steps; adapters must support scoped `clear`.
|
|
504
|
-
Gain excludes first-step probes and averages candidates and repetitions within each independent sequence.
|
|
505
|
-
Use `transferKey` on later probes for transfer and repeat one `retentionKey` across steps for forgetting.
|
|
506
|
-
Unmarked probes are not assigned those meanings.
|
|
507
|
-
|
|
508
|
-
Both arms share one cost limit and must have identical comparison references.
|
|
509
|
-
Run independent experiments with opposite `armOrder` values when provider behavior may drift.
|
|
510
|
-
Each saved probe includes the exact scoring input and content hash, so protect the run directory like the memory data itself.
|
|
511
|
-
Pass `signal` to cancel; rerun the same options and directory to resume completed work and cost records.
|
|
512
|
-
|
|
513
|
-
## Run benchmarks
|
|
514
|
-
|
|
515
|
-
`@tangle-network/agent-knowledge/benchmarks` provides common case and report types for:
|
|
516
|
-
|
|
517
|
-
- retrieval from qrels datasets
|
|
518
|
-
- RAG answer quality and unsupported claims
|
|
519
|
-
- knowledge-base improvement
|
|
520
|
-
- multi-turn memory behavior and provider comparison
|
|
521
|
-
|
|
522
|
-
The bundled industry cases are small smoke checks for adapter wiring.
|
|
523
|
-
They are not copies of full BEIR, MTEB, MS MARCO, LongMemEval, or other external datasets, and they do not produce a public leaderboard by themselves.
|
|
524
|
-
Import the real dataset rows or qrels and run them through `runKnowledgeBenchmarkSuite` for benchmark results.
|
|
447
|
+
The memory APIs support scoped reads and writes and isolated branches.
|
|
448
|
+
Compare providers on product tasks with `@tangle-network/agent-eval` before changing production behavior.
|
|
525
449
|
|
|
526
450
|
## Package boundaries
|
|
527
451
|
|
|
528
452
|
| Import | Contents |
|
|
529
453
|
|---|---|
|
|
530
454
|
| `@tangle-network/agent-knowledge` | KB files, indexes, search, validation, research callbacks, RAG evaluation, and candidate improvement |
|
|
531
|
-
| `@tangle-network/agent-knowledge/memory` | Memory contracts, provider adapters, branches, and
|
|
532
|
-
| `@tangle-network/agent-knowledge/
|
|
533
|
-
| `@tangle-network/agent-knowledge/benchmarks` | Benchmark cases, qrels import, execution, and reports |
|
|
455
|
+
| `@tangle-network/agent-knowledge/memory` | Memory contracts, provider adapters, branches, holdout, and play memory tools |
|
|
456
|
+
| `@tangle-network/agent-knowledge/benchmarks` | In-memory and no-op memory adapters for benchmark harnesses |
|
|
534
457
|
| `@tangle-network/agent-knowledge/viz` | Dependency-free graph analysis helpers |
|
|
535
458
|
|
|
536
459
|
Use the `agent-knowledge` binary for CLI commands rather than importing its CLI module.
|
|
@@ -541,8 +464,11 @@ Those choices stay in the application or in `@tangle-network/agent-runtime`.
|
|
|
541
464
|
## More detail
|
|
542
465
|
|
|
543
466
|
- [Architecture and data model](docs/architecture.md)
|
|
467
|
+
- [Run-scoped citations](docs/run-scoped-citations.md)
|
|
544
468
|
- [Knowledge retrieval and use receipts](docs/knowledge-use-receipts.md)
|
|
545
|
-
- [
|
|
469
|
+
- [QMD source snapshots](docs/qmd-retrieval.md)
|
|
470
|
+
- [Play-scoped Hindsight memory](docs/hindsight-memory.md)
|
|
471
|
+
- [Verified research comparison (historical; the research drivers were removed in 20.0.0)](docs/verified-research-ab.md)
|
|
546
472
|
- [Changelog](CHANGELOG.md)
|
|
547
473
|
|
|
548
474
|
## License
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { n as createNoopMemoryBenchmarkAdapter, t as createInMemoryBenchmarkAdapter } from "../index-OAxtm6is.js";
|
|
2
|
+
export { createInMemoryBenchmarkAdapter, createNoopMemoryBenchmarkAdapter };
|
package/dist/benchmarks/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { n as createNoopMemoryBenchmarkAdapter, t as createInMemoryBenchmarkAdapter } from "../benchmarks-jir3ZP-M.js";
|
|
2
|
+
export { createInMemoryBenchmarkAdapter, createNoopMemoryBenchmarkAdapter };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { n as memoryWriteResultToSourceRecord, t as memoryHitToSourceRecord } from "./source-record-CdWvzvO6.js";
|
|
2
|
+
//#region src/benchmarks/adapters.ts
|
|
3
|
+
function createNoopMemoryBenchmarkAdapter(id = "no-memory") {
|
|
4
|
+
return {
|
|
5
|
+
id,
|
|
6
|
+
branchIsolation: { mode: "scoped" },
|
|
7
|
+
async search() {
|
|
8
|
+
return [];
|
|
9
|
+
},
|
|
10
|
+
async getContext(query) {
|
|
11
|
+
return {
|
|
12
|
+
query,
|
|
13
|
+
text: "",
|
|
14
|
+
hits: [],
|
|
15
|
+
sourceRecords: []
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
async write(input) {
|
|
19
|
+
return {
|
|
20
|
+
accepted: false,
|
|
21
|
+
id: input.id ?? `${id}:ignored`,
|
|
22
|
+
uri: `memory://${id}/ignored`,
|
|
23
|
+
kind: input.kind
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
async clear() {},
|
|
27
|
+
async flush() {}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function createInMemoryBenchmarkAdapter(options = {}) {
|
|
31
|
+
const id = options.id ?? "in-memory";
|
|
32
|
+
const rows = [];
|
|
33
|
+
let seq = 0;
|
|
34
|
+
const adapter = {
|
|
35
|
+
id,
|
|
36
|
+
branchIsolation: { mode: "scoped" },
|
|
37
|
+
async search(query, searchOptions = {}) {
|
|
38
|
+
return rows.filter((row) => memoryScopeMatches(row.input.scope, searchOptions.scope)).filter((row) => !searchOptions.kinds?.length || searchOptions.kinds.includes(row.hit.kind)).map((row) => {
|
|
39
|
+
const lexical = tokenOverlap(query, row.hit.text);
|
|
40
|
+
const recency = row.seq / Math.max(1, seq);
|
|
41
|
+
return {
|
|
42
|
+
...row.hit,
|
|
43
|
+
score: lexical + recency * .01,
|
|
44
|
+
normalizedScore: lexical
|
|
45
|
+
};
|
|
46
|
+
}).filter((hit) => searchOptions.minScore === void 0 ? true : hit.score >= searchOptions.minScore).sort((a, b) => (b.score ?? 0) - (a.score ?? 0)).slice(0, searchOptions.limit ?? 5);
|
|
47
|
+
},
|
|
48
|
+
async getContext(query, searchOptions = {}) {
|
|
49
|
+
const hits = await adapter.search(query, searchOptions);
|
|
50
|
+
return {
|
|
51
|
+
query,
|
|
52
|
+
hits,
|
|
53
|
+
sourceRecords: hits.map((hit) => memoryHitToSourceRecord(hit, { scope: searchOptions.scope })),
|
|
54
|
+
text: renderMemoryHits(hits)
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
async write(input) {
|
|
58
|
+
seq += 1;
|
|
59
|
+
const memoryId = input.id ?? `${id}:${seq}`;
|
|
60
|
+
const hit = {
|
|
61
|
+
id: memoryId,
|
|
62
|
+
uri: `memory://${id}/${encodeURIComponent(memoryId)}`,
|
|
63
|
+
kind: input.kind,
|
|
64
|
+
text: input.text,
|
|
65
|
+
title: input.title,
|
|
66
|
+
score: 1,
|
|
67
|
+
normalizedScore: 1,
|
|
68
|
+
createdAt: input.metadata?.timestamp,
|
|
69
|
+
metadata: {
|
|
70
|
+
...input.metadata ?? {},
|
|
71
|
+
scope: input.scope
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
rows.push({
|
|
75
|
+
seq,
|
|
76
|
+
input,
|
|
77
|
+
hit
|
|
78
|
+
});
|
|
79
|
+
return {
|
|
80
|
+
accepted: true,
|
|
81
|
+
id: memoryId,
|
|
82
|
+
uri: hit.uri,
|
|
83
|
+
kind: input.kind,
|
|
84
|
+
sourceRecord: memoryWriteResultToSourceRecord({
|
|
85
|
+
accepted: true,
|
|
86
|
+
id: memoryId,
|
|
87
|
+
uri: hit.uri,
|
|
88
|
+
kind: input.kind,
|
|
89
|
+
metadata: hit.metadata
|
|
90
|
+
}, input.text, { scope: input.scope }),
|
|
91
|
+
metadata: hit.metadata
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
async clear(scope) {
|
|
95
|
+
for (let index = rows.length - 1; index >= 0; index -= 1) if (memoryScopeMatches(rows[index].input.scope, scope)) rows.splice(index, 1);
|
|
96
|
+
},
|
|
97
|
+
async flush() {}
|
|
98
|
+
};
|
|
99
|
+
return adapter;
|
|
100
|
+
}
|
|
101
|
+
function memoryEventId(hit) {
|
|
102
|
+
const eventId = hit.metadata?.eventId;
|
|
103
|
+
return typeof eventId === "string" ? eventId : void 0;
|
|
104
|
+
}
|
|
105
|
+
function memoryActorId(hit) {
|
|
106
|
+
const actorId = hit.metadata?.actorId;
|
|
107
|
+
return typeof actorId === "string" ? actorId : void 0;
|
|
108
|
+
}
|
|
109
|
+
function memoryScopeMatches(stored, requested) {
|
|
110
|
+
if (!requested) return true;
|
|
111
|
+
if (requested.tenantId !== void 0 && stored?.tenantId !== requested.tenantId) return false;
|
|
112
|
+
if (requested.userId !== void 0 && stored?.userId !== requested.userId) return false;
|
|
113
|
+
if (requested.agentId !== void 0 && stored?.agentId !== requested.agentId) return false;
|
|
114
|
+
if (requested.teamId !== void 0 && stored?.teamId !== requested.teamId) return false;
|
|
115
|
+
if (requested.runId !== void 0 && stored?.runId !== requested.runId) return false;
|
|
116
|
+
if (requested.sessionId !== void 0 && stored?.sessionId !== requested.sessionId) return false;
|
|
117
|
+
if (requested.namespace !== void 0 && stored?.namespace !== requested.namespace) return false;
|
|
118
|
+
for (const [key, value] of Object.entries(requested.tags ?? {})) if (stored?.tags?.[key] !== value) return false;
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
function tokenOverlap(query, text) {
|
|
122
|
+
const queryTokens = new Set(tokenize(query));
|
|
123
|
+
if (queryTokens.size === 0) return 0;
|
|
124
|
+
const textTokens = new Set(tokenize(text));
|
|
125
|
+
let matched = 0;
|
|
126
|
+
for (const token of queryTokens) if (textTokens.has(token)) matched += 1;
|
|
127
|
+
return matched / queryTokens.size;
|
|
128
|
+
}
|
|
129
|
+
function tokenize(text) {
|
|
130
|
+
const stop = /* @__PURE__ */ new Set([
|
|
131
|
+
"the",
|
|
132
|
+
"and",
|
|
133
|
+
"for",
|
|
134
|
+
"this",
|
|
135
|
+
"that",
|
|
136
|
+
"with",
|
|
137
|
+
"what",
|
|
138
|
+
"should",
|
|
139
|
+
"agent",
|
|
140
|
+
"user",
|
|
141
|
+
"current",
|
|
142
|
+
"now",
|
|
143
|
+
"use"
|
|
144
|
+
]);
|
|
145
|
+
return text.toLowerCase().split(/[^a-z0-9/]+/).filter((token) => token.length > 2 && !stop.has(token));
|
|
146
|
+
}
|
|
147
|
+
function renderMemoryHits(hits) {
|
|
148
|
+
return hits.map((hit, index) => {
|
|
149
|
+
const eventId = memoryEventId(hit);
|
|
150
|
+
const actorId = memoryActorId(hit);
|
|
151
|
+
return [
|
|
152
|
+
`[${index + 1}] ${hit.title ?? hit.id}`,
|
|
153
|
+
eventId ? `event=${eventId}` : "",
|
|
154
|
+
actorId ? `actor=${actorId}` : "",
|
|
155
|
+
hit.text
|
|
156
|
+
].filter(Boolean).join("\n");
|
|
157
|
+
}).join("\n\n");
|
|
158
|
+
}
|
|
159
|
+
//#endregion
|
|
160
|
+
export { createNoopMemoryBenchmarkAdapter as n, createInMemoryBenchmarkAdapter as t };
|
|
161
|
+
|
|
162
|
+
//# sourceMappingURL=benchmarks-jir3ZP-M.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmarks-jir3ZP-M.js","names":[],"sources":["../src/benchmarks/adapters.ts"],"sourcesContent":["import { memoryHitToSourceRecord, memoryWriteResultToSourceRecord } from '../memory/source-record'\n\nimport type {\n AgentMemoryAdapter,\n AgentMemoryHit,\n AgentMemoryScope,\n AgentMemoryWriteInput,\n} from '../memory/types'\n\nexport function createNoopMemoryBenchmarkAdapter(id = 'no-memory'): AgentMemoryAdapter {\n return {\n id,\n branchIsolation: { mode: 'scoped' },\n async search() {\n return []\n },\n async getContext(query) {\n return { query, text: '', hits: [], sourceRecords: [] }\n },\n async write(input) {\n return {\n accepted: false,\n id: input.id ?? `${id}:ignored`,\n uri: `memory://${id}/ignored`,\n kind: input.kind,\n }\n },\n async clear() {},\n async flush() {},\n }\n}\n\nexport function createInMemoryBenchmarkAdapter(options: { id?: string } = {}): AgentMemoryAdapter {\n const id = options.id ?? 'in-memory'\n const rows: Array<{\n seq: number\n input: AgentMemoryWriteInput\n hit: AgentMemoryHit\n }> = []\n let seq = 0\n const adapter: AgentMemoryAdapter = {\n id,\n branchIsolation: { mode: 'scoped' },\n async search(query, searchOptions = {}) {\n const scored = rows\n .filter((row) => memoryScopeMatches(row.input.scope, searchOptions.scope))\n .filter((row) => !searchOptions.kinds?.length || searchOptions.kinds.includes(row.hit.kind))\n .map((row) => {\n const lexical = tokenOverlap(query, row.hit.text)\n const recency = row.seq / Math.max(1, seq)\n return {\n ...row.hit,\n score: lexical + recency * 0.01,\n normalizedScore: lexical,\n }\n })\n .filter((hit) =>\n searchOptions.minScore === undefined ? true : hit.score! >= searchOptions.minScore,\n )\n .sort((a, b) => (b.score ?? 0) - (a.score ?? 0))\n return scored.slice(0, searchOptions.limit ?? 5)\n },\n async getContext(query, searchOptions = {}) {\n const hits = await adapter.search(query, searchOptions)\n return {\n query,\n hits,\n sourceRecords: hits.map((hit) =>\n memoryHitToSourceRecord(hit, { scope: searchOptions.scope }),\n ),\n text: renderMemoryHits(hits),\n }\n },\n async write(input) {\n seq += 1\n const memoryId = input.id ?? `${id}:${seq}`\n const hit: AgentMemoryHit = {\n id: memoryId,\n uri: `memory://${id}/${encodeURIComponent(memoryId)}`,\n kind: input.kind,\n text: input.text,\n title: input.title,\n score: 1,\n normalizedScore: 1,\n createdAt: input.metadata?.timestamp as string | undefined,\n metadata: {\n ...(input.metadata ?? {}),\n scope: input.scope,\n },\n }\n rows.push({ seq, input, hit })\n return {\n accepted: true,\n id: memoryId,\n uri: hit.uri,\n kind: input.kind,\n sourceRecord: memoryWriteResultToSourceRecord(\n {\n accepted: true,\n id: memoryId,\n uri: hit.uri,\n kind: input.kind,\n metadata: hit.metadata,\n },\n input.text,\n { scope: input.scope },\n ),\n metadata: hit.metadata,\n }\n },\n async clear(scope) {\n for (let index = rows.length - 1; index >= 0; index -= 1) {\n if (memoryScopeMatches(rows[index]!.input.scope, scope)) rows.splice(index, 1)\n }\n },\n async flush() {},\n }\n return adapter\n}\n\nexport function memoryEventId(hit: AgentMemoryHit): string | undefined {\n const eventId = hit.metadata?.eventId\n return typeof eventId === 'string' ? eventId : undefined\n}\n\nexport function memoryActorId(hit: AgentMemoryHit): string | undefined {\n const actorId = hit.metadata?.actorId\n return typeof actorId === 'string' ? actorId : undefined\n}\n\nfunction memoryScopeMatches(stored?: AgentMemoryScope, requested?: AgentMemoryScope): boolean {\n if (!requested) return true\n if (requested.tenantId !== undefined && stored?.tenantId !== requested.tenantId) return false\n if (requested.userId !== undefined && stored?.userId !== requested.userId) return false\n if (requested.agentId !== undefined && stored?.agentId !== requested.agentId) return false\n if (requested.teamId !== undefined && stored?.teamId !== requested.teamId) return false\n if (requested.runId !== undefined && stored?.runId !== requested.runId) return false\n if (requested.sessionId !== undefined && stored?.sessionId !== requested.sessionId) return false\n if (requested.namespace !== undefined && stored?.namespace !== requested.namespace) return false\n for (const [key, value] of Object.entries(requested.tags ?? {})) {\n if (stored?.tags?.[key] !== value) return false\n }\n return true\n}\n\nfunction tokenOverlap(query: string, text: string): number {\n const queryTokens = new Set(tokenize(query))\n if (queryTokens.size === 0) return 0\n const textTokens = new Set(tokenize(text))\n let matched = 0\n for (const token of queryTokens) {\n if (textTokens.has(token)) matched += 1\n }\n return matched / queryTokens.size\n}\n\nfunction tokenize(text: string): string[] {\n const stop = new Set([\n 'the',\n 'and',\n 'for',\n 'this',\n 'that',\n 'with',\n 'what',\n 'should',\n 'agent',\n 'user',\n 'current',\n 'now',\n 'use',\n ])\n return text\n .toLowerCase()\n .split(/[^a-z0-9/]+/)\n .filter((token) => token.length > 2 && !stop.has(token))\n}\n\nfunction renderMemoryHits(hits: readonly AgentMemoryHit[]): string {\n return hits\n .map((hit, index) => {\n const eventId = memoryEventId(hit)\n const actorId = memoryActorId(hit)\n return [\n `[${index + 1}] ${hit.title ?? hit.id}`,\n eventId ? `event=${eventId}` : '',\n actorId ? `actor=${actorId}` : '',\n hit.text,\n ]\n .filter(Boolean)\n .join('\\n')\n })\n .join('\\n\\n')\n}\n"],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { r as searchKnowledge } from "./search-BBr5eUyT.js";
|
|
2
|
+
import { Ht as layoutFor, J as validateKnowledgeIndex, Rt as initKnowledgeBase, Y as lintKnowledgeIndex, a as searchKnowledge, g as applyKnowledgeWriteBlocksFile, lt as loadSourceRegistry, n as inspectKnowledgeIndex, ot as writeKnowledgeIndex, st as addSourcePath, t as explainKnowledgeTarget } from "./inspect-CMigdsD5.js";
|
|
4
3
|
import { detectKnowledgeGaps, findSurprisingConnections, toKnowledgeVizGraph } from "./viz/index.js";
|
|
5
|
-
import { join, resolve } from "node:path";
|
|
6
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { join, resolve } from "node:path";
|
|
7
6
|
//#region src/cli.ts
|
|
8
7
|
function parseArgs(argv) {
|
|
9
8
|
const [command, ...rest] = argv;
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nimport { type buildKnowledgeIndex, writeKnowledgeIndex } from './indexer'\nimport { explainKnowledgeTarget, inspectKnowledgeIndex } from './inspect'\nimport { lintKnowledgeIndex } from './lint'\nimport type { KnowledgePagesOptions } from './pages-directory'\nimport { type ApplyKnowledgeWriteBlocksOptions, applyKnowledgeWriteBlocksFile } from './proposals'\nimport { searchKnowledge } from './search'\nimport { addSourcePath, loadSourceRegistry } from './sources'\nimport { initKnowledgeBase, layoutFor } from './store'\nimport { validateKnowledgeIndex } from './validate'\nimport { detectKnowledgeGaps, findSurprisingConnections, toKnowledgeVizGraph } from './viz/index'\n\ninterface Args {\n command: string\n positional: string[]\n flags: Record<string, string>\n}\n\nfunction parseArgs(argv: string[]): Args {\n const [command, ...rest] = argv\n const positional: string[] = []\n const flags: Record<string, string> = {}\n for (let i = 0; i < rest.length; i++) {\n const token = rest[i]!\n if (token.startsWith('--')) {\n const key = token.slice(2)\n const next = rest[i + 1]\n if (next && !next.startsWith('--')) {\n flags[key] = next\n i++\n } else {\n flags[key] = 'true'\n }\n } else {\n positional.push(token)\n }\n }\n return { command: command ?? 'help', positional, flags }\n}\n\nconst HELP = `agent-knowledge — source-grounded knowledge graph CLI.\n\nOptions shared by the commands below:\n --root <dir> Knowledge-base root. Defaults to the current directory.\n --pages-dir <dir> Root-relative directory that holds Markdown pages. Defaults to knowledge.\n Bounds apply-write-blocks and selects what index builds.\n\nCommands:\n init [--root .]\n Create raw/sources, knowledge, and cache directories.\n index [--root .] [--pages-dir knowledge] [--json]\n Build .agent-knowledge/index.json from <pages-dir>/**/*.md.\n source-add <path> [--root .] [--json]\n Copy a file or directory into raw/sources and register immutable source records.\n sources [--root .] [--json]\n List registered sources.\n apply-write-blocks <proposal-file> [--root .] [--pages-dir knowledge] [--intake]\n [--intake-threshold 0.82] [--json]\n Apply safe ---FILE: <pages-dir>/...--- blocks emitted by an agent.\n --intake refuses the whole proposal when a block duplicates a page already\n in the store without citing it, naming it in contradicts, or reusing its\n id, or when a block cites a page id that exists nowhere.\n --intake-threshold sets the duplicate Jaccard similarity.\n inspect [--root .] [--json]\n Summarize page/source/edge counts, top pages, and lint state.\n explain <page|id|query> [--root .] [--json]\n Explain sources, links, inbound links, and related pages.\n search <query> [--root .] [--pages-dir knowledge] [--limit 10] [--json]\n Local BM25 and link-graph search (RRF fused) over the generated knowledge index.\n graph [--root .] [--format summary|json]\n Emit graph summary or JSON.\n lint [--root .] [--json]\n Run deterministic structural lint.\n validate [--root .] [--strict] [--json]\n Run schema + lint validation. Exits non-zero on blocking findings.\n export [--root .] [--format json]\n Export the current index.\n viz [--root .] [--json]\n Emit graph gaps and surprising connections.\n version\n Print package version.\n`\n\nasync function main(): Promise<number> {\n const args = parseArgs(process.argv.slice(2))\n const root = resolve(args.flags.root ?? '.')\n const pages = pagesOptions(args)\n switch (args.command) {\n case 'init': {\n const layout = await initKnowledgeBase(root)\n process.stdout.write(`initialized knowledge base at ${layout.root}\\n`)\n return 0\n }\n case 'index': {\n const index = await writeKnowledgeIndex(root, pages)\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(index, null, 2)}\\n`)\n else\n process.stdout.write(\n `indexed ${index.pages.length} pages, ${index.graph.edges.length} edges\\n`,\n )\n return 0\n }\n case 'source-add': {\n const [path] = args.positional\n if (!path) {\n process.stderr.write('source-add requires a file or directory path\\n')\n return 1\n }\n await initKnowledgeBase(root)\n const sources = await addSourcePath(root, resolve(path))\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(sources, null, 2)}\\n`)\n else for (const source of sources) process.stdout.write(`${source.id} ${source.uri}\\n`)\n return 0\n }\n case 'sources': {\n const registry = await loadSourceRegistry(root)\n if (args.flags.json === 'true')\n process.stdout.write(`${JSON.stringify(registry.sources, null, 2)}\\n`)\n else {\n for (const source of registry.sources)\n process.stdout.write(`${source.id} ${source.title ?? source.uri} ${source.uri}\\n`)\n }\n return 0\n }\n case 'apply-write-blocks': {\n const [proposalPath] = args.positional\n if (!proposalPath) {\n process.stderr.write('apply-write-blocks requires a proposal file\\n')\n return 1\n }\n await initKnowledgeBase(root)\n const result = await applyKnowledgeWriteBlocksFile(root, resolve(proposalPath), {\n ...pages,\n ...intakeOption(args),\n })\n await writeKnowledgeIndex(root, pages)\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`)\n else {\n for (const path of result.written) process.stdout.write(`wrote ${path}\\n`)\n for (const warning of result.warnings) process.stderr.write(`warning: ${warning}\\n`)\n }\n return result.warnings.length > 0 ? 2 : 0\n }\n case 'inspect': {\n const index = await loadOrBuildIndex(root, pages)\n const inspection = inspectKnowledgeIndex(index)\n if (args.flags.json === 'true')\n process.stdout.write(`${JSON.stringify(inspection, null, 2)}\\n`)\n else {\n process.stdout.write(\n `pages=${inspection.pageCount} sources=${inspection.sourceCount} edges=${inspection.edgeCount} findings=${inspection.findingCount} blocking=${inspection.blockingFindingCount}\\n`,\n )\n for (const page of inspection.topPages.slice(0, 5))\n process.stdout.write(`${page.degree} ${page.path} sources=${page.sources}\\n`)\n }\n return inspection.blockingFindingCount > 0 ? 2 : 0\n }\n case 'explain': {\n const target = args.positional.join(' ')\n if (!target) {\n process.stderr.write('explain requires a page path, id, title, or query\\n')\n return 1\n }\n const explanation = explainKnowledgeTarget(await loadOrBuildIndex(root, pages), target)\n if (args.flags.json === 'true')\n process.stdout.write(`${JSON.stringify(explanation, null, 2)}\\n`)\n else {\n process.stdout.write(`${explanation.page ? explanation.page.title : target}\\n`)\n for (const source of explanation.sources)\n process.stdout.write(`source ${source.id} ${source.title ?? source.uri}\\n`)\n for (const link of explanation.links) process.stdout.write(`out ${link}\\n`)\n for (const inbound of explanation.inbound) process.stdout.write(`in ${inbound}\\n`)\n for (const related of explanation.related.slice(0, 5))\n process.stdout.write(`related ${related.path} score=${related.score.toFixed(5)}\\n`)\n }\n return 0\n }\n case 'search': {\n const query = args.positional.join(' ')\n if (!query) {\n process.stderr.write('search requires a query\\n')\n return 1\n }\n const index = await loadOrBuildIndex(root, pages)\n const results = searchKnowledge(index, query, Number(args.flags.limit ?? 10))\n if (args.flags.json === 'true') {\n process.stdout.write(`${JSON.stringify(results, null, 2)}\\n`)\n } else {\n for (const result of results) {\n process.stdout.write(\n `${result.rank}. ${result.page.title} (${result.page.path}) score=${result.score.toFixed(5)}\\n`,\n )\n if (result.snippet) process.stdout.write(` ${result.snippet}\\n`)\n }\n }\n return 0\n }\n case 'graph': {\n const index = await loadOrBuildIndex(root, pages)\n if ((args.flags.format ?? 'summary') === 'json')\n process.stdout.write(`${JSON.stringify(index.graph, null, 2)}\\n`)\n else\n process.stdout.write(\n `nodes=${index.graph.nodes.length} edges=${index.graph.edges.length}\\n`,\n )\n return 0\n }\n case 'lint': {\n const index = await loadOrBuildIndex(root, pages)\n const findings = lintKnowledgeIndex(index)\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(findings, null, 2)}\\n`)\n else {\n if (findings.length === 0) process.stdout.write('no findings\\n')\n for (const finding of findings) {\n process.stdout.write(\n `${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ''}: ${finding.message}\\n`,\n )\n }\n }\n return findings.some((finding) => finding.severity === 'error') ? 2 : 0\n }\n case 'validate': {\n const result = validateKnowledgeIndex(await loadOrBuildIndex(root, pages), {\n strict: args.flags.strict === 'true',\n })\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`)\n else {\n process.stdout.write(result.ok ? 'valid\\n' : 'invalid\\n')\n for (const finding of result.findings)\n process.stdout.write(\n `${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ''}: ${finding.message}\\n`,\n )\n }\n return result.ok ? 0 : 2\n }\n case 'export': {\n const index = await loadOrBuildIndex(root, pages)\n const format = args.flags.format ?? 'json'\n if (format !== 'json') {\n process.stderr.write('export currently supports --format json\\n')\n return 1\n }\n process.stdout.write(`${JSON.stringify(index, null, 2)}\\n`)\n return 0\n }\n case 'viz': {\n const index = await loadOrBuildIndex(root, pages)\n const viz = toKnowledgeVizGraph(index.graph)\n const payload = {\n graph: viz,\n gaps: detectKnowledgeGaps(viz),\n surprisingConnections: findSurprisingConnections(viz),\n }\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(payload, null, 2)}\\n`)\n else {\n process.stdout.write(\n `communities=${viz.communities.length} gaps=${payload.gaps.length} surprising=${payload.surprisingConnections.length}\\n`,\n )\n }\n return 0\n }\n case 'version': {\n const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as {\n version: string\n }\n process.stdout.write(`${pkg.version}\\n`)\n return 0\n }\n case 'help':\n case '--help':\n case '-h':\n process.stdout.write(HELP)\n return 0\n default:\n process.stderr.write(`unknown command: ${args.command}\\n${HELP}`)\n return 1\n }\n}\n\nfunction pagesOptions(args: Args): KnowledgePagesOptions {\n const pagesDirectory = args.flags['pages-dir']\n if (pagesDirectory === undefined) return {}\n if (pagesDirectory === 'true') throw new Error('--pages-dir requires a directory')\n return { pagesDirectory }\n}\n\nfunction intakeOption(args: Args): Pick<ApplyKnowledgeWriteBlocksOptions, 'intake'> {\n const threshold = args.flags['intake-threshold']\n if (args.flags.intake !== 'true') {\n if (threshold !== undefined) throw new Error('--intake-threshold requires --intake')\n return {}\n }\n if (threshold === undefined) return { intake: {} }\n if (threshold === 'true') throw new Error('--intake-threshold requires a number')\n const parsed = Number(threshold)\n if (!Number.isFinite(parsed)) throw new Error(`--intake-threshold is not a number: ${threshold}`)\n return { intake: { nearDuplicates: { threshold: parsed } } }\n}\n\nasync function loadOrBuildIndex(root: string, pages: KnowledgePagesOptions) {\n const path = join(layoutFor(root).cacheDir, 'index.json')\n if (existsSync(path))\n return JSON.parse(readFileSync(path, 'utf8')) as Awaited<ReturnType<typeof buildKnowledgeIndex>>\n return await writeKnowledgeIndex(root, pages)\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((err) => {\n process.stderr.write(\n `agent-knowledge error: ${err instanceof Error ? (err.stack ?? err.message) : String(err)}\\n`,\n )\n process.exit(1)\n })\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nimport { type buildKnowledgeIndex, writeKnowledgeIndex } from './indexer'\nimport { explainKnowledgeTarget, inspectKnowledgeIndex } from './inspect'\nimport { lintKnowledgeIndex } from './lint'\nimport type { KnowledgePagesOptions } from './pages-directory'\nimport { type ApplyKnowledgeWriteBlocksOptions, applyKnowledgeWriteBlocksFile } from './proposals'\nimport { searchKnowledge } from './search'\nimport { addSourcePath, loadSourceRegistry } from './sources'\nimport { initKnowledgeBase, layoutFor } from './store'\nimport { validateKnowledgeIndex } from './validate'\nimport { detectKnowledgeGaps, findSurprisingConnections, toKnowledgeVizGraph } from './viz/index'\n\ninterface Args {\n command: string\n positional: string[]\n flags: Record<string, string>\n}\n\nfunction parseArgs(argv: string[]): Args {\n const [command, ...rest] = argv\n const positional: string[] = []\n const flags: Record<string, string> = {}\n for (let i = 0; i < rest.length; i++) {\n const token = rest[i]!\n if (token.startsWith('--')) {\n const key = token.slice(2)\n const next = rest[i + 1]\n if (next && !next.startsWith('--')) {\n flags[key] = next\n i++\n } else {\n flags[key] = 'true'\n }\n } else {\n positional.push(token)\n }\n }\n return { command: command ?? 'help', positional, flags }\n}\n\nconst HELP = `agent-knowledge — source-grounded knowledge graph CLI.\n\nOptions shared by the commands below:\n --root <dir> Knowledge-base root. Defaults to the current directory.\n --pages-dir <dir> Root-relative directory that holds Markdown pages. Defaults to knowledge.\n Bounds apply-write-blocks and selects what index builds.\n\nCommands:\n init [--root .]\n Create raw/sources, knowledge, and cache directories.\n index [--root .] [--pages-dir knowledge] [--json]\n Build .agent-knowledge/index.json from <pages-dir>/**/*.md.\n source-add <path> [--root .] [--json]\n Copy a file or directory into raw/sources and register immutable source records.\n sources [--root .] [--json]\n List registered sources.\n apply-write-blocks <proposal-file> [--root .] [--pages-dir knowledge] [--intake]\n [--intake-threshold 0.82] [--json]\n Apply safe ---FILE: <pages-dir>/...--- blocks emitted by an agent.\n --intake refuses the whole proposal when a block duplicates a page already\n in the store without citing it, naming it in contradicts, or reusing its\n id, or when a block cites a page id that exists nowhere.\n --intake-threshold sets the duplicate Jaccard similarity.\n inspect [--root .] [--json]\n Summarize page/source/edge counts, top pages, and lint state.\n explain <page|id|query> [--root .] [--json]\n Explain sources, links, inbound links, and related pages.\n search <query> [--root .] [--pages-dir knowledge] [--limit 10] [--json]\n Local BM25 and link-graph search (RRF fused) over the generated knowledge index.\n graph [--root .] [--format summary|json]\n Emit graph summary or JSON.\n lint [--root .] [--json]\n Run deterministic structural lint.\n validate [--root .] [--strict] [--json]\n Run schema + lint validation. Exits non-zero on blocking findings.\n export [--root .] [--format json]\n Export the current index.\n viz [--root .] [--json]\n Emit graph gaps and surprising connections.\n version\n Print package version.\n`\n\nasync function main(): Promise<number> {\n const args = parseArgs(process.argv.slice(2))\n const root = resolve(args.flags.root ?? '.')\n const pages = pagesOptions(args)\n switch (args.command) {\n case 'init': {\n const layout = await initKnowledgeBase(root)\n process.stdout.write(`initialized knowledge base at ${layout.root}\\n`)\n return 0\n }\n case 'index': {\n const index = await writeKnowledgeIndex(root, pages)\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(index, null, 2)}\\n`)\n else\n process.stdout.write(\n `indexed ${index.pages.length} pages, ${index.graph.edges.length} edges\\n`,\n )\n return 0\n }\n case 'source-add': {\n const [path] = args.positional\n if (!path) {\n process.stderr.write('source-add requires a file or directory path\\n')\n return 1\n }\n await initKnowledgeBase(root)\n const sources = await addSourcePath(root, resolve(path))\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(sources, null, 2)}\\n`)\n else for (const source of sources) process.stdout.write(`${source.id} ${source.uri}\\n`)\n return 0\n }\n case 'sources': {\n const registry = await loadSourceRegistry(root)\n if (args.flags.json === 'true')\n process.stdout.write(`${JSON.stringify(registry.sources, null, 2)}\\n`)\n else {\n for (const source of registry.sources)\n process.stdout.write(`${source.id} ${source.title ?? source.uri} ${source.uri}\\n`)\n }\n return 0\n }\n case 'apply-write-blocks': {\n const [proposalPath] = args.positional\n if (!proposalPath) {\n process.stderr.write('apply-write-blocks requires a proposal file\\n')\n return 1\n }\n await initKnowledgeBase(root)\n const result = await applyKnowledgeWriteBlocksFile(root, resolve(proposalPath), {\n ...pages,\n ...intakeOption(args),\n })\n await writeKnowledgeIndex(root, pages)\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`)\n else {\n for (const path of result.written) process.stdout.write(`wrote ${path}\\n`)\n for (const warning of result.warnings) process.stderr.write(`warning: ${warning}\\n`)\n }\n return result.warnings.length > 0 ? 2 : 0\n }\n case 'inspect': {\n const index = await loadOrBuildIndex(root, pages)\n const inspection = inspectKnowledgeIndex(index)\n if (args.flags.json === 'true')\n process.stdout.write(`${JSON.stringify(inspection, null, 2)}\\n`)\n else {\n process.stdout.write(\n `pages=${inspection.pageCount} sources=${inspection.sourceCount} edges=${inspection.edgeCount} findings=${inspection.findingCount} blocking=${inspection.blockingFindingCount}\\n`,\n )\n for (const page of inspection.topPages.slice(0, 5))\n process.stdout.write(`${page.degree} ${page.path} sources=${page.sources}\\n`)\n }\n return inspection.blockingFindingCount > 0 ? 2 : 0\n }\n case 'explain': {\n const target = args.positional.join(' ')\n if (!target) {\n process.stderr.write('explain requires a page path, id, title, or query\\n')\n return 1\n }\n const explanation = explainKnowledgeTarget(await loadOrBuildIndex(root, pages), target)\n if (args.flags.json === 'true')\n process.stdout.write(`${JSON.stringify(explanation, null, 2)}\\n`)\n else {\n process.stdout.write(`${explanation.page ? explanation.page.title : target}\\n`)\n for (const source of explanation.sources)\n process.stdout.write(`source ${source.id} ${source.title ?? source.uri}\\n`)\n for (const link of explanation.links) process.stdout.write(`out ${link}\\n`)\n for (const inbound of explanation.inbound) process.stdout.write(`in ${inbound}\\n`)\n for (const related of explanation.related.slice(0, 5))\n process.stdout.write(`related ${related.path} score=${related.score.toFixed(5)}\\n`)\n }\n return 0\n }\n case 'search': {\n const query = args.positional.join(' ')\n if (!query) {\n process.stderr.write('search requires a query\\n')\n return 1\n }\n const index = await loadOrBuildIndex(root, pages)\n const results = searchKnowledge(index, query, Number(args.flags.limit ?? 10))\n if (args.flags.json === 'true') {\n process.stdout.write(`${JSON.stringify(results, null, 2)}\\n`)\n } else {\n for (const result of results) {\n process.stdout.write(\n `${result.rank}. ${result.page.title} (${result.page.path}) score=${result.score.toFixed(5)}\\n`,\n )\n if (result.snippet) process.stdout.write(` ${result.snippet}\\n`)\n }\n }\n return 0\n }\n case 'graph': {\n const index = await loadOrBuildIndex(root, pages)\n if ((args.flags.format ?? 'summary') === 'json')\n process.stdout.write(`${JSON.stringify(index.graph, null, 2)}\\n`)\n else\n process.stdout.write(\n `nodes=${index.graph.nodes.length} edges=${index.graph.edges.length}\\n`,\n )\n return 0\n }\n case 'lint': {\n const index = await loadOrBuildIndex(root, pages)\n const findings = lintKnowledgeIndex(index)\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(findings, null, 2)}\\n`)\n else {\n if (findings.length === 0) process.stdout.write('no findings\\n')\n for (const finding of findings) {\n process.stdout.write(\n `${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ''}: ${finding.message}\\n`,\n )\n }\n }\n return findings.some((finding) => finding.severity === 'error') ? 2 : 0\n }\n case 'validate': {\n const result = validateKnowledgeIndex(await loadOrBuildIndex(root, pages), {\n strict: args.flags.strict === 'true',\n })\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`)\n else {\n process.stdout.write(result.ok ? 'valid\\n' : 'invalid\\n')\n for (const finding of result.findings)\n process.stdout.write(\n `${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ''}: ${finding.message}\\n`,\n )\n }\n return result.ok ? 0 : 2\n }\n case 'export': {\n const index = await loadOrBuildIndex(root, pages)\n const format = args.flags.format ?? 'json'\n if (format !== 'json') {\n process.stderr.write('export currently supports --format json\\n')\n return 1\n }\n process.stdout.write(`${JSON.stringify(index, null, 2)}\\n`)\n return 0\n }\n case 'viz': {\n const index = await loadOrBuildIndex(root, pages)\n const viz = toKnowledgeVizGraph(index.graph)\n const payload = {\n graph: viz,\n gaps: detectKnowledgeGaps(viz),\n surprisingConnections: findSurprisingConnections(viz),\n }\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(payload, null, 2)}\\n`)\n else {\n process.stdout.write(\n `communities=${viz.communities.length} gaps=${payload.gaps.length} surprising=${payload.surprisingConnections.length}\\n`,\n )\n }\n return 0\n }\n case 'version': {\n const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as {\n version: string\n }\n process.stdout.write(`${pkg.version}\\n`)\n return 0\n }\n case 'help':\n case '--help':\n case '-h':\n process.stdout.write(HELP)\n return 0\n default:\n process.stderr.write(`unknown command: ${args.command}\\n${HELP}`)\n return 1\n }\n}\n\nfunction pagesOptions(args: Args): KnowledgePagesOptions {\n const pagesDirectory = args.flags['pages-dir']\n if (pagesDirectory === undefined) return {}\n if (pagesDirectory === 'true') throw new Error('--pages-dir requires a directory')\n return { pagesDirectory }\n}\n\nfunction intakeOption(args: Args): Pick<ApplyKnowledgeWriteBlocksOptions, 'intake'> {\n const threshold = args.flags['intake-threshold']\n if (args.flags.intake !== 'true') {\n if (threshold !== undefined) throw new Error('--intake-threshold requires --intake')\n return {}\n }\n if (threshold === undefined) return { intake: {} }\n if (threshold === 'true') throw new Error('--intake-threshold requires a number')\n const parsed = Number(threshold)\n if (!Number.isFinite(parsed)) throw new Error(`--intake-threshold is not a number: ${threshold}`)\n return { intake: { nearDuplicates: { threshold: parsed } } }\n}\n\nasync function loadOrBuildIndex(root: string, pages: KnowledgePagesOptions) {\n const path = join(layoutFor(root).cacheDir, 'index.json')\n if (existsSync(path))\n return JSON.parse(readFileSync(path, 'utf8')) as Awaited<ReturnType<typeof buildKnowledgeIndex>>\n return await writeKnowledgeIndex(root, pages)\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((err) => {\n process.stderr.write(\n `agent-knowledge error: ${err instanceof Error ? (err.stack ?? err.message) : String(err)}\\n`,\n )\n process.exit(1)\n })\n"],"mappings":"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"}
|