@claude-flow/cli 3.32.3 → 3.32.4
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 +2 -2
- package/catalog-manifest.json +2 -2
- package/dist/src/agenticow/speculative-exploration.d.ts +148 -0
- package/dist/src/agenticow/speculative-exploration.js +218 -0
- package/dist/src/appliance/gguf-engine.d.ts +91 -0
- package/dist/src/appliance/gguf-engine.js +425 -0
- package/dist/src/appliance/ruvllm-bridge.d.ts +102 -0
- package/dist/src/appliance/ruvllm-bridge.js +292 -0
- package/dist/src/appliance/rvfa-builder.d.ts +44 -0
- package/dist/src/appliance/rvfa-builder.js +329 -0
- package/dist/src/appliance/rvfa-distribution.d.ts +97 -0
- package/dist/src/appliance/rvfa-distribution.js +370 -0
- package/dist/src/appliance/rvfa-format.d.ts +111 -0
- package/dist/src/appliance/rvfa-format.js +393 -0
- package/dist/src/appliance/rvfa-runner.d.ts +69 -0
- package/dist/src/appliance/rvfa-runner.js +237 -0
- package/dist/src/appliance/rvfa-signing.d.ts +123 -0
- package/dist/src/appliance/rvfa-signing.js +347 -0
- package/dist/src/auth/client.d.ts +89 -0
- package/dist/src/auth/client.js +242 -0
- package/dist/src/auth/constants.d.ts +7 -0
- package/dist/src/auth/constants.js +7 -0
- package/dist/src/auth/scopes.d.ts +14 -0
- package/dist/src/auth/scopes.js +21 -0
- package/dist/src/auth/security-bridge.d.ts +36 -0
- package/dist/src/auth/security-bridge.js +42 -0
- package/dist/src/auth/session.d.ts +20 -0
- package/dist/src/auth/session.js +32 -0
- package/dist/src/auth/state.d.ts +19 -0
- package/dist/src/auth/state.js +53 -0
- package/dist/src/auth/types.d.ts +27 -0
- package/dist/src/auth/types.js +11 -0
- package/dist/src/autopilot-state.d.ts +77 -0
- package/dist/src/autopilot-state.js +271 -0
- package/dist/src/benchmarks/gaia-agent-planning.smoke.d.ts +18 -0
- package/dist/src/benchmarks/gaia-agent-planning.smoke.js +253 -0
- package/dist/src/benchmarks/gaia-agent.d.ts +198 -0
- package/dist/src/benchmarks/gaia-agent.js +651 -0
- package/dist/src/benchmarks/gaia-causal-memory.d.ts +133 -0
- package/dist/src/benchmarks/gaia-causal-memory.js +281 -0
- package/dist/src/benchmarks/gaia-causal-memory.smoke.d.ts +22 -0
- package/dist/src/benchmarks/gaia-causal-memory.smoke.js +300 -0
- package/dist/src/benchmarks/gaia-convergence.d.ts +138 -0
- package/dist/src/benchmarks/gaia-convergence.js +260 -0
- package/dist/src/benchmarks/gaia-convergence.smoke.d.ts +19 -0
- package/dist/src/benchmarks/gaia-convergence.smoke.js +246 -0
- package/dist/src/benchmarks/gaia-critic.d.ts +123 -0
- package/dist/src/benchmarks/gaia-critic.js +312 -0
- package/dist/src/benchmarks/gaia-critic.smoke.d.ts +21 -0
- package/dist/src/benchmarks/gaia-critic.smoke.js +327 -0
- package/dist/src/benchmarks/gaia-decomposer.d.ts +125 -0
- package/dist/src/benchmarks/gaia-decomposer.js +350 -0
- package/dist/src/benchmarks/gaia-decomposer.smoke.d.ts +21 -0
- package/dist/src/benchmarks/gaia-decomposer.smoke.js +228 -0
- package/dist/src/benchmarks/gaia-e2e-smoke.d.ts +27 -0
- package/dist/src/benchmarks/gaia-e2e-smoke.js +136 -0
- package/dist/src/benchmarks/gaia-extract.smoke.d.ts +45 -0
- package/dist/src/benchmarks/gaia-extract.smoke.js +242 -0
- package/dist/src/benchmarks/gaia-hardness/features.d.ts +46 -0
- package/dist/src/benchmarks/gaia-hardness/features.js +170 -0
- package/dist/src/benchmarks/gaia-hardness/predictor.d.ts +105 -0
- package/dist/src/benchmarks/gaia-hardness/predictor.js +260 -0
- package/dist/src/benchmarks/gaia-hardness/predictor.smoke.d.ts +20 -0
- package/dist/src/benchmarks/gaia-hardness/predictor.smoke.js +235 -0
- package/dist/src/benchmarks/gaia-hardness/train-data-loader.d.ts +51 -0
- package/dist/src/benchmarks/gaia-hardness/train-data-loader.js +179 -0
- package/dist/src/benchmarks/gaia-judge.d.ts +88 -0
- package/dist/src/benchmarks/gaia-judge.js +437 -0
- package/dist/src/benchmarks/gaia-loader.d.ts +87 -0
- package/dist/src/benchmarks/gaia-loader.js +326 -0
- package/dist/src/benchmarks/gaia-tools/file_read.d.ts +35 -0
- package/dist/src/benchmarks/gaia-tools/file_read.js +403 -0
- package/dist/src/benchmarks/gaia-tools/grounded_query.d.ts +126 -0
- package/dist/src/benchmarks/gaia-tools/grounded_query.js +225 -0
- package/dist/src/benchmarks/gaia-tools/index.d.ts +32 -0
- package/dist/src/benchmarks/gaia-tools/index.js +36 -0
- package/dist/src/benchmarks/gaia-tools/types.d.ts +62 -0
- package/dist/src/benchmarks/gaia-tools/types.js +12 -0
- package/dist/src/benchmarks/gaia-tools/web_search.d.ts +30 -0
- package/dist/src/benchmarks/gaia-tools/web_search.js +210 -0
- package/dist/src/benchmarks/gaia-voting.d.ts +88 -0
- package/dist/src/benchmarks/gaia-voting.js +297 -0
- package/dist/src/benchmarks/gaia-voting.smoke.d.ts +20 -0
- package/dist/src/benchmarks/gaia-voting.smoke.js +332 -0
- package/dist/src/benchmarks/pretrain/index.d.ts +58 -0
- package/dist/src/benchmarks/pretrain/index.js +404 -0
- package/dist/src/business-pods/bbs-budget-tracker.d.ts +139 -0
- package/dist/src/business-pods/bbs-budget-tracker.js +358 -0
- package/dist/src/business-pods/domain-affinity-policy.d.ts +47 -0
- package/dist/src/business-pods/domain-affinity-policy.js +65 -0
- package/dist/src/business-pods/pod-schema.d.ts +96 -0
- package/dist/src/business-pods/pod-schema.js +225 -0
- package/dist/src/commands/advisor.d.ts +15 -0
- package/dist/src/commands/advisor.js +94 -0
- package/dist/src/commands/agent-wasm.d.ts +14 -0
- package/dist/src/commands/agent-wasm.js +333 -0
- package/dist/src/commands/agent.d.ts +8 -0
- package/dist/src/commands/agent.js +927 -0
- package/dist/src/commands/analyze.d.ts +19 -0
- package/dist/src/commands/analyze.js +2047 -0
- package/dist/src/commands/announcements.d.ts +17 -0
- package/dist/src/commands/announcements.js +0 -0
- package/dist/src/commands/appliance-advanced.d.ts +9 -0
- package/dist/src/commands/appliance-advanced.js +215 -0
- package/dist/src/commands/appliance.d.ts +8 -0
- package/dist/src/commands/appliance.js +404 -0
- package/dist/src/commands/auth.d.ts +15 -0
- package/dist/src/commands/auth.js +244 -0
- package/dist/src/commands/autopilot.d.ts +15 -0
- package/dist/src/commands/autopilot.js +407 -0
- package/dist/src/commands/benchmark.d.ts +10 -0
- package/dist/src/commands/benchmark.js +460 -0
- package/dist/src/commands/claims.d.ts +10 -0
- package/dist/src/commands/claims.js +620 -0
- package/dist/src/commands/cleanup.d.ts +13 -0
- package/dist/src/commands/cleanup.js +250 -0
- package/dist/src/commands/completions.d.ts +10 -0
- package/dist/src/commands/completions.js +539 -0
- package/dist/src/commands/config.d.ts +8 -0
- package/dist/src/commands/config.js +428 -0
- package/dist/src/commands/daemon.d.ts +59 -0
- package/dist/src/commands/daemon.js +1733 -0
- package/dist/src/commands/deployment.d.ts +10 -0
- package/dist/src/commands/deployment.js +672 -0
- package/dist/src/commands/doctor.d.ts +10 -0
- package/dist/src/commands/doctor.js +1902 -0
- package/dist/src/commands/eject.d.ts +33 -0
- package/dist/src/commands/eject.js +195 -0
- package/dist/src/commands/embeddings.d.ts +18 -0
- package/dist/src/commands/embeddings.js +1623 -0
- package/dist/src/commands/funnel.d.ts +18 -0
- package/dist/src/commands/funnel.js +302 -0
- package/dist/src/commands/gaia-bench.d.ts +40 -0
- package/dist/src/commands/gaia-bench.js +597 -0
- package/dist/src/commands/guidance.d.ts +8 -0
- package/dist/src/commands/guidance.js +556 -0
- package/dist/src/commands/hive-mind.d.ts +11 -0
- package/dist/src/commands/hive-mind.js +1319 -0
- package/dist/src/commands/hooks.d.ts +8 -0
- package/dist/src/commands/hooks.js +4606 -0
- package/dist/src/commands/index.d.ts +118 -0
- package/dist/src/commands/index.js +366 -0
- package/dist/src/commands/init.d.ts +13 -0
- package/dist/src/commands/init.js +1297 -0
- package/dist/src/commands/issues.d.ts +21 -0
- package/dist/src/commands/issues.js +567 -0
- package/dist/src/commands/mcp.d.ts +11 -0
- package/dist/src/commands/mcp.js +732 -0
- package/dist/src/commands/memory-backup.d.ts +11 -0
- package/dist/src/commands/memory-backup.js +46 -0
- package/dist/src/commands/memory-distill.d.ts +27 -0
- package/dist/src/commands/memory-distill.js +374 -0
- package/dist/src/commands/memory.d.ts +8 -0
- package/dist/src/commands/memory.js +1596 -0
- package/dist/src/commands/metaharness.d.ts +39 -0
- package/dist/src/commands/metaharness.js +215 -0
- package/dist/src/commands/migrate.d.ts +8 -0
- package/dist/src/commands/migrate.js +742 -0
- package/dist/src/commands/neural.d.ts +10 -0
- package/dist/src/commands/neural.js +4331 -0
- package/dist/src/commands/performance.d.ts +10 -0
- package/dist/src/commands/performance.js +583 -0
- package/dist/src/commands/plugins.d.ts +11 -0
- package/dist/src/commands/plugins.js +826 -0
- package/dist/src/commands/process.d.ts +10 -0
- package/dist/src/commands/process.js +694 -0
- package/dist/src/commands/progress.d.ts +11 -0
- package/dist/src/commands/progress.js +259 -0
- package/dist/src/commands/providers.d.ts +10 -0
- package/dist/src/commands/providers.js +502 -0
- package/dist/src/commands/proxy-lifecycle.d.ts +12 -0
- package/dist/src/commands/proxy-lifecycle.js +232 -0
- package/dist/src/commands/proxy.d.ts +21 -0
- package/dist/src/commands/proxy.js +398 -0
- package/dist/src/commands/route.d.ts +16 -0
- package/dist/src/commands/route.js +822 -0
- package/dist/src/commands/ruvector/backup.d.ts +11 -0
- package/dist/src/commands/ruvector/backup.js +747 -0
- package/dist/src/commands/ruvector/benchmark.d.ts +11 -0
- package/dist/src/commands/ruvector/benchmark.js +490 -0
- package/dist/src/commands/ruvector/import.d.ts +18 -0
- package/dist/src/commands/ruvector/import.js +373 -0
- package/dist/src/commands/ruvector/index.d.ts +29 -0
- package/dist/src/commands/ruvector/index.js +129 -0
- package/dist/src/commands/ruvector/init.d.ts +11 -0
- package/dist/src/commands/ruvector/init.js +467 -0
- package/dist/src/commands/ruvector/migrate.d.ts +11 -0
- package/dist/src/commands/ruvector/migrate.js +498 -0
- package/dist/src/commands/ruvector/optimize.d.ts +11 -0
- package/dist/src/commands/ruvector/optimize.js +505 -0
- package/dist/src/commands/ruvector/pg-utils.d.ts +14 -0
- package/dist/src/commands/ruvector/pg-utils.js +41 -0
- package/dist/src/commands/ruvector/setup.d.ts +18 -0
- package/dist/src/commands/ruvector/setup.js +765 -0
- package/dist/src/commands/ruvector/status.d.ts +11 -0
- package/dist/src/commands/ruvector/status.js +479 -0
- package/dist/src/commands/security.d.ts +10 -0
- package/dist/src/commands/security.js +1012 -0
- package/dist/src/commands/session.d.ts +8 -0
- package/dist/src/commands/session.js +757 -0
- package/dist/src/commands/settings.d.ts +19 -0
- package/dist/src/commands/settings.js +180 -0
- package/dist/src/commands/spinner.d.ts +16 -0
- package/dist/src/commands/spinner.js +329 -0
- package/dist/src/commands/start.d.ts +8 -0
- package/dist/src/commands/start.js +418 -0
- package/dist/src/commands/status.d.ts +8 -0
- package/dist/src/commands/status.js +608 -0
- package/dist/src/commands/swarm.d.ts +8 -0
- package/dist/src/commands/swarm.js +891 -0
- package/dist/src/commands/task.d.ts +8 -0
- package/dist/src/commands/task.js +675 -0
- package/dist/src/commands/transfer-store.d.ts +13 -0
- package/dist/src/commands/transfer-store.js +428 -0
- package/dist/src/commands/update.d.ts +8 -0
- package/dist/src/commands/update.js +276 -0
- package/dist/src/commands/verify.d.ts +19 -0
- package/dist/src/commands/verify.js +261 -0
- package/dist/src/commands/version.d.ts +42 -0
- package/dist/src/commands/version.js +106 -0
- package/dist/src/commands/workflow.d.ts +8 -0
- package/dist/src/commands/workflow.js +617 -0
- package/dist/src/config/harness-feedback-applier.d.ts +50 -0
- package/dist/src/config/harness-feedback-applier.js +122 -0
- package/dist/src/config/proven-config-refresh.d.ts +39 -0
- package/dist/src/config/proven-config-refresh.js +154 -0
- package/dist/src/config/proven-config-rvfa.d.ts +23 -0
- package/dist/src/config/proven-config-rvfa.js +73 -0
- package/dist/src/config/proven-config.d.ts +86 -0
- package/dist/src/config/proven-config.js +176 -0
- package/dist/src/config-adapter.d.ts +15 -0
- package/dist/src/config-adapter.js +186 -0
- package/dist/src/encryption/vault.d.ts +94 -0
- package/dist/src/encryption/vault.js +172 -0
- package/dist/src/fs-secure.d.ts +86 -0
- package/dist/src/fs-secure.js +133 -0
- package/dist/src/funnel/advisor-tip.d.ts +58 -0
- package/dist/src/funnel/advisor-tip.js +92 -0
- package/dist/src/funnel/attribution.d.ts +37 -0
- package/dist/src/funnel/attribution.js +101 -0
- package/dist/src/funnel/consent.d.ts +22 -0
- package/dist/src/funnel/consent.js +58 -0
- package/dist/src/funnel/credit-errors.d.ts +31 -0
- package/dist/src/funnel/credit-errors.js +88 -0
- package/dist/src/funnel/credit-notifier.d.ts +44 -0
- package/dist/src/funnel/credit-notifier.js +74 -0
- package/dist/src/funnel/disclosure.d.ts +47 -0
- package/dist/src/funnel/disclosure.js +109 -0
- package/dist/src/funnel/enrollment.d.ts +36 -0
- package/dist/src/funnel/enrollment.js +64 -0
- package/dist/src/funnel/environment.d.ts +17 -0
- package/dist/src/funnel/environment.js +39 -0
- package/dist/src/funnel/event-transport.d.ts +51 -0
- package/dist/src/funnel/event-transport.js +199 -0
- package/dist/src/funnel/events.d.ts +42 -0
- package/dist/src/funnel/events.js +150 -0
- package/dist/src/funnel/index.d.ts +21 -0
- package/dist/src/funnel/index.js +21 -0
- package/dist/src/funnel/insights.d.ts +50 -0
- package/dist/src/funnel/insights.js +120 -0
- package/dist/src/funnel/local-signals.d.ts +20 -0
- package/dist/src/funnel/local-signals.js +77 -0
- package/dist/src/funnel/message-transport.d.ts +51 -0
- package/dist/src/funnel/message-transport.js +149 -0
- package/dist/src/funnel/messages.d.ts +55 -0
- package/dist/src/funnel/messages.js +160 -0
- package/dist/src/funnel/payout.d.ts +40 -0
- package/dist/src/funnel/payout.js +60 -0
- package/dist/src/funnel/power-saver-notifier.d.ts +44 -0
- package/dist/src/funnel/power-saver-notifier.js +92 -0
- package/dist/src/funnel/precedence.d.ts +16 -0
- package/dist/src/funnel/precedence.js +85 -0
- package/dist/src/funnel/promo.d.ts +41 -0
- package/dist/src/funnel/promo.js +144 -0
- package/dist/src/funnel/rate-limit-notifier.d.ts +55 -0
- package/dist/src/funnel/rate-limit-notifier.js +102 -0
- package/dist/src/funnel/rotation.d.ts +19 -0
- package/dist/src/funnel/rotation.js +70 -0
- package/dist/src/funnel/state.d.ts +13 -0
- package/dist/src/funnel/state.js +52 -0
- package/dist/src/funnel/toggle-cooldown.d.ts +17 -0
- package/dist/src/funnel/toggle-cooldown.js +32 -0
- package/dist/src/funnel/types.d.ts +98 -0
- package/dist/src/funnel/types.js +26 -0
- package/dist/src/index.d.ts +81 -0
- package/dist/src/index.js +609 -0
- package/dist/src/infrastructure/in-memory-repositories.d.ts +68 -0
- package/dist/src/infrastructure/in-memory-repositories.js +264 -0
- package/dist/src/init/claudemd-generator.d.ts +16 -0
- package/dist/src/init/claudemd-generator.js +368 -0
- package/dist/src/init/executor.d.ts +41 -0
- package/dist/src/init/executor.js +2142 -0
- package/dist/src/init/helper-refresh.d.ts +79 -0
- package/dist/src/init/helper-refresh.js +347 -0
- package/dist/src/init/helper-signing.d.ts +37 -0
- package/dist/src/init/helper-signing.js +67 -0
- package/dist/src/init/helpers-generator.d.ts +87 -0
- package/dist/src/init/helpers-generator.js +1456 -0
- package/dist/src/init/index.d.ts +13 -0
- package/dist/src/init/index.js +15 -0
- package/dist/src/init/mcp-generator.d.ts +26 -0
- package/dist/src/init/mcp-generator.js +126 -0
- package/dist/src/init/memory-package-resolver.d.ts +53 -0
- package/dist/src/init/memory-package-resolver.js +118 -0
- package/dist/src/init/settings-generator.d.ts +14 -0
- package/dist/src/init/settings-generator.js +462 -0
- package/dist/src/init/statusline-generator.d.ts +28 -0
- package/dist/src/init/statusline-generator.js +177 -0
- package/dist/src/init/types.d.ts +331 -0
- package/dist/src/init/types.js +276 -0
- package/dist/src/log-filters.d.ts +46 -0
- package/dist/src/log-filters.js +107 -0
- package/dist/src/mcp-client.d.ts +92 -0
- package/dist/src/mcp-client.js +397 -0
- package/dist/src/mcp-server.d.ts +163 -0
- package/dist/src/mcp-server.js +751 -0
- package/dist/src/mcp-tools/agent-execute-core.d.ts +115 -0
- package/dist/src/mcp-tools/agent-execute-core.js +587 -0
- package/dist/src/mcp-tools/agent-tools.d.ts +9 -0
- package/dist/src/mcp-tools/agent-tools.js +837 -0
- package/dist/src/mcp-tools/agentbbs-tools.d.ts +28 -0
- package/dist/src/mcp-tools/agentbbs-tools.js +394 -0
- package/dist/src/mcp-tools/agentdb-tools.d.ts +35 -0
- package/dist/src/mcp-tools/agentdb-tools.js +1473 -0
- package/dist/src/mcp-tools/agenticow-loader.d.ts +59 -0
- package/dist/src/mcp-tools/agenticow-loader.js +105 -0
- package/dist/src/mcp-tools/agenticow-speculate-tools.d.ts +24 -0
- package/dist/src/mcp-tools/agenticow-speculate-tools.js +209 -0
- package/dist/src/mcp-tools/agenticow-tools.d.ts +36 -0
- package/dist/src/mcp-tools/agenticow-tools.js +360 -0
- package/dist/src/mcp-tools/analyze-tools.d.ts +38 -0
- package/dist/src/mcp-tools/analyze-tools.js +346 -0
- package/dist/src/mcp-tools/auto-install.d.ts +83 -0
- package/dist/src/mcp-tools/auto-install.js +131 -0
- package/dist/src/mcp-tools/autopilot-tools.d.ts +12 -0
- package/dist/src/mcp-tools/autopilot-tools.js +231 -0
- 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-session-tools.d.ts +27 -0
- package/dist/src/mcp-tools/browser-session-tools.js +398 -0
- package/dist/src/mcp-tools/browser-tools.d.ts +21 -0
- package/dist/src/mcp-tools/browser-tools.js +760 -0
- package/dist/src/mcp-tools/business-pod-tools.d.ts +20 -0
- package/dist/src/mcp-tools/business-pod-tools.js +169 -0
- package/dist/src/mcp-tools/claims-tools.d.ts +12 -0
- package/dist/src/mcp-tools/claims-tools.js +863 -0
- package/dist/src/mcp-tools/config-tools.d.ts +8 -0
- package/dist/src/mcp-tools/config-tools.js +411 -0
- package/dist/src/mcp-tools/coordination-tools.d.ts +13 -0
- package/dist/src/mcp-tools/coordination-tools.js +729 -0
- package/dist/src/mcp-tools/daa-tools.d.ts +13 -0
- package/dist/src/mcp-tools/daa-tools.js +534 -0
- package/dist/src/mcp-tools/embeddings-tools.d.ts +9 -0
- package/dist/src/mcp-tools/embeddings-tools.js +904 -0
- package/dist/src/mcp-tools/github-tools.d.ts +9 -0
- package/dist/src/mcp-tools/github-tools.js +659 -0
- package/dist/src/mcp-tools/guidance-tools.d.ts +15 -0
- package/dist/src/mcp-tools/guidance-tools.js +639 -0
- package/dist/src/mcp-tools/hive-mind-tools.d.ts +8 -0
- package/dist/src/mcp-tools/hive-mind-tools.js +953 -0
- package/dist/src/mcp-tools/hooks-tools.d.ts +65 -0
- package/dist/src/mcp-tools/hooks-tools.js +4836 -0
- package/dist/src/mcp-tools/http-fetch-tools.d.ts +55 -0
- package/dist/src/mcp-tools/http-fetch-tools.js +329 -0
- package/dist/src/mcp-tools/index.d.ts +34 -0
- package/dist/src/mcp-tools/index.js +40 -0
- package/dist/src/mcp-tools/managed-agent-tools.d.ts +22 -0
- package/dist/src/mcp-tools/managed-agent-tools.js +357 -0
- package/dist/src/mcp-tools/memory-tools.d.ts +14 -0
- package/dist/src/mcp-tools/memory-tools.js +1330 -0
- package/dist/src/mcp-tools/metaharness-tools.d.ts +51 -0
- package/dist/src/mcp-tools/metaharness-tools.js +684 -0
- package/dist/src/mcp-tools/neural-tools.d.ts +54 -0
- package/dist/src/mcp-tools/neural-tools.js +1168 -0
- package/dist/src/mcp-tools/performance-tools.d.ts +16 -0
- package/dist/src/mcp-tools/performance-tools.js +675 -0
- package/dist/src/mcp-tools/progress-tools.d.ts +14 -0
- package/dist/src/mcp-tools/progress-tools.js +348 -0
- package/dist/src/mcp-tools/request-tracker.d.ts +17 -0
- package/dist/src/mcp-tools/request-tracker.js +27 -0
- package/dist/src/mcp-tools/ruvllm-tools.d.ts +9 -0
- package/dist/src/mcp-tools/ruvllm-tools.js +355 -0
- package/dist/src/mcp-tools/security-tools.d.ts +18 -0
- package/dist/src/mcp-tools/security-tools.js +556 -0
- package/dist/src/mcp-tools/session-tools.d.ts +8 -0
- package/dist/src/mcp-tools/session-tools.js +517 -0
- package/dist/src/mcp-tools/swarm-tools.d.ts +37 -0
- package/dist/src/mcp-tools/swarm-tools.js +390 -0
- package/dist/src/mcp-tools/system-tools.d.ts +13 -0
- package/dist/src/mcp-tools/system-tools.js +688 -0
- package/dist/src/mcp-tools/task-tools.d.ts +8 -0
- package/dist/src/mcp-tools/task-tools.js +487 -0
- package/dist/src/mcp-tools/terminal-tools.d.ts +8 -0
- package/dist/src/mcp-tools/terminal-tools.js +306 -0
- package/dist/src/mcp-tools/testgen-tools.d.ts +26 -0
- package/dist/src/mcp-tools/testgen-tools.js +168 -0
- package/dist/src/mcp-tools/tool-loop-guardrail.d.ts +31 -0
- package/dist/src/mcp-tools/tool-loop-guardrail.js +71 -0
- package/dist/src/mcp-tools/transfer-tools.d.ts +14 -0
- package/dist/src/mcp-tools/transfer-tools.js +447 -0
- package/dist/src/mcp-tools/types.d.ts +8 -0
- package/dist/src/mcp-tools/types.js +8 -0
- package/dist/src/mcp-tools/validate-input.d.ts +9 -0
- package/dist/src/mcp-tools/validate-input.js +9 -0
- package/dist/src/mcp-tools/wasm-agent-tools.d.ts +13 -0
- package/dist/src/mcp-tools/wasm-agent-tools.js +840 -0
- package/dist/src/mcp-tools/workflow-tools.d.ts +8 -0
- package/dist/src/mcp-tools/workflow-tools.js +884 -0
- package/dist/src/memory/bge-embedder.d.ts +25 -0
- package/dist/src/memory/bge-embedder.js +121 -0
- package/dist/src/memory/cross-encoder-rerank.d.ts +33 -0
- package/dist/src/memory/cross-encoder-rerank.js +123 -0
- package/dist/src/memory/embedding-policy.d.ts +21 -0
- package/dist/src/memory/embedding-policy.js +30 -0
- package/dist/src/memory/embedding-quantization.d.ts +62 -0
- package/dist/src/memory/embedding-quantization.js +156 -0
- package/dist/src/memory/ewc-consolidation.d.ts +305 -0
- package/dist/src/memory/ewc-consolidation.js +611 -0
- package/dist/src/memory/graph-edge-writer.d.ts +95 -0
- package/dist/src/memory/graph-edge-writer.js +217 -0
- package/dist/src/memory/hybrid-retrieval.d.ts +77 -0
- package/dist/src/memory/hybrid-retrieval.js +192 -0
- package/dist/src/memory/intelligence.d.ts +405 -0
- package/dist/src/memory/intelligence.js +1316 -0
- package/dist/src/memory/lucene-bm25.d.ts +19 -0
- package/dist/src/memory/lucene-bm25.js +308 -0
- package/dist/src/memory/memory-bridge.d.ts +537 -0
- package/dist/src/memory/memory-bridge.js +2460 -0
- package/dist/src/memory/memory-initializer.d.ts +556 -0
- package/dist/src/memory/memory-initializer.js +3021 -0
- package/dist/src/memory/neural-package-bridge.d.ts +48 -0
- package/dist/src/memory/neural-package-bridge.js +87 -0
- package/dist/src/memory/rabitq-index.d.ts +60 -0
- package/dist/src/memory/rabitq-index.js +242 -0
- package/dist/src/memory/sona-optimizer.d.ts +267 -0
- package/dist/src/memory/sona-optimizer.js +779 -0
- package/dist/src/memory/structured-distill.d.ts +48 -0
- package/dist/src/memory/structured-distill.js +125 -0
- package/dist/src/output.d.ts +9 -0
- package/dist/src/output.js +9 -0
- package/dist/src/parser.d.ts +89 -0
- package/dist/src/parser.js +516 -0
- package/dist/src/plugins/manager.d.ts +133 -0
- package/dist/src/plugins/manager.js +415 -0
- package/dist/src/plugins/store/discovery.d.ts +99 -0
- package/dist/src/plugins/store/discovery.js +1224 -0
- package/dist/src/plugins/store/index.d.ts +76 -0
- package/dist/src/plugins/store/index.js +141 -0
- package/dist/src/plugins/store/search.d.ts +46 -0
- package/dist/src/plugins/store/search.js +230 -0
- package/dist/src/plugins/store/types.d.ts +279 -0
- package/dist/src/plugins/store/types.js +7 -0
- package/dist/src/plugins/tests/demo-plugin-store.d.ts +7 -0
- package/dist/src/plugins/tests/demo-plugin-store.js +126 -0
- package/dist/src/plugins/tests/standalone-test.d.ts +12 -0
- package/dist/src/plugins/tests/standalone-test.js +188 -0
- package/dist/src/plugins/tests/test-plugin-store.d.ts +7 -0
- package/dist/src/plugins/tests/test-plugin-store.js +206 -0
- package/dist/src/production/circuit-breaker.d.ts +101 -0
- package/dist/src/production/circuit-breaker.js +241 -0
- package/dist/src/production/error-handler.d.ts +92 -0
- package/dist/src/production/error-handler.js +299 -0
- package/dist/src/production/index.d.ts +23 -0
- package/dist/src/production/index.js +18 -0
- package/dist/src/production/monitoring.d.ts +161 -0
- package/dist/src/production/monitoring.js +356 -0
- package/dist/src/production/rate-limiter.d.ts +80 -0
- package/dist/src/production/rate-limiter.js +201 -0
- package/dist/src/production/retry.d.ts +48 -0
- package/dist/src/production/retry.js +179 -0
- package/dist/src/prompt.d.ts +44 -0
- package/dist/src/prompt.js +501 -0
- package/dist/src/proxy/install.d.ts +29 -0
- package/dist/src/proxy/install.js +135 -0
- package/dist/src/proxy/lifecycle.d.ts +61 -0
- package/dist/src/proxy/lifecycle.js +249 -0
- package/dist/src/proxy/paths.d.ts +34 -0
- package/dist/src/proxy/paths.js +70 -0
- package/dist/src/proxy/release.d.ts +47 -0
- package/dist/src/proxy/release.js +138 -0
- package/dist/src/proxy/token-bridge.d.ts +5 -0
- package/dist/src/proxy/token-bridge.js +61 -0
- package/dist/src/proxy/verify.d.ts +44 -0
- package/dist/src/proxy/verify.js +68 -0
- package/dist/src/runtime/headless.d.ts +60 -0
- package/dist/src/runtime/headless.js +284 -0
- package/dist/src/runtime/parent-death-watchdog.d.ts +42 -0
- package/dist/src/runtime/parent-death-watchdog.js +70 -0
- package/dist/src/ruvector/agent-wasm.d.ts +228 -0
- package/dist/src/ruvector/agent-wasm.js +463 -0
- package/dist/src/ruvector/ast-analyzer.d.ts +67 -0
- package/dist/src/ruvector/ast-analyzer.js +277 -0
- package/dist/src/ruvector/codemods/engine.d.ts +45 -0
- package/dist/src/ruvector/codemods/engine.js +291 -0
- package/dist/src/ruvector/codemods/scope-analysis.d.ts +29 -0
- package/dist/src/ruvector/codemods/scope-analysis.js +162 -0
- package/dist/src/ruvector/coverage-router.d.ts +160 -0
- package/dist/src/ruvector/coverage-router.js +531 -0
- package/dist/src/ruvector/coverage-tools.d.ts +33 -0
- package/dist/src/ruvector/coverage-tools.js +157 -0
- package/dist/src/ruvector/diff-classifier.d.ts +175 -0
- package/dist/src/ruvector/diff-classifier.js +699 -0
- package/dist/src/ruvector/diskann-backend.d.ts +78 -0
- package/dist/src/ruvector/diskann-backend.js +310 -0
- package/dist/src/ruvector/enhanced-model-router.d.ts +172 -0
- package/dist/src/ruvector/enhanced-model-router.js +577 -0
- package/dist/src/ruvector/graph-analyzer.d.ts +187 -0
- package/dist/src/ruvector/graph-analyzer.js +929 -0
- package/dist/src/ruvector/graph-backend.d.ts +79 -0
- package/dist/src/ruvector/graph-backend.js +220 -0
- package/dist/src/ruvector/index.d.ts +38 -0
- package/dist/src/ruvector/index.js +86 -0
- package/dist/src/ruvector/lora-adapter.d.ts +292 -0
- package/dist/src/ruvector/lora-adapter.js +710 -0
- package/dist/src/ruvector/model-prices.d.ts +50 -0
- package/dist/src/ruvector/model-prices.js +72 -0
- package/dist/src/ruvector/model-router.d.ts +408 -0
- package/dist/src/ruvector/model-router.js +1162 -0
- package/dist/src/ruvector/neural-router.d.ts +182 -0
- package/dist/src/ruvector/neural-router.js +825 -0
- package/dist/src/ruvector/output-verifier.d.ts +83 -0
- package/dist/src/ruvector/output-verifier.js +277 -0
- package/dist/src/ruvector/q-learning-router.d.ts +227 -0
- package/dist/src/ruvector/q-learning-router.js +721 -0
- package/dist/src/ruvector/router-calibrator.d.ts +65 -0
- package/dist/src/ruvector/router-calibrator.js +120 -0
- package/dist/src/ruvector/router-parallel-recorder.d.ts +127 -0
- package/dist/src/ruvector/router-parallel-recorder.js +183 -0
- package/dist/src/ruvector/router-trajectory.d.ts +194 -0
- package/dist/src/ruvector/router-trajectory.js +281 -0
- package/dist/src/ruvector/run-transcript-recorder.d.ts +154 -0
- package/dist/src/ruvector/run-transcript-recorder.js +209 -0
- package/dist/src/ruvector/ruvllm-wasm.d.ts +179 -0
- package/dist/src/ruvector/ruvllm-wasm.js +379 -0
- package/dist/src/ruvector/semantic-router.d.ts +77 -0
- package/dist/src/ruvector/semantic-router.js +178 -0
- package/dist/src/ruvector/task-embedder.d.ts +56 -0
- package/dist/src/ruvector/task-embedder.js +237 -0
- package/dist/src/ruvector/trajectory-tree.d.ts +113 -0
- package/dist/src/ruvector/trajectory-tree.js +237 -0
- package/dist/src/ruvector/vector-db.d.ts +73 -0
- package/dist/src/ruvector/vector-db.js +301 -0
- package/dist/src/ruvector/wasm-embedder.d.ts +13 -0
- package/dist/src/ruvector/wasm-embedder.js +143 -0
- package/dist/src/security/builtin-aidefence.d.ts +34 -0
- package/dist/src/security/builtin-aidefence.js +86 -0
- package/dist/src/services/agentic-flow-bridge.d.ts +50 -0
- package/dist/src/services/agentic-flow-bridge.js +95 -0
- package/dist/src/services/ai-job-dedup.d.ts +61 -0
- package/dist/src/services/ai-job-dedup.js +136 -0
- package/dist/src/services/checkpoint-gate.d.ts +140 -0
- package/dist/src/services/checkpoint-gate.js +223 -0
- package/dist/src/services/claim-service.d.ts +204 -0
- package/dist/src/services/claim-service.js +818 -0
- package/dist/src/services/config-file-manager.d.ts +37 -0
- package/dist/src/services/config-file-manager.js +224 -0
- package/dist/src/services/container-worker-pool.d.ts +204 -0
- package/dist/src/services/container-worker-pool.js +589 -0
- package/dist/src/services/daemon-autostart.d.ts +17 -0
- package/dist/src/services/daemon-autostart.js +102 -0
- package/dist/src/services/distill-oracle.d.ts +190 -0
- package/dist/src/services/distill-oracle.js +349 -0
- package/dist/src/services/distill-tuning.d.ts +111 -0
- package/dist/src/services/distill-tuning.js +510 -0
- package/dist/src/services/evolve-proof.d.ts +253 -0
- package/dist/src/services/evolve-proof.js +343 -0
- package/dist/src/services/fable-harness.d.ts +208 -0
- package/dist/src/services/fable-harness.js +388 -0
- package/dist/src/services/git-workspace-identity.d.ts +42 -0
- package/dist/src/services/git-workspace-identity.js +99 -0
- package/dist/src/services/global-ai-budget.d.ts +135 -0
- package/dist/src/services/global-ai-budget.js +415 -0
- package/dist/src/services/harness-benchmark.d.ts +68 -0
- package/dist/src/services/harness-benchmark.js +94 -0
- package/dist/src/services/harness-canary.d.ts +60 -0
- package/dist/src/services/harness-canary.js +69 -0
- package/dist/src/services/harness-corpus-harvester.d.ts +51 -0
- package/dist/src/services/harness-corpus-harvester.js +74 -0
- package/dist/src/services/harness-flywheel-generations.d.ts +115 -0
- package/dist/src/services/harness-flywheel-generations.js +360 -0
- package/dist/src/services/harness-flywheel-runtime.d.ts +25 -0
- package/dist/src/services/harness-flywheel-runtime.js +92 -0
- package/dist/src/services/harness-flywheel.d.ts +48 -0
- package/dist/src/services/harness-flywheel.js +207 -0
- package/dist/src/services/harness-frozen-eval.d.ts +22 -0
- package/dist/src/services/harness-frozen-eval.js +66 -0
- package/dist/src/services/harness-hosts.d.ts +40 -0
- package/dist/src/services/harness-hosts.js +88 -0
- package/dist/src/services/harness-improvement-ledger.d.ts +63 -0
- package/dist/src/services/harness-improvement-ledger.js +101 -0
- package/dist/src/services/harness-loop.d.ts +53 -0
- package/dist/src/services/harness-loop.js +85 -0
- package/dist/src/services/harness-qualification.d.ts +66 -0
- package/dist/src/services/harness-qualification.js +143 -0
- package/dist/src/services/harness-replay.d.ts +37 -0
- package/dist/src/services/harness-replay.js +92 -0
- package/dist/src/services/harness-verify.d.ts +33 -0
- package/dist/src/services/harness-verify.js +26 -0
- package/dist/src/services/harness-worker.d.ts +23 -0
- package/dist/src/services/harness-worker.js +66 -0
- package/dist/src/services/headless-worker-executor.d.ts +358 -0
- package/dist/src/services/headless-worker-executor.js +1269 -0
- package/dist/src/services/index.d.ts +13 -0
- package/dist/src/services/index.js +11 -0
- package/dist/src/services/memory-backup.d.ts +53 -0
- package/dist/src/services/memory-backup.js +198 -0
- package/dist/src/services/memory-distillation.d.ts +41 -0
- package/dist/src/services/memory-distillation.js +277 -0
- package/dist/src/services/native-training.d.ts +68 -0
- package/dist/src/services/native-training.js +141 -0
- package/dist/src/services/registry-api.d.ts +58 -0
- package/dist/src/services/registry-api.js +146 -0
- package/dist/src/services/repo-supervisor.d.ts +70 -0
- package/dist/src/services/repo-supervisor.js +228 -0
- package/dist/src/services/ruvector-training.d.ts +222 -0
- package/dist/src/services/ruvector-training.js +693 -0
- package/dist/src/services/swarm-memory-branches.d.ts +135 -0
- package/dist/src/services/swarm-memory-branches.js +213 -0
- package/dist/src/services/weight-eft.d.ts +305 -0
- package/dist/src/services/weight-eft.js +296 -0
- package/dist/src/services/worker-daemon.d.ts +439 -0
- package/dist/src/services/worker-daemon.js +1865 -0
- package/dist/src/services/worker-queue.d.ts +194 -0
- package/dist/src/services/worker-queue.js +513 -0
- package/dist/src/services/workspace-lease.d.ts +55 -0
- package/dist/src/services/workspace-lease.js +191 -0
- package/dist/src/suggest.d.ts +53 -0
- package/dist/src/suggest.js +200 -0
- package/dist/src/transfer/anonymization/index.d.ts +25 -0
- package/dist/src/transfer/anonymization/index.js +175 -0
- package/dist/src/transfer/deploy-seraphine.d.ts +13 -0
- package/dist/src/transfer/deploy-seraphine.js +205 -0
- package/dist/src/transfer/export.d.ts +25 -0
- package/dist/src/transfer/export.js +113 -0
- package/dist/src/transfer/index.d.ts +12 -0
- package/dist/src/transfer/index.js +31 -0
- package/dist/src/transfer/ipfs/client.d.ts +109 -0
- package/dist/src/transfer/ipfs/client.js +307 -0
- package/dist/src/transfer/ipfs/upload.d.ts +95 -0
- package/dist/src/transfer/ipfs/upload.js +413 -0
- package/dist/src/transfer/models/seraphine.d.ts +72 -0
- package/dist/src/transfer/models/seraphine.js +373 -0
- package/dist/src/transfer/serialization/cfp.d.ts +49 -0
- package/dist/src/transfer/serialization/cfp.js +183 -0
- package/dist/src/transfer/storage/gcs.d.ts +82 -0
- package/dist/src/transfer/storage/gcs.js +272 -0
- package/dist/src/transfer/storage/index.d.ts +6 -0
- package/dist/src/transfer/storage/index.js +6 -0
- package/dist/src/transfer/store/discovery.d.ts +84 -0
- package/dist/src/transfer/store/discovery.js +382 -0
- package/dist/src/transfer/store/download.d.ts +70 -0
- package/dist/src/transfer/store/download.js +334 -0
- package/dist/src/transfer/store/index.d.ts +84 -0
- package/dist/src/transfer/store/index.js +153 -0
- package/dist/src/transfer/store/publish.d.ts +76 -0
- package/dist/src/transfer/store/publish.js +294 -0
- package/dist/src/transfer/store/registry.d.ts +58 -0
- package/dist/src/transfer/store/registry.js +285 -0
- package/dist/src/transfer/store/search.d.ts +54 -0
- package/dist/src/transfer/store/search.js +232 -0
- package/dist/src/transfer/store/tests/standalone-test.d.ts +12 -0
- package/dist/src/transfer/store/tests/standalone-test.js +190 -0
- package/dist/src/transfer/store/types.d.ts +193 -0
- package/dist/src/transfer/store/types.js +6 -0
- package/dist/src/transfer/test-seraphine.d.ts +6 -0
- package/dist/src/transfer/test-seraphine.js +105 -0
- package/dist/src/transfer/tests/test-store.d.ts +7 -0
- package/dist/src/transfer/tests/test-store.js +214 -0
- package/dist/src/transfer/types.d.ts +245 -0
- package/dist/src/transfer/types.js +6 -0
- package/dist/src/types.d.ts +13 -0
- package/dist/src/types.js +13 -0
- package/dist/src/update/checker.d.ts +34 -0
- package/dist/src/update/checker.js +191 -0
- package/dist/src/update/executor.d.ts +33 -0
- package/dist/src/update/executor.js +217 -0
- package/dist/src/update/index.d.ts +33 -0
- package/dist/src/update/index.js +64 -0
- package/dist/src/update/rate-limiter.d.ts +20 -0
- package/dist/src/update/rate-limiter.js +96 -0
- package/dist/src/update/validator.d.ts +17 -0
- package/dist/src/update/validator.js +123 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Neural MCP Tools for CLI
|
|
3
|
+
*
|
|
4
|
+
* V2 Compatibility - Neural network and ML tools
|
|
5
|
+
*
|
|
6
|
+
* ✅ HYBRID Implementation:
|
|
7
|
+
* - Uses @claude-flow/embeddings for REAL ML embeddings when available
|
|
8
|
+
* - Falls back to deterministic hash-based embeddings when ML model not installed
|
|
9
|
+
* - Pattern storage and search with cosine similarity (real math in all tiers)
|
|
10
|
+
* - Training stores patterns as searchable embeddings (not simulated)
|
|
11
|
+
*
|
|
12
|
+
* Note: For production neural features, use @claude-flow/neural module
|
|
13
|
+
*/
|
|
14
|
+
import { getProjectCwd } from './types.js';
|
|
15
|
+
import { validateIdentifier, validateText } from './validate-input.js';
|
|
16
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
let _corpusStatsCache = null;
|
|
19
|
+
// (query, store) → embedding + cosine cache. Small LRU (not size-1): the flywheel
|
|
20
|
+
// scores many configs across several queries in interleaved order, so a size-1
|
|
21
|
+
// cache would thrash. Cap keeps memory bounded; eviction is oldest-first.
|
|
22
|
+
const _cosineCache = new Map();
|
|
23
|
+
const _COSINE_CACHE_MAX = 128;
|
|
24
|
+
function _cosineCacheGet(key) {
|
|
25
|
+
const v = _cosineCache.get(key);
|
|
26
|
+
if (v) {
|
|
27
|
+
_cosineCache.delete(key);
|
|
28
|
+
_cosineCache.set(key, v);
|
|
29
|
+
} // LRU touch
|
|
30
|
+
return v;
|
|
31
|
+
}
|
|
32
|
+
function _cosineCacheSet(key, v) {
|
|
33
|
+
_cosineCache.set(key, v);
|
|
34
|
+
if (_cosineCache.size > _COSINE_CACHE_MAX)
|
|
35
|
+
_cosineCache.delete(_cosineCache.keys().next().value);
|
|
36
|
+
}
|
|
37
|
+
function corpusFingerprint(patterns) {
|
|
38
|
+
let h = 2166136261 >>> 0;
|
|
39
|
+
for (const p of patterns) {
|
|
40
|
+
const s = `${p.id}|${p.name?.length ?? 0}|${p.content?.length ?? 0}`;
|
|
41
|
+
for (let i = 0; i < s.length; i++) {
|
|
42
|
+
h ^= s.charCodeAt(i);
|
|
43
|
+
h = Math.imul(h, 16777619) >>> 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return `${patterns.length}:${h.toString(16)}`;
|
|
47
|
+
}
|
|
48
|
+
let _champCache = null;
|
|
49
|
+
function activeChampionParams() {
|
|
50
|
+
try {
|
|
51
|
+
if (_champCache && Date.now() - _champCache.at < 30_000)
|
|
52
|
+
return _champCache.params;
|
|
53
|
+
const p = join(getProjectCwd(), '.claude-flow', 'harness-active-policy.json');
|
|
54
|
+
let params = {};
|
|
55
|
+
if (existsSync(p)) {
|
|
56
|
+
const active = JSON.parse(readFileSync(p, 'utf-8'));
|
|
57
|
+
if (active && !active.rolledBack && active.params && typeof active.params === 'object')
|
|
58
|
+
params = active.params;
|
|
59
|
+
}
|
|
60
|
+
_champCache = { at: Date.now(), params };
|
|
61
|
+
return params;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return {};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Real embeddings — resolved LAZILY on first use.
|
|
68
|
+
// Perf (measured 2026-07): the previous top-level-await version of this block
|
|
69
|
+
// ran `await import('ruvector')` + `initOnnxEmbedder()` + a probe embed at
|
|
70
|
+
// module-import time, adding ~450ms (warm) to ~2800ms (cold) to EVERY CLI
|
|
71
|
+
// command, because mcp-client statically imports this module. ensureEmbeddings()
|
|
72
|
+
// keeps the exact same tier chain and degraded/fallback semantics, but only
|
|
73
|
+
// pays the cost when a handler actually needs an embedding.
|
|
74
|
+
// Tier 0 (ADR-089): ruvector@0.2.27 bundled ONNX (no sharp dep, fixes ADR-086's
|
|
75
|
+
// silent-fallback bug at source; closes the chain described in ruvnet/ruvector#523).
|
|
76
|
+
// Tier 1: agentic-flow v3 ReasoningBank (was Tier 1 — broken on darwin-arm64 without sharp)
|
|
77
|
+
// Tier 2-3: @claude-flow/embeddings
|
|
78
|
+
let realEmbeddings = null;
|
|
79
|
+
let embeddingServiceName = 'none';
|
|
80
|
+
let embeddingsPromise = null;
|
|
81
|
+
/**
|
|
82
|
+
* Memoized lazy initialiser for the embedding provider chain. Safe to call
|
|
83
|
+
* concurrently (single shared promise). If every tier fails to import or
|
|
84
|
+
* probe, `realEmbeddings` stays null and callers use the explicit
|
|
85
|
+
* hash-fallback path — identical degraded semantics to the old eager block.
|
|
86
|
+
*/
|
|
87
|
+
function ensureEmbeddings() {
|
|
88
|
+
if (embeddingsPromise)
|
|
89
|
+
return embeddingsPromise;
|
|
90
|
+
embeddingsPromise = (async () => {
|
|
91
|
+
try {
|
|
92
|
+
// Tier -1 (PRIMARY): optional WASM embedder — a pluggable real embedder
|
|
93
|
+
// ahead of everything. OPT-IN (RUFLO_EMBED_WASM_PKG) + FAIL-CLOSED: unset
|
|
94
|
+
// or absent/init-fail ⇒ fall straight through to the existing
|
|
95
|
+
// ruvector-ONNX → hash tiers with zero regression.
|
|
96
|
+
try {
|
|
97
|
+
const we = await import('../ruvector/wasm-embedder.js').catch(() => null);
|
|
98
|
+
if (we && await we.wasmEmbedderAvailable()) {
|
|
99
|
+
const model = we.DEFAULT_EMBED_MODEL;
|
|
100
|
+
realEmbeddings = {
|
|
101
|
+
embed: async (text) => {
|
|
102
|
+
const v = await we.wasmEmbed(text, model);
|
|
103
|
+
if (!v || !v.length)
|
|
104
|
+
throw new Error('wasm embed failed'); // → generateEmbedding falls to next tier
|
|
105
|
+
return v;
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
embeddingServiceName = `wasm-embedder/${model} (${we.wasmEmbedderModels().length} model${we.wasmEmbedderModels().length === 1 ? '' : 's'})`;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch { /* not configured — fall through */ }
|
|
112
|
+
// Tier 0: ruvector@0.2.27 — bundled all-MiniLM-L6-v2 + parallel worker pool.
|
|
113
|
+
// Probe with isOnnxAvailable() and verify an actual embed succeeds (avoids
|
|
114
|
+
// the type-load-success-but-runtime-fails trap from ADR-086). The probe now
|
|
115
|
+
// runs on first embed request instead of at import time.
|
|
116
|
+
// NOTE: ruvector's embed() returns `{embedding, dimension, timeMs}` — we
|
|
117
|
+
// unwrap to plain number[] for the shared interface.
|
|
118
|
+
const rv = !realEmbeddings ? await import('ruvector').catch(() => null) : null;
|
|
119
|
+
if (!realEmbeddings && rv?.embed && typeof rv.embed === 'function' && rv.isOnnxAvailable?.()) {
|
|
120
|
+
try {
|
|
121
|
+
if (typeof rv.initOnnxEmbedder === 'function')
|
|
122
|
+
await rv.initOnnxEmbedder();
|
|
123
|
+
const probe = await rv.embed('probe');
|
|
124
|
+
// Handle both shapes: ruvector wraps as {embedding, dimension, timeMs};
|
|
125
|
+
// some versions returned raw Float32Array.
|
|
126
|
+
const probeVec = probe?.embedding ?? probe;
|
|
127
|
+
if (probeVec && (Array.isArray(probeVec) || probeVec.length > 0)) {
|
|
128
|
+
realEmbeddings = {
|
|
129
|
+
embed: async (text) => {
|
|
130
|
+
const r = await rv.embed(text);
|
|
131
|
+
const v = r?.embedding ?? r;
|
|
132
|
+
return Array.isArray(v) ? v : Array.from(v);
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
embeddingServiceName = 'ruvector@0.2.27 (bundled all-MiniLM-L6-v2)';
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// ruvector embed failed at runtime; fall through to next tier
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Tier 1: agentic-flow v3 ReasoningBank (kept for backward-compat; may
|
|
143
|
+
// silently fall back on darwin-arm64 without sharp — that's the bug
|
|
144
|
+
// Tier 0 was added to bypass).
|
|
145
|
+
if (!realEmbeddings) {
|
|
146
|
+
const rb = await import('agentic-flow/reasoningbank').catch(() => null);
|
|
147
|
+
if (rb?.computeEmbedding) {
|
|
148
|
+
realEmbeddings = { embed: (text) => rb.computeEmbedding(text) };
|
|
149
|
+
embeddingServiceName = 'agentic-flow/reasoningbank';
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Tier 2: @claude-flow/embeddings with agentic-flow provider
|
|
153
|
+
if (!realEmbeddings) {
|
|
154
|
+
const embeddingsModule = await import('@claude-flow/embeddings').catch(() => null);
|
|
155
|
+
if (embeddingsModule?.createEmbeddingService) {
|
|
156
|
+
try {
|
|
157
|
+
const service = embeddingsModule.createEmbeddingService({ provider: 'agentic-flow' });
|
|
158
|
+
realEmbeddings = {
|
|
159
|
+
embed: async (text) => {
|
|
160
|
+
const result = await service.embed(text);
|
|
161
|
+
return Array.from(result.embedding);
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
embeddingServiceName = 'agentic-flow';
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// agentic-flow provider not available, try ONNX
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Tier 3: @claude-flow/embeddings with ONNX provider
|
|
172
|
+
if (!realEmbeddings) {
|
|
173
|
+
const embeddingsModule = await import('@claude-flow/embeddings').catch(() => null);
|
|
174
|
+
if (embeddingsModule?.createEmbeddingService) {
|
|
175
|
+
try {
|
|
176
|
+
const service = embeddingsModule.createEmbeddingService({ provider: 'onnx' });
|
|
177
|
+
realEmbeddings = {
|
|
178
|
+
embed: async (text) => {
|
|
179
|
+
const result = await service.embed(text);
|
|
180
|
+
return Array.from(result.embedding);
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
embeddingServiceName = 'onnx';
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// ONNX provider not available, fall through to mock
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// No Tier 4 mock fallback. If all real-embedder tiers fail to import or
|
|
191
|
+
// probe, leave realEmbeddings null and let downstream code use the
|
|
192
|
+
// explicit hash-fallback path with a clear _embeddingNote in stats.
|
|
193
|
+
// Silently substituting mock embeddings would hide a missing production
|
|
194
|
+
// dependency from callers — that's the bug ADR-086 was about.
|
|
195
|
+
}
|
|
196
|
+
catch {
|
|
197
|
+
// No embedding provider available, will use fallback
|
|
198
|
+
}
|
|
199
|
+
})();
|
|
200
|
+
return embeddingsPromise;
|
|
201
|
+
}
|
|
202
|
+
// Storage paths
|
|
203
|
+
const STORAGE_DIR = '.claude-flow';
|
|
204
|
+
const NEURAL_DIR = 'neural';
|
|
205
|
+
const MODELS_FILE = 'models.json';
|
|
206
|
+
const PATTERNS_FILE = 'patterns.json';
|
|
207
|
+
function getNeuralDir() {
|
|
208
|
+
return join(getProjectCwd(), STORAGE_DIR, NEURAL_DIR);
|
|
209
|
+
}
|
|
210
|
+
function getNeuralPath() {
|
|
211
|
+
return join(getNeuralDir(), MODELS_FILE);
|
|
212
|
+
}
|
|
213
|
+
function ensureNeuralDir() {
|
|
214
|
+
const dir = getNeuralDir();
|
|
215
|
+
if (!existsSync(dir)) {
|
|
216
|
+
mkdirSync(dir, { recursive: true });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function loadNeuralStore() {
|
|
220
|
+
try {
|
|
221
|
+
const path = getNeuralPath();
|
|
222
|
+
if (existsSync(path)) {
|
|
223
|
+
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// Return empty store
|
|
228
|
+
}
|
|
229
|
+
return { models: {}, patterns: {}, version: '3.0.0' };
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* ADR-176 flywheel: expose the stored patterns (id/name/content) so the
|
|
233
|
+
* self-optimizing loop can harvest a benchmark corpus from real usage. Additive,
|
|
234
|
+
* read-only, never throws.
|
|
235
|
+
*/
|
|
236
|
+
export function getStorePatterns() {
|
|
237
|
+
try {
|
|
238
|
+
return Object.values(loadNeuralStore().patterns ?? {}).map((p) => ({ id: p.id, name: p.name, content: p.content }));
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return [];
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function saveNeuralStore(store) {
|
|
245
|
+
ensureNeuralDir();
|
|
246
|
+
writeFileSync(getNeuralPath(), JSON.stringify(store, null, 2), 'utf-8');
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Public helper: read-only stats about the neural store, for the unified
|
|
250
|
+
* learning-stats aggregator. Returns total pattern count + per-type breakdown
|
|
251
|
+
* without exposing the embeddings.
|
|
252
|
+
*/
|
|
253
|
+
export function getNeuralStoreStats() {
|
|
254
|
+
const store = loadNeuralStore();
|
|
255
|
+
const patterns = Object.values(store.patterns ?? {});
|
|
256
|
+
const byType = {};
|
|
257
|
+
for (const p of patterns) {
|
|
258
|
+
const t = p.type || 'unknown';
|
|
259
|
+
byType[t] = (byType[t] ?? 0) + 1;
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
patternCount: patterns.length,
|
|
263
|
+
byType,
|
|
264
|
+
modelCount: Object.values(store.models ?? {}).length,
|
|
265
|
+
source: '.claude-flow/neural/patterns.json (loadNeuralStore)',
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Public helper: store an array of patterns into the neural store so they
|
|
270
|
+
* surface via `neural_patterns list`. Used by hooks_pretrain so its extracted
|
|
271
|
+
* patterns are actually queryable, not just bundled in the `pretrain` namespace.
|
|
272
|
+
* #2245.
|
|
273
|
+
*
|
|
274
|
+
* Returns the number of patterns written.
|
|
275
|
+
*/
|
|
276
|
+
export async function storeNeuralPatterns(items) {
|
|
277
|
+
if (!items || items.length === 0)
|
|
278
|
+
return { stored: 0, total: 0 };
|
|
279
|
+
// realEmbeddings is initialised lazily by ensureEmbeddings() (invoked from
|
|
280
|
+
// generateEmbedding()); it falls back to a hash-based embedding if no
|
|
281
|
+
// provider is available.
|
|
282
|
+
const store = loadNeuralStore();
|
|
283
|
+
let stored = 0;
|
|
284
|
+
for (const item of items) {
|
|
285
|
+
if (!item.name || !item.type)
|
|
286
|
+
continue;
|
|
287
|
+
const sourceText = item.content ?? item.name;
|
|
288
|
+
const embedding = await generateEmbedding(sourceText);
|
|
289
|
+
const id = `pattern-${Date.now()}-${stored.toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
|
|
290
|
+
store.patterns[id] = {
|
|
291
|
+
id,
|
|
292
|
+
name: String(item.name).slice(0, 200),
|
|
293
|
+
type: String(item.type).slice(0, 64),
|
|
294
|
+
embedding,
|
|
295
|
+
content: typeof sourceText === 'string' ? sourceText.slice(0, 4096) : undefined,
|
|
296
|
+
metadata: item.metadata ?? {},
|
|
297
|
+
createdAt: new Date().toISOString(),
|
|
298
|
+
usageCount: 0,
|
|
299
|
+
};
|
|
300
|
+
stored++;
|
|
301
|
+
}
|
|
302
|
+
saveNeuralStore(store);
|
|
303
|
+
return { stored, total: items.length };
|
|
304
|
+
}
|
|
305
|
+
// Generate embedding - uses real ML embeddings if available, falls back to deterministic hash
|
|
306
|
+
async function generateEmbedding(text, dims = 384) {
|
|
307
|
+
// Lazily resolve the embedding provider on first real use (perf: keeps
|
|
308
|
+
// ONNX init off the CLI startup path — see ensureEmbeddings()).
|
|
309
|
+
if (text)
|
|
310
|
+
await ensureEmbeddings();
|
|
311
|
+
// If real embeddings available and text provided, use them
|
|
312
|
+
if (realEmbeddings && text) {
|
|
313
|
+
try {
|
|
314
|
+
return await realEmbeddings.embed(text);
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
// Fall back to hash-based
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Hash-based deterministic embedding (better than pure random for consistency)
|
|
321
|
+
// NOTE: No semantic meaning — only useful for consistent deduplication, not similarity search
|
|
322
|
+
if (text) {
|
|
323
|
+
(await import('../memory/embedding-policy.js')).enforceNoStub('neural-tools.generateEmbedding'); // "no stubs" strict mode
|
|
324
|
+
if (embeddingServiceName === 'none') {
|
|
325
|
+
embeddingServiceName = 'hash-fallback';
|
|
326
|
+
}
|
|
327
|
+
const hash = text.split('').reduce((acc, char, i) => {
|
|
328
|
+
return acc + char.charCodeAt(0) * (i + 1);
|
|
329
|
+
}, 0);
|
|
330
|
+
// Use hash to seed a deterministic embedding
|
|
331
|
+
const embedding = [];
|
|
332
|
+
let seed = hash;
|
|
333
|
+
for (let i = 0; i < dims; i++) {
|
|
334
|
+
// Simple LCG random with seed
|
|
335
|
+
seed = (seed * 1103515245 + 12345) & 0x7fffffff;
|
|
336
|
+
embedding.push((seed / 0x7fffffff) * 2 - 1);
|
|
337
|
+
}
|
|
338
|
+
return embedding;
|
|
339
|
+
}
|
|
340
|
+
// No text provided — return zero vector (callers should always provide text)
|
|
341
|
+
return new Array(dims).fill(0);
|
|
342
|
+
}
|
|
343
|
+
// Cosine similarity for pattern search
|
|
344
|
+
function cosineSimilarity(a, b) {
|
|
345
|
+
if (a.length !== b.length)
|
|
346
|
+
return 0;
|
|
347
|
+
let dotProduct = 0;
|
|
348
|
+
let normA = 0;
|
|
349
|
+
let normB = 0;
|
|
350
|
+
for (let i = 0; i < a.length; i++) {
|
|
351
|
+
dotProduct += a[i] * b[i];
|
|
352
|
+
normA += a[i] * a[i];
|
|
353
|
+
normB += b[i] * b[i];
|
|
354
|
+
}
|
|
355
|
+
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB) || 1);
|
|
356
|
+
}
|
|
357
|
+
export const neuralTools = [
|
|
358
|
+
{
|
|
359
|
+
name: 'neural_train',
|
|
360
|
+
description: 'Train a neural model Use when nothing native trains on your workflow — Claude Code has no learning loop. Use to train SONA/MoE/EWC patterns from successful task outcomes; query via neural_predict before spawning agents. Off-path for one-shot work.',
|
|
361
|
+
category: 'neural',
|
|
362
|
+
inputSchema: {
|
|
363
|
+
type: 'object',
|
|
364
|
+
properties: {
|
|
365
|
+
modelId: { type: 'string', description: 'Model ID to train' },
|
|
366
|
+
modelType: { type: 'string', enum: ['moe', 'transformer', 'classifier', 'embedding'], description: 'Model type' },
|
|
367
|
+
epochs: { type: 'number', description: 'Number of training epochs' },
|
|
368
|
+
learningRate: { type: 'number', description: 'Learning rate' },
|
|
369
|
+
data: { type: 'object', description: 'Training data' },
|
|
370
|
+
},
|
|
371
|
+
required: ['modelType'],
|
|
372
|
+
},
|
|
373
|
+
handler: async (input) => {
|
|
374
|
+
if (input.modelId) {
|
|
375
|
+
const v = validateIdentifier(input.modelId, 'modelId');
|
|
376
|
+
if (!v.valid)
|
|
377
|
+
return { success: false, error: v.error };
|
|
378
|
+
}
|
|
379
|
+
const store = loadNeuralStore();
|
|
380
|
+
const modelId = input.modelId || `model-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
381
|
+
const modelType = input.modelType;
|
|
382
|
+
const epochs = input.epochs || 10;
|
|
383
|
+
const model = {
|
|
384
|
+
id: modelId,
|
|
385
|
+
name: `${modelType}-model`,
|
|
386
|
+
type: modelType,
|
|
387
|
+
status: 'training',
|
|
388
|
+
accuracy: 0,
|
|
389
|
+
epochs,
|
|
390
|
+
config: {
|
|
391
|
+
learningRate: input.learningRate || 0.001,
|
|
392
|
+
batchSize: 32,
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
store.models[modelId] = model;
|
|
396
|
+
saveNeuralStore(store);
|
|
397
|
+
// Real training: embed training data and store as searchable patterns
|
|
398
|
+
const trainingData = input.data;
|
|
399
|
+
let patternsStored = 0;
|
|
400
|
+
if (trainingData) {
|
|
401
|
+
const entries = Array.isArray(trainingData) ? trainingData : [trainingData];
|
|
402
|
+
for (let i = 0; i < entries.length; i++) {
|
|
403
|
+
const entry = entries[i];
|
|
404
|
+
const text = typeof entry === 'string' ? entry
|
|
405
|
+
: entry?.text
|
|
406
|
+
|| entry?.content
|
|
407
|
+
|| entry?.label
|
|
408
|
+
|| JSON.stringify(entry);
|
|
409
|
+
if (!text)
|
|
410
|
+
continue;
|
|
411
|
+
const embedding = await generateEmbedding(text, 384);
|
|
412
|
+
const patternId = `${modelId}-train-${i}`;
|
|
413
|
+
// ADR-093 F11: extract a meaningful label instead of dumping raw
|
|
414
|
+
// training JSON as the pattern name. Audit reported neural_predict
|
|
415
|
+
// returned `label: <raw training data JSON>` because the previous
|
|
416
|
+
// fallback was `text.slice(0, 100)` where text was `JSON.stringify(entry)`.
|
|
417
|
+
let label;
|
|
418
|
+
if (typeof entry === 'string') {
|
|
419
|
+
label = entry.slice(0, 80);
|
|
420
|
+
}
|
|
421
|
+
else if (entry && typeof entry === 'object') {
|
|
422
|
+
const e = entry;
|
|
423
|
+
// Prefer common semantic fields over a JSON dump
|
|
424
|
+
const labelField = e.label ?? e.category ?? e.class ?? e.tag ?? e.intent ?? e.name ?? e.title;
|
|
425
|
+
if (typeof labelField === 'string' && labelField.length > 0) {
|
|
426
|
+
label = labelField.slice(0, 80);
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
const summaryField = e.text ?? e.input ?? e.task ?? e.description ?? e.content;
|
|
430
|
+
if (typeof summaryField === 'string' && summaryField.length > 0) {
|
|
431
|
+
label = `${summaryField.slice(0, 60)}${summaryField.length > 60 ? '…' : ''}`;
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
// Last resort: reduce to a stable short hash-like id
|
|
435
|
+
label = `${modelType}:entry-${i}`;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
label = `${modelType}:entry-${i}`;
|
|
441
|
+
}
|
|
442
|
+
store.patterns[patternId] = {
|
|
443
|
+
id: patternId,
|
|
444
|
+
name: label,
|
|
445
|
+
type: modelType,
|
|
446
|
+
embedding,
|
|
447
|
+
metadata: { modelId, epoch: epochs, index: i, raw: entry },
|
|
448
|
+
createdAt: new Date().toISOString(),
|
|
449
|
+
usageCount: 0,
|
|
450
|
+
};
|
|
451
|
+
patternsStored++;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
model.status = 'ready';
|
|
455
|
+
model.accuracy = patternsStored > 0 ? 1.0 : 0; // accuracy = data stored, not simulated
|
|
456
|
+
model.trainedAt = new Date().toISOString();
|
|
457
|
+
saveNeuralStore(store);
|
|
458
|
+
return {
|
|
459
|
+
success: true,
|
|
460
|
+
_realEmbedding: !!realEmbeddings,
|
|
461
|
+
_embeddingSource: embeddingServiceName,
|
|
462
|
+
embeddingProvider: embeddingServiceName,
|
|
463
|
+
modelId,
|
|
464
|
+
type: modelType,
|
|
465
|
+
status: model.status,
|
|
466
|
+
patternsStored,
|
|
467
|
+
totalPatterns: Object.keys(store.patterns).length,
|
|
468
|
+
epochs,
|
|
469
|
+
trainedAt: model.trainedAt,
|
|
470
|
+
...(embeddingServiceName === 'hash-fallback' || embeddingServiceName === 'none' ? {
|
|
471
|
+
platformNote: 'ONNX embeddings not available — using hash-based fallback. Install @claude-flow/embeddings and run "embeddings init --download" for semantic search.',
|
|
472
|
+
} : {}),
|
|
473
|
+
};
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
name: 'neural_predict',
|
|
478
|
+
description: 'Make predictions using a neural model Use when nothing native trains on your workflow — Claude Code has no learning loop. Use to train SONA/MoE/EWC patterns from successful task outcomes; query via neural_predict before spawning agents. Off-path for one-shot work.',
|
|
479
|
+
category: 'neural',
|
|
480
|
+
inputSchema: {
|
|
481
|
+
type: 'object',
|
|
482
|
+
properties: {
|
|
483
|
+
modelId: { type: 'string', description: 'Model ID to use' },
|
|
484
|
+
input: { type: 'string', description: 'Input text or data' },
|
|
485
|
+
topK: { type: 'number', description: 'Number of top predictions' },
|
|
486
|
+
},
|
|
487
|
+
required: ['input'],
|
|
488
|
+
},
|
|
489
|
+
handler: async (input) => {
|
|
490
|
+
{
|
|
491
|
+
const v = validateText(input.input, 'input');
|
|
492
|
+
if (!v.valid)
|
|
493
|
+
return { success: false, error: v.error };
|
|
494
|
+
}
|
|
495
|
+
if (input.modelId) {
|
|
496
|
+
const v = validateIdentifier(input.modelId, 'modelId');
|
|
497
|
+
if (!v.valid)
|
|
498
|
+
return { success: false, error: v.error };
|
|
499
|
+
}
|
|
500
|
+
const store = loadNeuralStore();
|
|
501
|
+
const modelId = input.modelId;
|
|
502
|
+
const inputText = input.input;
|
|
503
|
+
const topK = input.topK || 3;
|
|
504
|
+
// Find model or use default
|
|
505
|
+
const model = modelId ? store.models[modelId] : Object.values(store.models).find(m => m.status === 'ready');
|
|
506
|
+
if (model && model.status !== 'ready') {
|
|
507
|
+
return { success: false, error: 'Model not ready' };
|
|
508
|
+
}
|
|
509
|
+
// Generate real embedding for the input
|
|
510
|
+
const startTime = performance.now();
|
|
511
|
+
const embedding = await generateEmbedding(inputText, 384);
|
|
512
|
+
const latency = Math.round(performance.now() - startTime);
|
|
513
|
+
// ADR-093 F11: real classifier head over stored patterns. Previously
|
|
514
|
+
// confidence was the raw cosine similarity (often clamped to 0 when
|
|
515
|
+
// stored embeddings were stale or zero-vectored). Now we run k-NN
|
|
516
|
+
// with cosine distance and apply a temperature-controlled softmax
|
|
517
|
+
// over the top-K so confidence is a proper distribution that sums
|
|
518
|
+
// to 1, and we surface enough metadata to trust the result.
|
|
519
|
+
const storedPatterns = Object.values(store.patterns);
|
|
520
|
+
let predictions;
|
|
521
|
+
if (storedPatterns.length > 0) {
|
|
522
|
+
// Step 1: k-NN with cosine
|
|
523
|
+
const scored = storedPatterns
|
|
524
|
+
.map(p => {
|
|
525
|
+
const sim = cosineSimilarity(embedding, p.embedding);
|
|
526
|
+
return {
|
|
527
|
+
patternId: p.id,
|
|
528
|
+
label: p.name || p.type || p.id,
|
|
529
|
+
cosineSimilarity: sim,
|
|
530
|
+
};
|
|
531
|
+
})
|
|
532
|
+
.sort((a, b) => b.cosineSimilarity - a.cosineSimilarity)
|
|
533
|
+
.slice(0, topK);
|
|
534
|
+
// Step 2: temperature-softmax over the top-K so confidence sums to 1.
|
|
535
|
+
// Temperature 0.1 sharpens differences between similar candidates.
|
|
536
|
+
const tau = 0.1;
|
|
537
|
+
const exps = scored.map(s => Math.exp(s.cosineSimilarity / tau));
|
|
538
|
+
const z = exps.reduce((a, b) => a + b, 0) || 1;
|
|
539
|
+
predictions = scored.map((s, i) => ({
|
|
540
|
+
label: s.label,
|
|
541
|
+
patternId: s.patternId,
|
|
542
|
+
cosineSimilarity: Number(s.cosineSimilarity.toFixed(4)),
|
|
543
|
+
confidence: Number((exps[i] / z).toFixed(4)),
|
|
544
|
+
}));
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
// No patterns stored — no predictions possible. Be honest about it
|
|
548
|
+
// instead of returning empty silently.
|
|
549
|
+
predictions = [];
|
|
550
|
+
}
|
|
551
|
+
const topConfidence = predictions[0]?.confidence ?? 0;
|
|
552
|
+
const topSimilarity = predictions[0]?.cosineSimilarity ?? 0;
|
|
553
|
+
return {
|
|
554
|
+
success: true,
|
|
555
|
+
_realEmbedding: !!realEmbeddings,
|
|
556
|
+
_embeddingSource: embeddingServiceName,
|
|
557
|
+
embeddingProvider: embeddingServiceName,
|
|
558
|
+
_hasStoredPatterns: storedPatterns.length > 0,
|
|
559
|
+
_classifierHead: storedPatterns.length > 0 ? 'knn-cosine+softmax(tau=0.1)' : 'none',
|
|
560
|
+
modelId: model?.id || 'default',
|
|
561
|
+
input: inputText,
|
|
562
|
+
predictions,
|
|
563
|
+
// Surface cosineSimilarity separately so callers know whether the
|
|
564
|
+
// softmax confidence reflects true match strength.
|
|
565
|
+
topPrediction: predictions[0]?.label ?? null,
|
|
566
|
+
topConfidence,
|
|
567
|
+
topSimilarity,
|
|
568
|
+
embedding: embedding.slice(0, 8), // Preview of embedding
|
|
569
|
+
embeddingDims: embedding.length,
|
|
570
|
+
latency,
|
|
571
|
+
...(storedPatterns.length === 0 ? {
|
|
572
|
+
_note: 'No patterns stored. Train with neural_train(modelType, trainingData) before predicting.',
|
|
573
|
+
} : {}),
|
|
574
|
+
};
|
|
575
|
+
},
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
name: 'neural_patterns',
|
|
579
|
+
description: 'Get or manage neural patterns Use when nothing native trains on your workflow — Claude Code has no learning loop. Use to train SONA/MoE/EWC patterns from successful task outcomes; query via neural_predict before spawning agents. Off-path for one-shot work.',
|
|
580
|
+
category: 'neural',
|
|
581
|
+
inputSchema: {
|
|
582
|
+
type: 'object',
|
|
583
|
+
properties: {
|
|
584
|
+
action: { type: 'string', enum: ['list', 'get', 'store', 'search', 'delete'], description: 'Action to perform' },
|
|
585
|
+
patternId: { type: 'string', description: 'Pattern ID' },
|
|
586
|
+
name: { type: 'string', description: 'Pattern name' },
|
|
587
|
+
type: { type: 'string', description: 'Pattern type' },
|
|
588
|
+
content: { type: 'string', description: 'Pattern source text (used for BM25 in hybrid search; falls back to name)' },
|
|
589
|
+
query: { type: 'string', description: 'Search query' },
|
|
590
|
+
limit: { type: 'number', description: 'Top-K results to return (default 10, max 100)' },
|
|
591
|
+
mode: { type: 'string', enum: ['hybrid', 'cosine'], description: 'Search mode — hybrid (cosine+BM25+MMR, default) or cosine (pre-3.10.18 behaviour, for A/B)' },
|
|
592
|
+
alpha: { type: 'number', description: 'Hybrid: cosine weight in [0,1]; (1-α) is BM25 weight (default 0.5, tuned ADR-082)' },
|
|
593
|
+
mmrLambda: { type: 'number', description: 'Hybrid: MMR balance — 1.0 = pure relevance, 0.0 = pure diversity (default 0.7, tuned ADR-082)' },
|
|
594
|
+
subjectWeight: { type: 'number', description: 'Hybrid: multi-field BM25 weight for subject/name (default 2.0 non-rerank, 3.0 with rerank — tuned ADR-082/083)' },
|
|
595
|
+
bodyWeight: { type: 'number', description: 'Hybrid: multi-field BM25 weight for body/content (default 1.0)' },
|
|
596
|
+
typePenaltyFactor: { type: 'number', description: 'Hybrid: meta-commit score multiplier — release/merge/bump commits × this factor (default 1.0 = disabled; set 0.5 for aggressive suppression)' },
|
|
597
|
+
rerank: { type: 'boolean', description: 'Hybrid: opt-in cross-encoder rerank pass over the top-K (ADR-080). Adds ~20-40 ms per (query, doc) pair; first call downloads ~30MB model. Gracefully degrades to hybrid+MMR order when unavailable.' },
|
|
598
|
+
hybridWeight: { type: 'number', description: 'Rerank: hybrid score weight in final combination (default 0.7, tuned ADR-083)' },
|
|
599
|
+
ceWeight: { type: 'number', description: 'Rerank: cross-encoder score weight in final combination (default 0.3, tuned ADR-083)' },
|
|
600
|
+
data: { type: 'object', description: 'Pattern data' },
|
|
601
|
+
},
|
|
602
|
+
},
|
|
603
|
+
handler: async (input) => {
|
|
604
|
+
if (input.patternId) {
|
|
605
|
+
const v = validateIdentifier(input.patternId, 'patternId');
|
|
606
|
+
if (!v.valid)
|
|
607
|
+
return { success: false, error: v.error };
|
|
608
|
+
}
|
|
609
|
+
if (input.name) {
|
|
610
|
+
const v = validateText(input.name, 'name');
|
|
611
|
+
if (!v.valid)
|
|
612
|
+
return { success: false, error: v.error };
|
|
613
|
+
}
|
|
614
|
+
if (input.type) {
|
|
615
|
+
const v = validateIdentifier(input.type, 'type');
|
|
616
|
+
if (!v.valid)
|
|
617
|
+
return { success: false, error: v.error };
|
|
618
|
+
}
|
|
619
|
+
if (input.query) {
|
|
620
|
+
const v = validateText(input.query, 'query');
|
|
621
|
+
if (!v.valid)
|
|
622
|
+
return { success: false, error: v.error };
|
|
623
|
+
}
|
|
624
|
+
const store = loadNeuralStore();
|
|
625
|
+
const action = input.action || 'list';
|
|
626
|
+
if (action === 'list') {
|
|
627
|
+
const patterns = Object.values(store.patterns);
|
|
628
|
+
const typeFilter = input.type;
|
|
629
|
+
const filtered = typeFilter ? patterns.filter(p => p.type === typeFilter) : patterns;
|
|
630
|
+
return {
|
|
631
|
+
patterns: filtered.map(p => ({
|
|
632
|
+
id: p.id,
|
|
633
|
+
name: p.name,
|
|
634
|
+
type: p.type,
|
|
635
|
+
usageCount: p.usageCount,
|
|
636
|
+
createdAt: p.createdAt,
|
|
637
|
+
})),
|
|
638
|
+
total: filtered.length,
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
if (action === 'get') {
|
|
642
|
+
const pattern = store.patterns[input.patternId];
|
|
643
|
+
if (!pattern) {
|
|
644
|
+
return { success: false, error: 'Pattern not found' };
|
|
645
|
+
}
|
|
646
|
+
return { success: true, pattern };
|
|
647
|
+
}
|
|
648
|
+
if (action === 'store') {
|
|
649
|
+
const patternId = `pattern-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
650
|
+
const patternName = input.name || 'Unnamed pattern';
|
|
651
|
+
const patternContent = input.content ?? patternName;
|
|
652
|
+
// Generate embedding from pattern content (falls back to name).
|
|
653
|
+
const embedding = await generateEmbedding(patternContent, 384);
|
|
654
|
+
const pattern = {
|
|
655
|
+
id: patternId,
|
|
656
|
+
name: patternName,
|
|
657
|
+
type: input.type || 'general',
|
|
658
|
+
embedding,
|
|
659
|
+
content: typeof patternContent === 'string' ? patternContent.slice(0, 4096) : undefined,
|
|
660
|
+
metadata: input.data || {},
|
|
661
|
+
createdAt: new Date().toISOString(),
|
|
662
|
+
usageCount: 0,
|
|
663
|
+
};
|
|
664
|
+
store.patterns[patternId] = pattern;
|
|
665
|
+
saveNeuralStore(store);
|
|
666
|
+
return {
|
|
667
|
+
success: true,
|
|
668
|
+
_realEmbedding: !!realEmbeddings,
|
|
669
|
+
_embeddingSource: embeddingServiceName,
|
|
670
|
+
embeddingProvider: embeddingServiceName,
|
|
671
|
+
patternId,
|
|
672
|
+
name: pattern.name,
|
|
673
|
+
type: pattern.type,
|
|
674
|
+
embeddingDims: embedding.length,
|
|
675
|
+
createdAt: pattern.createdAt,
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
if (action === 'search') {
|
|
679
|
+
const query = input.query;
|
|
680
|
+
const k = Math.min(Math.max(Number(input.limit ?? input.topK ?? 10), 1), 100);
|
|
681
|
+
// ADR-078 hybrid retrieval controls. Cosine-only mode preserves the
|
|
682
|
+
// pre-3.10.18 behaviour for A/B tests via {mode:'cosine'}; default is
|
|
683
|
+
// hybrid (cosine + BM25 + MMR).
|
|
684
|
+
const mode = String(input.mode ?? 'hybrid');
|
|
685
|
+
const useRerank = input.rerank === true || String(input.rerank) === 'true';
|
|
686
|
+
// ADR-083 joint grid: rerank path benefits from DIFFERENT hybrid
|
|
687
|
+
// sub-params than non-rerank (the cross-encoder adds semantic depth,
|
|
688
|
+
// so the hybrid stage can be more keyword-focused). nDCG@3 0.900 →
|
|
689
|
+
// 0.963 on rerank just by switching sw 2.0 → 3.0 in the hybrid stage.
|
|
690
|
+
// Champion-provided defaults (ADR-176/177): explicit input wins, then the
|
|
691
|
+
// adopted proven-config champion, then the hardcoded ADR-082 defaults.
|
|
692
|
+
const champ = activeChampionParams();
|
|
693
|
+
const alpha = Number(input.alpha ?? champ.alpha ?? 0.5);
|
|
694
|
+
const mmrLambda = Number(input.mmrLambda ?? champ.mmrLambda ?? 0.7);
|
|
695
|
+
const { tokenize, buildCorpusStats, hybridScores, mmrRerank, multiFieldBM25, typePenalty } = await import('../memory/hybrid-retrieval.js');
|
|
696
|
+
const patterns = Object.values(store.patterns);
|
|
697
|
+
// Query embedding + cosine array depend only on (query, store) — NOT the
|
|
698
|
+
// retrieval config. Cache them so scoring many configs for one query
|
|
699
|
+
// (the flywheel's access pattern) embeds + cosines once, not per config.
|
|
700
|
+
const _cosKey = `${corpusFingerprint(patterns)}::${query}`;
|
|
701
|
+
let queryEmbedding, cosineArr;
|
|
702
|
+
const _hit = _cosineCacheGet(_cosKey);
|
|
703
|
+
if (_hit) {
|
|
704
|
+
queryEmbedding = _hit.queryEmbedding;
|
|
705
|
+
cosineArr = _hit.cosineArr;
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
queryEmbedding = await generateEmbedding(query, 384);
|
|
709
|
+
cosineArr = patterns.map((p) => cosineSimilarity(queryEmbedding, p.embedding));
|
|
710
|
+
_cosineCacheSet(_cosKey, { queryEmbedding, cosineArr });
|
|
711
|
+
}
|
|
712
|
+
if (mode === 'cosine') {
|
|
713
|
+
const ranked = patterns
|
|
714
|
+
.map((p, i) => ({ ...p, similarity: cosineArr[i] }))
|
|
715
|
+
.sort((a, b) => b.similarity - a.similarity)
|
|
716
|
+
.slice(0, k);
|
|
717
|
+
return {
|
|
718
|
+
_realSimilarity: true,
|
|
719
|
+
_realEmbedding: !!realEmbeddings,
|
|
720
|
+
_embeddingSource: embeddingServiceName,
|
|
721
|
+
embeddingProvider: embeddingServiceName,
|
|
722
|
+
mode: 'cosine',
|
|
723
|
+
query,
|
|
724
|
+
results: ranked.map((r) => ({ id: r.id, name: r.name, type: r.type, similarity: r.similarity })),
|
|
725
|
+
total: ranked.length,
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
// Hybrid path — multi-field BM25 (subject 3×, body 1×) + type penalty
|
|
729
|
+
// for meta-commits (release bumps / merges) per ADR-079. Falls back
|
|
730
|
+
// to single-field BM25 when no content is stored.
|
|
731
|
+
// Cache the (config-independent) tokenized docs + BM25 stats by store fingerprint.
|
|
732
|
+
const _fp = corpusFingerprint(patterns);
|
|
733
|
+
let subjectDocs, bodyDocs, subjectStats, bodyStats;
|
|
734
|
+
if (_corpusStatsCache && _corpusStatsCache.fp === _fp) {
|
|
735
|
+
subjectDocs = _corpusStatsCache.subjectDocs;
|
|
736
|
+
bodyDocs = _corpusStatsCache.bodyDocs;
|
|
737
|
+
subjectStats = _corpusStatsCache.subjectStats;
|
|
738
|
+
bodyStats = _corpusStatsCache.bodyStats;
|
|
739
|
+
}
|
|
740
|
+
else {
|
|
741
|
+
subjectDocs = patterns.map((p) => tokenize(p.name ?? ''));
|
|
742
|
+
bodyDocs = patterns.map((p) => {
|
|
743
|
+
// Body is content minus the subject — if content starts with name,
|
|
744
|
+
// strip it; otherwise use full content (with name removed if duplicated).
|
|
745
|
+
const c = p.content ?? '';
|
|
746
|
+
const n = p.name ?? '';
|
|
747
|
+
return tokenize(c.startsWith(n) ? c.slice(n.length) : c);
|
|
748
|
+
});
|
|
749
|
+
subjectStats = buildCorpusStats(subjectDocs);
|
|
750
|
+
bodyStats = buildCorpusStats(bodyDocs);
|
|
751
|
+
_corpusStatsCache = { fp: _fp, subjectDocs, bodyDocs, subjectStats, bodyStats };
|
|
752
|
+
}
|
|
753
|
+
const queryTokens = tokenize(query);
|
|
754
|
+
// ADR-082: subjectWeight 3.0 → 2.0 from grid (sw=2 dominates at hybrid-only).
|
|
755
|
+
// ADR-083 joint grid: when rerank is on, the cross-encoder handles
|
|
756
|
+
// semantic understanding, so the hybrid stage can be MORE
|
|
757
|
+
// subject-focused (sw=3) — recovers nDCG@3 0.963.
|
|
758
|
+
const subjectWeight = Number(input.subjectWeight ?? champ.subjectWeight ?? (useRerank ? 3.0 : 2.0));
|
|
759
|
+
const bodyWeight = Number(input.bodyWeight ?? champ.bodyWeight ?? 1.0);
|
|
760
|
+
const bm25Arr = patterns.map((_, i) => multiFieldBM25(queryTokens, subjectDocs[i], bodyDocs[i], subjectStats, bodyStats, subjectWeight, bodyWeight));
|
|
761
|
+
const baseHybrid = hybridScores(cosineArr, bm25Arr, alpha);
|
|
762
|
+
// Type penalty — opt-in (default 1.0 = disabled). Ablation in ADR-079
|
|
763
|
+
// showed multi-field BM25 alone gives best top-1 (8/10 vs 7/10 with
|
|
764
|
+
// penalty enabled) because some relevant work commits also match the
|
|
765
|
+
// Merge/release regex. Callers wanting aggressive meta-commit
|
|
766
|
+
// suppression can set {typePenaltyFactor: 0.5}.
|
|
767
|
+
const typeFactor = Number(input.typePenaltyFactor ?? champ.typePenaltyFactor ?? 1.0);
|
|
768
|
+
const hybridArr = typeFactor === 1.0
|
|
769
|
+
? baseHybrid
|
|
770
|
+
: baseHybrid.map((s, i) => s * typePenalty(patterns[i].name, typeFactor));
|
|
771
|
+
// Candidate pool sizing: k*3 for MMR, k*6 for cross-encoder (it needs
|
|
772
|
+
// more options to find the truly-best). ADR-080 ablation: rerank over
|
|
773
|
+
// a narrow post-MMR slice degrades top-1; reranking a wider hybrid
|
|
774
|
+
// top-K*6 pool restores and exceeds the no-rerank baseline.
|
|
775
|
+
// useRerank declared at top of search block for conditional defaults.
|
|
776
|
+
const poolSize = useRerank ? k * 6 : k * 3;
|
|
777
|
+
const prelim = patterns
|
|
778
|
+
.map((p, i) => ({ p, hybrid: hybridArr[i], cosine: cosineArr[i], bm25: bm25Arr[i] }))
|
|
779
|
+
.sort((a, b) => b.hybrid - a.hybrid)
|
|
780
|
+
.slice(0, Math.min(poolSize, patterns.length));
|
|
781
|
+
const candidates = prelim.map(({ p, hybrid, cosine, bm25 }) => ({
|
|
782
|
+
id: p.id, name: p.name, type: p.type,
|
|
783
|
+
embedding: p.embedding,
|
|
784
|
+
content: p.content,
|
|
785
|
+
relevance: hybrid,
|
|
786
|
+
_cosine: cosine,
|
|
787
|
+
_bm25: bm25,
|
|
788
|
+
}));
|
|
789
|
+
let picked;
|
|
790
|
+
if (useRerank) {
|
|
791
|
+
// ADR-080: cross-encoder reranks the wider candidate pool, then
|
|
792
|
+
// final score = hybridWeight * hybrid + ceWeight * crossEncoder
|
|
793
|
+
// on normalised scales. Ablation showed cross-encoder alone hits
|
|
794
|
+
// 100% top-3 but loses top-1 (calibration on short commit subjects
|
|
795
|
+
// is noisy); linear combination preserves hybrid's top-1 strength
|
|
796
|
+
// while gaining the cross-encoder's recall.
|
|
797
|
+
try {
|
|
798
|
+
const { crossEncoderRerank } = await import('../memory/cross-encoder-rerank.js');
|
|
799
|
+
const { normalise } = await import('../memory/hybrid-retrieval.js');
|
|
800
|
+
const docs = candidates.map((c) => c.content || c.name);
|
|
801
|
+
const reranked = await crossEncoderRerank(query, docs);
|
|
802
|
+
const ceScores = new Array(candidates.length).fill(0);
|
|
803
|
+
for (const { index, score } of reranked)
|
|
804
|
+
ceScores[index] = score;
|
|
805
|
+
const hybridNorm = normalise(candidates.map((c) => c.relevance));
|
|
806
|
+
const ceNorm = normalise(ceScores);
|
|
807
|
+
// ADR-083 joint grid: hw=0.7 cw=0.3 (with α=0.5 sw=3 from above) is
|
|
808
|
+
// the joint optimum at nDCG@3=0.963 (vs 0.900 at 0.5/0.5). The
|
|
809
|
+
// hybrid signal carries most of the relevance; the cross-encoder
|
|
810
|
+
// contributes a 30% smoothing/disambiguation kick.
|
|
811
|
+
const hybridWeight = Number(input.hybridWeight ?? 0.7);
|
|
812
|
+
const ceWeight = Number(input.ceWeight ?? 0.3);
|
|
813
|
+
const combined = candidates.map((c, i) => ({
|
|
814
|
+
...c,
|
|
815
|
+
_crossEncoderScore: ceScores[i],
|
|
816
|
+
_combinedScore: hybridWeight * hybridNorm[i] + ceWeight * ceNorm[i],
|
|
817
|
+
}));
|
|
818
|
+
picked = combined
|
|
819
|
+
.sort((a, b) => b._combinedScore - a._combinedScore)
|
|
820
|
+
.slice(0, k);
|
|
821
|
+
}
|
|
822
|
+
catch {
|
|
823
|
+
picked = candidates.slice(0, k);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
// Default path: MMR diversity over top-K*3 hybrid candidates.
|
|
828
|
+
picked = mmrRerank(candidates, k, mmrLambda);
|
|
829
|
+
}
|
|
830
|
+
return {
|
|
831
|
+
_realSimilarity: true,
|
|
832
|
+
_realEmbedding: !!realEmbeddings,
|
|
833
|
+
_embeddingSource: embeddingServiceName,
|
|
834
|
+
embeddingProvider: embeddingServiceName,
|
|
835
|
+
mode: 'hybrid',
|
|
836
|
+
alpha,
|
|
837
|
+
mmrLambda,
|
|
838
|
+
rerank: useRerank,
|
|
839
|
+
query,
|
|
840
|
+
results: picked.map((r) => ({
|
|
841
|
+
id: r.id,
|
|
842
|
+
name: r.name,
|
|
843
|
+
type: r.type,
|
|
844
|
+
similarity: r.relevance, // exposed as `similarity` for back-compat
|
|
845
|
+
hybridScore: r.relevance,
|
|
846
|
+
cosineScore: r._cosine,
|
|
847
|
+
bm25Score: r._bm25,
|
|
848
|
+
mmrScore: r.mmrScore,
|
|
849
|
+
...(r._crossEncoderScore !== undefined
|
|
850
|
+
? { crossEncoderScore: r._crossEncoderScore }
|
|
851
|
+
: {}),
|
|
852
|
+
})),
|
|
853
|
+
total: picked.length,
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
if (action === 'delete') {
|
|
857
|
+
const patternId = input.patternId;
|
|
858
|
+
if (!store.patterns[patternId]) {
|
|
859
|
+
return { success: false, error: 'Pattern not found' };
|
|
860
|
+
}
|
|
861
|
+
delete store.patterns[patternId];
|
|
862
|
+
saveNeuralStore(store);
|
|
863
|
+
return { success: true, deleted: patternId };
|
|
864
|
+
}
|
|
865
|
+
return { success: false, error: 'Unknown action' };
|
|
866
|
+
},
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
name: 'neural_compress',
|
|
870
|
+
description: 'Compress neural model or embeddings Use when nothing native trains on your workflow — Claude Code has no learning loop. Use to train SONA/MoE/EWC patterns from successful task outcomes; query via neural_predict before spawning agents. Off-path for one-shot work.',
|
|
871
|
+
category: 'neural',
|
|
872
|
+
inputSchema: {
|
|
873
|
+
type: 'object',
|
|
874
|
+
properties: {
|
|
875
|
+
modelId: { type: 'string', description: 'Model ID to compress' },
|
|
876
|
+
method: { type: 'string', enum: ['quantize', 'prune', 'distill'], description: 'Compression method' },
|
|
877
|
+
targetSize: { type: 'number', description: 'Target size reduction (0-1)' },
|
|
878
|
+
},
|
|
879
|
+
},
|
|
880
|
+
handler: async (input) => {
|
|
881
|
+
if (input.modelId) {
|
|
882
|
+
const v = validateIdentifier(input.modelId, 'modelId');
|
|
883
|
+
if (!v.valid)
|
|
884
|
+
return { success: false, error: v.error };
|
|
885
|
+
}
|
|
886
|
+
// Resolve provider so embeddingProvider in the result matches the old
|
|
887
|
+
// eager-init reporting.
|
|
888
|
+
await ensureEmbeddings();
|
|
889
|
+
const store = loadNeuralStore();
|
|
890
|
+
const method = input.method || 'quantize';
|
|
891
|
+
const targetReduction = input.targetSize || 0.5;
|
|
892
|
+
const patterns = Object.values(store.patterns);
|
|
893
|
+
if (patterns.length === 0) {
|
|
894
|
+
return { success: false, error: 'No patterns to compress. Train patterns first with neural_train.' };
|
|
895
|
+
}
|
|
896
|
+
const beforeCount = patterns.length;
|
|
897
|
+
const beforeSize = patterns.reduce((s, p) => s + (p.embedding?.length || 0) * 4, 0); // Float32 = 4 bytes
|
|
898
|
+
if (method === 'quantize') {
|
|
899
|
+
try {
|
|
900
|
+
const { quantizeInt8, getQuantizationStats } = await import('../memory/memory-initializer.js');
|
|
901
|
+
let totalCompressed = 0;
|
|
902
|
+
for (const pattern of patterns) {
|
|
903
|
+
if (pattern.embedding && pattern.embedding.length > 0) {
|
|
904
|
+
const stats = getQuantizationStats(pattern.embedding);
|
|
905
|
+
const quantized = quantizeInt8(pattern.embedding);
|
|
906
|
+
// Store quantized metadata (keep original embedding for search)
|
|
907
|
+
pattern._quantized = {
|
|
908
|
+
scale: quantized.scale,
|
|
909
|
+
zeroPoint: quantized.zeroPoint,
|
|
910
|
+
compressionRatio: stats.compressionRatio,
|
|
911
|
+
};
|
|
912
|
+
totalCompressed++;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
saveNeuralStore(store);
|
|
916
|
+
return {
|
|
917
|
+
success: true, _real: true, method,
|
|
918
|
+
embeddingProvider: embeddingServiceName,
|
|
919
|
+
patternsCompressed: totalCompressed,
|
|
920
|
+
compressionRatio: '3.92x (Int8)',
|
|
921
|
+
beforeBytes: beforeSize,
|
|
922
|
+
afterBytes: Math.round(beforeSize / 3.92),
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
catch {
|
|
926
|
+
return { success: false, error: 'Quantization requires memory-initializer. Run `memory init` first.' };
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
if (method === 'prune') {
|
|
930
|
+
// Prune patterns with low usage count below threshold (targetReduction as min usage)
|
|
931
|
+
const threshold = targetReduction;
|
|
932
|
+
const toRemove = [];
|
|
933
|
+
for (const [id, pattern] of Object.entries(store.patterns)) {
|
|
934
|
+
if ((pattern.usageCount || 0) < threshold)
|
|
935
|
+
toRemove.push(id);
|
|
936
|
+
}
|
|
937
|
+
for (const id of toRemove)
|
|
938
|
+
delete store.patterns[id];
|
|
939
|
+
saveNeuralStore(store);
|
|
940
|
+
return {
|
|
941
|
+
success: true, _real: true, method,
|
|
942
|
+
embeddingProvider: embeddingServiceName,
|
|
943
|
+
threshold,
|
|
944
|
+
patternsRemoved: toRemove.length,
|
|
945
|
+
patternsBefore: beforeCount,
|
|
946
|
+
patternsAfter: Object.keys(store.patterns).length,
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
if (method === 'distill') {
|
|
950
|
+
// Merge similar patterns by cosine similarity > 0.95
|
|
951
|
+
const patternList = Object.entries(store.patterns);
|
|
952
|
+
const merged = [];
|
|
953
|
+
for (let i = 0; i < patternList.length; i++) {
|
|
954
|
+
const [idA, a] = patternList[i];
|
|
955
|
+
if (merged.includes(idA))
|
|
956
|
+
continue;
|
|
957
|
+
for (let j = i + 1; j < patternList.length; j++) {
|
|
958
|
+
const [idB, b] = patternList[j];
|
|
959
|
+
if (!a.embedding || !b.embedding || merged.includes(idB))
|
|
960
|
+
continue;
|
|
961
|
+
const sim = cosineSimilarity(a.embedding, b.embedding);
|
|
962
|
+
if (sim > 0.95) {
|
|
963
|
+
// Merge: average embeddings, keep higher usage count
|
|
964
|
+
for (let k = 0; k < a.embedding.length; k++) {
|
|
965
|
+
a.embedding[k] = (a.embedding[k] + (b.embedding[k] || 0)) / 2;
|
|
966
|
+
}
|
|
967
|
+
a.usageCount = Math.max(a.usageCount || 0, b.usageCount || 0);
|
|
968
|
+
delete store.patterns[idB];
|
|
969
|
+
merged.push(idB);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
saveNeuralStore(store);
|
|
974
|
+
return {
|
|
975
|
+
success: true, _real: true, method,
|
|
976
|
+
embeddingProvider: embeddingServiceName,
|
|
977
|
+
patternsMerged: merged.length,
|
|
978
|
+
patternsBefore: beforeCount,
|
|
979
|
+
patternsAfter: Object.keys(store.patterns).length,
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
return { success: false, error: `Unknown method: ${method}. Use quantize, prune, or distill.` };
|
|
983
|
+
},
|
|
984
|
+
},
|
|
985
|
+
{
|
|
986
|
+
name: 'neural_status',
|
|
987
|
+
description: 'Get neural system status Use when nothing native trains on your workflow — Claude Code has no learning loop. Use to train SONA/MoE/EWC patterns from successful task outcomes; query via neural_predict before spawning agents. Off-path for one-shot work.',
|
|
988
|
+
category: 'neural',
|
|
989
|
+
inputSchema: {
|
|
990
|
+
type: 'object',
|
|
991
|
+
properties: {
|
|
992
|
+
modelId: { type: 'string', description: 'Specific model ID' },
|
|
993
|
+
detailed: { type: 'boolean', description: 'Include detailed info' },
|
|
994
|
+
},
|
|
995
|
+
},
|
|
996
|
+
handler: async (input) => {
|
|
997
|
+
if (input.modelId) {
|
|
998
|
+
const v = validateIdentifier(input.modelId, 'modelId');
|
|
999
|
+
if (!v.valid)
|
|
1000
|
+
return { success: false, error: v.error };
|
|
1001
|
+
}
|
|
1002
|
+
// Resolve provider so _realEmbeddings/embeddingProvider report the same
|
|
1003
|
+
// values the old eager-init version produced.
|
|
1004
|
+
await ensureEmbeddings();
|
|
1005
|
+
const store = loadNeuralStore();
|
|
1006
|
+
if (input.modelId) {
|
|
1007
|
+
const model = store.models[input.modelId];
|
|
1008
|
+
if (!model) {
|
|
1009
|
+
return { success: false, error: 'Model not found' };
|
|
1010
|
+
}
|
|
1011
|
+
return { success: true, model };
|
|
1012
|
+
}
|
|
1013
|
+
const models = Object.values(store.models);
|
|
1014
|
+
const patterns = Object.values(store.patterns);
|
|
1015
|
+
return {
|
|
1016
|
+
_realEmbeddings: !!realEmbeddings,
|
|
1017
|
+
embeddingProvider: realEmbeddings ? `@claude-flow/embeddings (${embeddingServiceName})` : 'hash-based (deterministic)',
|
|
1018
|
+
models: {
|
|
1019
|
+
total: models.length,
|
|
1020
|
+
ready: models.filter(m => m.status === 'ready').length,
|
|
1021
|
+
training: models.filter(m => m.status === 'training').length,
|
|
1022
|
+
avgAccuracy: models.length > 0
|
|
1023
|
+
? models.reduce((sum, m) => sum + m.accuracy, 0) / models.length
|
|
1024
|
+
: 0,
|
|
1025
|
+
},
|
|
1026
|
+
patterns: {
|
|
1027
|
+
total: patterns.length,
|
|
1028
|
+
byType: patterns.reduce((acc, p) => {
|
|
1029
|
+
acc[p.type] = (acc[p.type] || 0) + 1;
|
|
1030
|
+
return acc;
|
|
1031
|
+
}, {}),
|
|
1032
|
+
totalEmbeddingDims: patterns.length > 0 ? patterns[0].embedding.length : 384,
|
|
1033
|
+
},
|
|
1034
|
+
features: {
|
|
1035
|
+
hnsw: true,
|
|
1036
|
+
quantization: true,
|
|
1037
|
+
// #1770: probe the real loader instead of returning a literal false.
|
|
1038
|
+
// Was hardcoded false, which contradicted hooks_intelligence_stats's
|
|
1039
|
+
// simultaneous claim of `implementation: real-flash-attention`.
|
|
1040
|
+
// The two surfaces now agree on a single source of truth.
|
|
1041
|
+
flashAttention: await (async () => {
|
|
1042
|
+
try {
|
|
1043
|
+
// #1773 item 4 — flash-attention now lives in @claude-flow/neural
|
|
1044
|
+
const { getFlashAttention } = await import('@claude-flow/neural');
|
|
1045
|
+
return getFlashAttention() !== null;
|
|
1046
|
+
}
|
|
1047
|
+
catch {
|
|
1048
|
+
return false;
|
|
1049
|
+
}
|
|
1050
|
+
})(),
|
|
1051
|
+
reasoningBank: true,
|
|
1052
|
+
},
|
|
1053
|
+
};
|
|
1054
|
+
},
|
|
1055
|
+
},
|
|
1056
|
+
{
|
|
1057
|
+
name: 'neural_optimize',
|
|
1058
|
+
description: 'Optimize neural model performance Use when nothing native trains on your workflow — Claude Code has no learning loop. Use to train SONA/MoE/EWC patterns from successful task outcomes; query via neural_predict before spawning agents. Off-path for one-shot work.',
|
|
1059
|
+
category: 'neural',
|
|
1060
|
+
inputSchema: {
|
|
1061
|
+
type: 'object',
|
|
1062
|
+
properties: {
|
|
1063
|
+
modelId: { type: 'string', description: 'Model ID to optimize' },
|
|
1064
|
+
target: { type: 'string', enum: ['speed', 'memory', 'accuracy', 'balanced'], description: 'Optimization target' },
|
|
1065
|
+
},
|
|
1066
|
+
},
|
|
1067
|
+
handler: async (input) => {
|
|
1068
|
+
if (input.modelId) {
|
|
1069
|
+
const v = validateIdentifier(input.modelId, 'modelId');
|
|
1070
|
+
if (!v.valid)
|
|
1071
|
+
return { success: false, error: v.error };
|
|
1072
|
+
}
|
|
1073
|
+
// Resolve provider so embeddingProvider in the result matches the old
|
|
1074
|
+
// eager-init reporting.
|
|
1075
|
+
await ensureEmbeddings();
|
|
1076
|
+
const store = loadNeuralStore();
|
|
1077
|
+
const target = input.target || 'balanced';
|
|
1078
|
+
const patterns = Object.values(store.patterns);
|
|
1079
|
+
if (patterns.length === 0) {
|
|
1080
|
+
return { success: false, error: 'No patterns to optimize. Train patterns first with neural_train.' };
|
|
1081
|
+
}
|
|
1082
|
+
const startTime = performance.now();
|
|
1083
|
+
const actions = [];
|
|
1084
|
+
const beforeCount = patterns.length;
|
|
1085
|
+
const dims = patterns[0]?.embedding?.length || 0;
|
|
1086
|
+
let patternsRemoved = 0;
|
|
1087
|
+
let patternsQuantized = 0;
|
|
1088
|
+
let duplicatesRemoved = 0;
|
|
1089
|
+
// speed / balanced: deduplicate identical or near-identical patterns
|
|
1090
|
+
if (target === 'speed' || target === 'balanced') {
|
|
1091
|
+
const seen = new Map(); // hash -> id
|
|
1092
|
+
for (const [id, p] of Object.entries(store.patterns)) {
|
|
1093
|
+
if (!p.embedding || p.embedding.length === 0)
|
|
1094
|
+
continue;
|
|
1095
|
+
// Quick hash: first 8 dims rounded
|
|
1096
|
+
const hash = p.embedding.slice(0, 8).map(v => v.toFixed(4)).join(',');
|
|
1097
|
+
if (seen.has(hash)) {
|
|
1098
|
+
// Verify with full cosine similarity
|
|
1099
|
+
const existingId = seen.get(hash);
|
|
1100
|
+
const existing = store.patterns[existingId];
|
|
1101
|
+
if (existing && cosineSimilarity(p.embedding, existing.embedding) > 0.99) {
|
|
1102
|
+
existing.usageCount = Math.max(existing.usageCount || 0, p.usageCount || 0);
|
|
1103
|
+
delete store.patterns[id];
|
|
1104
|
+
duplicatesRemoved++;
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
else {
|
|
1108
|
+
seen.set(hash, id);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
if (duplicatesRemoved > 0)
|
|
1112
|
+
actions.push(`Removed ${duplicatesRemoved} near-duplicate patterns`);
|
|
1113
|
+
}
|
|
1114
|
+
// memory / balanced: quantize large embeddings
|
|
1115
|
+
if (target === 'memory' || target === 'balanced') {
|
|
1116
|
+
try {
|
|
1117
|
+
const { quantizeInt8, getQuantizationStats } = await import('../memory/memory-initializer.js');
|
|
1118
|
+
for (const p of Object.values(store.patterns)) {
|
|
1119
|
+
if (p.embedding && p.embedding.length > 0 && !p._quantized) {
|
|
1120
|
+
const stats = getQuantizationStats(p.embedding);
|
|
1121
|
+
const q = quantizeInt8(p.embedding);
|
|
1122
|
+
p._quantized = { scale: q.scale, zeroPoint: q.zeroPoint, compressionRatio: stats.compressionRatio };
|
|
1123
|
+
patternsQuantized++;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
if (patternsQuantized > 0)
|
|
1127
|
+
actions.push(`Quantized ${patternsQuantized} pattern embeddings (Int8, ~3.92x)`);
|
|
1128
|
+
}
|
|
1129
|
+
catch {
|
|
1130
|
+
actions.push('Quantization skipped (memory-initializer not available)');
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
// accuracy / balanced: prune low-usage, zero-embedding patterns
|
|
1134
|
+
if (target === 'accuracy' || target === 'balanced') {
|
|
1135
|
+
for (const [id, p] of Object.entries(store.patterns)) {
|
|
1136
|
+
if (!p.embedding || p.embedding.length === 0) {
|
|
1137
|
+
delete store.patterns[id];
|
|
1138
|
+
patternsRemoved++;
|
|
1139
|
+
continue;
|
|
1140
|
+
}
|
|
1141
|
+
// Remove patterns with all-zero embeddings (no useful signal)
|
|
1142
|
+
const norm = p.embedding.reduce((s, v) => s + v * v, 0);
|
|
1143
|
+
if (norm < 1e-10) {
|
|
1144
|
+
delete store.patterns[id];
|
|
1145
|
+
patternsRemoved++;
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
if (patternsRemoved > 0)
|
|
1149
|
+
actions.push(`Pruned ${patternsRemoved} empty/zero-signal patterns`);
|
|
1150
|
+
}
|
|
1151
|
+
saveNeuralStore(store);
|
|
1152
|
+
const elapsed = Math.round(performance.now() - startTime);
|
|
1153
|
+
return {
|
|
1154
|
+
success: true, _real: true, target,
|
|
1155
|
+
embeddingProvider: embeddingServiceName,
|
|
1156
|
+
actions,
|
|
1157
|
+
patternsBefore: beforeCount,
|
|
1158
|
+
patternsAfter: Object.keys(store.patterns).length,
|
|
1159
|
+
duplicatesRemoved,
|
|
1160
|
+
patternsQuantized,
|
|
1161
|
+
patternsRemoved,
|
|
1162
|
+
embeddingDims: dims,
|
|
1163
|
+
elapsedMs: elapsed,
|
|
1164
|
+
};
|
|
1165
|
+
},
|
|
1166
|
+
},
|
|
1167
|
+
];
|
|
1168
|
+
//# sourceMappingURL=neural-tools.js.map
|