memento-mcp-server 1.24.0-d → 1.24.0-e
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.en.md +13 -13
- package/README.md +5 -5
- package/node_modules/@memento/core/dist/bootstrap.d.ts +5 -0
- package/node_modules/@memento/core/dist/bootstrap.d.ts.map +1 -1
- package/node_modules/@memento/core/dist/bootstrap.js +109 -7
- package/node_modules/@memento/core/dist/bootstrap.js.map +1 -1
- package/node_modules/@memento/core/dist/domains/embedding/services/embedding-migration-service.d.ts +6 -0
- package/node_modules/@memento/core/dist/domains/embedding/services/embedding-migration-service.d.ts.map +1 -1
- package/node_modules/@memento/core/dist/domains/embedding/services/embedding-migration-service.js +101 -62
- package/node_modules/@memento/core/dist/domains/embedding/services/embedding-migration-service.js.map +1 -1
- package/node_modules/@memento/core/dist/domains/memory/tools/remember-tool.js +1 -1
- package/node_modules/@memento/core/dist/domains/monitoring/services/runtime-diagnostics-logger.d.ts +9 -0
- package/node_modules/@memento/core/dist/domains/monitoring/services/runtime-diagnostics-logger.d.ts.map +1 -0
- package/node_modules/@memento/core/dist/domains/monitoring/services/runtime-diagnostics-logger.js +32 -0
- package/node_modules/@memento/core/dist/domains/monitoring/services/runtime-diagnostics-logger.js.map +1 -0
- package/node_modules/@memento/core/dist/infrastructure/database/database-lock-monitor.d.ts +4 -1
- package/node_modules/@memento/core/dist/infrastructure/database/database-lock-monitor.d.ts.map +1 -1
- package/node_modules/@memento/core/dist/infrastructure/database/database-lock-monitor.js +41 -1
- package/node_modules/@memento/core/dist/infrastructure/database/database-lock-monitor.js.map +1 -1
- package/node_modules/@memento/core/dist/infrastructure/database/wal-checkpoint-scheduler.d.ts +4 -1
- package/node_modules/@memento/core/dist/infrastructure/database/wal-checkpoint-scheduler.d.ts.map +1 -1
- package/node_modules/@memento/core/dist/infrastructure/database/wal-checkpoint-scheduler.js +62 -3
- package/node_modules/@memento/core/dist/infrastructure/database/wal-checkpoint-scheduler.js.map +1 -1
- package/node_modules/@memento/core/dist/infrastructure/scheduler/batch-scheduler.d.ts +5 -0
- package/node_modules/@memento/core/dist/infrastructure/scheduler/batch-scheduler.d.ts.map +1 -1
- package/node_modules/@memento/core/dist/infrastructure/scheduler/batch-scheduler.js +47 -0
- package/node_modules/@memento/core/dist/infrastructure/scheduler/batch-scheduler.js.map +1 -1
- package/node_modules/@memento/core/dist/shared/config/environment.d.ts.map +1 -1
- package/node_modules/@memento/core/dist/shared/config/environment.js +6 -0
- package/node_modules/@memento/core/dist/shared/config/environment.js.map +1 -1
- package/node_modules/@memento/core/dist/shared/config/index.d.ts.map +1 -1
- package/node_modules/@memento/core/dist/shared/config/index.js +6 -0
- package/node_modules/@memento/core/dist/shared/config/index.js.map +1 -1
- package/node_modules/@memento/core/dist/shared/types/index.d.ts +6 -0
- package/node_modules/@memento/core/dist/shared/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/scripts/__tests__/check-magic-numbers.spec.ts +3 -1
- package/scripts/__tests__/count-console-logs.spec.ts +2 -2
- package/scripts/__tests__/supports-tsx-subprocess.ts +22 -0
- package/scripts/collect-docker-diagnostics.sh +60 -0
package/README.en.md
CHANGED
|
@@ -21,8 +21,7 @@ Memento MCP Server is a Model Context Protocol (MCP) server that helps AI Agents
|
|
|
21
21
|
- **Memory Pinning**: Pin/unpin important memories
|
|
22
22
|
- **Memory Deletion**: Soft/hard deletion
|
|
23
23
|
- **Anchor System**: Set important memories as anchors for context management
|
|
24
|
-
|
|
25
|
-
- **Memory Conversion**: Automatic conversion from Episodic Memory to Semantic Memory
|
|
24
|
+
> **Note**: Anchor recovery, embedding migration, Episodic → Semantic conversion, and meta memory statistics are exposed through the HTTP Management API, not MCP tools.
|
|
26
25
|
|
|
27
26
|
### 🔍 Advanced Search
|
|
28
27
|
- **FTS5 Text Search**: SQLite's Full-Text Search
|
|
@@ -39,7 +38,7 @@ Memento MCP Server is a Model Context Protocol (MCP) server that helps AI Agents
|
|
|
39
38
|
- **Auto Cleanup**: Automated soft/hard deletion
|
|
40
39
|
|
|
41
40
|
### 📊 Performance Monitoring (HTTP Management API)
|
|
42
|
-
- **Security**: HTTP
|
|
41
|
+
- **Security**: HTTP server splits browser-session and header-based trust. `/auth/session` starts the cookie-backed browser flow; `/admin` and `/api` require a browser session; `/api/v1/quality`, `/tools`, and `/mcp` require `Authorization: Bearer` or `X-API-Key`. See [docs/reference/en/security.md](docs/reference/en/security.md).
|
|
43
42
|
- **Real-time Metrics**: Database, search, memory performance monitoring
|
|
44
43
|
- **Real-time Alerts**: Automatic performance checks every 30 seconds with threshold-based alerts
|
|
45
44
|
- **Error Logging**: Structured error logging and statistics collection
|
|
@@ -49,9 +48,10 @@ Memento MCP Server is a Model Context Protocol (MCP) server that helps AI Agents
|
|
|
49
48
|
|
|
50
49
|
### 🔗 Memory Graph View (Browser)
|
|
51
50
|
|
|
52
|
-
After starting the HTTP server, visualize semantic relationships between memories as an interactive graph in your browser.
|
|
51
|
+
After starting the HTTP server, you can visualize semantic relationships between memories as an interactive graph in your browser. `/dashboard` is the preferred entry point for the full admin flow, and opening `/graph` directly now offers the same `/auth/session` re-auth path so signed-out users can recover the session in place.
|
|
53
52
|
|
|
54
53
|
```
|
|
54
|
+
http://localhost:9001/dashboard
|
|
55
55
|
http://localhost:9001/graph
|
|
56
56
|
```
|
|
57
57
|
|
|
@@ -166,8 +166,7 @@ const results = await client.callTool({
|
|
|
166
166
|
|
|
167
167
|
### MCP Tools (Core 14)
|
|
168
168
|
|
|
169
|
-
> **Important**: MCP client exposes 14 core memory management functions.
|
|
170
|
-
> Management functions are separated into HTTP API endpoints.
|
|
169
|
+
> **Important**: MCP client exposes 14 core memory management functions. Operational functions are exposed through the HTTP Management API below, not through MCP.
|
|
171
170
|
|
|
172
171
|
#### Basic Memory Management (7)
|
|
173
172
|
| Tool | Description | Parameters |
|
|
@@ -180,21 +179,22 @@ const results = await client.callTool({
|
|
|
180
179
|
| `get_memory_neighbors` | Find neighbor memories | memory_id, limit |
|
|
181
180
|
| `memory_injection` | Generate context injection prompt | query, token_budget |
|
|
182
181
|
|
|
183
|
-
#### Anchor System (
|
|
182
|
+
#### Anchor System (4)
|
|
184
183
|
| Tool | Description | Parameters |
|
|
185
184
|
|------|-------------|------------|
|
|
186
185
|
| `set_anchor` | Set anchor | memory_id, slot |
|
|
187
186
|
| `get_anchor` | Get anchor | slot |
|
|
188
187
|
| `search_local` | Search around anchor | slot, query, limit |
|
|
189
188
|
| `clear_anchor` | Clear anchor | slot |
|
|
190
|
-
| `restore_anchors` | Restore anchors | agent_id |
|
|
191
189
|
|
|
192
|
-
####
|
|
190
|
+
#### Procedural Memory (3)
|
|
193
191
|
| Tool | Description | Parameters |
|
|
194
192
|
|------|-------------|------------|
|
|
195
|
-
| `
|
|
196
|
-
| `
|
|
197
|
-
| `
|
|
193
|
+
| `remember_procedure` | Store procedural memory | content, workflow_name, skill_name, steps, etc. |
|
|
194
|
+
| `procedural_diff` | Compare procedural memory versions | left_id, right_id |
|
|
195
|
+
| `procedural_rollback` | Roll back procedural memory to a previous version | current_id, target_version_id |
|
|
196
|
+
|
|
197
|
+
**HTTP-only (not MCP)**: `restore_anchors`, `migrate_embeddings`, `convert_episodic_to_semantic`, `get_meta_memory_stats` - see the HTTP Management API below.
|
|
198
198
|
|
|
199
199
|
### HTTP Management API
|
|
200
200
|
|
|
@@ -333,7 +333,7 @@ npm run test -- --coverage
|
|
|
333
333
|
### M1: Personal Use (Current Implementation)
|
|
334
334
|
- **Storage**: better-sqlite3 embedded
|
|
335
335
|
- **Index**: FTS5 + sqlite-vec
|
|
336
|
-
- **Authentication**:
|
|
336
|
+
- **Authentication**: Split browser-session and header-based trust model (`/auth/session` starts the cookie-backed browser flow; `/admin` and `/api` require a browser session; `/api/v1/quality`, `/tools`, and `/mcp` require `Authorization: Bearer` or `X-API-Key`)
|
|
337
337
|
- **Operation**: Local execution
|
|
338
338
|
- **MCP Client**: Exposes 14 core tools
|
|
339
339
|
- **Management Functions**: Separated into HTTP API
|
package/README.md
CHANGED
|
@@ -40,8 +40,7 @@ Memento MCP Server는 AI Agent가 장기 기억을 저장하고 관리할 수
|
|
|
40
40
|
- **기억 고정**: 중요한 기억 고정/해제
|
|
41
41
|
- **기억 삭제**: 소프트/하드 삭제
|
|
42
42
|
- **앵커 시스템**: 중요한 기억을 앵커로 설정하여 컨텍스트 관리
|
|
43
|
-
|
|
44
|
-
- **기억 변환**: Episodic Memory를 Semantic Memory로 자동 변환
|
|
43
|
+
> **참고**: 앵커 복원, 임베딩 마이그레이션, Episodic → Semantic 변환, 메타 메모리 통계는 MCP 도구가 아니라 HTTP 관리 API로만 제공됩니다.
|
|
45
44
|
|
|
46
45
|
### 🔍 고급 검색
|
|
47
46
|
- **FTS5 텍스트 검색**: SQLite의 Full-Text Search
|
|
@@ -59,7 +58,7 @@ Memento MCP Server는 AI Agent가 장기 기억을 저장하고 관리할 수
|
|
|
59
58
|
- **자동 정리**: 소프트/하드 삭제 자동화
|
|
60
59
|
|
|
61
60
|
### 📊 성능 모니터링 (HTTP 관리 API)
|
|
62
|
-
- **보안**: HTTP
|
|
61
|
+
- **보안**: HTTP 서버는 브라우저 세션과 헤더 기반 신뢰 경계를 분리합니다. `/auth/session`은 쿠키 기반 브라우저 세션을 시작하고, `/admin`과 `/api`는 브라우저 세션이 필요하며, `/api/v1/quality`, `/tools`, `/mcp`는 `Authorization: Bearer` 또는 `X-API-Key`가 필요합니다. 자세한 내용은 [docs/reference/ko/security.md](docs/reference/ko/security.md)를 참고하세요.
|
|
63
62
|
- **실시간 메트릭**: 데이터베이스, 검색, 메모리 성능 모니터링
|
|
64
63
|
- **실시간 알림**: 30초마다 자동 성능 체크 및 임계값 기반 알림
|
|
65
64
|
- **에러 로깅**: 구조화된 에러 로깅 및 통계 수집
|
|
@@ -69,9 +68,10 @@ Memento MCP Server는 AI Agent가 장기 기억을 저장하고 관리할 수
|
|
|
69
68
|
|
|
70
69
|
### 🔗 메모리 그래프 뷰 (브라우저)
|
|
71
70
|
|
|
72
|
-
HTTP 서버 실행 후 브라우저에서 기억들의 의미적 관계를 그래프로 시각화할 수 있습니다.
|
|
71
|
+
HTTP 서버 실행 후 브라우저에서 기억들의 의미적 관계를 그래프로 시각화할 수 있습니다. 전체 관리 흐름은 `/dashboard`에서 여는 편이 가장 안전하며, `/graph`를 직접 열어도 동일한 `/auth/session` 기반 재인증 패널로 세션을 시작하거나 복구할 수 있습니다.
|
|
73
72
|
|
|
74
73
|
```
|
|
74
|
+
http://localhost:9001/dashboard
|
|
75
75
|
http://localhost:9001/graph
|
|
76
76
|
```
|
|
77
77
|
|
|
@@ -528,7 +528,7 @@ npm run test -- --coverage
|
|
|
528
528
|
### M1: 개인용 (현재 구현)
|
|
529
529
|
- **스토리지**: better-sqlite3 임베디드
|
|
530
530
|
- **인덱스**: FTS5 + sqlite-vec
|
|
531
|
-
- **인증**:
|
|
531
|
+
- **인증**: 브라우저 세션 + 헤더 기반 분리 신뢰 모델 (/auth/session은 쿠키 세션, /admin·/api는 브라우저 세션, /api/v1/quality·/tools·/mcp는 Authorization Bearer 또는 X-API-Key)
|
|
532
532
|
- **운영**: 로컬 실행
|
|
533
533
|
- **MCP 클라이언트**: 핵심 14개 도구 노출
|
|
534
534
|
- **관리 기능**: HTTP API로 분리
|
|
@@ -25,6 +25,7 @@ import { DatabaseLockMonitor } from './infrastructure/database/database-lock-mon
|
|
|
25
25
|
import { MetaMemoryService } from './domains/memory/services/meta-memory-service.js';
|
|
26
26
|
import { IntrospectionScanCache } from './domains/memory/services/introspection-scan-cache.js';
|
|
27
27
|
import { TelemetryService } from './domains/telemetry/services/telemetry-service.js';
|
|
28
|
+
import { RuntimeDiagnosticsLogger } from './domains/monitoring/services/runtime-diagnostics-logger.js';
|
|
28
29
|
export interface ServerServices {
|
|
29
30
|
searchEngine: SearchEngine;
|
|
30
31
|
hybridSearchEngine: HybridSearchEngine;
|
|
@@ -50,6 +51,10 @@ export interface ServerServices {
|
|
|
50
51
|
sleepConsolidationService?: SleepConsolidationService;
|
|
51
52
|
/** 006 observability telemetry */
|
|
52
53
|
telemetryService?: TelemetryService;
|
|
54
|
+
/** 런타임 샘플 및 부트스트랩 이벤트 진단 로거 */
|
|
55
|
+
runtimeDiagnosticsLogger?: RuntimeDiagnosticsLogger;
|
|
56
|
+
/** diagnostics sampler cleanup hook */
|
|
57
|
+
runtimeDiagnosticsSamplerCleanup?: () => Promise<void>;
|
|
53
58
|
}
|
|
54
59
|
export declare function initializeServices(db: Database.Database): Promise<ServerServices>;
|
|
55
60
|
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,qDAAqD,CAAC;AAEzF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4DAA4D,CAAC;AACrG,OAAO,EAAE,qBAAqB,EAAE,MAAM,sDAAsD,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,wDAAwD,CAAC;AAC7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4DAA4D,CAAC;AACrG,OAAO,EAAE,sBAAsB,EAAuB,MAAM,oCAAoC,CAAC;AAEjG,OAAO,EAAE,aAAa,EAAE,MAAM,oDAAoD,CAAC;AAGnF,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AAEpF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kDAAkD,CAAC;AACxF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sDAAsD,CAAC;AACvG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qDAAqD,CAAC;AAC9F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AAI1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,qDAAqD,CAAC;AAE5F,OAAO,EAAE,yBAAyB,EAAE,MAAM,iEAAiE,CAAC;AAG5G,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,oDAAoD,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAG/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,qDAAqD,CAAC;AAEzF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4DAA4D,CAAC;AACrG,OAAO,EAAE,qBAAqB,EAAE,MAAM,sDAAsD,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,wDAAwD,CAAC;AAC7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4DAA4D,CAAC;AACrG,OAAO,EAAE,sBAAsB,EAAuB,MAAM,oCAAoC,CAAC;AAEjG,OAAO,EAAE,aAAa,EAAE,MAAM,oDAAoD,CAAC;AAGnF,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AAEpF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kDAAkD,CAAC;AACxF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sDAAsD,CAAC;AACvG,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qDAAqD,CAAC;AAC9F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AAI1F,OAAO,EAAE,qBAAqB,EAAE,MAAM,qDAAqD,CAAC;AAE5F,OAAO,EAAE,yBAAyB,EAAE,MAAM,iEAAiE,CAAC;AAG5G,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,oDAAoD,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAG/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AACrF,OAAO,EAAE,wBAAwB,EAAE,MAAM,6DAA6D,CAAC;AAEvG,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,gBAAgB,EAAE,sBAAsB,CAAC;IACzC,uBAAuB,EAAE,uBAAuB,CAAC;IACjD,kBAAkB,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;IAC7D,iBAAiB,EAAE,kBAAkB,CAAC;IACtC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,uBAAuB,EAAE,uBAAuB,CAAC;IACjD,yBAAyB,CAAC,EAAE,0BAA0B,CAAC;IACvD,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,aAAa,EAAE,aAAa,CAAC;IAC7B,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,CAAC,EAAE,gBAAgB,CAAC;IACnC,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,kBAAkB,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;IAC7D,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,mGAAmG;IACnG,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAChD,8BAA8B;IAC9B,yBAAyB,CAAC,EAAE,yBAAyB,CAAC;IACtD,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,+BAA+B;IAC/B,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,uCAAuC;IACvC,gCAAgC,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,CAkQvF"}
|
|
@@ -34,6 +34,7 @@ import { MetaMemoryService } from './domains/memory/services/meta-memory-service
|
|
|
34
34
|
import { IntrospectionScanCache } from './domains/memory/services/introspection-scan-cache.js';
|
|
35
35
|
import { TelemetryRepository } from './domains/telemetry/repositories/telemetry-repository.js';
|
|
36
36
|
import { TelemetryService } from './domains/telemetry/services/telemetry-service.js';
|
|
37
|
+
import { RuntimeDiagnosticsLogger } from './domains/monitoring/services/runtime-diagnostics-logger.js';
|
|
37
38
|
export async function initializeServices(db) {
|
|
38
39
|
try {
|
|
39
40
|
const searchEngine = new SearchEngine();
|
|
@@ -64,6 +65,12 @@ export async function initializeServices(db) {
|
|
|
64
65
|
await reflexionWorker.start();
|
|
65
66
|
const performanceMonitor = getPerformanceMonitor();
|
|
66
67
|
performanceMonitor.initialize(db);
|
|
68
|
+
const runtimeDiagnosticsLogger = new RuntimeDiagnosticsLogger(mementoConfig.diagnosticsEnabled, mementoConfig.diagnosticsLogDir);
|
|
69
|
+
await runtimeDiagnosticsLogger.writeEvent({
|
|
70
|
+
type: 'bootstrap_start',
|
|
71
|
+
timestamp: new Date().toISOString(),
|
|
72
|
+
diagnosticsEnabled: mementoConfig.diagnosticsEnabled
|
|
73
|
+
});
|
|
67
74
|
const walCheckpointScheduler = new WalCheckpointScheduler(db, {
|
|
68
75
|
intervalMs: mementoConfig.walCheckpointIntervalMs,
|
|
69
76
|
walSizeWarningThreshold: mementoConfig.walSizeWarningThreshold,
|
|
@@ -71,16 +78,21 @@ export async function initializeServices(db) {
|
|
|
71
78
|
useDedicatedConnection: mementoConfig.walCheckpointUseDedicatedConnection,
|
|
72
79
|
maxRetries: mementoConfig.walCheckpointMaxRetries,
|
|
73
80
|
retryBackoffMs: mementoConfig.walCheckpointRetryBackoffMs
|
|
74
|
-
}, logger, performanceMonitor);
|
|
81
|
+
}, logger, performanceMonitor, runtimeDiagnosticsLogger);
|
|
75
82
|
const databaseLockMonitor = new DatabaseLockMonitor(db, {
|
|
76
83
|
intervalMs: mementoConfig.lockMonitorIntervalMs,
|
|
77
84
|
warningThresholdMs: mementoConfig.lockMonitorWarningThresholdMs,
|
|
78
85
|
dangerThresholdMs: mementoConfig.lockMonitorDangerThresholdMs,
|
|
79
86
|
criticalThresholdMs: mementoConfig.lockMonitorCriticalThresholdMs
|
|
80
|
-
}, logger, performanceMonitor, walCheckpointScheduler);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
}, logger, performanceMonitor, walCheckpointScheduler, runtimeDiagnosticsLogger);
|
|
88
|
+
if (mementoConfig.walCheckpointEnabled) {
|
|
89
|
+
walCheckpointScheduler.start();
|
|
90
|
+
logger.info('WAL 체크포인트 스케줄러 시작됨');
|
|
91
|
+
}
|
|
92
|
+
if (mementoConfig.dbLockMonitorEnabled) {
|
|
93
|
+
databaseLockMonitor.start();
|
|
94
|
+
logger.info('데이터베이스 락 모니터 시작됨');
|
|
95
|
+
}
|
|
84
96
|
let consolidationScoreService;
|
|
85
97
|
const writeCoalescingManager = new WriteCoalescingManager(1000, async (writes) => {
|
|
86
98
|
if (!db || writes.length === 0)
|
|
@@ -128,6 +140,7 @@ export async function initializeServices(db) {
|
|
|
128
140
|
const introspectionScanCache = new IntrospectionScanCache();
|
|
129
141
|
const telemetryRepository = new TelemetryRepository(db);
|
|
130
142
|
const batchScheduler = getBatchScheduler();
|
|
143
|
+
batchScheduler.setDiagnosticsLogger(runtimeDiagnosticsLogger);
|
|
131
144
|
batchScheduler.setTelemetryCleanupRepository(telemetryRepository);
|
|
132
145
|
const telemetryService = new TelemetryService(telemetryRepository, () => getBatchScheduler());
|
|
133
146
|
batchScheduler.setIntrospectionScanCache(introspectionScanCache);
|
|
@@ -137,7 +150,94 @@ export async function initializeServices(db) {
|
|
|
137
150
|
telemetryService
|
|
138
151
|
});
|
|
139
152
|
batchScheduler.setSleepConsolidationService(sleepConsolidationService);
|
|
140
|
-
|
|
153
|
+
if (mementoConfig.batchSchedulerEnabled) {
|
|
154
|
+
await batchScheduler.start(db, reflexionWorker);
|
|
155
|
+
}
|
|
156
|
+
let runtimeDiagnosticsSamplerCleanup;
|
|
157
|
+
if (mementoConfig.diagnosticsEnabled) {
|
|
158
|
+
let runtimeDiagnosticsSamplerStopped = false;
|
|
159
|
+
let runtimeDiagnosticsSamplerInFlight = null;
|
|
160
|
+
let runtimeDiagnosticsSamplerTimer = null;
|
|
161
|
+
const scheduleRuntimeDiagnosticsSampler = () => {
|
|
162
|
+
if (runtimeDiagnosticsSamplerStopped) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
runtimeDiagnosticsSamplerTimer = setTimeout(() => {
|
|
166
|
+
runtimeDiagnosticsSamplerTimer = null;
|
|
167
|
+
void runRuntimeDiagnosticsSampler();
|
|
168
|
+
}, mementoConfig.diagnosticsIntervalMs);
|
|
169
|
+
runtimeDiagnosticsSamplerTimer.unref?.();
|
|
170
|
+
};
|
|
171
|
+
const runRuntimeDiagnosticsSampler = async () => {
|
|
172
|
+
if (runtimeDiagnosticsSamplerStopped) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const currentRun = (async () => {
|
|
176
|
+
if (runtimeDiagnosticsSamplerStopped) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
const batchSchedulerStatus = batchScheduler.getStatus();
|
|
181
|
+
await runtimeDiagnosticsLogger.writeSample({
|
|
182
|
+
type: 'runtime_sample',
|
|
183
|
+
timestamp: new Date().toISOString(),
|
|
184
|
+
memory: process.memoryUsage(),
|
|
185
|
+
uptime: process.uptime(),
|
|
186
|
+
batchScheduler: {
|
|
187
|
+
isRunning: batchSchedulerStatus.isRunning,
|
|
188
|
+
activeJobs: batchSchedulerStatus.activeJobs ?? [],
|
|
189
|
+
uptime: batchSchedulerStatus.uptime ?? 0,
|
|
190
|
+
lastExecution: batchSchedulerStatus.lastExecution
|
|
191
|
+
? Object.fromEntries(Array.from(batchSchedulerStatus.lastExecution.entries()).map(([jobName, executedAt]) => [
|
|
192
|
+
jobName,
|
|
193
|
+
executedAt.toISOString()
|
|
194
|
+
]))
|
|
195
|
+
: undefined,
|
|
196
|
+
totalExecutions: batchSchedulerStatus.totalExecutions
|
|
197
|
+
? Object.fromEntries(batchSchedulerStatus.totalExecutions.entries())
|
|
198
|
+
: undefined,
|
|
199
|
+
errorCount: batchSchedulerStatus.errorCount
|
|
200
|
+
? Object.fromEntries(batchSchedulerStatus.errorCount.entries())
|
|
201
|
+
: undefined
|
|
202
|
+
},
|
|
203
|
+
walCheckpointEnabled: mementoConfig.walCheckpointEnabled,
|
|
204
|
+
dbLockMonitorEnabled: mementoConfig.dbLockMonitorEnabled
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
try {
|
|
209
|
+
logger.error('런타임 진단 샘플 기록 실패', {
|
|
210
|
+
error: error instanceof Error ? error.message : String(error)
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// diagnostics best-effort: sampler failure must not abort bootstrap
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
})();
|
|
218
|
+
runtimeDiagnosticsSamplerInFlight = currentRun;
|
|
219
|
+
try {
|
|
220
|
+
await currentRun;
|
|
221
|
+
}
|
|
222
|
+
finally {
|
|
223
|
+
if (runtimeDiagnosticsSamplerInFlight === currentRun) {
|
|
224
|
+
runtimeDiagnosticsSamplerInFlight = null;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (!runtimeDiagnosticsSamplerStopped) {
|
|
228
|
+
scheduleRuntimeDiagnosticsSampler();
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
scheduleRuntimeDiagnosticsSampler();
|
|
232
|
+
runtimeDiagnosticsSamplerCleanup = async () => {
|
|
233
|
+
runtimeDiagnosticsSamplerStopped = true;
|
|
234
|
+
if (runtimeDiagnosticsSamplerTimer) {
|
|
235
|
+
clearTimeout(runtimeDiagnosticsSamplerTimer);
|
|
236
|
+
runtimeDiagnosticsSamplerTimer = null;
|
|
237
|
+
}
|
|
238
|
+
await runtimeDiagnosticsSamplerInFlight;
|
|
239
|
+
};
|
|
240
|
+
}
|
|
141
241
|
return {
|
|
142
242
|
searchEngine,
|
|
143
243
|
hybridSearchEngine,
|
|
@@ -159,7 +259,9 @@ export async function initializeServices(db) {
|
|
|
159
259
|
batchScheduler,
|
|
160
260
|
introspectionScanCache,
|
|
161
261
|
sleepConsolidationService,
|
|
162
|
-
telemetryService
|
|
262
|
+
telemetryService,
|
|
263
|
+
runtimeDiagnosticsLogger,
|
|
264
|
+
runtimeDiagnosticsSamplerCleanup
|
|
163
265
|
};
|
|
164
266
|
}
|
|
165
267
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,qDAAqD,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qDAAqD,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4DAA4D,CAAC;AACrG,OAAO,EAAE,qBAAqB,EAAE,MAAM,sDAAsD,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,wDAAwD,CAAC;AAC7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4DAA4D,CAAC;AACrG,OAAO,EAAE,sBAAsB,EAAuB,MAAM,oCAAoC,CAAC;AACjG,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oDAAoD,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0DAA0D,CAAC;AAC9F,OAAO,EAAE,mBAAmB,EAAE,MAAM,2DAA2D,CAAC;AAChG,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAKrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qDAAqD,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iEAAiE,CAAC;AAC5G,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,oDAAoD,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAE/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,0DAA0D,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,8CAA8C,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,qDAAqD,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qDAAqD,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4DAA4D,CAAC;AACrG,OAAO,EAAE,qBAAqB,EAAE,MAAM,sDAAsD,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,MAAM,wDAAwD,CAAC;AAC7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4DAA4D,CAAC;AACrG,OAAO,EAAE,sBAAsB,EAAuB,MAAM,oCAAoC,CAAC;AACjG,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oDAAoD,CAAC;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0DAA0D,CAAC;AAC9F,OAAO,EAAE,mBAAmB,EAAE,MAAM,2DAA2D,CAAC;AAChG,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAKrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qDAAqD,CAAC;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,iEAAiE,CAAC;AAC5G,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,oDAAoD,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAE/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,0DAA0D,CAAC;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAC;AACrF,OAAO,EAAE,wBAAwB,EAAE,MAAM,6DAA6D,CAAC;AAiCvG,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAqB;IAC5D,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;QACxC,MAAM,gBAAgB,GAAG,IAAI,sBAAsB,EAAE,CAAC;QACtD,+DAA+D;QAC/D,MAAM,qBAAqB,GAAG,IAAI,sBAAsB,EAAE,CAAC;QAC3D,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,mBAAmB,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC;QAC9F,MAAM,uBAAuB,GAAG,IAAI,uBAAuB,EAAE,CAAC;QAC9D,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACpD,MAAM,mBAAmB,GAAG,IAAI,mBAAmB,EAAE,CAAC;QACtD,MAAM,uBAAuB,GAAG,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC;QACtE,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;QACxE,MAAM,kBAAkB,GAAG,qBAAqB,EAAE,CAAC;QACnD,MAAM,mBAAmB,GAAG,IAAI,mBAAmB,CAAC,kBAAkB,EAAE;YACtE,EAAE;YACF,kBAAkB;YAClB,kBAAkB;SACnB,CAAC,CAAC;QACH,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,kBAAkB,EAAE,mBAAmB,EAAE;YAC/E,EAAE;YACF,mBAAmB;SACpB,CAAC,CAAC;QACH,MAAM,kBAAkB,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QAChD,MAAM,iBAAiB,GAAG,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;QAChD,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,iBAAiB,CAAC,CAAC;QAC/D,MAAM,eAAe,CAAC,UAAU,EAAE,CAAC;QACnC,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;QACjE,MAAM,eAAe,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,kBAAkB,GAAG,qBAAqB,EAAE,CAAC;QACnD,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,wBAAwB,GAAG,IAAI,wBAAwB,CAC3D,aAAa,CAAC,kBAAkB,EAChC,aAAa,CAAC,iBAAiB,CAChC,CAAC;QACF,MAAM,wBAAwB,CAAC,UAAU,CAAC;YACxC,IAAI,EAAE,iBAAiB;YACvB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,kBAAkB,EAAE,aAAa,CAAC,kBAAkB;SACrD,CAAC,CAAC;QACH,MAAM,sBAAsB,GAAG,IAAI,sBAAsB,CACvD,EAAE,EACF;YACE,UAAU,EAAE,aAAa,CAAC,uBAAuB;YACjD,uBAAuB,EAAE,aAAa,CAAC,uBAAuB;YAC9D,sBAAsB,EAAE,aAAa,CAAC,sBAAsB;YAC5D,sBAAsB,EAAE,aAAa,CAAC,mCAAmC;YACzE,UAAU,EAAE,aAAa,CAAC,uBAAuB;YACjD,cAAc,EAAE,aAAa,CAAC,2BAA2B;SAC1D,EACD,MAAM,EACN,kBAAkB,EAClB,wBAAwB,CACzB,CAAC;QACF,MAAM,mBAAmB,GAAG,IAAI,mBAAmB,CACjD,EAAE,EACF;YACE,UAAU,EAAE,aAAa,CAAC,qBAAqB;YAC/C,kBAAkB,EAAE,aAAa,CAAC,6BAA6B;YAC/D,iBAAiB,EAAE,aAAa,CAAC,4BAA4B;YAC7D,mBAAmB,EAAE,aAAa,CAAC,8BAA8B;SAClE,EACD,MAAM,EACN,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,CACzB,CAAC;QACF,IAAI,aAAa,CAAC,oBAAoB,EAAE,CAAC;YACvC,sBAAsB,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,aAAa,CAAC,oBAAoB,EAAE,CAAC;YACvC,mBAAmB,CAAC,KAAK,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,yBAAgE,CAAC;QACrE,MAAM,sBAAsB,GAAG,IAAI,sBAAsB,CACvD,IAAI,EACJ,KAAK,EAAE,MAAwB,EAAE,EAAE;YACjC,IAAI,CAAC,EAAE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YACvC,MAAM,SAAS,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,aAAa,CAAC,cAAc,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;oBACvD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;wBAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;wBAC7B,MAAM,MAAM,GAAe,EAAE,CAAC;wBAC9B,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;4BAC5C,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;4BACjC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;wBACzC,CAAC;wBACD,IAAI,KAAK,CAAC,MAAM,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;4BAChD,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;4BACrC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;wBAC7C,CAAC;wBACD,IAAI,aAAa,CAAC,yBAAyB,EAAE,CAAC;4BAC5C,IAAI,KAAK,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gCACvC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gCAC5B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;4BACpC,CAAC;4BACD,IAAI,KAAK,CAAC,MAAM,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;gCACnD,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;gCACxC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;4BAChD,CAAC;wBACH,CAAC;wBACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACvB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;4BAC5B,aAAa,CAAC,GAAG,CACf,SAAS,EACT,0BAA0B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAC3D,MAAM,CACP,CAAC;wBACJ,CAAC;oBACH,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,iCAAiC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1G,CAAC;QACH,CAAC,CACF,CAAC;QACF,IAAI,aAAa,CAAC,yBAAyB,EAAE,CAAC;YAC5C,yBAAyB,GAAG,IAAI,yBAAyB,EAAE,CAAC;QAC9D,CAAC;QACD,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,EAAE,EAAE,sBAAsB,CAAC,CAAC;QAC5E,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACxC,MAAM,sBAAsB,GAAG,IAAI,sBAAsB,EAAE,CAAC;QAC5D,MAAM,mBAAmB,GAAG,IAAI,mBAAmB,CAAC,EAAE,CAAC,CAAC;QACxD,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAC;QAC3C,cAAc,CAAC,oBAAoB,CAAC,wBAAwB,CAAC,CAAC;QAC9D,cAAc,CAAC,6BAA6B,CAAC,mBAAmB,CAAC,CAAC;QAClE,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC;QAC9F,cAAc,CAAC,yBAAyB,CAAC,sBAAsB,CAAC,CAAC;QACjE,MAAM,yBAAyB,GAAG,IAAI,yBAAyB,CAAC,EAAE,EAAE;YAClE,aAAa,EAAE,mBAAmB,CAAC,EAAE,CAAC;YACtC,sBAAsB,EAAE,gBAAgB;YACxC,gBAAgB;SACjB,CAAC,CAAC;QACH,cAAc,CAAC,4BAA4B,CAAC,yBAAyB,CAAC,CAAC;QACvE,IAAI,aAAa,CAAC,qBAAqB,EAAE,CAAC;YACxC,MAAM,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,gCAAmE,CAAC;QACxE,IAAI,aAAa,CAAC,kBAAkB,EAAE,CAAC;YACrC,IAAI,gCAAgC,GAAG,KAAK,CAAC;YAC7C,IAAI,iCAAiC,GAAyB,IAAI,CAAC;YACnE,IAAI,8BAA8B,GAAyC,IAAI,CAAC;YAChF,MAAM,iCAAiC,GAAG,GAAS,EAAE;gBACnD,IAAI,gCAAgC,EAAE,CAAC;oBACrC,OAAO;gBACT,CAAC;gBAED,8BAA8B,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC/C,8BAA8B,GAAG,IAAI,CAAC;oBACtC,KAAK,4BAA4B,EAAE,CAAC;gBACtC,CAAC,EAAE,aAAa,CAAC,qBAAqB,CAAC,CAAC;gBACxC,8BAA8B,CAAC,KAAK,EAAE,EAAE,CAAC;YAC3C,CAAC,CAAC;YAEF,MAAM,4BAA4B,GAAG,KAAK,IAAmB,EAAE;gBAC7D,IAAI,gCAAgC,EAAE,CAAC;oBACrC,OAAO;gBACT,CAAC;gBAED,MAAM,UAAU,GAAG,CAAC,KAAK,IAAI,EAAE;oBAC7B,IAAI,gCAAgC,EAAE,CAAC;wBACrC,OAAO;oBACT,CAAC;oBAED,IAAI,CAAC;wBACH,MAAM,oBAAoB,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC;wBACxD,MAAM,wBAAwB,CAAC,WAAW,CAAC;4BACzC,IAAI,EAAE,gBAAgB;4BACtB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;4BACnC,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE;4BAC7B,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;4BACxB,cAAc,EAAE;gCACd,SAAS,EAAE,oBAAoB,CAAC,SAAS;gCACzC,UAAU,EAAE,oBAAoB,CAAC,UAAU,IAAI,EAAE;gCACjD,MAAM,EAAE,oBAAoB,CAAC,MAAM,IAAI,CAAC;gCACxC,aAAa,EAAE,oBAAoB,CAAC,aAAa;oCAC/C,CAAC,CAAC,MAAM,CAAC,WAAW,CAChB,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC;wCACtF,OAAO;wCACP,UAAU,CAAC,WAAW,EAAE;qCACzB,CAAC,CACH;oCACH,CAAC,CAAC,SAAS;gCACb,eAAe,EAAE,oBAAoB,CAAC,eAAe;oCACnD,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,oBAAoB,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;oCACpE,CAAC,CAAC,SAAS;gCACb,UAAU,EAAE,oBAAoB,CAAC,UAAU;oCACzC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,oBAAoB,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;oCAC/D,CAAC,CAAC,SAAS;6BACd;4BACD,oBAAoB,EAAE,aAAa,CAAC,oBAAoB;4BACxD,oBAAoB,EAAE,aAAa,CAAC,oBAAoB;yBACzD,CAAC,CAAC;oBACL,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,IAAI,CAAC;4BACH,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE;gCAC9B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;6BAC9D,CAAC,CAAC;wBACL,CAAC;wBAAC,MAAM,CAAC;4BACP,oEAAoE;wBACtE,CAAC;oBACH,CAAC;gBACH,CAAC,CAAC,EAAE,CAAC;gBAEL,iCAAiC,GAAG,UAAU,CAAC;gBAC/C,IAAI,CAAC;oBACH,MAAM,UAAU,CAAC;gBACnB,CAAC;wBAAS,CAAC;oBACT,IAAI,iCAAiC,KAAK,UAAU,EAAE,CAAC;wBACrD,iCAAiC,GAAG,IAAI,CAAC;oBAC3C,CAAC;gBACH,CAAC;gBACD,IAAI,CAAC,gCAAgC,EAAE,CAAC;oBACtC,iCAAiC,EAAE,CAAC;gBACtC,CAAC;YACH,CAAC,CAAC;YAEF,iCAAiC,EAAE,CAAC;YACpC,gCAAgC,GAAG,KAAK,IAAI,EAAE;gBAC5C,gCAAgC,GAAG,IAAI,CAAC;gBACxC,IAAI,8BAA8B,EAAE,CAAC;oBACnC,YAAY,CAAC,8BAA8B,CAAC,CAAC;oBAC7C,8BAA8B,GAAG,IAAI,CAAC;gBACxC,CAAC;gBACD,MAAM,iCAAiC,CAAC;YAC1C,CAAC,CAAC;QACJ,CAAC;QACD,OAAO;YACL,YAAY;YACZ,kBAAkB;YAClB,kBAAkB;YAClB,gBAAgB;YAChB,uBAAuB;YACvB,kBAAkB;YAClB,iBAAiB;YACjB,mBAAmB;YACnB,uBAAuB;YACvB,yBAAyB;YACzB,sBAAsB;YACtB,iBAAiB;YACjB,aAAa;YACb,eAAe;YACf,eAAe;YACf,sBAAsB;YACtB,mBAAmB;YACnB,cAAc;YACd,sBAAsB;YACtB,yBAAyB;YACzB,gBAAgB;YAChB,wBAAwB;YACxB,gCAAgC;SACjC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5E,MAAM,IAAI,KAAK,CAAC,eAAe,YAAY,EAAE,CAAC,CAAC;IACjD,CAAC;AACH,CAAC"}
|
package/node_modules/@memento/core/dist/domains/embedding/services/embedding-migration-service.d.ts
CHANGED
|
@@ -15,9 +15,15 @@ export declare class EmbeddingMigrationService {
|
|
|
15
15
|
createPlan(sourceProvider: EmbeddingProvider, targetProvider: EmbeddingProvider, overrides?: Partial<EmbeddingMigrationPlan>): EmbeddingMigrationPlan;
|
|
16
16
|
listTargets(db: Database, plan: EmbeddingMigrationPlan, limit?: number): EmbeddingMigrationTarget[];
|
|
17
17
|
initializeProgress(total: number, resumeFromId?: string): MigrationProgress;
|
|
18
|
+
private resolveEffectiveMonitor;
|
|
18
19
|
execute(db: Database, plan: EmbeddingMigrationPlan, monitor?: MigrationMonitorOptions): Promise<MigrationResult>;
|
|
20
|
+
private processMigrationRow;
|
|
21
|
+
private runMigrationBatchLoop;
|
|
22
|
+
private finalizeMigrationExecution;
|
|
19
23
|
private safeParseEmbedding;
|
|
20
24
|
rollback(db: Database, entries: ReadonlyArray<MigrationRollbackEntry>): void;
|
|
25
|
+
private applyRollbackDelete;
|
|
26
|
+
private applyRollbackRestore;
|
|
21
27
|
listHistory(db: Database, limit?: number): MigrationHistoryRecord[];
|
|
22
28
|
}
|
|
23
29
|
export declare const embeddingMigrationService: EmbeddingMigrationService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedding-migration-service.d.ts","sourceRoot":"","sources":["../../../../src/domains/embedding/services/embedding-migration-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"embedding-migration-service.d.ts","sourceRoot":"","sources":["../../../../src/domains/embedding/services/embedding-migration-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAa,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAuC,MAAM,0CAA0C,CAAC;AACvH,OAAO,KAAK,EAEV,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EAEjB,sBAAsB,EACtB,eAAe,EAIhB,MAAM,0CAA0C,CAAC;AA+BlD;;;;GAIG;AACH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,cAAc;IAqBtB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,YAAY;IAcpB,UAAU,CACR,cAAc,EAAE,iBAAiB,EACjC,cAAc,EAAE,iBAAiB,EACjC,SAAS,GAAE,OAAO,CAAC,sBAAsB,CAAM,GAC9C,sBAAsB;IAiCzB,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,wBAAwB,EAAE;IAsCnG,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,iBAAiB;IAe3E,OAAO,CAAC,uBAAuB;IAMzB,OAAO,CACX,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE,sBAAsB,EAC5B,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,eAAe,CAAC;IA6H3B,OAAO,CAAC,mBAAmB;IAyG3B,OAAO,CAAC,qBAAqB;IA0B7B,OAAO,CAAC,0BAA0B;IAsDlC,OAAO,CAAC,kBAAkB;IAc1B,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,CAAC,sBAAsB,CAAC,GAAG,IAAI;IA+C5E,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,oBAAoB;IAoB5B,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,GAAE,MAAW,GAAG,sBAAsB,EAAE;CAGxE;AAED,eAAO,MAAM,yBAAyB,2BAAkC,CAAC"}
|
package/node_modules/@memento/core/dist/domains/embedding/services/embedding-migration-service.js
CHANGED
|
@@ -115,10 +115,13 @@ export class EmbeddingMigrationService {
|
|
|
115
115
|
stepHistory: []
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
resolveEffectiveMonitor(monitor) {
|
|
119
|
+
return monitor.runId && !monitor.reporter
|
|
120
120
|
? { ...monitor, reporter: migrationMonitorService }
|
|
121
121
|
: monitor;
|
|
122
|
+
}
|
|
123
|
+
async execute(db, plan, monitor = {}) {
|
|
124
|
+
const effectiveMonitor = this.resolveEffectiveMonitor(monitor);
|
|
122
125
|
const totalRow = db
|
|
123
126
|
.prepare('SELECT COUNT(*) AS count FROM memory_embedding WHERE embedding_provider = ?')
|
|
124
127
|
.get(plan.sourceProvider);
|
|
@@ -147,7 +150,6 @@ export class EmbeddingMigrationService {
|
|
|
147
150
|
rolledBack: false
|
|
148
151
|
};
|
|
149
152
|
}
|
|
150
|
-
let lastProcessedId = plan.resumeFromId ?? null;
|
|
151
153
|
const selectStatement = db.prepare(`
|
|
152
154
|
SELECT memory_id, embedding, model, embedding_provider, projection_type, dim, dimensions, created_at
|
|
153
155
|
FROM memory_embedding
|
|
@@ -190,67 +192,95 @@ export class EmbeddingMigrationService {
|
|
|
190
192
|
`);
|
|
191
193
|
const processBatch = (batch) => {
|
|
192
194
|
for (const row of batch) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
195
|
+
this.processMigrationRow({
|
|
196
|
+
row,
|
|
197
|
+
plan,
|
|
198
|
+
normalizationMode,
|
|
199
|
+
existingStatement,
|
|
200
|
+
upsertStatement,
|
|
201
|
+
progress,
|
|
202
|
+
errors,
|
|
203
|
+
rollbackEntries,
|
|
204
|
+
reportEvery,
|
|
205
|
+
effectiveMonitor
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
this.runMigrationBatchLoop(plan, selectStatement, progress, plan.resumeFromId ?? null, processBatch, effectiveMonitor);
|
|
210
|
+
return this.finalizeMigrationExecution({
|
|
211
|
+
db,
|
|
212
|
+
plan,
|
|
213
|
+
progress,
|
|
214
|
+
step,
|
|
215
|
+
errors,
|
|
216
|
+
rollbackEntries,
|
|
217
|
+
effectiveMonitor
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
processMigrationRow(params) {
|
|
221
|
+
const { row, plan, normalizationMode, existingStatement, upsertStatement, progress, errors, rollbackEntries, reportEvery, effectiveMonitor } = params;
|
|
222
|
+
progress.processed += 1;
|
|
223
|
+
progress.lastMemoryId = row.memory_id;
|
|
224
|
+
try {
|
|
225
|
+
const parsed = this.safeParseEmbedding(row.embedding);
|
|
226
|
+
const assessment = vectorCompatibilityService.assessProviderCompatibility(parsed, plan.targetProvider, {
|
|
227
|
+
targetDimensions: plan.targetDimensions,
|
|
228
|
+
normalization: normalizationMode
|
|
229
|
+
});
|
|
230
|
+
const storedVector = assessment.projection.vector;
|
|
231
|
+
const serialized = JSON.stringify(storedVector);
|
|
232
|
+
const projectionType = assessment.projection.projectionType;
|
|
233
|
+
const normalizedFlag = assessment.projection.normalized ? 1 : 0;
|
|
234
|
+
const targetModel = plan.targetModel ?? row.model ?? `compat-${plan.targetProvider}`;
|
|
235
|
+
const createdBy = plan.createdBy ?? DEFAULT_CREATED_BY;
|
|
236
|
+
if (!plan.dryRun) {
|
|
237
|
+
const existing = existingStatement.get(row.memory_id, plan.targetProvider, projectionType);
|
|
238
|
+
upsertStatement.run(row.memory_id, plan.targetProvider, projectionType, serialized, plan.targetDimensions, targetModel, plan.targetDimensions, 32, normalizedFlag, 1, createdBy);
|
|
239
|
+
if (existing) {
|
|
240
|
+
rollbackEntries.push({
|
|
241
|
+
memoryId: row.memory_id,
|
|
242
|
+
provider: plan.targetProvider,
|
|
243
|
+
projectionType,
|
|
244
|
+
operation: 'restore',
|
|
245
|
+
embedding: existing.embedding,
|
|
246
|
+
dim: existing.dim,
|
|
247
|
+
dimensions: existing.dimensions,
|
|
248
|
+
model: existing.model,
|
|
249
|
+
precision: existing.precision,
|
|
250
|
+
normalized: existing.normalized,
|
|
251
|
+
version: existing.version,
|
|
252
|
+
createdBy: existing.created_by,
|
|
253
|
+
createdAt: existing.created_at ?? undefined
|
|
200
254
|
});
|
|
201
|
-
const storedVector = assessment.projection.vector;
|
|
202
|
-
const serialized = JSON.stringify(storedVector);
|
|
203
|
-
const projectionType = assessment.projection.projectionType;
|
|
204
|
-
const normalizedFlag = assessment.projection.normalized ? 1 : 0;
|
|
205
|
-
const targetModel = plan.targetModel ?? row.model ?? `compat-${plan.targetProvider}`;
|
|
206
|
-
const createdBy = plan.createdBy ?? DEFAULT_CREATED_BY;
|
|
207
|
-
if (!plan.dryRun) {
|
|
208
|
-
const existing = existingStatement.get(row.memory_id, plan.targetProvider, projectionType);
|
|
209
|
-
upsertStatement.run(row.memory_id, plan.targetProvider, projectionType, serialized, plan.targetDimensions, targetModel, plan.targetDimensions, 32, normalizedFlag, 1, createdBy);
|
|
210
|
-
if (existing) {
|
|
211
|
-
rollbackEntries.push({
|
|
212
|
-
memoryId: row.memory_id,
|
|
213
|
-
provider: plan.targetProvider,
|
|
214
|
-
projectionType,
|
|
215
|
-
operation: 'restore',
|
|
216
|
-
embedding: existing.embedding,
|
|
217
|
-
dim: existing.dim,
|
|
218
|
-
dimensions: existing.dimensions,
|
|
219
|
-
model: existing.model,
|
|
220
|
-
precision: existing.precision,
|
|
221
|
-
normalized: existing.normalized,
|
|
222
|
-
version: existing.version,
|
|
223
|
-
createdBy: existing.created_by,
|
|
224
|
-
createdAt: existing.created_at ?? undefined
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
rollbackEntries.push({
|
|
229
|
-
memoryId: row.memory_id,
|
|
230
|
-
provider: plan.targetProvider,
|
|
231
|
-
projectionType,
|
|
232
|
-
operation: 'delete'
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
progress.succeeded += 1;
|
|
237
255
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
errors.push({
|
|
256
|
+
else {
|
|
257
|
+
rollbackEntries.push({
|
|
241
258
|
memoryId: row.memory_id,
|
|
242
259
|
provider: plan.targetProvider,
|
|
243
|
-
|
|
260
|
+
projectionType,
|
|
261
|
+
operation: 'delete'
|
|
244
262
|
});
|
|
245
263
|
}
|
|
246
|
-
finally {
|
|
247
|
-
progress.updatedAt = new Date();
|
|
248
|
-
if (reportEvery > 0 && progress.processed % reportEvery === 0) {
|
|
249
|
-
this.notifyProgress(progress, effectiveMonitor);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
264
|
}
|
|
253
|
-
|
|
265
|
+
progress.succeeded += 1;
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
progress.failed += 1;
|
|
269
|
+
errors.push({
|
|
270
|
+
memoryId: row.memory_id,
|
|
271
|
+
provider: plan.targetProvider,
|
|
272
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
finally {
|
|
276
|
+
progress.updatedAt = new Date();
|
|
277
|
+
if (reportEvery > 0 && progress.processed % reportEvery === 0) {
|
|
278
|
+
this.notifyProgress(progress, effectiveMonitor);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
runMigrationBatchLoop(plan, selectStatement, progress, initialLastId, processBatch, effectiveMonitor) {
|
|
283
|
+
let lastProcessedId = initialLastId;
|
|
254
284
|
while (true) {
|
|
255
285
|
const batch = selectStatement.all(plan.sourceProvider, lastProcessedId, lastProcessedId, plan.batchSize ?? DEFAULT_BATCH_SIZE);
|
|
256
286
|
if (!batch.length) {
|
|
@@ -260,6 +290,9 @@ export class EmbeddingMigrationService {
|
|
|
260
290
|
lastProcessedId = batch[batch.length - 1]?.memory_id ?? lastProcessedId;
|
|
261
291
|
this.notifyProgress(progress, effectiveMonitor);
|
|
262
292
|
}
|
|
293
|
+
}
|
|
294
|
+
finalizeMigrationExecution(params) {
|
|
295
|
+
const { db, plan, progress, step, errors, rollbackEntries, effectiveMonitor } = params;
|
|
263
296
|
const endTime = new Date();
|
|
264
297
|
const success = progress.failed === 0;
|
|
265
298
|
let rolledBack = false;
|
|
@@ -342,16 +375,22 @@ export class EmbeddingMigrationService {
|
|
|
342
375
|
`);
|
|
343
376
|
for (const entry of [...entries].reverse()) {
|
|
344
377
|
if (entry.operation === 'delete') {
|
|
345
|
-
|
|
378
|
+
this.applyRollbackDelete(deleteStatement, entry);
|
|
346
379
|
}
|
|
347
380
|
else {
|
|
348
|
-
|
|
349
|
-
throw new Error(`Rollback 데이터가 누락되었습니다: ${entry.memoryId}`);
|
|
350
|
-
}
|
|
351
|
-
restoreStatement.run(entry.memoryId, entry.provider, entry.projectionType, entry.embedding, entry.dim ?? entry.dimensions ?? 0, entry.model ?? null, entry.dimensions ?? entry.dim ?? 0, entry.precision ?? 32, entry.normalized ?? 0, entry.version ?? 1, entry.createdBy ?? DEFAULT_CREATED_BY, entry.createdAt ?? new Date().toISOString());
|
|
381
|
+
this.applyRollbackRestore(restoreStatement, entry);
|
|
352
382
|
}
|
|
353
383
|
}
|
|
354
384
|
}
|
|
385
|
+
applyRollbackDelete(deleteStatement, entry) {
|
|
386
|
+
deleteStatement.run(entry.memoryId, entry.provider, entry.projectionType);
|
|
387
|
+
}
|
|
388
|
+
applyRollbackRestore(restoreStatement, entry) {
|
|
389
|
+
if (!entry.embedding) {
|
|
390
|
+
throw new Error(`Rollback 데이터가 누락되었습니다: ${entry.memoryId}`);
|
|
391
|
+
}
|
|
392
|
+
restoreStatement.run(entry.memoryId, entry.provider, entry.projectionType, entry.embedding, entry.dim ?? entry.dimensions ?? 0, entry.model ?? null, entry.dimensions ?? entry.dim ?? 0, entry.precision ?? 32, entry.normalized ?? 0, entry.version ?? 1, entry.createdBy ?? DEFAULT_CREATED_BY, entry.createdAt ?? new Date().toISOString());
|
|
393
|
+
}
|
|
355
394
|
listHistory(db, limit = 20) {
|
|
356
395
|
return migrationHistoryService.listHistory(db, { limit });
|
|
357
396
|
}
|