Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Two ways in, depending on what you're doing:
- *"Spawn live agents to improve a KB"* → pass an `updateKnowledge` callback to `improveKnowledgeBase`; runtime-backed supervisors live in `@tangle-network/agent-runtime`.
- *"Tune retrieval for a knowledge base"* → `runRetrievalImprovementLoop` in the [Agent-Eval integration](#agent-eval-integration) section.
- *"Run an operator-grade KB improvement cycle"* → `improveKnowledgeBase` in the [Agent-Eval integration](#agent-eval-integration) section.
It creates a candidate KB, lets agents or deterministic hooks improve it, runs configured evals, can be resumed, and promotes only when the live KB has not changed underneath it.
It creates a candidate KB, lets agents or deterministic hooks improve it, runs configured evals, and returns exact candidate identity for later approval.
- *"Expose the lower-level RAG lifecycle phases"* → `runRagKnowledgeImprovementLoop` in the [Agent-Eval integration](#agent-eval-integration) section.
It exposes retrieval tuning, gap diagnosis, knowledge acquisition/update, answer-quality checks, and promotion as one typed lifecycle.
- *"Evaluate RAG answers or a wiki/KB"* → `ragAnswerQualityJudge`, `createRagAnswerQualityHook`, and `scoreKnowledgeBaseIndex` in the [Agent-Eval integration](#agent-eval-integration) section.
Expand All @@ -53,8 +53,8 @@ Storage stays consumer-owned via `KbStore` (`MemoryKbStore`, `FileSystemKbStore`
| RAG | Retrieval eval, source-span labels, answer quality checks, missing/stale/noisy-source diagnosis | `runRagKnowledgeImprovementLoop` |
| Memory DB | Adapter contract that turns memory hits into source-like evidence and benchmark rows | `/memory` plus `runMemoryAdapterBenchmark` |
| From scratch | Empty KB layout, source ingestion, write-block application, indexing, readiness checks | CLI `init` or `runKnowledgeResearchLoop` |
| Existing KB | Candidate workspace, resume state, base-hash conflict check, promotion only after evals pass | `improveKnowledgeBase` |
| Parallel agents | Per-run locks, isolated candidates, `promote: false` handoff, retry with the same `runId` | `improveKnowledgeBase` with runtime workers |
| Existing KB | Candidate workspace, resume state, base-hash conflict check, exact approved promotion | `improveKnowledgeBase` |
| Parallel agents | Per-run locks, isolated candidates, frozen candidate handoff, retry with the same `runId` | `improveKnowledgeBase` with runtime workers |
| One-call agent job | Runtime supervisor plus all KB mechanics above | `runKnowledgeImprovementJob` from `@tangle-network/agent-runtime/knowledge` |

## CLI
Expand Down Expand Up @@ -119,7 +119,7 @@ from `@tangle-network/agent-knowledge`.
without this package hardcoding an agent runner.
- `improveKnowledgeBase()` wraps that lifecycle with durable candidate state,
a per-run lock, resume support, isolated candidate workspaces, KB quality
scoring, and conflict-safe promotion.
scoring, and an exact candidate reference for explicit promotion.
Use it when running agents in loops against a real KB rather than only
exposing phase hooks.
- `evaluateKnowledgeBaseReadiness()` checks one KB root without running an
Expand Down Expand Up @@ -223,13 +223,14 @@ const result = await runKnowledgeBenchmarkSuite({
respond: async ({ case: testCase }) => {
if (testCase.taskKind !== 'retrieval') return { hits: [] }
const hits = await retrieveFromYourKb(testCase.query)
return { hits, costUsd: 0.001 }
return { hits }
},
})

console.log(result.report.score.mean)
```

Billable responders must execute paid work through `context.cost.runPaidCall()`; `costUsd` on an artifact is display-only.
Use `buildRetrievalBenchmarkCasesFromQrels()` for qrels-backed retrieval datasets.
The smoke pack proves that every declared benchmark family is wired through the runner; full BEIR, MTEB, MS MARCO, TREC DL, MIRACL, LoTTE, BRIGHT, CRAG, HotpotQA, KILT, RAGTruth, and FaithBench runs should pass real dataset rows through the same case shapes.
Use `KnowledgeAnswerBenchmarkCase` for CRAG/HotpotQA/KILT-style answer checks and RAGTruth/FaithBench-style hallucination checks by encoding required claims, forbidden claims, and expected source IDs.
Expand Down Expand Up @@ -272,6 +273,7 @@ const kbQuality = scoreKnowledgeBaseIndex(index, {
Use `runRagKnowledgeImprovementLoop` when the product question is broader than retrieval:
can the system find the gaps, gather or update knowledge, prove generated answers still behave, and decide whether to promote?
`agent-knowledge` owns the knowledge/eval contract; the caller supplies the research, coding, connector, and answer-eval hooks.
This lower-level loop returns a promotion recommendation; it never writes to the live knowledge base.

```ts
import { runRagKnowledgeImprovementLoop } from '@tangle-network/agent-knowledge'
Expand Down Expand Up @@ -299,12 +301,17 @@ console.log(result.promotion)
```

Use `improveKnowledgeBase` when a program should own the candidate workspace and promotion mechanics.
The wrapper composes the same RAG lifecycle, but adds resumable state under `.agent-knowledge/improvements/<runId>/`, a lock lease for parallel operators, and a base-hash check before copying the candidate over the live KB.
The wrapper composes the same RAG lifecycle, but adds resumable state under `.agent-knowledge/improvements/<runId>/`, a lock lease for parallel operators, and exact candidate bytes that can be approved later.

```ts
import { improveKnowledgeBase } from '@tangle-network/agent-knowledge'
import {
improveKnowledgeBase,
knowledgeImprovementCandidateRef,
promoteKnowledgeCandidate,
withKnowledgeImprovementCandidate,
} from '@tangle-network/agent-knowledge'

const result = await improveKnowledgeBase({
const staged = await improveKnowledgeBase({
root: './kb',
goal: 'Improve support refund-policy knowledge',
readinessSpecs,
Expand All @@ -320,11 +327,24 @@ const result = await improveKnowledgeBase({
requiredPhases: ['knowledge-update', 'retrieval-tuning', 'answer-quality'],
})

console.log(result.promoted, result.candidate?.evaluation)
const candidate = knowledgeImprovementCandidateRef(staged)
console.log(staged.evaluation, candidate)

await withKnowledgeImprovementCandidate({ root: './kb', candidate }, async (snapshot) => {
await inspectCandidateFiles(snapshot.root, snapshot.evaluation)
})

// Call this only after your product records approval for this exact candidate.
const promoted = await promoteKnowledgeCandidate({ root: './kb', candidate })
console.log(promoted.promoted)
```

Pass `promote: false` to leave the candidate workspace open for another agent or a human edit.
Calling `improveKnowledgeBase` again with the same `runId` re-evaluates that candidate and promotes it only if the original live KB hash still matches.
`improveKnowledgeBase` stages a measured candidate by default and does not change the live knowledge base.
Calling it again with the same `runId` resumes interrupted work.
`withKnowledgeImprovementCandidate` materializes the measured bytes in an isolated temporary directory for the callback, checks them again afterward, and removes the directory.
`promoteKnowledgeCandidate` applies only the frozen bytes identified by the approved candidate reference, and refuses if the live base changed.
The current release intentionally accepts only its strict run-state format; incomplete runs created by 1.x must be completed or restarted before upgrading.
The exact candidate workflow requires Linux; other knowledge, retrieval, and evaluation APIs remain cross-platform.

If a required phase is missing its hook, the loop throws.
That keeps the public API from reporting a fake “RAG improved” result when the caller only wired retrieval or only wired a researcher.
Expand Down Expand Up @@ -558,7 +578,7 @@ await runTwoAgentResearchLoop({
`agent-knowledge` owns knowledge state and measurement.
It deliberately does not own an agent runner.
Live agent orchestration belongs in `@tangle-network/agent-runtime`.
Use the one-call runtime job when you want agents, candidate workspaces, readiness checks, promotion, and spend measurement wired together:
Use the one-call runtime job when you want agents, candidate workspaces, readiness checks, exact candidate handoff, and spend measurement wired together:

```ts
import { runKnowledgeImprovementJob } from '@tangle-network/agent-runtime/knowledge'
Expand Down
14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tangle-network/agent-knowledge",
"version": "1.12.1",
"version": "2.0.0",
"description": "Source-grounded, eval-gated knowledge growth primitives for agents.",
"homepage": "https://github.com/tangle-network/agent-knowledge#readme",
"repository": {
Expand Down Expand Up @@ -68,14 +68,16 @@
"format": "biome format --write src tests"
},
"dependencies": {
"@tangle-network/agent-eval": "^0.115.1",
"@tangle-network/agent-eval": "^0.118.3",
"proper-lockfile": "4.1.2",
"zod": "^4.3.6"
},
"devDependencies": {
"@biomejs/biome": "^2.4.15",
"@neo4j-labs/agent-memory": "0.4.0",
"@tangle-network/sandbox": "^0.9.7",
"@types/node": "^25.6.0",
"@types/proper-lockfile": "4.1.4",
"tsup": "^8.0.0",
"tsx": "^4.22.4",
"typescript": "^5.7.0",
Expand All @@ -86,10 +88,14 @@
"minimumReleaseAgeExclude": [
"@tangle-network/agent-eval",
"@tangle-network/sandbox"
]
],
"overrides": {
"hono": "4.12.30",
"ws": "8.21.0"
}
},
"engines": {
"node": ">=20"
"node": ">=20.19.0"
},
"license": "MIT",
"packageManager": "pnpm@10.28.0"
Expand Down
Loading
Loading