426e9eeabd
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Waiting to run
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Waiting to run
Build Agent Image / build-and-push (push) Waiting to run
Chat shell gestures / Chat shell gesture + parity e2e (push) Waiting to run
ci / test (push) Waiting to run
ci / lint-and-format (push) Waiting to run
ci / build (push) Waiting to run
ci / dev-startup (push) Waiting to run
Cloud Gateway Discord / Test (push) Waiting to run
Cloud Gateway Webhook / Test (push) Waiting to run
Cloud Tests / lint-and-types (push) Waiting to run
Cloud Tests / unit-tests (push) Waiting to run
Cloud Tests / integration-tests (push) Waiting to run
Cloud Tests / e2e-tests (push) Blocked by required conditions
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Apps Worker (Product 2) / Determine environment (push) Waiting to run
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Blocked by required conditions
Deploy Eliza Provisioning Worker / Determine environment (push) Waiting to run
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Blocked by required conditions
Dev Smoke / Classify changed paths (push) Waiting to run
Dev Smoke / bun run dev onboarding chat (push) Blocked by required conditions
Dev Smoke / Vite HMR dependency-level smoke (push) Blocked by required conditions
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Waiting to run
gitleaks / gitleaks (push) Waiting to run
Markdown Links / Relative Markdown Links (push) Waiting to run
Publish @elizaos/example-code / check_npm (push) Waiting to run
Publish @elizaos/example-code / publish_npm (push) Blocked by required conditions
Publish @elizaos/plugin-elizacloud / verify_version (push) Waiting to run
Publish @elizaos/plugin-elizacloud / publish_npm (push) Blocked by required conditions
Quality (Extended) / Homepage Build (PR smoke) (push) Waiting to run
Quality (Extended) / Comment-only diff guard (push) Waiting to run
Quality (Extended) / Format + Type Safety Ratchet (push) Waiting to run
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Waiting to run
Quality (Extended) / Develop Gate (lint) (push) Waiting to run
Sandbox Live Smoke / Sandbox live smoke (push) Waiting to run
Snap Build & Test / Build Snap (amd64) (push) Waiting to run
Snap Build & Test / Build Snap (arm64) (push) Waiting to run
supply-chain / sbom (push) Waiting to run
supply-chain / vulnerability-scan (push) Waiting to run
Build, Push & Deploy to Phala Cloud / build-and-push (push) Waiting to run
Test Packaging / Validate Packaging Configs (push) Waiting to run
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Waiting to run
Test Packaging / Pack & Test JS Tarballs (push) Waiting to run
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Waiting to run
UI Fixture E2E / ui-fixture-e2e (push) Waiting to run
UI Fixture E2E / fixture-e2e (push) Waiting to run
UI Story Gate / story-gate (push) Waiting to run
vault-ci / test (macos-latest) (push) Waiting to run
vault-ci / test (ubuntu-latest) (push) Waiting to run
vault-ci / test (windows-latest) (push) Waiting to run
vault-ci / app-core wiring tests (push) Waiting to run
verify-patches / verify patches/CHECKSUMS.sha256 (push) Waiting to run
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Waiting to run
Voice Benchmark Smoke / voice bench smoke summary (push) Blocked by required conditions
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Waiting to run
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Waiting to run
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Waiting to run
Test Packaging / Build & Test PyPI Package (push) Waiting to run
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
5.3 KiB
5.3 KiB
@elizaos/recall-bench
Precision/Recall/nDCG/latency benchmark + CI gate for the real memory-recall
- knowledge-retrieval pipeline (#9956). Drives shipped
@elizaos/corecode over a committed, document-scale, labeled corpus — see README.md for the what/why and the committed baseline.
Layout
metrics.ts Pure IR metrics (P@K/R@K/MRR/nDCG/HitRate, percentiles) + summarizeRecall()
embedding.ts Deterministic feature-hash embedding (FNV-1a tokens + char trigrams, L2-norm, 384d)
corpus.ts buildCorpus(tier) + buildFacts(tier) + buildMorphologyCorpus() — labeled, deterministic PRNG
runtime.ts buildBenchRuntime() — real AgentRuntime + plugin-sql/PGlite + DocumentService
run.ts The runner: ingest → drive every SearchMode → emit report → budget gate (exit 0/1/2)
budgets.json Committed per-mode floors + min observable fail-open drop (1k baseline + ~20% headroom)
baseline-1k.json Committed reference metrics (the "before/after" artifact)
scripts/check-registry.py Orchestrator-registration contract check (CI)
*.test.ts Unit tests for the pure pieces + corpus design invariants
Run: bun run bench:recall (smoke) / bun run bench:recall:1k (gate) from the
repo root, or bun run --cwd packages/benchmarks/recall-bench test for units.
Why these exact construction choices (do not "simplify" them away)
- The morphology slice (
buildMorphologyCorpus+keyword-morph-*) uses untagged real English families because the main corpus's numeric-tagged tokens (configure0) defeat Porter2 (its suffix rules need a real letter-ending), so the main corpus CANNOT measure stemming. Each family's-ingquery form is absent from its docs but shares their Porter stem → unstemmed BM25 scores 0, stemmed BM25 matches. Verify every form's stem offline before adding a family (Porter doesn't strip prefixes —reconfigure→reconfigur— and drifts on irregulars/derivations —analysis→analysi≠analyz,ran≠run); keep the per-family stems mutually disjoint and distinct from any distractor. rankByKeyworduses thesearch.tsBM25(with{stemming:true}), not the documentsbm25Scores— only the former has Porter2 stemming, a stop-word list, and Unicode/accent normalization (the documents tokenizer's[^a-z0-9]strip silently drops accented + CJK text). It is index-built per call; callers re-sort, so input order isn't relied on.- PGlite via
@elizaos/plugin-sql, notInMemoryDatabaseAdapterorplugin-inmemorydb. Core's in-memorysearchMemoriesis a stub that returns[];plugin-inmemorydboverwritesmetadata.typewith the table name, soDocumentServicefilters out every fragment. Only PGlite gives real pgvector cosine while preservingmetadata.type— and it is embedded WASM (no server, no secrets). DocumentService.start(runtime)directly, notruntime.getService("documents")— the service getter is gated byisNativeFeatureServiceEnabled, off in a bare benchmark runtime.start()drives the same ingest/search code.addDocument({ content })must be base64-encoded (Buffer.from(text).toString("base64")). The text path base64-decodescontentas a heuristic; raw text misfires it ("File … appears to be corrupted or incorrectly encoded").- Passing
querytoruntime.searchMemoriestriggers a BM25 rerank that drops zero-keyword-overlap candidates (rerankMemories→search.tsBM25,if (score <= 0) continue). The raw-vector slice omitsqueryto measure pure cosine. This bench caught DocumentService'svector/hybridmodes passingquery(andlimit, which the adapter ignores in favour ofcount→ a silent 10-fragment pool) — two structural bugs that throttled document-vector to 0.715 vs the 0.965 cosine ceiling. Both are fixed inservice.ts; the committed baseline reflects the corrected pipeline. - The fail-open slice calls
runtime.startRun()before flipping the embedder to throw.embedRecallQuerymemoizes successful query vectors per run id; a fresh run id busts that cache so the throw actually reaches_vectorSearchand the keyword fall-open is observed (otherwise the drop reads as 0).
Determinism contract
Every number is reproducible run-to-run: seeded mulberry32 corpus, deterministic
embedText, deterministic pgvector cosine. Never introduce Date.now() /
Math.random() / wall-clock into the corpus or embedding — it would flake the CI
gate. (Latency is timed with performance.now() and only feeds p50/p95, never
ranking.) Honesty contract from memperf: unmeasured rows are null, never 0;
measured: true only on a real run.
Gotchas
- Run with
bun --conditions=eliza-sourceso@elizaos/*resolves to workspace source; the runner callsprocess.exit()(lingering DB/task services otherwise keep the event loop alive). - Fresh checkout:
bun run --cwd packages/shared build:i18nfirst — the bench imports@elizaos/coresource, which needs the generated keyword data. factsProvideris internal to core (not on the public barrel); the bench imports it via a relative source path — a benchmark legitimately reaches into the same tree to measure it.
Repo-wide rules (logger-only, ESM, naming) live in the root AGENTS.md.