shieldcortex 2.0.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/LICENSE +21 -0
- package/README.md +282 -0
- package/dashboard/components.json +22 -0
- package/dashboard/eslint.config.mjs +42 -0
- package/dashboard/next.config.ts +7 -0
- package/dashboard/package-lock.json +8053 -0
- package/dashboard/package.json +44 -0
- package/dashboard/postcss.config.mjs +7 -0
- package/dashboard/public/file.svg +1 -0
- package/dashboard/public/globe.svg +1 -0
- package/dashboard/public/next.svg +1 -0
- package/dashboard/public/vercel.svg +1 -0
- package/dashboard/public/window.svg +1 -0
- package/dashboard/scripts/ensure-api.mjs +76 -0
- package/dashboard/src/app/error.tsx +49 -0
- package/dashboard/src/app/favicon.ico +0 -0
- package/dashboard/src/app/globals.css +130 -0
- package/dashboard/src/app/layout.tsx +35 -0
- package/dashboard/src/app/page.tsx +364 -0
- package/dashboard/src/components/Providers.tsx +27 -0
- package/dashboard/src/components/brain/ActivityPulseSystem.tsx +229 -0
- package/dashboard/src/components/brain/BrainMesh.tsx +133 -0
- package/dashboard/src/components/brain/BrainRegions.tsx +254 -0
- package/dashboard/src/components/brain/BrainScene.tsx +255 -0
- package/dashboard/src/components/brain/CategoryLabels.tsx +103 -0
- package/dashboard/src/components/brain/CoreSphere.tsx +215 -0
- package/dashboard/src/components/brain/DataFlowParticles.tsx +123 -0
- package/dashboard/src/components/brain/DataStreamRings.tsx +161 -0
- package/dashboard/src/components/brain/ElectronFlow.tsx +323 -0
- package/dashboard/src/components/brain/HolographicGrid.tsx +235 -0
- package/dashboard/src/components/brain/MemoryLinks.tsx +271 -0
- package/dashboard/src/components/brain/MemoryNode.tsx +245 -0
- package/dashboard/src/components/brain/NeuralPathways.tsx +441 -0
- package/dashboard/src/components/brain/SynapseNodes.tsx +312 -0
- package/dashboard/src/components/brain/TimelineControls.tsx +205 -0
- package/dashboard/src/components/chip/ChipScene.tsx +497 -0
- package/dashboard/src/components/chip/ChipSubstrate.tsx +238 -0
- package/dashboard/src/components/chip/CortexCore.tsx +210 -0
- package/dashboard/src/components/chip/DataBus.tsx +416 -0
- package/dashboard/src/components/chip/MemoryCell.tsx +225 -0
- package/dashboard/src/components/chip/MemoryGrid.tsx +328 -0
- package/dashboard/src/components/chip/QuantumCell.tsx +316 -0
- package/dashboard/src/components/chip/SectionLabel.tsx +113 -0
- package/dashboard/src/components/chip/index.ts +14 -0
- package/dashboard/src/components/controls/ControlPanel.tsx +106 -0
- package/dashboard/src/components/controls/VersionPanel.tsx +185 -0
- package/dashboard/src/components/dashboard/StatsPanel.tsx +164 -0
- package/dashboard/src/components/debug/ActivityLog.tsx +250 -0
- package/dashboard/src/components/debug/DebugPanel.tsx +101 -0
- package/dashboard/src/components/debug/QueryTester.tsx +192 -0
- package/dashboard/src/components/debug/RelationshipGraph.tsx +403 -0
- package/dashboard/src/components/debug/SqlConsole.tsx +319 -0
- package/dashboard/src/components/graph/KnowledgeGraph.tsx +230 -0
- package/dashboard/src/components/graph/OntologyGraph.tsx +631 -0
- package/dashboard/src/components/insights/ActivityHeatmap.tsx +131 -0
- package/dashboard/src/components/insights/InsightsView.tsx +46 -0
- package/dashboard/src/components/insights/KnowledgeMapPanel.tsx +80 -0
- package/dashboard/src/components/insights/QualityPanel.tsx +116 -0
- package/dashboard/src/components/memories/MemoriesView.tsx +150 -0
- package/dashboard/src/components/memories/MemoryCard.tsx +103 -0
- package/dashboard/src/components/memory/MemoryDetail.tsx +325 -0
- package/dashboard/src/components/nav/NavRail.tsx +54 -0
- package/dashboard/src/components/ui/button.tsx +62 -0
- package/dashboard/src/components/ui/card.tsx +92 -0
- package/dashboard/src/components/ui/input.tsx +21 -0
- package/dashboard/src/hooks/useDebouncedValue.ts +24 -0
- package/dashboard/src/hooks/useMemories.ts +458 -0
- package/dashboard/src/hooks/useSuggestions.ts +46 -0
- package/dashboard/src/lib/category-colors.ts +84 -0
- package/dashboard/src/lib/position-algorithm.ts +177 -0
- package/dashboard/src/lib/simplex-noise.ts +217 -0
- package/dashboard/src/lib/store.ts +88 -0
- package/dashboard/src/lib/utils.ts +6 -0
- package/dashboard/src/lib/websocket.ts +249 -0
- package/dashboard/src/types/memory.ts +73 -0
- package/dashboard/tsconfig.json +34 -0
- package/dist/__tests__/consolidation-merge.test.d.ts +9 -0
- package/dist/__tests__/consolidation-merge.test.d.ts.map +1 -0
- package/dist/__tests__/consolidation-merge.test.js +137 -0
- package/dist/__tests__/consolidation-merge.test.js.map +1 -0
- package/dist/__tests__/contradictions.test.d.ts +8 -0
- package/dist/__tests__/contradictions.test.d.ts.map +1 -0
- package/dist/__tests__/contradictions.test.js +78 -0
- package/dist/__tests__/contradictions.test.js.map +1 -0
- package/dist/__tests__/salience-evolution.test.d.ts +7 -0
- package/dist/__tests__/salience-evolution.test.d.ts.map +1 -0
- package/dist/__tests__/salience-evolution.test.js +151 -0
- package/dist/__tests__/salience-evolution.test.js.map +1 -0
- package/dist/__tests__/store.test.d.ts +7 -0
- package/dist/__tests__/store.test.d.ts.map +1 -0
- package/dist/__tests__/store.test.js +582 -0
- package/dist/__tests__/store.test.js.map +1 -0
- package/dist/api/control.d.ts +27 -0
- package/dist/api/control.d.ts.map +1 -0
- package/dist/api/control.js +60 -0
- package/dist/api/control.js.map +1 -0
- package/dist/api/events.d.ts +159 -0
- package/dist/api/events.d.ts.map +1 -0
- package/dist/api/events.js +155 -0
- package/dist/api/events.js.map +1 -0
- package/dist/api/version.d.ts +36 -0
- package/dist/api/version.d.ts.map +1 -0
- package/dist/api/version.js +146 -0
- package/dist/api/version.js.map +1 -0
- package/dist/api/visualization-server.d.ts +11 -0
- package/dist/api/visualization-server.d.ts.map +1 -0
- package/dist/api/visualization-server.js +1186 -0
- package/dist/api/visualization-server.js.map +1 -0
- package/dist/context/project-context.d.ts +57 -0
- package/dist/context/project-context.d.ts.map +1 -0
- package/dist/context/project-context.js +135 -0
- package/dist/context/project-context.js.map +1 -0
- package/dist/database/init.d.ts +49 -0
- package/dist/database/init.d.ts.map +1 -0
- package/dist/database/init.js +567 -0
- package/dist/database/init.js.map +1 -0
- package/dist/defence/__tests__/firewall.test.d.ts +8 -0
- package/dist/defence/__tests__/firewall.test.d.ts.map +1 -0
- package/dist/defence/__tests__/firewall.test.js +123 -0
- package/dist/defence/__tests__/firewall.test.js.map +1 -0
- package/dist/defence/__tests__/fragmentation.test.d.ts +7 -0
- package/dist/defence/__tests__/fragmentation.test.d.ts.map +1 -0
- package/dist/defence/__tests__/fragmentation.test.js +51 -0
- package/dist/defence/__tests__/fragmentation.test.js.map +1 -0
- package/dist/defence/__tests__/pipeline.test.d.ts +8 -0
- package/dist/defence/__tests__/pipeline.test.d.ts.map +1 -0
- package/dist/defence/__tests__/pipeline.test.js +61 -0
- package/dist/defence/__tests__/pipeline.test.js.map +1 -0
- package/dist/defence/__tests__/sensitivity.test.d.ts +7 -0
- package/dist/defence/__tests__/sensitivity.test.d.ts.map +1 -0
- package/dist/defence/__tests__/sensitivity.test.js +61 -0
- package/dist/defence/__tests__/sensitivity.test.js.map +1 -0
- package/dist/defence/__tests__/trust.test.d.ts +7 -0
- package/dist/defence/__tests__/trust.test.d.ts.map +1 -0
- package/dist/defence/__tests__/trust.test.js +49 -0
- package/dist/defence/__tests__/trust.test.js.map +1 -0
- package/dist/defence/audit/index.d.ts +4 -0
- package/dist/defence/audit/index.d.ts.map +1 -0
- package/dist/defence/audit/index.js +3 -0
- package/dist/defence/audit/index.js.map +1 -0
- package/dist/defence/audit/logger.d.ts +14 -0
- package/dist/defence/audit/logger.d.ts.map +1 -0
- package/dist/defence/audit/logger.js +54 -0
- package/dist/defence/audit/logger.js.map +1 -0
- package/dist/defence/audit/queries.d.ts +33 -0
- package/dist/defence/audit/queries.d.ts.map +1 -0
- package/dist/defence/audit/queries.js +103 -0
- package/dist/defence/audit/queries.js.map +1 -0
- package/dist/defence/firewall/anomaly-scorer.d.ts +8 -0
- package/dist/defence/firewall/anomaly-scorer.d.ts.map +1 -0
- package/dist/defence/firewall/anomaly-scorer.js +58 -0
- package/dist/defence/firewall/anomaly-scorer.js.map +1 -0
- package/dist/defence/firewall/encoding-detector.d.ts +13 -0
- package/dist/defence/firewall/encoding-detector.d.ts.map +1 -0
- package/dist/defence/firewall/encoding-detector.js +120 -0
- package/dist/defence/firewall/encoding-detector.js.map +1 -0
- package/dist/defence/firewall/index.d.ts +21 -0
- package/dist/defence/firewall/index.d.ts.map +1 -0
- package/dist/defence/firewall/index.js +133 -0
- package/dist/defence/firewall/index.js.map +1 -0
- package/dist/defence/firewall/instruction-detector.d.ts +12 -0
- package/dist/defence/firewall/instruction-detector.d.ts.map +1 -0
- package/dist/defence/firewall/instruction-detector.js +99 -0
- package/dist/defence/firewall/instruction-detector.js.map +1 -0
- package/dist/defence/firewall/privilege-detector.d.ts +13 -0
- package/dist/defence/firewall/privilege-detector.d.ts.map +1 -0
- package/dist/defence/firewall/privilege-detector.js +89 -0
- package/dist/defence/firewall/privilege-detector.js.map +1 -0
- package/dist/defence/fragmentation/assembly-detector.d.ts +18 -0
- package/dist/defence/fragmentation/assembly-detector.d.ts.map +1 -0
- package/dist/defence/fragmentation/assembly-detector.js +72 -0
- package/dist/defence/fragmentation/assembly-detector.js.map +1 -0
- package/dist/defence/fragmentation/entity-extractor.d.ts +19 -0
- package/dist/defence/fragmentation/entity-extractor.d.ts.map +1 -0
- package/dist/defence/fragmentation/entity-extractor.js +86 -0
- package/dist/defence/fragmentation/entity-extractor.js.map +1 -0
- package/dist/defence/fragmentation/index.d.ts +23 -0
- package/dist/defence/fragmentation/index.d.ts.map +1 -0
- package/dist/defence/fragmentation/index.js +49 -0
- package/dist/defence/fragmentation/index.js.map +1 -0
- package/dist/defence/fragmentation/temporal-analyzer.d.ts +28 -0
- package/dist/defence/fragmentation/temporal-analyzer.d.ts.map +1 -0
- package/dist/defence/fragmentation/temporal-analyzer.js +41 -0
- package/dist/defence/fragmentation/temporal-analyzer.js.map +1 -0
- package/dist/defence/index.d.ts +12 -0
- package/dist/defence/index.d.ts.map +1 -0
- package/dist/defence/index.js +18 -0
- package/dist/defence/index.js.map +1 -0
- package/dist/defence/pipeline.d.ts +9 -0
- package/dist/defence/pipeline.d.ts.map +1 -0
- package/dist/defence/pipeline.js +115 -0
- package/dist/defence/pipeline.js.map +1 -0
- package/dist/defence/scanner/index.d.ts +5 -0
- package/dist/defence/scanner/index.d.ts.map +1 -0
- package/dist/defence/scanner/index.js +5 -0
- package/dist/defence/scanner/index.js.map +1 -0
- package/dist/defence/scanner/scan-existing.d.ts +34 -0
- package/dist/defence/scanner/scan-existing.d.ts.map +1 -0
- package/dist/defence/scanner/scan-existing.js +136 -0
- package/dist/defence/scanner/scan-existing.js.map +1 -0
- package/dist/defence/sensitivity/classifier.d.ts +6 -0
- package/dist/defence/sensitivity/classifier.d.ts.map +1 -0
- package/dist/defence/sensitivity/classifier.js +50 -0
- package/dist/defence/sensitivity/classifier.js.map +1 -0
- package/dist/defence/sensitivity/index.d.ts +11 -0
- package/dist/defence/sensitivity/index.d.ts.map +1 -0
- package/dist/defence/sensitivity/index.js +13 -0
- package/dist/defence/sensitivity/index.js.map +1 -0
- package/dist/defence/sensitivity/patterns.d.ts +14 -0
- package/dist/defence/sensitivity/patterns.d.ts.map +1 -0
- package/dist/defence/sensitivity/patterns.js +67 -0
- package/dist/defence/sensitivity/patterns.js.map +1 -0
- package/dist/defence/sensitivity/redaction.d.ts +17 -0
- package/dist/defence/sensitivity/redaction.d.ts.map +1 -0
- package/dist/defence/sensitivity/redaction.js +47 -0
- package/dist/defence/sensitivity/redaction.js.map +1 -0
- package/dist/defence/trust/index.d.ts +3 -0
- package/dist/defence/trust/index.d.ts.map +1 -0
- package/dist/defence/trust/index.js +3 -0
- package/dist/defence/trust/index.js.map +1 -0
- package/dist/defence/trust/recall-filter.d.ts +10 -0
- package/dist/defence/trust/recall-filter.d.ts.map +1 -0
- package/dist/defence/trust/recall-filter.js +38 -0
- package/dist/defence/trust/recall-filter.js.map +1 -0
- package/dist/defence/trust/source-scorer.d.ts +6 -0
- package/dist/defence/trust/source-scorer.d.ts.map +1 -0
- package/dist/defence/trust/source-scorer.js +34 -0
- package/dist/defence/trust/source-scorer.js.map +1 -0
- package/dist/defence/types.d.ts +88 -0
- package/dist/defence/types.d.ts.map +1 -0
- package/dist/defence/types.js +15 -0
- package/dist/defence/types.js.map +1 -0
- package/dist/embeddings/generator.d.ts +20 -0
- package/dist/embeddings/generator.d.ts.map +1 -0
- package/dist/embeddings/generator.js +83 -0
- package/dist/embeddings/generator.js.map +1 -0
- package/dist/embeddings/index.d.ts +2 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +2 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/errors.d.ts +74 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +131 -0
- package/dist/errors.js.map +1 -0
- package/dist/graph/backfill.d.ts +6 -0
- package/dist/graph/backfill.d.ts.map +1 -0
- package/dist/graph/backfill.js +33 -0
- package/dist/graph/backfill.js.map +1 -0
- package/dist/graph/extract.d.ts +21 -0
- package/dist/graph/extract.d.ts.map +1 -0
- package/dist/graph/extract.js +231 -0
- package/dist/graph/extract.js.map +1 -0
- package/dist/graph/resolve.d.ts +6 -0
- package/dist/graph/resolve.d.ts.map +1 -0
- package/dist/graph/resolve.js +126 -0
- package/dist/graph/resolve.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +248 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/activation.d.ts +69 -0
- package/dist/memory/activation.d.ts.map +1 -0
- package/dist/memory/activation.js +168 -0
- package/dist/memory/activation.js.map +1 -0
- package/dist/memory/consolidate.d.ts +98 -0
- package/dist/memory/consolidate.d.ts.map +1 -0
- package/dist/memory/consolidate.js +511 -0
- package/dist/memory/consolidate.js.map +1 -0
- package/dist/memory/contradiction.d.ts +69 -0
- package/dist/memory/contradiction.d.ts.map +1 -0
- package/dist/memory/contradiction.js +286 -0
- package/dist/memory/contradiction.js.map +1 -0
- package/dist/memory/decay.d.ts +62 -0
- package/dist/memory/decay.d.ts.map +1 -0
- package/dist/memory/decay.js +184 -0
- package/dist/memory/decay.js.map +1 -0
- package/dist/memory/salience.d.ts +36 -0
- package/dist/memory/salience.d.ts.map +1 -0
- package/dist/memory/salience.js +216 -0
- package/dist/memory/salience.js.map +1 -0
- package/dist/memory/similarity.d.ts +57 -0
- package/dist/memory/similarity.d.ts.map +1 -0
- package/dist/memory/similarity.js +114 -0
- package/dist/memory/similarity.js.map +1 -0
- package/dist/memory/store.d.ts +179 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +1184 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/memory/types.d.ts +97 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +30 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +568 -0
- package/dist/server.js.map +1 -0
- package/dist/service/install.d.ts +15 -0
- package/dist/service/install.d.ts.map +1 -0
- package/dist/service/install.js +178 -0
- package/dist/service/install.js.map +1 -0
- package/dist/service/templates.d.ts +13 -0
- package/dist/service/templates.d.ts.map +1 -0
- package/dist/service/templates.js +58 -0
- package/dist/service/templates.js.map +1 -0
- package/dist/setup/claude-md.d.ts +12 -0
- package/dist/setup/claude-md.d.ts.map +1 -0
- package/dist/setup/claude-md.js +68 -0
- package/dist/setup/claude-md.js.map +1 -0
- package/dist/setup/clawdbot.d.ts +15 -0
- package/dist/setup/clawdbot.d.ts.map +1 -0
- package/dist/setup/clawdbot.js +118 -0
- package/dist/setup/clawdbot.js.map +1 -0
- package/dist/setup/doctor.d.ts +5 -0
- package/dist/setup/doctor.d.ts.map +1 -0
- package/dist/setup/doctor.js +141 -0
- package/dist/setup/doctor.js.map +1 -0
- package/dist/setup/hooks.d.ts +6 -0
- package/dist/setup/hooks.d.ts.map +1 -0
- package/dist/setup/hooks.js +36 -0
- package/dist/setup/hooks.js.map +1 -0
- package/dist/setup/migrate.d.ts +16 -0
- package/dist/setup/migrate.d.ts.map +1 -0
- package/dist/setup/migrate.js +164 -0
- package/dist/setup/migrate.js.map +1 -0
- package/dist/setup/settings-hooks.d.ts +7 -0
- package/dist/setup/settings-hooks.d.ts.map +1 -0
- package/dist/setup/settings-hooks.js +83 -0
- package/dist/setup/settings-hooks.js.map +1 -0
- package/dist/setup/uninstall.d.ts +12 -0
- package/dist/setup/uninstall.d.ts.map +1 -0
- package/dist/setup/uninstall.js +125 -0
- package/dist/setup/uninstall.js.map +1 -0
- package/dist/tools/context.d.ts +135 -0
- package/dist/tools/context.d.ts.map +1 -0
- package/dist/tools/context.js +273 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/forget.d.ts +53 -0
- package/dist/tools/forget.d.ts.map +1 -0
- package/dist/tools/forget.js +179 -0
- package/dist/tools/forget.js.map +1 -0
- package/dist/tools/graph.d.ts +46 -0
- package/dist/tools/graph.d.ts.map +1 -0
- package/dist/tools/graph.js +206 -0
- package/dist/tools/graph.js.map +1 -0
- package/dist/tools/recall.d.ts +79 -0
- package/dist/tools/recall.d.ts.map +1 -0
- package/dist/tools/recall.js +156 -0
- package/dist/tools/recall.js.map +1 -0
- package/dist/tools/remember.d.ts +83 -0
- package/dist/tools/remember.d.ts.map +1 -0
- package/dist/tools/remember.js +151 -0
- package/dist/tools/remember.js.map +1 -0
- package/dist/worker/brain-worker.d.ts +100 -0
- package/dist/worker/brain-worker.d.ts.map +1 -0
- package/dist/worker/brain-worker.js +283 -0
- package/dist/worker/brain-worker.js.map +1 -0
- package/dist/worker/link-discovery.d.ts +47 -0
- package/dist/worker/link-discovery.d.ts.map +1 -0
- package/dist/worker/link-discovery.js +103 -0
- package/dist/worker/link-discovery.js.map +1 -0
- package/dist/worker/predictive-consolidation.d.ts +46 -0
- package/dist/worker/predictive-consolidation.d.ts.map +1 -0
- package/dist/worker/predictive-consolidation.js +110 -0
- package/dist/worker/predictive-consolidation.js.map +1 -0
- package/dist/worker/types.d.ts +91 -0
- package/dist/worker/types.d.ts.map +1 -0
- package/dist/worker/types.js +22 -0
- package/dist/worker/types.js.map +1 -0
- package/hooks/clawdbot/cortex-memory/HOOK.md +71 -0
- package/hooks/clawdbot/cortex-memory/handler.js +279 -0
- package/package.json +73 -0
- package/scripts/pre-compact-hook.mjs +716 -0
- package/scripts/session-end-hook.mjs +548 -0
- package/scripts/session-start-hook.mjs +221 -0
- package/scripts/start-dashboard.sh +41 -0
- package/scripts/stop-dashboard.sh +21 -0
- package/scripts/stop-hook.mjs +163 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket client for real-time memory updates
|
|
3
|
+
*
|
|
4
|
+
* Connects to the visualization server's WebSocket endpoint
|
|
5
|
+
* and dispatches events to React Query for cache invalidation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useEffect, useRef, useCallback, useState } from 'react';
|
|
9
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
10
|
+
|
|
11
|
+
const WS_URL = process.env.NEXT_PUBLIC_WS_URL || 'ws://localhost:3001/ws/events';
|
|
12
|
+
|
|
13
|
+
export type WebSocketEventType =
|
|
14
|
+
| 'initial_state'
|
|
15
|
+
| 'memory_created'
|
|
16
|
+
| 'memory_accessed'
|
|
17
|
+
| 'memory_updated'
|
|
18
|
+
| 'memory_deleted'
|
|
19
|
+
| 'consolidation_complete'
|
|
20
|
+
| 'decay_tick'
|
|
21
|
+
// Phase 4: Worker events
|
|
22
|
+
| 'worker_light_tick'
|
|
23
|
+
| 'worker_medium_tick'
|
|
24
|
+
| 'link_discovered'
|
|
25
|
+
| 'predictive_consolidation'
|
|
26
|
+
// Version/Update events
|
|
27
|
+
| 'update_started'
|
|
28
|
+
| 'update_complete'
|
|
29
|
+
| 'update_failed'
|
|
30
|
+
| 'server_restarting';
|
|
31
|
+
|
|
32
|
+
// Alias for backwards compatibility
|
|
33
|
+
export type MemoryEventType = WebSocketEventType;
|
|
34
|
+
|
|
35
|
+
interface WebSocketMessage {
|
|
36
|
+
type: WebSocketEventType;
|
|
37
|
+
data?: unknown;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface UseMemoryWebSocketOptions {
|
|
41
|
+
enabled?: boolean;
|
|
42
|
+
onMessage?: (event: WebSocketMessage) => void;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Reconnection configuration
|
|
46
|
+
const INITIAL_RECONNECT_DELAY = 1000; // 1 second
|
|
47
|
+
const MAX_RECONNECT_DELAY = 30000; // 30 seconds max
|
|
48
|
+
const MAX_RECONNECT_ATTEMPTS = 10;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Hook to connect to memory WebSocket and handle real-time updates
|
|
52
|
+
*/
|
|
53
|
+
export function useMemoryWebSocket(options: UseMemoryWebSocketOptions = {}) {
|
|
54
|
+
const { enabled = true, onMessage } = options;
|
|
55
|
+
const queryClient = useQueryClient();
|
|
56
|
+
const wsRef = useRef<WebSocket | null>(null);
|
|
57
|
+
const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
58
|
+
const reconnectAttemptsRef = useRef(0);
|
|
59
|
+
const reconnectDelayRef = useRef(INITIAL_RECONNECT_DELAY);
|
|
60
|
+
const connectRef = useRef<() => void>(() => {});
|
|
61
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
62
|
+
const [lastEvent, setLastEvent] = useState<{
|
|
63
|
+
type: WebSocketEventType;
|
|
64
|
+
data?: unknown;
|
|
65
|
+
timestamp: string;
|
|
66
|
+
} | null>(null);
|
|
67
|
+
|
|
68
|
+
// Use ref for onMessage to avoid recreating connect callback when callback changes
|
|
69
|
+
// This prevents WebSocket reconnections on every render
|
|
70
|
+
const onMessageRef = useRef(onMessage);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
onMessageRef.current = onMessage;
|
|
73
|
+
}, [onMessage]);
|
|
74
|
+
|
|
75
|
+
const connect = useCallback(() => {
|
|
76
|
+
if (!enabled || wsRef.current?.readyState === WebSocket.OPEN) return;
|
|
77
|
+
|
|
78
|
+
// Clear any pending reconnect timeout
|
|
79
|
+
if (reconnectTimeoutRef.current) {
|
|
80
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
81
|
+
reconnectTimeoutRef.current = null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const ws = new WebSocket(WS_URL);
|
|
86
|
+
wsRef.current = ws;
|
|
87
|
+
|
|
88
|
+
ws.onopen = () => {
|
|
89
|
+
setIsConnected(true);
|
|
90
|
+
// Reset reconnect state on successful connection
|
|
91
|
+
reconnectAttemptsRef.current = 0;
|
|
92
|
+
reconnectDelayRef.current = INITIAL_RECONNECT_DELAY;
|
|
93
|
+
console.log('[WebSocket] Connected to memory server');
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
ws.onmessage = (event) => {
|
|
97
|
+
try {
|
|
98
|
+
const message = JSON.parse(event.data) as WebSocketMessage & { timestamp?: string };
|
|
99
|
+
setLastEvent({
|
|
100
|
+
type: message.type,
|
|
101
|
+
data: message.data,
|
|
102
|
+
timestamp: message.timestamp || new Date().toISOString(),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Notify external handler (use ref to avoid stale closure)
|
|
106
|
+
onMessageRef.current?.(message);
|
|
107
|
+
|
|
108
|
+
// Invalidate relevant queries based on event type
|
|
109
|
+
switch (message.type) {
|
|
110
|
+
case 'initial_state':
|
|
111
|
+
// Full state received, refresh everything
|
|
112
|
+
queryClient.invalidateQueries({ queryKey: ['memories'] });
|
|
113
|
+
queryClient.invalidateQueries({ queryKey: ['stats'] });
|
|
114
|
+
queryClient.invalidateQueries({ queryKey: ['links'] });
|
|
115
|
+
break;
|
|
116
|
+
|
|
117
|
+
case 'memory_created':
|
|
118
|
+
case 'memory_updated':
|
|
119
|
+
case 'memory_deleted':
|
|
120
|
+
// Memory changed, refresh memories list
|
|
121
|
+
queryClient.invalidateQueries({ queryKey: ['memories'] });
|
|
122
|
+
queryClient.invalidateQueries({ queryKey: ['stats'] });
|
|
123
|
+
break;
|
|
124
|
+
|
|
125
|
+
case 'consolidation_complete':
|
|
126
|
+
// Major changes, refresh everything
|
|
127
|
+
queryClient.invalidateQueries({ queryKey: ['memories'] });
|
|
128
|
+
queryClient.invalidateQueries({ queryKey: ['stats'] });
|
|
129
|
+
queryClient.invalidateQueries({ queryKey: ['links'] });
|
|
130
|
+
break;
|
|
131
|
+
|
|
132
|
+
case 'decay_tick':
|
|
133
|
+
// Just decay scores updated, soft refresh
|
|
134
|
+
// We don't invalidate here to avoid constant refetches
|
|
135
|
+
// The dashboard can handle this via the onMessage callback
|
|
136
|
+
break;
|
|
137
|
+
|
|
138
|
+
// Phase 4: Worker events
|
|
139
|
+
case 'link_discovered':
|
|
140
|
+
// New link created, refresh links
|
|
141
|
+
queryClient.invalidateQueries({ queryKey: ['links'] });
|
|
142
|
+
break;
|
|
143
|
+
|
|
144
|
+
case 'predictive_consolidation':
|
|
145
|
+
// Predictive consolidation ran, refresh everything
|
|
146
|
+
queryClient.invalidateQueries({ queryKey: ['memories'] });
|
|
147
|
+
queryClient.invalidateQueries({ queryKey: ['stats'] });
|
|
148
|
+
queryClient.invalidateQueries({ queryKey: ['links'] });
|
|
149
|
+
break;
|
|
150
|
+
|
|
151
|
+
case 'worker_light_tick':
|
|
152
|
+
case 'worker_medium_tick':
|
|
153
|
+
// Worker ticks don't require cache invalidation
|
|
154
|
+
// Dashboard can track via onMessage callback if needed
|
|
155
|
+
break;
|
|
156
|
+
|
|
157
|
+
// Version/Update events
|
|
158
|
+
case 'update_started':
|
|
159
|
+
case 'update_complete':
|
|
160
|
+
case 'update_failed':
|
|
161
|
+
// Let VersionPanel handle via onMessage callback
|
|
162
|
+
// Invalidate version queries on completion
|
|
163
|
+
if (message.type === 'update_complete') {
|
|
164
|
+
queryClient.invalidateQueries({ queryKey: ['version'] });
|
|
165
|
+
queryClient.invalidateQueries({ queryKey: ['version-check'] });
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
|
|
169
|
+
case 'server_restarting':
|
|
170
|
+
// Server is restarting - let onMessage callback handle UI
|
|
171
|
+
console.log('[WebSocket] Server restarting, will reconnect shortly...');
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
} catch (err) {
|
|
175
|
+
console.error('[WebSocket] Failed to parse message:', err);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
ws.onerror = () => {
|
|
180
|
+
// Use warn instead of error to avoid Next.js error overlay in dev mode
|
|
181
|
+
// WebSocket connection failures are expected when API server isn't running
|
|
182
|
+
console.warn('[WebSocket] Connection failed - is the API server running?');
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
ws.onclose = () => {
|
|
186
|
+
setIsConnected(false);
|
|
187
|
+
console.log('[WebSocket] Disconnected');
|
|
188
|
+
|
|
189
|
+
// Attempt to reconnect with exponential backoff
|
|
190
|
+
if (enabled && reconnectAttemptsRef.current < MAX_RECONNECT_ATTEMPTS) {
|
|
191
|
+
const delay = reconnectDelayRef.current;
|
|
192
|
+
reconnectAttemptsRef.current++;
|
|
193
|
+
|
|
194
|
+
// Exponential backoff: double the delay each time, up to max
|
|
195
|
+
reconnectDelayRef.current = Math.min(
|
|
196
|
+
reconnectDelayRef.current * 2,
|
|
197
|
+
MAX_RECONNECT_DELAY
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
console.log(
|
|
201
|
+
`[WebSocket] Reconnecting in ${delay}ms (attempt ${reconnectAttemptsRef.current}/${MAX_RECONNECT_ATTEMPTS})...`
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
reconnectTimeoutRef.current = setTimeout(() => {
|
|
205
|
+
connectRef.current();
|
|
206
|
+
}, delay);
|
|
207
|
+
} else if (reconnectAttemptsRef.current >= MAX_RECONNECT_ATTEMPTS) {
|
|
208
|
+
console.error('[WebSocket] Max reconnection attempts reached. Use reconnect() to try again.');
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
} catch (err) {
|
|
212
|
+
console.error('[WebSocket] Failed to connect:', err);
|
|
213
|
+
}
|
|
214
|
+
}, [enabled, queryClient]); // onMessage accessed via ref to prevent reconnection loops
|
|
215
|
+
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
connectRef.current = connect;
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Connect on mount
|
|
221
|
+
useEffect(() => {
|
|
222
|
+
if (enabled) {
|
|
223
|
+
connect();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return () => {
|
|
227
|
+
if (reconnectTimeoutRef.current) {
|
|
228
|
+
clearTimeout(reconnectTimeoutRef.current);
|
|
229
|
+
}
|
|
230
|
+
if (wsRef.current) {
|
|
231
|
+
wsRef.current.close();
|
|
232
|
+
wsRef.current = null;
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}, [enabled, connect]);
|
|
236
|
+
|
|
237
|
+
// Manual reconnect that resets backoff state
|
|
238
|
+
const manualReconnect = useCallback(() => {
|
|
239
|
+
reconnectAttemptsRef.current = 0;
|
|
240
|
+
reconnectDelayRef.current = INITIAL_RECONNECT_DELAY;
|
|
241
|
+
connect();
|
|
242
|
+
}, [connect]);
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
isConnected,
|
|
246
|
+
lastEvent,
|
|
247
|
+
reconnect: manualReconnect,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Types
|
|
3
|
+
* Shared type definitions for the dashboard
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type MemoryType = 'short_term' | 'long_term' | 'episodic';
|
|
7
|
+
|
|
8
|
+
export type MemoryCategory =
|
|
9
|
+
| 'architecture'
|
|
10
|
+
| 'pattern'
|
|
11
|
+
| 'preference'
|
|
12
|
+
| 'error'
|
|
13
|
+
| 'context'
|
|
14
|
+
| 'learning'
|
|
15
|
+
| 'todo'
|
|
16
|
+
| 'note'
|
|
17
|
+
| 'relationship'
|
|
18
|
+
| 'custom';
|
|
19
|
+
|
|
20
|
+
export interface Memory {
|
|
21
|
+
id: number;
|
|
22
|
+
type: MemoryType;
|
|
23
|
+
category: MemoryCategory;
|
|
24
|
+
title: string;
|
|
25
|
+
content: string;
|
|
26
|
+
project?: string;
|
|
27
|
+
tags: string[];
|
|
28
|
+
salience: number;
|
|
29
|
+
accessCount: number;
|
|
30
|
+
lastAccessed: string;
|
|
31
|
+
createdAt: string;
|
|
32
|
+
decayedScore?: number;
|
|
33
|
+
metadata?: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface MemoryLink {
|
|
37
|
+
id: number;
|
|
38
|
+
source_id: number;
|
|
39
|
+
target_id: number;
|
|
40
|
+
relationship: string;
|
|
41
|
+
strength: number;
|
|
42
|
+
created_at: string;
|
|
43
|
+
source_title?: string;
|
|
44
|
+
target_title?: string;
|
|
45
|
+
source_category?: MemoryCategory;
|
|
46
|
+
target_category?: MemoryCategory;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface MemoryStats {
|
|
50
|
+
total: number;
|
|
51
|
+
shortTerm: number;
|
|
52
|
+
longTerm: number;
|
|
53
|
+
episodic: number;
|
|
54
|
+
byCategory: Record<string, number>;
|
|
55
|
+
averageSalience: number;
|
|
56
|
+
decayDistribution?: {
|
|
57
|
+
healthy: number;
|
|
58
|
+
fading: number;
|
|
59
|
+
critical: number;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface MemoryEvent {
|
|
64
|
+
type: 'memory_created' | 'memory_accessed' | 'memory_updated' | 'memory_deleted' | 'consolidation_complete' | 'decay_tick';
|
|
65
|
+
timestamp: string;
|
|
66
|
+
data: unknown;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface Memory3DPosition {
|
|
70
|
+
x: number;
|
|
71
|
+
y: number;
|
|
72
|
+
z: number;
|
|
73
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [
|
|
17
|
+
{
|
|
18
|
+
"name": "next"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"paths": {
|
|
22
|
+
"@/*": ["./src/*"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"include": [
|
|
26
|
+
"next-env.d.ts",
|
|
27
|
+
"**/*.ts",
|
|
28
|
+
"**/*.tsx",
|
|
29
|
+
".next/types/**/*.ts",
|
|
30
|
+
".next/dev/types/**/*.ts",
|
|
31
|
+
"**/*.mts"
|
|
32
|
+
],
|
|
33
|
+
"exclude": ["node_modules"]
|
|
34
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidation Merge Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests the similarity-based clustering logic used by mergeSimilarMemories.
|
|
5
|
+
* Since the full function requires database access, we test the clustering
|
|
6
|
+
* algorithm components and similarity thresholds.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=consolidation-merge.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidation-merge.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/consolidation-merge.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidation Merge Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests the similarity-based clustering logic used by mergeSimilarMemories.
|
|
5
|
+
* Since the full function requires database access, we test the clustering
|
|
6
|
+
* algorithm components and similarity thresholds.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect } from '@jest/globals';
|
|
9
|
+
import { jaccardSimilarity } from '../memory/similarity.js';
|
|
10
|
+
describe('mergeSimilarMemories clustering logic', () => {
|
|
11
|
+
// Simulate the clustering algorithm from mergeSimilarMemories
|
|
12
|
+
function findClusters(memories, threshold = 0.25) {
|
|
13
|
+
const clustered = new Set();
|
|
14
|
+
const clusters = [];
|
|
15
|
+
for (let i = 0; i < memories.length; i++) {
|
|
16
|
+
if (clustered.has(i))
|
|
17
|
+
continue;
|
|
18
|
+
const cluster = [i];
|
|
19
|
+
const memA = memories[i];
|
|
20
|
+
for (let j = i + 1; j < memories.length; j++) {
|
|
21
|
+
if (clustered.has(j))
|
|
22
|
+
continue;
|
|
23
|
+
const memB = memories[j];
|
|
24
|
+
const contentSim = jaccardSimilarity(memA.content, memB.content);
|
|
25
|
+
const titleSim = jaccardSimilarity(memA.title, memB.title);
|
|
26
|
+
const combinedSim = contentSim * 0.6 + titleSim * 0.4;
|
|
27
|
+
if (combinedSim >= threshold) {
|
|
28
|
+
cluster.push(j);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (cluster.length >= 2) {
|
|
32
|
+
for (const idx of cluster)
|
|
33
|
+
clustered.add(idx);
|
|
34
|
+
clusters.push(cluster);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return clusters;
|
|
38
|
+
}
|
|
39
|
+
it('should cluster related JWT memories together', () => {
|
|
40
|
+
const memories = [
|
|
41
|
+
{
|
|
42
|
+
title: 'JWT authentication token setup',
|
|
43
|
+
content: 'Set up JWT authentication token signing using RS256 algorithm in the auth service for user authentication and token validation',
|
|
44
|
+
salience: 0.6,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
title: 'JWT authentication token expiry',
|
|
48
|
+
content: 'JWT authentication tokens expire after 24 hours with refresh token rotation for the auth service user authentication flow',
|
|
49
|
+
salience: 0.5,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
title: 'JWT authentication token middleware',
|
|
53
|
+
content: 'Created JWT authentication token middleware that validates user tokens on every auth service API request and handles token refresh',
|
|
54
|
+
salience: 0.4,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
const clusters = findClusters(memories, 0.25);
|
|
58
|
+
// All 3 should be in one cluster (they share JWT/token/auth vocabulary)
|
|
59
|
+
expect(clusters.length).toBeGreaterThanOrEqual(1);
|
|
60
|
+
const biggestCluster = clusters.reduce((a, b) => (a.length > b.length ? a : b), []);
|
|
61
|
+
expect(biggestCluster.length).toBeGreaterThanOrEqual(2);
|
|
62
|
+
});
|
|
63
|
+
it('should pick highest salience memory as base', () => {
|
|
64
|
+
const memories = [
|
|
65
|
+
{ title: 'JWT authentication setup', content: 'JWT authentication token signing RS256 in auth service', salience: 0.6 },
|
|
66
|
+
{ title: 'JWT authentication expiry', content: 'JWT authentication token expiry 24 hours auth service', salience: 0.5 },
|
|
67
|
+
{ title: 'JWT authentication middleware', content: 'JWT authentication token middleware validates auth service', salience: 0.4 },
|
|
68
|
+
];
|
|
69
|
+
const clusters = findClusters(memories, 0.25);
|
|
70
|
+
expect(clusters.length).toBeGreaterThanOrEqual(1);
|
|
71
|
+
// Sort cluster by salience desc - index 0 (salience 0.6) should be first
|
|
72
|
+
const cluster = clusters[0];
|
|
73
|
+
const sorted = [...cluster].sort((a, b) => memories[b].salience - memories[a].salience);
|
|
74
|
+
expect(sorted[0]).toBe(0); // Highest salience is index 0
|
|
75
|
+
});
|
|
76
|
+
it('should not cluster unrelated memories', () => {
|
|
77
|
+
const memories = [
|
|
78
|
+
{
|
|
79
|
+
title: 'JWT Setup',
|
|
80
|
+
content: 'Set up JWT authentication using RS256 algorithm',
|
|
81
|
+
salience: 0.5,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: 'Database Migration',
|
|
85
|
+
content: 'Migrated PostgreSQL schema to add user preferences table with JSONB columns',
|
|
86
|
+
salience: 0.5,
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
const clusters = findClusters(memories, 0.25);
|
|
90
|
+
// These should NOT cluster - completely different topics
|
|
91
|
+
expect(clusters.length).toBe(0);
|
|
92
|
+
});
|
|
93
|
+
it('should produce correct merged content format', () => {
|
|
94
|
+
// Simulate what mergeSimilarMemories does after clustering
|
|
95
|
+
const base = {
|
|
96
|
+
title: 'JWT Setup',
|
|
97
|
+
content: 'Set up JWT authentication using RS256 algorithm for token signing in the auth service',
|
|
98
|
+
};
|
|
99
|
+
const others = [
|
|
100
|
+
{
|
|
101
|
+
title: 'JWT Token Expiry',
|
|
102
|
+
content: 'JWT tokens expire after 24 hours, refresh tokens last 30 days for the auth system',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
title: 'JWT Middleware',
|
|
106
|
+
content: 'Created JWT middleware that validates tokens on every API request and attaches user context',
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
const bulletPoints = others
|
|
110
|
+
.map(m => `- ${m.title}: ${m.content}`)
|
|
111
|
+
.join('\n');
|
|
112
|
+
const mergedContent = `${base.content}\n\nConsolidated context:\n${bulletPoints}`;
|
|
113
|
+
expect(mergedContent).toContain('RS256');
|
|
114
|
+
expect(mergedContent).toContain('24 hours');
|
|
115
|
+
expect(mergedContent).toContain('middleware');
|
|
116
|
+
expect(mergedContent).toContain('Consolidated context:');
|
|
117
|
+
});
|
|
118
|
+
it('should merge tags as a union', () => {
|
|
119
|
+
const tagSets = [
|
|
120
|
+
['jwt', 'auth'],
|
|
121
|
+
['jwt', 'expiry'],
|
|
122
|
+
['jwt', 'middleware'],
|
|
123
|
+
];
|
|
124
|
+
const allTags = new Set();
|
|
125
|
+
for (const tags of tagSets) {
|
|
126
|
+
for (const t of tags)
|
|
127
|
+
allTags.add(t);
|
|
128
|
+
}
|
|
129
|
+
expect([...allTags].sort()).toEqual(['auth', 'expiry', 'jwt', 'middleware']);
|
|
130
|
+
});
|
|
131
|
+
it('should cap salience at 1.0 after boost', () => {
|
|
132
|
+
const baseSalience = 0.95;
|
|
133
|
+
const newSalience = Math.min(1.0, baseSalience + 0.1);
|
|
134
|
+
expect(newSalience).toBe(1.0);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
//# sourceMappingURL=consolidation-merge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidation-merge.test.js","sourceRoot":"","sources":["../../src/__tests__/consolidation-merge.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contradictions.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/contradictions.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contradiction Surfacing Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests that contradictions are properly included in search results
|
|
5
|
+
* and displayed in recall output.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from '@jest/globals';
|
|
8
|
+
import { formatRecallResult } from '../tools/recall.js';
|
|
9
|
+
function makeMemory(overrides = {}) {
|
|
10
|
+
return {
|
|
11
|
+
id: 1,
|
|
12
|
+
type: 'long_term',
|
|
13
|
+
category: 'architecture',
|
|
14
|
+
title: 'Use PostgreSQL',
|
|
15
|
+
content: 'Decided to use PostgreSQL for the database',
|
|
16
|
+
project: 'test',
|
|
17
|
+
tags: [],
|
|
18
|
+
salience: 0.8,
|
|
19
|
+
accessCount: 1,
|
|
20
|
+
lastAccessed: new Date(),
|
|
21
|
+
createdAt: new Date(),
|
|
22
|
+
decayedScore: 0.7,
|
|
23
|
+
metadata: {},
|
|
24
|
+
scope: 'project',
|
|
25
|
+
transferable: false,
|
|
26
|
+
...overrides,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
describe('SearchResult contradictions field', () => {
|
|
30
|
+
it('should allow contradictions on SearchResult', () => {
|
|
31
|
+
const result = {
|
|
32
|
+
memory: makeMemory(),
|
|
33
|
+
relevanceScore: 0.9,
|
|
34
|
+
contradictions: [
|
|
35
|
+
{ memoryId: 2, title: 'Use SQLite', score: 0.8 },
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
expect(result.contradictions).toBeDefined();
|
|
39
|
+
expect(result.contradictions).toHaveLength(1);
|
|
40
|
+
expect(result.contradictions[0].memoryId).toBe(2);
|
|
41
|
+
expect(result.contradictions[0].title).toBe('Use SQLite');
|
|
42
|
+
expect(result.contradictions[0].score).toBe(0.8);
|
|
43
|
+
});
|
|
44
|
+
it('should allow SearchResult without contradictions', () => {
|
|
45
|
+
const result = {
|
|
46
|
+
memory: makeMemory(),
|
|
47
|
+
relevanceScore: 0.9,
|
|
48
|
+
};
|
|
49
|
+
expect(result.contradictions).toBeUndefined();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
describe('formatRecallResult with contradictions', () => {
|
|
53
|
+
it('should show contradiction warnings in formatted output', () => {
|
|
54
|
+
const mem1 = makeMemory({ id: 1, title: 'Use PostgreSQL' });
|
|
55
|
+
const mem2 = makeMemory({ id: 2, title: 'Use SQLite' });
|
|
56
|
+
const contradictions = new Map();
|
|
57
|
+
contradictions.set(1, [{ memoryId: 2, title: 'Use SQLite', score: 0.8 }]);
|
|
58
|
+
const output = formatRecallResult({
|
|
59
|
+
success: true,
|
|
60
|
+
memories: [mem1, mem2],
|
|
61
|
+
contradictions,
|
|
62
|
+
count: 2,
|
|
63
|
+
});
|
|
64
|
+
expect(output).toContain('CONTRADICTS');
|
|
65
|
+
expect(output).toContain('"Use SQLite"');
|
|
66
|
+
expect(output).toContain('ID 2');
|
|
67
|
+
});
|
|
68
|
+
it('should not show contradiction warning for memories without contradictions', () => {
|
|
69
|
+
const mem = makeMemory({ id: 3, title: 'Some memory' });
|
|
70
|
+
const output = formatRecallResult({
|
|
71
|
+
success: true,
|
|
72
|
+
memories: [mem],
|
|
73
|
+
count: 1,
|
|
74
|
+
});
|
|
75
|
+
expect(output).not.toContain('CONTRADICTS');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=contradictions.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contradictions.test.js","sourceRoot":"","sources":["../../src/__tests__/contradictions.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,SAAS,UAAU,CAAC,YAA6B,EAAE;IACjD,OAAO;QACL,EAAE,EAAE,CAAC;QACL,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,gBAAgB;QACvB,OAAO,EAAE,4CAA4C;QACrD,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,EAAE;QACR,QAAQ,EAAE,GAAG;QACb,WAAW,EAAE,CAAC;QACd,YAAY,EAAE,IAAI,IAAI,EAAE;QACxB,SAAS,EAAE,IAAI,IAAI,EAAE;QACrB,YAAY,EAAE,GAAG;QACjB,QAAQ,EAAE,EAAE;QACZ,KAAK,EAAE,SAAS;QAChB,YAAY,EAAE,KAAK;QACnB,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,MAAM,GAAiB;YAC3B,MAAM,EAAE,UAAU,EAAE;YACpB,cAAc,EAAE,GAAG;YACnB,cAAc,EAAE;gBACd,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE;aACjD;SACF,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,cAAe,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,cAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,cAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAiB;YAC3B,MAAM,EAAE,UAAU,EAAE;YACpB,cAAc,EAAE,GAAG;SACpB,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,aAAa,EAAE,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,wCAAwC,EAAE,GAAG,EAAE;IACtD,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;QAExD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAgE,CAAC;QAC/F,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAE1E,MAAM,MAAM,GAAG,kBAAkB,CAAC;YAChC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC;YACtB,cAAc;YACd,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,GAAG,EAAE;QACnF,MAAM,GAAG,GAAG,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;QAExD,MAAM,MAAM,GAAG,kBAAkB,CAAC;YAChC,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,CAAC,GAAG,CAAC;YACf,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"salience-evolution.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/salience-evolution.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|