@claude-flow/cli 3.21.1 → 3.22.0
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/.claude/helpers/helpers.manifest.json +12 -0
- package/.claude/helpers/hook-handler.cjs +26 -5
- package/.claude/helpers/intelligence.cjs +4 -1
- package/dist/src/commands/daemon.js +23 -2
- package/dist/src/commands/memory-distill.d.ts +27 -0
- package/dist/src/commands/memory-distill.js +374 -0
- package/dist/src/commands/memory.js +4 -2
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +22 -1
- package/dist/src/init/executor.js +20 -0
- package/dist/src/init/helper-refresh.d.ts +19 -0
- package/dist/src/init/helper-refresh.js +175 -0
- package/dist/src/init/helper-signing.d.ts +30 -0
- package/dist/src/init/helper-signing.js +60 -0
- package/dist/src/init/helpers-generator.d.ts +16 -0
- package/dist/src/init/helpers-generator.js +63 -6
- package/dist/src/init/statusline-generator.js +18 -7
- package/dist/src/mcp-client.js +13 -0
- package/dist/src/mcp-tools/agenticow-speculate-tools.js +9 -2
- package/dist/src/mcp-tools/browser-intent-tools.d.ts +162 -0
- package/dist/src/mcp-tools/browser-intent-tools.js +548 -0
- package/dist/src/mcp-tools/browser-tools.d.ts +9 -1
- package/dist/src/mcp-tools/browser-tools.js +4 -1
- package/dist/src/memory/memory-bridge.js +67 -47
- package/dist/src/memory/memory-initializer.d.ts +71 -0
- package/dist/src/memory/memory-initializer.js +330 -2
- package/dist/src/services/distill-tuning.d.ts +111 -0
- package/dist/src/services/distill-tuning.js +510 -0
- package/dist/src/services/memory-distillation.d.ts +41 -0
- package/dist/src/services/memory-distillation.js +277 -0
- package/dist/src/services/worker-daemon.d.ts +22 -1
- package/dist/src/services/worker-daemon.js +117 -6
- package/package.json +5 -2
- package/dist/src/agenticow/speculative-exploration.d.ts.map +0 -1
- package/dist/src/agenticow/speculative-exploration.js.map +0 -1
- package/dist/src/appliance/gguf-engine.d.ts.map +0 -1
- package/dist/src/appliance/gguf-engine.js.map +0 -1
- package/dist/src/appliance/ruvllm-bridge.d.ts.map +0 -1
- package/dist/src/appliance/ruvllm-bridge.js.map +0 -1
- package/dist/src/appliance/rvfa-builder.d.ts.map +0 -1
- package/dist/src/appliance/rvfa-builder.js.map +0 -1
- package/dist/src/appliance/rvfa-distribution.d.ts.map +0 -1
- package/dist/src/appliance/rvfa-distribution.js.map +0 -1
- package/dist/src/appliance/rvfa-format.d.ts.map +0 -1
- package/dist/src/appliance/rvfa-format.js.map +0 -1
- package/dist/src/appliance/rvfa-runner.d.ts.map +0 -1
- package/dist/src/appliance/rvfa-runner.js.map +0 -1
- package/dist/src/appliance/rvfa-signing.d.ts.map +0 -1
- package/dist/src/appliance/rvfa-signing.js.map +0 -1
- package/dist/src/autopilot-state.d.ts.map +0 -1
- package/dist/src/autopilot-state.js.map +0 -1
- package/dist/src/benchmarks/gaia-agent-planning.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-agent-planning.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-agent.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-agent.js.map +0 -1
- package/dist/src/benchmarks/gaia-causal-memory.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-causal-memory.js.map +0 -1
- package/dist/src/benchmarks/gaia-causal-memory.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-causal-memory.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-convergence.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-convergence.js.map +0 -1
- package/dist/src/benchmarks/gaia-convergence.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-convergence.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-critic.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-critic.js.map +0 -1
- package/dist/src/benchmarks/gaia-critic.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-critic.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-decomposer.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-decomposer.js.map +0 -1
- package/dist/src/benchmarks/gaia-decomposer.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-decomposer.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-e2e-smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-e2e-smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-extract.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-extract.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-hardness/features.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-hardness/features.js.map +0 -1
- package/dist/src/benchmarks/gaia-hardness/predictor.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-hardness/predictor.js.map +0 -1
- package/dist/src/benchmarks/gaia-hardness/predictor.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-hardness/predictor.smoke.js.map +0 -1
- package/dist/src/benchmarks/gaia-hardness/train-data-loader.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-hardness/train-data-loader.js.map +0 -1
- package/dist/src/benchmarks/gaia-judge.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-judge.js.map +0 -1
- package/dist/src/benchmarks/gaia-loader.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-loader.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/file_read.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/file_read.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/grounded_query.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/grounded_query.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/index.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/index.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/types.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/types.js.map +0 -1
- package/dist/src/benchmarks/gaia-tools/web_search.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-tools/web_search.js.map +0 -1
- package/dist/src/benchmarks/gaia-voting.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-voting.js.map +0 -1
- package/dist/src/benchmarks/gaia-voting.smoke.d.ts.map +0 -1
- package/dist/src/benchmarks/gaia-voting.smoke.js.map +0 -1
- package/dist/src/benchmarks/pretrain/index.d.ts.map +0 -1
- package/dist/src/benchmarks/pretrain/index.js.map +0 -1
- package/dist/src/business-pods/bbs-budget-tracker.d.ts.map +0 -1
- package/dist/src/business-pods/bbs-budget-tracker.js.map +0 -1
- package/dist/src/business-pods/domain-affinity-policy.d.ts.map +0 -1
- package/dist/src/business-pods/domain-affinity-policy.js.map +0 -1
- package/dist/src/business-pods/pod-schema.d.ts.map +0 -1
- package/dist/src/business-pods/pod-schema.js.map +0 -1
- package/dist/src/commands/agent-wasm.d.ts.map +0 -1
- package/dist/src/commands/agent-wasm.js.map +0 -1
- package/dist/src/commands/agent.d.ts.map +0 -1
- package/dist/src/commands/agent.js.map +0 -1
- package/dist/src/commands/analyze.d.ts.map +0 -1
- package/dist/src/commands/analyze.js.map +0 -1
- package/dist/src/commands/appliance-advanced.d.ts.map +0 -1
- package/dist/src/commands/appliance-advanced.js.map +0 -1
- package/dist/src/commands/appliance.d.ts.map +0 -1
- package/dist/src/commands/appliance.js.map +0 -1
- package/dist/src/commands/autopilot.d.ts.map +0 -1
- package/dist/src/commands/autopilot.js.map +0 -1
- package/dist/src/commands/benchmark.d.ts.map +0 -1
- package/dist/src/commands/benchmark.js.map +0 -1
- package/dist/src/commands/claims.d.ts.map +0 -1
- package/dist/src/commands/claims.js.map +0 -1
- package/dist/src/commands/cleanup.d.ts.map +0 -1
- package/dist/src/commands/cleanup.js.map +0 -1
- package/dist/src/commands/completions.d.ts.map +0 -1
- package/dist/src/commands/completions.js.map +0 -1
- package/dist/src/commands/config.d.ts.map +0 -1
- package/dist/src/commands/config.js.map +0 -1
- package/dist/src/commands/daemon.d.ts.map +0 -1
- package/dist/src/commands/daemon.js.map +0 -1
- package/dist/src/commands/deployment.d.ts.map +0 -1
- package/dist/src/commands/deployment.js.map +0 -1
- package/dist/src/commands/doctor.d.ts.map +0 -1
- package/dist/src/commands/doctor.js.map +0 -1
- package/dist/src/commands/eject.d.ts.map +0 -1
- package/dist/src/commands/eject.js.map +0 -1
- package/dist/src/commands/embeddings.d.ts.map +0 -1
- package/dist/src/commands/embeddings.js.map +0 -1
- package/dist/src/commands/gaia-bench.d.ts.map +0 -1
- package/dist/src/commands/gaia-bench.js.map +0 -1
- package/dist/src/commands/guidance.d.ts.map +0 -1
- package/dist/src/commands/guidance.js.map +0 -1
- package/dist/src/commands/hive-mind.d.ts.map +0 -1
- package/dist/src/commands/hive-mind.js.map +0 -1
- package/dist/src/commands/hooks.d.ts.map +0 -1
- package/dist/src/commands/hooks.js.map +0 -1
- package/dist/src/commands/index.d.ts.map +0 -1
- package/dist/src/commands/index.js.map +0 -1
- package/dist/src/commands/init.d.ts.map +0 -1
- package/dist/src/commands/init.js.map +0 -1
- package/dist/src/commands/issues.d.ts.map +0 -1
- package/dist/src/commands/issues.js.map +0 -1
- package/dist/src/commands/mcp.d.ts.map +0 -1
- package/dist/src/commands/mcp.js.map +0 -1
- package/dist/src/commands/memory.d.ts.map +0 -1
- package/dist/src/commands/memory.js.map +0 -1
- package/dist/src/commands/metaharness.d.ts.map +0 -1
- package/dist/src/commands/metaharness.js.map +0 -1
- package/dist/src/commands/migrate.d.ts.map +0 -1
- package/dist/src/commands/migrate.js.map +0 -1
- package/dist/src/commands/neural.d.ts.map +0 -1
- package/dist/src/commands/neural.js.map +0 -1
- package/dist/src/commands/performance.d.ts.map +0 -1
- package/dist/src/commands/performance.js.map +0 -1
- package/dist/src/commands/plugins.d.ts.map +0 -1
- package/dist/src/commands/plugins.js.map +0 -1
- package/dist/src/commands/process.d.ts.map +0 -1
- package/dist/src/commands/process.js.map +0 -1
- package/dist/src/commands/progress.d.ts.map +0 -1
- package/dist/src/commands/progress.js.map +0 -1
- package/dist/src/commands/providers.d.ts.map +0 -1
- package/dist/src/commands/providers.js.map +0 -1
- package/dist/src/commands/route.d.ts.map +0 -1
- package/dist/src/commands/route.js.map +0 -1
- package/dist/src/commands/ruvector/backup.d.ts.map +0 -1
- package/dist/src/commands/ruvector/backup.js.map +0 -1
- package/dist/src/commands/ruvector/benchmark.d.ts.map +0 -1
- package/dist/src/commands/ruvector/benchmark.js.map +0 -1
- package/dist/src/commands/ruvector/import.d.ts.map +0 -1
- package/dist/src/commands/ruvector/import.js.map +0 -1
- package/dist/src/commands/ruvector/index.d.ts.map +0 -1
- package/dist/src/commands/ruvector/index.js.map +0 -1
- package/dist/src/commands/ruvector/init.d.ts.map +0 -1
- package/dist/src/commands/ruvector/init.js.map +0 -1
- package/dist/src/commands/ruvector/migrate.d.ts.map +0 -1
- package/dist/src/commands/ruvector/migrate.js.map +0 -1
- package/dist/src/commands/ruvector/optimize.d.ts.map +0 -1
- package/dist/src/commands/ruvector/optimize.js.map +0 -1
- package/dist/src/commands/ruvector/pg-utils.d.ts.map +0 -1
- package/dist/src/commands/ruvector/pg-utils.js.map +0 -1
- package/dist/src/commands/ruvector/setup.d.ts.map +0 -1
- package/dist/src/commands/ruvector/setup.js.map +0 -1
- package/dist/src/commands/ruvector/status.d.ts.map +0 -1
- package/dist/src/commands/ruvector/status.js.map +0 -1
- package/dist/src/commands/security.d.ts.map +0 -1
- package/dist/src/commands/security.js.map +0 -1
- package/dist/src/commands/session.d.ts.map +0 -1
- package/dist/src/commands/session.js.map +0 -1
- package/dist/src/commands/start.d.ts.map +0 -1
- package/dist/src/commands/start.js.map +0 -1
- package/dist/src/commands/status.d.ts.map +0 -1
- package/dist/src/commands/status.js.map +0 -1
- package/dist/src/commands/swarm.d.ts.map +0 -1
- package/dist/src/commands/swarm.js.map +0 -1
- package/dist/src/commands/task.d.ts.map +0 -1
- package/dist/src/commands/task.js.map +0 -1
- package/dist/src/commands/transfer-store.d.ts.map +0 -1
- package/dist/src/commands/transfer-store.js.map +0 -1
- package/dist/src/commands/update.d.ts.map +0 -1
- package/dist/src/commands/update.js.map +0 -1
- package/dist/src/commands/verify.d.ts.map +0 -1
- package/dist/src/commands/verify.js.map +0 -1
- package/dist/src/commands/workflow.d.ts.map +0 -1
- package/dist/src/commands/workflow.js.map +0 -1
- package/dist/src/config-adapter.d.ts.map +0 -1
- package/dist/src/config-adapter.js.map +0 -1
- package/dist/src/encryption/vault.d.ts.map +0 -1
- package/dist/src/encryption/vault.js.map +0 -1
- package/dist/src/fs-secure.d.ts.map +0 -1
- package/dist/src/fs-secure.js.map +0 -1
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/index.js.map +0 -1
- package/dist/src/infrastructure/in-memory-repositories.d.ts.map +0 -1
- package/dist/src/infrastructure/in-memory-repositories.js.map +0 -1
- package/dist/src/init/claudemd-generator.d.ts.map +0 -1
- package/dist/src/init/claudemd-generator.js.map +0 -1
- package/dist/src/init/executor.d.ts.map +0 -1
- package/dist/src/init/executor.js.map +0 -1
- package/dist/src/init/helpers-generator.d.ts.map +0 -1
- package/dist/src/init/helpers-generator.js.map +0 -1
- package/dist/src/init/index.d.ts.map +0 -1
- package/dist/src/init/index.js.map +0 -1
- package/dist/src/init/mcp-generator.d.ts.map +0 -1
- package/dist/src/init/mcp-generator.js.map +0 -1
- package/dist/src/init/memory-package-resolver.d.ts.map +0 -1
- package/dist/src/init/memory-package-resolver.js.map +0 -1
- package/dist/src/init/settings-generator.d.ts.map +0 -1
- package/dist/src/init/settings-generator.js.map +0 -1
- package/dist/src/init/statusline-generator.d.ts.map +0 -1
- package/dist/src/init/statusline-generator.js.map +0 -1
- package/dist/src/init/types.d.ts.map +0 -1
- package/dist/src/init/types.js.map +0 -1
- package/dist/src/log-filters.d.ts.map +0 -1
- package/dist/src/log-filters.js.map +0 -1
- package/dist/src/mcp-client.d.ts.map +0 -1
- package/dist/src/mcp-client.js.map +0 -1
- package/dist/src/mcp-server.d.ts.map +0 -1
- package/dist/src/mcp-server.js.map +0 -1
- package/dist/src/mcp-tools/agent-execute-core.d.ts.map +0 -1
- package/dist/src/mcp-tools/agent-execute-core.js.map +0 -1
- package/dist/src/mcp-tools/agent-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/agent-tools.js.map +0 -1
- package/dist/src/mcp-tools/agentbbs-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/agentbbs-tools.js.map +0 -1
- package/dist/src/mcp-tools/agentdb-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/agentdb-tools.js.map +0 -1
- package/dist/src/mcp-tools/agenticow-loader.d.ts.map +0 -1
- package/dist/src/mcp-tools/agenticow-loader.js.map +0 -1
- package/dist/src/mcp-tools/agenticow-speculate-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/agenticow-speculate-tools.js.map +0 -1
- package/dist/src/mcp-tools/agenticow-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/agenticow-tools.js.map +0 -1
- package/dist/src/mcp-tools/analyze-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/analyze-tools.js.map +0 -1
- package/dist/src/mcp-tools/auto-install.d.ts.map +0 -1
- package/dist/src/mcp-tools/auto-install.js.map +0 -1
- package/dist/src/mcp-tools/autopilot-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/autopilot-tools.js.map +0 -1
- package/dist/src/mcp-tools/browser-session-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/browser-session-tools.js.map +0 -1
- package/dist/src/mcp-tools/browser-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/browser-tools.js.map +0 -1
- package/dist/src/mcp-tools/business-pod-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/business-pod-tools.js.map +0 -1
- package/dist/src/mcp-tools/claims-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/claims-tools.js.map +0 -1
- package/dist/src/mcp-tools/config-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/config-tools.js.map +0 -1
- package/dist/src/mcp-tools/coordination-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/coordination-tools.js.map +0 -1
- package/dist/src/mcp-tools/daa-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/daa-tools.js.map +0 -1
- package/dist/src/mcp-tools/embeddings-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/embeddings-tools.js.map +0 -1
- package/dist/src/mcp-tools/github-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/github-tools.js.map +0 -1
- package/dist/src/mcp-tools/guidance-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/guidance-tools.js.map +0 -1
- package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/hive-mind-tools.js.map +0 -1
- package/dist/src/mcp-tools/hooks-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/hooks-tools.js.map +0 -1
- package/dist/src/mcp-tools/http-fetch-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/http-fetch-tools.js.map +0 -1
- package/dist/src/mcp-tools/index.d.ts.map +0 -1
- package/dist/src/mcp-tools/index.js.map +0 -1
- package/dist/src/mcp-tools/managed-agent-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/managed-agent-tools.js.map +0 -1
- package/dist/src/mcp-tools/memory-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/memory-tools.js.map +0 -1
- package/dist/src/mcp-tools/metaharness-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/metaharness-tools.js.map +0 -1
- package/dist/src/mcp-tools/neural-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/neural-tools.js.map +0 -1
- package/dist/src/mcp-tools/performance-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/performance-tools.js.map +0 -1
- package/dist/src/mcp-tools/progress-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/progress-tools.js.map +0 -1
- package/dist/src/mcp-tools/request-tracker.d.ts.map +0 -1
- package/dist/src/mcp-tools/request-tracker.js.map +0 -1
- package/dist/src/mcp-tools/ruvllm-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/ruvllm-tools.js.map +0 -1
- package/dist/src/mcp-tools/security-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/security-tools.js.map +0 -1
- package/dist/src/mcp-tools/session-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/session-tools.js.map +0 -1
- package/dist/src/mcp-tools/swarm-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/swarm-tools.js.map +0 -1
- package/dist/src/mcp-tools/system-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/system-tools.js.map +0 -1
- package/dist/src/mcp-tools/task-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/task-tools.js.map +0 -1
- package/dist/src/mcp-tools/terminal-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/terminal-tools.js.map +0 -1
- package/dist/src/mcp-tools/testgen-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/testgen-tools.js.map +0 -1
- package/dist/src/mcp-tools/tool-loop-guardrail.d.ts.map +0 -1
- package/dist/src/mcp-tools/tool-loop-guardrail.js.map +0 -1
- package/dist/src/mcp-tools/transfer-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/transfer-tools.js.map +0 -1
- package/dist/src/mcp-tools/types.d.ts.map +0 -1
- package/dist/src/mcp-tools/types.js.map +0 -1
- package/dist/src/mcp-tools/validate-input.d.ts.map +0 -1
- package/dist/src/mcp-tools/validate-input.js.map +0 -1
- package/dist/src/mcp-tools/wasm-agent-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/wasm-agent-tools.js.map +0 -1
- package/dist/src/mcp-tools/workflow-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/workflow-tools.js.map +0 -1
- package/dist/src/memory/bge-embedder.d.ts.map +0 -1
- package/dist/src/memory/bge-embedder.js.map +0 -1
- package/dist/src/memory/cross-encoder-rerank.d.ts.map +0 -1
- package/dist/src/memory/cross-encoder-rerank.js.map +0 -1
- package/dist/src/memory/embedding-quantization.d.ts.map +0 -1
- package/dist/src/memory/embedding-quantization.js.map +0 -1
- package/dist/src/memory/ewc-consolidation.d.ts.map +0 -1
- package/dist/src/memory/ewc-consolidation.js.map +0 -1
- package/dist/src/memory/graph-edge-writer.d.ts.map +0 -1
- package/dist/src/memory/graph-edge-writer.js.map +0 -1
- package/dist/src/memory/hybrid-retrieval.d.ts.map +0 -1
- package/dist/src/memory/hybrid-retrieval.js.map +0 -1
- package/dist/src/memory/intelligence.d.ts.map +0 -1
- package/dist/src/memory/intelligence.js.map +0 -1
- package/dist/src/memory/lucene-bm25.d.ts.map +0 -1
- package/dist/src/memory/lucene-bm25.js.map +0 -1
- package/dist/src/memory/memory-bridge.d.ts.map +0 -1
- package/dist/src/memory/memory-bridge.js.map +0 -1
- package/dist/src/memory/memory-initializer.d.ts.map +0 -1
- package/dist/src/memory/memory-initializer.js.map +0 -1
- package/dist/src/memory/neural-package-bridge.d.ts.map +0 -1
- package/dist/src/memory/neural-package-bridge.js.map +0 -1
- package/dist/src/memory/rabitq-index.d.ts.map +0 -1
- package/dist/src/memory/rabitq-index.js.map +0 -1
- package/dist/src/memory/sona-optimizer.d.ts.map +0 -1
- package/dist/src/memory/sona-optimizer.js.map +0 -1
- package/dist/src/memory/structured-distill.d.ts.map +0 -1
- package/dist/src/memory/structured-distill.js.map +0 -1
- package/dist/src/output.d.ts.map +0 -1
- package/dist/src/output.js.map +0 -1
- package/dist/src/parser.d.ts.map +0 -1
- package/dist/src/parser.js.map +0 -1
- package/dist/src/plugins/manager.d.ts.map +0 -1
- package/dist/src/plugins/manager.js.map +0 -1
- package/dist/src/plugins/store/discovery.d.ts.map +0 -1
- package/dist/src/plugins/store/discovery.js.map +0 -1
- package/dist/src/plugins/store/index.d.ts.map +0 -1
- package/dist/src/plugins/store/index.js.map +0 -1
- package/dist/src/plugins/store/search.d.ts.map +0 -1
- package/dist/src/plugins/store/search.js.map +0 -1
- package/dist/src/plugins/store/types.d.ts.map +0 -1
- package/dist/src/plugins/store/types.js.map +0 -1
- package/dist/src/plugins/tests/demo-plugin-store.d.ts.map +0 -1
- package/dist/src/plugins/tests/demo-plugin-store.js.map +0 -1
- package/dist/src/plugins/tests/standalone-test.d.ts.map +0 -1
- package/dist/src/plugins/tests/standalone-test.js.map +0 -1
- package/dist/src/plugins/tests/test-plugin-store.d.ts.map +0 -1
- package/dist/src/plugins/tests/test-plugin-store.js.map +0 -1
- package/dist/src/production/circuit-breaker.d.ts.map +0 -1
- package/dist/src/production/circuit-breaker.js.map +0 -1
- package/dist/src/production/error-handler.d.ts.map +0 -1
- package/dist/src/production/error-handler.js.map +0 -1
- package/dist/src/production/index.d.ts.map +0 -1
- package/dist/src/production/index.js.map +0 -1
- package/dist/src/production/monitoring.d.ts.map +0 -1
- package/dist/src/production/monitoring.js.map +0 -1
- package/dist/src/production/rate-limiter.d.ts.map +0 -1
- package/dist/src/production/rate-limiter.js.map +0 -1
- package/dist/src/production/retry.d.ts.map +0 -1
- package/dist/src/production/retry.js.map +0 -1
- package/dist/src/prompt.d.ts.map +0 -1
- package/dist/src/prompt.js.map +0 -1
- package/dist/src/runtime/headless.d.ts.map +0 -1
- package/dist/src/runtime/headless.js.map +0 -1
- package/dist/src/runtime/parent-death-watchdog.d.ts.map +0 -1
- package/dist/src/runtime/parent-death-watchdog.js.map +0 -1
- package/dist/src/ruvector/agent-wasm.d.ts.map +0 -1
- package/dist/src/ruvector/agent-wasm.js.map +0 -1
- package/dist/src/ruvector/ast-analyzer.d.ts.map +0 -1
- package/dist/src/ruvector/ast-analyzer.js.map +0 -1
- package/dist/src/ruvector/codemods/engine.d.ts.map +0 -1
- package/dist/src/ruvector/codemods/engine.js.map +0 -1
- package/dist/src/ruvector/codemods/scope-analysis.d.ts.map +0 -1
- package/dist/src/ruvector/codemods/scope-analysis.js.map +0 -1
- package/dist/src/ruvector/coverage-router.d.ts.map +0 -1
- package/dist/src/ruvector/coverage-router.js.map +0 -1
- package/dist/src/ruvector/coverage-tools.d.ts.map +0 -1
- package/dist/src/ruvector/coverage-tools.js.map +0 -1
- package/dist/src/ruvector/diff-classifier.d.ts.map +0 -1
- package/dist/src/ruvector/diff-classifier.js.map +0 -1
- package/dist/src/ruvector/diskann-backend.d.ts.map +0 -1
- package/dist/src/ruvector/diskann-backend.js.map +0 -1
- package/dist/src/ruvector/enhanced-model-router.d.ts.map +0 -1
- package/dist/src/ruvector/enhanced-model-router.js.map +0 -1
- package/dist/src/ruvector/graph-analyzer.d.ts.map +0 -1
- package/dist/src/ruvector/graph-analyzer.js.map +0 -1
- package/dist/src/ruvector/graph-backend.d.ts.map +0 -1
- package/dist/src/ruvector/graph-backend.js.map +0 -1
- package/dist/src/ruvector/index.d.ts.map +0 -1
- package/dist/src/ruvector/index.js.map +0 -1
- package/dist/src/ruvector/lora-adapter.d.ts.map +0 -1
- package/dist/src/ruvector/lora-adapter.js.map +0 -1
- package/dist/src/ruvector/model-prices.d.ts.map +0 -1
- package/dist/src/ruvector/model-prices.js.map +0 -1
- package/dist/src/ruvector/model-router.d.ts.map +0 -1
- package/dist/src/ruvector/model-router.js.map +0 -1
- package/dist/src/ruvector/neural-router.d.ts.map +0 -1
- package/dist/src/ruvector/neural-router.js.map +0 -1
- package/dist/src/ruvector/output-verifier.d.ts.map +0 -1
- package/dist/src/ruvector/output-verifier.js.map +0 -1
- package/dist/src/ruvector/q-learning-router.d.ts.map +0 -1
- package/dist/src/ruvector/q-learning-router.js.map +0 -1
- package/dist/src/ruvector/router-calibrator.d.ts.map +0 -1
- package/dist/src/ruvector/router-calibrator.js.map +0 -1
- package/dist/src/ruvector/router-parallel-recorder.d.ts.map +0 -1
- package/dist/src/ruvector/router-parallel-recorder.js.map +0 -1
- package/dist/src/ruvector/router-trajectory.d.ts.map +0 -1
- package/dist/src/ruvector/router-trajectory.js.map +0 -1
- package/dist/src/ruvector/run-transcript-recorder.d.ts.map +0 -1
- package/dist/src/ruvector/run-transcript-recorder.js.map +0 -1
- package/dist/src/ruvector/ruvllm-wasm.d.ts.map +0 -1
- package/dist/src/ruvector/ruvllm-wasm.js.map +0 -1
- package/dist/src/ruvector/semantic-router.d.ts.map +0 -1
- package/dist/src/ruvector/semantic-router.js.map +0 -1
- package/dist/src/ruvector/task-embedder.d.ts.map +0 -1
- package/dist/src/ruvector/task-embedder.js.map +0 -1
- package/dist/src/ruvector/trajectory-tree.d.ts.map +0 -1
- package/dist/src/ruvector/trajectory-tree.js.map +0 -1
- package/dist/src/ruvector/vector-db.d.ts.map +0 -1
- package/dist/src/ruvector/vector-db.js.map +0 -1
- package/dist/src/services/agentic-flow-bridge.d.ts.map +0 -1
- package/dist/src/services/agentic-flow-bridge.js.map +0 -1
- package/dist/src/services/checkpoint-gate.d.ts.map +0 -1
- package/dist/src/services/checkpoint-gate.js.map +0 -1
- package/dist/src/services/claim-service.d.ts.map +0 -1
- package/dist/src/services/claim-service.js.map +0 -1
- package/dist/src/services/config-file-manager.d.ts.map +0 -1
- package/dist/src/services/config-file-manager.js.map +0 -1
- package/dist/src/services/container-worker-pool.d.ts.map +0 -1
- package/dist/src/services/container-worker-pool.js.map +0 -1
- package/dist/src/services/distill-oracle.d.ts.map +0 -1
- package/dist/src/services/distill-oracle.js.map +0 -1
- package/dist/src/services/fable-harness.d.ts.map +0 -1
- package/dist/src/services/fable-harness.js.map +0 -1
- package/dist/src/services/headless-worker-executor.d.ts.map +0 -1
- package/dist/src/services/headless-worker-executor.js.map +0 -1
- package/dist/src/services/index.d.ts.map +0 -1
- package/dist/src/services/index.js.map +0 -1
- package/dist/src/services/native-training.d.ts.map +0 -1
- package/dist/src/services/native-training.js.map +0 -1
- package/dist/src/services/registry-api.d.ts.map +0 -1
- package/dist/src/services/registry-api.js.map +0 -1
- package/dist/src/services/ruvector-training.d.ts.map +0 -1
- package/dist/src/services/ruvector-training.js.map +0 -1
- package/dist/src/services/swarm-memory-branches.d.ts.map +0 -1
- package/dist/src/services/swarm-memory-branches.js.map +0 -1
- package/dist/src/services/weight-eft.d.ts.map +0 -1
- package/dist/src/services/weight-eft.js.map +0 -1
- package/dist/src/services/worker-daemon.d.ts.map +0 -1
- package/dist/src/services/worker-daemon.js.map +0 -1
- package/dist/src/services/worker-queue.d.ts.map +0 -1
- package/dist/src/services/worker-queue.js.map +0 -1
- package/dist/src/suggest.d.ts.map +0 -1
- package/dist/src/suggest.js.map +0 -1
- package/dist/src/transfer/anonymization/index.d.ts.map +0 -1
- package/dist/src/transfer/anonymization/index.js.map +0 -1
- package/dist/src/transfer/deploy-seraphine.d.ts.map +0 -1
- package/dist/src/transfer/deploy-seraphine.js.map +0 -1
- package/dist/src/transfer/export.d.ts.map +0 -1
- package/dist/src/transfer/export.js.map +0 -1
- package/dist/src/transfer/index.d.ts.map +0 -1
- package/dist/src/transfer/index.js.map +0 -1
- package/dist/src/transfer/ipfs/client.d.ts.map +0 -1
- package/dist/src/transfer/ipfs/client.js.map +0 -1
- package/dist/src/transfer/ipfs/upload.d.ts.map +0 -1
- package/dist/src/transfer/ipfs/upload.js.map +0 -1
- package/dist/src/transfer/models/seraphine.d.ts.map +0 -1
- package/dist/src/transfer/models/seraphine.js.map +0 -1
- package/dist/src/transfer/serialization/cfp.d.ts.map +0 -1
- package/dist/src/transfer/serialization/cfp.js.map +0 -1
- package/dist/src/transfer/storage/gcs.d.ts.map +0 -1
- package/dist/src/transfer/storage/gcs.js.map +0 -1
- package/dist/src/transfer/storage/index.d.ts.map +0 -1
- package/dist/src/transfer/storage/index.js.map +0 -1
- package/dist/src/transfer/store/discovery.d.ts.map +0 -1
- package/dist/src/transfer/store/discovery.js.map +0 -1
- package/dist/src/transfer/store/download.d.ts.map +0 -1
- package/dist/src/transfer/store/download.js.map +0 -1
- package/dist/src/transfer/store/index.d.ts.map +0 -1
- package/dist/src/transfer/store/index.js.map +0 -1
- package/dist/src/transfer/store/publish.d.ts.map +0 -1
- package/dist/src/transfer/store/publish.js.map +0 -1
- package/dist/src/transfer/store/registry.d.ts.map +0 -1
- package/dist/src/transfer/store/registry.js.map +0 -1
- package/dist/src/transfer/store/search.d.ts.map +0 -1
- package/dist/src/transfer/store/search.js.map +0 -1
- package/dist/src/transfer/store/tests/standalone-test.d.ts.map +0 -1
- package/dist/src/transfer/store/tests/standalone-test.js.map +0 -1
- package/dist/src/transfer/store/types.d.ts.map +0 -1
- package/dist/src/transfer/store/types.js.map +0 -1
- package/dist/src/transfer/test-seraphine.d.ts.map +0 -1
- package/dist/src/transfer/test-seraphine.js.map +0 -1
- package/dist/src/transfer/tests/test-store.d.ts.map +0 -1
- package/dist/src/transfer/tests/test-store.js.map +0 -1
- package/dist/src/transfer/types.d.ts.map +0 -1
- package/dist/src/transfer/types.js.map +0 -1
- package/dist/src/types.d.ts.map +0 -1
- package/dist/src/types.js.map +0 -1
- package/dist/src/update/checker.d.ts.map +0 -1
- package/dist/src/update/checker.js.map +0 -1
- package/dist/src/update/executor.d.ts.map +0 -1
- package/dist/src/update/executor.js.map +0 -1
- package/dist/src/update/index.d.ts.map +0 -1
- package/dist/src/update/index.js.map +0 -1
- package/dist/src/update/rate-limiter.d.ts.map +0 -1
- package/dist/src/update/rate-limiter.js.map +0 -1
- package/dist/src/update/validator.d.ts.map +0 -1
- package/dist/src/update/validator.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/scripts/beir-bootstrap-significance.mjs +0 -162
- package/scripts/bench-rvagent.mjs +0 -312
- package/scripts/benchmark-codemods.mjs +0 -127
- package/scripts/benchmark-cross-repo.mjs +0 -206
- package/scripts/benchmark-pretrained-retrieval.mjs +0 -305
- package/scripts/benchmark-self-learning.mjs +0 -241
- package/scripts/benchmark-trajectory-mrr.mjs +0 -191
- package/scripts/deploy-ipfs-node.sh +0 -153
- package/scripts/grid-search-retrieval.mjs +0 -216
- package/scripts/pretrain-from-github.mjs +0 -358
- package/scripts/publish-registry.ts +0 -345
- package/scripts/publish.sh +0 -57
- package/scripts/run-beir-bge.mjs +0 -324
- package/scripts/run-beir-hybrid.mjs +0 -284
- package/scripts/run-beir-lucene-bm25.mjs +0 -154
- package/scripts/run-beir-nfcorpus.mjs +0 -231
- package/scripts/run-beir-rrf-ablation.mjs +0 -221
- package/scripts/setup-ipfs-registry.md +0 -366
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// run-beir-lucene-bm25.mjs — test our Lucene-style BM25 against the
|
|
3
|
-
// published BEIR BM25 baselines. Also runs RRF with Lucene-BM25 + dense
|
|
4
|
-
// to see if the stronger BM25 closes the asymmetric-strength gap that
|
|
5
|
-
// broke RRF in ADR-087.
|
|
6
|
-
//
|
|
7
|
-
// Usage:
|
|
8
|
-
// cd /tmp/beir-nfcorpus
|
|
9
|
-
// node /path/to/scripts/run-beir-lucene-bm25.mjs
|
|
10
|
-
// BEIR_DATA_DIR=/tmp/beir-scifact/scifact node /path/to/scripts/run-beir-lucene-bm25.mjs
|
|
11
|
-
|
|
12
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
13
|
-
import { fileURLToPath } from 'node:url';
|
|
14
|
-
import { dirname, join, resolve } from 'node:path';
|
|
15
|
-
import { performance } from 'node:perf_hooks';
|
|
16
|
-
|
|
17
|
-
const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
|
|
18
|
-
const CLI_ROOT = resolve(SCRIPT_DIR, '..');
|
|
19
|
-
const RUFLO_ROOT = resolve(SCRIPT_DIR, '../../../..');
|
|
20
|
-
const RUNS_DIR = join(RUFLO_ROOT, 'docs', 'benchmarks', 'runs');
|
|
21
|
-
|
|
22
|
-
const DATA_DIR = process.env.BEIR_DATA_DIR || '/tmp/beir-nfcorpus/nfcorpus';
|
|
23
|
-
const BGE_MODEL = 'Xenova/bge-base-en-v1.5';
|
|
24
|
-
const CACHE_DIR = join(dirname(DATA_DIR), 'bge-cache');
|
|
25
|
-
|
|
26
|
-
const BASELINES = {
|
|
27
|
-
nfcorpus: { BM25: 0.325, 'BGE-large-pub': 0.380, 'SPLADE++': 0.347 },
|
|
28
|
-
scifact: { BM25: 0.679, 'BGE-large-pub': 0.722, 'SPLADE++': 0.704 },
|
|
29
|
-
};
|
|
30
|
-
function detect(p) { const x = p.toLowerCase(); return Object.keys(BASELINES).find(d => x.includes(d)) || 'nfcorpus'; }
|
|
31
|
-
|
|
32
|
-
function dcg(rels, k) { let s = 0; for (let i = 0; i < Math.min(rels.length, k); i++) s += (Math.pow(2, rels[i]) - 1) / Math.log2(i + 2); return s; }
|
|
33
|
-
function ndcg(retrieved, qrels, k) { const rels = retrieved.slice(0, k).map((id) => qrels.get(id) ?? 0); const ideal = [...qrels.values()].sort((a, b) => b - a).slice(0, k); const idcg = dcg(ideal, k); return idcg > 0 ? dcg(rels, k) / idcg : 0; }
|
|
34
|
-
function recall(retrieved, qrels, k) { const tot = [...qrels.values()].filter((v) => v > 0).length; if (tot === 0) return 0; let h = 0; for (let i = 0; i < Math.min(retrieved.length, k); i++) if ((qrels.get(retrieved[i]) ?? 0) > 0) h++; return h / tot; }
|
|
35
|
-
function cosine(a, b) { let s = 0; for (let i = 0; i < a.length; i++) s += a[i] * b[i]; return s; }
|
|
36
|
-
|
|
37
|
-
function loadJsonl(p) { return readFileSync(p, 'utf-8').split('\n').filter(Boolean).map((l) => JSON.parse(l)); }
|
|
38
|
-
function loadQrels(p) { const q = new Map(); const lines = readFileSync(p, 'utf-8').split('\n'); for (let i = 1; i < lines.length; i++) { if (!lines[i].trim()) continue; const [qid, did, s] = lines[i].split('\t'); if (!q.has(qid)) q.set(qid, new Map()); q.get(qid).set(did, Number(s)); } return q; }
|
|
39
|
-
|
|
40
|
-
function cachePath(s) { const safe = BGE_MODEL.replace(/\//g, '_'); return join(CACHE_DIR, `${safe}.${s}`); }
|
|
41
|
-
function loadEmbeddings(dim) {
|
|
42
|
-
if (!existsSync(cachePath('ids')) || !existsSync(cachePath('f32'))) return null;
|
|
43
|
-
const ids = readFileSync(cachePath('ids'), 'utf-8').split('\n').filter(Boolean);
|
|
44
|
-
const raw = readFileSync(cachePath('f32'));
|
|
45
|
-
const buf = new Float32Array(raw.buffer, raw.byteOffset, raw.length / 4);
|
|
46
|
-
return { ids, embeds: ids.map((_, i) => buf.slice(i * dim, (i + 1) * dim)) };
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function rrfFuse(rankings, k = 60, weights) {
|
|
50
|
-
const scores = new Map();
|
|
51
|
-
rankings.forEach((ranking, sIdx) => {
|
|
52
|
-
const w = weights?.[sIdx] ?? 1;
|
|
53
|
-
ranking.forEach((doc, rankIdx) => {
|
|
54
|
-
const rank = rankIdx + 1;
|
|
55
|
-
scores.set(doc.id, (scores.get(doc.id) ?? 0) + w / (k + rank));
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
return [...scores.entries()].map(([id, score]) => ({ id, score })).sort((a, b) => b.score - a.score);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async function main() {
|
|
62
|
-
const dataset = detect(DATA_DIR);
|
|
63
|
-
console.log(`# Lucene-style BM25 + RRF on BEIR ${dataset} (ADR-088)`);
|
|
64
|
-
console.log(`Data: ${DATA_DIR}\n`);
|
|
65
|
-
|
|
66
|
-
const corpus = loadJsonl(join(DATA_DIR, 'corpus.jsonl'));
|
|
67
|
-
const queries = loadJsonl(join(DATA_DIR, 'queries.jsonl'));
|
|
68
|
-
const qrels = loadQrels(join(DATA_DIR, 'qrels/test.tsv'));
|
|
69
|
-
console.log(`Corpus: ${corpus.length} · test qrels: ${qrels.size}`);
|
|
70
|
-
|
|
71
|
-
// Lucene BM25
|
|
72
|
-
const { luceneTokenize, buildLuceneCorpusStats, luceneBM25 } = await import(join(CLI_ROOT, 'dist/src/memory/lucene-bm25.js'));
|
|
73
|
-
console.log('\nTokenising corpus (Lucene-style: Porter stem + Lucene stopwords + length norm)...');
|
|
74
|
-
const tIngest = performance.now();
|
|
75
|
-
const docs = corpus.map((d) => luceneTokenize(`${d.title || ''} ${d.text || ''}`));
|
|
76
|
-
const stats = buildLuceneCorpusStats(docs);
|
|
77
|
-
console.log(`Tokenized + stats built in ${((performance.now() - tIngest) / 1000).toFixed(1)}s. avgDocLen=${stats.avgDocLen.toFixed(0)}, vocab=${stats.idf.size}`);
|
|
78
|
-
|
|
79
|
-
// BGE dense (from cache)
|
|
80
|
-
const bge = await import(join(CLI_ROOT, 'dist/src/memory/bge-embedder.js'));
|
|
81
|
-
const emb = await bge.getBgeEmbedder(BGE_MODEL);
|
|
82
|
-
if (!emb) { console.error('BGE failed'); process.exit(1); }
|
|
83
|
-
const cached = loadEmbeddings(emb.dim());
|
|
84
|
-
if (!cached) { console.error(`No cached embeddings. Run run-beir-bge.mjs first.`); process.exit(2); }
|
|
85
|
-
const { ids: docIds, embeds: docEmbeds } = cached;
|
|
86
|
-
const corpusIdxToId = corpus.map((d) => d._id);
|
|
87
|
-
|
|
88
|
-
// Run all configs
|
|
89
|
-
const queriesById = new Map(queries.map((q) => [q._id, q.text]));
|
|
90
|
-
const evalQids = [...qrels.keys()];
|
|
91
|
-
console.log(`\nRunning ${evalQids.length} queries through 4 configs (dense, Lucene-BM25, RRF, RRF-tuned)...\n`);
|
|
92
|
-
|
|
93
|
-
let n = 0;
|
|
94
|
-
const results = {
|
|
95
|
-
dense: { n: 0, ndcg: 0, r10: 0, r100: 0 },
|
|
96
|
-
bm25: { n: 0, ndcg: 0, r10: 0, r100: 0 },
|
|
97
|
-
rrf60: { n: 0, ndcg: 0, r10: 0, r100: 0 },
|
|
98
|
-
rrf30: { n: 0, ndcg: 0, r10: 0, r100: 0 },
|
|
99
|
-
};
|
|
100
|
-
const tQ = performance.now();
|
|
101
|
-
for (const qid of evalQids) {
|
|
102
|
-
const qtext = queriesById.get(qid);
|
|
103
|
-
if (!qtext) continue;
|
|
104
|
-
n++;
|
|
105
|
-
|
|
106
|
-
// Dense
|
|
107
|
-
const qEmb = await emb.embed(qtext);
|
|
108
|
-
const dense = docIds.map((id, i) => ({ id, score: cosine(qEmb, docEmbeds[i]) })).sort((a, b) => b.score - a.score).slice(0, 1000);
|
|
109
|
-
|
|
110
|
-
// BM25
|
|
111
|
-
const qTokens = luceneTokenize(qtext);
|
|
112
|
-
const bm25 = corpus.map((d, i) => ({ id: corpusIdxToId[i], score: luceneBM25(qTokens, docs[i], stats) })).filter((d) => d.score > 0).sort((a, b) => b.score - a.score).slice(0, 1000);
|
|
113
|
-
|
|
114
|
-
// RRF k=60 and k=30
|
|
115
|
-
const rrf60 = rrfFuse([dense, bm25], 60);
|
|
116
|
-
const rrf30 = rrfFuse([dense, bm25], 30);
|
|
117
|
-
|
|
118
|
-
const qmap = qrels.get(qid);
|
|
119
|
-
for (const [key, top] of [['dense', dense], ['bm25', bm25], ['rrf60', rrf60], ['rrf30', rrf30]]) {
|
|
120
|
-
const top100 = top.slice(0, 100).map((s) => s.id);
|
|
121
|
-
results[key].n++;
|
|
122
|
-
results[key].ndcg += ndcg(top100, qmap, 10);
|
|
123
|
-
results[key].r10 += recall(top100, qmap, 10);
|
|
124
|
-
results[key].r100 += recall(top100, qmap, 100);
|
|
125
|
-
}
|
|
126
|
-
if (n % 50 === 0) console.log(` ${n}/${evalQids.length} dense=${(results.dense.ndcg / results.dense.n).toFixed(3)} bm25=${(results.bm25.ndcg / results.bm25.n).toFixed(3)} rrf60=${(results.rrf60.ndcg / results.rrf60.n).toFixed(3)}`);
|
|
127
|
-
}
|
|
128
|
-
const elapsed = (performance.now() - tQ) / 1000;
|
|
129
|
-
|
|
130
|
-
console.log(`\nDone in ${elapsed.toFixed(0)}s.\n`);
|
|
131
|
-
console.log('Config | nDCG@10 R@10 R@100 vs published-BM25');
|
|
132
|
-
console.log('---------------|---------------------------------');
|
|
133
|
-
for (const [key, r] of Object.entries(results)) {
|
|
134
|
-
const score = r.ndcg / r.n;
|
|
135
|
-
const delta = score - BASELINES[dataset].BM25;
|
|
136
|
-
console.log(`${key.padEnd(14)} | ${score.toFixed(4)} ${(r.r10 / r.n).toFixed(3)} ${(r.r100 / r.n).toFixed(3)} ${(delta >= 0 ? '+' : '') + delta.toFixed(4)}`);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const summary = {
|
|
140
|
-
runAt: new Date().toISOString(),
|
|
141
|
-
benchmark: `beir-${dataset}-lucene-bm25`,
|
|
142
|
-
dataset, model: BGE_MODEL, queries: n,
|
|
143
|
-
results: Object.fromEntries(Object.entries(results).map(([k, v]) => [k, { ndcg10: v.ndcg / v.n, recall10: v.r10 / v.n, recall100: v.r100 / v.n }])),
|
|
144
|
-
baselines: BASELINES[dataset],
|
|
145
|
-
};
|
|
146
|
-
mkdirSync(RUNS_DIR, { recursive: true });
|
|
147
|
-
const stamp = summary.runAt.replace(/[:.]/g, '-');
|
|
148
|
-
writeFileSync(join(RUNS_DIR, `beir-${dataset}-lucene-bm25-${stamp}.json`), JSON.stringify(summary, null, 2));
|
|
149
|
-
writeFileSync(join(RUNS_DIR, `beir-${dataset}-lucene-bm25-latest.json`), JSON.stringify(summary, null, 2));
|
|
150
|
-
console.log(`\nWrote ${join(RUNS_DIR, `beir-${dataset}-lucene-bm25-${stamp}.json`)}`);
|
|
151
|
-
process.exit(0);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
main().catch((err) => { console.error(err); process.exit(1); });
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// run-beir-nfcorpus.mjs — public benchmark harness for BEIR NFCorpus.
|
|
3
|
-
//
|
|
4
|
-
// Why NFCorpus: smallest BEIR dataset (3.6k docs, 323 test queries) with a
|
|
5
|
-
// well-published BM25 baseline and dense-retriever ceilings — runs end-to-end
|
|
6
|
-
// in <15 min on this hardware.
|
|
7
|
-
//
|
|
8
|
-
// Setup:
|
|
9
|
-
// mkdir -p /tmp/beir-nfcorpus && cd /tmp/beir-nfcorpus
|
|
10
|
-
// curl -sL -o nfcorpus.zip 'https://public.ukp.informatik.tu-darmstadt.de/thakur/BEIR/datasets/nfcorpus.zip'
|
|
11
|
-
// unzip -q nfcorpus.zip
|
|
12
|
-
//
|
|
13
|
-
// Run:
|
|
14
|
-
// cd /tmp/beir-nfcorpus && rm -rf .claude-flow
|
|
15
|
-
// node /path/to/scripts/run-beir-nfcorpus.mjs
|
|
16
|
-
//
|
|
17
|
-
// Reports:
|
|
18
|
-
// - nDCG@10 (graded, BEIR standard)
|
|
19
|
-
// - MRR@10
|
|
20
|
-
// - Recall@10, Recall@100
|
|
21
|
-
// - Published comparisons (BM25, ColBERT, SPLADE, etc.)
|
|
22
|
-
|
|
23
|
-
import { readFileSync, writeFileSync, mkdirSync, readdirSync, statSync } from 'node:fs';
|
|
24
|
-
import { fileURLToPath } from 'node:url';
|
|
25
|
-
import { dirname, join, resolve } from 'node:path';
|
|
26
|
-
import { performance } from 'node:perf_hooks';
|
|
27
|
-
|
|
28
|
-
const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
|
|
29
|
-
const CLI_ROOT = resolve(SCRIPT_DIR, '..');
|
|
30
|
-
const RUFLO_ROOT = resolve(SCRIPT_DIR, '../../../..');
|
|
31
|
-
const RUNS_DIR = join(RUFLO_ROOT, 'docs', 'benchmarks', 'runs');
|
|
32
|
-
|
|
33
|
-
const DATA_DIR = process.env.BEIR_DATA_DIR || '/tmp/beir-nfcorpus/nfcorpus';
|
|
34
|
-
const TOP_K = Number(process.env.TOP_K) || 100; // top-100 for recall@100
|
|
35
|
-
const NDCG_K = 10;
|
|
36
|
-
const MAX_QUERIES = Number(process.env.MAX_QUERIES) || 0; // 0 = all
|
|
37
|
-
const SKIP_INGEST = process.env.SKIP_INGEST === '1'; // reuse existing store
|
|
38
|
-
|
|
39
|
-
// Published BEIR NFCorpus baselines (from Thakur et al. 2021 + leaderboard tracker)
|
|
40
|
-
const BASELINES_NDCG10 = {
|
|
41
|
-
'BM25': 0.325,
|
|
42
|
-
'DocT5query': 0.328,
|
|
43
|
-
'SBERT (msmarco)': 0.272, // dense bi-encoder on MS MARCO
|
|
44
|
-
'TAS-B': 0.319,
|
|
45
|
-
'GenQ': 0.319,
|
|
46
|
-
'ColBERT': 0.305,
|
|
47
|
-
'SPLADE++': 0.347, // top dense at time of paper
|
|
48
|
-
'Contriever': 0.328,
|
|
49
|
-
'GTR-XL': 0.343,
|
|
50
|
-
'BGE-large-v1.5': 0.380, // current ~top-of-class
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// ---------------------------------------------------------------------------
|
|
54
|
-
// nDCG with graded relevance (BEIR standard)
|
|
55
|
-
// ---------------------------------------------------------------------------
|
|
56
|
-
|
|
57
|
-
function dcg(rels, k) {
|
|
58
|
-
let s = 0;
|
|
59
|
-
for (let i = 0; i < Math.min(rels.length, k); i++) {
|
|
60
|
-
s += (Math.pow(2, rels[i]) - 1) / Math.log2(i + 2);
|
|
61
|
-
}
|
|
62
|
-
return s;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function ndcg(retrievedDocIds, qrelsMap, k) {
|
|
66
|
-
const rels = retrievedDocIds.slice(0, k).map((id) => qrelsMap.get(id) ?? 0);
|
|
67
|
-
const ideal = [...qrelsMap.values()].sort((a, b) => b - a).slice(0, k);
|
|
68
|
-
const idcg = dcg(ideal, k);
|
|
69
|
-
return idcg > 0 ? dcg(rels, k) / idcg : 0;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function mrr(retrievedDocIds, qrelsMap, k) {
|
|
73
|
-
for (let i = 0; i < Math.min(retrievedDocIds.length, k); i++) {
|
|
74
|
-
if ((qrelsMap.get(retrievedDocIds[i]) ?? 0) > 0) return 1 / (i + 1);
|
|
75
|
-
}
|
|
76
|
-
return 0;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function recall(retrievedDocIds, qrelsMap, k) {
|
|
80
|
-
const totalRelevant = [...qrelsMap.values()].filter((v) => v > 0).length;
|
|
81
|
-
if (totalRelevant === 0) return 0;
|
|
82
|
-
let hit = 0;
|
|
83
|
-
for (let i = 0; i < Math.min(retrievedDocIds.length, k); i++) {
|
|
84
|
-
if ((qrelsMap.get(retrievedDocIds[i]) ?? 0) > 0) hit++;
|
|
85
|
-
}
|
|
86
|
-
return hit / totalRelevant;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// ---------------------------------------------------------------------------
|
|
90
|
-
// Loaders
|
|
91
|
-
// ---------------------------------------------------------------------------
|
|
92
|
-
|
|
93
|
-
function loadJsonl(path) {
|
|
94
|
-
const items = [];
|
|
95
|
-
for (const line of readFileSync(path, 'utf-8').split('\n')) {
|
|
96
|
-
if (!line.trim()) continue;
|
|
97
|
-
items.push(JSON.parse(line));
|
|
98
|
-
}
|
|
99
|
-
return items;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function loadQrels(path) {
|
|
103
|
-
// Map<queryId, Map<docId, grade>>
|
|
104
|
-
const qrels = new Map();
|
|
105
|
-
const lines = readFileSync(path, 'utf-8').split('\n');
|
|
106
|
-
for (let i = 1; i < lines.length; i++) {
|
|
107
|
-
if (!lines[i].trim()) continue;
|
|
108
|
-
const [qid, did, score] = lines[i].split('\t');
|
|
109
|
-
if (!qrels.has(qid)) qrels.set(qid, new Map());
|
|
110
|
-
qrels.get(qid).set(did, Number(score));
|
|
111
|
-
}
|
|
112
|
-
return qrels;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// ---------------------------------------------------------------------------
|
|
116
|
-
// Main
|
|
117
|
-
// ---------------------------------------------------------------------------
|
|
118
|
-
|
|
119
|
-
async function main() {
|
|
120
|
-
console.log(`# BEIR NFCorpus benchmark (ADR-085)`);
|
|
121
|
-
console.log(`Data: ${DATA_DIR}`);
|
|
122
|
-
console.log(`Cwd: ${process.cwd()}`);
|
|
123
|
-
|
|
124
|
-
const corpus = loadJsonl(join(DATA_DIR, 'corpus.jsonl'));
|
|
125
|
-
const queries = loadJsonl(join(DATA_DIR, 'queries.jsonl'));
|
|
126
|
-
const qrels = loadQrels(join(DATA_DIR, 'qrels/test.tsv'));
|
|
127
|
-
|
|
128
|
-
console.log(`Corpus: ${corpus.length} docs, ${queries.length} queries (total), ${qrels.size} eval queries (test split)`);
|
|
129
|
-
|
|
130
|
-
const neural = await import(join(CLI_ROOT, 'dist/src/mcp-tools/neural-tools.js'));
|
|
131
|
-
const tool = neural.neuralTools.find((t) => t.name === 'neural_patterns');
|
|
132
|
-
|
|
133
|
-
// §1 — Ingest corpus (id-stable pattern name = doc _id; content = title + text).
|
|
134
|
-
// Skip if SKIP_INGEST=1 and store already populated.
|
|
135
|
-
if (!SKIP_INGEST) {
|
|
136
|
-
console.log(`\nIngesting ${corpus.length} docs...`);
|
|
137
|
-
const t0 = performance.now();
|
|
138
|
-
// Batch in chunks to avoid memory pressure.
|
|
139
|
-
const CHUNK = 200;
|
|
140
|
-
for (let i = 0; i < corpus.length; i += CHUNK) {
|
|
141
|
-
const batch = corpus.slice(i, i + CHUNK);
|
|
142
|
-
await neural.storeNeuralPatterns(batch.map((d) => ({
|
|
143
|
-
name: d._id, // use _id as the stable identifier
|
|
144
|
-
type: 'beir-nfcorpus',
|
|
145
|
-
content: `${d.title || ''}\n${d.text || ''}`.slice(0, 4096),
|
|
146
|
-
})));
|
|
147
|
-
if ((i + CHUNK) % 1000 === 0 || i + CHUNK >= corpus.length) {
|
|
148
|
-
const pct = Math.min(100, ((i + CHUNK) / corpus.length * 100)).toFixed(0);
|
|
149
|
-
const elapsed = (performance.now() - t0) / 1000;
|
|
150
|
-
console.log(` ${Math.min(i + CHUNK, corpus.length)}/${corpus.length} (${pct}%) in ${elapsed.toFixed(0)}s`);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
console.log(`Ingest done in ${((performance.now() - t0) / 1000).toFixed(0)}s`);
|
|
154
|
-
} else {
|
|
155
|
-
console.log('SKIP_INGEST=1 → reusing existing store');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// §2 — Build query lookup (eval queries only).
|
|
159
|
-
const queriesById = new Map(queries.map((q) => [q._id, q.text]));
|
|
160
|
-
const evalQueryIds = MAX_QUERIES
|
|
161
|
-
? [...qrels.keys()].slice(0, MAX_QUERIES)
|
|
162
|
-
: [...qrels.keys()];
|
|
163
|
-
|
|
164
|
-
// §3 — Run retrieval for each query, compute metrics.
|
|
165
|
-
console.log(`\nRunning ${evalQueryIds.length} queries...`);
|
|
166
|
-
let ndcgSum = 0, mrrSum = 0, recall10Sum = 0, recall100Sum = 0;
|
|
167
|
-
const tQ = performance.now();
|
|
168
|
-
let queryIdx = 0;
|
|
169
|
-
for (const qid of evalQueryIds) {
|
|
170
|
-
const qtext = queriesById.get(qid);
|
|
171
|
-
if (!qtext) { queryIdx++; continue; }
|
|
172
|
-
const r = await tool.handler({ action: 'search', query: qtext, mode: 'hybrid', limit: TOP_K, rerank: false });
|
|
173
|
-
const retrievedIds = (r.results || []).map((m) => m.name); // we set name = _id
|
|
174
|
-
const qrelsMap = qrels.get(qid) || new Map();
|
|
175
|
-
ndcgSum += ndcg(retrievedIds, qrelsMap, NDCG_K);
|
|
176
|
-
mrrSum += mrr(retrievedIds, qrelsMap, NDCG_K);
|
|
177
|
-
recall10Sum += recall(retrievedIds, qrelsMap, 10);
|
|
178
|
-
recall100Sum += recall(retrievedIds, qrelsMap, 100);
|
|
179
|
-
queryIdx++;
|
|
180
|
-
if (queryIdx % 50 === 0) {
|
|
181
|
-
const elapsed = (performance.now() - tQ) / 1000;
|
|
182
|
-
console.log(` ${queryIdx}/${evalQueryIds.length} in ${elapsed.toFixed(0)}s — running nDCG@10=${(ndcgSum / queryIdx).toFixed(4)}`);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
const queryMs = performance.now() - tQ;
|
|
186
|
-
const N = evalQueryIds.length;
|
|
187
|
-
const ndcg10 = ndcgSum / N;
|
|
188
|
-
const mrr10 = mrrSum / N;
|
|
189
|
-
const recall10 = recall10Sum / N;
|
|
190
|
-
const recall100 = recall100Sum / N;
|
|
191
|
-
|
|
192
|
-
console.log(`\n=== Results (N=${N} queries) ===`);
|
|
193
|
-
console.log(` nDCG@10: ${ndcg10.toFixed(4)}`);
|
|
194
|
-
console.log(` MRR@10: ${mrr10.toFixed(4)}`);
|
|
195
|
-
console.log(` Recall@10: ${recall10.toFixed(4)}`);
|
|
196
|
-
console.log(` Recall@100: ${recall100.toFixed(4)}`);
|
|
197
|
-
console.log(` Avg query latency: ${(queryMs / N).toFixed(0)}ms`);
|
|
198
|
-
|
|
199
|
-
console.log(`\n=== vs published NFCorpus nDCG@10 baselines ===`);
|
|
200
|
-
const ourEntry = { name: 'ruflo hybrid (3.10.25)', score: ndcg10, ours: true };
|
|
201
|
-
const ranking = [
|
|
202
|
-
...Object.entries(BASELINES_NDCG10).map(([name, score]) => ({ name, score, ours: false })),
|
|
203
|
-
ourEntry,
|
|
204
|
-
].sort((a, b) => b.score - a.score);
|
|
205
|
-
for (const r of ranking) {
|
|
206
|
-
const marker = r.ours ? ' ← us' : '';
|
|
207
|
-
console.log(` ${r.score.toFixed(3)} ${r.name}${marker}`);
|
|
208
|
-
}
|
|
209
|
-
const ourRank = ranking.findIndex((r) => r.ours) + 1;
|
|
210
|
-
console.log(`\n Our rank: ${ourRank} / ${ranking.length}`);
|
|
211
|
-
|
|
212
|
-
const summary = {
|
|
213
|
-
runAt: new Date().toISOString(),
|
|
214
|
-
benchmark: 'beir-nfcorpus',
|
|
215
|
-
queries: N,
|
|
216
|
-
corpusSize: corpus.length,
|
|
217
|
-
metrics: { ndcg10, mrr10, recall10, recall100, avgQueryLatencyMs: queryMs / N },
|
|
218
|
-
baselines: BASELINES_NDCG10,
|
|
219
|
-
ourRank,
|
|
220
|
-
leaderboardLength: ranking.length,
|
|
221
|
-
};
|
|
222
|
-
mkdirSync(RUNS_DIR, { recursive: true });
|
|
223
|
-
const stamp = summary.runAt.replace(/[:.]/g, '-');
|
|
224
|
-
writeFileSync(join(RUNS_DIR, `beir-nfcorpus-${stamp}.json`), JSON.stringify(summary, null, 2));
|
|
225
|
-
writeFileSync(join(RUNS_DIR, 'beir-nfcorpus-latest.json'), JSON.stringify(summary, null, 2));
|
|
226
|
-
console.log(`\nWrote ${join(RUNS_DIR, `beir-nfcorpus-${stamp}.json`)}`);
|
|
227
|
-
|
|
228
|
-
process.exit(0);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
main().catch((err) => { console.error(err); process.exit(1); });
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// run-beir-rrf-ablation.mjs — RRF weight/k ablation matrix on a single
|
|
3
|
-
// BEIR dataset (ADR-087).
|
|
4
|
-
//
|
|
5
|
-
// Pre-requisite: BGE doc embeddings cached at <dataset>/bge-cache/
|
|
6
|
-
// (run scripts/run-beir-bge.mjs first).
|
|
7
|
-
//
|
|
8
|
-
// Reports:
|
|
9
|
-
// - Fixed default: k=60, equal weights (the headline number we ship)
|
|
10
|
-
// - Ablations: k=30/60/120 × weights (0.8/1.0, 1.0/1.0, 1.2/0.8 dense/bm25)
|
|
11
|
-
// - Bootstrap 95% CI on the fixed-default config only
|
|
12
|
-
//
|
|
13
|
-
// Usage:
|
|
14
|
-
// cd /tmp/beir-nfcorpus
|
|
15
|
-
// node /path/to/scripts/run-beir-rrf-ablation.mjs
|
|
16
|
-
// cd /tmp/beir-scifact
|
|
17
|
-
// BEIR_DATA_DIR=/tmp/beir-scifact/scifact node /path/to/scripts/run-beir-rrf-ablation.mjs
|
|
18
|
-
|
|
19
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
20
|
-
import { fileURLToPath } from 'node:url';
|
|
21
|
-
import { dirname, join, resolve } from 'node:path';
|
|
22
|
-
import { performance } from 'node:perf_hooks';
|
|
23
|
-
|
|
24
|
-
const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
|
|
25
|
-
const CLI_ROOT = resolve(SCRIPT_DIR, '..');
|
|
26
|
-
const RUFLO_ROOT = resolve(SCRIPT_DIR, '../../../..');
|
|
27
|
-
const RUNS_DIR = join(RUFLO_ROOT, 'docs', 'benchmarks', 'runs');
|
|
28
|
-
|
|
29
|
-
const DATA_DIR = process.env.BEIR_DATA_DIR || '/tmp/beir-nfcorpus/nfcorpus';
|
|
30
|
-
const BGE_MODEL = process.env.BGE_MODEL || 'Xenova/bge-base-en-v1.5';
|
|
31
|
-
const CACHE_DIR = join(dirname(DATA_DIR), 'bge-cache');
|
|
32
|
-
|
|
33
|
-
const BASELINES = {
|
|
34
|
-
nfcorpus: { 'BM25': 0.325, 'BGE-large-pub': 0.380, 'SPLADE++': 0.347 },
|
|
35
|
-
scifact: { 'BM25': 0.679, 'BGE-large-pub': 0.722, 'SPLADE++': 0.704 },
|
|
36
|
-
};
|
|
37
|
-
function detectDataset(p) { const x = p.toLowerCase(); return Object.keys(BASELINES).find(d => x.includes(d)) || 'nfcorpus'; }
|
|
38
|
-
const DATASET = detectDataset(DATA_DIR);
|
|
39
|
-
|
|
40
|
-
function dcg(rels, k) { let s = 0; for (let i = 0; i < Math.min(rels.length, k); i++) s += (Math.pow(2, rels[i]) - 1) / Math.log2(i + 2); return s; }
|
|
41
|
-
function ndcg(retrieved, qrels, k) { const rels = retrieved.slice(0, k).map((id) => qrels.get(id) ?? 0); const ideal = [...qrels.values()].sort((a, b) => b - a).slice(0, k); const idcg = dcg(ideal, k); return idcg > 0 ? dcg(rels, k) / idcg : 0; }
|
|
42
|
-
function recall(retrieved, qrels, k) { const tot = [...qrels.values()].filter((v) => v > 0).length; if (tot === 0) return 0; let h = 0; for (let i = 0; i < Math.min(retrieved.length, k); i++) if ((qrels.get(retrieved[i]) ?? 0) > 0) h++; return h / tot; }
|
|
43
|
-
function cosine(a, b) { let s = 0; for (let i = 0; i < a.length; i++) s += a[i] * b[i]; return s; }
|
|
44
|
-
|
|
45
|
-
function loadJsonl(p) { return readFileSync(p, 'utf-8').split('\n').filter(Boolean).map((l) => JSON.parse(l)); }
|
|
46
|
-
function loadQrels(p) { const q = new Map(); const lines = readFileSync(p, 'utf-8').split('\n'); for (let i = 1; i < lines.length; i++) { if (!lines[i].trim()) continue; const [qid, did, s] = lines[i].split('\t'); if (!q.has(qid)) q.set(qid, new Map()); q.get(qid).set(did, Number(s)); } return q; }
|
|
47
|
-
|
|
48
|
-
function cachePath(s) { const safe = BGE_MODEL.replace(/\//g, '_'); return join(CACHE_DIR, `${safe}.${s}`); }
|
|
49
|
-
function loadEmbeddings(dim) {
|
|
50
|
-
if (!existsSync(cachePath('ids')) || !existsSync(cachePath('f32'))) return null;
|
|
51
|
-
const ids = readFileSync(cachePath('ids'), 'utf-8').split('\n').filter(Boolean);
|
|
52
|
-
const raw = readFileSync(cachePath('f32'));
|
|
53
|
-
const buf = new Float32Array(raw.buffer, raw.byteOffset, raw.length / 4);
|
|
54
|
-
return { ids, embeds: ids.map((_, i) => buf.slice(i * dim, (i + 1) * dim)) };
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// RRF — pure function per the original Cormack/Clarke/Buettcher 2009 paper.
|
|
58
|
-
// `rankings` is an array of [{id, score}, ...] sorted descending by score.
|
|
59
|
-
// `weights` is per-system weight (default 1.0 each).
|
|
60
|
-
function rrfFuse(rankings, k = 60, weights) {
|
|
61
|
-
const scores = new Map();
|
|
62
|
-
rankings.forEach((ranking, sIdx) => {
|
|
63
|
-
const w = weights?.[sIdx] ?? 1;
|
|
64
|
-
ranking.forEach((doc, rankIdx) => {
|
|
65
|
-
const rank = rankIdx + 1;
|
|
66
|
-
scores.set(doc.id, (scores.get(doc.id) ?? 0) + w / (k + rank));
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
return [...scores.entries()].map(([id, score]) => ({ id, score })).sort((a, b) => b.score - a.score);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Mulberry32 PRNG for deterministic bootstrap.
|
|
73
|
-
function mulberry32(a) { return function () { a |= 0; a = (a + 0x6D2B79F5) | 0; let t = a; t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }; }
|
|
74
|
-
function bootstrapCI(scores, iter = 10000, rng = mulberry32(42)) {
|
|
75
|
-
const n = scores.length; const means = new Float64Array(iter);
|
|
76
|
-
for (let i = 0; i < iter; i++) { let s = 0; for (let j = 0; j < n; j++) s += scores[Math.floor(rng() * n)]; means[i] = s / n; }
|
|
77
|
-
const sorted = Array.from(means).sort((a, b) => a - b);
|
|
78
|
-
const lo = sorted[Math.floor(0.025 * iter)]; const hi = sorted[Math.floor(0.975 * iter)];
|
|
79
|
-
return { mean: scores.reduce((s, v) => s + v, 0) / n, lo, hi };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async function main() {
|
|
83
|
-
console.log(`# RRF ablation on BEIR ${DATASET} (ADR-087)`);
|
|
84
|
-
console.log(`Data: ${DATA_DIR}\nDense: ${BGE_MODEL}\n`);
|
|
85
|
-
|
|
86
|
-
const corpus = loadJsonl(join(DATA_DIR, 'corpus.jsonl'));
|
|
87
|
-
const queries = loadJsonl(join(DATA_DIR, 'queries.jsonl'));
|
|
88
|
-
const qrels = loadQrels(join(DATA_DIR, 'qrels/test.tsv'));
|
|
89
|
-
console.log(`Corpus: ${corpus.length} · queries: ${queries.length} · test qrels: ${qrels.size}`);
|
|
90
|
-
|
|
91
|
-
// Dense
|
|
92
|
-
const bge = await import(join(CLI_ROOT, 'dist/src/memory/bge-embedder.js'));
|
|
93
|
-
const emb = await bge.getBgeEmbedder(BGE_MODEL);
|
|
94
|
-
if (!emb) { console.error('BGE failed'); process.exit(1); }
|
|
95
|
-
const cached = loadEmbeddings(emb.dim());
|
|
96
|
-
if (!cached) { console.error(`No cached embeddings at ${cachePath('f32')}. Run run-beir-bge.mjs first.`); process.exit(2); }
|
|
97
|
-
const { ids: docIds, embeds: docEmbeds } = cached;
|
|
98
|
-
|
|
99
|
-
// BM25
|
|
100
|
-
const { tokenize, buildCorpusStats, multiFieldBM25 } = await import(join(CLI_ROOT, 'dist/src/memory/hybrid-retrieval.js'));
|
|
101
|
-
const titleDocs = corpus.map((d) => tokenize(d.title || ''));
|
|
102
|
-
const textDocs = corpus.map((d) => tokenize(d.text || ''));
|
|
103
|
-
const titleStats = buildCorpusStats(titleDocs);
|
|
104
|
-
const textStats = buildCorpusStats(textDocs);
|
|
105
|
-
const corpusIdxToId = corpus.map((d) => d._id);
|
|
106
|
-
|
|
107
|
-
// Pre-compute per-query rankings for both systems ONCE, so the ablation
|
|
108
|
-
// matrix below just permutes RRF k/weights, not the underlying retrievals.
|
|
109
|
-
const queriesById = new Map(queries.map((q) => [q._id, q.text]));
|
|
110
|
-
const evalQids = [...qrels.keys()];
|
|
111
|
-
|
|
112
|
-
console.log(`Pre-computing dense + BM25 rankings for ${evalQids.length} queries...`);
|
|
113
|
-
const cached_dense = new Map();
|
|
114
|
-
const cached_bm25 = new Map();
|
|
115
|
-
const TOP_K_RETRIEVE = 1000; // enough for stable RRF
|
|
116
|
-
const tPre = performance.now();
|
|
117
|
-
for (const qid of evalQids) {
|
|
118
|
-
const qtext = queriesById.get(qid);
|
|
119
|
-
if (!qtext) continue;
|
|
120
|
-
// Dense
|
|
121
|
-
const qEmb = await emb.embed(qtext);
|
|
122
|
-
const dense = docIds.map((id, i) => ({ id, score: cosine(qEmb, docEmbeds[i]) })).sort((a, b) => b.score - a.score).slice(0, TOP_K_RETRIEVE);
|
|
123
|
-
cached_dense.set(qid, dense);
|
|
124
|
-
// BM25
|
|
125
|
-
const qTokens = tokenize(qtext);
|
|
126
|
-
const bm25 = corpus.map((d, i) => ({ id: corpusIdxToId[i], score: multiFieldBM25(qTokens, titleDocs[i], textDocs[i], titleStats, textStats, 1, 1) })).filter((d) => d.score > 0).sort((a, b) => b.score - a.score).slice(0, TOP_K_RETRIEVE);
|
|
127
|
-
cached_bm25.set(qid, bm25);
|
|
128
|
-
}
|
|
129
|
-
console.log(`Pre-compute done in ${((performance.now() - tPre) / 1000).toFixed(0)}s.\n`);
|
|
130
|
-
|
|
131
|
-
// ----- ABLATION GRID -----
|
|
132
|
-
// FIXED-DEFAULT first (the ship claim). Other variants reported as exploratory.
|
|
133
|
-
const CONFIGS = [
|
|
134
|
-
// The headline configurations — defaults fixed before viewing results.
|
|
135
|
-
{ name: 'dense only', rrf: false, weights: null, kVal: null },
|
|
136
|
-
{ name: 'BM25 only', rrf: false, weights: null, kVal: null, bm25Only: true },
|
|
137
|
-
{ name: 'RRF k=60 equal (default)', rrf: true, weights: [1.0, 1.0], kVal: 60 },
|
|
138
|
-
// Exploratory — disclose as tuned variants, not default.
|
|
139
|
-
{ name: 'RRF k=30 equal', rrf: true, weights: [1.0, 1.0], kVal: 30 },
|
|
140
|
-
{ name: 'RRF k=120 equal', rrf: true, weights: [1.0, 1.0], kVal: 120 },
|
|
141
|
-
{ name: 'RRF k=60 dense=1.2,bm25=0.8', rrf: true, weights: [1.2, 0.8], kVal: 60 },
|
|
142
|
-
{ name: 'RRF k=60 dense=0.8,bm25=1.2', rrf: true, weights: [0.8, 1.2], kVal: 60 },
|
|
143
|
-
];
|
|
144
|
-
|
|
145
|
-
function scoreConfig(cfg) {
|
|
146
|
-
let nSum = 0, r10Sum = 0, r100Sum = 0, n = 0;
|
|
147
|
-
const perQuery = [];
|
|
148
|
-
for (const qid of evalQids) {
|
|
149
|
-
const dense = cached_dense.get(qid);
|
|
150
|
-
const bm25 = cached_bm25.get(qid);
|
|
151
|
-
if (!dense) continue;
|
|
152
|
-
let top100;
|
|
153
|
-
if (!cfg.rrf) {
|
|
154
|
-
if (cfg.bm25Only) top100 = (bm25 || []).slice(0, 100).map((d) => d.id);
|
|
155
|
-
else top100 = dense.slice(0, 100).map((d) => d.id);
|
|
156
|
-
} else {
|
|
157
|
-
const fused = rrfFuse([dense, bm25 || []], cfg.kVal, cfg.weights);
|
|
158
|
-
top100 = fused.slice(0, 100).map((d) => d.id);
|
|
159
|
-
}
|
|
160
|
-
const qmap = qrels.get(qid);
|
|
161
|
-
const ndcg10 = ndcg(top100, qmap, 10);
|
|
162
|
-
nSum += ndcg10;
|
|
163
|
-
r10Sum += recall(top100, qmap, 10);
|
|
164
|
-
r100Sum += recall(top100, qmap, 100);
|
|
165
|
-
n++;
|
|
166
|
-
perQuery.push({ qid, ndcg10 });
|
|
167
|
-
}
|
|
168
|
-
return {
|
|
169
|
-
name: cfg.name,
|
|
170
|
-
ndcg10: nSum / n,
|
|
171
|
-
recall10: r10Sum / n,
|
|
172
|
-
recall100: r100Sum / n,
|
|
173
|
-
n,
|
|
174
|
-
perQuery,
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
console.log('Config | nDCG@10 R@10 R@100 95% CI');
|
|
179
|
-
console.log('--------------------------------------|---------------------------------');
|
|
180
|
-
const results = [];
|
|
181
|
-
let defaultResult = null;
|
|
182
|
-
for (const cfg of CONFIGS) {
|
|
183
|
-
const r = scoreConfig(cfg);
|
|
184
|
-
const ci = bootstrapCI(r.perQuery.map((q) => q.ndcg10));
|
|
185
|
-
const ciStr = `[${ci.lo.toFixed(3)}, ${ci.hi.toFixed(3)}]`;
|
|
186
|
-
console.log(`${cfg.name.padEnd(38)} | ${r.ndcg10.toFixed(4)} ${r.recall10.toFixed(3)} ${r.recall100.toFixed(3)} ${ciStr}`);
|
|
187
|
-
results.push({ ...r, ci, cfg });
|
|
188
|
-
if (cfg.name.includes('default')) defaultResult = { ...r, ci, cfg };
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
console.log('\n=== Ship claim (fixed default, k=60, equal weights) ===');
|
|
192
|
-
console.log(`Dataset: ${DATASET}`);
|
|
193
|
-
console.log(`nDCG@10: ${defaultResult.ndcg10.toFixed(4)} 95% CI ${`[${defaultResult.ci.lo.toFixed(4)}, ${defaultResult.ci.hi.toFixed(4)}]`}`);
|
|
194
|
-
for (const [name, score] of Object.entries(BASELINES[DATASET])) {
|
|
195
|
-
const delta = defaultResult.ndcg10 - score;
|
|
196
|
-
const inCi = score >= defaultResult.ci.lo && score <= defaultResult.ci.hi;
|
|
197
|
-
const sig = inCi ? 'n.s.' : (delta > 0 ? 'p<0.05 WIN' : 'p<0.05 LOSS');
|
|
198
|
-
console.log(` vs ${name.padEnd(15)} Δ=${(delta >= 0 ? '+' : '') + delta.toFixed(4)} ${sig}`);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Save
|
|
202
|
-
const summary = {
|
|
203
|
-
runAt: new Date().toISOString(),
|
|
204
|
-
benchmark: `beir-${DATASET}-rrf-ablation`,
|
|
205
|
-
dataset: DATASET,
|
|
206
|
-
bgeModel: BGE_MODEL,
|
|
207
|
-
queries: defaultResult.n,
|
|
208
|
-
corpusSize: corpus.length,
|
|
209
|
-
fixedDefault: { name: defaultResult.cfg.name, metrics: { ndcg10: defaultResult.ndcg10, recall10: defaultResult.recall10, recall100: defaultResult.recall100 }, ci: defaultResult.ci, perQuery: defaultResult.perQuery },
|
|
210
|
-
ablation: results.map((r) => ({ name: r.cfg.name, ndcg10: r.ndcg10, recall10: r.recall10, recall100: r.recall100, ci: r.ci })),
|
|
211
|
-
baselines: BASELINES[DATASET],
|
|
212
|
-
};
|
|
213
|
-
mkdirSync(RUNS_DIR, { recursive: true });
|
|
214
|
-
const stamp = summary.runAt.replace(/[:.]/g, '-');
|
|
215
|
-
writeFileSync(join(RUNS_DIR, `beir-${DATASET}-rrf-ablation-${stamp}.json`), JSON.stringify(summary, null, 2));
|
|
216
|
-
writeFileSync(join(RUNS_DIR, `beir-${DATASET}-rrf-ablation-latest.json`), JSON.stringify(summary, null, 2));
|
|
217
|
-
console.log(`\nWrote ${join(RUNS_DIR, `beir-${DATASET}-rrf-ablation-${stamp}.json`)}`);
|
|
218
|
-
process.exit(0);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
main().catch((err) => { console.error(err); process.exit(1); });
|