@tangle-network/agent-knowledge 3.2.1 → 4.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 ADDED
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ ## 4.0.1
4
+
5
+ ### Changed
6
+
7
+ - Split benchmark, memory experiment, and memory improvement internals into focused modules while preserving every public export and signature.
8
+ - Split memory and benchmark tests by behavior, with shared controller and adapter fixtures kept in one test-support module.
9
+ - Moved retrieval holdout contracts into the memory type layer to remove the holdout/types import cycle.
10
+
11
+ ### Fixed
12
+
13
+ - Made the Mem0 deletion-convergence test deterministic under file-level parallel execution.
14
+
15
+ ## 4.0.0
16
+
17
+ ### Breaking Changes
18
+
19
+ - `runAgentMemoryImprovement()` now activates a measured winner through `activation.readCurrent()` and atomic `activation.compareAndSet()` instead of `onPromote`.
20
+ - `AgentMemoryActivation.receiptPath` is now `journalPath` because the file is an append-only activation record.
21
+ - `mem0MemoryAdapterIdentity()` and `graphitiMemoryAdapterIdentity()` require a stable, non-secret `backendRef` so two deployments cannot share a cache identity.
22
+ - Mem0 hosted mode now follows the synchronous array response from `mem0ai` 3.x; the unsupported queued-event options were removed.
23
+ - Paid benchmark and improvement work now defaults to a zero dollar limit and requires an explicit `costCeiling` or `maxTotalCostUsd`.
24
+ - In-flight run directories from releases before 4.0 are not migrated; archive or clear them before upgrading because 4.0 rejects older attempt records.
25
+
26
+ ### Added
27
+
28
+ - Official-client adapters for Mem0 hosted and open-source deployments, Graphiti MCP, and Neo4j Agent Memory.
29
+ - Isolated memory branches with snapshots, replayable forks, private, team, and shared visibility, and ordered writes per agent.
30
+ - Parallel multi-track memory experiments and configuration search on `agent-eval`, with fresh-history comparison before activation.
31
+ - Durable controller ownership, interrupted-attempt cleanup, retired-candidate recovery, bounded cleanup work, and conservative recovery cost reconciliation.
32
+ - Complete candidate cost attribution across interrupted retries, plus explicit unranked recovery spend for retired benchmark candidates.
33
+ - Exact scoped Mem0 deletion with list and search convergence checks.
34
+
35
+ ### Fixed
36
+
37
+ - Mem0 and direct Neo4j operations reject provider scopes they cannot enforce before any provider call.
38
+ - Hosted Mem0 `appId` is an additional filter and cannot authorize an unscoped whole-application read or delete.
39
+ - Mem0 cleanup tracks fresh writes until they become visible and confirms deletion from both list and search indexes.
40
+ - Broader Mem0 cleanup scopes wait for delayed writes created under matching narrower scopes.
41
+ - Mem0 pending-write probes expire after the configured visibility window instead of accumulating for the adapter lifetime.
42
+ - Direct Neo4j reasoning writes reject combined session and run scopes because the SDK can enforce only one conversation identifier.
43
+ - Timed-out provider work blocks close or reuse of the same adapter until the original operation settles.
44
+ - Recovery retries are reserved durably before provider work and stop after three failures per attempt by default.
45
+ - Direct memory benchmarks account for billable adapter provisioning and reconnects in the shared dollar limit.
46
+ - Fully cached benchmark resumes skip adapter creation and add no provider charge.
47
+ - Execute and recovery adapter factories receive abort signals and are bounded by the configured timeout.
48
+ - Adapters returned after a timed-out factory call are closed, and experiment adapters also run their configured disposal callback.
49
+ - Reported dollar totals are normalized to twelve decimal places instead of exposing binary floating-point artifacts.
package/README.md CHANGED
@@ -11,9 +11,9 @@ This package turns raw sources and generated markdown knowledge into a versionab
11
11
  - [Common uses](#common-uses): wiki, RAG, memory, new KBs, existing KBs, and parallel agents
12
12
  - [CLI](#cli): `init` → `source-add` → `index` → `search` → `lint`
13
13
  - [Design](#design): the invariants, including immutable sources, cited claims, and deterministic graph output
14
- - [Benchmark harness](#benchmark-harness): BEIR/MTEB/qrels, RAG answer, hallucination, KB-improvement cases
14
+ - [Benchmark runner](#benchmark-runner): BEIR/MTEB/qrels, RAG answer, hallucination, KB-improvement cases
15
15
  - [Agent-Eval integration](#agent-eval-integration): retrieval eval, readiness bundles, and release reports
16
- - [Memory adapters](#memory-adapters): generic memory contract plus Neo4j Agent Memory bridge
16
+ - [Memory adapters](#memory-adapters): Mem0, Graphiti, Neo4j, branching, and automatic improvement
17
17
  - [Research loop](#research-loop): `runKnowledgeResearchLoop` plus the control-loop adapter
18
18
  - [Runtime integration](#runtime-integration): how agent runners plug into the pure KB loop
19
19
  - [Pluggable knowledge sources](#pluggable-knowledge-sources): live authorities → eval re-runs
@@ -39,8 +39,8 @@ Two ways in, depending on what you're doing:
39
39
  - *"Expose the lower-level RAG lifecycle phases"* → `runRagKnowledgeImprovementLoop` in the [Agent-Eval integration](#agent-eval-integration) section.
40
40
  It exposes retrieval tuning, gap diagnosis, knowledge acquisition/update, answer-quality checks, and promotion as one typed lifecycle.
41
41
  - *"Evaluate RAG answers or a wiki/KB"* → `ragAnswerQualityJudge`, `createRagAnswerQualityHook`, and `scoreKnowledgeBaseIndex` in the [Agent-Eval integration](#agent-eval-integration) section.
42
- - *"Run standard RAG/KB benchmarks"* → `runKnowledgeBenchmarkSuite` in the [Benchmark harness](#benchmark-harness) section.
43
- - *"Does this candidate KB actually improve task success?"* → run an [agent-eval improvement loop](#agent-eval-integration) over KB variants, then `knowledgeReleaseReport` for the promotion decision.
42
+ - *"Run standard RAG/KB benchmarks"* → `runKnowledgeBenchmarkSuite` in the [Benchmark runner](#benchmark-runner) section.
43
+ - *"Does this candidate KB improve task success?"* → run an [agent-eval improvement loop](#agent-eval-integration) over KB variants, then `knowledgeReleaseReport` for the promotion decision.
44
44
  - *"Keep live authorities fresh"* → [pluggable sources](#pluggable-knowledge-sources) + `detectChanges` → eval re-runs.
45
45
 
46
46
  Storage stays consumer-owned via `KbStore` (`MemoryKbStore`, `FileSystemKbStore`, or your own D1/Postgres). Every primitive below is source-grounded: claims cite immutable source records, and lint fails on un-grounded citations.
@@ -51,10 +51,10 @@ Storage stays consumer-owned via `KbStore` (`MemoryKbStore`, `FileSystemKbStore`
51
51
  |---|---|---|
52
52
  | LLM wiki or docs KB | Source records, cited markdown pages, lint, readiness scoring, candidate promotion | `improveKnowledgeBase` or `runKnowledgeResearchLoop` |
53
53
  | RAG | Retrieval eval, source-span labels, answer quality checks, missing/stale/noisy-source diagnosis | `runRagKnowledgeImprovementLoop` |
54
- | Memory DB | Adapter contract that turns memory hits into source-like evidence and benchmark rows | `/memory` plus `runMemoryAdapterBenchmark` |
54
+ | Memory DB | Provider adapters, isolated branches, sharing policies, ordered histories, and fresh comparison | `/memory` plus `runAgentMemoryExperiment` |
55
55
  | From scratch | Empty KB layout, source ingestion, write-block application, indexing, readiness checks | CLI `init` or `runKnowledgeResearchLoop` |
56
56
  | Existing KB | Candidate workspace, resume state, base-hash conflict check, exact approved promotion | `improveKnowledgeBase` |
57
- | Parallel agents | Per-run locks, isolated candidates, frozen candidate handoff, retry with the same `runId` | `improveKnowledgeBase` with runtime workers |
57
+ | Parallel agents | Isolated KB candidates or memory branches, ordered per-agent writes, concurrent histories, and explicit activation | `improveKnowledgeBase` or `runAgentMemoryImprovement` |
58
58
  | One-call agent job | Runtime supervisor plus all KB mechanics above | `runKnowledgeImprovementJob` from `@tangle-network/agent-runtime/knowledge` |
59
59
 
60
60
  ## CLI
@@ -132,7 +132,7 @@ from `@tangle-network/agent-knowledge`.
132
132
  - Zod schemas define the stable wire shape.
133
133
  - Graph/search/lint are deterministic and fast.
134
134
  - `searchKnowledge` returns hits with three score fields. `score` and
135
- `rrfScore` are the raw reciprocal-rank-fusion value (typically 0.010.05);
135
+ `rrfScore` are the raw reciprocal-rank-fusion value (typically 0.01 to 0.05);
136
136
  use them when intent matters or when fusing across queries.
137
137
  `normalizedScore` is the same value scaled into [0, 1] relative to the top
138
138
  hit *in this result set* (top hit = 1, others = score / topScore). Use it
@@ -151,7 +151,7 @@ The `/memory` subpath exports an optional memory adapter contract. Use it to
151
151
  bridge episodic or graph-native memory systems into the same source-grounded
152
152
  readiness/eval machinery without making `agent-knowledge` own the database.
153
153
 
154
- ## Benchmark Harness
154
+ ## Benchmark Runner
155
155
 
156
156
  Use `runKnowledgeBenchmarkSuite()` when the product goal is to run a fixed RAG/KB benchmark pack and get one report across retrieval, answer quality, hallucination, and candidate-KB improvement cases.
157
157
  The module also exports `INDUSTRY_RAG_BENCHMARKS`, a compact manifest for BEIR, MTEB retrieval, MS MARCO, TREC DL, MIRACL, LoTTE, BRIGHT, CRAG, HotpotQA, KILT, RAGTruth, FaithBench, and first-party KB-improvement tasks.
@@ -171,17 +171,18 @@ import {
171
171
  runMemoryAdapterBenchmark,
172
172
  runKnowledgeBenchmarkSuite,
173
173
  } from '@tangle-network/agent-knowledge/benchmarks'
174
- import { createNeo4jAgentMemoryAdapter } from '@tangle-network/agent-knowledge/memory'
175
174
 
176
175
  await runKnowledgeBenchmarkSuite({
177
176
  cases: buildIndustryRagBenchmarkSmokeCases(),
178
177
  runDir: '.agent-knowledge/benchmark-runs/industry-smoke',
178
+ respondRef: 'industry-rag-smoke:v1',
179
179
  respond: respondToIndustryRagBenchmarkSmokeCase,
180
180
  })
181
181
 
182
182
  await runKnowledgeBenchmarkSuite({
183
183
  cases: buildIndustryMemoryBenchmarkSmokeCases(),
184
184
  runDir: '.agent-knowledge/benchmark-runs/memory-smoke',
185
+ respondRef: 'industry-memory-smoke:v1',
185
186
  respond: ({ case: testCase }) => {
186
187
  if (!isKnowledgeMemoryBenchmarkCase(testCase)) return { answer: '' }
187
188
  return respondToIndustryMemoryBenchmarkSmokeCase({ case: testCase })
@@ -191,18 +192,15 @@ await runKnowledgeBenchmarkSuite({
191
192
  const memoryRanking = await runMemoryAdapterBenchmark({
192
193
  cases: buildFirstPartyMemoryLifecycleBenchmarkCases(),
193
194
  runDir: '.agent-knowledge/benchmark-runs/memory-ranking',
195
+ costCeiling: 5,
194
196
  candidates: [
195
- { id: 'no-memory', createAdapter: () => createNoopMemoryBenchmarkAdapter() },
197
+ { id: 'no-memory', ref: 'no-memory:v1', createAdapter: () => createNoopMemoryBenchmarkAdapter() },
196
198
  {
197
199
  id: 'in-memory',
200
+ ref: 'in-memory:v1',
198
201
  createAdapter: () => createInMemoryBenchmarkAdapter(),
199
202
  searchLimit: 1,
200
203
  },
201
- {
202
- id: 'neo4j-agent-memory',
203
- createAdapter: () => createNeo4jAgentMemoryAdapter({ client: neo4jMemoryClient }),
204
- searchLimit: 5,
205
- },
206
204
  ],
207
205
  })
208
206
 
@@ -220,6 +218,8 @@ const cases = buildRetrievalBenchmarkCasesFromQrels({
220
218
  const result = await runKnowledgeBenchmarkSuite({
221
219
  cases,
222
220
  runDir: '.agent-knowledge/benchmark-runs/beir-nfcorpus-smoke',
221
+ respondRef: 'product-retriever:v3',
222
+ costCeiling: 5,
223
223
  respond: async ({ case: testCase }) => {
224
224
  if (testCase.taskKind !== 'retrieval') return { hits: [] }
225
225
  const hits = await retrieveFromYourKb(testCase.query)
@@ -230,7 +230,29 @@ const result = await runKnowledgeBenchmarkSuite({
230
230
  console.log(result.report.score.mean)
231
231
  ```
232
232
 
233
+ `runMemoryAdapterBenchmark()` is for adapters that enforce every supplied scope and support exact scoped deletion.
234
+ Every cell records its fresh provider namespace before the first write and deletes it after measurement, so concurrent repetitions and retries cannot share memory.
235
+ On restart, unfinished scopes are deleted before any new benchmark cell runs.
236
+ The candidate factory receives `purpose: 'execute' | 'recovery'`, `signal`, and `markExternalCall()`; both paths must reconnect to the same provider and adapter identity.
237
+ Pass `signal` to provider connection and provisioning calls so timeout cancellation reaches the SDK.
238
+ Set `adapterId` when the returned adapter ID differs from the candidate ID.
239
+ The declared ID lets a fully cached resume skip adapter creation entirely; a returned mismatch fails before any case runs.
240
+ Keep local construction free.
241
+ When construction provisions or reconnects billable provider state, set `adapterCreationCostUsd` and call `markExternalCall()` immediately before the external action.
242
+ Normal read and write work belongs in adapter methods so it runs inside per-case cost accounting.
243
+ Use `runAgentMemoryExperiment()` below when an agent profile needs ordered multi-step histories, branch snapshots, runtime callbacks, or automatic configuration improvement.
244
+ Set `cleanupTimeoutMs` to bound each provider cleanup and close operation; the default is 180 seconds.
245
+ Set `costUsdPerCase` for normal provider work, `adapterCreationCostUsd` for billable construction or reconnects, and `recoveryCostUsdPerAttempt` when deleting an interrupted case can add another provider charge.
246
+ One `costCeiling` covers every candidate and recovery call in the comparison, and `totalCostUsd` reports the complete comparison cost.
247
+ `unrankedRecoveryCostUsd` identifies cleanup spend from retired candidates that cannot appear in ranking rows.
248
+ The default `costCeiling` is zero, so paid work is refused until the caller sets a limit.
249
+ Keep removed implementations in `recoveryCandidates` until their unfinished scopes are gone, and use `maxRecoveryAttempts` to reject an unexpectedly large backlog before provider work starts.
250
+ Each failed recovery is recorded before its provider call.
251
+ `maxRecoveryRetriesPerAttempt` defaults to three, and `recoveryLogPath` identifies the durable retry history returned by the run.
252
+ The default filesystem storage uses an OS lock; custom storage requires `controllerMode: 'process-local'` or a distributed `acquireRunLease` implementation.
253
+
233
254
  Billable responders must execute paid work through `context.cost.runPaidCall()`; `costUsd` on an artifact is display-only.
255
+ Change `respondRef` whenever the model, prompt, retrieval, tools, or runtime behavior changes; resumable runs reject a missing reference instead of reusing ambiguous cached rows.
234
256
  Use `buildRetrievalBenchmarkCasesFromQrels()` for qrels-backed retrieval datasets.
235
257
  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.
236
258
  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.
@@ -239,7 +261,8 @@ Use `KnowledgeMemoryBenchmarkCase` for memory systems.
239
261
  Memory cases carry ordered events plus current required facts, stale forbidden facts, expected event IDs, and expected actor IDs.
240
262
  The built-in memory scorer reports current fact recall, stale-memory safety, event recall, and actor recall, which maps to LoCoMo, LongMemEval, Memora, MemoryAgentBench, MemoryBank-style personalization, GroupMemBench, and first-party memory lifecycle checks.
241
263
  Use `runMemoryAdapterBenchmark()` to rank real memory systems that implement `AgentMemoryAdapter`.
242
- This is the path for Neo4j Agent Memory, Mem0, Zep, Letta, Graphiti, a vector store, or a product-owned memory backend.
264
+ Built-in adapters cover Neo4j Agent Memory, Mem0 hosted and open source, and the official Graphiti MCP server.
265
+ Zep, Letta, a vector store, or a product-owned backend can implement the same small contract.
243
266
 
244
267
  ## Agent-Eval Integration
245
268
 
@@ -364,7 +387,7 @@ That keeps the public API from reporting a fake “RAG improved” result when t
364
387
 
365
388
  Use retrieval eval when the question is whether a retrieval/RAG config can find the right knowledge before an agent reasons over it.
366
389
  The labels should name stable pages, source records, anchors, or source spans, not ephemeral chunk IDs.
367
- The completion roadmap is in [`docs/eval/rag-eval-roadmap.md`](docs/eval/rag-eval-roadmap.md).
390
+ Benchmark coverage and completion criteria are documented in [`docs/eval/rag-eval-roadmap.md`](docs/eval/rag-eval-roadmap.md).
368
391
 
369
392
  ```ts
370
393
  import { runRetrievalImprovementLoop } from '@tangle-network/agent-knowledge'
@@ -392,7 +415,7 @@ Pass a custom `retrieve` function to `buildRetrievalEvalDispatch` when the confi
392
415
  The built-in fallback uses `searchKnowledge` over the local deterministic index.
393
416
  Use `buildRetrievalEvalDispatch`, `retrievalRecallJudge`, and `retrievalParameterSweepProposer` directly only when you need custom `agent-eval` wiring.
394
417
 
395
- To answer whether a candidate knowledge base actually improves agent task success, run an `@tangle-network/agent-eval` improvement loop (`runImprovementLoop`) over your KB variants on a real task corpus; each run is scored into a `RunRecord`.
418
+ To answer whether a candidate knowledge base improves agent task success, run an `@tangle-network/agent-eval` improvement loop (`runImprovementLoop`) over your KB variants on a real task corpus; each run is scored into a `RunRecord`.
396
419
 
397
420
  Use `knowledgeReleaseReport()` before promotion: pass the candidate and baseline `RunRecord[]` (plus optional `ReleaseTraceEvidence` and the gate decision) and it folds them into a `ReleaseConfidenceScorecard` and a `KnowledgeRelease` using `agent-eval`'s release gates and `RunRecord` validation.
398
421
 
@@ -429,35 +452,278 @@ Pass `readiness.report` to `blockingKnowledgeEval()` from
429
452
 
430
453
  ## Memory Adapters
431
454
 
432
- `agent-knowledge` does not store operational memory itself. It defines the
433
- contract that lets a runtime read/write memory through any backend, then turn
434
- memory hits into `SourceRecord` evidence for readiness, linting, and eval gates.
455
+ `agent-knowledge` does not replace a memory database.
456
+ It gives existing memory systems one contract, isolated branches, ordered multi-agent histories, comparable measurements, and an automatic improvement loop.
457
+
458
+ Use the provider adapter that matches the system you already run:
435
459
 
436
460
  ```ts
437
461
  import {
462
+ createGraphitiMemoryAdapter,
463
+ createMem0MemoryAdapter,
438
464
  createNeo4jAgentMemoryAdapter,
439
- memoryHitToSourceRecord,
440
465
  } from '@tangle-network/agent-knowledge/memory'
441
466
 
442
- const memory = createNeo4jAgentMemoryAdapter({ client: neo4jMemoryClient })
467
+ const mem0Hosted = createMem0MemoryAdapter({
468
+ client: mem0Client,
469
+ mode: 'hosted',
470
+ backendRef: 'mem0:production-account',
471
+ })
472
+
473
+ const mem0Oss = createMem0MemoryAdapter({
474
+ client: mem0OssClient,
475
+ mode: 'oss',
476
+ backendRef: 'mem0:local-postgres',
477
+ })
478
+
479
+ const graphiti = createGraphitiMemoryAdapter({
480
+ client: graphitiMcpClient,
481
+ backendRef: 'graphiti:production-cluster',
482
+ })
483
+
484
+ const neo4j = createNeo4jAgentMemoryAdapter({
485
+ client: neo4jMemoryClient,
486
+ transport: 'rest',
487
+ contextMode: 'search',
488
+ })
489
+ ```
490
+
491
+ The Graphiti defaults match the current official server tools: `add_memory`, `search_memory_facts`, `search_nodes`, `get_episodes`, and `clear_graph`.
492
+ Set `toolNames` explicitly when your server lists different names.
493
+ The adapter never retries a write under another name because that could enqueue it twice.
494
+ Visible writes expand the episode scan when Graphiti truncates a long group and fail explicitly at `episodeScanLimit` instead of reporting a false success.
495
+ Hosted Mem0 follows the synchronous memory-array response from `mem0ai` 3.x and rejects legacy asynchronous event responses instead of treating them as successful writes.
496
+ Mem0 cleanup requires `getAll` plus per-memory `delete`, refuses an empty identity scope, and waits until both list and search results stop returning deleted IDs.
497
+ Every Mem0 operation requires `userId`, `agentId`, `runId`, or `namespace`.
498
+ `appId`, tenant, team, session, and tag filters refine that identity but cannot replace it.
499
+ Fresh-write probes expire after `ingestionTimeoutMs`, so a long-lived adapter retains only its current visibility window rather than its lifetime write history.
500
+ The adapter does not call Mem0's account-wide `deleteAll` method.
501
+ Use a stable, non-secret `backendRef` in Mem0 and Graphiti adapter identities so caches and dispatch keys cannot alias two accounts or clusters.
502
+
503
+ Each adapter uses the same `search`, `getContext`, and `write` method shape, but provider capabilities remain explicit.
504
+
505
+ | Adapter | Searchable through this adapter | Writable through this adapter |
506
+ | --- | --- | --- |
507
+ | Mem0 hosted or OSS | messages, observations, facts, entities, preferences, reasoning traces | all six kinds |
508
+ | Graphiti MCP | extracted facts and entities | all six kinds as episodes |
509
+ | Neo4j hosted REST | messages, observations, entities | messages, observations, entities, conversation reasoning steps |
510
+ | Neo4j bridge | messages, observations, entities, preferences, similar reasoning traces | all six kinds |
511
+
512
+ Neo4j bridge facts are graph writes.
513
+ The official `@neo4j-labs/agent-memory` 0.4 API has no corresponding fact-search method, so fact-only retrieval experiments should use another provider or a custom Neo4j query adapter.
514
+ Mem0 and Graphiti apply tenant, user, agent, team, run, session, namespace, and tag filters per request, subject to Mem0's required provider identity above.
515
+ Neo4j Agent Memory experiments require disposable external state per branch because the SDK cannot clear every memory kind atomically.
516
+ On a shared Neo4j client, the adapter rejects scope fields the selected SDK method cannot enforce before making a provider call.
517
+ Conversation messages can use `sessionId`, and reasoning writes can use either `sessionId` or `runId`; other direct operations are unscoped unless a dedicated client is used.
518
+ Pass `branchId` only after the caller has provisioned one physically isolated instance for that exact branch.
519
+ Provider-specific identifiers remain internal to the adapter.
520
+ Custom adapters must declare `branchIsolation: { mode: 'scoped' }` only when every operation enforces the supplied scope; undeclared adapters are rejected by branch execution.
521
+
522
+ ```ts
523
+ const neo4jInstances = new WeakMap<object, string>()
524
+
525
+ const neo4jCandidate = {
526
+ id: 'neo4j',
527
+ ref: 'neo4j-agent-memory:0.4.0:rest',
528
+ policy: { read: ['shared'], write: 'shared' },
529
+ async createAdapter({ branchId, purpose, signal, markExternalCall }: {
530
+ branchId: string
531
+ purpose: 'execute' | 'recovery'
532
+ signal: AbortSignal
533
+ markExternalCall(): void
534
+ }) {
535
+ markExternalCall()
536
+ const client = purpose === 'recovery'
537
+ ? await openDedicatedNeo4jMemory({ branchId, transport: 'rest', signal })
538
+ : await provisionDedicatedNeo4jMemory({ branchId, transport: 'rest', signal })
539
+ if (!client) return null
540
+ const adapter = createNeo4jAgentMemoryAdapter({ client, transport: 'rest', branchId })
541
+ neo4jInstances.set(adapter, branchId)
542
+ return adapter
543
+ },
544
+ async disposeAdapter(adapter: object) {
545
+ const branchId = neo4jInstances.get(adapter)
546
+ if (!branchId) throw new Error('unknown Neo4j branch')
547
+ await destroyDedicatedNeo4jMemory({ branchId })
548
+ },
549
+ }
550
+ ```
551
+
552
+ The adapter requires `transport: 'rest' | 'bridge'` and rejects unsupported searches or writes before making a provider call.
553
+ `contextMode: 'search'` is the default and preserves query-based behavior across providers.
554
+ Set `contextMode: 'native'` with hosted REST to use Neo4j's whole-conversation context for message and observation memory.
555
+
556
+ Use a branch when agents or candidate configurations must not share state accidentally:
557
+
558
+ ```ts
559
+ import {
560
+ createAgentMemoryBranch,
561
+ createMem0MemoryAdapter,
562
+ } from '@tangle-network/agent-knowledge/memory'
563
+
564
+ const memory = createAgentMemoryBranch({
565
+ adapter: mem0Oss,
566
+ branchId: 'candidate-17',
567
+ policy: { read: ['private', 'team'], write: 'team' },
568
+ baseScope: { tenantId: 'acme', teamId: 'research' },
569
+ })
443
570
 
444
- const context = await memory.getContext('What does this user prefer?', {
445
- scope: { userId: 'user-123', sessionId: 'session-456' },
571
+ await memory.write({
572
+ kind: 'fact',
573
+ text: 'The launch date is Friday.',
574
+ scope: { agentId: 'researcher' },
575
+ })
576
+
577
+ const context = await memory.getContext('When is launch?', {
578
+ scope: { agentId: 'builder' },
446
579
  limit: 5,
447
580
  })
448
581
 
449
- const sourceRecords = context.hits.map((hit) =>
450
- memoryHitToSourceRecord(hit, { scope: { userId: 'user-123' } }),
451
- )
582
+ const snapshot = await memory.snapshot()
583
+ await memory.close?.()
584
+ const reopenedMem0Oss = createMem0MemoryAdapter({
585
+ client: mem0OssClient,
586
+ mode: 'oss',
587
+ id: snapshot.adapterId,
588
+ })
589
+ const resumed = createAgentMemoryBranch({
590
+ adapter: reopenedMem0Oss,
591
+ branchId: 'candidate-17',
592
+ snapshot,
593
+ })
594
+ ```
595
+
596
+ Private writes stay visible only to one agent.
597
+ Team writes are shared inside one team.
598
+ Shared writes are visible to every agent in the branch.
599
+ `fork()` replays accepted writes into a child branch, including a branch backed by a different provider.
600
+ One adapter object can have only one live handle for a given branch ID in a process.
601
+ Close the prior handle before resuming it, and use the run lease to prevent distributed controllers from owning the same durable run at once.
602
+
603
+ Use `runAgentMemoryExperiment()` to compare known providers or configurations across ordered histories.
604
+ `buildAgentMemorySequencesFromBenchmarkCases()` feeds existing LoCoMo, LongMemEval, GroupMemBench, or first-party memory cases into the same runner without changing their event order.
605
+ Use `runAgentMemoryImprovement()` when a proposer should search configurations, measure them on training histories, compare the winner with the baseline on fresh histories, and activate it only after a statistically supported win.
606
+
607
+ ```ts
608
+ const result = await runAgentMemoryImprovement({
609
+ experimentId: 'support-memory-v3',
610
+ trainSequences,
611
+ holdoutSequences,
612
+ seeds: [
613
+ {
614
+ config: currentConfig,
615
+ track: 'conservative',
616
+ proposer: 'conservative',
617
+ vision: 'Improve recall without increasing stale-memory reuse.',
618
+ },
619
+ {
620
+ config: graphConfig,
621
+ track: 'graph',
622
+ proposer: 'graph',
623
+ vision: 'Improve temporal and multi-actor reasoning.',
624
+ },
625
+ ],
626
+ proposer: configProposer,
627
+ proposers: {
628
+ conservative: conservativeConfigProposer,
629
+ graph: graphConfigProposer,
630
+ },
631
+ improvementRef: 'memory-stack@8f2c1a7',
632
+ budget: { maxSteps: 12 },
633
+ maxTotalCostUsd: 25,
634
+ candidateConcurrency: 4,
635
+ sequenceConcurrency: 8,
636
+ createCandidate: ({ config }) => buildMemoryCandidate(config),
637
+ executeStep: ({ memory, step, context }) =>
638
+ runProfileStep({ memory, step, context }),
639
+ executeStepRef: 'support-profile@8f2c1a7',
640
+ runDir: '.agent-knowledge/memory-runs/support-v3',
641
+ activation: {
642
+ ref: 'config-store:support-memory:v1',
643
+ readCurrent: () => configStore.read('support-memory'),
644
+ compareAndSet: ({
645
+ activationId,
646
+ expectedSurfaceHash,
647
+ config,
648
+ surfaceHash,
649
+ }) => configStore.compareAndSet({
650
+ key: 'support-memory',
651
+ operationId: activationId,
652
+ expectedHash: expectedSurfaceHash,
653
+ nextHash: surfaceHash,
654
+ value: config,
655
+ }),
656
+ },
657
+ })
452
658
  ```
453
659
 
454
- The Neo4j adapter is runtime dependency-free: pass the real
455
- `@neo4j-labs/agent-memory` client in products, or a fake client in tests. CI
456
- typechecks against `@neo4j-labs/agent-memory@0.4.0` and covers the published
457
- TypeScript SDK surface: `shortTerm.addMessage/searchMessages/getContext`,
458
- `longTerm.addEntity/addPreference/addFact/searchEntities/searchPreferences`,
459
- and `reasoning.getSimilarTraces`. Generic `search` / `getContext` and
460
- snake_case bridge-style methods remain supported for non-hosted clients.
660
+ `candidateConcurrency` controls how many configurations are measured at once.
661
+ `sequenceConcurrency` controls how many independent histories run at once.
662
+ Every experiment candidate must set `ref` to a version or commit that changes whenever its provider configuration or adapter behavior changes.
663
+ The first seed is always the deployed baseline.
664
+ Each seed starts an independent track with its own objective and optional proposer, and a branch inherits its parent track's proposer unless the governor chooses another one.
665
+ Candidate factories should perform local construction only when possible.
666
+ When a dedicated instance must be provisioned or reconnected, call `markExternalCall()` immediately before that action.
667
+ Set each candidate's `externalCostUsdPerSequence` to a conservative memory-provider charge; it is counted once an adapter method or a marked factory action attempts provider work, while a local factory failure costs zero.
668
+ Set `externalRecoveryCostUsdPerAttempt` when reconnecting and deleting an interrupted history adds a separate provider charge.
669
+ Recovery uses the same durable run-wide cost account as candidate execution, proposers, profile steps, and the governor, so a resumed run cannot exceed `maxTotalCostUsd` by treating cleanup as free work.
670
+ `runAgentMemoryExperiment()` reports all attempt and recovery spend in `totalCostUsd`, with retired-candidate cleanup separated as `unrankedRecoveryCostUsd`.
671
+ Cleanup completion is journaled before a paid-call receipt.
672
+ If a process exits between those writes, resume charges the reserved maximum without repeating provider cleanup and continues only after the account is complete.
673
+ The default `maxTotalCostUsd` is zero, so model and paid provider calls require an explicit limit.
674
+ Model calls inside `executeStep` should use `context.cost.runPaidCall()` so `maxTotalCostUsd` counts both sources before starting more work.
675
+ The same budget is supplied to named proposers as `context.costLedger` and to the governor as `context.costLedger`; the standard `agent-eval` proposers charge their model calls there.
676
+ Steps inside one history remain ordered, and writes from one agent remain ordered while independent agents can write concurrently.
677
+ Runtime callbacks may write only to scopes declared on a step, write, probe, or `sequence.cleanupScopes`; this lets an interrupted retry clear every actor and session it could have touched.
678
+ Search never changes the live configuration.
679
+ Only `activation.compareAndSet` can activate the fresh-history winner.
680
+ The activation target must provide an exact current read and an atomic compare-and-set from the measured baseline to the measured winner.
681
+ The durable activation journal is written before that operation.
682
+ After a crash, the runner reads the live configuration and records the completed activation without applying it twice.
683
+ Change `activation.ref` whenever the target or activation behavior changes.
684
+ The default filesystem path permits one controller and many parallel workers, persists candidate history, and resumes without adding more than `maxSteps` candidate nodes.
685
+ Custom storage must set `controllerMode: 'process-local'` when all controllers share one process, or provide `acquireRunLease` for distributed controllers.
686
+ Independent workers still use `candidateConcurrency` and `sequenceConcurrency`.
687
+ Every measured cell receives a fresh provider branch ID for that execution attempt.
688
+ This prevents a late asynchronous write from a crashed worker from entering a retried cell.
689
+ `experimentRunId` keeps the logical experiment identity stable across workers without reusing physical branch state.
690
+ Timed-out histories enter bounded branch cleanup before `runAgentMemoryExperiment()` returns.
691
+ The run waits for cleanup to succeed or for `cleanupTimeoutMs` to expire, and either cleanup failure leaves the attempt available for recovery.
692
+ The runner appends a `started` event before adapter creation and a `cleaned` event only after provider cleanup and disposal succeed.
693
+ On resume it recovers every unfinished attempt before starting new cells.
694
+ Independent unfinished attempts recover up to `maxConcurrency` at once, and no new cell starts until every cleanup succeeds.
695
+ Recovery refuses more than `maxRecoveryAttempts`, which defaults to 1000.
696
+ Recovery also refuses a fourth failed cleanup for the same attempt by default.
697
+ Set `maxRecoveryRetriesPerAttempt` to change that limit; its durable retry record is returned as `recoveryLogPath`.
698
+ `runAgentMemoryImprovement()` forwards the same option to every training and fresh-history experiment.
699
+ Pass retired implementations through `recoveryCandidates` until their recorded attempts are cleaned.
700
+ `createAdapter` receives `purpose: 'recovery'` during that pass so a dedicated-instance candidate can reconnect to the existing branch instead of provisioning another one.
701
+ It may return `null` during recovery when the recorded attempt never created external state.
702
+ Hosted Mem0 and Graphiti recovery waits for their configured ingestion timeout before deletion so an accepted asynchronous write can become visible first.
703
+ That visibility wait is bounded by `cleanupTimeoutMs`; a longer required delay fails before new provider work starts.
704
+ The default filesystem storage survives process restarts and uses an OS lock.
705
+ Custom durable storage must implement atomic `append`; process-local custom storage opts in with `controllerMode: 'process-local'`, and distributed controllers provide `acquireRunLease`.
706
+ Provider SDK calls should also have their own network timeout because a caller-side cleanup timeout cannot cancel an arbitrary third-party promise.
707
+ Candidate factories receive an `AbortSignal` and must pass it into provider connection or provisioning calls.
708
+ The persisted run identity includes `budget.maxSteps`; start a new `runDir` to enlarge a completed search instead of mutating its history.
709
+ Promotion is blocked when a configured critical dimension is missing or incomplete on either fresh-history arm.
710
+ Improvement runs clear each scoped branch before and after a measured history by default, including timeout and thrown-error cleanup.
711
+ Set `cleanupBranches: false` only when the candidate creates and disposes a physically isolated provider instance per cell.
712
+ The current Neo4j SDK has no complete all-memory clear operation, so a Neo4j improvement run must use disposable per-cell service instances with `cleanupBranches: false` and `disposeAdapter`; a persistent shared workspace is rejected because failed retries could read partial state.
713
+ If recovery cannot confirm deletion, the resumed run stops before launching new provider work and leaves the attempt active for another retry.
714
+
715
+ The package stays independent of `agent-runtime`.
716
+ The `executeStep` callback is where a runtime profile, coding agent, research agent, or deterministic worker uses the branch.
717
+ This keeps provider and measurement code reusable while the profile owns what agents do and what they choose to remember.
718
+
719
+ The Neo4j adapter accepts the real `@neo4j-labs/agent-memory` client and rejects unsafe branch reuse unless `branchId` identifies caller-provisioned isolated state.
720
+ The Mem0 adapter typechecks against `mem0ai` hosted and open-source clients and accepts only the current hosted SDK response shape.
721
+ The Graphiti adapter calls the official MCP tools and waits for queued episodes to become visible before evaluating them by default.
722
+ Hosted Mem0 and Graphiti visible writes are safe only in `lifetime: 'attempt'` branches because their writes may outlive a worker process.
723
+ `runAgentMemoryExperiment()` creates those fresh attempt branches automatically.
724
+ Attempt snapshots are audit and fork inputs, not restart points; use `forkAgentMemoryBranchSnapshot()` to replay one into a fresh branch.
725
+ Mem0 OSS and caller-provisioned disposable instances can use resumable branches.
726
+ Graphiti `consistency: 'queued'` is available only for direct ingestion and is rejected by branch execution.
461
727
 
462
728
  ## Research Loop
463
729
 
@@ -549,11 +815,11 @@ with its own pass (`driverResearches: true`), and gates on the readiness check.
549
815
  Both are yours (no creds). The loop owns the deterministic mechanics (indexing,
550
816
  applying write blocks, scoring readiness) and stops once no blocking gap remains.
551
817
 
552
- Does the verifying driver actually earn its keep? See
553
- [docs/two-agent-research-ab.md](docs/two-agent-research-ab.md) for an equal-compute
554
- A/B (9 ML topics, `glm-5.2`): the two-agent loop admits ~2.33 fewer sources per topic
555
- at identical coverage, though most of that win is de-duplication, not relevance
556
- filtering. Honest caveats and how to reproduce included.
818
+ An equal-compute comparison across 9 ML topics using `glm-5.2` is documented in
819
+ [docs/two-agent-research-ab.md](docs/two-agent-research-ab.md).
820
+ The two-agent loop admitted about 2.33 fewer sources per topic at identical coverage.
821
+ Most of that difference came from de-duplication rather than relevance filtering.
822
+ The document includes limitations and reproduction steps.
557
823
 
558
824
  ```ts
559
825
  import {
@@ -1,5 +1,52 @@
1
- import '@tangle-network/agent-eval/campaign';
2
- import '../types-BFRyr390.js';
3
- export { B as BuildRetrievalBenchmarkCasesFromQrelsOptions, I as INDUSTRY_MEMORY_BENCHMARKS, d as INDUSTRY_RAG_BENCHMARKS, K as KnowledgeAnswerBenchmarkCase, e as KnowledgeAnswerBenchmarkTaskKind, f as KnowledgeBenchmarkArtifact, g as KnowledgeBenchmarkCase, h as KnowledgeBenchmarkCaseBase, i as KnowledgeBenchmarkDistribution, j as KnowledgeBenchmarkEvaluation, k as KnowledgeBenchmarkFamily, l as KnowledgeBenchmarkReport, m as KnowledgeBenchmarkResponder, n as KnowledgeBenchmarkScenario, o as KnowledgeBenchmarkSliceSummary, p as KnowledgeBenchmarkSource, q as KnowledgeBenchmarkSpec, r as KnowledgeBenchmarkSplit, s as KnowledgeBenchmarkTaskKind, t as KnowledgeClaimMatcher, u as KnowledgeMemoryBenchmarkCase, v as KnowledgeMemoryBenchmarkTaskKind, w as KnowledgeMemoryEvent, x as KnowledgeMemoryFactMatcher, y as KnowledgeRetrievalBenchmarkCase, z as KnowledgeRetrievalBenchmarkQrel, A as KnowledgeRetrievalBenchmarkQuery, M as MemoryAdapterBenchmarkCandidate, C as MemoryAdapterBenchmarkRankingRow, V as RunKnowledgeBenchmarkSuiteOptions, W as RunKnowledgeBenchmarkSuiteResult, X as RunMemoryAdapterBenchmarkOptions, Y as RunMemoryAdapterBenchmarkResult, Z as buildFirstPartyMemoryLifecycleBenchmarkCases, _ as buildIndustryMemoryBenchmarkSmokeCases, $ as buildIndustryRagBenchmarkSmokeCases, a0 as buildKnowledgeBenchmarkScenarios, a1 as buildRetrievalBenchmarkCasesFromQrels, a4 as createInMemoryBenchmarkAdapter, a5 as createMemoryAdapterBenchmarkResponder, a6 as createNoopMemoryBenchmarkAdapter, a7 as isKnowledgeMemoryBenchmarkCase, a8 as knowledgeBenchmarkJudge, a9 as parseKnowledgeBenchmarkJsonl, aa as parseKnowledgeBenchmarkQrels, ab as renderKnowledgeBenchmarkReportMarkdown, ac as respondToIndustryMemoryBenchmarkSmokeCase, ad as respondToIndustryRagBenchmarkSmokeCase, ai as runKnowledgeBenchmarkSuite, aj as runMemoryAdapterBenchmark, al as scoreKnowledgeBenchmarkArtifact, am as scoreMemoryBenchmarkArtifact, ao as summarizeKnowledgeBenchmarkCampaign } from '../index-BHQk7jOT.js';
1
+ import { b as AgentMemoryAdapter, C as KnowledgeBenchmarkSpec, H as KnowledgeMemoryBenchmarkTaskKind, o as KnowledgeAnswerBenchmarkTaskKind, G as KnowledgeMemoryBenchmarkCase, q as KnowledgeBenchmarkCase, p as KnowledgeBenchmarkArtifact, ad as RunMemoryAdapterBenchmarkOptions, ae as RunMemoryAdapterBenchmarkResult, x as KnowledgeBenchmarkScenario, v as KnowledgeBenchmarkReport, B as BuildRetrievalBenchmarkCasesFromQrelsOptions, L as KnowledgeRetrievalBenchmarkCase, M as KnowledgeRetrievalBenchmarkQrel, t as KnowledgeBenchmarkEvaluation, D as KnowledgeBenchmarkSplit, ab as RunKnowledgeBenchmarkSuiteOptions, ac as RunKnowledgeBenchmarkSuiteResult } from '../types-ZzY_x0r7.js';
2
+ export { K as KnowledgeAnswerBenchmarkCase, r as KnowledgeBenchmarkCaseBase, s as KnowledgeBenchmarkDistribution, u as KnowledgeBenchmarkFamily, w as KnowledgeBenchmarkResponder, y as KnowledgeBenchmarkSliceSummary, z as KnowledgeBenchmarkSource, E as KnowledgeBenchmarkTaskKind, F as KnowledgeClaimMatcher, I as KnowledgeMemoryEvent, J as KnowledgeMemoryFactMatcher, N as KnowledgeRetrievalBenchmarkQuery, O as MemoryAdapterBenchmarkCandidate, P as MemoryAdapterBenchmarkRankingRow } from '../types-ZzY_x0r7.js';
3
+ import { CampaignResult, JudgeConfig } from '@tangle-network/agent-eval/campaign';
4
4
  import '../types-6x0OpfW6.js';
5
- import '@tangle-network/agent-eval/rl';
5
+
6
+ declare function createNoopMemoryBenchmarkAdapter(id?: string): AgentMemoryAdapter;
7
+ declare function createInMemoryBenchmarkAdapter(options?: {
8
+ id?: string;
9
+ }): AgentMemoryAdapter;
10
+
11
+ declare const INDUSTRY_RAG_BENCHMARKS: readonly (KnowledgeBenchmarkSpec & {
12
+ taskKind: 'retrieval' | KnowledgeAnswerBenchmarkTaskKind;
13
+ })[];
14
+ declare const INDUSTRY_MEMORY_BENCHMARKS: readonly (KnowledgeBenchmarkSpec & {
15
+ taskKind: KnowledgeMemoryBenchmarkTaskKind;
16
+ })[];
17
+ declare function buildIndustryRagBenchmarkSmokeCases(specs?: readonly (KnowledgeBenchmarkSpec & {
18
+ taskKind: 'retrieval' | KnowledgeAnswerBenchmarkTaskKind;
19
+ })[]): KnowledgeBenchmarkCase[];
20
+ declare function respondToIndustryRagBenchmarkSmokeCase(input: {
21
+ case: KnowledgeBenchmarkCase;
22
+ }): KnowledgeBenchmarkArtifact;
23
+ declare function buildIndustryMemoryBenchmarkSmokeCases(specs?: readonly (KnowledgeBenchmarkSpec & {
24
+ taskKind: KnowledgeMemoryBenchmarkTaskKind;
25
+ })[]): KnowledgeMemoryBenchmarkCase[];
26
+ declare function respondToIndustryMemoryBenchmarkSmokeCase(input: {
27
+ case: KnowledgeMemoryBenchmarkCase;
28
+ }): KnowledgeBenchmarkArtifact;
29
+ declare function buildFirstPartyMemoryLifecycleBenchmarkCases(): KnowledgeMemoryBenchmarkCase[];
30
+
31
+ declare function runMemoryAdapterBenchmark(options: RunMemoryAdapterBenchmarkOptions): Promise<RunMemoryAdapterBenchmarkResult>;
32
+
33
+ declare function summarizeKnowledgeBenchmarkCampaign<TArtifact>(input: {
34
+ scenarios: readonly KnowledgeBenchmarkScenario[];
35
+ campaign: CampaignResult<TArtifact, KnowledgeBenchmarkScenario>;
36
+ }): KnowledgeBenchmarkReport;
37
+
38
+ declare function parseKnowledgeBenchmarkJsonl<T = unknown>(text: string): T[];
39
+ declare function parseKnowledgeBenchmarkQrels(text: string): KnowledgeRetrievalBenchmarkQrel[];
40
+ declare function buildRetrievalBenchmarkCasesFromQrels(options: BuildRetrievalBenchmarkCasesFromQrelsOptions): KnowledgeRetrievalBenchmarkCase[];
41
+
42
+ declare function scoreKnowledgeBenchmarkArtifact<TArtifact>(testCase: KnowledgeBenchmarkCase, artifact: TArtifact): KnowledgeBenchmarkEvaluation;
43
+ declare function scoreMemoryBenchmarkArtifact<TArtifact>(testCase: KnowledgeMemoryBenchmarkCase, artifact: TArtifact): KnowledgeBenchmarkEvaluation;
44
+
45
+ declare function runKnowledgeBenchmarkSuite<TArtifact = KnowledgeBenchmarkArtifact>(options: RunKnowledgeBenchmarkSuiteOptions<TArtifact>): Promise<RunKnowledgeBenchmarkSuiteResult<TArtifact>>;
46
+ declare function renderKnowledgeBenchmarkReportMarkdown(report: KnowledgeBenchmarkReport): string;
47
+ declare function buildKnowledgeBenchmarkScenarios(cases: readonly KnowledgeBenchmarkCase[], splits?: readonly KnowledgeBenchmarkSplit[]): KnowledgeBenchmarkScenario[];
48
+ declare function knowledgeBenchmarkJudge<TArtifact = KnowledgeBenchmarkArtifact>(): JudgeConfig<TArtifact, KnowledgeBenchmarkScenario>;
49
+
50
+ declare function isKnowledgeMemoryBenchmarkCase(testCase: KnowledgeBenchmarkCase): testCase is KnowledgeMemoryBenchmarkCase;
51
+
52
+ export { BuildRetrievalBenchmarkCasesFromQrelsOptions, INDUSTRY_MEMORY_BENCHMARKS, INDUSTRY_RAG_BENCHMARKS, KnowledgeAnswerBenchmarkTaskKind, KnowledgeBenchmarkArtifact, KnowledgeBenchmarkCase, KnowledgeBenchmarkEvaluation, KnowledgeBenchmarkReport, KnowledgeBenchmarkScenario, KnowledgeBenchmarkSpec, KnowledgeBenchmarkSplit, KnowledgeMemoryBenchmarkCase, KnowledgeMemoryBenchmarkTaskKind, KnowledgeRetrievalBenchmarkCase, KnowledgeRetrievalBenchmarkQrel, RunKnowledgeBenchmarkSuiteOptions, RunKnowledgeBenchmarkSuiteResult, RunMemoryAdapterBenchmarkOptions, RunMemoryAdapterBenchmarkResult, buildFirstPartyMemoryLifecycleBenchmarkCases, buildIndustryMemoryBenchmarkSmokeCases, buildIndustryRagBenchmarkSmokeCases, buildKnowledgeBenchmarkScenarios, buildRetrievalBenchmarkCasesFromQrels, createInMemoryBenchmarkAdapter, createNoopMemoryBenchmarkAdapter, isKnowledgeMemoryBenchmarkCase, knowledgeBenchmarkJudge, parseKnowledgeBenchmarkJsonl, parseKnowledgeBenchmarkQrels, renderKnowledgeBenchmarkReportMarkdown, respondToIndustryMemoryBenchmarkSmokeCase, respondToIndustryRagBenchmarkSmokeCase, runKnowledgeBenchmarkSuite, runMemoryAdapterBenchmark, scoreKnowledgeBenchmarkArtifact, scoreMemoryBenchmarkArtifact, summarizeKnowledgeBenchmarkCampaign };
@@ -7,7 +7,6 @@ import {
7
7
  buildKnowledgeBenchmarkScenarios,
8
8
  buildRetrievalBenchmarkCasesFromQrels,
9
9
  createInMemoryBenchmarkAdapter,
10
- createMemoryAdapterBenchmarkResponder,
11
10
  createNoopMemoryBenchmarkAdapter,
12
11
  isKnowledgeMemoryBenchmarkCase,
13
12
  knowledgeBenchmarkJudge,
@@ -21,9 +20,8 @@ import {
21
20
  scoreKnowledgeBenchmarkArtifact,
22
21
  scoreMemoryBenchmarkArtifact,
23
22
  summarizeKnowledgeBenchmarkCampaign
24
- } from "../chunk-RIHIYCX2.js";
23
+ } from "../chunk-BBCIB4UL.js";
25
24
  import "../chunk-DQ3PDMDP.js";
26
- import "../chunk-XVU5FFQA.js";
27
25
  import "../chunk-YMKHCTS2.js";
28
26
  export {
29
27
  INDUSTRY_MEMORY_BENCHMARKS,
@@ -34,7 +32,6 @@ export {
34
32
  buildKnowledgeBenchmarkScenarios,
35
33
  buildRetrievalBenchmarkCasesFromQrels,
36
34
  createInMemoryBenchmarkAdapter,
37
- createMemoryAdapterBenchmarkResponder,
38
35
  createNoopMemoryBenchmarkAdapter,
39
36
  isKnowledgeMemoryBenchmarkCase,
40
37
  knowledgeBenchmarkJudge,