claude-memory-layer 1.0.30 → 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 +12 -5
- package/dist/cli/index.js +4 -3
- package/dist/cli/index.js.map +2 -2
- package/dist/core/index.js +3 -2
- package/dist/core/index.js.map +2 -2
- package/dist/hooks/post-tool-use.js +3 -2
- package/dist/hooks/post-tool-use.js.map +2 -2
- package/dist/hooks/semantic-daemon.js +3 -2
- package/dist/hooks/semantic-daemon.js.map +2 -2
- package/dist/hooks/session-end.js +3 -2
- package/dist/hooks/session-end.js.map +2 -2
- package/dist/hooks/session-start.js +3 -2
- package/dist/hooks/session-start.js.map +2 -2
- package/dist/hooks/stop.js +3 -2
- package/dist/hooks/stop.js.map +2 -2
- package/dist/hooks/user-prompt-submit.js +3 -2
- package/dist/hooks/user-prompt-submit.js.map +2 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +2 -2
- package/dist/mcp/index.js +3 -2
- package/dist/mcp/index.js.map +2 -2
- package/dist/server/api/index.js +3 -2
- package/dist/server/api/index.js.map +2 -2
- package/dist/server/index.js +3 -2
- package/dist/server/index.js.map +2 -2
- package/dist/services/memory-service.js +3 -2
- package/dist/services/memory-service.js.map +2 -2
- package/package.json +10 -3
- package/scripts/postinstall-embedding-backend.cjs +18 -16
- 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 -233
- 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 -175
- 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 -83
- 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,521 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Vector Worker - Single-Writer Pattern Implementation
|
|
3
|
-
* AXIOMMIND Principle 6: DuckDB → outbox → LanceDB unidirectional flow
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { EventStore } from './event-store.js';
|
|
7
|
-
import { VectorStore } from './vector-store.js';
|
|
8
|
-
import { Embedder } from './embedder.js';
|
|
9
|
-
import type { VectorRecord } from './types.js';
|
|
10
|
-
|
|
11
|
-
export interface WorkerConfig {
|
|
12
|
-
batchSize: number;
|
|
13
|
-
pollIntervalMs: number;
|
|
14
|
-
maxRetries: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const DEFAULT_CONFIG: WorkerConfig = {
|
|
18
|
-
batchSize: 32,
|
|
19
|
-
pollIntervalMs: 1000,
|
|
20
|
-
maxRetries: 3
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export class VectorWorker {
|
|
24
|
-
private readonly eventStore: EventStore;
|
|
25
|
-
private readonly vectorStore: VectorStore;
|
|
26
|
-
private readonly embedder: Embedder;
|
|
27
|
-
private readonly config: WorkerConfig;
|
|
28
|
-
private running = false;
|
|
29
|
-
private stopping = false;
|
|
30
|
-
private pollTimeout: NodeJS.Timeout | null = null;
|
|
31
|
-
|
|
32
|
-
constructor(
|
|
33
|
-
eventStore: EventStore,
|
|
34
|
-
vectorStore: VectorStore,
|
|
35
|
-
embedder: Embedder,
|
|
36
|
-
config: Partial<WorkerConfig> = {}
|
|
37
|
-
) {
|
|
38
|
-
this.eventStore = eventStore;
|
|
39
|
-
this.vectorStore = vectorStore;
|
|
40
|
-
this.embedder = embedder;
|
|
41
|
-
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Start the worker polling loop
|
|
46
|
-
*/
|
|
47
|
-
start(): void {
|
|
48
|
-
if (this.running) return;
|
|
49
|
-
this.running = true;
|
|
50
|
-
this.stopping = false;
|
|
51
|
-
this.poll();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Stop the worker
|
|
56
|
-
*/
|
|
57
|
-
stop(): void {
|
|
58
|
-
this.running = false;
|
|
59
|
-
this.stopping = true;
|
|
60
|
-
if (this.pollTimeout) {
|
|
61
|
-
clearTimeout(this.pollTimeout);
|
|
62
|
-
this.pollTimeout = null;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Process a single batch of outbox items
|
|
68
|
-
*/
|
|
69
|
-
async processBatch(): Promise<number> {
|
|
70
|
-
const items = await this.eventStore.getPendingOutboxItems(this.config.batchSize);
|
|
71
|
-
|
|
72
|
-
if (items.length === 0) {
|
|
73
|
-
return 0;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const successful: string[] = [];
|
|
77
|
-
const failed: string[] = [];
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
// Generate embeddings for all items
|
|
81
|
-
const embeddings = await this.embedder.embedBatch(items.map(i => i.content));
|
|
82
|
-
|
|
83
|
-
// Prepare vector records
|
|
84
|
-
const records: VectorRecord[] = [];
|
|
85
|
-
|
|
86
|
-
for (let i = 0; i < items.length; i++) {
|
|
87
|
-
const item = items[i];
|
|
88
|
-
const embedding = embeddings[i];
|
|
89
|
-
|
|
90
|
-
// Get event details
|
|
91
|
-
const event = await this.eventStore.getEvent(item.eventId);
|
|
92
|
-
if (!event) {
|
|
93
|
-
failed.push(item.id);
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
records.push({
|
|
98
|
-
id: `vec_${item.id}`,
|
|
99
|
-
eventId: item.eventId,
|
|
100
|
-
sessionId: event.sessionId,
|
|
101
|
-
eventType: event.eventType,
|
|
102
|
-
content: item.content,
|
|
103
|
-
vector: embedding.vector,
|
|
104
|
-
timestamp: event.timestamp.toISOString(),
|
|
105
|
-
metadata: event.metadata
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
successful.push(item.id);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Batch insert to vector store
|
|
112
|
-
if (records.length > 0) {
|
|
113
|
-
await this.vectorStore.upsertBatch(records);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Mark successful items as done
|
|
117
|
-
if (successful.length > 0) {
|
|
118
|
-
await this.eventStore.completeOutboxItems(successful);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Mark failed items
|
|
122
|
-
if (failed.length > 0) {
|
|
123
|
-
await this.eventStore.failOutboxItems(failed, 'Event not found');
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return successful.length;
|
|
127
|
-
} catch (error) {
|
|
128
|
-
// Mark all items as failed, but only if not stopping (DB might be closed)
|
|
129
|
-
if (!this.stopping) {
|
|
130
|
-
try {
|
|
131
|
-
const allIds = items.map(i => i.id);
|
|
132
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
133
|
-
await this.eventStore.failOutboxItems(allIds, errorMessage);
|
|
134
|
-
} catch (failError) {
|
|
135
|
-
// Database might be closed during shutdown, ignore
|
|
136
|
-
console.warn('Could not mark outbox items as failed (database may be closed)');
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
throw error;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Poll for new items
|
|
145
|
-
*/
|
|
146
|
-
private async poll(): Promise<void> {
|
|
147
|
-
if (!this.running || this.stopping) return;
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
await this.processBatch();
|
|
151
|
-
} catch (error) {
|
|
152
|
-
// Only log if not stopping (error during shutdown is expected)
|
|
153
|
-
if (!this.stopping) {
|
|
154
|
-
console.error('Vector worker error:', error);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Schedule next poll only if still running
|
|
159
|
-
if (this.running && !this.stopping) {
|
|
160
|
-
this.pollTimeout = setTimeout(() => this.poll(), this.config.pollIntervalMs);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Process all pending items (blocking)
|
|
166
|
-
*/
|
|
167
|
-
async processAll(): Promise<number> {
|
|
168
|
-
let totalProcessed = 0;
|
|
169
|
-
let processed: number;
|
|
170
|
-
|
|
171
|
-
do {
|
|
172
|
-
processed = await this.processBatch();
|
|
173
|
-
totalProcessed += processed;
|
|
174
|
-
} while (processed > 0);
|
|
175
|
-
|
|
176
|
-
return totalProcessed;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Check if worker is running
|
|
181
|
-
*/
|
|
182
|
-
isRunning(): boolean {
|
|
183
|
-
return this.running;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Create and start a vector worker
|
|
189
|
-
*/
|
|
190
|
-
export function createVectorWorker(
|
|
191
|
-
eventStore: EventStore,
|
|
192
|
-
vectorStore: VectorStore,
|
|
193
|
-
embedder: Embedder,
|
|
194
|
-
config?: Partial<WorkerConfig>
|
|
195
|
-
): VectorWorker {
|
|
196
|
-
const worker = new VectorWorker(eventStore, vectorStore, embedder, config);
|
|
197
|
-
return worker;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// ============================================================
|
|
201
|
-
// Vector Worker V2 - Extended for Task Entity System
|
|
202
|
-
// ============================================================
|
|
203
|
-
|
|
204
|
-
import { dbAll, type Database } from './db-wrapper.js';
|
|
205
|
-
import { VectorOutbox } from './vector-outbox.js';
|
|
206
|
-
import type { OutboxJob, OutboxItemKind } from './types.js';
|
|
207
|
-
|
|
208
|
-
export interface WorkerConfigV2 {
|
|
209
|
-
batchSize: number;
|
|
210
|
-
pollIntervalMs: number;
|
|
211
|
-
maxRetries: number;
|
|
212
|
-
embeddingVersion: string;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const DEFAULT_CONFIG_V2: WorkerConfigV2 = {
|
|
216
|
-
batchSize: 32,
|
|
217
|
-
pollIntervalMs: 1000,
|
|
218
|
-
maxRetries: 3,
|
|
219
|
-
embeddingVersion: 'v1'
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Content provider interface for different item kinds
|
|
224
|
-
*/
|
|
225
|
-
export interface ContentProvider {
|
|
226
|
-
getContent(itemKind: OutboxItemKind, itemId: string): Promise<{
|
|
227
|
-
content: string;
|
|
228
|
-
metadata: Record<string, unknown>;
|
|
229
|
-
} | null>;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Default content provider using database
|
|
234
|
-
*/
|
|
235
|
-
export class DefaultContentProvider implements ContentProvider {
|
|
236
|
-
constructor(private db: Database) {}
|
|
237
|
-
|
|
238
|
-
async getContent(itemKind: OutboxItemKind, itemId: string): Promise<{
|
|
239
|
-
content: string;
|
|
240
|
-
metadata: Record<string, unknown>;
|
|
241
|
-
} | null> {
|
|
242
|
-
switch (itemKind) {
|
|
243
|
-
case 'entry':
|
|
244
|
-
return this.getEntryContent(itemId);
|
|
245
|
-
case 'task_title':
|
|
246
|
-
return this.getTaskTitleContent(itemId);
|
|
247
|
-
case 'event':
|
|
248
|
-
return this.getEventContent(itemId);
|
|
249
|
-
default:
|
|
250
|
-
return null;
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
private async getEntryContent(entryId: string): Promise<{
|
|
255
|
-
content: string;
|
|
256
|
-
metadata: Record<string, unknown>;
|
|
257
|
-
} | null> {
|
|
258
|
-
const rows = await dbAll<Record<string, unknown>>(
|
|
259
|
-
this.db,
|
|
260
|
-
`SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,
|
|
261
|
-
[entryId]
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
if (rows.length === 0) return null;
|
|
265
|
-
|
|
266
|
-
const row = rows[0];
|
|
267
|
-
const contentJson = typeof row.content_json === 'string'
|
|
268
|
-
? JSON.parse(row.content_json)
|
|
269
|
-
: row.content_json;
|
|
270
|
-
|
|
271
|
-
return {
|
|
272
|
-
content: `${row.title}\n${JSON.stringify(contentJson)}`,
|
|
273
|
-
metadata: {
|
|
274
|
-
itemKind: 'entry',
|
|
275
|
-
entryType: row.entry_type
|
|
276
|
-
}
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
private async getTaskTitleContent(taskId: string): Promise<{
|
|
281
|
-
content: string;
|
|
282
|
-
metadata: Record<string, unknown>;
|
|
283
|
-
} | null> {
|
|
284
|
-
const rows = await dbAll<Record<string, unknown>>(
|
|
285
|
-
this.db,
|
|
286
|
-
`SELECT title, search_text, current_json FROM entities
|
|
287
|
-
WHERE entity_id = ? AND entity_type = 'task'`,
|
|
288
|
-
[taskId]
|
|
289
|
-
);
|
|
290
|
-
|
|
291
|
-
if (rows.length === 0) return null;
|
|
292
|
-
|
|
293
|
-
const row = rows[0];
|
|
294
|
-
return {
|
|
295
|
-
content: row.search_text as string || row.title as string,
|
|
296
|
-
metadata: {
|
|
297
|
-
itemKind: 'task_title',
|
|
298
|
-
entityType: 'task'
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
private async getEventContent(eventId: string): Promise<{
|
|
304
|
-
content: string;
|
|
305
|
-
metadata: Record<string, unknown>;
|
|
306
|
-
} | null> {
|
|
307
|
-
const rows = await dbAll<Record<string, unknown>>(
|
|
308
|
-
this.db,
|
|
309
|
-
`SELECT content, event_type, session_id FROM events WHERE id = ?`,
|
|
310
|
-
[eventId]
|
|
311
|
-
);
|
|
312
|
-
|
|
313
|
-
if (rows.length === 0) return null;
|
|
314
|
-
|
|
315
|
-
const row = rows[0];
|
|
316
|
-
return {
|
|
317
|
-
content: row.content as string,
|
|
318
|
-
metadata: {
|
|
319
|
-
itemKind: 'event',
|
|
320
|
-
eventType: row.event_type,
|
|
321
|
-
sessionId: row.session_id
|
|
322
|
-
}
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* Vector Worker V2 - Supports multiple item kinds
|
|
329
|
-
*/
|
|
330
|
-
export class VectorWorkerV2 {
|
|
331
|
-
private readonly outbox: VectorOutbox;
|
|
332
|
-
private readonly vectorStore: VectorStore;
|
|
333
|
-
private readonly embedder: Embedder;
|
|
334
|
-
private readonly contentProvider: ContentProvider;
|
|
335
|
-
private readonly config: WorkerConfigV2;
|
|
336
|
-
private running = false;
|
|
337
|
-
private stopping = false;
|
|
338
|
-
private pollTimeout: NodeJS.Timeout | null = null;
|
|
339
|
-
|
|
340
|
-
constructor(
|
|
341
|
-
db: Database,
|
|
342
|
-
vectorStore: VectorStore,
|
|
343
|
-
embedder: Embedder,
|
|
344
|
-
config: Partial<WorkerConfigV2> = {},
|
|
345
|
-
contentProvider?: ContentProvider
|
|
346
|
-
) {
|
|
347
|
-
this.outbox = new VectorOutbox(db, {
|
|
348
|
-
embeddingVersion: config.embeddingVersion ?? DEFAULT_CONFIG_V2.embeddingVersion,
|
|
349
|
-
maxRetries: config.maxRetries ?? DEFAULT_CONFIG_V2.maxRetries
|
|
350
|
-
});
|
|
351
|
-
this.vectorStore = vectorStore;
|
|
352
|
-
this.embedder = embedder;
|
|
353
|
-
this.config = { ...DEFAULT_CONFIG_V2, ...config };
|
|
354
|
-
this.contentProvider = contentProvider ?? new DefaultContentProvider(db);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Start the worker polling loop
|
|
359
|
-
*/
|
|
360
|
-
start(): void {
|
|
361
|
-
if (this.running) return;
|
|
362
|
-
this.running = true;
|
|
363
|
-
this.stopping = false;
|
|
364
|
-
this.poll();
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Stop the worker
|
|
369
|
-
*/
|
|
370
|
-
stop(): void {
|
|
371
|
-
this.running = false;
|
|
372
|
-
this.stopping = true;
|
|
373
|
-
if (this.pollTimeout) {
|
|
374
|
-
clearTimeout(this.pollTimeout);
|
|
375
|
-
this.pollTimeout = null;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* Process a single batch of outbox jobs
|
|
381
|
-
*/
|
|
382
|
-
async processBatch(): Promise<number> {
|
|
383
|
-
const jobs = await this.outbox.claimJobs(this.config.batchSize);
|
|
384
|
-
|
|
385
|
-
if (jobs.length === 0) {
|
|
386
|
-
return 0;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
let successCount = 0;
|
|
390
|
-
|
|
391
|
-
for (const job of jobs) {
|
|
392
|
-
try {
|
|
393
|
-
await this.processJob(job);
|
|
394
|
-
await this.outbox.markDone(job.jobId);
|
|
395
|
-
successCount++;
|
|
396
|
-
} catch (error) {
|
|
397
|
-
// Only try to mark as failed if not stopping (DB might be closed)
|
|
398
|
-
if (!this.stopping) {
|
|
399
|
-
try {
|
|
400
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
401
|
-
await this.outbox.markFailed(job.jobId, errorMessage);
|
|
402
|
-
} catch {
|
|
403
|
-
// Database might be closed during shutdown, ignore
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
return successCount;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Process a single job
|
|
414
|
-
*/
|
|
415
|
-
private async processJob(job: OutboxJob): Promise<void> {
|
|
416
|
-
// Get content
|
|
417
|
-
const contentData = await this.contentProvider.getContent(job.itemKind, job.itemId);
|
|
418
|
-
|
|
419
|
-
if (!contentData) {
|
|
420
|
-
// Item not found, mark as done (skip)
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// Generate embedding
|
|
425
|
-
const embedding = await this.embedder.embed(contentData.content);
|
|
426
|
-
|
|
427
|
-
// Upsert to vector store
|
|
428
|
-
const record: VectorRecord = {
|
|
429
|
-
id: `${job.itemKind}_${job.itemId}_${job.embeddingVersion}`,
|
|
430
|
-
eventId: job.itemKind === 'event' ? job.itemId : '',
|
|
431
|
-
sessionId: (contentData.metadata.sessionId as string) ?? '',
|
|
432
|
-
eventType: (contentData.metadata.eventType as string) ?? job.itemKind,
|
|
433
|
-
content: contentData.content,
|
|
434
|
-
vector: embedding.vector,
|
|
435
|
-
timestamp: new Date().toISOString(),
|
|
436
|
-
metadata: {
|
|
437
|
-
...contentData.metadata,
|
|
438
|
-
embeddingVersion: job.embeddingVersion
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
// Use idempotent upsert (delete + add)
|
|
443
|
-
await this.vectorStore.upsertBatch([record]);
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* Poll for new jobs
|
|
448
|
-
*/
|
|
449
|
-
private async poll(): Promise<void> {
|
|
450
|
-
if (!this.running || this.stopping) return;
|
|
451
|
-
|
|
452
|
-
try {
|
|
453
|
-
await this.processBatch();
|
|
454
|
-
} catch (error) {
|
|
455
|
-
// Only log if not stopping (error during shutdown is expected)
|
|
456
|
-
if (!this.stopping) {
|
|
457
|
-
console.error('Vector worker V2 error:', error);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
// Schedule next poll only if still running
|
|
462
|
-
if (this.running && !this.stopping) {
|
|
463
|
-
this.pollTimeout = setTimeout(() => this.poll(), this.config.pollIntervalMs);
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
/**
|
|
468
|
-
* Process all pending jobs (blocking)
|
|
469
|
-
*/
|
|
470
|
-
async processAll(): Promise<number> {
|
|
471
|
-
let totalProcessed = 0;
|
|
472
|
-
let processed: number;
|
|
473
|
-
|
|
474
|
-
do {
|
|
475
|
-
processed = await this.processBatch();
|
|
476
|
-
totalProcessed += processed;
|
|
477
|
-
} while (processed > 0);
|
|
478
|
-
|
|
479
|
-
return totalProcessed;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* Run reconciliation
|
|
484
|
-
*/
|
|
485
|
-
async reconcile(): Promise<{ recovered: number; retried: number }> {
|
|
486
|
-
return this.outbox.reconcile();
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Get metrics
|
|
491
|
-
*/
|
|
492
|
-
async getMetrics() {
|
|
493
|
-
return this.outbox.getMetrics();
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* Check if worker is running
|
|
498
|
-
*/
|
|
499
|
-
isRunning(): boolean {
|
|
500
|
-
return this.running;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* Get the outbox instance for direct access
|
|
505
|
-
*/
|
|
506
|
-
getOutbox(): VectorOutbox {
|
|
507
|
-
return this.outbox;
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* Create a Vector Worker V2 instance
|
|
513
|
-
*/
|
|
514
|
-
export function createVectorWorkerV2(
|
|
515
|
-
db: Database,
|
|
516
|
-
vectorStore: VectorStore,
|
|
517
|
-
embedder: Embedder,
|
|
518
|
-
config?: Partial<WorkerConfigV2>
|
|
519
|
-
): VectorWorkerV2 {
|
|
520
|
-
return new VectorWorkerV2(db, vectorStore, embedder, config);
|
|
521
|
-
}
|