memento-mcp-server 1.11.0 → 1.11.1

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 (75) hide show
  1. package/README.md +7 -0
  2. package/dist/server/context.d.ts +36 -0
  3. package/dist/server/context.d.ts.map +1 -0
  4. package/dist/server/context.js +45 -0
  5. package/dist/server/context.js.map +1 -0
  6. package/dist/server/handlers/anchor-map.handler.d.ts +60 -0
  7. package/dist/server/handlers/anchor-map.handler.d.ts.map +1 -0
  8. package/dist/server/handlers/anchor-map.handler.js +190 -0
  9. package/dist/server/handlers/anchor-map.handler.js.map +1 -0
  10. package/dist/server/http-server.d.ts.map +1 -1
  11. package/dist/server/http-server.js +41 -1131
  12. package/dist/server/http-server.js.map +1 -1
  13. package/dist/server/middleware/error-handler.middleware.d.ts +25 -0
  14. package/dist/server/middleware/error-handler.middleware.d.ts.map +1 -0
  15. package/dist/server/middleware/error-handler.middleware.js +97 -0
  16. package/dist/server/middleware/error-handler.middleware.js.map +1 -0
  17. package/dist/server/middleware/index.d.ts +8 -0
  18. package/dist/server/middleware/index.d.ts.map +1 -0
  19. package/dist/server/middleware/index.js +8 -0
  20. package/dist/server/middleware/index.js.map +1 -0
  21. package/dist/server/middleware/service-injector.middleware.d.ts +30 -0
  22. package/dist/server/middleware/service-injector.middleware.d.ts.map +1 -0
  23. package/dist/server/middleware/service-injector.middleware.js +20 -0
  24. package/dist/server/middleware/service-injector.middleware.js.map +1 -0
  25. package/dist/server/middleware/tool-context.middleware.d.ts +29 -0
  26. package/dist/server/middleware/tool-context.middleware.d.ts.map +1 -0
  27. package/dist/server/middleware/tool-context.middleware.js +34 -0
  28. package/dist/server/middleware/tool-context.middleware.js.map +1 -0
  29. package/dist/server/routes/admin.routes.d.ts +12 -0
  30. package/dist/server/routes/admin.routes.d.ts.map +1 -0
  31. package/dist/server/routes/admin.routes.js +338 -0
  32. package/dist/server/routes/admin.routes.js.map +1 -0
  33. package/dist/server/routes/api.routes.d.ts +13 -0
  34. package/dist/server/routes/api.routes.d.ts.map +1 -0
  35. package/dist/server/routes/api.routes.js +122 -0
  36. package/dist/server/routes/api.routes.js.map +1 -0
  37. package/dist/server/routes/mcp.routes.d.ts +22 -0
  38. package/dist/server/routes/mcp.routes.d.ts.map +1 -0
  39. package/dist/server/routes/mcp.routes.js +383 -0
  40. package/dist/server/routes/mcp.routes.js.map +1 -0
  41. package/dist/server/routes/tools.routes.d.ts +13 -0
  42. package/dist/server/routes/tools.routes.d.ts.map +1 -0
  43. package/dist/server/routes/tools.routes.js +99 -0
  44. package/dist/server/routes/tools.routes.js.map +1 -0
  45. package/dist/services/anchor/anchor-cache-service.d.ts +77 -0
  46. package/dist/services/anchor/anchor-cache-service.d.ts.map +1 -0
  47. package/dist/services/anchor/anchor-cache-service.js +193 -0
  48. package/dist/services/anchor/anchor-cache-service.js.map +1 -0
  49. package/dist/services/anchor/anchor-interfaces.d.ts +143 -0
  50. package/dist/services/anchor/anchor-interfaces.d.ts.map +1 -0
  51. package/dist/services/anchor/anchor-interfaces.js +24 -0
  52. package/dist/services/anchor/anchor-interfaces.js.map +1 -0
  53. package/dist/services/anchor/anchor-manager.d.ts +71 -0
  54. package/dist/services/anchor/anchor-manager.d.ts.map +1 -0
  55. package/dist/services/anchor/anchor-manager.js +205 -0
  56. package/dist/services/anchor/anchor-manager.js.map +1 -0
  57. package/dist/services/anchor/anchor-search-service.d.ts +115 -0
  58. package/dist/services/anchor/anchor-search-service.d.ts.map +1 -0
  59. package/dist/services/anchor/anchor-search-service.js +799 -0
  60. package/dist/services/anchor/anchor-search-service.js.map +1 -0
  61. package/dist/services/anchor/index.d.ts +11 -0
  62. package/dist/services/anchor/index.d.ts.map +1 -0
  63. package/dist/services/anchor/index.js +10 -0
  64. package/dist/services/anchor/index.js.map +1 -0
  65. package/dist/services/anchor-manager.d.ts +22 -208
  66. package/dist/services/anchor-manager.d.ts.map +1 -1
  67. package/dist/services/anchor-manager.js +72 -1088
  68. package/dist/services/anchor-manager.js.map +1 -1
  69. package/dist/services/error-logging-service.d.ts +1 -0
  70. package/dist/services/error-logging-service.d.ts.map +1 -1
  71. package/dist/services/error-logging-service.js +2 -0
  72. package/dist/services/error-logging-service.js.map +1 -1
  73. package/dist/tools/forget-tool.js +1 -1
  74. package/dist/tools/forget-tool.js.map +1 -1
  75. package/package.json +3 -1
