memento-mcp-server 1.12.0 → 1.13.0-a

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.
Files changed (119) hide show
  1. package/dist/algorithms/forgetting-algorithm.d.ts +21 -13
  2. package/dist/algorithms/forgetting-algorithm.d.ts.map +1 -1
  3. package/dist/algorithms/forgetting-algorithm.js +32 -24
  4. package/dist/algorithms/forgetting-algorithm.js.map +1 -1
  5. package/dist/algorithms/hybrid-search-engine.d.ts +11 -9
  6. package/dist/algorithms/hybrid-search-engine.d.ts.map +1 -1
  7. package/dist/algorithms/hybrid-search-engine.js +77 -75
  8. package/dist/algorithms/hybrid-search-engine.js.map +1 -1
  9. package/dist/algorithms/search-engine.d.ts +33 -11
  10. package/dist/algorithms/search-engine.d.ts.map +1 -1
  11. package/dist/algorithms/search-engine.js +157 -62
  12. package/dist/algorithms/search-engine.js.map +1 -1
  13. package/dist/algorithms/search-ranking.d.ts +57 -50
  14. package/dist/algorithms/search-ranking.d.ts.map +1 -1
  15. package/dist/algorithms/search-ranking.js +91 -84
  16. package/dist/algorithms/search-ranking.js.map +1 -1
  17. package/dist/algorithms/spaced-repetition.d.ts +18 -13
  18. package/dist/algorithms/spaced-repetition.d.ts.map +1 -1
  19. package/dist/algorithms/spaced-repetition.js +28 -23
  20. package/dist/algorithms/spaced-repetition.js.map +1 -1
  21. package/dist/algorithms/vector-search-engine-migration.d.ts +8 -6
  22. package/dist/algorithms/vector-search-engine-migration.d.ts.map +1 -1
  23. package/dist/algorithms/vector-search-engine-migration.js +13 -11
  24. package/dist/algorithms/vector-search-engine-migration.js.map +1 -1
  25. package/dist/algorithms/vector-search-engine-refactored.d.ts +7 -7
  26. package/dist/algorithms/vector-search-engine-refactored.d.ts.map +1 -1
  27. package/dist/algorithms/vector-search-engine-refactored.js +7 -7
  28. package/dist/algorithms/vector-search-engine-refactored.js.map +1 -1
  29. package/dist/algorithms/vector-search-engine.d.ts +25 -20
  30. package/dist/algorithms/vector-search-engine.d.ts.map +1 -1
  31. package/dist/algorithms/vector-search-engine.js +47 -43
  32. package/dist/algorithms/vector-search-engine.js.map +1 -1
  33. package/dist/config/index.d.ts.map +1 -1
  34. package/dist/config/index.js +4 -1
  35. package/dist/config/index.js.map +1 -1
  36. package/dist/database/init.d.ts.map +1 -1
  37. package/dist/database/init.js +20 -0
  38. package/dist/database/init.js.map +1 -1
  39. package/dist/database/migration/migrations/006-fts5-reflection-notes-migration-status.sql +30 -0
  40. package/dist/database/migration/migrations/006-fts5-reflection-notes.d.ts +113 -0
  41. package/dist/database/migration/migrations/006-fts5-reflection-notes.d.ts.map +1 -0
  42. package/dist/database/migration/migrations/006-fts5-reflection-notes.js +435 -0
  43. package/dist/database/migration/migrations/006-fts5-reflection-notes.js.map +1 -0
  44. package/dist/database/migration/migrations/006-fts5-reflection-notes.sql +26 -0
  45. package/dist/database/schema.sql +11 -9
  46. package/dist/server/bootstrap.d.ts +4 -0
  47. package/dist/server/bootstrap.d.ts.map +1 -1
  48. package/dist/server/bootstrap.js +11 -1
  49. package/dist/server/bootstrap.js.map +1 -1
  50. package/dist/server/context.d.ts.map +1 -1
  51. package/dist/server/context.js +3 -1
  52. package/dist/server/context.js.map +1 -1
  53. package/dist/server/http-server.d.ts.map +1 -1
  54. package/dist/server/http-server.js +2 -1
  55. package/dist/server/http-server.js.map +1 -1
  56. package/dist/server/index.js +3 -1
  57. package/dist/server/index.js.map +1 -1
  58. package/dist/services/async-optimizer.d.ts +2 -1
  59. package/dist/services/async-optimizer.d.ts.map +1 -1
  60. package/dist/services/async-optimizer.js +28 -1
  61. package/dist/services/async-optimizer.js.map +1 -1
  62. package/dist/services/batch-scheduler.d.ts +5 -1
  63. package/dist/services/batch-scheduler.d.ts.map +1 -1
  64. package/dist/services/batch-scheduler.js +13 -1
  65. package/dist/services/batch-scheduler.js.map +1 -1
  66. package/dist/services/cache-service.js +1 -1
  67. package/dist/services/cache-service.js.map +1 -1
  68. package/dist/services/failure-detector.d.ts +120 -0
  69. package/dist/services/failure-detector.d.ts.map +1 -0
  70. package/dist/services/failure-detector.js +370 -0
  71. package/dist/services/failure-detector.js.map +1 -0
  72. package/dist/services/llm-based-relation-extractor.js +1 -1
  73. package/dist/services/llm-based-relation-extractor.js.map +1 -1
  74. package/dist/services/reflexion-worker.d.ts +170 -0
  75. package/dist/services/reflexion-worker.d.ts.map +1 -0
  76. package/dist/services/reflexion-worker.js +636 -0
  77. package/dist/services/reflexion-worker.js.map +1 -0
  78. package/dist/services/relation-graph.d.ts +2 -2
  79. package/dist/services/relation-graph.js +3 -3
  80. package/dist/services/relation-graph.js.map +1 -1
  81. package/dist/tools/base-tool.d.ts +5 -0
  82. package/dist/tools/base-tool.d.ts.map +1 -1
  83. package/dist/tools/base-tool.js +39 -0
  84. package/dist/tools/base-tool.js.map +1 -1
  85. package/dist/tools/recall-tool.d.ts.map +1 -1
  86. package/dist/tools/recall-tool.js +36 -2
  87. package/dist/tools/recall-tool.js.map +1 -1
  88. package/dist/tools/remember-tool.d.ts +24 -0
  89. package/dist/tools/remember-tool.d.ts.map +1 -1
  90. package/dist/tools/remember-tool.js +445 -273
  91. package/dist/tools/remember-tool.js.map +1 -1
  92. package/dist/tools/types.d.ts +5 -1
  93. package/dist/tools/types.d.ts.map +1 -1
  94. package/dist/tools/types.js +1 -1
  95. package/dist/tools/types.js.map +1 -1
  96. package/dist/types/index.d.ts +2 -0
  97. package/dist/types/index.d.ts.map +1 -1
  98. package/dist/types/index.js.map +1 -1
  99. package/dist/utils/database.d.ts.map +1 -1
  100. package/dist/utils/database.js +34 -10
  101. package/dist/utils/database.js.map +1 -1
  102. package/dist/utils/fts5-migration-status.d.ts +72 -0
  103. package/dist/utils/fts5-migration-status.d.ts.map +1 -0
  104. package/dist/utils/fts5-migration-status.js +304 -0
  105. package/dist/utils/fts5-migration-status.js.map +1 -0
  106. package/dist/utils/reflection-notes-merge.d.ts +58 -0
  107. package/dist/utils/reflection-notes-merge.d.ts.map +1 -0
  108. package/dist/utils/reflection-notes-merge.js +227 -0
  109. package/dist/utils/reflection-notes-merge.js.map +1 -0
  110. package/dist/utils/reflection-notes-normalize.d.ts +43 -0
  111. package/dist/utils/reflection-notes-normalize.d.ts.map +1 -0
  112. package/dist/utils/reflection-notes-normalize.js +164 -0
  113. package/dist/utils/reflection-notes-normalize.js.map +1 -0
  114. package/dist/utils/reflection-notes-schema.d.ts +84 -0
  115. package/dist/utils/reflection-notes-schema.d.ts.map +1 -0
  116. package/dist/utils/reflection-notes-schema.js +215 -0
  117. package/dist/utils/reflection-notes-schema.js.map +1 -0
  118. package/package.json +3 -1
  119. package/src/database/schema.sql +11 -9
