shieldcortex 4.14.11 → 4.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
- package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
- package/dist/cloud/cli.js +25 -1
- package/dist/cloud/config.d.ts +19 -0
- package/dist/cloud/config.js +72 -0
- package/dist/memory/ranker/graph-rank.d.ts +39 -0
- package/dist/memory/ranker/graph-rank.js +186 -0
- package/dist/memory/ranker/index.d.ts +74 -0
- package/dist/memory/ranker/index.js +170 -0
- package/dist/memory/ranker/rrf.d.ts +41 -0
- package/dist/memory/ranker/rrf.js +54 -0
- package/dist/memory/search-recall.js +196 -65
- package/dist/memory/types.d.ts +18 -0
- package/dist/memory/types.js +6 -0
- package/package.json +3 -1
- package/plugins/openclaw/dist/openclaw.plugin.json +1 -1
- /package/dashboard/.next/standalone/dashboard/.next/static/{InYbgmj1l661AgpmCj6zr → 10a_MRwbHFUuDdfr86RUu}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{InYbgmj1l661AgpmCj6zr → 10a_MRwbHFUuDdfr86RUu}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{InYbgmj1l661AgpmCj6zr → 10a_MRwbHFUuDdfr86RUu}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hybrid retrieval orchestrator — Step A.3 of v4.15.
|
|
3
|
+
*
|
|
4
|
+
* Glues the three retrievers (FTS via SQLite FTS5, vector via embeddings,
|
|
5
|
+
* graph via `graphRankFromQuery`) into a single ranking by feeding their
|
|
6
|
+
* rank lists into Reciprocal Rank Fusion (`reciprocalRankFusion`), then
|
|
7
|
+
* applying the existing per-memory boosts (recency, category, link, tag,
|
|
8
|
+
* activation, contradiction) as **multiplicative tweaks on top of the
|
|
9
|
+
* RRF score** rather than additive components in a fixed-weight sum.
|
|
10
|
+
*
|
|
11
|
+
* finalScore = rrfScore
|
|
12
|
+
* × (1 + 0.05 × priority) // priority: 0–1
|
|
13
|
+
* × (1 + recencyBoost) // 0 / 0.05 / 0.1
|
|
14
|
+
* × (1 + 0.1 × categoryMatch) // 0 or 1
|
|
15
|
+
* × (1 + linkBoost) // 0–0.15
|
|
16
|
+
* × (1 + tagBoost) // 0–0.1
|
|
17
|
+
* × (1 + activationBoost) // 0–?
|
|
18
|
+
* × (1 - contradictionPenalty) // 0–0.12
|
|
19
|
+
*
|
|
20
|
+
* Why multiplicative on top of RRF rather than additive:
|
|
21
|
+
* - RRF is rank-based, so its raw score scale is small and consistent.
|
|
22
|
+
* - Multiplicative boosts preserve the *relative* RRF order while
|
|
23
|
+
* letting context modulate it — they don't drown out the underlying
|
|
24
|
+
* retrieval signal the way fixed additive weights do.
|
|
25
|
+
* - Contradiction penalty is multiplicative (`1 - p`) so it shrinks
|
|
26
|
+
* score proportionally rather than potentially flipping sign.
|
|
27
|
+
*
|
|
28
|
+
* The module is split intentionally: `runHybridRanker` is pure-ish (it
|
|
29
|
+
* accepts already-loaded rank lists + a memory map) so it can be unit
|
|
30
|
+
* tested without standing up the embedding model or the FTS pipeline.
|
|
31
|
+
* Step A.4 will add the DB-backed `hybridSearch` wrapper that builds
|
|
32
|
+
* those inputs from a `SearchOptions`.
|
|
33
|
+
*/
|
|
34
|
+
import { reciprocalRankFusion } from './rrf.js';
|
|
35
|
+
import { calculateDecayedScore, calculatePriority } from '../decay.js';
|
|
36
|
+
import { getActivationBoost as defaultActivationBoost } from '../activation.js';
|
|
37
|
+
import { buildSearchExplanation, calculateLinkBoost, calculateTagScore, detectQueryCategory, extractQueryTags, } from '../search.js';
|
|
38
|
+
export const DEFAULT_HYBRID_WEIGHTS = {
|
|
39
|
+
fts: 0.4,
|
|
40
|
+
vector: 0.6,
|
|
41
|
+
graph: 0.3,
|
|
42
|
+
};
|
|
43
|
+
/** Cormack et al. (2009) recommended RRF smoothing constant. */
|
|
44
|
+
export const DEFAULT_RRF_K = 60;
|
|
45
|
+
const DEFAULT_LIMIT = 20;
|
|
46
|
+
export function runHybridRanker(input) {
|
|
47
|
+
const fused = reciprocalRankFusion(input.rankLists, { k: input.rrfK ?? DEFAULT_RRF_K });
|
|
48
|
+
if (fused.length === 0)
|
|
49
|
+
return [];
|
|
50
|
+
const limit = input.limit ?? DEFAULT_LIMIT;
|
|
51
|
+
const includeDecayed = input.includeDecayed ?? false;
|
|
52
|
+
const includeExplanation = input.includeExplanation ?? false;
|
|
53
|
+
const activationBoostFn = input.activationBoostFn ?? defaultActivationBoost;
|
|
54
|
+
const detectedCategory = input.query ? detectQueryCategory(input.query) : null;
|
|
55
|
+
const queryTags = input.query ? extractQueryTags(input.query) : [];
|
|
56
|
+
const scoringContext = {
|
|
57
|
+
db: input.db,
|
|
58
|
+
config: input.config,
|
|
59
|
+
detectedCategory,
|
|
60
|
+
queryTags,
|
|
61
|
+
vectorResults: input.vectorSimilarities ?? new Map(),
|
|
62
|
+
query: input.query,
|
|
63
|
+
};
|
|
64
|
+
const scored = [];
|
|
65
|
+
for (const fusedItem of fused) {
|
|
66
|
+
const memory = input.memories.get(fusedItem.id);
|
|
67
|
+
if (!memory)
|
|
68
|
+
continue;
|
|
69
|
+
const decayedScore = calculateDecayedScore(memory, input.config);
|
|
70
|
+
memory.decayedScore = decayedScore;
|
|
71
|
+
const candidate = scoreCandidate({
|
|
72
|
+
memory,
|
|
73
|
+
rrfScore: fusedItem.score,
|
|
74
|
+
contributions: fusedItem.contributions,
|
|
75
|
+
decayedScore,
|
|
76
|
+
detectedCategory,
|
|
77
|
+
queryTags,
|
|
78
|
+
vectorSimilarity: input.vectorSimilarities?.get(memory.id) ?? 0,
|
|
79
|
+
ftsScore: input.ftsScores?.get(memory.id) ?? 0,
|
|
80
|
+
db: input.db,
|
|
81
|
+
activationBoostFn,
|
|
82
|
+
});
|
|
83
|
+
scored.push(candidate);
|
|
84
|
+
}
|
|
85
|
+
const filtered = includeDecayed
|
|
86
|
+
? scored
|
|
87
|
+
: scored.filter((c) => c.decayedScore >= input.config.salienceThreshold);
|
|
88
|
+
filtered.sort((a, b) => b.finalScore - a.finalScore ||
|
|
89
|
+
a.memory.id - b.memory.id);
|
|
90
|
+
const capped = filtered.slice(0, limit);
|
|
91
|
+
return capped.map((c) => buildSearchResult(c, scoringContext, includeExplanation));
|
|
92
|
+
}
|
|
93
|
+
function scoreCandidate(input) {
|
|
94
|
+
const { memory } = input;
|
|
95
|
+
const hoursSinceAccess = (Date.now() - new Date(memory.lastAccessed).getTime()) / (1000 * 60 * 60);
|
|
96
|
+
const recencyBoost = hoursSinceAccess < 1 ? 0.1 : hoursSinceAccess < 24 ? 0.05 : 0;
|
|
97
|
+
const matchedCategory = input.detectedCategory !== null && memory.category === input.detectedCategory;
|
|
98
|
+
const categoryBoost = matchedCategory ? 0.1 : 0;
|
|
99
|
+
const linkBoost = calculateLinkBoost(memory.id, input.db);
|
|
100
|
+
const tagBoost = calculateTagScore(input.queryTags, memory.tags);
|
|
101
|
+
const activationBoost = input.activationBoostFn(memory.id);
|
|
102
|
+
const priority = calculatePriority(memory);
|
|
103
|
+
const priorityBoost = priority * 0.05;
|
|
104
|
+
const contradictionCount = input.db
|
|
105
|
+
.prepare(`SELECT COUNT(*) as count FROM memory_links
|
|
106
|
+
WHERE relationship = 'contradicts' AND (source_id = ? OR target_id = ?)`)
|
|
107
|
+
.get(memory.id, memory.id).count;
|
|
108
|
+
const contradictionPenalty = Math.min(0.12, contradictionCount * 0.03);
|
|
109
|
+
const multiplier = (1 + priorityBoost) *
|
|
110
|
+
(1 + recencyBoost) *
|
|
111
|
+
(1 + categoryBoost) *
|
|
112
|
+
(1 + linkBoost) *
|
|
113
|
+
(1 + tagBoost) *
|
|
114
|
+
(1 + activationBoost) *
|
|
115
|
+
(1 - contradictionPenalty);
|
|
116
|
+
const finalScore = input.rrfScore * multiplier;
|
|
117
|
+
const eligibilityReasons = [];
|
|
118
|
+
if (memory.status === 'archived')
|
|
119
|
+
eligibilityReasons.push('Archived memories are excluded from normal recall');
|
|
120
|
+
if (memory.status === 'suppressed')
|
|
121
|
+
eligibilityReasons.push('Suppressed memories are excluded from normal recall');
|
|
122
|
+
if (memory.cloudExcluded)
|
|
123
|
+
eligibilityReasons.push('Excluded from cloud sync');
|
|
124
|
+
if (memory.trustScore < 0.7)
|
|
125
|
+
eligibilityReasons.push(`Low trust source (${memory.trustScore.toFixed(2)})`);
|
|
126
|
+
if (contradictionCount > 0) {
|
|
127
|
+
eligibilityReasons.push(`${contradictionCount} contradiction link${contradictionCount === 1 ? '' : 's'} attached`);
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
memory,
|
|
131
|
+
rrfScore: input.rrfScore,
|
|
132
|
+
finalScore,
|
|
133
|
+
decayedScore: input.decayedScore,
|
|
134
|
+
contributions: input.contributions,
|
|
135
|
+
values: {
|
|
136
|
+
ftsScore: input.ftsScore,
|
|
137
|
+
vectorSimilarity: input.vectorSimilarity,
|
|
138
|
+
vectorBoost: input.vectorSimilarity * 0.3, // for explanation breakdown only
|
|
139
|
+
decayedScore: input.decayedScore,
|
|
140
|
+
priorityBoost,
|
|
141
|
+
recencyBoost,
|
|
142
|
+
categoryBoost,
|
|
143
|
+
linkBoost,
|
|
144
|
+
tagBoost,
|
|
145
|
+
activationBoost,
|
|
146
|
+
contradictionPenalty,
|
|
147
|
+
finalScore,
|
|
148
|
+
},
|
|
149
|
+
eligibilityReasons,
|
|
150
|
+
matchedCategory,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function buildSearchResult(c, ctx, includeExplanation) {
|
|
154
|
+
const result = {
|
|
155
|
+
memory: c.memory,
|
|
156
|
+
relevanceScore: c.finalScore,
|
|
157
|
+
recallEligibility: {
|
|
158
|
+
eligible: c.eligibilityReasons.length === 0,
|
|
159
|
+
reasons: c.eligibilityReasons,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
if (includeExplanation) {
|
|
163
|
+
const explanation = buildSearchExplanation(c.memory, ctx, c.values);
|
|
164
|
+
if (explanation) {
|
|
165
|
+
explanation.eligibility = result.recallEligibility;
|
|
166
|
+
result.explanation = explanation;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reciprocal Rank Fusion (RRF).
|
|
3
|
+
*
|
|
4
|
+
* Combines ordered rank lists from multiple retrievers (e.g. BM25, vector,
|
|
5
|
+
* graph) into a single fused ranking. Robust to heterogeneous score scales:
|
|
6
|
+
* the only thing that matters is each retriever's rank order.
|
|
7
|
+
*
|
|
8
|
+
* score(d) = Σ_i w_i / (k + rank_i(d))
|
|
9
|
+
*
|
|
10
|
+
* - rank_i(d) is the 1-indexed position of d in retriever i's list.
|
|
11
|
+
* - w_i is the optional weight for retriever i (default 1).
|
|
12
|
+
* - k is a smoothing constant. Cormack et al. (2009) recommend 60.
|
|
13
|
+
*
|
|
14
|
+
* The function returns the union of ids across all rank lists, sorted by
|
|
15
|
+
* fused score descending. Ties break by id ascending for stable output.
|
|
16
|
+
*/
|
|
17
|
+
export interface RankList {
|
|
18
|
+
/** Identifier for this retriever (e.g. 'fts', 'vector', 'graph'). */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Ordered ids, best-first. May be empty. Duplicates within a list are deduplicated, keeping the first occurrence. */
|
|
21
|
+
ids: number[];
|
|
22
|
+
/** Multiplicative weight on this retriever's contribution. Defaults to 1. */
|
|
23
|
+
weight?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface RrfOptions {
|
|
26
|
+
/** RRF smoothing constant. Default 60. */
|
|
27
|
+
k?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface RrfContribution {
|
|
30
|
+
name: string;
|
|
31
|
+
/** 1-indexed rank within that retriever's list. */
|
|
32
|
+
rank: number;
|
|
33
|
+
/** weight / (k + rank) — this contribution's addition to the final score. */
|
|
34
|
+
weighted: number;
|
|
35
|
+
}
|
|
36
|
+
export interface RrfResult {
|
|
37
|
+
id: number;
|
|
38
|
+
score: number;
|
|
39
|
+
contributions: RrfContribution[];
|
|
40
|
+
}
|
|
41
|
+
export declare function reciprocalRankFusion(rankLists: readonly RankList[], options?: RrfOptions): RrfResult[];
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reciprocal Rank Fusion (RRF).
|
|
3
|
+
*
|
|
4
|
+
* Combines ordered rank lists from multiple retrievers (e.g. BM25, vector,
|
|
5
|
+
* graph) into a single fused ranking. Robust to heterogeneous score scales:
|
|
6
|
+
* the only thing that matters is each retriever's rank order.
|
|
7
|
+
*
|
|
8
|
+
* score(d) = Σ_i w_i / (k + rank_i(d))
|
|
9
|
+
*
|
|
10
|
+
* - rank_i(d) is the 1-indexed position of d in retriever i's list.
|
|
11
|
+
* - w_i is the optional weight for retriever i (default 1).
|
|
12
|
+
* - k is a smoothing constant. Cormack et al. (2009) recommend 60.
|
|
13
|
+
*
|
|
14
|
+
* The function returns the union of ids across all rank lists, sorted by
|
|
15
|
+
* fused score descending. Ties break by id ascending for stable output.
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_K = 60;
|
|
18
|
+
export function reciprocalRankFusion(rankLists, options = {}) {
|
|
19
|
+
const k = options.k ?? DEFAULT_K;
|
|
20
|
+
const accumulator = new Map();
|
|
21
|
+
for (const list of rankLists) {
|
|
22
|
+
if (list.ids.length === 0)
|
|
23
|
+
continue;
|
|
24
|
+
const weight = list.weight ?? 1;
|
|
25
|
+
const seen = new Set();
|
|
26
|
+
list.ids.forEach((id, idx) => {
|
|
27
|
+
if (seen.has(id))
|
|
28
|
+
return; // dedupe within a single rank list, keep first
|
|
29
|
+
seen.add(id);
|
|
30
|
+
const rank = idx + 1;
|
|
31
|
+
const weighted = weight / (k + rank);
|
|
32
|
+
const entry = accumulator.get(id);
|
|
33
|
+
const contribution = { name: list.name, rank, weighted };
|
|
34
|
+
if (entry) {
|
|
35
|
+
entry.score += weighted;
|
|
36
|
+
entry.contributions.push(contribution);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
accumulator.set(id, { score: weighted, contributions: [contribution] });
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const results = Array.from(accumulator.entries()).map(([id, { score, contributions }]) => ({
|
|
44
|
+
id,
|
|
45
|
+
score,
|
|
46
|
+
contributions,
|
|
47
|
+
}));
|
|
48
|
+
results.sort((a, b) => {
|
|
49
|
+
if (b.score !== a.score)
|
|
50
|
+
return b.score - a.score;
|
|
51
|
+
return a.id - b.id; // stable tie-break by id ascending
|
|
52
|
+
});
|
|
53
|
+
return results;
|
|
54
|
+
}
|
|
@@ -34,6 +34,9 @@ import { reinforceFromSearch, enrichMemory } from './lifecycle.js';
|
|
|
34
34
|
// Cyclic import — see header. rowToMemory and logAccessDenial live in store.ts;
|
|
35
35
|
// both are only invoked inside function bodies below, never at module load.
|
|
36
36
|
import { rowToMemory, logAccessDenial } from './store.js';
|
|
37
|
+
import { runHybridRanker } from './ranker/index.js';
|
|
38
|
+
import { graphRankFromQuery } from './ranker/graph-rank.js';
|
|
39
|
+
import { getRankerConfig } from '../cloud/config.js';
|
|
37
40
|
let searchCount = 0;
|
|
38
41
|
async function searchMemoriesInternal(options, config, source, execution) {
|
|
39
42
|
if (++searchCount % 100 === 0) {
|
|
@@ -124,72 +127,45 @@ async function searchMemoriesInternal(options, config, source, execution) {
|
|
|
124
127
|
vectorResults,
|
|
125
128
|
query: options.query,
|
|
126
129
|
};
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
// FTS-derived per-row scores (legacy: used directly; RRF: kept for explanations)
|
|
131
|
+
const ftsScores = new Map();
|
|
132
|
+
for (const row of rows) {
|
|
133
|
+
const id = row.id;
|
|
131
134
|
const rawRank = row.rank;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
reasons: eligibilityReasons,
|
|
167
|
-
},
|
|
168
|
-
};
|
|
169
|
-
if (execution.includeExplanation) {
|
|
170
|
-
result.explanation = buildSearchExplanation(memory, scoringContext, {
|
|
171
|
-
ftsScore,
|
|
172
|
-
vectorSimilarity,
|
|
173
|
-
vectorBoost,
|
|
174
|
-
decayedScore,
|
|
175
|
-
priorityBoost,
|
|
176
|
-
recencyBoost,
|
|
177
|
-
categoryBoost,
|
|
178
|
-
linkBoost,
|
|
179
|
-
tagBoost,
|
|
180
|
-
activationBoost,
|
|
181
|
-
contradictionPenalty,
|
|
182
|
-
finalScore: relevanceScore,
|
|
183
|
-
});
|
|
184
|
-
if (result.explanation) {
|
|
185
|
-
result.explanation.eligibility = result.recallEligibility;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
return result;
|
|
189
|
-
});
|
|
190
|
-
const sortedResults = results
|
|
191
|
-
.filter((result) => options.includeDecayed || result.memory.decayedScore >= config.salienceThreshold)
|
|
192
|
-
.sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
135
|
+
ftsScores.set(id, rawRank ? 1 / (1 + Math.abs(rawRank)) : 0.3);
|
|
136
|
+
}
|
|
137
|
+
// Resolve ranker engine. Honour caller-supplied config.ranker if present
|
|
138
|
+
// (tests and explicit callers can pin engine), otherwise fall back to the
|
|
139
|
+
// env/file resolver in cloud/config.
|
|
140
|
+
const rankerConfig = config.ranker ?? getRankerConfig();
|
|
141
|
+
let sortedResults;
|
|
142
|
+
if (rankerConfig.engine === 'rrf') {
|
|
143
|
+
sortedResults = scoreWithRrf({
|
|
144
|
+
rows,
|
|
145
|
+
ftsScores,
|
|
146
|
+
vectorResults,
|
|
147
|
+
query: options.query,
|
|
148
|
+
options,
|
|
149
|
+
db,
|
|
150
|
+
config,
|
|
151
|
+
rankerConfig,
|
|
152
|
+
limit,
|
|
153
|
+
includeExplanation: execution.includeExplanation,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
sortedResults = scoreLegacy({
|
|
158
|
+
rows,
|
|
159
|
+
vectorResults,
|
|
160
|
+
detectedCategory,
|
|
161
|
+
queryTags,
|
|
162
|
+
db,
|
|
163
|
+
config,
|
|
164
|
+
includeDecayed: options.includeDecayed ?? false,
|
|
165
|
+
includeExplanation: execution.includeExplanation,
|
|
166
|
+
scoringContext,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
193
169
|
if (execution.enableSideEffects) {
|
|
194
170
|
const topResults = sortedResults.slice(0, 5);
|
|
195
171
|
for (const result of topResults) {
|
|
@@ -266,6 +242,161 @@ async function searchMemoriesInternal(options, config, source, execution) {
|
|
|
266
242
|
}
|
|
267
243
|
return finalResults;
|
|
268
244
|
}
|
|
245
|
+
function scoreLegacy(input) {
|
|
246
|
+
const { rows, vectorResults, detectedCategory, queryTags, db, config, includeDecayed, includeExplanation, scoringContext, } = input;
|
|
247
|
+
const results = rows.map((row) => {
|
|
248
|
+
const memory = rowToMemory(row);
|
|
249
|
+
const decayedScore = calculateDecayedScore(memory, config);
|
|
250
|
+
memory.decayedScore = decayedScore;
|
|
251
|
+
const rawRank = row.rank;
|
|
252
|
+
const ftsScore = rawRank ? 1 / (1 + Math.abs(rawRank)) : 0.3;
|
|
253
|
+
const hoursSinceAccess = (Date.now() - new Date(memory.lastAccessed).getTime()) / (1000 * 60 * 60);
|
|
254
|
+
const recencyBoost = hoursSinceAccess < 1 ? 0.1 : (hoursSinceAccess < 24 ? 0.05 : 0);
|
|
255
|
+
const categoryBoost = detectedCategory && memory.category === detectedCategory ? 0.1 : 0;
|
|
256
|
+
const linkBoost = calculateLinkBoost(memory.id, db);
|
|
257
|
+
const tagBoost = calculateTagScore(queryTags, memory.tags);
|
|
258
|
+
const activationBoost = getActivationBoost(memory.id);
|
|
259
|
+
const vectorSimilarity = vectorResults.get(memory.id) || 0;
|
|
260
|
+
const vectorBoost = vectorSimilarity * 0.3;
|
|
261
|
+
const priorityBoost = calculatePriority(memory) * 0.05;
|
|
262
|
+
const contradictionCount = db.prepare(`SELECT COUNT(*) as count FROM memory_links WHERE relationship = 'contradicts' AND (source_id = ? OR target_id = ?)`).get(memory.id, memory.id).count;
|
|
263
|
+
const contradictionPenalty = Math.min(0.12, contradictionCount * 0.03);
|
|
264
|
+
const eligibilityReasons = [];
|
|
265
|
+
if (memory.status === 'archived')
|
|
266
|
+
eligibilityReasons.push('Archived memories are excluded from normal recall');
|
|
267
|
+
if (memory.status === 'suppressed')
|
|
268
|
+
eligibilityReasons.push('Suppressed memories are excluded from normal recall');
|
|
269
|
+
if (memory.cloudExcluded)
|
|
270
|
+
eligibilityReasons.push('Excluded from cloud sync');
|
|
271
|
+
if (memory.trustScore < 0.7)
|
|
272
|
+
eligibilityReasons.push(`Low trust source (${memory.trustScore.toFixed(2)})`);
|
|
273
|
+
if (contradictionCount > 0)
|
|
274
|
+
eligibilityReasons.push(`${contradictionCount} contradiction link${contradictionCount === 1 ? '' : 's'} attached`);
|
|
275
|
+
const relevanceScore = (ftsScore * 0.25 +
|
|
276
|
+
vectorBoost +
|
|
277
|
+
decayedScore * 0.2 +
|
|
278
|
+
priorityBoost +
|
|
279
|
+
recencyBoost + categoryBoost + linkBoost + tagBoost + activationBoost -
|
|
280
|
+
contradictionPenalty);
|
|
281
|
+
const result = {
|
|
282
|
+
memory,
|
|
283
|
+
relevanceScore,
|
|
284
|
+
recallEligibility: {
|
|
285
|
+
eligible: eligibilityReasons.length === 0,
|
|
286
|
+
reasons: eligibilityReasons,
|
|
287
|
+
},
|
|
288
|
+
};
|
|
289
|
+
if (includeExplanation) {
|
|
290
|
+
result.explanation = buildSearchExplanation(memory, scoringContext, {
|
|
291
|
+
ftsScore,
|
|
292
|
+
vectorSimilarity,
|
|
293
|
+
vectorBoost,
|
|
294
|
+
decayedScore,
|
|
295
|
+
priorityBoost,
|
|
296
|
+
recencyBoost,
|
|
297
|
+
categoryBoost,
|
|
298
|
+
linkBoost,
|
|
299
|
+
tagBoost,
|
|
300
|
+
activationBoost,
|
|
301
|
+
contradictionPenalty,
|
|
302
|
+
finalScore: relevanceScore,
|
|
303
|
+
});
|
|
304
|
+
if (result.explanation) {
|
|
305
|
+
result.explanation.eligibility = result.recallEligibility;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return result;
|
|
309
|
+
});
|
|
310
|
+
return results
|
|
311
|
+
.filter((result) => includeDecayed || result.memory.decayedScore >= config.salienceThreshold)
|
|
312
|
+
.sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* RRF retrieval path: build per-retriever rank lists from the FTS rows
|
|
316
|
+
* already produced by the SQL prelude, the cosine-similarity vector hits,
|
|
317
|
+
* and a fresh `graphRankFromQuery` call. Hand them to `runHybridRanker`,
|
|
318
|
+
* which fuses with RRF and applies post-fusion multiplicative boosts.
|
|
319
|
+
*
|
|
320
|
+
* Vector and graph rank lists may surface ids the FTS WHERE clause would
|
|
321
|
+
* have filtered out (category/type/status/tags/minSalience). Those are
|
|
322
|
+
* dropped at memory-map build time so the same filters apply across all
|
|
323
|
+
* three retrievers, keeping search behaviour predictable.
|
|
324
|
+
*/
|
|
325
|
+
function scoreWithRrf(input) {
|
|
326
|
+
const { rows, ftsScores, vectorResults, query, options, db, config, rankerConfig, limit, includeExplanation, } = input;
|
|
327
|
+
// Memory map starts with FTS rows (already passed all SQL filters).
|
|
328
|
+
const memoryMap = new Map();
|
|
329
|
+
const ftsIds = [];
|
|
330
|
+
for (const row of rows) {
|
|
331
|
+
const memory = rowToMemory(row);
|
|
332
|
+
memoryMap.set(memory.id, memory);
|
|
333
|
+
ftsIds.push(memory.id);
|
|
334
|
+
}
|
|
335
|
+
// Vector and graph rank lists may contain ids the FTS WHERE would have
|
|
336
|
+
// filtered out — fetch + filter to enforce the same constraints.
|
|
337
|
+
const considerCandidate = (id) => {
|
|
338
|
+
if (memoryMap.has(id))
|
|
339
|
+
return true;
|
|
340
|
+
const row = db.prepare('SELECT * FROM memories WHERE id = ?').get(id);
|
|
341
|
+
if (!row)
|
|
342
|
+
return false;
|
|
343
|
+
const memory = rowToMemory(row);
|
|
344
|
+
if (!candidatePassesFilters(memory, options))
|
|
345
|
+
return false;
|
|
346
|
+
memoryMap.set(memory.id, memory);
|
|
347
|
+
return true;
|
|
348
|
+
};
|
|
349
|
+
const vectorIds = Array.from(vectorResults.entries())
|
|
350
|
+
.sort((a, b) => b[1] - a[1])
|
|
351
|
+
.map(([id]) => id)
|
|
352
|
+
.filter(considerCandidate);
|
|
353
|
+
const graphLimit = Math.max(limit * 3, 50);
|
|
354
|
+
const graphResults = query && query.trim()
|
|
355
|
+
? graphRankFromQuery(query, db, { project: options.project, limit: graphLimit })
|
|
356
|
+
: [];
|
|
357
|
+
const graphIds = graphResults.map((r) => r.memoryId).filter(considerCandidate);
|
|
358
|
+
return runHybridRanker({
|
|
359
|
+
rankLists: [
|
|
360
|
+
{ name: 'fts', ids: ftsIds, weight: rankerConfig.weights.fts },
|
|
361
|
+
{ name: 'vector', ids: vectorIds, weight: rankerConfig.weights.vector },
|
|
362
|
+
{ name: 'graph', ids: graphIds, weight: rankerConfig.weights.graph },
|
|
363
|
+
],
|
|
364
|
+
memories: memoryMap,
|
|
365
|
+
vectorSimilarities: vectorResults,
|
|
366
|
+
ftsScores,
|
|
367
|
+
query,
|
|
368
|
+
db,
|
|
369
|
+
config,
|
|
370
|
+
rrfK: rankerConfig.rrfK,
|
|
371
|
+
includeExplanation,
|
|
372
|
+
includeDecayed: options.includeDecayed ?? false,
|
|
373
|
+
limit,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Mirror the WHERE-clause filters from the FTS SQL so that vector/graph
|
|
378
|
+
* candidates not returned by FTS are held to the same standard. Project
|
|
379
|
+
* scoping is already handled at the source (`vectorSearch` and
|
|
380
|
+
* `graphRankFromQuery`) so it isn't duplicated here.
|
|
381
|
+
*/
|
|
382
|
+
function candidatePassesFilters(memory, options) {
|
|
383
|
+
if (options.category && memory.category !== options.category)
|
|
384
|
+
return false;
|
|
385
|
+
if (options.type && memory.type !== options.type)
|
|
386
|
+
return false;
|
|
387
|
+
if (!options.includeArchived && memory.status === 'archived')
|
|
388
|
+
return false;
|
|
389
|
+
if (!options.includeSuppressed && memory.status === 'suppressed')
|
|
390
|
+
return false;
|
|
391
|
+
if (options.minSalience !== undefined && memory.salience < options.minSalience)
|
|
392
|
+
return false;
|
|
393
|
+
if (options.tags && options.tags.length > 0) {
|
|
394
|
+
const hasTag = options.tags.some((tag) => memory.tags.includes(tag));
|
|
395
|
+
if (!hasTag)
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
269
400
|
/**
|
|
270
401
|
* Search memories using full-text search, vector similarity, and filters
|
|
271
402
|
* Now uses hybrid search combining FTS5 keywords with semantic vector matching
|
package/dist/memory/types.d.ts
CHANGED
|
@@ -141,6 +141,22 @@ export interface SalienceFactors {
|
|
|
141
141
|
hasCodeReference: boolean;
|
|
142
142
|
emotionalMarkers: boolean;
|
|
143
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Hybrid retrieval engine selection. RRF is the v4.15 default; `legacy`
|
|
146
|
+
* keeps the pre-v4.15 weighted-sum scoring as a one-release safety belt.
|
|
147
|
+
*/
|
|
148
|
+
export type RankerEngine = 'rrf' | 'legacy';
|
|
149
|
+
export interface RankerWeights {
|
|
150
|
+
fts: number;
|
|
151
|
+
vector: number;
|
|
152
|
+
graph: number;
|
|
153
|
+
}
|
|
154
|
+
export interface RankerConfig {
|
|
155
|
+
engine: RankerEngine;
|
|
156
|
+
/** RRF smoothing constant. Cormack et al. (2009) recommend 60. */
|
|
157
|
+
rrfK: number;
|
|
158
|
+
weights: RankerWeights;
|
|
159
|
+
}
|
|
144
160
|
export interface MemoryConfig {
|
|
145
161
|
dbPath: string;
|
|
146
162
|
decayRate: number;
|
|
@@ -150,7 +166,9 @@ export interface MemoryConfig {
|
|
|
150
166
|
maxShortTermMemories: number;
|
|
151
167
|
maxLongTermMemories: number;
|
|
152
168
|
autoConsolidateHours: number;
|
|
169
|
+
ranker: RankerConfig;
|
|
153
170
|
}
|
|
171
|
+
export declare const DEFAULT_RANKER_CONFIG: RankerConfig;
|
|
154
172
|
export declare const DEFAULT_CONFIG: MemoryConfig;
|
|
155
173
|
/**
|
|
156
174
|
* Category-specific deletion thresholds
|
package/dist/memory/types.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core type definitions for the ShieldCortex memory system
|
|
3
3
|
*/
|
|
4
|
+
export const DEFAULT_RANKER_CONFIG = {
|
|
5
|
+
engine: 'rrf',
|
|
6
|
+
rrfK: 60,
|
|
7
|
+
weights: { fts: 0.4, vector: 0.6, graph: 0.3 },
|
|
8
|
+
};
|
|
4
9
|
export const DEFAULT_CONFIG = {
|
|
5
10
|
dbPath: '~/.shieldcortex/memories.db', // Note: actual path auto-detected with legacy fallback
|
|
6
11
|
decayRate: 0.995,
|
|
@@ -10,6 +15,7 @@ export const DEFAULT_CONFIG = {
|
|
|
10
15
|
maxShortTermMemories: 100,
|
|
11
16
|
maxLongTermMemories: 1000,
|
|
12
17
|
autoConsolidateHours: 4,
|
|
18
|
+
ranker: DEFAULT_RANKER_CONFIG,
|
|
13
19
|
};
|
|
14
20
|
/**
|
|
15
21
|
* Category-specific deletion thresholds
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shieldcortex",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.15.0",
|
|
4
4
|
"description": "Trustworthy memory and security for AI agents. Recall debugging, review queue, OpenClaw session capture, and memory poisoning defence for Claude Code, Codex, OpenClaw, LangChain, and MCP agents.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -57,6 +57,8 @@
|
|
|
57
57
|
"test": "node scripts/run-jest.mjs",
|
|
58
58
|
"test:watch": "node scripts/run-jest.mjs --watch",
|
|
59
59
|
"test:coverage": "node scripts/run-jest.mjs --coverage",
|
|
60
|
+
"bench": "tsx benchmark/longmemeval/run.ts",
|
|
61
|
+
"bench:smoke": "SHIELDCORTEX_SKIP_EMBEDDINGS=1 tsx benchmark/longmemeval/run.ts --quiet",
|
|
60
62
|
"audit:security": "npm audit --audit-level=moderate",
|
|
61
63
|
"prepack": "node scripts/ensure-bin-executable.mjs",
|
|
62
64
|
"prepublishOnly": "npm run build"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "shieldcortex-realtime",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.15.0",
|
|
4
4
|
"name": "ShieldCortex Real-time Scanner",
|
|
5
5
|
"description": "Real-time defence scanning on LLM input, memory extraction on LLM output, and active tool call interception with approval gating.",
|
|
6
6
|
"kind": null,
|
|
File without changes
|
|
File without changes
|