@@ -0,0 +1,383 @@
1
+ /**
2
+ * MCP 라우터
3
+ * /mcp, /messages 엔드포인트 처리
4
+ * Phase 1.2: http-server.ts 리팩토링
5
+ */
6
+ import { Router } from 'express';
7
+ import { getToolRegistry } from '../../tools/index.js';
8
+ import { createToolContext } from '../context.js';
9
+ import { logger } from '../../utils/logger.js';
10
+ /**
11
+ * MCP 라우터 생성
12
+ */
13
+ export function createMcpRouter(db, serverServices, transports) {
14
+ const router = Router();
15
+ // MCP SSE 엔드포인트
16
+ router.get('/mcp', async (req, res) => {
17
+ logger.info('MCP SSE client connection request');
18
+ try {
19
+ // SSE 헤더 설정
20
+ res.writeHead(200, {
21
+ 'Content-Type': 'text/event-stream',
22
+ 'Cache-Control': 'no-cache, no-transform',
23
+ 'Connection': 'keep-alive',
24
+ 'Access-Control-Allow-Origin': '*',
25
+ 'Access-Control-Allow-Headers': 'Cache-Control, Content-Type, Authorization',
26
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
27
+ 'X-Accel-Buffering': 'no'
28
+ });
29
+ // 세션 ID 생성
30
+ const sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
31
+ // 엔드포인트 이벤트 전송
32
+ const endpointUrl = `/messages?sessionId=${sessionId}`;
33
+ res.write(`event: endpoint\ndata: ${endpointUrl}\n\n`);
34
+ // MCP 서버 준비 완료 알림
35
+ res.write(`data: {"type": "ready"}\n\n`);
36
+ // Keep-alive ping 전송
37
+ const keepAliveInterval = setInterval(() => {
38
+ if (res.writableEnded) {
39
+ clearInterval(keepAliveInterval);
40
+ return;
41
+ }
42
+ try {
43
+ res.write(`data: {"type": "ping"}\n\n`);
44
+ }
45
+ catch (error) {
46
+ clearInterval(keepAliveInterval);
47
+ }
48
+ }, 30000); // 30초마다 ping
49
+ // Transport 정보 저장
50
+ transports[sessionId] = {
51
+ res: res,
52
+ sessionId: sessionId,
53
+ keepAliveInterval: keepAliveInterval
54
+ };
55
+ // 연결 종료 처리
56
+ req.on('close', () => {
57
+ logger.info('MCP SSE client connection closed', { sessionId });
58
+ clearInterval(keepAliveInterval);
59
+ delete transports[sessionId];
60
+ });
61
+ req.on('error', (error) => {
62
+ if (error.code === 'ECONNRESET') {
63
+ logger.info('MCP SSE client connection closed (normal)', { sessionId });
64
+ }
65
+ else {
66
+ logger.error('MCP SSE connection error', {
67
+ sessionId,
68
+ error: error instanceof Error ? error.message : String(error)
69
+ });
70
+ }
71
+ clearInterval(keepAliveInterval);
72
+ delete transports[sessionId];
73
+ });
74
+ logger.info('MCP SSE stream setup completed', { sessionId });
75
+ return;
76
+ }
77
+ catch (error) {
78
+ logger.error('SSE stream setup failed', {
79
+ error: error instanceof Error ? error.message : String(error)
80
+ });
81
+ if (!res.headersSent) {
82
+ res.status(500).send('Error establishing SSE stream');
83
+ }
84
+ return;
85
+ }
86
+ });
87
+ // Messages 엔드포인트 (JSON-RPC 요청 수신)
88
+ router.post('/messages', async (req, res) => {
89
+ logger.info('MCP message received', { method: req.body.method });
90
+ // 세션 ID 추출
91
+ const sessionId = req.query.sessionId;
92
+ if (!sessionId) {
93
+ logger.error('No session ID provided in request URL');
94
+ res.status(400).send('Missing sessionId parameter');
95
+ return;
96
+ }
97
+ const transport = transports[sessionId];
98
+ if (!transport) {
99
+ logger.error('No active transport found for session ID', { sessionId });
100
+ res.status(404).send('Session not found');
101
+ return;
102
+ }
103
+ const message = req.body;
104
+ let result;
105
+ try {
106
+ if (message.method === 'initialize') {
107
+ logger.info('MCP initialize request processing');
108
+ result = {
109
+ jsonrpc: '2.0',
110
+ id: message.id,
111
+ result: {
112
+ protocolVersion: '2024-11-05',
113
+ capabilities: {
114
+ tools: {}
115
+ },
116
+ serverInfo: {
117
+ name: 'memento-memory',
118
+ version: '0.1.0'
119
+ }
120
+ }
121
+ };
122
+ }
123
+ else if (message.method === 'notifications/initialized') {
124
+ logger.info('MCP initialized notification received');
125
+ result = {
126
+ jsonrpc: '2.0',
127
+ id: message.id,
128
+ result: {}
129
+ };
130
+ }
131
+ else if (message.method === 'tools/list') {
132
+ logger.info('MCP tools/list request processing');
133
+ try {
134
+ const toolRegistry = getToolRegistry();
135
+ const tools = toolRegistry.getAll();
136
+ result = {
137
+ jsonrpc: '2.0',
138
+ id: message.id,
139
+ result: { tools }
140
+ };
141
+ // SSE 응답 즉시 전송
142
+ if (transport && transport.res && !transport.res.writableEnded) {
143
+ const sseData = `data: ${JSON.stringify(result)}\n\n`;
144
+ transport.res.write(sseData);
145
+ }
146
+ // HTTP 응답 전송
147
+ res.json({ status: 'ok' });
148
+ return;
149
+ }
150
+ catch (toolsError) {
151
+ logger.error('tools/list processing error', {
152
+ error: toolsError instanceof Error ? toolsError.message : String(toolsError)
153
+ });
154
+ const errorResult = {
155
+ jsonrpc: '2.0',
156
+ id: message.id,
157
+ error: {
158
+ code: -32603,
159
+ message: 'Internal error',
160
+ data: toolsError instanceof Error ? toolsError.message : String(toolsError)
161
+ }
162
+ };
163
+ if (transport && transport.res && !transport.res.writableEnded) {
164
+ transport.res.write(`data: ${JSON.stringify(errorResult)}\n\n`);
165
+ }
166
+ res.json({ status: 'error' });
167
+ return;
168
+ }
169
+ }
170
+ else if (message.method === 'tools/call') {
171
+ const { name, arguments: args } = message.params;
172
+ if (!serverServices) {
173
+ result = {
174
+ jsonrpc: '2.0',
175
+ id: message.id,
176
+ error: {
177
+ code: -32603,
178
+ message: 'Internal error',
179
+ data: '서비스가 초기화되지 않았습니다'
180
+ }
181
+ };
182
+ }
183
+ else {
184
+ // ToolContext 생성 (Phase 0의 공통 모듈 사용)
185
+ const serverContext = {
186
+ db: db,
187
+ services: serverServices
188
+ };
189
+ const toolContext = createToolContext(serverContext);
190
+ // 도구 실행
191
+ const toolRegistry = getToolRegistry();
192
+ const toolResult = await toolRegistry.execute(name, args, toolContext);
193
+ result = {
194
+ jsonrpc: '2.0',
195
+ id: message.id,
196
+ result: { content: [{ type: 'text', text: JSON.stringify(toolResult) }] }
197
+ };
198
+ }
199
+ }
200
+ else if (message.method === 'prompts/list') {
201
+ logger.info('MCP prompts/list request processing');
202
+ const prompts = [
203
+ {
204
+ name: 'memory_injection',
205
+ description: '관련 기억을 요약하여 프롬프트에 주입',
206
+ arguments: [
207
+ {
208
+ name: 'query',
209
+ description: '검색할 쿼리',
210
+ required: true
211
+ },
212
+ {
213
+ name: 'token_budget',
214
+ description: '토큰 예산 (기본값: 1000)',
215
+ required: false
216
+ },
217
+ {
218
+ name: 'max_memories',
219
+ description: '최대 기억 개수 (기본값: 5)',
220
+ required: false
221
+ }
222
+ ]
223
+ }
224
+ ];
225
+ result = {
226
+ jsonrpc: '2.0',
227
+ id: message.id,
228
+ result: { prompts }
229
+ };
230
+ }
231
+ else if (message.method === 'prompts/get') {
232
+ const { name } = message.params;
233
+ if (name === 'memory_injection') {
234
+ result = {
235
+ jsonrpc: '2.0',
236
+ id: message.id,
237
+ result: {
238
+ description: '관련 기억을 요약하여 프롬프트에 주입',
239
+ arguments: [
240
+ {
241
+ name: 'query',
242
+ description: '검색할 쿼리',
243
+ required: true
244
+ },
245
+ {
246
+ name: 'token_budget',
247
+ description: '토큰 예산 (기본값: 1000)',
248
+ required: false
249
+ },
250
+ {
251
+ name: 'max_memories',
252
+ description: '최대 기억 개수 (기본값: 5)',
253
+ required: false
254
+ }
255
+ ]
256
+ }
257
+ };
258
+ }
259
+ else {
260
+ result = {
261
+ jsonrpc: '2.0',
262
+ id: message.id,
263
+ error: {
264
+ code: -32601,
265
+ message: 'Prompt not found'
266
+ }
267
+ };
268
+ }
269
+ }
270
+ else if (message.method === 'prompts/call') {
271
+ const { name, arguments: args } = message.params;
272
+ if (name === 'memory_injection') {
273
+ try {
274
+ if (!serverServices) {
275
+ result = {
276
+ jsonrpc: '2.0',
277
+ id: message.id,
278
+ error: {
279
+ code: -32603,
280
+ message: 'Internal error',
281
+ data: '서비스가 초기화되지 않았습니다'
282
+ }
283
+ };
284
+ }
285
+ else {
286
+ // MemoryInjectionPrompt 도구 사용
287
+ const toolRegistry = getToolRegistry();
288
+ const serverContext = {
289
+ db: db,
290
+ services: serverServices
291
+ };
292
+ const toolContext = createToolContext(serverContext);
293
+ const promptResult = await toolRegistry.execute('memory_injection', args, toolContext);
294
+ result = {
295
+ jsonrpc: '2.0',
296
+ id: message.id,
297
+ result: promptResult
298
+ };
299
+ }
300
+ }
301
+ catch (error) {
302
+ result = {
303
+ jsonrpc: '2.0',
304
+ id: message.id,
305
+ error: {
306
+ code: -32603,
307
+ message: 'Prompt execution failed',
308
+ data: error instanceof Error ? error.message : 'Unknown error'
309
+ }
310
+ };
311
+ }
312
+ }
313
+ else {
314
+ result = {
315
+ jsonrpc: '2.0',
316
+ id: message.id,
317
+ error: {
318
+ code: -32601,
319
+ message: 'Prompt not found'
320
+ }
321
+ };
322
+ }
323
+ }
324
+ else {
325
+ result = {
326
+ jsonrpc: '2.0',
327
+ id: message.id,
328
+ error: {
329
+ code: -32601,
330
+ message: 'Method not found'
331
+ }
332
+ };
333
+ }
334
+ // SSE 응답 전송
335
+ try {
336
+ if (!transport || !transport.res || transport.res.writableEnded) {
337
+ logger.error('SSE transport invalid');
338
+ res.status(500).json({ error: 'SSE transport invalid' });
339
+ return;
340
+ }
341
+ const sseData = `data: ${JSON.stringify(result)}\n\n`;
342
+ transport.res.write(sseData);
343
+ }
344
+ catch (sseError) {
345
+ logger.error('SSE response send failed', {
346
+ error: sseError instanceof Error ? sseError.message : String(sseError)
347
+ });
348
+ }
349
+ // HTTP 응답 전송
350
+ res.json({ status: 'ok' });
351
+ }
352
+ catch (error) {
353
+ logger.error('MCP message processing failed', {
354
+ error: error instanceof Error ? error.message : String(error)
355
+ });
356
+ const errorResponse = {
357
+ jsonrpc: '2.0',
358
+ id: message?.id || null,
359
+ error: {
360
+ code: -32603,
361
+ message: 'Internal error',
362
+ data: error instanceof Error ? error.message : 'Unknown error'
363
+ }
364
+ };
365
+ // SSE 에러 응답 전송
366
+ try {
367
+ if (transport && transport.res && !transport.res.writableEnded) {
368
+ const errorSseData = `data: ${JSON.stringify(errorResponse)}\n\n`;
369
+ transport.res.write(errorSseData);
370
+ }
371
+ }
372
+ catch (errorSseError) {
373
+ logger.error('SSE error response send failed', {
374
+ error: errorSseError instanceof Error ? errorSseError.message : String(errorSseError)
375
+ });
376
+ }
377
+ // HTTP 응답 전송
378
+ res.json({ status: 'error' });
379
+ }
380
+ });
381
+ return router;
382
+ }
383
+ //# sourceMappingURL=mcp.routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.routes.js","sourceRoot":"","sources":["../../../src/server/routes/mcp.routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Tools 라우터
3
+ * /tools/* 엔드포인트 처리
4
+ * Phase 1.2: http-server.ts 리팩토링
5
+ */
6
+ import { Router } from 'express';
7
+ import type { ServerServices } from '../bootstrap.js';
8
+ import type Database from 'better-sqlite3';
9
+ /**
10
+ * Tools 라우터 생성
11
+ */
12
+ export declare function createToolsRouter(db: Database.Database, serverServices: ServerServices | null, anchorMapSubscribers: Map<string, Set<any>>): Router;
13
+ //# sourceMappingURL=tools.routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.routes.d.ts","sourceRoot":"","sources":["../../../src/server/routes/tools.routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAI3C;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,cAAc,EAAE,cAAc,GAAG,IAAI,EACrC,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAC1C,MAAM,CA4FR"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Tools 라우터
3
+ * /tools/* 엔드포인트 처리
4
+ * Phase 1.2: http-server.ts 리팩토링
5
+ */
6
+ import { Router } from 'express';
7
+ import { getToolRegistry } from '../../tools/index.js';
8
+ import { broadcastAnchorMapUpdate } from '../handlers/anchor-map.handler.js';
9
+ import { logger } from '../../utils/logger.js';
10
+ /**
11
+ * Tools 라우터 생성
12
+ */
13
+ export function createToolsRouter(db, serverServices, anchorMapSubscribers) {
14
+ const router = Router();
15
+ // 도구 목록 조회
16
+ router.get('/', (req, res) => {
17
+ try {
18
+ const toolRegistry = getToolRegistry();
19
+ const tools = toolRegistry.getAll();
20
+ res.json({
21
+ tools,
22
+ count: tools.length,
23
+ server: 'Memento MCP Server'
24
+ });
25
+ }
26
+ catch (error) {
27
+ logger.error('Tool list retrieval failed', {
28
+ error: error instanceof Error ? error.message : String(error)
29
+ });
30
+ res.status(500).json({
31
+ error: 'Failed to get tools',
32
+ message: error instanceof Error ? error.message : 'Unknown error'
33
+ });
34
+ }
35
+ });
36
+ // 도구 실행
37
+ router.post('/:name', async (req, res) => {
38
+ const { name } = req.params;
39
+ const params = req.body;
40
+ try {
41
+ const toolRegistry = getToolRegistry();
42
+ // Phase 0: 미들웨어에서 주입된 ToolContext 사용
43
+ if (!req.toolContext) {
44
+ return res.status(500).json({
45
+ error: 'ToolContext not initialized',
46
+ message: 'ToolContext가 초기화되지 않았습니다. tool-context 미들웨어를 먼저 적용하세요.'
47
+ });
48
+ }
49
+ const toolContext = req.toolContext;
50
+ // 도구 실행
51
+ const toolResult = await toolRegistry.execute(name, params, toolContext);
52
+ // MCP 형식의 ToolResult에서 실제 데이터 추출
53
+ let actualResult = toolResult;
54
+ if (toolResult.content && Array.isArray(toolResult.content) && toolResult.content.length > 0) {
55
+ const firstContent = toolResult.content[0];
56
+ if (firstContent && firstContent.text) {
57
+ try {
58
+ const textContent = firstContent.text;
59
+ actualResult = JSON.parse(textContent);
60
+ }
61
+ catch (parseError) {
62
+ // JSON 파싱 실패 시 원본 content 사용
63
+ actualResult = toolResult;
64
+ }
65
+ }
66
+ }
67
+ // 앵커 관련 도구 실행 후 WebSocket 브로드캐스트
68
+ if (name === 'set_anchor' || name === 'clear_anchor') {
69
+ const agentId = params.agent_id || 'default';
70
+ // 비동기로 브로드캐스트 (응답 지연 방지)
71
+ setImmediate(() => {
72
+ broadcastAnchorMapUpdate(db, serverServices, anchorMapSubscribers, agentId).catch(error => {
73
+ logger.error('Anchor Map broadcast failed', {
74
+ error: error instanceof Error ? error.message : String(error)
75
+ });
76
+ });
77
+ });
78
+ }
79
+ return res.json({
80
+ result: actualResult,
81
+ tool: name,
82
+ timestamp: new Date().toISOString()
83
+ });
84
+ }
85
+ catch (error) {
86
+ logger.error('Tool execution failed', {
87
+ tool: name,
88
+ error: error instanceof Error ? error.message : String(error)
89
+ });
90
+ return res.status(500).json({
91
+ error: 'Tool execution failed',
92
+ tool: name,
93
+ message: error instanceof Error ? error.message : 'Unknown error'
94
+ });
95
+ }
96
+ });
97
+ return router;
98
+ }
99
+ //# sourceMappingURL=tools.routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.routes.js","sourceRoot":"","sources":["../../../src/server/routes/tools.routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Anchor Cache Service
3
+ * 캐시 및 임베딩 관리 담당
4
+ * Phase 1.1: anchor-manager.ts 리팩토링
5
+ */
6
+ import type Database from 'better-sqlite3';
7
+ import type { MemoryEmbeddingService } from '../memory-embedding-service.js';
8
+ import type { IAnchorCacheService, AnchorSlot } from './anchor-interfaces.js';
9
+ /**
10
+ * Anchor Cache Service 구현
11
+ */
12
+ export declare class AnchorCacheService implements IAnchorCacheService {
13
+ /**
14
+ * 메모리 캐시: agent_id별 슬롯 상태 관리
15
+ * Map<agent_id, {A: memory_id | null, B: memory_id | null, C: memory_id | null}>
16
+ */
17
+ private cache;
18
+ private db;
19
+ private embeddingService;
20
+ /**
21
+ * 생성자
22
+ */
23
+ constructor();
24
+ /**
25
+ * 데이터베이스 설정
26
+ */
27
+ setDatabase(db: Database.Database): void;
28
+ /**
29
+ * 임베딩 서비스 설정
30
+ */
31
+ setEmbeddingService(embeddingService: MemoryEmbeddingService): void;
32
+ /**
33
+ * 앵커 메모리의 임베딩 조회
34
+ * @param memoryId - 메모리 ID
35
+ * @returns 임베딩 벡터 및 제공자 정보, 없으면 null
36
+ */
37
+ getAnchorEmbedding(memoryId: string): Promise<{
38
+ embedding: number[];
39
+ provider: string;
40
+ } | null>;
41
+ /**
42
+ * 서버 재시작 시 DB에서 캐시 복원
43
+ * @param db - 데이터베이스 인스턴스
44
+ */
45
+ restoreCacheFromDB(db: Database.Database): Promise<void>;
46
+ /**
47
+ * 캐시 업데이트 헬퍼 메서드
48
+ * @param agentId - 에이전트 ID
49
+ * @param slot - 슬롯
50
+ * @param memoryId - 메모리 ID (null이면 제거)
51
+ */
52
+ updateCache(agentId: string, slot: AnchorSlot, memoryId: string | null): void;
53
+ /**
54
+ * 캐시에서 앵커 조회
55
+ * @param agentId - 에이전트 ID
56
+ * @param slot - 슬롯 (선택적)
57
+ * @returns 캐시된 앵커 정보
58
+ */
59
+ getCachedAnchor(agentId: string, slot?: AnchorSlot): {
60
+ A: string | null;
61
+ B: string | null;
62
+ C: string | null;
63
+ } | undefined;
64
+ /**
65
+ * 캐시에서 특정 슬롯의 메모리 ID 조회
66
+ * @param agentId - 에이전트 ID
67
+ * @param slot - 슬롯
68
+ * @returns 메모리 ID 또는 undefined
69
+ */
70
+ getCachedMemoryId(agentId: string, slot: AnchorSlot): string | null | undefined;
71
+ /**
72
+ * 캐시 삭제
73
+ * @param agentId - 에이전트 ID
74
+ */
75
+ deleteCache(agentId: string): void;
76
+ }
77
+ //# sourceMappingURL=anchor-cache-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor-cache-service.d.ts","sourceRoot":"","sources":["../../../src/services/anchor/anchor-cache-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAG9E;;GAEG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB;IAC5D;;;OAGG;IACH,OAAO,CAAC,KAAK,CAAoF;IAEjG,OAAO,CAAC,EAAE,CAAkC;IAC5C,OAAO,CAAC,gBAAgB,CAAuC;IAE/D;;OAEG;;IAKH;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI;IAOxC;;OAEG;IACH,mBAAmB,CAAC,gBAAgB,EAAE,sBAAsB,GAAG,IAAI;IAOnE;;;;OAIG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAsErG;;;OAGG;IACG,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAoD9D;;;;;OAKG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAS7E;;;;;OAKG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG;QAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,SAAS;IAIzH;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS;IAK/E;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAGnC"}