@@ -0,0 +1,304 @@
1
+ /**
2
+ * FTS5 Migration Status 유틸리티
3
+ *
4
+ * FTS5 reflection_notes 마이그레이션 상태를 관리하는 유틸리티 함수를 제공합니다.
5
+ * Fallback 전략을 위해 마이그레이션 상태를 추적하고 관리합니다.
6
+ */
7
+ import { DatabaseUtils } from './database.js';
8
+ import { mementoConfig } from '../config/index.js';
9
+ const MIGRATION_KEY = 'fts5-reflection-notes';
10
+ /**
11
+ * 마이그레이션 상태 테이블 초기화
12
+ * 테이블이 없으면 생성하고, 초기 상태 'pending' 삽입
13
+ */
14
+ export function initializeMigrationStatusTable(db) {
15
+ try {
16
+ // 테이블 생성
17
+ DatabaseUtils.run(db, `
18
+ CREATE TABLE IF NOT EXISTS fts5_migration_status (
19
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
20
+ migration_key TEXT NOT NULL UNIQUE DEFAULT 'fts5-reflection-notes',
21
+ status TEXT NOT NULL CHECK (status IN ('pending', 'in_progress', 'completed', 'failed')) DEFAULT 'pending',
22
+ started_at TIMESTAMP,
23
+ completed_at TIMESTAMP,
24
+ failed_at TIMESTAMP,
25
+ error_message TEXT,
26
+ retry_count INTEGER DEFAULT 0,
27
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
28
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
29
+ )
30
+ `);
31
+ // 인덱스 생성
32
+ DatabaseUtils.run(db, `
33
+ CREATE INDEX IF NOT EXISTS idx_fts5_migration_status_key ON fts5_migration_status(migration_key)
34
+ `);
35
+ DatabaseUtils.run(db, `
36
+ CREATE INDEX IF NOT EXISTS idx_fts5_migration_status_status ON fts5_migration_status(status)
37
+ `);
38
+ // 초기 상태 삽입 (없는 경우)
39
+ DatabaseUtils.run(db, `
40
+ INSERT OR IGNORE INTO fts5_migration_status (migration_key, status)
41
+ VALUES (?, 'pending')
42
+ `, [MIGRATION_KEY]);
43
+ }
44
+ catch (error) {
45
+ throw new Error(`마이그레이션 상태 테이블 초기화 실패: ${error instanceof Error ? error.message : String(error)}`);
46
+ }
47
+ }
48
+ /**
49
+ * 마이그레이션 상태 조회
50
+ *
51
+ * @param db - 데이터베이스 인스턴스
52
+ * @returns 마이그레이션 상태
53
+ */
54
+ export function getMigrationStatus(db) {
55
+ try {
56
+ // 먼저 테이블이 존재하는지 확인
57
+ const tableExists = DatabaseUtils.get(db, `
58
+ SELECT name FROM sqlite_master
59
+ WHERE type='table' AND name='fts5_migration_status'
60
+ `);
61
+ if (!tableExists) {
62
+ // 테이블이 없으면 초기화 후 'pending' 반환
63
+ initializeMigrationStatusTable(db);
64
+ return 'pending';
65
+ }
66
+ // 테이블이 있으면 상태 조회
67
+ const result = DatabaseUtils.get(db, `
68
+ SELECT status FROM fts5_migration_status
69
+ WHERE migration_key = ?
70
+ `, [MIGRATION_KEY]);
71
+ if (!result) {
72
+ // 상태가 없으면 초기화 후 'pending' 반환
73
+ initializeMigrationStatusTable(db);
74
+ return 'pending';
75
+ }
76
+ return result.status;
77
+ }
78
+ catch (error) {
79
+ // 조회 실패 시 테이블 초기화 시도
80
+ try {
81
+ initializeMigrationStatusTable(db);
82
+ return 'pending';
83
+ }
84
+ catch (initError) {
85
+ // 초기화도 실패하면 기본값 반환
86
+ console.warn('마이그레이션 상태 조회 및 초기화 실패:', error, initError);
87
+ return 'pending';
88
+ }
89
+ }
90
+ }
91
+ /**
92
+ * 마이그레이션 상태 업데이트
93
+ *
94
+ * @param db - 데이터베이스 인스턴스
95
+ * @param status - 새로운 상태
96
+ * @param errorMessage - 에러 메시지 (실패 시)
97
+ * @throws Error - 상태 전이 검증 실패 시
98
+ */
99
+ export function setMigrationStatus(db, status, errorMessage) {
100
+ try {
101
+ // 현재 상태 조회
102
+ const currentStatus = getMigrationStatus(db);
103
+ // 상태 전이 검증
104
+ if (!isValidStatusTransition(currentStatus, status)) {
105
+ throw new Error(`유효하지 않은 상태 전이: ${currentStatus} → ${status}`);
106
+ }
107
+ // 상태 업데이트
108
+ const now = new Date().toISOString();
109
+ let updateSql = '';
110
+ let params = [];
111
+ if (status === 'in_progress') {
112
+ updateSql = `
113
+ UPDATE fts5_migration_status
114
+ SET status = ?, started_at = ?, updated_at = ?
115
+ WHERE migration_key = ?
116
+ `;
117
+ params = [status, now, now, MIGRATION_KEY];
118
+ }
119
+ else if (status === 'completed') {
120
+ updateSql = `
121
+ UPDATE fts5_migration_status
122
+ SET status = ?, completed_at = ?, updated_at = ?
123
+ WHERE migration_key = ?
124
+ `;
125
+ params = [status, now, now, MIGRATION_KEY];
126
+ }
127
+ else if (status === 'failed') {
128
+ updateSql = `
129
+ UPDATE fts5_migration_status
130
+ SET status = ?, failed_at = ?, error_message = ?, retry_count = retry_count + 1, updated_at = ?
131
+ WHERE migration_key = ?
132
+ `;
133
+ params = [status, now, errorMessage || null, now, MIGRATION_KEY];
134
+ }
135
+ else if (status === 'pending') {
136
+ // 재시도 시 pending으로 되돌림
137
+ updateSql = `
138
+ UPDATE fts5_migration_status
139
+ SET status = ?, started_at = NULL, completed_at = NULL, failed_at = NULL, error_message = NULL, updated_at = ?
140
+ WHERE migration_key = ?
141
+ `;
142
+ params = [status, now, MIGRATION_KEY];
143
+ }
144
+ if (updateSql) {
145
+ DatabaseUtils.run(db, updateSql, params);
146
+ }
147
+ // Config 캐시 업데이트
148
+ mementoConfig.fts5MigrationStatus = status;
149
+ }
150
+ catch (error) {
151
+ throw new Error(`마이그레이션 상태 업데이트 실패: ${error instanceof Error ? error.message : String(error)}`);
152
+ }
153
+ }
154
+ /**
155
+ * 상태 전이 검증
156
+ *
157
+ * 유효한 상태 전이:
158
+ * - pending → in_progress
159
+ * - in_progress → completed
160
+ * - in_progress → failed
161
+ * - failed → pending (재시도)
162
+ * - completed → (변경 불가)
163
+ *
164
+ * @param currentStatus - 현재 상태
165
+ * @param newStatus - 새로운 상태
166
+ * @returns 유효한 전이인지 여부
167
+ */
168
+ function isValidStatusTransition(currentStatus, newStatus) {
169
+ // 동일한 상태로 변경은 허용 (에러 메시지 업데이트 등)
170
+ if (currentStatus === newStatus) {
171
+ return true;
172
+ }
173
+ // 상태 전이 규칙
174
+ const validTransitions = {
175
+ pending: ['in_progress'],
176
+ in_progress: ['completed', 'failed'],
177
+ completed: [], // completed는 변경 불가
178
+ failed: ['pending'] // 재시도를 위해 pending으로 되돌릴 수 있음
179
+ };
180
+ return validTransitions[currentStatus].includes(newStatus);
181
+ }
182
+ /**
183
+ * 마이그레이션 상태를 config에 로드 및 캐시
184
+ *
185
+ * @param db - 데이터베이스 인스턴스
186
+ */
187
+ export function loadMigrationStatusToConfig(db) {
188
+ try {
189
+ const status = getMigrationStatus(db);
190
+ mementoConfig.fts5MigrationStatus = status;
191
+ }
192
+ catch (error) {
193
+ // 로드 실패 시 기본값 설정
194
+ console.warn('마이그레이션 상태 로드 실패, 기본값 사용:', error);
195
+ mementoConfig.fts5MigrationStatus = 'pending';
196
+ }
197
+ }
198
+ /**
199
+ * 마이그레이션 상태가 완료되었는지 확인
200
+ *
201
+ * @param db - 데이터베이스 인스턴스 (선택적, 없으면 config 캐시 사용)
202
+ * @returns 완료 여부
203
+ */
204
+ export function isMigrationCompleted(db) {
205
+ if (db) {
206
+ const status = getMigrationStatus(db);
207
+ return status === 'completed';
208
+ }
209
+ return mementoConfig.fts5MigrationStatus === 'completed';
210
+ }
211
+ /**
212
+ * 마이그레이션 상태가 실패했는지 확인
213
+ *
214
+ * @param db - 데이터베이스 인스턴스 (선택적, 없으면 config 캐시 사용)
215
+ * @returns 실패 여부
216
+ */
217
+ export function isMigrationFailed(db) {
218
+ if (db) {
219
+ const status = getMigrationStatus(db);
220
+ return status === 'failed';
221
+ }
222
+ return mementoConfig.fts5MigrationStatus === 'failed';
223
+ }
224
+ /**
225
+ * Fallback이 필요한지 확인 (마이그레이션 실패 또는 대기 중)
226
+ *
227
+ * @param db - 데이터베이스 인스턴스 (선택적, 없으면 config 캐시 사용)
228
+ * @returns Fallback 필요 여부
229
+ */
230
+ export function shouldUseFallback(db) {
231
+ // 환경 변수로 강제 Fallback 활성화 확인
232
+ if (process.env.MEMENTO_FTS5_FALLBACK_ENABLED === 'true') {
233
+ return true;
234
+ }
235
+ if (db) {
236
+ const status = getMigrationStatus(db);
237
+ return status === 'failed' || status === 'pending';
238
+ }
239
+ const status = mementoConfig.fts5MigrationStatus;
240
+ return status === 'failed' || status === 'pending';
241
+ }
242
+ /**
243
+ * 마이그레이션 재시도 준비
244
+ * 실패한 마이그레이션을 재시도하기 위해 상태를 'pending'으로 되돌립니다.
245
+ *
246
+ * @param db - 데이터베이스 인스턴스
247
+ */
248
+ export function prepareMigrationRetry(db) {
249
+ const currentStatus = getMigrationStatus(db);
250
+ if (currentStatus !== 'failed') {
251
+ throw new Error(`마이그레이션 재시도는 'failed' 상태에서만 가능합니다. 현재 상태: ${currentStatus}`);
252
+ }
253
+ setMigrationStatus(db, 'pending');
254
+ }
255
+ /**
256
+ * 마이그레이션 상태를 강제로 업데이트 (관리자용)
257
+ *
258
+ * @param db - 데이터베이스 인스턴스
259
+ * @param status - 새로운 상태
260
+ * @param errorMessage - 에러 메시지 (선택적)
261
+ */
262
+ export function forceSetMigrationStatus(db, status, errorMessage) {
263
+ // 상태 전이 검증 없이 강제 업데이트
264
+ const now = new Date().toISOString();
265
+ let updateSql = '';
266
+ let params = [];
267
+ if (status === 'in_progress') {
268
+ updateSql = `
269
+ UPDATE fts5_migration_status
270
+ SET status = ?, started_at = ?, updated_at = ?
271
+ WHERE migration_key = ?
272
+ `;
273
+ params = [status, now, now, MIGRATION_KEY];
274
+ }
275
+ else if (status === 'completed') {
276
+ updateSql = `
277
+ UPDATE fts5_migration_status
278
+ SET status = ?, completed_at = ?, updated_at = ?
279
+ WHERE migration_key = ?
280
+ `;
281
+ params = [status, now, now, MIGRATION_KEY];
282
+ }
283
+ else if (status === 'failed') {
284
+ updateSql = `
285
+ UPDATE fts5_migration_status
286
+ SET status = ?, failed_at = ?, error_message = ?, retry_count = retry_count + 1, updated_at = ?
287
+ WHERE migration_key = ?
288
+ `;
289
+ params = [status, now, errorMessage || null, now, MIGRATION_KEY];
290
+ }
291
+ else if (status === 'pending') {
292
+ updateSql = `
293
+ UPDATE fts5_migration_status
294
+ SET status = ?, started_at = NULL, completed_at = NULL, failed_at = NULL, error_message = NULL, updated_at = ?
295
+ WHERE migration_key = ?
296
+ `;
297
+ params = [status, now, MIGRATION_KEY];
298
+ }
299
+ if (updateSql) {
300
+ DatabaseUtils.run(db, updateSql, params);
301
+ mementoConfig.fts5MigrationStatus = status;
302
+ }
303
+ }
304
+ //# sourceMappingURL=fts5-migration-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fts5-migration-status.js","sourceRoot":"","sources":["../../src/utils/fts5-migration-status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Reflection Notes 병합 및 배열 크기 제한 유틸리티
3
+ *
4
+ * reflection_notes 필드의 병합 로직과 크기 제한을 처리하는 공통 유틸리티 함수를 제공합니다.
5
+ * remember Tool과 Reflexion Worker에서 공통으로 사용됩니다.
6
+ */
7
+ /**
8
+ * 병합 결과 타입
9
+ */
10
+ export interface MergeResult {
11
+ merged: any[];
12
+ removedCount: number;
13
+ warnings: string[];
14
+ }
15
+ /**
16
+ * 기존 reflection_notes 타입
17
+ */
18
+ export type ExistingReflectionNotes = {
19
+ type: 'null';
20
+ value: null;
21
+ } | {
22
+ type: 'object';
23
+ value: any;
24
+ } | {
25
+ type: 'array';
26
+ value: any[];
27
+ };
28
+ /**
29
+ * 새로 추가할 reflection_notes 타입
30
+ */
31
+ export type NewReflectionNotes = string | any | any[];
32
+ /**
33
+ * reflection_notes 병합 및 배열 크기 제한
34
+ *
35
+ * 병합 로직:
36
+ * - NULL → 새로 저장
37
+ * - 단일 객체 → 배열 변환 후 추가
38
+ * - 배열 → 배열에 추가
39
+ *
40
+ * 크기 제한:
41
+ * - 배열 크기: 최대 100개, 초과 시 FIFO로 가장 오래된 항목 제거
42
+ * - 단일 객체: 최대 10KB, 초과 시 에러 반환
43
+ * - 전체 필드: 최대 1MB, 초과 시 자동 정리 (가장 오래된 항목부터 제거)
44
+ *
45
+ * @param existing - 기존 reflection_notes (조회 결과)
46
+ * @param newNotes - 새로 추가할 reflection_notes (문자열, 객체, 또는 배열)
47
+ * @returns 병합 결과
48
+ * @throws Error - 단일 객체 크기 초과 시
49
+ */
50
+ export declare function mergeReflectionNotes(existing: ExistingReflectionNotes, newNotes: NewReflectionNotes): MergeResult;
51
+ /**
52
+ * 병합된 reflection_notes를 JSON 문자열로 변환
53
+ *
54
+ * @param merged - 병합된 배열
55
+ * @returns JSON 문자열
56
+ */
57
+ export declare function serializeReflectionNotes(merged: any[]): string;
58
+ //# sourceMappingURL=reflection-notes-merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflection-notes-merge.d.ts","sourceRoot":"","sources":["../../src/utils/reflection-notes-merge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,GAAG,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,GAAG,EAAE,CAAA;CAAE,CAAC;AAEpC;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC;AA4JtD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,uBAAuB,EACjC,QAAQ,EAAE,kBAAkB,GAC3B,WAAW,CA2Db;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,CAQ9D"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Reflection Notes 병합 및 배열 크기 제한 유틸리티
3
+ *
4
+ * reflection_notes 필드의 병합 로직과 크기 제한을 처리하는 공통 유틸리티 함수를 제공합니다.
5
+ * remember Tool과 Reflexion Worker에서 공통으로 사용됩니다.
6
+ */
7
+ import { logger } from './logger.js';
8
+ import { validateReflectionNotes } from './reflection-notes-schema.js';
9
+ /**
10
+ * 단일 객체 최대 크기 (10KB)
11
+ */
12
+ const MAX_SINGLE_OBJECT_SIZE = 10 * 1024; // 10KB
13
+ /**
14
+ * 전체 필드 최대 크기 (1MB)
15
+ */
16
+ const MAX_TOTAL_FIELD_SIZE = 1024 * 1024; // 1MB
17
+ /**
18
+ * 배열 최대 크기 (100개)
19
+ */
20
+ const MAX_ARRAY_SIZE = 100;
21
+ /**
22
+ * 단일 객체 크기 검증
23
+ *
24
+ * @param obj - 검증할 객체
25
+ * @returns 객체 크기 (바이트)
26
+ */
27
+ function getObjectSize(obj) {
28
+ try {
29
+ return new TextEncoder().encode(JSON.stringify(obj)).length;
30
+ }
31
+ catch (error) {
32
+ // JSON 직렬화 실패 시 안전하게 처리
33
+ return 0;
34
+ }
35
+ }
36
+ /**
37
+ * 단일 객체 최대 크기 검증
38
+ *
39
+ * @param obj - 검증할 객체
40
+ * @throws Error - 10KB 초과 시
41
+ */
42
+ function validateSingleObjectSize(obj) {
43
+ const size = getObjectSize(obj);
44
+ if (size > MAX_SINGLE_OBJECT_SIZE) {
45
+ throw new Error(`단일 reflection_notes 객체는 최대 ${MAX_SINGLE_OBJECT_SIZE}바이트(10KB)를 초과할 수 없습니다. 현재 크기: ${size}바이트`);
46
+ }
47
+ }
48
+ /**
49
+ * 배열 크기 제한 적용 (FIFO 방식)
50
+ *
51
+ * @param array - 제한을 적용할 배열
52
+ * @returns 제한이 적용된 배열과 제거된 항목 수
53
+ */
54
+ function limitArraySize(array) {
55
+ if (array.length <= MAX_ARRAY_SIZE) {
56
+ return { limited: array, removedCount: 0 };
57
+ }
58
+ const removedCount = array.length - MAX_ARRAY_SIZE;
59
+ const limited = array.slice(-MAX_ARRAY_SIZE); // 가장 최근 항목 유지 (FIFO)
60
+ logger.warn('reflection_notes 배열 크기 제한 초과', {
61
+ originalSize: array.length,
62
+ maxSize: MAX_ARRAY_SIZE,
63
+ removedCount,
64
+ message: `배열 크기가 ${MAX_ARRAY_SIZE}개를 초과하여 가장 오래된 ${removedCount}개 항목이 제거되었습니다`
65
+ });
66
+ return { limited, removedCount };
67
+ }
68
+ /**
69
+ * 전체 필드 크기 검증 및 자동 정리
70
+ *
71
+ * @param array - 검증할 배열
72
+ * @returns 정리된 배열과 제거된 항목 수
73
+ */
74
+ function validateAndCleanupTotalSize(array) {
75
+ const totalSize = getObjectSize(array);
76
+ if (totalSize <= MAX_TOTAL_FIELD_SIZE) {
77
+ return { cleaned: array, removedCount: 0 };
78
+ }
79
+ // 가장 오래된 항목부터 제거 (timestamp 기준으로 정렬)
80
+ const sorted = [...array].sort((a, b) => {
81
+ const timestampA = a.timestamp ? new Date(a.timestamp).getTime() : 0;
82
+ const timestampB = b.timestamp ? new Date(b.timestamp).getTime() : 0;
83
+ return timestampA - timestampB; // 오래된 것부터
84
+ });
85
+ let cleaned = [...array];
86
+ let removedCount = 0;
87
+ // 전체 크기가 1MB 이하가 될 때까지 가장 오래된 항목 제거
88
+ while (getObjectSize(cleaned) > MAX_TOTAL_FIELD_SIZE && cleaned.length > 0) {
89
+ // 가장 오래된 항목 찾기
90
+ const oldestIndex = cleaned.findIndex((item, idx) => {
91
+ const itemTimestamp = item.timestamp ? new Date(item.timestamp).getTime() : 0;
92
+ const oldestTimestamp = sorted[removedCount]?.timestamp
93
+ ? new Date(sorted[removedCount].timestamp).getTime()
94
+ : 0;
95
+ return itemTimestamp === oldestTimestamp;
96
+ });
97
+ if (oldestIndex !== -1) {
98
+ cleaned.splice(oldestIndex, 1);
99
+ removedCount++;
100
+ }
101
+ else {
102
+ // timestamp가 없는 경우 첫 번째 항목 제거
103
+ cleaned.shift();
104
+ removedCount++;
105
+ }
106
+ }
107
+ if (removedCount > 0) {
108
+ logger.warn('reflection_notes 전체 필드 크기 제한 초과', {
109
+ originalSize: totalSize,
110
+ maxSize: MAX_TOTAL_FIELD_SIZE,
111
+ removedCount,
112
+ remainingSize: getObjectSize(cleaned),
113
+ message: `전체 필드 크기가 ${MAX_TOTAL_FIELD_SIZE}바이트(1MB)를 초과하여 가장 오래된 ${removedCount}개 항목이 자동으로 제거되었습니다`
114
+ });
115
+ }
116
+ return { cleaned, removedCount };
117
+ }
118
+ /**
119
+ * 새로 추가할 reflection_notes를 배열로 변환
120
+ *
121
+ * @param newNotes - 새로 추가할 reflection_notes (문자열, 객체, 또는 배열)
122
+ * @returns 배열로 변환된 reflection_notes
123
+ */
124
+ function normalizeNewReflectionNotes(newNotes) {
125
+ // 문자열인 경우 JSON 파싱
126
+ if (typeof newNotes === 'string') {
127
+ try {
128
+ const parsed = JSON.parse(newNotes);
129
+ return Array.isArray(parsed) ? parsed : [parsed];
130
+ }
131
+ catch (error) {
132
+ throw new Error(`reflection_notes JSON 파싱 실패: ${error instanceof Error ? error.message : String(error)}`);
133
+ }
134
+ }
135
+ // 이미 배열인 경우
136
+ if (Array.isArray(newNotes)) {
137
+ return newNotes;
138
+ }
139
+ // 단일 객체인 경우
140
+ return [newNotes];
141
+ }
142
+ /**
143
+ * reflection_notes 병합 및 배열 크기 제한
144
+ *
145
+ * 병합 로직:
146
+ * - NULL → 새로 저장
147
+ * - 단일 객체 → 배열 변환 후 추가
148
+ * - 배열 → 배열에 추가
149
+ *
150
+ * 크기 제한:
151
+ * - 배열 크기: 최대 100개, 초과 시 FIFO로 가장 오래된 항목 제거
152
+ * - 단일 객체: 최대 10KB, 초과 시 에러 반환
153
+ * - 전체 필드: 최대 1MB, 초과 시 자동 정리 (가장 오래된 항목부터 제거)
154
+ *
155
+ * @param existing - 기존 reflection_notes (조회 결과)
156
+ * @param newNotes - 새로 추가할 reflection_notes (문자열, 객체, 또는 배열)
157
+ * @returns 병합 결과
158
+ * @throws Error - 단일 객체 크기 초과 시
159
+ */
160
+ export function mergeReflectionNotes(existing, newNotes) {
161
+ const warnings = [];
162
+ let removedCount = 0;
163
+ // 새로 추가할 reflection_notes를 배열로 변환
164
+ const newNotesArray = normalizeNewReflectionNotes(newNotes);
165
+ // 각 새 항목의 크기 검증
166
+ for (const item of newNotesArray) {
167
+ try {
168
+ validateSingleObjectSize(item);
169
+ }
170
+ catch (error) {
171
+ throw error; // 단일 객체 크기 초과는 즉시 에러 반환
172
+ }
173
+ }
174
+ // 기존 reflection_notes 처리
175
+ let merged;
176
+ if (existing.type === 'null') {
177
+ // NULL → 새로 저장
178
+ merged = newNotesArray;
179
+ }
180
+ else if (existing.type === 'object') {
181
+ // 단일 객체 → 배열 변환 후 추가
182
+ merged = [existing.value, ...newNotesArray];
183
+ }
184
+ else if (existing.type === 'array') {
185
+ // 배열 → 배열에 추가
186
+ merged = [...existing.value, ...newNotesArray];
187
+ }
188
+ else {
189
+ // 예상치 못한 타입
190
+ merged = newNotesArray;
191
+ warnings.push(`예상치 못한 기존 reflection_notes 타입: ${existing.type}`);
192
+ }
193
+ // 배열 크기 제한 적용
194
+ const sizeLimitResult = limitArraySize(merged);
195
+ merged = sizeLimitResult.limited;
196
+ removedCount += sizeLimitResult.removedCount;
197
+ if (sizeLimitResult.removedCount > 0) {
198
+ warnings.push(`배열 크기 제한: ${sizeLimitResult.removedCount}개 항목 제거됨 (최대 ${MAX_ARRAY_SIZE}개)`);
199
+ }
200
+ // 전체 필드 크기 검증 및 자동 정리
201
+ const sizeCleanupResult = validateAndCleanupTotalSize(merged);
202
+ merged = sizeCleanupResult.cleaned;
203
+ removedCount += sizeCleanupResult.removedCount;
204
+ if (sizeCleanupResult.removedCount > 0) {
205
+ warnings.push(`전체 필드 크기 제한: ${sizeCleanupResult.removedCount}개 항목 제거됨 (최대 ${MAX_TOTAL_FIELD_SIZE}바이트)`);
206
+ }
207
+ return {
208
+ merged,
209
+ removedCount,
210
+ warnings
211
+ };
212
+ }
213
+ /**
214
+ * 병합된 reflection_notes를 JSON 문자열로 변환
215
+ *
216
+ * @param merged - 병합된 배열
217
+ * @returns JSON 문자열
218
+ */
219
+ export function serializeReflectionNotes(merged) {
220
+ // 배열이 1개인 경우 단일 객체로 저장 (Phase 1 호환성)
221
+ if (merged.length === 1) {
222
+ return JSON.stringify(merged[0]);
223
+ }
224
+ // 배열인 경우 배열로 저장
225
+ return JSON.stringify(merged);
226
+ }
227
+ //# sourceMappingURL=reflection-notes-merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflection-notes-merge.js","sourceRoot":"","sources":["../../src/utils/reflection-notes-merge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAwBvE;;GAEG;AACH,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO;AAEjD;;GAEG;AACH,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,MAAM;AAEhD;;GAEG;AACH,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;;;;;GAKG;AACH,SAAS,aAAa,CAAC,GAAQ;IAC7B,IAAI,CAAC;QACH,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAC9D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,wBAAwB;QACxB,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,GAAQ;IACxC,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,IAAI,GAAG,sBAAsB,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,8BAA8B,sBAAsB,iCAAiC,IAAI,KAAK,CAC/F,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,KAAY;IAClC,IAAI,KAAK,CAAC,MAAM,IAAI,cAAc,EAAE,CAAC;QACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,cAAc,CAAC;IACnD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,qBAAqB;IAEnE,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE;QAC1C,YAAY,EAAE,KAAK,CAAC,MAAM;QAC1B,OAAO,EAAE,cAAc;QACvB,YAAY;QACZ,OAAO,EAAE,UAAU,cAAc,kBAAkB,YAAY,eAAe;KAC/E,CAAC,CAAC;IAEH,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,SAAS,2BAA2B,CAAC,KAAY;IAC/C,MAAM,SAAS,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEvC,IAAI,SAAS,IAAI,oBAAoB,EAAE,CAAC;QACtC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAC7C,CAAC;IAED,qCAAqC;IACrC,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,UAAU,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,UAAU,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,OAAO,UAAU,GAAG,UAAU,CAAC,CAAC,UAAU;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IACzB,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,oCAAoC;IACpC,OAAO,aAAa,CAAC,OAAO,CAAC,GAAG,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3E,eAAe;QACf,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAClD,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9E,MAAM,eAAe,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,SAAS;gBACrD,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE;gBACpD,CAAC,CAAC,CAAC,CAAC;YACN,OAAO,aAAa,KAAK,eAAe,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YAC/B,YAAY,EAAE,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,8BAA8B;YAC9B,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,YAAY,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE;YAC7C,YAAY,EAAE,SAAS;YACvB,OAAO,EAAE,oBAAoB;YAC7B,YAAY;YACZ,aAAa,EAAE,aAAa,CAAC,OAAO,CAAC;YACrC,OAAO,EAAE,aAAa,oBAAoB,yBAAyB,YAAY,oBAAoB;SACpG,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,SAAS,2BAA2B,CAAC,QAA4B;IAC/D,kBAAkB;IAClB,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACpC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,gCAAgC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACzF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,YAAY;IACZ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,YAAY;IACZ,OAAO,CAAC,QAAQ,CAAC,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAiC,EACjC,QAA4B;IAE5B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,kCAAkC;IAClC,MAAM,aAAa,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IAE5D,gBAAgB;IAChB,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,wBAAwB,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,KAAK,CAAC,CAAC,wBAAwB;QACvC,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,IAAI,MAAa,CAAC;IAElB,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC7B,eAAe;QACf,MAAM,GAAG,aAAa,CAAC;IACzB,CAAC;SAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,qBAAqB;QACrB,MAAM,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,aAAa,CAAC,CAAC;IAC9C,CAAC;SAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACrC,cAAc;QACd,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,aAAa,CAAC,CAAC;IACjD,CAAC;SAAM,CAAC;QACN,YAAY;QACZ,MAAM,GAAG,aAAa,CAAC;QACvB,QAAQ,CAAC,IAAI,CAAC,kCAAmC,QAAgB,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,cAAc;IACd,MAAM,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC;IACjC,YAAY,IAAI,eAAe,CAAC,YAAY,CAAC;IAC7C,IAAI,eAAe,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CACX,aAAa,eAAe,CAAC,YAAY,gBAAgB,cAAc,IAAI,CAC5E,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,MAAM,iBAAiB,GAAG,2BAA2B,CAAC,MAAM,CAAC,CAAC;IAC9D,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC;IACnC,YAAY,IAAI,iBAAiB,CAAC,YAAY,CAAC;IAC/C,IAAI,iBAAiB,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;QACvC,QAAQ,CAAC,IAAI,CACX,gBAAgB,iBAAiB,CAAC,YAAY,gBAAgB,oBAAoB,MAAM,CACzF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM;QACN,YAAY;QACZ,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAa;IACpD,qCAAqC;IACrC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,gBAAgB;IAChB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Reflection Notes JSON 정규화 유틸리티
3
+ *
4
+ * reflection_notes 필드를 FTS5 인덱싱을 위해 텍스트로 정규화하는 유틸리티 함수를 제공합니다.
5
+ * 트리거에서 사용되며, JSON 형식(단일 객체 또는 배열)을 FTS5 검색 가능한 텍스트로 변환합니다.
6
+ */
7
+ /**
8
+ * reflection_notes JSON을 FTS5 인덱싱을 위해 텍스트로 정규화
9
+ *
10
+ * 정규화 규칙:
11
+ * - 단일 객체: 모든 값 필드를 추출하여 공백으로 구분된 단일 문자열로 병합
12
+ * - 배열: 각 요소의 모든 값 필드를 추출하여 공백으로 구분된 단일 문자열로 병합
13
+ * - 키 토큰 포함: failure_type, phase는 "key:value" 형식으로 포함
14
+ * - 제외 필드: timestamp는 제외
15
+ *
16
+ * 예시:
17
+ * - `{"failure_type": "tool_error", "failure_description": "API timeout"}`
18
+ * → "type:tool_error API timeout"
19
+ * - `[{"failure_description": "API timeout"}, {"lessons_learned": "retry needed"}]`
20
+ * → "API timeout retry needed"
21
+ *
22
+ * @param reflectionNotes - 정규화할 reflection_notes (JSON 문자열, 객체, 또는 배열)
23
+ * @returns 정규화된 텍스트 문자열 (FTS5 인덱싱용)
24
+ */
25
+ export declare function normalizeReflectionNotes(reflectionNotes: string | null | undefined | any): string;
26
+ /**
27
+ * 정규화된 텍스트에서 키 토큰 추출 (검색 쿼리 빌더용)
28
+ *
29
+ * @param normalizedText - 정규화된 텍스트
30
+ * @returns 키 토큰 배열 (예: ["type:tool_error", "phase:manual"])
31
+ */
32
+ export declare function extractKeyTokens(normalizedText: string): string[];
33
+ /**
34
+ * 검색 쿼리 예시 생성 (문서화용)
35
+ *
36
+ * @returns 검색 쿼리 예시 객체
37
+ */
38
+ export declare function getSearchQueryExamples(): {
39
+ description: string;
40
+ query: string;
41
+ explanation: string;
42
+ }[];
43
+ //# sourceMappingURL=reflection-notes-normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflection-notes-normalize.d.ts","sourceRoot":"","sources":["../../src/utils/reflection-notes-normalize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,GAAG,MAAM,CAmCjG;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE,CAUjE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB,EAAE,CAuBF"}