enigma-memory 0.1.2 → 0.1.3
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/docs/benchmark-reproducibility.md +113 -0
- package/docs/developer-ecosystem.md +5 -3
- package/docs/memory-benchmarks.md +33 -2
- package/docs/sdk-api.md +1 -1
- package/examples/ci/github-actions.yml +29 -1
- package/package.json +2 -1
- package/packages/mcp-server/src/index.js +1 -1
- package/scripts/build-installer-assets.mjs +1 -1
- package/scripts/run-memory-benchmarks.mjs +314 -2
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Benchmark reproducibility
|
|
2
|
+
|
|
3
|
+
This guide explains how to reproduce the current local Enigma memory benchmark, save the public-safe JSON report, cite the external benchmark standards it is modeled after, and understand what is still required before publishing live third-party comparisons.
|
|
4
|
+
|
|
5
|
+
## What is reproducible today
|
|
6
|
+
|
|
7
|
+
The current package is `enigma-memory@0.1.3`. The local benchmark is available through the package script and the script file it wraps:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
cd enigma
|
|
11
|
+
npm run benchmark:memory-suite
|
|
12
|
+
npm run benchmark:memory-suite -- --out benchmark-report.json
|
|
13
|
+
node scripts/run-memory-benchmarks.mjs --out benchmark-report.json
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The `--out` form writes the report to the requested path and prints only a small status object. Without `--out`, the command writes the full JSON report to stdout.
|
|
17
|
+
|
|
18
|
+
The report schema is `enigma.memory_benchmark_suite.v1`. It is designed to be public-safe: it contains aggregate metrics, commitments, citations, cross-provider profile labels, and claim boundaries. It does not include raw fixture memory, private question text, private answer text, provider transcripts, credentials, account ids, or local absolute paths.
|
|
19
|
+
|
|
20
|
+
## Reproduce and save JSON
|
|
21
|
+
|
|
22
|
+
1. Use a clean checkout containing `enigma-memory@0.1.3`.
|
|
23
|
+
2. From a repository root that contains `enigma/package.json`, enter the package directory:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
cd enigma
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
If your checkout already has `package.json` for `enigma-memory` at the current directory, skip this `cd`.
|
|
30
|
+
|
|
31
|
+
3. Install the package dependencies with the reviewed package command:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
npm install
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
4. Run the benchmark and save the public-safe JSON report:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
npm run benchmark:memory-suite -- --out benchmark-report.json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
5. Preserve the JSON file with the command, package version, operating system/runtime, and review context that produced it.
|
|
44
|
+
6. When sharing the result publicly, share the generated JSON report only after confirming it still has `public_safe: true` and `schema: "enigma.memory_benchmark_suite.v1"`.
|
|
45
|
+
|
|
46
|
+
The local fixture measures Enigma-controlled operations only: vault remember/update, vault export/import, passport context-pack retrieval, optimizer token estimates and duplicate removal, bundle/context-pack verification, abstention behavior, exact-answer recall over the deterministic fixture, and p50/p95 operation latency from `performance.now`.
|
|
47
|
+
|
|
48
|
+
## Local baseline rows in the report
|
|
49
|
+
|
|
50
|
+
The report now includes `metrics.local_baseline_comparisons`, which compares deterministic local baselines over the same private fixture questions. These rows are local package evidence only: they do not call hosted providers, use provider APIs, or support invoice savings, ROI, compliance, model-forgetting, or benchmark-leadership claims.
|
|
51
|
+
|
|
52
|
+
| Row | Local boundary |
|
|
53
|
+
| --- | --- |
|
|
54
|
+
| `full_context` | Supplies every active fixture memory without optimization or deduplication. |
|
|
55
|
+
| `recency_last_n` | Supplies the three most recently updated active fixture memories. |
|
|
56
|
+
| `keyword_filter` | Supplies active fixture memories whose content or tags match deterministic query terms. |
|
|
57
|
+
| `enigma_context_pack` | Uses the Enigma passport context-pack compiler and optimizer boundary. |
|
|
58
|
+
|
|
59
|
+
The report also includes `public_claims_allowed`; keep public copy within those local-fixture boundaries unless separate reviewed external evidence exists.
|
|
60
|
+
|
|
61
|
+
## How to cite external benchmark standards
|
|
62
|
+
|
|
63
|
+
Use these standards as citations and task-category references, not as claimed Enigma results unless the exact external benchmark has been run and reviewed:
|
|
64
|
+
|
|
65
|
+
- LoCoMo: https://snap-research.github.io/locomo/ — cite for long-term conversational-memory QA, event summarization, and multimodal generation over long conversations.
|
|
66
|
+
- LongMemEval: https://arxiv.org/abs/2410.10813 — cite for information extraction, multi-session reasoning, temporal reasoning, knowledge updates, and abstention.
|
|
67
|
+
|
|
68
|
+
The current local report mirrors some task categories from those benchmarks, but it does not download LoCoMo or LongMemEval data, run their official evaluation pipelines, or claim leaderboard-equivalent results.
|
|
69
|
+
|
|
70
|
+
## Why live third-party comparisons are not claimed yet
|
|
71
|
+
|
|
72
|
+
The current benchmark does not call external provider APIs, external SDKs, hosted memory services, ChatGPT native memory, Claude memory tooling, or third-party agent loops. Cross-provider rows in the report are profile labels that reuse the same Enigma context-pack boundary; they do not call or compare live provider models and are not live provider rankings.
|
|
73
|
+
|
|
74
|
+
Real comparisons require fixed adapters, fixed datasets, fixed agent/tool loops, explicit provider terms review, and reviewed handling of secrets and raw benchmark data. Memory quality can change with the surrounding agent framework and tool loop, so a fair comparison must document more than the memory store.
|
|
75
|
+
|
|
76
|
+
The current report must not be used as evidence of provider-side deletion, model forgetting, compliance certification, token ROI, provider invoice savings, benchmark leadership, hosted-cloud readiness, or “best in world” superiority.
|
|
77
|
+
|
|
78
|
+
## External comparison requirements
|
|
79
|
+
|
|
80
|
+
Use placeholder environment names only. Do not commit real tokens, API keys, account ids, provider transcripts, raw benchmark conversations, or private memory.
|
|
81
|
+
|
|
82
|
+
The report field `external_competitor_adapters` is a requirements matrix, not a score table. External rows are expected to remain requirements-only until credentials, runtimes, and datasets are supplied and reviewed: `can_run_in_this_harness: false`, `scores_included: false`, and no recall, abstention, token, latency, or ranking scores.
|
|
83
|
+
|
|
84
|
+
| Target | Runtime or SDK needed | Placeholder secrets and local inputs | Dataset requirement | Adapter boundary before results can be claimed |
|
|
85
|
+
| --- | --- | --- | --- | --- |
|
|
86
|
+
| Letta | Letta SDK/runtime; documented SDK packages include `@letta-ai/letta-client` and `letta-client`; API-key-backed service access may be required. | `LETTA_API_KEY`, `LETTA_BASE_URL`, `LETTA_PROJECT_ID`, `BENCHMARK_DATASET_PATH` | Local reviewed LoCoMo/LongMemEval split or another reviewed local dataset file with license, version, split, and checksum metadata. | Build a Letta adapter that fixes the agent loop, memory write/read policy, model settings, and scoring path. Results may describe that configured Letta run only, not generic provider deletion or model forgetting. |
|
|
87
|
+
| LangGraph memory | LangGraph runtime with short-term checkpointer memory and long-term namespaced store. | `LANGGRAPH_CHECKPOINTER_URI`, `LANGGRAPH_STORE_URI`, `BENCHMARK_DATASET_PATH` | Same local dataset file and split used for Enigma and every competitor. | Fix graph topology, checkpoint scope, namespace policy, retrieval policy, model/tool loop, and scorer. Do not attribute graph/tool behavior solely to the memory store. |
|
|
88
|
+
| Zep | Zep service/runtime positioned around temporal Context Graph and Context Lake retrieval. | `ZEP_API_KEY`, `ZEP_PROJECT_ID`, `ZEP_BASE_URL`, `BENCHMARK_DATASET_PATH` | Same local dataset file and split; include source checksum and whether any provider-side graph state is reused or reset. | Build a Zep adapter that records ingest, session, retrieval, reset, and scoring policy. Zep’s sub-200ms retrieval positioning is a vendor/source fact, not an Enigma-measured claim until measured in the same harness. |
|
|
89
|
+
| Mem0 | Mem0 platform or open-source stack; positioned as a universal self-improving memory layer. | `MEM0_API_KEY`, `MEM0_BASE_URL`, `MEM0_PROJECT_ID`, `BENCHMARK_DATASET_PATH` | Same local dataset file and split; record Mem0 deployment flavor/version. | Build a Mem0 adapter with fixed extraction, update, retrieval, reset, and scorer behavior. Self-improving or platform behavior must be bounded to the configured run. |
|
|
90
|
+
| OpenAI native ChatGPT memory | ChatGPT consumer-app/native memory environment. It is not directly available through a public API in this harness. | No usable harness secret; `OPENAI_API_KEY` alone is not sufficient to exercise ChatGPT native memory. | No fair automated dataset run until an approved interface can load/reset/query native memory reproducibly. | Do not claim live native ChatGPT memory comparison from this repository. A future adapter would need an approved public interface, reproducible memory reset/load semantics, and provider-policy review. |
|
|
91
|
+
| Claude memory tool | Client-side/provider-specific memory tool environment. | `CLAUDE_MEMORY_TOOL_CONFIG`, `ANTHROPIC_API_KEY`, `BENCHMARK_DATASET_PATH` | Same local dataset file and split, plus reviewed tool-state reset/export rules. | Build an adapter around the exact client/tool environment, not generic Claude model behavior. Results can only cover that configured memory-tool setup. |
|
|
92
|
+
|
|
93
|
+
## Source references for adapter planning
|
|
94
|
+
|
|
95
|
+
- Letta MemGPT concepts: https://docs.letta.com/concepts/memgpt/
|
|
96
|
+
- Zep documentation: https://help.getzep.com/
|
|
97
|
+
- Mem0 documentation: https://docs.mem0.ai/
|
|
98
|
+
- LangGraph memory documentation: https://docs.langchain.com/oss/python/langgraph/memory
|
|
99
|
+
- OpenAI ChatGPT memory FAQ: https://help.openai.com/en/articles/8590148-memory-faq
|
|
100
|
+
- Claude memory tool support article: https://support.anthropic.com/en/articles/11145838-using-claude-memory
|
|
101
|
+
|
|
102
|
+
## Minimum evidence for a future live comparison
|
|
103
|
+
|
|
104
|
+
Before publishing external comparison language, capture all of the following in the benchmark report or an adjacent reviewed evidence file:
|
|
105
|
+
|
|
106
|
+
1. Package version, benchmark schema, command, timestamp, OS/runtime, and adapter version.
|
|
107
|
+
2. Dataset name, source URL, license review status, local file checksum, split, and record count.
|
|
108
|
+
3. Secret names used as placeholders, with confirmation that no secret values are printed or persisted.
|
|
109
|
+
4. Adapter configuration: SDK/runtime version, model where applicable, memory write/read policy, reset policy, context limits, retry policy, and scoring code.
|
|
110
|
+
5. Per-target raw scoring inputs retained privately when license permits, with public reports limited to safe aggregates.
|
|
111
|
+
6. Explicit boundaries separating memory-store behavior, agent-loop behavior, model behavior, provider-hosted state, and Enigma receipt verification.
|
|
112
|
+
|
|
113
|
+
Until that evidence exists, use only the local benchmark claim: Enigma can reproduce deterministic local memory-fixture operations and emit a public-safe `enigma.memory_benchmark_suite.v1` JSON report.
|
|
@@ -7,6 +7,7 @@ Enigma Memory is a local-first SDK, CLI, MCP server, and service-contract packag
|
|
|
7
7
|
- SDK/API guide: [`docs/sdk-api.md`](./sdk-api.md)
|
|
8
8
|
- Node example app: [`examples/node-basic-memory.mjs`](../examples/node-basic-memory.mjs)
|
|
9
9
|
- GitHub Actions example: [`examples/ci/github-actions.yml`](../examples/ci/github-actions.yml)
|
|
10
|
+
- Benchmark reproducibility guide: [`docs/benchmark-reproducibility.md`](./benchmark-reproducibility.md)
|
|
10
11
|
- Generic MCP client template: [`templates/mcp-client-config.json`](../templates/mcp-client-config.json)
|
|
11
12
|
|
|
12
13
|
## Local SDK loop
|
|
@@ -24,16 +25,17 @@ The example app prints ids, counts, roots, and verification status only. It does
|
|
|
24
25
|
|
|
25
26
|
## CLI and CI loop
|
|
26
27
|
|
|
27
|
-
The CI example installs Node 24, installs the published `enigma-memory` package, runs:
|
|
28
|
+
The CI example installs Node 24, installs the published `enigma-memory@0.1.3` package, runs:
|
|
28
29
|
|
|
29
30
|
```sh
|
|
30
31
|
npx enigma quickstart --overwrite
|
|
31
32
|
npx enigma doctor
|
|
33
|
+
npm run benchmark:memory-suite -- --out benchmark-report.json
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
and then runs a small ESM import smoke. It does not require GitHub secrets, cloud provider credentials, npm tokens, private bundles, or local path assumptions.
|
|
36
|
+
and then runs a small ESM import smoke. It does not require GitHub secrets, cloud provider credentials, npm tokens, private bundles, or local path assumptions. The benchmark step writes a public-safe local JSON report using schema `enigma.memory_benchmark_suite.v1`; see the benchmark reproducibility guide for claim boundaries and the requirements for any future live third-party comparison.
|
|
35
37
|
|
|
36
|
-
Use the workflow as a template in a consumer repository. It is intentionally limited to install/import/doctor smoke coverage and local
|
|
38
|
+
Use the workflow as a template in a consumer repository. It is intentionally limited to install/import/doctor smoke coverage, local proof generation, and deterministic local benchmark evidence; it does not publish packages, deploy infrastructure, contact hosted Enigma cloud, or call external memory providers.
|
|
37
39
|
|
|
38
40
|
## MCP client loop
|
|
39
41
|
|
|
@@ -29,15 +29,46 @@ The harness measures local Enigma operations only:
|
|
|
29
29
|
- context-pack retrieval through the passport package;
|
|
30
30
|
- optimizer plan token estimates and duplicate removal;
|
|
31
31
|
- bundle and context-pack verification;
|
|
32
|
+
- local baseline comparisons over the same deterministic fixture questions;
|
|
32
33
|
- p50/p95 latency with `performance.now`.
|
|
33
34
|
|
|
34
|
-
Reported metrics include exact-answer recall, abstention correctness,
|
|
35
|
+
Reported metrics include exact-answer recall, abstention correctness, estimated prompt tokens, duplicate candidates removed where applicable, operation latency summaries, verification status, and same-boundary cross-provider profile rows.
|
|
36
|
+
|
|
37
|
+
## Local baseline comparison
|
|
38
|
+
|
|
39
|
+
`metrics.local_baseline_comparisons` compares Enigma against deterministic local baselines only. Every row scores the same private fixture questions and keeps raw memory, question text, and answer text out of the report.
|
|
40
|
+
|
|
41
|
+
| Row | Boundary | Reported fields |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| `full_context` | Supplies every active fixture memory without optimization or deduplication. | Recall, abstention correctness, estimated prompt tokens, selected memory count, p50/p95 local latency. |
|
|
44
|
+
| `recency_last_n` | Supplies the three most recently updated active fixture memories. | Same fields; duplicate removal is marked not applicable. |
|
|
45
|
+
| `keyword_filter` | Supplies active fixture memories whose content or tags match deterministic query terms. | Same fields; duplicate removal is marked not applicable. |
|
|
46
|
+
| `enigma_context_pack` | Uses the Enigma passport context-pack compiler and optimizer boundary. | Same fields plus duplicate-removal counts from the Enigma optimizer plan. |
|
|
47
|
+
|
|
48
|
+
These rows are local package evidence only. They do not compare hosted providers, do not use provider APIs, and do not support invoice savings, ROI, compliance, model-forgetting, or benchmark-leadership claims.
|
|
49
|
+
|
|
50
|
+
## External competitor adapter requirements
|
|
51
|
+
|
|
52
|
+
`external_competitor_adapters` is a requirements matrix, not a score table. Each row has `status: "not_run_requires_credentials_or_runtime"`, `can_run_in_this_harness: false`, `required_artifacts`, `official_doc`, an exact `boundary_reason`, and `scores_included: false`.
|
|
53
|
+
|
|
54
|
+
| Adapter | Official source | Required artifacts before scoring | Boundary reason |
|
|
55
|
+
| --- | --- | --- | --- |
|
|
56
|
+
| Letta / MemGPT | https://docs.letta.com/concepts/memgpt/ | Letta API key or self-hosted runtime; pinned SDK such as `@letta-ai/letta-client` or `letta-client`; fixed agent/tools/model/memory config; operator-supplied dataset mapping. | This harness has no Letta credentials, SDK installation, runtime, fixed agent loop, or approved external dataset. |
|
|
57
|
+
| LangGraph memory | https://docs.langchain.com/oss/python/langgraph/memory | Pinned LangGraph runtime; short-term checkpointer config; namespaced long-term store config; fixed graph/model/tools/dataset mapping. | This Node local package harness does not execute a LangGraph runtime, checkpointer, store, graph, model, or adapter. |
|
|
58
|
+
| Zep | https://help.getzep.com/ | Zep credentials or endpoint; pinned client; temporal Context Graph or Context Lake config; ingestion and retrieval mapping. | This harness has no Zep credentials, client package, Context Graph/Context Lake runtime, ingestion job, or retrieval dataset. |
|
|
59
|
+
| Mem0 | https://docs.mem0.ai/ | Mem0 platform credentials or open-source runtime; pinned SDK/package versions; extraction/update/retrieval/model/tool config; dataset mapping. | This harness has no Mem0 credentials, runtime, configured memory loop, model/tool environment, or external dataset adapter. |
|
|
60
|
+
| OpenAI ChatGPT native memory | https://help.openai.com/en/articles/8590148-memory-faq | ChatGPT account/runtime with native memory enabled; account-safe evaluation protocol; dataset prompts; evidence capture that excludes personal data and credentials. | ChatGPT native memory is a consumer-app feature rather than a public API surface available to this local package harness. |
|
|
61
|
+
| Claude memory tool | https://support.anthropic.com/en/articles/11145838-using-claude-memory | Claude/provider runtime with the memory tool available; client-side tool configuration; fixed model/tool-use policy/prompts/dataset mapping; safe evidence capture. | The memory tool is provider/client-side and requires a Claude runtime plus tool environment that this benchmark does not control. |
|
|
62
|
+
|
|
63
|
+
No external adapter row contains recall, abstention, token, latency, or ranking scores. Third-party claims stay blocked until the required credentials, runtimes, and datasets are supplied and reviewed.
|
|
35
64
|
|
|
36
65
|
## Claim limits
|
|
37
66
|
|
|
38
67
|
The benchmark report is evidence for this local deterministic fixture only. It is not provider deletion proof, model forgetting proof, compliance certification, ROI evidence, provider invoice savings evidence, benchmark leadership proof, hosted cloud readiness, or a substitute for external LoCoMo/LongMemEval evaluation.
|
|
39
68
|
|
|
40
|
-
Cross-provider rows are profile labels using the same Enigma context-pack boundary.
|
|
69
|
+
Cross-provider rows are profile labels using the same Enigma context-pack boundary. External competitor rows are adapter requirements only; they do not call, score, or rank live provider models.
|
|
70
|
+
|
|
71
|
+
`public_claims_allowed` is intentionally narrow: deterministic local fixture execution, local recall/abstention metrics, local baseline comparison, local token estimates, duplicate removal where applicable, p50/p95 local latency, Enigma bundle/context-pack verification, and explicit withholding of third-party scores until the required external artifacts exist.
|
|
41
72
|
|
|
42
73
|
## Extending with external datasets later
|
|
43
74
|
|
package/docs/sdk-api.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# SDK and API guide
|
|
2
2
|
|
|
3
|
-
This guide covers the public package imports for `enigma-memory@0.1.
|
|
3
|
+
This guide covers the public package imports for `enigma-memory@0.1.3`. The SDK runs locally by default: vaults, passports, context packs, receipts, relay/gateway demo state, storage contracts, metering artifacts, and settlement artifacts are package-level developer surfaces. They are not evidence of hosted Enigma cloud, provider-side deletion, provider model forgetting, token ROI, invoice savings, compliance certification, or benchmark leadership.
|
|
4
4
|
|
|
5
5
|
## Install and import style
|
|
6
6
|
|
|
@@ -22,7 +22,18 @@ jobs:
|
|
|
22
22
|
run: npm init -y
|
|
23
23
|
|
|
24
24
|
- name: Install Enigma Memory
|
|
25
|
-
run: npm install enigma-memory@0.1.
|
|
25
|
+
run: npm install enigma-memory@0.1.3
|
|
26
|
+
|
|
27
|
+
- name: Expose local benchmark script
|
|
28
|
+
run: |
|
|
29
|
+
node --input-type=module <<'JS'
|
|
30
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
31
|
+
|
|
32
|
+
const pkg = JSON.parse(await readFile('package.json', 'utf8'));
|
|
33
|
+
pkg.scripts ??= {};
|
|
34
|
+
pkg.scripts['benchmark:memory-suite'] = 'node ./node_modules/enigma-memory/scripts/run-memory-benchmarks.mjs';
|
|
35
|
+
await writeFile('package.json', `${JSON.stringify(pkg, null, 2)}\n`, 'utf8');
|
|
36
|
+
JS
|
|
26
37
|
|
|
27
38
|
- name: Run Enigma quickstart
|
|
28
39
|
run: npx enigma quickstart --overwrite
|
|
@@ -30,6 +41,23 @@ jobs:
|
|
|
30
41
|
- name: Run Enigma doctor
|
|
31
42
|
run: npx enigma doctor
|
|
32
43
|
|
|
44
|
+
- name: Run local memory benchmark
|
|
45
|
+
run: |
|
|
46
|
+
npm run benchmark:memory-suite -- --out benchmark-report.json
|
|
47
|
+
mkdir -p artifacts
|
|
48
|
+
cp benchmark-report.json artifacts/benchmark-report.json
|
|
49
|
+
echo "Saved public-safe benchmark report placeholder at artifacts/benchmark-report.json"
|
|
50
|
+
|
|
51
|
+
# Optional artifact upload placeholder:
|
|
52
|
+
# If your repository already permits actions/upload-artifact, uncomment a
|
|
53
|
+
# reviewed upload step like this. The example keeps the report saved in the
|
|
54
|
+
# workspace without requiring that action.
|
|
55
|
+
# - name: Upload benchmark report
|
|
56
|
+
# uses: actions/upload-artifact@v4
|
|
57
|
+
# with:
|
|
58
|
+
# name: enigma-memory-benchmark-report
|
|
59
|
+
# path: artifacts/benchmark-report.json
|
|
60
|
+
|
|
33
61
|
- name: Smoke test package imports
|
|
34
62
|
run: |
|
|
35
63
|
node --input-type=module <<'JS'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "enigma-memory",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Provider-agnostic AI memory passport and offline-verifiable proof layer.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -112,6 +112,7 @@
|
|
|
112
112
|
"docs/sdk-api.md",
|
|
113
113
|
"docs/developer-ecosystem.md",
|
|
114
114
|
"docs/memory-benchmarks.md",
|
|
115
|
+
"docs/benchmark-reproducibility.md",
|
|
115
116
|
"docs/installers-and-desktop.md",
|
|
116
117
|
"docs/browser-extension-install.md",
|
|
117
118
|
"docs/hosted-cloud-product.md",
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
const DEFAULT_BUNDLE = '.enigma/bundle.json';
|
|
18
18
|
const JSONRPC_VERSION = '2.0';
|
|
19
19
|
const MCP_PROTOCOL_VERSION = '2024-11-05';
|
|
20
|
-
const SERVER_INFO = Object.freeze({ name: 'enigma-mcp-server', version: '0.1.
|
|
20
|
+
const SERVER_INFO = Object.freeze({ name: 'enigma-mcp-server', version: '0.1.3' });
|
|
21
21
|
const JSON_RPC_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
22
22
|
const JSON_RPC_ERROR = Object.freeze({
|
|
23
23
|
INVALID_REQUEST: -32600,
|
|
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
6
6
|
|
|
7
7
|
export const INSTALLER_ASSET_SCHEMA = 'enigma.installer_assets.v1';
|
|
8
8
|
export const INSTALLER_ASSET_PACKAGE = 'enigma-memory';
|
|
9
|
-
export const INSTALLER_ASSET_VERSION = '0.1.
|
|
9
|
+
export const INSTALLER_ASSET_VERSION = '0.1.3';
|
|
10
10
|
export const INSTALLER_ASSET_GENERATED_AT = '1970-01-01T00:00:00.000Z';
|
|
11
11
|
|
|
12
12
|
const SCRIPT_PATH = fileURLToPath(import.meta.url);
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
compileContextPack,
|
|
17
17
|
verifyContextPack,
|
|
18
18
|
} from '../packages/passport/src/index.js';
|
|
19
|
-
import { createMemoryOptimizationPlan } from '../packages/optimizer/src/index.js';
|
|
19
|
+
import { createMemoryOptimizationPlan, estimateTextTokens } from '../packages/optimizer/src/index.js';
|
|
20
20
|
import { verifyBundle } from '../apps/verifier/bin/enigma-verify.mjs';
|
|
21
21
|
|
|
22
22
|
export const MEMORY_BENCHMARK_SUITE_SCHEMA = 'enigma.memory_benchmark_suite.v1';
|
|
@@ -34,6 +34,131 @@ const CONTEXT_BOUNDARY = Object.freeze({
|
|
|
34
34
|
|
|
35
35
|
const PROVIDER_PROFILES = Object.freeze(['chatgpt', 'claude', 'kimi', 'cursor', 'local-llm']);
|
|
36
36
|
|
|
37
|
+
const LOCAL_BASELINES = Object.freeze([
|
|
38
|
+
{
|
|
39
|
+
id: 'full_context',
|
|
40
|
+
label: 'Full active context',
|
|
41
|
+
boundary: 'All active fixture memories are supplied without optimization or deduplication.',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: 'recency_last_n',
|
|
45
|
+
label: 'Recency last N',
|
|
46
|
+
boundary: 'The three most recently updated active fixture memories are supplied.',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'keyword_filter',
|
|
50
|
+
label: 'Keyword filter',
|
|
51
|
+
boundary: 'Active fixture memories are supplied when deterministic query terms match content or tags.',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'enigma_context_pack',
|
|
55
|
+
label: 'Enigma context pack',
|
|
56
|
+
boundary: 'The Enigma passport context-pack compiler and optimizer boundary are used locally.',
|
|
57
|
+
},
|
|
58
|
+
]);
|
|
59
|
+
|
|
60
|
+
const EXTERNAL_COMPETITOR_ADAPTERS = Object.freeze([
|
|
61
|
+
{
|
|
62
|
+
id: 'letta_memgpt',
|
|
63
|
+
name: 'Letta / MemGPT',
|
|
64
|
+
status: 'not_run_requires_credentials_or_runtime',
|
|
65
|
+
required_artifacts: [
|
|
66
|
+
'Letta API key or self-hosted Letta runtime',
|
|
67
|
+
'Pinned Letta SDK package and version such as @letta-ai/letta-client or letta-client',
|
|
68
|
+
'Agent, tools, model, and memory configuration',
|
|
69
|
+
'Operator-supplied benchmark dataset or fixture mapping',
|
|
70
|
+
],
|
|
71
|
+
official_doc: 'https://docs.letta.com/concepts/memgpt/',
|
|
72
|
+
can_run_in_this_harness: false,
|
|
73
|
+
boundary_reason: 'This local harness has no Letta credentials, SDK installation, hosted/self-hosted Letta runtime, fixed agent loop, or approved external dataset, so no Letta score is produced.',
|
|
74
|
+
scores_included: false,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
id: 'langgraph_memory',
|
|
78
|
+
name: 'LangGraph memory',
|
|
79
|
+
status: 'not_run_requires_credentials_or_runtime',
|
|
80
|
+
required_artifacts: [
|
|
81
|
+
'Pinned LangGraph runtime and package versions',
|
|
82
|
+
'Checkpointer configuration for short-term memory',
|
|
83
|
+
'Namespaced long-term store configuration',
|
|
84
|
+
'Fixed graph, model, tools, and dataset mapping',
|
|
85
|
+
],
|
|
86
|
+
official_doc: 'https://docs.langchain.com/oss/python/langgraph/memory',
|
|
87
|
+
can_run_in_this_harness: false,
|
|
88
|
+
boundary_reason: 'This Node local package harness does not install or execute a LangGraph runtime, checkpointer, namespaced store, graph, model, or dataset adapter, so no LangGraph score is produced.',
|
|
89
|
+
scores_included: false,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: 'zep',
|
|
93
|
+
name: 'Zep',
|
|
94
|
+
status: 'not_run_requires_credentials_or_runtime',
|
|
95
|
+
required_artifacts: [
|
|
96
|
+
'Zep credentials or local/runtime endpoint',
|
|
97
|
+
'Pinned Zep client and version',
|
|
98
|
+
'Temporal Context Graph or Context Lake configuration',
|
|
99
|
+
'Dataset ingestion and retrieval mapping',
|
|
100
|
+
],
|
|
101
|
+
official_doc: 'https://help.getzep.com/',
|
|
102
|
+
can_run_in_this_harness: false,
|
|
103
|
+
boundary_reason: 'This local harness has no Zep credentials, client package, Context Graph or Context Lake runtime, ingestion job, or provider-approved retrieval dataset, so no Zep score or latency claim is produced.',
|
|
104
|
+
scores_included: false,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 'mem0',
|
|
108
|
+
name: 'Mem0',
|
|
109
|
+
status: 'not_run_requires_credentials_or_runtime',
|
|
110
|
+
required_artifacts: [
|
|
111
|
+
'Mem0 platform credentials or open-source stack runtime',
|
|
112
|
+
'Pinned Mem0 SDK/package versions',
|
|
113
|
+
'Memory extraction, update, retrieval, model, and tool configuration',
|
|
114
|
+
'Dataset ingestion and scoring mapping',
|
|
115
|
+
],
|
|
116
|
+
official_doc: 'https://docs.mem0.ai/',
|
|
117
|
+
can_run_in_this_harness: false,
|
|
118
|
+
boundary_reason: 'This local harness has no Mem0 credentials, SDK/runtime, configured extraction/retrieval loop, model/tool environment, or external dataset adapter, so no Mem0 score is produced.',
|
|
119
|
+
scores_included: false,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: 'openai_native_memory',
|
|
123
|
+
name: 'OpenAI ChatGPT native memory',
|
|
124
|
+
status: 'not_run_requires_credentials_or_runtime',
|
|
125
|
+
required_artifacts: [
|
|
126
|
+
'Consumer ChatGPT account/runtime with native memory enabled',
|
|
127
|
+
'Account-safe evaluation protocol and export/review process',
|
|
128
|
+
'Dataset prompts and operator approval for non-public app interaction',
|
|
129
|
+
'Evidence capture that excludes personal data and credentials',
|
|
130
|
+
],
|
|
131
|
+
official_doc: 'https://help.openai.com/en/articles/8590148-memory-faq',
|
|
132
|
+
can_run_in_this_harness: false,
|
|
133
|
+
boundary_reason: 'ChatGPT native memory is a consumer-app feature rather than a public API surface available to this local package harness, so no OpenAI native-memory score is produced.',
|
|
134
|
+
scores_included: false,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: 'claude_memory_tool',
|
|
138
|
+
name: 'Claude memory tool',
|
|
139
|
+
status: 'not_run_requires_credentials_or_runtime',
|
|
140
|
+
required_artifacts: [
|
|
141
|
+
'Claude/provider runtime with the memory tool available',
|
|
142
|
+
'Client-side tool configuration and storage boundary',
|
|
143
|
+
'Fixed model, tool-use policy, prompts, and dataset mapping',
|
|
144
|
+
'Evidence capture that excludes personal data and credentials',
|
|
145
|
+
],
|
|
146
|
+
official_doc: 'https://support.anthropic.com/en/articles/11145838-using-claude-memory',
|
|
147
|
+
can_run_in_this_harness: false,
|
|
148
|
+
boundary_reason: 'The Claude memory tool is provider/client-side and requires a Claude runtime plus tool environment that this local package benchmark does not control, so no Claude memory-tool score is produced.',
|
|
149
|
+
scores_included: false,
|
|
150
|
+
},
|
|
151
|
+
]);
|
|
152
|
+
|
|
153
|
+
const PUBLIC_CLAIMS_ALLOWED = Object.freeze([
|
|
154
|
+
'Runs a deterministic local Enigma memory fixture without external provider calls.',
|
|
155
|
+
'Reports local exact-answer recall and abstention correctness for the fixture questions.',
|
|
156
|
+
'Compares Enigma context packs with full-context, recency, and keyword local baselines on the same fixture.',
|
|
157
|
+
'Reports local estimated prompt tokens, duplicate-removal counts where applicable, and p50/p95 local latency.',
|
|
158
|
+
'Verifies Enigma-controlled bundles and context packs without exposing raw fixture memory, questions, or answers.',
|
|
159
|
+
'Lists external competitor adapter requirements and withholds third-party scores until credentials, runtimes, and datasets are supplied.',
|
|
160
|
+
]);
|
|
161
|
+
|
|
37
162
|
const BENCHMARK_CITATIONS = Object.freeze([
|
|
38
163
|
{
|
|
39
164
|
id: 'locomo',
|
|
@@ -402,6 +527,188 @@ function activeOptimizationPlan(vault, query) {
|
|
|
402
527
|
});
|
|
403
528
|
}
|
|
404
529
|
|
|
530
|
+
function activeBenchmarkMemories(vault) {
|
|
531
|
+
const memories = [];
|
|
532
|
+
for (const memoryAddr of vault.activeAddresses ?? []) {
|
|
533
|
+
const record = vault.__getRecord(memoryAddr);
|
|
534
|
+
if (!record || record.state !== 'active') continue;
|
|
535
|
+
memories.push({
|
|
536
|
+
memory_addr: memoryAddr,
|
|
537
|
+
content: vault.__getPlaintext(memoryAddr),
|
|
538
|
+
updated_at: record.updated_at ?? record.created_at,
|
|
539
|
+
created_at: record.created_at,
|
|
540
|
+
purpose_tags: Array.isArray(record.purpose_tags) ? [...record.purpose_tags] : [],
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
return memories;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
function estimatePromptTokens(query, memories) {
|
|
547
|
+
let tokens = estimateTextTokens(query);
|
|
548
|
+
for (const memory of memories) tokens += estimateTextTokens(memory.content);
|
|
549
|
+
return tokens;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
function localLatencySummary(values) {
|
|
553
|
+
return {
|
|
554
|
+
samples: values.length,
|
|
555
|
+
p50_ms: Number(percentile(values, 0.5).toFixed(6)),
|
|
556
|
+
p95_ms: Number(percentile(values, 0.95).toFixed(6)),
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
function compareUpdatedDesc(left, right) {
|
|
561
|
+
const leftTime = Date.parse(left.updated_at ?? left.created_at ?? '');
|
|
562
|
+
const rightTime = Date.parse(right.updated_at ?? right.created_at ?? '');
|
|
563
|
+
if (leftTime !== rightTime) return rightTime - leftTime;
|
|
564
|
+
return String(left.memory_addr).localeCompare(String(right.memory_addr));
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
function queryTerms(query) {
|
|
568
|
+
const stopwords = new Set([
|
|
569
|
+
'after',
|
|
570
|
+
'should',
|
|
571
|
+
'the',
|
|
572
|
+
'use',
|
|
573
|
+
'what',
|
|
574
|
+
'which',
|
|
575
|
+
'who',
|
|
576
|
+
]);
|
|
577
|
+
const terms = [];
|
|
578
|
+
for (const match of String(query).toLowerCase().matchAll(/[a-z0-9_-]{3,}/gu)) {
|
|
579
|
+
const term = match[0];
|
|
580
|
+
if (!stopwords.has(term)) terms.push(term);
|
|
581
|
+
}
|
|
582
|
+
return terms;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
function keywordFilteredMemories(memories, query) {
|
|
586
|
+
const terms = queryTerms(query);
|
|
587
|
+
if (terms.length === 0) return [];
|
|
588
|
+
return memories.filter((memory) => {
|
|
589
|
+
const haystack = `${memory.content} ${(memory.purpose_tags ?? []).join(' ')}`.toLowerCase();
|
|
590
|
+
return terms.some((term) => haystack.includes(term));
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
function selectLocalBaselineMemories(baselineId, vault, passport, question) {
|
|
595
|
+
const memories = activeBenchmarkMemories(vault);
|
|
596
|
+
if (baselineId === 'full_context') {
|
|
597
|
+
return {
|
|
598
|
+
memories,
|
|
599
|
+
estimatedPromptTokens: estimatePromptTokens(question.query, memories),
|
|
600
|
+
duplicateCandidatesRemoved: 0,
|
|
601
|
+
duplicateRemovalApplicable: false,
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
if (baselineId === 'recency_last_n') {
|
|
605
|
+
const selected = [...memories].sort(compareUpdatedDesc).slice(0, 3);
|
|
606
|
+
return {
|
|
607
|
+
memories: selected,
|
|
608
|
+
estimatedPromptTokens: estimatePromptTokens(question.query, selected),
|
|
609
|
+
duplicateCandidatesRemoved: 0,
|
|
610
|
+
duplicateRemovalApplicable: false,
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
if (baselineId === 'keyword_filter') {
|
|
614
|
+
const selected = keywordFilteredMemories(memories, question.query);
|
|
615
|
+
return {
|
|
616
|
+
memories: selected,
|
|
617
|
+
estimatedPromptTokens: estimatePromptTokens(question.query, selected),
|
|
618
|
+
duplicateCandidatesRemoved: 0,
|
|
619
|
+
duplicateRemovalApplicable: false,
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
if (baselineId === 'enigma_context_pack') {
|
|
623
|
+
const fullPlan = activeOptimizationPlan(vault, question.query);
|
|
624
|
+
const pack = compileContextPack({
|
|
625
|
+
vault,
|
|
626
|
+
passport,
|
|
627
|
+
query: question.query,
|
|
628
|
+
context_pack_id: `ctx_benchmark_local_baseline_${question.id}`,
|
|
629
|
+
...packOptions('local-llm'),
|
|
630
|
+
});
|
|
631
|
+
return {
|
|
632
|
+
memories: pack.memories,
|
|
633
|
+
estimatedPromptTokens: pack.optimization_plan?.optimized_prompt_tokens ?? estimatePromptTokens(question.query, pack.memories),
|
|
634
|
+
duplicateCandidatesRemoved: fullPlan.totals.duplicates_removed,
|
|
635
|
+
duplicateRemovalApplicable: true,
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
throw new Error(`unknown local baseline ${baselineId}`);
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
function compareLocalBaselines(vault, passport) {
|
|
642
|
+
const rows = [];
|
|
643
|
+
for (const baseline of LOCAL_BASELINES) {
|
|
644
|
+
let exactTotal = 0;
|
|
645
|
+
let exactCorrect = 0;
|
|
646
|
+
let abstainTotal = 0;
|
|
647
|
+
let abstainCorrect = 0;
|
|
648
|
+
let totalEstimatedPromptTokens = 0;
|
|
649
|
+
let selectedMemoryTotal = 0;
|
|
650
|
+
let maxDuplicateCandidatesRemoved = 0;
|
|
651
|
+
let totalDuplicateCandidatesRemoved = 0;
|
|
652
|
+
let duplicateRemovalApplicable = false;
|
|
653
|
+
const latencies = [];
|
|
654
|
+
|
|
655
|
+
for (const question of PRIVATE_FIXTURE.questions) {
|
|
656
|
+
const start = performance.now();
|
|
657
|
+
const selected = selectLocalBaselineMemories(baseline.id, vault, passport, question);
|
|
658
|
+
const result = chooseAnswer(question, { memories: selected.memories });
|
|
659
|
+
latencies.push(Math.max(0, performance.now() - start));
|
|
660
|
+
|
|
661
|
+
totalEstimatedPromptTokens += selected.estimatedPromptTokens;
|
|
662
|
+
selectedMemoryTotal += selected.memories.length;
|
|
663
|
+
maxDuplicateCandidatesRemoved = Math.max(maxDuplicateCandidatesRemoved, selected.duplicateCandidatesRemoved);
|
|
664
|
+
totalDuplicateCandidatesRemoved += selected.duplicateCandidatesRemoved;
|
|
665
|
+
duplicateRemovalApplicable = duplicateRemovalApplicable || selected.duplicateRemovalApplicable;
|
|
666
|
+
|
|
667
|
+
if (question.category === 'abstention') {
|
|
668
|
+
abstainTotal += 1;
|
|
669
|
+
if (result.abstained && result.correct) abstainCorrect += 1;
|
|
670
|
+
} else {
|
|
671
|
+
exactTotal += 1;
|
|
672
|
+
if (!result.abstained && result.correct) exactCorrect += 1;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
rows.push({
|
|
677
|
+
id: baseline.id,
|
|
678
|
+
label: baseline.label,
|
|
679
|
+
boundary: baseline.boundary,
|
|
680
|
+
local_fixture_only: true,
|
|
681
|
+
external_provider_called: false,
|
|
682
|
+
deterministic_fixture: true,
|
|
683
|
+
question_count: PRIVATE_FIXTURE.questions.length,
|
|
684
|
+
exact_answer_questions: exactTotal,
|
|
685
|
+
exact_answer_correct: exactCorrect,
|
|
686
|
+
exact_answer_recall: exactTotal === 0 ? 0 : Number((exactCorrect / exactTotal).toFixed(6)),
|
|
687
|
+
abstention_questions: abstainTotal,
|
|
688
|
+
abstention_correct: abstainCorrect,
|
|
689
|
+
abstention_correctness: abstainTotal === 0 ? 0 : Number((abstainCorrect / abstainTotal).toFixed(6)),
|
|
690
|
+
estimated_prompt_tokens: {
|
|
691
|
+
total: totalEstimatedPromptTokens,
|
|
692
|
+
mean_per_question: Number((totalEstimatedPromptTokens / PRIVATE_FIXTURE.questions.length).toFixed(6)),
|
|
693
|
+
estimator: 'estimateTextTokens deterministic local estimator',
|
|
694
|
+
},
|
|
695
|
+
selected_memory_count: {
|
|
696
|
+
total: selectedMemoryTotal,
|
|
697
|
+
mean_per_question: Number((selectedMemoryTotal / PRIVATE_FIXTURE.questions.length).toFixed(6)),
|
|
698
|
+
},
|
|
699
|
+
duplicate_removal: {
|
|
700
|
+
applicable: duplicateRemovalApplicable,
|
|
701
|
+
max_duplicate_candidates_removed: maxDuplicateCandidatesRemoved,
|
|
702
|
+
total_duplicate_candidates_removed: totalDuplicateCandidatesRemoved,
|
|
703
|
+
},
|
|
704
|
+
latency: localLatencySummary(latencies),
|
|
705
|
+
public_question_text_included: false,
|
|
706
|
+
public_answer_text_included: false,
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
return rows;
|
|
710
|
+
}
|
|
711
|
+
|
|
405
712
|
function summarizeContextReduction(plan) {
|
|
406
713
|
const baseline = plan?.baseline_prompt_tokens ?? 0;
|
|
407
714
|
const optimized = plan?.optimized_prompt_tokens ?? 0;
|
|
@@ -489,6 +796,7 @@ export function runMemoryBenchmarkSuite(options = {}) {
|
|
|
489
796
|
const passport = createPassport({ vault: importedVault, now: generatedAt });
|
|
490
797
|
|
|
491
798
|
const scored = scoreQuestions(importedVault, passport, samples);
|
|
799
|
+
const localBaselineRows = compareLocalBaselines(importedVault, passport);
|
|
492
800
|
const fullOptimizationPlan = activeOptimizationPlan(importedVault, 'Use the benchmark memory boundary for recall and abstention evaluation.');
|
|
493
801
|
const providerRows = compareProviders(importedVault, passport, samples);
|
|
494
802
|
const verificationBundleResults = [];
|
|
@@ -522,7 +830,7 @@ export function runMemoryBenchmarkSuite(options = {}) {
|
|
|
522
830
|
benchmark_leadership_claim: false,
|
|
523
831
|
claim_boundary: [
|
|
524
832
|
'This suite measures deterministic local Enigma fixture operations only.',
|
|
525
|
-
'Cross-provider
|
|
833
|
+
'Cross-provider profile rows remain same-boundary Enigma labels; external competitor adapter rows are requirements only and contain no third-party scores.',
|
|
526
834
|
'Token reduction is a local estimator result against this fixture, not a provider invoice, ROI, guaranteed savings, or benchmark-leadership claim.',
|
|
527
835
|
'Verification proves Enigma-controlled receipts/bundles/context packs only; it is not provider deletion, provider forgetting, model forgetting, or compliance certification evidence.',
|
|
528
836
|
],
|
|
@@ -536,6 +844,7 @@ export function runMemoryBenchmarkSuite(options = {}) {
|
|
|
536
844
|
optimizer_plan_token_estimates: true,
|
|
537
845
|
bundle_verification: true,
|
|
538
846
|
context_pack_verification: true,
|
|
847
|
+
local_baseline_comparison: true,
|
|
539
848
|
latency_clock: 'performance.now',
|
|
540
849
|
},
|
|
541
850
|
metrics: {
|
|
@@ -546,6 +855,7 @@ export function runMemoryBenchmarkSuite(options = {}) {
|
|
|
546
855
|
deduped_candidates: fullOptimizationPlan.totals.deduped_candidates,
|
|
547
856
|
duplicate_candidates_removed: fullOptimizationPlan.totals.duplicates_removed,
|
|
548
857
|
},
|
|
858
|
+
local_baseline_comparisons: localBaselineRows,
|
|
549
859
|
latency: latencySummary(samples),
|
|
550
860
|
verification: {
|
|
551
861
|
bundle_verify_runs: verificationBundleResults.length,
|
|
@@ -554,6 +864,8 @@ export function runMemoryBenchmarkSuite(options = {}) {
|
|
|
554
864
|
},
|
|
555
865
|
},
|
|
556
866
|
cross_provider_profiles: providerRows,
|
|
867
|
+
external_competitor_adapters: EXTERNAL_COMPETITOR_ADAPTERS,
|
|
868
|
+
public_claims_allowed: PUBLIC_CLAIMS_ALLOWED,
|
|
557
869
|
};
|
|
558
870
|
|
|
559
871
|
return assertNoRawFixtureLeak(report);
|