claude-memory-layer 1.0.31 → 1.0.32
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/README.md +9 -2
- package/dist/cli/index.js +1 -1
- package/package.json +11 -2
- package/scripts/postinstall-embedding-backend.cjs +16 -12
- package/AGENTS.md +0 -71
- package/CLAUDE.md +0 -30
- package/HANDOFF.md +0 -92
- package/Memo.txt +0 -558
- package/benchmarks/replay/anonymized-real-sessions.json +0 -48
- package/config/kpi-thresholds.json +0 -7
- package/context.md +0 -636
- package/docs/ARCHITECTURE_COMPARISON_AND_RECOMMENDATIONS.md +0 -627
- package/docs/HERMES_MEMORY_INGESTION_ANALYSIS.md +0 -440
- package/docs/MCP_MEMORY_SERVICE_COMPARATIVE_REVIEW.md +0 -271
- package/docs/MEMORY_USEFULNESS_AUDIT.md +0 -371
- package/docs/MEMORY_USEFULNESS_AUDIT_RAW.json +0 -80
- package/docs/MEMSEARCH_PROJECT_STRUCTURE_ANALYSIS.md +0 -333
- package/docs/MEMU_ADOPTION.md +0 -40
- package/docs/OPERATIONS.md +0 -18
- package/docs/PRODUCT_VALIDATION_MATRIX.md +0 -82
- package/docs/PROJECT_STRUCTURE_ANALYSIS.md +0 -421
- package/docs/REFACTORING_MILESTONES_AND_ISSUES.md +0 -501
- package/docs/REFACTORING_PLAN_THIN_CORE.md +0 -414
- package/docs/REFERENCE_PROJECT_ANALYSES.md +0 -25
- package/docs/SUPERLOCALMEMORY_PROJECT_STRUCTURE_ANALYSIS.md +0 -452
- package/docs/TARGET_ARCHITECTURE_AND_FOLDER_STRUCTURE.md +0 -446
- package/docs/architecture/comparison-index.md +0 -47
- package/docs/reports/codex-real-data-validation-20260505T040447Z.md +0 -46
- package/plan.md +0 -1642
- package/scripts/build.ts +0 -159
- package/scripts/bump-patch-version.sh +0 -18
- package/scripts/delete-unknown-projects.js +0 -154
- package/scripts/fix-sync-gap.js +0 -32
- package/scripts/generate-session-qrels.ts +0 -126
- package/scripts/heartbeat-memory-orchestrator.sh +0 -28
- package/scripts/replay-retrieval-benchmark.ts +0 -69
- package/scripts/report-sync-gap.js +0 -26
- package/scripts/review-queue-auto-resolve.js +0 -21
- package/scripts/sync-gap-auto-heal.sh +0 -17
- package/spec.md +0 -624
- package/specs/20260207-dashboard-upgrade/context.md +0 -38
- package/specs/20260207-dashboard-upgrade/spec.md +0 -96
- package/specs/citations-system/context.md +0 -243
- package/specs/citations-system/plan.md +0 -495
- package/specs/citations-system/spec.md +0 -371
- package/specs/endless-mode/context.md +0 -305
- package/specs/endless-mode/plan.md +0 -620
- package/specs/endless-mode/spec.md +0 -455
- package/specs/entity-edge-model/context.md +0 -401
- package/specs/entity-edge-model/plan.md +0 -459
- package/specs/entity-edge-model/spec.md +0 -391
- package/specs/evidence-aligner-v2/context.md +0 -401
- package/specs/evidence-aligner-v2/plan.md +0 -303
- package/specs/evidence-aligner-v2/spec.md +0 -312
- package/specs/mcp-desktop-integration/context.md +0 -278
- package/specs/mcp-desktop-integration/plan.md +0 -550
- package/specs/mcp-desktop-integration/spec.md +0 -494
- package/specs/memory-utilization-improvements/context.md +0 -145
- package/specs/memory-utilization-improvements/plan.md +0 -361
- package/specs/memory-utilization-improvements/spec.md +0 -361
- package/specs/post-tool-use-hook/context.md +0 -319
- package/specs/post-tool-use-hook/plan.md +0 -469
- package/specs/post-tool-use-hook/spec.md +0 -364
- package/specs/private-tags/context.md +0 -288
- package/specs/private-tags/plan.md +0 -412
- package/specs/private-tags/spec.md +0 -345
- package/specs/progressive-disclosure/context.md +0 -346
- package/specs/progressive-disclosure/plan.md +0 -663
- package/specs/progressive-disclosure/spec.md +0 -415
- package/specs/selective-tool-observation/context.md +0 -100
- package/specs/selective-tool-observation/plan.md +0 -158
- package/specs/selective-tool-observation/spec.md +0 -127
- package/specs/task-entity-system/context.md +0 -297
- package/specs/task-entity-system/plan.md +0 -301
- package/specs/task-entity-system/spec.md +0 -314
- package/specs/thin-core-refactor/context.md +0 -275
- package/specs/thin-core-refactor/plan.md +0 -536
- package/specs/thin-core-refactor/spec.md +0 -465
- package/specs/vector-outbox-v2/context.md +0 -470
- package/specs/vector-outbox-v2/plan.md +0 -562
- package/specs/vector-outbox-v2/spec.md +0 -466
- package/specs/web-viewer-ui/context.md +0 -384
- package/specs/web-viewer-ui/plan.md +0 -797
- package/specs/web-viewer-ui/spec.md +0 -516
- package/src/adapters/claude/capture/index.ts +0 -3
- package/src/adapters/claude/context/index.ts +0 -3
- package/src/adapters/claude/hooks/index.ts +0 -21
- package/src/adapters/claude/hooks/post-tool-use.ts +0 -239
- package/src/adapters/claude/hooks/prompt-injection-policy.ts +0 -104
- package/src/adapters/claude/hooks/semantic-daemon-client.ts +0 -209
- package/src/adapters/claude/hooks/semantic-daemon.ts +0 -283
- package/src/adapters/claude/hooks/session-end.ts +0 -59
- package/src/adapters/claude/hooks/session-start.ts +0 -73
- package/src/adapters/claude/hooks/stop.ts +0 -128
- package/src/adapters/claude/hooks/user-prompt-submit.ts +0 -361
- package/src/adapters/claude/index.ts +0 -4
- package/src/adapters/claude/transcript/index.ts +0 -4
- package/src/adapters/claude/transcript/transcript-reader.ts +0 -57
- package/src/adapters/claude/transcript/turn-reconstructor.ts +0 -65
- package/src/apps/cli/claude-settings-hooks.ts +0 -138
- package/src/apps/cli/codex-import-runner.ts +0 -125
- package/src/apps/cli/codex-validation-output.ts +0 -95
- package/src/apps/cli/hermes-import-runner.ts +0 -130
- package/src/apps/cli/hermes-validation-output.ts +0 -91
- package/src/apps/cli/index.ts +0 -1735
- package/src/apps/cli/mcp-install.ts +0 -106
- package/src/apps/cli/retrieval-disclosure-output.ts +0 -196
- package/src/apps/dashboard/assets/js/bootstrap.js +0 -244
- package/src/apps/dashboard/assets/js/chat.js +0 -373
- package/src/apps/dashboard/assets/js/disclosure.js +0 -232
- package/src/apps/dashboard/assets/js/modals.js +0 -298
- package/src/apps/dashboard/assets/js/overview.js +0 -655
- package/src/apps/dashboard/assets/js/state.js +0 -72
- package/src/apps/dashboard/assets/js/views.js +0 -468
- package/src/apps/dashboard/index.html +0 -543
- package/src/apps/dashboard/index.ts +0 -3
- package/src/apps/dashboard/style.css +0 -1750
- package/src/apps/index.ts +0 -5
- package/src/apps/server/api/chat.ts +0 -244
- package/src/apps/server/api/citations.ts +0 -105
- package/src/apps/server/api/events.ts +0 -137
- package/src/apps/server/api/health.ts +0 -53
- package/src/apps/server/api/index.ts +0 -26
- package/src/apps/server/api/projects.ts +0 -74
- package/src/apps/server/api/search.ts +0 -184
- package/src/apps/server/api/sessions.ts +0 -115
- package/src/apps/server/api/stats.ts +0 -723
- package/src/apps/server/api/turns.ts +0 -143
- package/src/apps/server/api/utils.ts +0 -65
- package/src/apps/server/index.ts +0 -111
- package/src/cli/index.ts +0 -3
- package/src/cli/retrieval-disclosure-output.ts +0 -2
- package/src/compat/index.ts +0 -5
- package/src/core/canonical-key.ts +0 -186
- package/src/core/citation-generator.ts +0 -63
- package/src/core/consolidated-store.ts +0 -356
- package/src/core/consolidation-worker.ts +0 -493
- package/src/core/context-formatter.ts +0 -276
- package/src/core/continuity-manager.ts +0 -341
- package/src/core/db-wrapper.ts +0 -64
- package/src/core/derive/fact-deriver.ts +0 -170
- package/src/core/derive/index.ts +0 -2
- package/src/core/derive/summary-deriver.ts +0 -76
- package/src/core/edge-repo.ts +0 -333
- package/src/core/embedder.ts +0 -4
- package/src/core/engine/embedding-maintenance-service.ts +0 -187
- package/src/core/engine/endless-memory-services.ts +0 -4
- package/src/core/engine/index.ts +0 -19
- package/src/core/engine/memory-engine-services.ts +0 -170
- package/src/core/engine/memory-ingest-service.ts +0 -317
- package/src/core/engine/memory-query-service.ts +0 -173
- package/src/core/engine/memory-runtime-service.ts +0 -162
- package/src/core/engine/memory-service-composition.ts +0 -231
- package/src/core/engine/retrieval-analytics-service.ts +0 -181
- package/src/core/engine/retrieval-disclosure-service.ts +0 -420
- package/src/core/engine/retrieval-orchestrator.ts +0 -377
- package/src/core/engine/retrieval-services.ts +0 -176
- package/src/core/engine/shared-memory-services.ts +0 -4
- package/src/core/entity-repo.ts +0 -349
- package/src/core/event-store.ts +0 -779
- package/src/core/evidence-aligner.ts +0 -635
- package/src/core/external-market-context.ts +0 -582
- package/src/core/graduation-worker.ts +0 -171
- package/src/core/graduation.ts +0 -377
- package/src/core/index.ts +0 -64
- package/src/core/ingest-interceptor.ts +0 -80
- package/src/core/markdown-mirror.ts +0 -70
- package/src/core/matcher.ts +0 -208
- package/src/core/md-mirror.ts +0 -92
- package/src/core/metadata-extractor.ts +0 -203
- package/src/core/model/memory-fact.ts +0 -30
- package/src/core/model/memory-rule.ts +0 -14
- package/src/core/model/memory-summary.ts +0 -21
- package/src/core/model/raw-event.ts +0 -28
- package/src/core/model/retrieval-result.ts +0 -35
- package/src/core/mongo-sync-config.ts +0 -165
- package/src/core/mongo-sync-worker.ts +0 -381
- package/src/core/privacy/filter.ts +0 -190
- package/src/core/privacy/index.ts +0 -20
- package/src/core/privacy/tag-parser.ts +0 -145
- package/src/core/product-validation-matrix.ts +0 -314
- package/src/core/progressive-retriever.ts +0 -414
- package/src/core/registry/project-path.ts +0 -54
- package/src/core/registry/session-registry.ts +0 -69
- package/src/core/replay-evaluator.ts +0 -625
- package/src/core/retrieval-benchmark.ts +0 -117
- package/src/core/retrieval-quality.ts +0 -109
- package/src/core/retriever.ts +0 -800
- package/src/core/session-qrels.ts +0 -360
- package/src/core/shared-event-store.ts +0 -114
- package/src/core/shared-promoter.ts +0 -249
- package/src/core/shared-store.ts +0 -289
- package/src/core/shared-vector-store.ts +0 -203
- package/src/core/sqlite-event-store.ts +0 -1846
- package/src/core/sqlite-wrapper.ts +0 -116
- package/src/core/sync-worker.ts +0 -228
- package/src/core/tag-taxonomy.ts +0 -51
- package/src/core/task/blocker-resolver.ts +0 -333
- package/src/core/task/index.ts +0 -9
- package/src/core/task/task-matcher.ts +0 -240
- package/src/core/task/task-projector.ts +0 -358
- package/src/core/task/task-resolver.ts +0 -421
- package/src/core/turn-state.ts +0 -207
- package/src/core/types.ts +0 -952
- package/src/core/vector-outbox.ts +0 -299
- package/src/core/vector-store.ts +0 -231
- package/src/core/vector-worker.ts +0 -521
- package/src/core/working-set-store.ts +0 -257
- package/src/extensions/endless-memory/endless-memory-services.ts +0 -350
- package/src/extensions/endless-memory/index.ts +0 -1
- package/src/extensions/index.ts +0 -5
- package/src/extensions/mcp/handlers.ts +0 -960
- package/src/extensions/mcp/index.ts +0 -48
- package/src/extensions/mcp/tools.ts +0 -252
- package/src/extensions/shared-memory/index.ts +0 -1
- package/src/extensions/shared-memory/shared-memory-services.ts +0 -211
- package/src/extensions/vector/embedder.ts +0 -234
- package/src/extensions/vector/index.ts +0 -1
- package/src/hooks/post-tool-use.ts +0 -9
- package/src/hooks/semantic-daemon-client.ts +0 -1
- package/src/hooks/semantic-daemon.ts +0 -11
- package/src/hooks/session-end.ts +0 -9
- package/src/hooks/session-start.ts +0 -9
- package/src/hooks/stop.ts +0 -9
- package/src/hooks/user-prompt-submit.ts +0 -9
- package/src/index.ts +0 -13
- package/src/mcp/handlers.ts +0 -2
- package/src/mcp/index.ts +0 -4
- package/src/mcp/tools.ts +0 -2
- package/src/server/api/chat.ts +0 -2
- package/src/server/api/citations.ts +0 -2
- package/src/server/api/events.ts +0 -2
- package/src/server/api/health.ts +0 -2
- package/src/server/api/index.ts +0 -2
- package/src/server/api/projects.ts +0 -2
- package/src/server/api/search.ts +0 -2
- package/src/server/api/sessions.ts +0 -2
- package/src/server/api/stats.ts +0 -2
- package/src/server/api/turns.ts +0 -2
- package/src/server/api/utils.ts +0 -2
- package/src/server/index.ts +0 -2
- package/src/services/bootstrap-organizer.ts +0 -463
- package/src/services/codex-session-history-importer.ts +0 -966
- package/src/services/hermes-session-history-importer.ts +0 -733
- package/src/services/memory-service-config.ts +0 -36
- package/src/services/memory-service-registry.ts +0 -150
- package/src/services/memory-service.ts +0 -688
- package/src/services/session-history-importer.ts +0 -629
- package/tests/README.md +0 -23
- package/tests/adapters/claude/claude-semantic-daemon-adapter.test.ts +0 -54
- package/tests/adapters/claude/claude-transcript-reconstructor.test.ts +0 -98
- package/tests/adapters/claude-hook-prompt-injection-policy.test.ts +0 -99
- package/tests/apps/app-layer-boundary.test.ts +0 -48
- package/tests/apps/claude-settings-hooks.test.ts +0 -107
- package/tests/apps/cli-disclosure-output.test.ts +0 -212
- package/tests/apps/codex-import-runner.test.ts +0 -99
- package/tests/apps/codex-validation-output.test.ts +0 -100
- package/tests/apps/hermes-import-runner.test.ts +0 -99
- package/tests/apps/mcp-install-command.test.ts +0 -59
- package/tests/apps/package-build-entrypoints.test.ts +0 -30
- package/tests/apps/postinstall-embedding-backend.test.ts +0 -185
- package/tests/apps/search-api-disclosure.test.ts +0 -162
- package/tests/apps/stats-api-lightweight.test.ts +0 -67
- package/tests/apps/ui-disclosure-output.test.ts +0 -140
- package/tests/core/bootstrap-organizer.test.ts +0 -111
- package/tests/core/canonical-key.test.ts +0 -101
- package/tests/core/codex-session-history-importer-validation.test.ts +0 -185
- package/tests/core/consolidation-worker.test.ts +0 -75
- package/tests/core/embedding-maintenance-service.test.ts +0 -282
- package/tests/core/evidence-aligner.test.ts +0 -152
- package/tests/core/external-market-context.test.ts +0 -209
- package/tests/core/fact-deriver.test.ts +0 -79
- package/tests/core/hermes-session-history-importer-validation.test.ts +0 -609
- package/tests/core/ingest-interceptor.test.ts +0 -38
- package/tests/core/markdown-mirror.test.ts +0 -85
- package/tests/core/matcher.test.ts +0 -112
- package/tests/core/md-mirror.test.ts +0 -50
- package/tests/core/memory-engine-services.test.ts +0 -240
- package/tests/core/memory-ingest-service.test.ts +0 -296
- package/tests/core/memory-query-service.test.ts +0 -129
- package/tests/core/memory-runtime-service.test.ts +0 -201
- package/tests/core/memory-service-composition.test.ts +0 -192
- package/tests/core/memory-service-config.test.ts +0 -41
- package/tests/core/memory-service-facade.test.ts +0 -30
- package/tests/core/memory-service-registry.test.ts +0 -206
- package/tests/core/product-validation-matrix.test.ts +0 -61
- package/tests/core/project-registry.test.ts +0 -78
- package/tests/core/replay-evaluator.test.ts +0 -181
- package/tests/core/retrieval-analytics-service.test.ts +0 -210
- package/tests/core/retrieval-benchmark.test.ts +0 -93
- package/tests/core/retrieval-disclosure-service.test.ts +0 -264
- package/tests/core/retrieval-orchestrator.test.ts +0 -403
- package/tests/core/retrieval-quality.test.ts +0 -31
- package/tests/core/retrieval-services.test.ts +0 -185
- package/tests/core/retriever-fallback-chain.test.ts +0 -223
- package/tests/core/retriever-strategy-scope.test.ts +0 -164
- package/tests/core/retriever.memu-adoption.test.ts +0 -122
- package/tests/core/session-history-importer-filter.test.ts +0 -78
- package/tests/core/session-qrels.test.ts +0 -250
- package/tests/core/sqlite-event-store-replication.test.ts +0 -127
- package/tests/core/summary-deriver.test.ts +0 -66
- package/tests/extensions/embedder-warning-suppression.test.ts +0 -84
- package/tests/extensions/endless-memory-extension-boundary.test.ts +0 -17
- package/tests/extensions/endless-memory-services.test.ts +0 -325
- package/tests/extensions/mcp-context-tools.test.ts +0 -905
- package/tests/extensions/mcp-extension-boundary.test.ts +0 -21
- package/tests/extensions/mcp-package-build.test.ts +0 -22
- package/tests/extensions/mcp-project-aware-tools.test.ts +0 -102
- package/tests/extensions/shared-memory-extension-boundary.test.ts +0 -24
- package/tests/extensions/shared-memory-services.test.ts +0 -309
- package/tests/extensions/vector-extension-boundary.test.ts +0 -21
- package/tsconfig.json +0 -24
- package/vitest.config.ts +0 -15
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
|
|
4
|
-
export interface EmbeddingMaintenanceEvent {
|
|
5
|
-
id: string;
|
|
6
|
-
content: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface EmbeddingMaintenanceEventStore {
|
|
10
|
-
clearEmbeddingOutbox(): Promise<void>;
|
|
11
|
-
getEventsPage(limit: number, offset: number): Promise<EmbeddingMaintenanceEvent[]>;
|
|
12
|
-
enqueueForEmbedding(eventId: string, content: string): Promise<void>;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface EmbeddingMaintenanceVectorStore {
|
|
16
|
-
count(): Promise<number>;
|
|
17
|
-
clearAll(): Promise<void>;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface EmbeddingMaintenanceVectorWorker {
|
|
21
|
-
isRunning(): boolean;
|
|
22
|
-
stop(): void;
|
|
23
|
-
start(): void;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface EmbeddingMaintenanceFileSystem {
|
|
27
|
-
existsSync(targetPath: string): boolean;
|
|
28
|
-
readFileSync(targetPath: string, encoding: BufferEncoding): string;
|
|
29
|
-
writeFileSync(targetPath: string, content: string): void;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface EmbeddingModelMaintenanceOptions {
|
|
33
|
-
autoMigrate?: boolean;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface EmbeddingModelMaintenanceResult {
|
|
37
|
-
changed: boolean;
|
|
38
|
-
previousModel: string | null;
|
|
39
|
-
currentModel: string;
|
|
40
|
-
enqueued: number;
|
|
41
|
-
reason?: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface EmbeddingMaintenanceServiceOptions {
|
|
45
|
-
storagePath: string;
|
|
46
|
-
initialize: () => Promise<void>;
|
|
47
|
-
getEmbeddingModelName: () => string;
|
|
48
|
-
vectorStore: EmbeddingMaintenanceVectorStore;
|
|
49
|
-
eventStore: EmbeddingMaintenanceEventStore;
|
|
50
|
-
getVectorWorker: () => EmbeddingMaintenanceVectorWorker | null;
|
|
51
|
-
fileSystem?: EmbeddingMaintenanceFileSystem;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export interface EmbeddingMaintenanceService {
|
|
55
|
-
getEmbeddingModelName(): string;
|
|
56
|
-
ensureEmbeddingModelForImport(options?: EmbeddingModelMaintenanceOptions): Promise<EmbeddingModelMaintenanceResult>;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const DEFAULT_PAGE_SIZE = 1000;
|
|
60
|
-
|
|
61
|
-
const defaultFileSystem: EmbeddingMaintenanceFileSystem = {
|
|
62
|
-
existsSync: fs.existsSync,
|
|
63
|
-
readFileSync: (targetPath, encoding) => fs.readFileSync(targetPath, encoding),
|
|
64
|
-
writeFileSync: (targetPath, content) => fs.writeFileSync(targetPath, content)
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
class DefaultEmbeddingMaintenanceService implements EmbeddingMaintenanceService {
|
|
68
|
-
private readonly fileSystem: EmbeddingMaintenanceFileSystem;
|
|
69
|
-
|
|
70
|
-
constructor(private readonly options: EmbeddingMaintenanceServiceOptions) {
|
|
71
|
-
this.fileSystem = options.fileSystem ?? defaultFileSystem;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
getEmbeddingModelName(): string {
|
|
75
|
-
return this.options.getEmbeddingModelName();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async ensureEmbeddingModelForImport(
|
|
79
|
-
options?: EmbeddingModelMaintenanceOptions
|
|
80
|
-
): Promise<EmbeddingModelMaintenanceResult> {
|
|
81
|
-
await this.options.initialize();
|
|
82
|
-
|
|
83
|
-
const currentModel = this.getEmbeddingModelName();
|
|
84
|
-
const metaPath = path.join(this.options.storagePath, 'embedding-meta.json');
|
|
85
|
-
const previousModel = this.readPreviousModel(metaPath);
|
|
86
|
-
const vectorCount = await this.options.vectorStore.count();
|
|
87
|
-
const hasExistingVectors = vectorCount > 0;
|
|
88
|
-
|
|
89
|
-
// First-time metadata write (no migration needed unless legacy vectors exist)
|
|
90
|
-
if (!previousModel && !hasExistingVectors) {
|
|
91
|
-
this.fileSystem.writeFileSync(
|
|
92
|
-
metaPath,
|
|
93
|
-
JSON.stringify({ model: currentModel, updatedAt: new Date().toISOString() }, null, 2)
|
|
94
|
-
);
|
|
95
|
-
return { changed: false, previousModel: null, currentModel, enqueued: 0, reason: 'initialized-meta' };
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const modelChanged = previousModel !== currentModel;
|
|
99
|
-
const legacyUnknownButVectorsExist = !previousModel && hasExistingVectors;
|
|
100
|
-
|
|
101
|
-
if (!modelChanged && !legacyUnknownButVectorsExist) {
|
|
102
|
-
return { changed: false, previousModel, currentModel, enqueued: 0 };
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (options?.autoMigrate === false) {
|
|
106
|
-
return {
|
|
107
|
-
changed: true,
|
|
108
|
-
previousModel,
|
|
109
|
-
currentModel,
|
|
110
|
-
enqueued: 0,
|
|
111
|
-
reason: legacyUnknownButVectorsExist ? 'legacy-vectors-without-meta' : 'model-mismatch'
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const worker = this.options.getVectorWorker();
|
|
116
|
-
const wasRunning = worker?.isRunning() || false;
|
|
117
|
-
if (wasRunning) worker?.stop();
|
|
118
|
-
|
|
119
|
-
await this.options.vectorStore.clearAll();
|
|
120
|
-
await this.options.eventStore.clearEmbeddingOutbox();
|
|
121
|
-
|
|
122
|
-
const enqueued = await this.reenqueueAllEvents();
|
|
123
|
-
|
|
124
|
-
this.fileSystem.writeFileSync(
|
|
125
|
-
metaPath,
|
|
126
|
-
JSON.stringify(
|
|
127
|
-
{
|
|
128
|
-
model: currentModel,
|
|
129
|
-
previousModel,
|
|
130
|
-
migratedAt: new Date().toISOString(),
|
|
131
|
-
enqueued
|
|
132
|
-
},
|
|
133
|
-
null,
|
|
134
|
-
2
|
|
135
|
-
)
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
if (wasRunning) worker?.start();
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
changed: true,
|
|
142
|
-
previousModel,
|
|
143
|
-
currentModel,
|
|
144
|
-
enqueued,
|
|
145
|
-
reason: legacyUnknownButVectorsExist ? 'legacy-vectors-without-meta' : 'model-mismatch'
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
private readPreviousModel(metaPath: string): string | null {
|
|
150
|
-
try {
|
|
151
|
-
if (this.fileSystem.existsSync(metaPath)) {
|
|
152
|
-
const parsed = JSON.parse(this.fileSystem.readFileSync(metaPath, 'utf-8')) as { model?: string };
|
|
153
|
-
return parsed?.model || null;
|
|
154
|
-
}
|
|
155
|
-
} catch {
|
|
156
|
-
return null;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
private async reenqueueAllEvents(): Promise<number> {
|
|
163
|
-
let offset = 0;
|
|
164
|
-
let enqueued = 0;
|
|
165
|
-
|
|
166
|
-
while (true) {
|
|
167
|
-
const page = await this.options.eventStore.getEventsPage(DEFAULT_PAGE_SIZE, offset);
|
|
168
|
-
if (page.length === 0) break;
|
|
169
|
-
|
|
170
|
-
for (const event of page) {
|
|
171
|
-
await this.options.eventStore.enqueueForEmbedding(event.id, event.content);
|
|
172
|
-
enqueued += 1;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
offset += page.length;
|
|
176
|
-
if (page.length < DEFAULT_PAGE_SIZE) break;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return enqueued;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export function createEmbeddingMaintenanceService(
|
|
184
|
-
options: EmbeddingMaintenanceServiceOptions
|
|
185
|
-
): EmbeddingMaintenanceService {
|
|
186
|
-
return new DefaultEmbeddingMaintenanceService(options);
|
|
187
|
-
}
|
package/src/core/engine/index.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export * from './memory-ingest-service.js';
|
|
2
|
-
export * from './memory-query-service.js';
|
|
3
|
-
export * from './memory-engine-services.js';
|
|
4
|
-
export * from './retrieval-orchestrator.js';
|
|
5
|
-
export * from './retrieval-disclosure-service.js';
|
|
6
|
-
export * from './retrieval-analytics-service.js';
|
|
7
|
-
export * from './shared-memory-services.js';
|
|
8
|
-
export * from './endless-memory-services.js';
|
|
9
|
-
export * from './embedding-maintenance-service.js';
|
|
10
|
-
export * from './memory-runtime-service.js';
|
|
11
|
-
export {
|
|
12
|
-
createRetrievalServices
|
|
13
|
-
} from './retrieval-services.js';
|
|
14
|
-
export type {
|
|
15
|
-
CreateRetrieverFn,
|
|
16
|
-
RetrievalEventStore,
|
|
17
|
-
RetrievalServices,
|
|
18
|
-
RetrievalServicesDeps
|
|
19
|
-
} from './retrieval-services.js';
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Memory Engine Services Bundle
|
|
3
|
-
*
|
|
4
|
-
* Owns construction and wiring for storage-backed engine services so
|
|
5
|
-
* MemoryService can stay focused on public facade/lifecycle behavior.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import * as fs from 'fs';
|
|
9
|
-
import * as path from 'path';
|
|
10
|
-
|
|
11
|
-
import { Embedder, getDefaultEmbedder } from '../embedder.js';
|
|
12
|
-
import type { EventStore } from '../event-store.js';
|
|
13
|
-
import { createGraduationPipeline, type GraduationPipeline } from '../graduation.js';
|
|
14
|
-
import { getDefaultMatcher, type Matcher } from '../matcher.js';
|
|
15
|
-
import { MarkdownMirror } from '../md-mirror.js';
|
|
16
|
-
import type { Retriever } from '../retriever.js';
|
|
17
|
-
import { SQLiteEventStore } from '../sqlite-event-store.js';
|
|
18
|
-
import type { ToolObservationPayload } from '../types.js';
|
|
19
|
-
import { VectorStore } from '../vector-store.js';
|
|
20
|
-
import { MemoryIngestService } from './memory-ingest-service.js';
|
|
21
|
-
import { MemoryQueryService } from './memory-query-service.js';
|
|
22
|
-
import {
|
|
23
|
-
createRetrievalServices,
|
|
24
|
-
type RetrievalAnalyticsService,
|
|
25
|
-
type RetrievalDisclosureService,
|
|
26
|
-
type RetrievalDisclosureSharedStore,
|
|
27
|
-
type RetrievalEventStore,
|
|
28
|
-
type RetrievalOrchestrator,
|
|
29
|
-
type RetrievalServices,
|
|
30
|
-
type RetrievalServicesDeps
|
|
31
|
-
} from './retrieval-services.js';
|
|
32
|
-
|
|
33
|
-
export interface MemoryEngineServicesOptions {
|
|
34
|
-
storagePath: string;
|
|
35
|
-
readOnly: boolean;
|
|
36
|
-
embeddingModel?: string;
|
|
37
|
-
cwd?: string;
|
|
38
|
-
initialize: () => Promise<void>;
|
|
39
|
-
getProjectHash: () => string | null;
|
|
40
|
-
getProjectPath?: () => string | null;
|
|
41
|
-
hasSharedStore: () => boolean;
|
|
42
|
-
sharedStore?: RetrievalDisclosureSharedStore;
|
|
43
|
-
createToolObservationEmbedding: (payload: ToolObservationPayload) => string;
|
|
44
|
-
factories?: MemoryEngineServicesFactories;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export interface MemoryEngineServicesFactories {
|
|
48
|
-
createSQLiteEventStore?: (
|
|
49
|
-
dbPath: string,
|
|
50
|
-
options: { readonly: boolean; markdownMirrorRoot: string }
|
|
51
|
-
) => SQLiteEventStore;
|
|
52
|
-
createVectorStore?: (vectorsPath: string) => VectorStore;
|
|
53
|
-
createEmbedder?: (model: string) => Embedder;
|
|
54
|
-
getDefaultEmbedder?: () => Embedder;
|
|
55
|
-
getDefaultMatcher?: () => Matcher;
|
|
56
|
-
createMarkdownMirror?: (cwd: string) => MarkdownMirror;
|
|
57
|
-
createGraduationPipeline?: (eventStore: EventStore) => GraduationPipeline;
|
|
58
|
-
createRetrievalServices?: (deps: RetrievalServicesDeps) => RetrievalServices;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface MemoryEngineServices {
|
|
62
|
-
storagePath: string;
|
|
63
|
-
sqliteStore: SQLiteEventStore;
|
|
64
|
-
vectorStore: VectorStore;
|
|
65
|
-
embedder: Embedder;
|
|
66
|
-
matcher: Matcher;
|
|
67
|
-
retriever: Retriever;
|
|
68
|
-
retrievalOrchestrator: RetrievalOrchestrator;
|
|
69
|
-
retrievalDisclosureService: RetrievalDisclosureService;
|
|
70
|
-
retrievalAnalyticsService: RetrievalAnalyticsService;
|
|
71
|
-
graduation: GraduationPipeline;
|
|
72
|
-
mdMirror: MarkdownMirror;
|
|
73
|
-
ingestService: MemoryIngestService;
|
|
74
|
-
queryService: MemoryQueryService;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function createMemoryEngineServices(options: MemoryEngineServicesOptions): MemoryEngineServices {
|
|
78
|
-
const factories = options.factories ?? {};
|
|
79
|
-
const storagePath = options.storagePath;
|
|
80
|
-
|
|
81
|
-
if (!options.readOnly && !fs.existsSync(storagePath)) {
|
|
82
|
-
fs.mkdirSync(storagePath, { recursive: true });
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const sqliteStore = (factories.createSQLiteEventStore ?? defaultCreateSQLiteEventStore)(
|
|
86
|
-
path.join(storagePath, 'events.sqlite'),
|
|
87
|
-
{
|
|
88
|
-
readonly: options.readOnly,
|
|
89
|
-
markdownMirrorRoot: storagePath
|
|
90
|
-
}
|
|
91
|
-
);
|
|
92
|
-
const vectorStore = (factories.createVectorStore ?? defaultCreateVectorStore)(
|
|
93
|
-
path.join(storagePath, 'vectors')
|
|
94
|
-
);
|
|
95
|
-
const embeddingModel = options.embeddingModel || process.env.CLAUDE_MEMORY_EMBEDDING_MODEL;
|
|
96
|
-
const embedder = embeddingModel
|
|
97
|
-
? (factories.createEmbedder ?? defaultCreateEmbedder)(embeddingModel)
|
|
98
|
-
: (factories.getDefaultEmbedder ?? getDefaultEmbedder)();
|
|
99
|
-
const matcher = (factories.getDefaultMatcher ?? getDefaultMatcher)();
|
|
100
|
-
const mdMirror = (factories.createMarkdownMirror ?? defaultCreateMarkdownMirror)(
|
|
101
|
-
options.cwd ?? process.cwd()
|
|
102
|
-
);
|
|
103
|
-
const graduation = (factories.createGraduationPipeline ?? defaultCreateGraduationPipeline)(
|
|
104
|
-
sqliteStore as unknown as EventStore
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
const retrievalServices = (factories.createRetrievalServices ?? createRetrievalServices)({
|
|
108
|
-
initialize: options.initialize,
|
|
109
|
-
eventStore: sqliteStore as unknown as RetrievalEventStore,
|
|
110
|
-
vectorStore,
|
|
111
|
-
embedder,
|
|
112
|
-
matcher,
|
|
113
|
-
getProjectHash: options.getProjectHash,
|
|
114
|
-
hasSharedStore: options.hasSharedStore,
|
|
115
|
-
sharedStore: options.sharedStore
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
const ingestService = new MemoryIngestService({
|
|
119
|
-
initialize: options.initialize,
|
|
120
|
-
eventStore: sqliteStore,
|
|
121
|
-
markdownMirror: mdMirror,
|
|
122
|
-
createToolEmbedding: options.createToolObservationEmbedding,
|
|
123
|
-
getProjectHash: options.getProjectHash,
|
|
124
|
-
getProjectPath: options.getProjectPath
|
|
125
|
-
});
|
|
126
|
-
const queryService = new MemoryQueryService(
|
|
127
|
-
() => sqliteStore.initialize(),
|
|
128
|
-
sqliteStore,
|
|
129
|
-
{ vectorStore, graduation }
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
return {
|
|
133
|
-
storagePath,
|
|
134
|
-
sqliteStore,
|
|
135
|
-
vectorStore,
|
|
136
|
-
embedder,
|
|
137
|
-
matcher,
|
|
138
|
-
retriever: retrievalServices.retriever,
|
|
139
|
-
retrievalOrchestrator: retrievalServices.retrievalOrchestrator,
|
|
140
|
-
retrievalDisclosureService: retrievalServices.retrievalDisclosureService,
|
|
141
|
-
retrievalAnalyticsService: retrievalServices.retrievalAnalyticsService,
|
|
142
|
-
graduation,
|
|
143
|
-
mdMirror,
|
|
144
|
-
ingestService,
|
|
145
|
-
queryService
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function defaultCreateSQLiteEventStore(
|
|
150
|
-
dbPath: string,
|
|
151
|
-
options: { readonly: boolean; markdownMirrorRoot: string }
|
|
152
|
-
): SQLiteEventStore {
|
|
153
|
-
return new SQLiteEventStore(dbPath, options);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function defaultCreateVectorStore(vectorsPath: string): VectorStore {
|
|
157
|
-
return new VectorStore(vectorsPath);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function defaultCreateEmbedder(model: string): Embedder {
|
|
161
|
-
return new Embedder(model);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function defaultCreateMarkdownMirror(cwd: string): MarkdownMirror {
|
|
165
|
-
return new MarkdownMirror(cwd);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function defaultCreateGraduationPipeline(eventStore: EventStore): GraduationPipeline {
|
|
169
|
-
return createGraduationPipeline(eventStore);
|
|
170
|
-
}
|
|
@@ -1,317 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
IngestInterceptor,
|
|
3
|
-
IngestInterceptorRegistry,
|
|
4
|
-
mergeHierarchicalMetadata
|
|
5
|
-
} from '../ingest-interceptor.js';
|
|
6
|
-
import { normalizeTags } from '../tag-taxonomy.js';
|
|
7
|
-
import { createSummaryDeriver, type SummaryDeriver } from '../derive/summary-deriver.js';
|
|
8
|
-
import type { AppendResult, MemoryEvent, MemoryEventInput, ToolObservationPayload } from '../types.js';
|
|
9
|
-
|
|
10
|
-
interface SessionRecord {
|
|
11
|
-
id: string;
|
|
12
|
-
startedAt?: Date;
|
|
13
|
-
endedAt?: Date;
|
|
14
|
-
projectPath?: string;
|
|
15
|
-
summary?: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface SessionUpsertStore {
|
|
19
|
-
upsertSession(session: SessionRecord): Promise<void>;
|
|
20
|
-
getSessionEvents(sessionId: string): Promise<MemoryEvent[]>;
|
|
21
|
-
getSessionsWithoutSummary(currentSessionId: string, limit?: number): Promise<string[]>;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
interface IngestEventStore extends SessionUpsertStore {
|
|
25
|
-
append(input: MemoryEventInput): Promise<AppendResult>;
|
|
26
|
-
enqueueForEmbedding(eventId: string, content: string): Promise<unknown>;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
interface IngestMarkdownMirror {
|
|
30
|
-
append(event: MemoryEventInput, eventId?: string): Promise<void>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type IngestOperation = 'user_prompt' | 'agent_response' | 'session_summary' | 'tool_observation';
|
|
34
|
-
|
|
35
|
-
export interface MemoryIngestServiceOptions {
|
|
36
|
-
initialize: () => Promise<void>;
|
|
37
|
-
eventStore: IngestEventStore;
|
|
38
|
-
markdownMirror: IngestMarkdownMirror;
|
|
39
|
-
createToolEmbedding: (payload: ToolObservationPayload) => string;
|
|
40
|
-
getProjectHash?: () => string | null;
|
|
41
|
-
getProjectPath?: () => string | null;
|
|
42
|
-
summaryDeriver?: SummaryDeriver;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Thin-core ingest service for session lifecycle and event writes.
|
|
47
|
-
*
|
|
48
|
-
* Owns the ingest normalization/interceptor/append pipeline so the public
|
|
49
|
-
* MemoryService facade can delegate ingest behavior without coordinating
|
|
50
|
-
* storage-side effects itself.
|
|
51
|
-
*/
|
|
52
|
-
export class MemoryIngestService {
|
|
53
|
-
private readonly initialize: () => Promise<void>;
|
|
54
|
-
private readonly eventStore: IngestEventStore;
|
|
55
|
-
private readonly markdownMirror: IngestMarkdownMirror;
|
|
56
|
-
private readonly createToolEmbedding: (payload: ToolObservationPayload) => string;
|
|
57
|
-
private readonly getProjectHash: () => string | null;
|
|
58
|
-
private readonly getProjectPath: () => string | null;
|
|
59
|
-
private readonly summaryDeriver: SummaryDeriver;
|
|
60
|
-
private readonly ingestInterceptors = new IngestInterceptorRegistry();
|
|
61
|
-
|
|
62
|
-
constructor(options: MemoryIngestServiceOptions) {
|
|
63
|
-
this.initialize = options.initialize;
|
|
64
|
-
this.eventStore = options.eventStore;
|
|
65
|
-
this.markdownMirror = options.markdownMirror;
|
|
66
|
-
this.createToolEmbedding = options.createToolEmbedding;
|
|
67
|
-
this.getProjectHash = options.getProjectHash ?? (() => null);
|
|
68
|
-
this.getProjectPath = options.getProjectPath ?? (() => null);
|
|
69
|
-
this.summaryDeriver = options.summaryDeriver ?? createSummaryDeriver();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
registerIngestBefore(interceptor: IngestInterceptor): () => void {
|
|
73
|
-
return this.ingestInterceptors.registerBefore(interceptor);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
registerIngestAfter(interceptor: IngestInterceptor): () => void {
|
|
77
|
-
return this.ingestInterceptors.registerAfter(interceptor);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
registerIngestOnError(interceptor: IngestInterceptor): () => void {
|
|
81
|
-
return this.ingestInterceptors.registerOnError(interceptor);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async startSession(sessionId: string, projectPath?: string): Promise<void> {
|
|
85
|
-
await this.initialize();
|
|
86
|
-
|
|
87
|
-
await this.eventStore.upsertSession({
|
|
88
|
-
id: sessionId,
|
|
89
|
-
startedAt: new Date(),
|
|
90
|
-
projectPath
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async endSession(sessionId: string, summary?: string): Promise<void> {
|
|
95
|
-
await this.initialize();
|
|
96
|
-
|
|
97
|
-
await this.eventStore.upsertSession({
|
|
98
|
-
id: sessionId,
|
|
99
|
-
endedAt: new Date(),
|
|
100
|
-
summary
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async storeUserPrompt(
|
|
105
|
-
sessionId: string,
|
|
106
|
-
content: string,
|
|
107
|
-
metadata?: Record<string, unknown>
|
|
108
|
-
): Promise<AppendResult> {
|
|
109
|
-
return this.ingestEvent({
|
|
110
|
-
operation: 'user_prompt',
|
|
111
|
-
input: {
|
|
112
|
-
eventType: 'user_prompt',
|
|
113
|
-
sessionId,
|
|
114
|
-
timestamp: new Date(),
|
|
115
|
-
content,
|
|
116
|
-
metadata
|
|
117
|
-
},
|
|
118
|
-
embeddingContent: content
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async storeAgentResponse(
|
|
123
|
-
sessionId: string,
|
|
124
|
-
content: string,
|
|
125
|
-
metadata?: Record<string, unknown>
|
|
126
|
-
): Promise<AppendResult> {
|
|
127
|
-
return this.ingestEvent({
|
|
128
|
-
operation: 'agent_response',
|
|
129
|
-
input: {
|
|
130
|
-
eventType: 'agent_response',
|
|
131
|
-
sessionId,
|
|
132
|
-
timestamp: new Date(),
|
|
133
|
-
content,
|
|
134
|
-
metadata
|
|
135
|
-
},
|
|
136
|
-
embeddingContent: content
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async storeSessionSummary(
|
|
141
|
-
sessionId: string,
|
|
142
|
-
summary: string,
|
|
143
|
-
metadata?: Record<string, unknown>
|
|
144
|
-
): Promise<AppendResult> {
|
|
145
|
-
return this.ingestEvent({
|
|
146
|
-
operation: 'session_summary',
|
|
147
|
-
input: {
|
|
148
|
-
eventType: 'session_summary',
|
|
149
|
-
sessionId,
|
|
150
|
-
timestamp: new Date(),
|
|
151
|
-
content: summary,
|
|
152
|
-
metadata
|
|
153
|
-
},
|
|
154
|
-
embeddingContent: summary
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Backfill session summaries for recent sessions that are missing them.
|
|
160
|
-
* Called from session-start hook to catch sessions that ended without Stop hook.
|
|
161
|
-
*/
|
|
162
|
-
async backfillMissingSummaries(currentSessionId: string, limit = 5): Promise<void> {
|
|
163
|
-
await this.initialize();
|
|
164
|
-
|
|
165
|
-
const recentSessionIds = await this.eventStore.getSessionsWithoutSummary(currentSessionId, limit);
|
|
166
|
-
for (const sessionId of recentSessionIds) {
|
|
167
|
-
try {
|
|
168
|
-
await this.generateSessionSummary(sessionId);
|
|
169
|
-
} catch {
|
|
170
|
-
// non-critical backfill path
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Generate a rule-based session summary from stored events.
|
|
177
|
-
* Skips short sessions and sessions that already contain a summary event.
|
|
178
|
-
*/
|
|
179
|
-
async generateSessionSummary(sessionId: string): Promise<void> {
|
|
180
|
-
await this.initialize();
|
|
181
|
-
|
|
182
|
-
const events = await this.eventStore.getSessionEvents(sessionId);
|
|
183
|
-
const summary = this.summaryDeriver.deriveSessionSummary(events);
|
|
184
|
-
if (!summary) return;
|
|
185
|
-
|
|
186
|
-
await this.storeSessionSummary(sessionId, summary.text, summary.metadata);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async storeToolObservation(
|
|
190
|
-
sessionId: string,
|
|
191
|
-
payload: ToolObservationPayload
|
|
192
|
-
): Promise<AppendResult> {
|
|
193
|
-
const content = JSON.stringify(payload);
|
|
194
|
-
const turnId = (payload.metadata as Record<string, unknown> | undefined)?.turnId;
|
|
195
|
-
|
|
196
|
-
return this.ingestEvent({
|
|
197
|
-
operation: 'tool_observation',
|
|
198
|
-
input: {
|
|
199
|
-
eventType: 'tool_observation',
|
|
200
|
-
sessionId,
|
|
201
|
-
timestamp: new Date(),
|
|
202
|
-
content,
|
|
203
|
-
metadata: {
|
|
204
|
-
toolName: payload.toolName,
|
|
205
|
-
success: payload.success,
|
|
206
|
-
...(typeof turnId === 'string' && turnId.length > 0 ? { turnId } : {})
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
|
-
embeddingContent: this.createToolEmbedding(payload)
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
private async ingestEvent(options: {
|
|
214
|
-
operation: IngestOperation;
|
|
215
|
-
input: MemoryEventInput;
|
|
216
|
-
embeddingContent?: string;
|
|
217
|
-
}): Promise<AppendResult> {
|
|
218
|
-
const normalizedInput = this.normalizeInput(options.operation, options.input);
|
|
219
|
-
|
|
220
|
-
await this.ingestInterceptors.run('before', {
|
|
221
|
-
operation: options.operation,
|
|
222
|
-
sessionId: normalizedInput.sessionId,
|
|
223
|
-
event: normalizedInput
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
try {
|
|
227
|
-
const result = await this.eventStore.append(normalizedInput);
|
|
228
|
-
if (result.success === false) {
|
|
229
|
-
await this.ingestInterceptors.run('error', {
|
|
230
|
-
operation: options.operation,
|
|
231
|
-
sessionId: normalizedInput.sessionId,
|
|
232
|
-
event: normalizedInput,
|
|
233
|
-
error: new Error(result.error)
|
|
234
|
-
});
|
|
235
|
-
return result;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if (!result.isDuplicate) {
|
|
239
|
-
if (options.embeddingContent) {
|
|
240
|
-
await this.eventStore.enqueueForEmbedding(result.eventId, options.embeddingContent);
|
|
241
|
-
}
|
|
242
|
-
try {
|
|
243
|
-
await this.markdownMirror.append(normalizedInput, result.eventId);
|
|
244
|
-
} catch {
|
|
245
|
-
// non-breaking markdown mirror write
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
await this.ingestInterceptors.run('after', {
|
|
250
|
-
operation: options.operation,
|
|
251
|
-
sessionId: normalizedInput.sessionId,
|
|
252
|
-
event: normalizedInput
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
return result;
|
|
256
|
-
} catch (error) {
|
|
257
|
-
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
258
|
-
await this.ingestInterceptors.run('error', {
|
|
259
|
-
operation: options.operation,
|
|
260
|
-
sessionId: normalizedInput.sessionId,
|
|
261
|
-
event: normalizedInput,
|
|
262
|
-
error: normalizedError
|
|
263
|
-
});
|
|
264
|
-
throw error;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
private normalizeInput(operation: IngestOperation, input: MemoryEventInput): MemoryEventInput {
|
|
269
|
-
const projectHash = this.getProjectHash();
|
|
270
|
-
const projectPath = this.getProjectPath();
|
|
271
|
-
const normalizedInput: MemoryEventInput = {
|
|
272
|
-
...input,
|
|
273
|
-
metadata: mergeHierarchicalMetadata(
|
|
274
|
-
{
|
|
275
|
-
ingest: {
|
|
276
|
-
operation,
|
|
277
|
-
pipeline: 'default',
|
|
278
|
-
ts: new Date().toISOString()
|
|
279
|
-
},
|
|
280
|
-
...(projectHash
|
|
281
|
-
? {
|
|
282
|
-
scope: {
|
|
283
|
-
project: {
|
|
284
|
-
hash: projectHash,
|
|
285
|
-
...(projectPath ? { path: projectPath } : {})
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
tags: [`proj:${projectHash}`]
|
|
289
|
-
}
|
|
290
|
-
: {})
|
|
291
|
-
},
|
|
292
|
-
input.metadata
|
|
293
|
-
)
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
if (projectHash && normalizedInput.metadata) {
|
|
297
|
-
const meta = normalizedInput.metadata as Record<string, unknown>;
|
|
298
|
-
const currentTags = Array.isArray(meta.tags)
|
|
299
|
-
? meta.tags.filter((x): x is string => typeof x === 'string')
|
|
300
|
-
: [];
|
|
301
|
-
const projectTag = `proj:${projectHash}`;
|
|
302
|
-
if (!currentTags.includes(projectTag)) {
|
|
303
|
-
meta.tags = [...currentTags, projectTag];
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (normalizedInput.metadata) {
|
|
308
|
-
const meta = normalizedInput.metadata as Record<string, unknown>;
|
|
309
|
-
const normalizedTags = normalizeTags(meta.tags);
|
|
310
|
-
if (normalizedTags.length > 0) {
|
|
311
|
-
meta.tags = normalizedTags;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return normalizedInput;
|
|
316
|
-
}
|
|
317
|
-
}
|