claude-memory-layer 1.0.26 → 1.0.28
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/.env.example +7 -0
- package/AGENTS.md +11 -0
- package/README.md +184 -41
- package/benchmarks/replay/anonymized-real-sessions.json +48 -0
- package/dist/cli/index.js +10097 -6003
- package/dist/cli/index.js.map +4 -4
- package/dist/core/index.js +9745 -5587
- package/dist/core/index.js.map +4 -4
- package/dist/hooks/post-tool-use.js +6545 -5270
- package/dist/hooks/post-tool-use.js.map +4 -4
- package/dist/hooks/semantic-daemon.js +6646 -5354
- package/dist/hooks/semantic-daemon.js.map +4 -4
- package/dist/hooks/session-end.js +6618 -5347
- package/dist/hooks/session-end.js.map +4 -4
- package/dist/hooks/session-start.js +6619 -5354
- package/dist/hooks/session-start.js.map +4 -4
- package/dist/hooks/stop.js +6614 -5325
- package/dist/hooks/stop.js.map +4 -4
- package/dist/hooks/user-prompt-submit.js +6702 -5356
- package/dist/hooks/user-prompt-submit.js.map +4 -4
- package/dist/index.js +13537 -0
- package/dist/index.js.map +7 -0
- package/dist/mcp/index.js +20770 -0
- package/dist/mcp/index.js.map +7 -0
- package/dist/server/api/index.js +6632 -5319
- package/dist/server/api/index.js.map +4 -4
- package/dist/server/index.js +6667 -5340
- package/dist/server/index.js.map +4 -4
- package/dist/services/memory-service.js +6568 -5350
- package/dist/services/memory-service.js.map +4 -4
- package/dist/ui/assets/js/bootstrap.js +244 -0
- package/dist/ui/assets/js/chat.js +373 -0
- package/dist/ui/assets/js/disclosure.js +232 -0
- package/dist/ui/assets/js/modals.js +298 -0
- package/dist/ui/assets/js/overview.js +655 -0
- package/dist/ui/assets/js/state.js +72 -0
- package/dist/ui/assets/js/views.js +468 -0
- package/dist/ui/index.html +43 -1
- package/dist/ui/index.ts +3 -0
- package/dist/ui/style.css +222 -0
- package/docs/ARCHITECTURE_COMPARISON_AND_RECOMMENDATIONS.md +627 -0
- package/docs/HERMES_MEMORY_INGESTION_ANALYSIS.md +440 -0
- package/docs/MEMORY_USEFULNESS_AUDIT.md +371 -0
- package/docs/MEMORY_USEFULNESS_AUDIT_RAW.json +80 -0
- package/docs/MEMSEARCH_PROJECT_STRUCTURE_ANALYSIS.md +333 -0
- package/docs/PRODUCT_VALIDATION_MATRIX.md +82 -0
- package/docs/PROJECT_STRUCTURE_ANALYSIS.md +421 -0
- package/docs/REFACTORING_MILESTONES_AND_ISSUES.md +501 -0
- package/docs/REFACTORING_PLAN_THIN_CORE.md +414 -0
- package/docs/REFERENCE_PROJECT_ANALYSES.md +25 -0
- package/docs/SUPERLOCALMEMORY_PROJECT_STRUCTURE_ANALYSIS.md +452 -0
- package/docs/TARGET_ARCHITECTURE_AND_FOLDER_STRUCTURE.md +446 -0
- package/docs/architecture/comparison-index.md +47 -0
- package/docs/reports/codex-real-data-validation-20260505T040447Z.md +46 -0
- package/package.json +9 -5
- package/scripts/build.ts +25 -8
- package/scripts/generate-session-qrels.ts +126 -0
- package/scripts/replay-retrieval-benchmark.ts +69 -0
- package/specs/thin-core-refactor/context.md +275 -0
- package/specs/thin-core-refactor/plan.md +536 -0
- package/specs/thin-core-refactor/spec.md +465 -0
- package/src/adapters/claude/capture/index.ts +3 -0
- package/src/adapters/claude/context/index.ts +3 -0
- package/src/adapters/claude/hooks/index.ts +21 -0
- package/src/adapters/claude/hooks/post-tool-use.ts +239 -0
- package/src/adapters/claude/hooks/prompt-injection-policy.ts +104 -0
- package/src/adapters/claude/hooks/semantic-daemon-client.ts +209 -0
- package/src/adapters/claude/hooks/semantic-daemon.ts +283 -0
- package/src/adapters/claude/hooks/session-end.ts +59 -0
- package/src/adapters/claude/hooks/session-start.ts +73 -0
- package/src/adapters/claude/hooks/stop.ts +128 -0
- package/src/adapters/claude/hooks/user-prompt-submit.ts +361 -0
- package/src/adapters/claude/index.ts +4 -0
- package/src/adapters/claude/transcript/index.ts +4 -0
- package/src/adapters/claude/transcript/transcript-reader.ts +57 -0
- package/src/adapters/claude/transcript/turn-reconstructor.ts +65 -0
- package/src/apps/cli/claude-settings-hooks.ts +138 -0
- package/src/apps/cli/codex-import-runner.ts +125 -0
- package/src/apps/cli/codex-validation-output.ts +95 -0
- package/src/apps/cli/hermes-import-runner.ts +130 -0
- package/src/apps/cli/hermes-validation-output.ts +91 -0
- package/src/apps/cli/index.ts +1731 -0
- package/src/apps/cli/mcp-install.ts +106 -0
- package/src/apps/cli/retrieval-disclosure-output.ts +196 -0
- package/src/apps/dashboard/assets/js/bootstrap.js +244 -0
- package/src/apps/dashboard/assets/js/chat.js +373 -0
- package/src/apps/dashboard/assets/js/disclosure.js +232 -0
- package/src/apps/dashboard/assets/js/modals.js +298 -0
- package/src/apps/dashboard/assets/js/overview.js +655 -0
- package/src/apps/dashboard/assets/js/state.js +72 -0
- package/src/apps/dashboard/assets/js/views.js +468 -0
- package/src/{ui → apps/dashboard}/index.html +43 -1
- package/src/apps/dashboard/index.ts +3 -0
- package/src/{ui → apps/dashboard}/style.css +222 -0
- package/src/apps/index.ts +5 -0
- package/src/apps/server/api/chat.ts +244 -0
- package/src/apps/server/api/citations.ts +105 -0
- package/src/apps/server/api/events.ts +137 -0
- package/src/apps/server/api/health.ts +53 -0
- package/src/apps/server/api/index.ts +26 -0
- package/src/apps/server/api/projects.ts +74 -0
- package/src/apps/server/api/search.ts +184 -0
- package/src/apps/server/api/sessions.ts +115 -0
- package/src/apps/server/api/stats.ts +723 -0
- package/src/apps/server/api/turns.ts +143 -0
- package/src/apps/server/api/utils.ts +65 -0
- package/src/apps/server/index.ts +111 -0
- package/src/cli/index.ts +2 -1311
- package/src/cli/retrieval-disclosure-output.ts +2 -0
- package/src/compat/index.ts +5 -0
- package/src/core/derive/fact-deriver.ts +170 -0
- package/src/core/derive/index.ts +2 -0
- package/src/core/derive/summary-deriver.ts +76 -0
- package/src/core/embedder.ts +4 -152
- package/src/core/engine/embedding-maintenance-service.ts +187 -0
- package/src/core/engine/endless-memory-services.ts +4 -0
- package/src/core/engine/index.ts +19 -0
- package/src/core/engine/memory-engine-services.ts +170 -0
- package/src/core/engine/memory-ingest-service.ts +317 -0
- package/src/core/engine/memory-query-service.ts +173 -0
- package/src/core/engine/memory-runtime-service.ts +162 -0
- package/src/core/engine/memory-service-composition.ts +231 -0
- package/src/core/engine/retrieval-analytics-service.ts +181 -0
- package/src/core/engine/retrieval-disclosure-service.ts +420 -0
- package/src/core/engine/retrieval-orchestrator.ts +377 -0
- package/src/core/engine/retrieval-services.ts +176 -0
- package/src/core/engine/shared-memory-services.ts +4 -0
- package/src/core/entity-repo.ts +1 -3
- package/src/core/event-store.ts +3 -3
- package/src/core/evidence-aligner.ts +2 -2
- package/src/core/external-market-context.ts +582 -0
- package/src/core/graduation.ts +2 -3
- package/src/core/index.ts +21 -0
- package/src/core/matcher.ts +2 -4
- package/src/core/model/memory-fact.ts +30 -0
- package/src/core/model/memory-rule.ts +14 -0
- package/src/core/model/memory-summary.ts +21 -0
- package/src/core/model/raw-event.ts +28 -0
- package/src/core/model/retrieval-result.ts +35 -0
- package/src/core/privacy/filter.ts +21 -10
- package/src/core/product-validation-matrix.ts +314 -0
- package/src/core/progressive-retriever.ts +1 -2
- package/src/core/registry/project-path.ts +54 -0
- package/src/core/registry/session-registry.ts +69 -0
- package/src/core/replay-evaluator.ts +625 -0
- package/src/core/retrieval-benchmark.ts +117 -0
- package/src/core/retrieval-quality.ts +109 -0
- package/src/core/retriever.ts +53 -15
- package/src/core/session-qrels.ts +360 -0
- package/src/core/shared-event-store.ts +1 -1
- package/src/core/sqlite-event-store.ts +35 -11
- package/src/core/task/blocker-resolver.ts +2 -2
- package/src/core/task/task-resolver.ts +0 -1
- package/src/core/vector-outbox.ts +1 -10
- package/src/core/vector-worker.ts +1 -1
- package/src/extensions/endless-memory/endless-memory-services.ts +350 -0
- package/src/extensions/endless-memory/index.ts +1 -0
- package/src/extensions/index.ts +5 -0
- package/src/extensions/mcp/handlers.ts +960 -0
- package/src/extensions/mcp/index.ts +48 -0
- package/src/extensions/mcp/tools.ts +252 -0
- package/src/extensions/shared-memory/index.ts +1 -0
- package/src/extensions/shared-memory/shared-memory-services.ts +211 -0
- package/src/extensions/vector/embedder.ts +197 -0
- package/src/extensions/vector/index.ts +1 -0
- package/src/hooks/post-tool-use.ts +3 -236
- package/src/hooks/semantic-daemon-client.ts +1 -208
- package/src/hooks/semantic-daemon.ts +6 -271
- package/src/hooks/session-end.ts +4 -79
- package/src/hooks/session-start.ts +4 -73
- package/src/hooks/stop.ts +3 -173
- package/src/hooks/user-prompt-submit.ts +3 -338
- package/src/index.ts +13 -0
- package/src/mcp/handlers.ts +2 -212
- package/src/mcp/index.ts +3 -46
- package/src/mcp/tools.ts +2 -78
- package/src/server/api/chat.ts +2 -244
- package/src/server/api/citations.ts +2 -105
- package/src/server/api/events.ts +2 -137
- package/src/server/api/health.ts +2 -53
- package/src/server/api/index.ts +2 -26
- package/src/server/api/projects.ts +2 -74
- package/src/server/api/search.ts +2 -102
- package/src/server/api/sessions.ts +2 -115
- package/src/server/api/stats.ts +2 -724
- package/src/server/api/turns.ts +2 -143
- package/src/server/api/utils.ts +2 -46
- package/src/server/index.ts +2 -100
- package/src/services/bootstrap-organizer.ts +46 -26
- package/src/services/codex-session-history-importer.ts +521 -29
- package/src/services/hermes-session-history-importer.ts +733 -0
- package/src/services/memory-service-config.ts +36 -0
- package/src/services/memory-service-registry.ts +150 -0
- package/src/services/memory-service.ts +211 -1325
- package/src/services/session-history-importer.ts +58 -14
- package/tests/README.md +23 -0
- package/tests/adapters/claude/claude-semantic-daemon-adapter.test.ts +54 -0
- package/tests/adapters/claude/claude-transcript-reconstructor.test.ts +98 -0
- package/tests/adapters/claude-hook-prompt-injection-policy.test.ts +99 -0
- package/tests/apps/app-layer-boundary.test.ts +48 -0
- package/tests/apps/claude-settings-hooks.test.ts +107 -0
- package/tests/apps/cli-disclosure-output.test.ts +212 -0
- package/tests/apps/codex-import-runner.test.ts +99 -0
- package/tests/apps/codex-validation-output.test.ts +100 -0
- package/tests/apps/hermes-import-runner.test.ts +99 -0
- package/tests/apps/mcp-install-command.test.ts +59 -0
- package/tests/apps/package-build-entrypoints.test.ts +30 -0
- package/tests/apps/search-api-disclosure.test.ts +162 -0
- package/tests/apps/stats-api-lightweight.test.ts +67 -0
- package/tests/apps/ui-disclosure-output.test.ts +140 -0
- package/tests/{bootstrap-organizer.test.ts → core/bootstrap-organizer.test.ts} +1 -1
- package/tests/{canonical-key.test.ts → core/canonical-key.test.ts} +1 -1
- package/tests/core/codex-session-history-importer-validation.test.ts +185 -0
- package/tests/{consolidation-worker.test.ts → core/consolidation-worker.test.ts} +2 -2
- package/tests/core/embedding-maintenance-service.test.ts +282 -0
- package/tests/{evidence-aligner.test.ts → core/evidence-aligner.test.ts} +1 -1
- package/tests/core/external-market-context.test.ts +209 -0
- package/tests/core/fact-deriver.test.ts +79 -0
- package/tests/core/hermes-session-history-importer-validation.test.ts +609 -0
- package/tests/{ingest-interceptor.test.ts → core/ingest-interceptor.test.ts} +1 -1
- package/tests/{markdown-mirror.test.ts → core/markdown-mirror.test.ts} +2 -2
- package/tests/{matcher.test.ts → core/matcher.test.ts} +1 -1
- package/tests/{md-mirror.test.ts → core/md-mirror.test.ts} +2 -2
- package/tests/core/memory-engine-services.test.ts +240 -0
- package/tests/core/memory-ingest-service.test.ts +296 -0
- package/tests/core/memory-query-service.test.ts +129 -0
- package/tests/core/memory-runtime-service.test.ts +201 -0
- package/tests/core/memory-service-composition.test.ts +192 -0
- package/tests/core/memory-service-config.test.ts +41 -0
- package/tests/core/memory-service-facade.test.ts +30 -0
- package/tests/core/memory-service-registry.test.ts +206 -0
- package/tests/core/product-validation-matrix.test.ts +61 -0
- package/tests/core/project-registry.test.ts +78 -0
- package/tests/core/replay-evaluator.test.ts +181 -0
- package/tests/core/retrieval-analytics-service.test.ts +210 -0
- package/tests/core/retrieval-benchmark.test.ts +93 -0
- package/tests/core/retrieval-disclosure-service.test.ts +264 -0
- package/tests/core/retrieval-orchestrator.test.ts +403 -0
- package/tests/core/retrieval-quality.test.ts +31 -0
- package/tests/core/retrieval-services.test.ts +185 -0
- package/tests/{retriever-fallback-chain.test.ts → core/retriever-fallback-chain.test.ts} +3 -3
- package/tests/{retriever-strategy-scope.test.ts → core/retriever-strategy-scope.test.ts} +70 -3
- package/tests/{retriever.memu-adoption.test.ts → core/retriever.memu-adoption.test.ts} +3 -3
- package/tests/core/session-history-importer-filter.test.ts +78 -0
- package/tests/core/session-qrels.test.ts +250 -0
- package/tests/{sqlite-event-store-replication.test.ts → core/sqlite-event-store-replication.test.ts} +36 -1
- package/tests/core/summary-deriver.test.ts +66 -0
- package/tests/extensions/embedder-warning-suppression.test.ts +53 -0
- package/tests/extensions/endless-memory-extension-boundary.test.ts +17 -0
- package/tests/extensions/endless-memory-services.test.ts +325 -0
- package/tests/extensions/mcp-context-tools.test.ts +905 -0
- package/tests/extensions/mcp-extension-boundary.test.ts +21 -0
- package/tests/extensions/mcp-package-build.test.ts +22 -0
- package/tests/extensions/mcp-project-aware-tools.test.ts +102 -0
- package/tests/extensions/shared-memory-extension-boundary.test.ts +24 -0
- package/tests/extensions/shared-memory-services.test.ts +309 -0
- package/tests/extensions/vector-extension-boundary.test.ts +21 -0
- package/.claude/settings.local.json +0 -25
- package/.npm-cache/_cacache/content-v2/sha512/04/76/c098f88dfe584a2b80870bff7421b05d17d3d9ee1027f77772332a22d3f93a9a57101a2855107f6ad82077a818bba912b2bc317f2361b5ddb09ad284d9ce +0 -0
- package/.npm-cache/_cacache/content-v2/sha512/60/25/d2ecd39cfc7cab58351162814be77f935c6d6491c10c3745d456da7ddb2117ffd90c10e53fe3c0f1ed16b403307841543634504398b16ee4e6b6dd8e0c45 +0 -0
- package/.npm-cache/_cacache/index-v5/2b/9a/7f8f40206ed8a2e0a84efaa953ccaed1f5d001e14b931083f2e7a0738007 +0 -2
- package/.npm-cache/_cacache/index-v5/2e/d9/fcfa5c6a6abdc2a3644ab84a95936047298c465a2f47ee03db8f7fe1e946 +0 -3
- package/.npm-cache/_cacache/index-v5/a9/42/e519633356d12d3d2f19da66a8301016d496c8f5c3e0554124aaa62dc043 +0 -2
- package/.npm-cache/_logs/2026-02-26T12_04_52_729Z-debug-0.log +0 -256
- package/.npm-cache/_logs/2026-02-26T12_05_36_835Z-debug-0.log +0 -18
- package/.npm-cache/_logs/2026-02-26T12_05_45_982Z-debug-0.log +0 -32
- package/.npm-cache/_logs/2026-02-26T12_05_48_515Z-debug-0.log +0 -260
- package/.npm-cache/_logs/2026-02-26T12_05_53_567Z-debug-0.log +0 -69
- package/.npm-cache/_update-notifier-last-checked +0 -0
- package/bootstrap-kb/decisions/decisions.md +0 -244
- package/bootstrap-kb/glossary/glossary.md +0 -46
- package/bootstrap-kb/modules/.claude-plugin.md +0 -22
- package/bootstrap-kb/modules/agents.md.md +0 -15
- package/bootstrap-kb/modules/claude.md.md +0 -15
- package/bootstrap-kb/modules/context.md.md +0 -15
- package/bootstrap-kb/modules/docs.md +0 -18
- package/bootstrap-kb/modules/handoff.md.md +0 -15
- package/bootstrap-kb/modules/package-lock.json.md +0 -15
- package/bootstrap-kb/modules/package.json.md +0 -15
- package/bootstrap-kb/modules/plan.md.md +0 -15
- package/bootstrap-kb/modules/readme.md.md +0 -15
- package/bootstrap-kb/modules/scripts.md +0 -26
- package/bootstrap-kb/modules/spec.md.md +0 -15
- package/bootstrap-kb/modules/specs.md +0 -20
- package/bootstrap-kb/modules/src.md +0 -51
- package/bootstrap-kb/modules/tests.md +0 -42
- package/bootstrap-kb/modules/tsconfig.json.md +0 -15
- package/bootstrap-kb/modules/vitest.config.ts.md +0 -15
- package/bootstrap-kb/overview/overview.md +0 -40
- package/bootstrap-kb/sources/manifest.json +0 -950
- package/bootstrap-kb/sources/manifest.md +0 -227
- package/bootstrap-kb/timeline/timeline.md +0 -57
- package/claude-memory-layer-1.0.14.tgz +0 -0
- package/d.sh +0 -3
- package/deploy.sh +0 -3
- package/dist/ui/app.js +0 -2101
- package/memory/.claude-plugin/commands/2026-02-25.md +0 -263
- package/memory/_index.md +0 -418
- package/memory/agent_response/uncategorized/2026-02-26.md +0 -176
- package/memory/agent_response/uncategorized/2026-03-03.md +0 -14
- package/memory/agent_response/uncategorized/2026-03-04.md +0 -1421
- package/memory/agent_response/uncategorized/2026-03-05.md +0 -48
- package/memory/default/uncategorized/2026-02-25.md +0 -4839
- package/memory/session_summary/uncategorized/2026-02-26.md +0 -13
- package/memory/session_summary/uncategorized/2026-03-03.md +0 -5
- package/memory/session_summary/uncategorized/2026-03-04.md +0 -50
- package/memory/specs/20260207-dashboard-upgrade/2026-02-25.md +0 -142
- package/memory/specs/citations-system/2026-02-25.md +0 -1121
- package/memory/specs/endless-mode/2026-02-25.md +0 -1392
- package/memory/specs/entity-edge-model/2026-02-25.md +0 -1263
- package/memory/specs/evidence-aligner-v2/2026-02-25.md +0 -1028
- package/memory/specs/mcp-desktop-integration/2026-02-25.md +0 -1334
- package/memory/specs/post-tool-use-hook/2026-02-25.md +0 -1164
- package/memory/specs/private-tags/2026-02-25.md +0 -1057
- package/memory/specs/progressive-disclosure/2026-02-25.md +0 -1436
- package/memory/specs/task-entity-system/2026-02-25.md +0 -924
- package/memory/specs/vector-outbox-v2/2026-02-25.md +0 -1510
- package/memory/specs/web-viewer-ui/2026-02-25.md +0 -1709
- package/memory/tool_observation/uncategorized/2026-02-26.md +0 -209
- package/memory/tool_observation/uncategorized/2026-03-03.md +0 -21
- package/memory/tool_observation/uncategorized/2026-03-04.md +0 -1033
- package/memory/tool_observation/uncategorized/2026-03-05.md +0 -29
- package/memory/user_prompt/uncategorized/2026-02-26.md +0 -25
- package/memory/user_prompt/uncategorized/2026-03-04.md +0 -634
- package/specs/optional-duckdb/context.md +0 -77
- package/specs/optional-duckdb/plan.md +0 -142
- package/specs/optional-duckdb/spec.md +0 -35
- package/src/ui/app.js +0 -2101
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Runtime Service
|
|
3
|
+
* Owns MemoryService lifecycle concerns: initialization, background workers,
|
|
4
|
+
* lightweight/read-only modes, and orderly shutdown.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { EventStore } from '../event-store.js';
|
|
8
|
+
import type { Embedder } from '../embedder.js';
|
|
9
|
+
import type { GraduationPipeline } from '../graduation.js';
|
|
10
|
+
import {
|
|
11
|
+
createGraduationWorker as defaultCreateGraduationWorker,
|
|
12
|
+
type GraduationRunResult,
|
|
13
|
+
type GraduationWorker
|
|
14
|
+
} from '../graduation-worker.js';
|
|
15
|
+
import type { Retriever } from '../retriever.js';
|
|
16
|
+
import type { VectorStore } from '../vector-store.js';
|
|
17
|
+
import {
|
|
18
|
+
createVectorWorker as defaultCreateVectorWorker,
|
|
19
|
+
type VectorWorker
|
|
20
|
+
} from '../vector-worker.js';
|
|
21
|
+
|
|
22
|
+
export interface RuntimeSQLiteStore {
|
|
23
|
+
initialize(): Promise<void>;
|
|
24
|
+
close(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface RuntimeEndlessMemoryServices {
|
|
28
|
+
initializeFromSavedMode(): Promise<void>;
|
|
29
|
+
shutdown(): void;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface RuntimeSharedMemoryServices {
|
|
33
|
+
initialize(): Promise<void>;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface MemoryRuntimeServicesFactories {
|
|
38
|
+
createVectorWorker?: typeof defaultCreateVectorWorker;
|
|
39
|
+
createGraduationWorker?: typeof defaultCreateGraduationWorker;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface MemoryRuntimeServicesDeps {
|
|
43
|
+
sqliteStore: RuntimeSQLiteStore;
|
|
44
|
+
eventStore: EventStore;
|
|
45
|
+
vectorStore: VectorStore;
|
|
46
|
+
embedder: Embedder;
|
|
47
|
+
retriever: Retriever;
|
|
48
|
+
graduation: GraduationPipeline;
|
|
49
|
+
endlessMemoryServices: RuntimeEndlessMemoryServices;
|
|
50
|
+
sharedMemoryServices: RuntimeSharedMemoryServices;
|
|
51
|
+
readOnly: boolean;
|
|
52
|
+
lightweightMode: boolean;
|
|
53
|
+
embeddingOnly: boolean;
|
|
54
|
+
factories?: MemoryRuntimeServicesFactories;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface MemoryRuntimeService {
|
|
58
|
+
initialize(): Promise<void>;
|
|
59
|
+
shutdown(): Promise<void>;
|
|
60
|
+
processPendingEmbeddings(): Promise<number>;
|
|
61
|
+
forceGraduation(): Promise<GraduationRunResult>;
|
|
62
|
+
recordMemoryAccess(eventId: string, sessionId: string, confidence?: number): void;
|
|
63
|
+
getVectorWorker(): VectorWorker | null;
|
|
64
|
+
isInitialized(): boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function createEmptyGraduationResult(): GraduationRunResult {
|
|
68
|
+
return { evaluated: 0, graduated: 0, byLevel: {} };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function createMemoryRuntimeService(deps: MemoryRuntimeServicesDeps): MemoryRuntimeService {
|
|
72
|
+
const createVectorWorker = deps.factories?.createVectorWorker ?? defaultCreateVectorWorker;
|
|
73
|
+
const createGraduationWorker = deps.factories?.createGraduationWorker ?? defaultCreateGraduationWorker;
|
|
74
|
+
|
|
75
|
+
let initialized = false;
|
|
76
|
+
let vectorWorker: VectorWorker | null = null;
|
|
77
|
+
let graduationWorker: GraduationWorker | null = null;
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
async initialize(): Promise<void> {
|
|
81
|
+
if (initialized) return;
|
|
82
|
+
|
|
83
|
+
// Initialize PRIMARY store: SQLite (always)
|
|
84
|
+
await deps.sqliteStore.initialize();
|
|
85
|
+
|
|
86
|
+
// Lightweight mode: only SQLite, no embedder/vector/workers.
|
|
87
|
+
// Used for hooks that just need to store data quickly.
|
|
88
|
+
if (deps.lightweightMode) {
|
|
89
|
+
initialized = true;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
await deps.vectorStore.initialize();
|
|
94
|
+
await deps.embedder.initialize();
|
|
95
|
+
|
|
96
|
+
// Skip write-related workers in read-only mode.
|
|
97
|
+
if (!deps.readOnly) {
|
|
98
|
+
vectorWorker = createVectorWorker(
|
|
99
|
+
deps.eventStore,
|
|
100
|
+
deps.vectorStore,
|
|
101
|
+
deps.embedder
|
|
102
|
+
);
|
|
103
|
+
vectorWorker.start();
|
|
104
|
+
|
|
105
|
+
if (!deps.embeddingOnly) {
|
|
106
|
+
deps.retriever.setGraduationPipeline(deps.graduation);
|
|
107
|
+
graduationWorker = createGraduationWorker(
|
|
108
|
+
deps.eventStore,
|
|
109
|
+
deps.graduation
|
|
110
|
+
);
|
|
111
|
+
graduationWorker.start();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
await deps.endlessMemoryServices.initializeFromSavedMode();
|
|
115
|
+
await deps.sharedMemoryServices.initialize();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
initialized = true;
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
async shutdown(): Promise<void> {
|
|
122
|
+
if (graduationWorker) {
|
|
123
|
+
graduationWorker.stop();
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
deps.endlessMemoryServices.shutdown();
|
|
127
|
+
|
|
128
|
+
if (vectorWorker) {
|
|
129
|
+
vectorWorker.stop();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
await deps.sharedMemoryServices.close();
|
|
133
|
+
await deps.sqliteStore.close();
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
async processPendingEmbeddings(): Promise<number> {
|
|
137
|
+
if (vectorWorker) {
|
|
138
|
+
return vectorWorker.processAll();
|
|
139
|
+
}
|
|
140
|
+
return 0;
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
async forceGraduation(): Promise<GraduationRunResult> {
|
|
144
|
+
if (!graduationWorker) {
|
|
145
|
+
return createEmptyGraduationResult();
|
|
146
|
+
}
|
|
147
|
+
return graduationWorker.forceRun();
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
recordMemoryAccess(eventId: string, sessionId: string, confidence: number = 1.0): void {
|
|
151
|
+
deps.graduation.recordAccess(eventId, sessionId, confidence);
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
getVectorWorker(): VectorWorker | null {
|
|
155
|
+
return vectorWorker;
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
isInitialized(): boolean {
|
|
159
|
+
return initialized;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Service Composition
|
|
3
|
+
*
|
|
4
|
+
* Owns constructor-time service graph wiring for MemoryService so the public
|
|
5
|
+
* facade can stay focused on state assignment and method delegation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as os from 'os';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
|
|
11
|
+
import type { EventStore } from '../event-store.js';
|
|
12
|
+
import type { Embedder } from '../embedder.js';
|
|
13
|
+
import type { GraduationPipeline } from '../graduation.js';
|
|
14
|
+
import { createToolObservationEmbedding as defaultCreateToolObservationEmbedding } from '../metadata-extractor.js';
|
|
15
|
+
import type { Retriever } from '../retriever.js';
|
|
16
|
+
import type { SQLiteEventStore } from '../sqlite-event-store.js';
|
|
17
|
+
import type { ToolObservationPayload, SharedStoreConfig } from '../types.js';
|
|
18
|
+
import type { VectorStore } from '../vector-store.js';
|
|
19
|
+
import {
|
|
20
|
+
createEmbeddingMaintenanceService as defaultCreateEmbeddingMaintenanceService,
|
|
21
|
+
type EmbeddingMaintenanceService,
|
|
22
|
+
type EmbeddingMaintenanceServiceOptions
|
|
23
|
+
} from './embedding-maintenance-service.js';
|
|
24
|
+
import {
|
|
25
|
+
createEndlessMemoryServices as defaultCreateEndlessMemoryServices,
|
|
26
|
+
type EndlessMemoryServices,
|
|
27
|
+
type EndlessMemoryServicesOptions
|
|
28
|
+
} from './endless-memory-services.js';
|
|
29
|
+
import {
|
|
30
|
+
createMemoryEngineServices as defaultCreateMemoryEngineServices,
|
|
31
|
+
type MemoryEngineServices,
|
|
32
|
+
type MemoryEngineServicesOptions
|
|
33
|
+
} from './memory-engine-services.js';
|
|
34
|
+
import {
|
|
35
|
+
createMemoryRuntimeService as defaultCreateMemoryRuntimeService,
|
|
36
|
+
type MemoryRuntimeService,
|
|
37
|
+
type MemoryRuntimeServicesDeps
|
|
38
|
+
} from './memory-runtime-service.js';
|
|
39
|
+
import type {
|
|
40
|
+
MemoryIngestService
|
|
41
|
+
} from './memory-ingest-service.js';
|
|
42
|
+
import type {
|
|
43
|
+
MemoryQueryService
|
|
44
|
+
} from './memory-query-service.js';
|
|
45
|
+
import {
|
|
46
|
+
createSharedMemoryServices as defaultCreateSharedMemoryServices,
|
|
47
|
+
type SharedMemoryServices,
|
|
48
|
+
type SharedMemoryServicesOptions
|
|
49
|
+
} from './shared-memory-services.js';
|
|
50
|
+
import type {
|
|
51
|
+
RetrievalAnalyticsService,
|
|
52
|
+
RetrievalDisclosureService,
|
|
53
|
+
RetrievalOrchestrator
|
|
54
|
+
} from './retrieval-services.js';
|
|
55
|
+
|
|
56
|
+
export interface MemoryServiceCompositionConfig {
|
|
57
|
+
storagePath: string;
|
|
58
|
+
embeddingModel?: string;
|
|
59
|
+
readOnly?: boolean;
|
|
60
|
+
lightweightMode?: boolean;
|
|
61
|
+
embeddingOnly?: boolean;
|
|
62
|
+
projectHash?: string;
|
|
63
|
+
projectPath?: string;
|
|
64
|
+
sharedStoreConfig?: SharedStoreConfig;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface MemoryServiceCompositionFactories {
|
|
68
|
+
expandPath?: (targetPath: string) => string;
|
|
69
|
+
createToolObservationEmbedding?: (
|
|
70
|
+
toolName: string,
|
|
71
|
+
metadata: Record<string, unknown>,
|
|
72
|
+
success: boolean
|
|
73
|
+
) => string;
|
|
74
|
+
createMemoryEngineServices?: (options: MemoryEngineServicesOptions) => MemoryEngineServices;
|
|
75
|
+
createEndlessMemoryServices?: (options: EndlessMemoryServicesOptions) => EndlessMemoryServices;
|
|
76
|
+
createSharedMemoryServices?: (options: SharedMemoryServicesOptions) => SharedMemoryServices;
|
|
77
|
+
createMemoryRuntimeService?: (deps: MemoryRuntimeServicesDeps) => MemoryRuntimeService;
|
|
78
|
+
createEmbeddingMaintenanceService?: (
|
|
79
|
+
options: EmbeddingMaintenanceServiceOptions
|
|
80
|
+
) => EmbeddingMaintenanceService;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface MemoryServiceCompositionOptions {
|
|
84
|
+
config: MemoryServiceCompositionConfig;
|
|
85
|
+
defaultSharedStoragePath: string;
|
|
86
|
+
defaultSharedStoreConfig?: SharedStoreConfig;
|
|
87
|
+
initialize: () => Promise<void>;
|
|
88
|
+
getProjectHash: () => string | null;
|
|
89
|
+
getProjectPath?: () => string | null;
|
|
90
|
+
factories?: MemoryServiceCompositionFactories;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface MemoryServiceComposition {
|
|
94
|
+
storagePath: string;
|
|
95
|
+
readOnly: boolean;
|
|
96
|
+
lightweightMode: boolean;
|
|
97
|
+
embeddingOnly: boolean;
|
|
98
|
+
sqliteStore: SQLiteEventStore;
|
|
99
|
+
vectorStore: VectorStore;
|
|
100
|
+
embedder: Embedder;
|
|
101
|
+
retriever: Retriever;
|
|
102
|
+
retrievalOrchestrator: RetrievalOrchestrator;
|
|
103
|
+
retrievalDisclosureService: RetrievalDisclosureService;
|
|
104
|
+
retrievalAnalyticsService: RetrievalAnalyticsService;
|
|
105
|
+
embeddingMaintenanceService: EmbeddingMaintenanceService;
|
|
106
|
+
runtimeService: MemoryRuntimeService;
|
|
107
|
+
graduation: GraduationPipeline;
|
|
108
|
+
endlessMemoryServices: EndlessMemoryServices;
|
|
109
|
+
sharedMemoryServices: SharedMemoryServices;
|
|
110
|
+
ingestService: MemoryIngestService;
|
|
111
|
+
queryService: MemoryQueryService;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function createMemoryServiceComposition(
|
|
115
|
+
options: MemoryServiceCompositionOptions
|
|
116
|
+
): MemoryServiceComposition {
|
|
117
|
+
const factories = options.factories ?? {};
|
|
118
|
+
const expandPath = factories.expandPath ?? defaultExpandPath;
|
|
119
|
+
const createToolEmbedding = factories.createToolObservationEmbedding ?? defaultCreateToolObservationEmbedding;
|
|
120
|
+
|
|
121
|
+
const storagePath = expandPath(options.config.storagePath);
|
|
122
|
+
const projectPathForMirror = options.getProjectPath?.() ?? options.config.projectPath ?? process.cwd();
|
|
123
|
+
const readOnly = options.config.readOnly ?? false;
|
|
124
|
+
const lightweightMode = options.config.lightweightMode ?? false;
|
|
125
|
+
const embeddingOnly = options.config.embeddingOnly ?? false;
|
|
126
|
+
const sharedStoreConfig = options.config.sharedStoreConfig ?? options.defaultSharedStoreConfig ?? {
|
|
127
|
+
enabled: true,
|
|
128
|
+
autoPromote: true,
|
|
129
|
+
searchShared: true,
|
|
130
|
+
minConfidenceForPromotion: 0.8,
|
|
131
|
+
sharedStoragePath: options.defaultSharedStoragePath
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
let sharedMemoryServices: SharedMemoryServices | null = null;
|
|
135
|
+
|
|
136
|
+
const engineServices = (factories.createMemoryEngineServices ?? defaultCreateMemoryEngineServices)({
|
|
137
|
+
storagePath,
|
|
138
|
+
readOnly,
|
|
139
|
+
embeddingModel: options.config.embeddingModel,
|
|
140
|
+
cwd: projectPathForMirror,
|
|
141
|
+
initialize: options.initialize,
|
|
142
|
+
getProjectHash: options.getProjectHash,
|
|
143
|
+
getProjectPath: options.getProjectPath,
|
|
144
|
+
hasSharedStore: () => sharedMemoryServices?.isEnabled() ?? false,
|
|
145
|
+
sharedStore: {
|
|
146
|
+
get: (entryId: string) => sharedMemoryServices?.getEntryForDisclosure(entryId) ?? Promise.resolve(null)
|
|
147
|
+
},
|
|
148
|
+
createToolObservationEmbedding: (payload: ToolObservationPayload) => createToolEmbedding(
|
|
149
|
+
payload.toolName,
|
|
150
|
+
payload.metadata || {},
|
|
151
|
+
payload.success
|
|
152
|
+
)
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const endlessMemoryServices = (factories.createEndlessMemoryServices ?? defaultCreateEndlessMemoryServices)({
|
|
156
|
+
eventStore: engineServices.sqliteStore as unknown as EventStore,
|
|
157
|
+
configStore: engineServices.sqliteStore,
|
|
158
|
+
initialize: options.initialize
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
sharedMemoryServices = (factories.createSharedMemoryServices ?? defaultCreateSharedMemoryServices)({
|
|
162
|
+
config: sharedStoreConfig,
|
|
163
|
+
defaultSharedStoragePath: options.defaultSharedStoragePath,
|
|
164
|
+
readOnly,
|
|
165
|
+
expandPath,
|
|
166
|
+
embedder: engineServices.embedder,
|
|
167
|
+
retriever: engineServices.retriever
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const runtimeService = (factories.createMemoryRuntimeService ?? defaultCreateMemoryRuntimeService)({
|
|
171
|
+
sqliteStore: engineServices.sqliteStore,
|
|
172
|
+
eventStore: engineServices.sqliteStore as unknown as EventStore,
|
|
173
|
+
vectorStore: engineServices.vectorStore,
|
|
174
|
+
embedder: engineServices.embedder,
|
|
175
|
+
retriever: engineServices.retriever,
|
|
176
|
+
graduation: engineServices.graduation,
|
|
177
|
+
endlessMemoryServices,
|
|
178
|
+
sharedMemoryServices,
|
|
179
|
+
readOnly,
|
|
180
|
+
lightweightMode,
|
|
181
|
+
embeddingOnly
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
const embeddingMaintenanceService = (
|
|
185
|
+
factories.createEmbeddingMaintenanceService ?? defaultCreateEmbeddingMaintenanceService
|
|
186
|
+
)({
|
|
187
|
+
storagePath,
|
|
188
|
+
initialize: options.initialize,
|
|
189
|
+
getEmbeddingModelName: () => engineServices.embedder.getModelName(),
|
|
190
|
+
vectorStore: engineServices.vectorStore,
|
|
191
|
+
eventStore: {
|
|
192
|
+
clearEmbeddingOutbox: () => engineServices.sqliteStore.clearEmbeddingOutbox(),
|
|
193
|
+
getEventsPage: async (limit, offset) => {
|
|
194
|
+
const events = await engineServices.sqliteStore.getEventsPage(limit, offset);
|
|
195
|
+
return events.map((event) => ({ id: event.id, content: event.content }));
|
|
196
|
+
},
|
|
197
|
+
enqueueForEmbedding: async (eventId, content) => {
|
|
198
|
+
await engineServices.sqliteStore.enqueueForEmbedding(eventId, content);
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
getVectorWorker: () => runtimeService.getVectorWorker()
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
storagePath,
|
|
206
|
+
readOnly,
|
|
207
|
+
lightweightMode,
|
|
208
|
+
embeddingOnly,
|
|
209
|
+
sqliteStore: engineServices.sqliteStore,
|
|
210
|
+
vectorStore: engineServices.vectorStore,
|
|
211
|
+
embedder: engineServices.embedder,
|
|
212
|
+
retriever: engineServices.retriever,
|
|
213
|
+
retrievalOrchestrator: engineServices.retrievalOrchestrator,
|
|
214
|
+
retrievalDisclosureService: engineServices.retrievalDisclosureService,
|
|
215
|
+
retrievalAnalyticsService: engineServices.retrievalAnalyticsService,
|
|
216
|
+
embeddingMaintenanceService,
|
|
217
|
+
runtimeService,
|
|
218
|
+
graduation: engineServices.graduation,
|
|
219
|
+
endlessMemoryServices,
|
|
220
|
+
sharedMemoryServices,
|
|
221
|
+
ingestService: engineServices.ingestService,
|
|
222
|
+
queryService: engineServices.queryService
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function defaultExpandPath(targetPath: string): string {
|
|
227
|
+
if (targetPath.startsWith('~')) {
|
|
228
|
+
return path.join(os.homedir(), targetPath.slice(1));
|
|
229
|
+
}
|
|
230
|
+
return targetPath;
|
|
231
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieval Analytics Service
|
|
3
|
+
*
|
|
4
|
+
* Owns retrieval telemetry read-model and helpfulness evaluation workflows so
|
|
5
|
+
* MemoryService can remain a thin facade over focused engine services.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { MemoryEvent } from '../types.js';
|
|
9
|
+
|
|
10
|
+
export interface RetrievalTraceStats {
|
|
11
|
+
totalQueries: number;
|
|
12
|
+
avgCandidateCount: number;
|
|
13
|
+
avgSelectedCount: number;
|
|
14
|
+
selectionRate: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface HelpfulnessStats {
|
|
18
|
+
avgScore: number;
|
|
19
|
+
totalEvaluated: number;
|
|
20
|
+
totalRetrievals: number;
|
|
21
|
+
helpful: number;
|
|
22
|
+
neutral: number;
|
|
23
|
+
unhelpful: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface HelpfulMemory {
|
|
27
|
+
eventId: string;
|
|
28
|
+
summary: string;
|
|
29
|
+
helpfulnessScore: number;
|
|
30
|
+
accessCount: number;
|
|
31
|
+
evaluationCount: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface RetrievalTraceDetail {
|
|
35
|
+
eventId: string;
|
|
36
|
+
score: number;
|
|
37
|
+
semanticScore?: number;
|
|
38
|
+
lexicalScore?: number;
|
|
39
|
+
recencyScore?: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface RetrievalTrace {
|
|
43
|
+
traceId: string;
|
|
44
|
+
sessionId?: string;
|
|
45
|
+
projectHash?: string;
|
|
46
|
+
queryText: string;
|
|
47
|
+
strategy?: string;
|
|
48
|
+
candidateEventIds: string[];
|
|
49
|
+
selectedEventIds: string[];
|
|
50
|
+
candidateDetails: RetrievalTraceDetail[];
|
|
51
|
+
selectedDetails: RetrievalTraceDetail[];
|
|
52
|
+
candidateCount: number;
|
|
53
|
+
selectedCount: number;
|
|
54
|
+
confidence?: string;
|
|
55
|
+
fallbackTrace: string[];
|
|
56
|
+
createdAt: Date;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface AccessedMemory {
|
|
60
|
+
memoryId: string;
|
|
61
|
+
summary: string;
|
|
62
|
+
topics: string[];
|
|
63
|
+
accessCount: number;
|
|
64
|
+
lastAccessed: string | null;
|
|
65
|
+
confidence: number;
|
|
66
|
+
createdAt: Date;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type AccessedMemoryEvent = MemoryEvent & {
|
|
70
|
+
access_count?: number;
|
|
71
|
+
last_accessed_at?: string | null;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export interface RetrievalAnalyticsStore {
|
|
75
|
+
getRetrievalTraceStats(): Promise<RetrievalTraceStats>;
|
|
76
|
+
getRecentRetrievalTraces(limit?: number): Promise<RetrievalTrace[]>;
|
|
77
|
+
getMostAccessed(limit?: number): Promise<AccessedMemoryEvent[]>;
|
|
78
|
+
evaluateSessionHelpfulness(sessionId: string): Promise<void>;
|
|
79
|
+
getUnevaluatedSessions(currentSessionId: string, limit?: number): Promise<string[]>;
|
|
80
|
+
getHelpfulMemories(limit?: number): Promise<HelpfulMemory[]>;
|
|
81
|
+
getHelpfulnessStats(): Promise<HelpfulnessStats>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface RetrievalAnalyticsServiceDeps {
|
|
85
|
+
initialize: () => Promise<void>;
|
|
86
|
+
retrievalStore: RetrievalAnalyticsStore;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export class RetrievalAnalyticsService {
|
|
90
|
+
constructor(private readonly deps: RetrievalAnalyticsServiceDeps) {}
|
|
91
|
+
|
|
92
|
+
async getRetrievalTraceStats(): Promise<RetrievalTraceStats> {
|
|
93
|
+
await this.deps.initialize();
|
|
94
|
+
return this.deps.retrievalStore.getRetrievalTraceStats();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async getRecentRetrievalTraces(limit: number = 50): Promise<RetrievalTrace[]> {
|
|
98
|
+
await this.deps.initialize();
|
|
99
|
+
return this.deps.retrievalStore.getRecentRetrievalTraces(limit);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async getMostAccessedMemories(limit: number = 10): Promise<AccessedMemory[]> {
|
|
103
|
+
// Preserve the historical lightweight path: SQLiteEventStore.getMostAccessed()
|
|
104
|
+
// initializes itself and no-ops safely in read-only scenarios, so dashboard
|
|
105
|
+
// access summaries should not trigger vector/embedder/worker initialization.
|
|
106
|
+
const events = await this.deps.retrievalStore.getMostAccessed(limit);
|
|
107
|
+
|
|
108
|
+
return events.map((event) => ({
|
|
109
|
+
memoryId: event.id,
|
|
110
|
+
summary: event.content.substring(0, 200) + (event.content.length > 200 ? '...' : ''),
|
|
111
|
+
topics: this.extractTopicsFromContent(event.content),
|
|
112
|
+
accessCount: event.access_count || 0,
|
|
113
|
+
lastAccessed: event.last_accessed_at || null,
|
|
114
|
+
confidence: 1.0,
|
|
115
|
+
createdAt: event.timestamp,
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async evaluateSessionHelpfulness(sessionId: string): Promise<void> {
|
|
120
|
+
await this.deps.initialize();
|
|
121
|
+
await this.deps.retrievalStore.evaluateSessionHelpfulness(sessionId);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async evaluatePendingSessions(currentSessionId: string, limit: number = 5): Promise<void> {
|
|
125
|
+
await this.deps.initialize();
|
|
126
|
+
const sessions = await this.deps.retrievalStore.getUnevaluatedSessions(currentSessionId, limit);
|
|
127
|
+
|
|
128
|
+
for (const sessionId of sessions) {
|
|
129
|
+
try {
|
|
130
|
+
await this.deps.retrievalStore.evaluateSessionHelpfulness(sessionId);
|
|
131
|
+
} catch {
|
|
132
|
+
// Best-effort backfill: one broken session should not block hook startup.
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async getHelpfulMemories(limit: number = 10): Promise<HelpfulMemory[]> {
|
|
138
|
+
await this.deps.initialize();
|
|
139
|
+
return this.deps.retrievalStore.getHelpfulMemories(limit);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async getHelpfulnessStats(): Promise<HelpfulnessStats> {
|
|
143
|
+
await this.deps.initialize();
|
|
144
|
+
return this.deps.retrievalStore.getHelpfulnessStats();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Extract topic keywords from event content (markdown headings and key terms).
|
|
149
|
+
*/
|
|
150
|
+
private extractTopicsFromContent(content: string): string[] {
|
|
151
|
+
const topics: Set<string> = new Set();
|
|
152
|
+
|
|
153
|
+
const headings = content.match(/^#{1,3}\s+(.+)$/gm);
|
|
154
|
+
if (headings) {
|
|
155
|
+
for (const heading of headings.slice(0, 5)) {
|
|
156
|
+
const text = heading.replace(/^#+\s+/, '').replace(/[*_`#]/g, '').trim();
|
|
157
|
+
if (text.length > 2 && text.length < 50) {
|
|
158
|
+
topics.add(text);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const boldTerms = content.match(/\*\*([^*]+)\*\*/g);
|
|
164
|
+
if (boldTerms) {
|
|
165
|
+
for (const boldTerm of boldTerms.slice(0, 5)) {
|
|
166
|
+
const text = boldTerm.replace(/\*\*/g, '').trim();
|
|
167
|
+
if (text.length > 2 && text.length < 30) {
|
|
168
|
+
topics.add(text);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return Array.from(topics).slice(0, 5);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function createRetrievalAnalyticsService(
|
|
178
|
+
deps: RetrievalAnalyticsServiceDeps
|
|
179
|
+
): RetrievalAnalyticsService {
|
|
180
|
+
return new RetrievalAnalyticsService(deps);
|
|
181
|
+
}
|