opcode-pg-memory 2.2.8 → 2.3.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 (76) hide show
  1. package/dist/cli.js +232 -214
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +30 -21006
  5. package/dist/index.js.map +1 -0
  6. package/dist/mcp-server.js +319 -302
  7. package/dist/mcp-server.js.map +1 -0
  8. package/dist/src/cache/semantic-cache.js +399 -0
  9. package/dist/src/cache/semantic-cache.js.map +1 -0
  10. package/dist/src/cli.js +404 -0
  11. package/dist/src/cli.js.map +1 -0
  12. package/dist/src/config.d.ts +5 -0
  13. package/dist/src/config.d.ts.map +1 -1
  14. package/dist/src/config.js +89 -0
  15. package/dist/src/config.js.map +1 -0
  16. package/dist/src/db/init-db.js +545 -0
  17. package/dist/src/db/init-db.js.map +1 -0
  18. package/dist/src/hooks/message-part-updated.js +203 -0
  19. package/dist/src/hooks/message-part-updated.js.map +1 -0
  20. package/dist/src/hooks/message-updated.js +347 -0
  21. package/dist/src/hooks/message-updated.js.map +1 -0
  22. package/dist/src/hooks/session-compacting.js +179 -0
  23. package/dist/src/hooks/session-compacting.js.map +1 -0
  24. package/dist/src/hooks/session-completed.js +337 -0
  25. package/dist/src/hooks/session-completed.js.map +1 -0
  26. package/dist/src/hooks/session-created.js +206 -0
  27. package/dist/src/hooks/session-created.js.map +1 -0
  28. package/dist/src/hooks/tool-execute.js +267 -0
  29. package/dist/src/hooks/tool-execute.js.map +1 -0
  30. package/dist/src/index.d.ts +1 -0
  31. package/dist/src/index.d.ts.map +1 -1
  32. package/dist/src/index.js +642 -0
  33. package/dist/src/index.js.map +1 -0
  34. package/dist/src/mcp/hindsight-reflect-omo.js +318 -0
  35. package/dist/src/mcp/hindsight-reflect-omo.js.map +1 -0
  36. package/dist/src/mcp/hindsight-reflect.js +838 -0
  37. package/dist/src/mcp/hindsight-reflect.js.map +1 -0
  38. package/dist/src/mcp/recall-memory-omo.js +263 -0
  39. package/dist/src/mcp/recall-memory-omo.js.map +1 -0
  40. package/dist/src/mcp/recall-memory.d.ts +6 -0
  41. package/dist/src/mcp/recall-memory.d.ts.map +1 -1
  42. package/dist/src/mcp/recall-memory.js +900 -0
  43. package/dist/src/mcp/recall-memory.js.map +1 -0
  44. package/dist/src/omo/adapter.js +583 -0
  45. package/dist/src/omo/adapter.js.map +1 -0
  46. package/dist/src/omo/types.js +44 -0
  47. package/dist/src/omo/types.js.map +1 -0
  48. package/dist/src/services/db-polling.d.ts +33 -0
  49. package/dist/src/services/db-polling.d.ts.map +1 -0
  50. package/dist/src/services/db-polling.js +104 -0
  51. package/dist/src/services/db-polling.js.map +1 -0
  52. package/dist/src/services/event-synchronizer.d.ts +15 -0
  53. package/dist/src/services/event-synchronizer.d.ts.map +1 -0
  54. package/dist/src/services/event-synchronizer.js +119 -0
  55. package/dist/src/services/event-synchronizer.js.map +1 -0
  56. package/dist/src/services/keyword.js +29 -0
  57. package/dist/src/services/keyword.js.map +1 -0
  58. package/dist/src/services/logger.js +42 -0
  59. package/dist/src/services/logger.js.map +1 -0
  60. package/dist/src/services/opencode-schema-adapter.d.ts +100 -0
  61. package/dist/src/services/opencode-schema-adapter.d.ts.map +1 -0
  62. package/dist/src/services/opencode-schema-adapter.js +192 -0
  63. package/dist/src/services/opencode-schema-adapter.js.map +1 -0
  64. package/dist/src/services/privacy.js +23 -0
  65. package/dist/src/services/privacy.js.map +1 -0
  66. package/dist/src/topic/segment-manager.js +447 -0
  67. package/dist/src/topic/segment-manager.js.map +1 -0
  68. package/dist/src/types.d.ts +20 -2
  69. package/dist/src/types.d.ts.map +1 -1
  70. package/dist/src/types.js +8 -0
  71. package/dist/src/types.js.map +1 -0
  72. package/dist/src/utils/embedding.js +180 -0
  73. package/dist/src/utils/embedding.js.map +1 -0
  74. package/dist/src/utils/token-budget.js +152 -0
  75. package/dist/src/utils/token-budget.js.map +1 -0
  76. package/package.json +5 -4
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleMessagePartUpdated = handleMessagePartUpdated;
4
+ exports.cleanupExpiredAccumulators = cleanupExpiredAccumulators;
5
+ const logger_1 = require("../services/logger");
6
+ const logger = (0, logger_1.createLogger)('message-part-updated');
7
+ const DEFAULT_CONFIG = {
8
+ maxContentLength: 10000,
9
+ accumulationTimeoutMs: 5000
10
+ };
11
+ // 内存中的部分消息累积器
12
+ // 注意:生产环境应使用 Redis 等外部存储
13
+ const partAccumulators = new Map();
14
+ /**
15
+ * 处理 message.part.updated 事件
16
+ *
17
+ * 功能:
18
+ * 1. 监听工具输出的增量更新
19
+ * 2. 触发经验增量记录
20
+ * 3. 累积部分内容,在 isComplete = true 时统一处理
21
+ *
22
+ * 签名规范:(input, output) => Promise<void>
23
+ */
24
+ async function handleMessagePartUpdated(input, output, // ✅ 添加 output 参数
25
+ pool, config = {}) {
26
+ const mergedConfig = { ...DEFAULT_CONFIG, ...config };
27
+ const { session, message } = input;
28
+ logger.info(`Message part updated: ${message.id}, partIndex: ${message.partIndex}, isComplete: ${message.isComplete}`);
29
+ try {
30
+ // 获取 session 内部 ID
31
+ const sessionResult = await pool.query('SELECT id FROM session_map WHERE opencode_session_id = $1', [session.id]);
32
+ if (sessionResult.rows.length === 0) {
33
+ logger.warn(`Session not found: ${session.id}`);
34
+ return; // ✅ 返回 void
35
+ }
36
+ const sessionInternalId = sessionResult.rows[0].id;
37
+ const accumulatorKey = `${sessionInternalId}:${message.id}`;
38
+ // 获取或创建累积器
39
+ let accumulator = partAccumulators.get(accumulatorKey);
40
+ if (!accumulator) {
41
+ accumulator = {
42
+ contents: [],
43
+ lastUpdate: Date.now(),
44
+ sessionId: sessionInternalId,
45
+ messageId: message.id
46
+ };
47
+ partAccumulators.set(accumulatorKey, accumulator);
48
+ }
49
+ // 累积内容
50
+ accumulator.contents.push(message.content);
51
+ accumulator.lastUpdate = Date.now();
52
+ // 如果内容完成,处理累积的内容
53
+ if (message.isComplete) {
54
+ await processCompletedParts(accumulatorKey, pool);
55
+ }
56
+ else {
57
+ // 设置超时处理(防止部分消息丢失)
58
+ scheduleAccumulationTimeout(accumulatorKey, pool, mergedConfig.accumulationTimeoutMs);
59
+ }
60
+ // ✅ 正确的钩子签名:不返回任何值
61
+ }
62
+ catch (error) {
63
+ logger.error('Error handling message.part.updated:', error);
64
+ // 出错时不阻断主流程
65
+ }
66
+ }
67
+ /**
68
+ * 处理完成的部分消息
69
+ */
70
+ async function processCompletedParts(accumulatorKey, pool) {
71
+ const accumulator = partAccumulators.get(accumulatorKey);
72
+ if (!accumulator) {
73
+ return;
74
+ }
75
+ // 合并所有部分内容
76
+ const fullContent = accumulator.contents.join('');
77
+ // 清理累积器
78
+ partAccumulators.delete(accumulatorKey);
79
+ if (fullContent.length === 0) {
80
+ return;
81
+ }
82
+ logger.info(`Processing completed parts for message: ${accumulator.messageId}`);
83
+ // 生成摘要
84
+ const summary = generatePartSummary(fullContent);
85
+ // 存储为观察记录
86
+ await pool.query(`
87
+ INSERT INTO observations (
88
+ session_id,
89
+ tool_output_summary,
90
+ message_id,
91
+ importance,
92
+ metadata
93
+ ) VALUES ($1, $2, $3, $4, $5)
94
+ `, [
95
+ accumulator.sessionId,
96
+ summary,
97
+ accumulator.messageId,
98
+ calculatePartImportance(fullContent),
99
+ JSON.stringify({
100
+ source: 'message.part.updated',
101
+ isAccumulated: true,
102
+ partCount: accumulator.contents.length,
103
+ contentLength: fullContent.length
104
+ })
105
+ ]);
106
+ logger.info(`Stored accumulated observation for message: ${accumulator.messageId}`);
107
+ }
108
+ /**
109
+ * 设置累积超时处理
110
+ */
111
+ function scheduleAccumulationTimeout(accumulatorKey, pool, timeoutMs) {
112
+ setTimeout(async () => {
113
+ const accumulator = partAccumulators.get(accumulatorKey);
114
+ if (!accumulator) {
115
+ return;
116
+ }
117
+ // 检查是否超时(可能已经被完成处理)
118
+ const timeSinceLastUpdate = Date.now() - accumulator.lastUpdate;
119
+ if (timeSinceLastUpdate >= timeoutMs * 0.8) {
120
+ // 超时,强制处理
121
+ logger.info(`Accumulation timeout for message: ${accumulator.messageId}`);
122
+ await processCompletedParts(accumulatorKey, pool);
123
+ }
124
+ }, timeoutMs);
125
+ }
126
+ /**
127
+ * 生成部分内容摘要
128
+ */
129
+ function generatePartSummary(content) {
130
+ const maxLength = 1000;
131
+ // 提取关键信息
132
+ const lines = content.split('\n');
133
+ const keyLines = [];
134
+ for (const line of lines) {
135
+ const trimmed = line.trim();
136
+ // 关注错误、警告、成功等关键信息
137
+ if (trimmed.toLowerCase().includes('error') ||
138
+ trimmed.toLowerCase().includes('warning') ||
139
+ trimmed.toLowerCase().includes('success') ||
140
+ trimmed.toLowerCase().includes('completed') ||
141
+ trimmed.toLowerCase().includes('failed') ||
142
+ trimmed.startsWith('>') ||
143
+ trimmed.startsWith('$')) {
144
+ keyLines.push(trimmed);
145
+ }
146
+ if (keyLines.length >= 10) {
147
+ break;
148
+ }
149
+ }
150
+ let summary = keyLines.join('\n');
151
+ // 如果关键行太少,添加内容开头
152
+ if (summary.length < 200) {
153
+ summary = content.substring(0, maxLength);
154
+ }
155
+ if (summary.length > maxLength) {
156
+ summary = summary.substring(0, maxLength) + '... [truncated]';
157
+ }
158
+ return summary;
159
+ }
160
+ /**
161
+ * 计算部分内容的重要性
162
+ */
163
+ function calculatePartImportance(content) {
164
+ let importance = 3; // 默认中等
165
+ const lowerContent = content.toLowerCase();
166
+ // 包含错误信息
167
+ if (lowerContent.includes('error') || lowerContent.includes('exception')) {
168
+ importance += 1;
169
+ }
170
+ // 包含警告信息
171
+ if (lowerContent.includes('warning') || lowerContent.includes('warn')) {
172
+ importance += 0.5;
173
+ }
174
+ // 包含成功信息
175
+ if (lowerContent.includes('success') || lowerContent.includes('completed')) {
176
+ importance += 0.5;
177
+ }
178
+ // 内容较长可能更复杂
179
+ if (content.length > 5000) {
180
+ importance += 0.5;
181
+ }
182
+ return Math.min(5, importance);
183
+ }
184
+ /**
185
+ * 清理过期的累积器(防止内存泄漏)
186
+ * 应定期调用
187
+ */
188
+ function cleanupExpiredAccumulators(maxAgeMs = 300000) {
189
+ const now = Date.now();
190
+ let cleaned = 0;
191
+ for (const [key, accumulator] of partAccumulators.entries()) {
192
+ if (now - accumulator.lastUpdate > maxAgeMs) {
193
+ partAccumulators.delete(key);
194
+ cleaned++;
195
+ }
196
+ }
197
+ if (cleaned > 0) {
198
+ logger.info(`Cleaned up ${cleaned} expired accumulators`);
199
+ }
200
+ }
201
+ // 每 5 分钟清理一次过期累积器
202
+ setInterval(() => cleanupExpiredAccumulators(), 300000);
203
+ //# sourceMappingURL=message-part-updated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-part-updated.js","sourceRoot":"","sources":["../../../src/hooks/message-part-updated.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,347 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleMessageUpdated = handleMessageUpdated;
4
+ const privacy_1 = require("../services/privacy");
5
+ const logger_1 = require("../services/logger");
6
+ const logger = (0, logger_1.createLogger)('message-updated');
7
+ const DEFAULT_CONFIG = {
8
+ minConfidence: 0.5,
9
+ minEntityNameLength: 2,
10
+ maxEntitiesPerMessage: 10,
11
+ maxRelationsPerEntity: 5
12
+ };
13
+ /**
14
+ * 处理 message.updated 事件
15
+ *
16
+ * 功能:
17
+ * 1. 存储原始消息到 messages 表
18
+ * 2. 异步调用 LLM 提取命名实体
19
+ * 3. 识别实体间关系
20
+ * 4. 写入 entities 表(置信度 < 0.5 的不写入)
21
+ * 5. 写入 relations 表(置信度 < 0.5 的不写入)
22
+ * 6. 更新实体 weight 和 last_seen_at
23
+ *
24
+ * 签名规范:(input, output) => Promise<void>
25
+ */
26
+ async function handleMessageUpdated(input, output, // ✅ 添加 output 参数
27
+ pool, config = {}) {
28
+ const mergedConfig = { ...DEFAULT_CONFIG, ...config };
29
+ const { session, message } = input;
30
+ logger.info(`Message updated: ${message.id}, role: ${message.role}`);
31
+ try {
32
+ // 1. 存储原始消息(异步,不阻塞主流程)
33
+ storeMessage(session.id, message, pool).catch(err => logger.warn('Failed to store message:', err.message));
34
+ // 2. 获取 session 内部 ID
35
+ const sessionResult = await pool.query('SELECT id FROM session_map WHERE opencode_session_id = $1', [session.id]);
36
+ if (sessionResult.rows.length === 0) {
37
+ logger.warn(`Session not found: ${session.id}`);
38
+ return; // ✅ 返回 void
39
+ }
40
+ const sessionInternalId = sessionResult.rows[0].id;
41
+ // 3. 提取实体(异步,不阻塞主流程)
42
+ extractEntitiesAndRelations(sessionInternalId, message.content, session.id, pool, mergedConfig).catch(err => logger.warn('Failed to extract entities:', err.message));
43
+ // ✅ 正确的钩子签名:不返回任何值
44
+ }
45
+ catch (error) {
46
+ logger.error('Error handling message.updated:', error);
47
+ // 出错时不阻断主流程
48
+ }
49
+ }
50
+ /**
51
+ * 存储原始消息到 messages 表
52
+ * 支持 OpenCode 的完整消息结构(包含 parts 数组)
53
+ */
54
+ async function storeMessage(sessionId, message, pool) {
55
+ try {
56
+ // 提取 reasoning 内容
57
+ const reasoningPart = message.parts?.find(p => p.type === 'reasoning');
58
+ const reasoning = reasoningPart?.text || null;
59
+ // 提取主要文本内容
60
+ const textPart = message.parts?.find(p => p.type === 'text');
61
+ const content = textPart?.text || message.content || '';
62
+ // 提取工具调用信息
63
+ const toolParts = message.parts?.filter(p => p.type === 'tool') || [];
64
+ const toolCalls = toolParts.map(p => ({
65
+ type: p.type,
66
+ tool: p.tool?.name || '',
67
+ callID: p.tool?.callID || '',
68
+ input: p.tool?.state?.input || {},
69
+ output: p.tool?.state?.output || null,
70
+ status: p.tool?.state?.status || 'pending'
71
+ }));
72
+ // 计算总 token
73
+ const tokenTotal = message.tokens?.total || 0;
74
+ await pool.query(`
75
+ INSERT INTO messages (
76
+ session_id,
77
+ message_id,
78
+ role,
79
+ raw_message,
80
+ reasoning,
81
+ content,
82
+ tool_calls,
83
+ token_input,
84
+ token_output,
85
+ token_reasoning,
86
+ token_total,
87
+ cost,
88
+ model_id,
89
+ agent,
90
+ mode,
91
+ finish_reason,
92
+ created_at,
93
+ completed_at,
94
+ embedding
95
+ ) VALUES (
96
+ (SELECT id FROM session_map WHERE opencode_session_id = $1),
97
+ $2, $3, $4, $5, $6, $7,
98
+ $8, $9, $10, $11, $12, $13, $14, $15, $16,
99
+ TO_TIMESTAMP($17/1000),
100
+ CASE WHEN $18 IS NOT NULL THEN TO_TIMESTAMP($18/1000) ELSE NULL END,
101
+ NULL
102
+ )
103
+ ON CONFLICT (message_id) DO UPDATE SET
104
+ raw_message = EXCLUDED.raw_message,
105
+ reasoning = EXCLUDED.reasoning,
106
+ content = EXCLUDED.content,
107
+ tool_calls = EXCLUDED.tool_calls,
108
+ token_input = EXCLUDED.token_input,
109
+ token_output = EXCLUDED.token_output,
110
+ token_reasoning = EXCLUDED.token_reasoning,
111
+ token_total = EXCLUDED.token_total,
112
+ cost = EXCLUDED.cost,
113
+ completed_at = EXCLUDED.completed_at,
114
+ finish_reason = EXCLUDED.finish_reason
115
+ `, [
116
+ sessionId,
117
+ message.id,
118
+ message.role,
119
+ JSON.stringify(message),
120
+ reasoning,
121
+ content,
122
+ toolCalls.length > 0 ? JSON.stringify(toolCalls) : null,
123
+ message.tokens?.input || 0,
124
+ message.tokens?.output || 0,
125
+ message.tokens?.reasoning || 0,
126
+ tokenTotal,
127
+ message.cost || 0,
128
+ message.modelID || null,
129
+ message.agent || null,
130
+ message.mode || null,
131
+ message.finish || null,
132
+ message.time?.created || Date.now(),
133
+ message.time?.completed
134
+ ]);
135
+ logger.info(`Stored message: ${message.id} (${message.role}, ${tokenTotal} tokens)`);
136
+ }
137
+ catch (error) {
138
+ logger.error('Failed to store message:', error);
139
+ throw error;
140
+ }
141
+ }
142
+ /**
143
+ * 从消息内容中提取实体和关系(统一入口)
144
+ */
145
+ async function extractEntitiesAndRelations(sessionId, content, externalSessionId, pool, config) {
146
+ const extractedEntities = await extractEntities(content, sessionId, pool, config);
147
+ logger.info(`Extracted ${extractedEntities.length} entities`);
148
+ if (extractedEntities.length >= 2) {
149
+ await extractAndStoreRelations(extractedEntities, content, sessionId, pool, config);
150
+ }
151
+ }
152
+ /**
153
+ * 从消息内容中提取实体
154
+ *
155
+ * 注意:这是一个简化实现。生产环境应该调用 LLM API 进行 NER。
156
+ */
157
+ async function extractEntities(content, sessionId, pool, config) {
158
+ const entities = [];
159
+ // 移除 <private> 标记内容后再进行实体提取
160
+ const sanitizedContent = (0, privacy_1.stripPrivateContent)(content);
161
+ // 基于规则的实体提取(简化版)
162
+ const extractedNames = heuristicEntityExtraction(sanitizedContent);
163
+ for (const extracted of extractedNames.slice(0, config.maxEntitiesPerMessage)) {
164
+ if (extracted.name.length < config.minEntityNameLength) {
165
+ continue;
166
+ }
167
+ // 模拟置信度(实际应从 LLM 获取)
168
+ const confidence = Math.random() * 0.5 + 0.5;
169
+ if (confidence < config.minConfidence) {
170
+ continue;
171
+ }
172
+ // 检查是否已存在相同实体
173
+ const existingResult = await pool.query(`
174
+ SELECT id, weight FROM entities
175
+ WHERE session_id = $1 AND name = $2 AND type = $3
176
+ `, [sessionId, extracted.name, extracted.type]);
177
+ if (existingResult.rows.length > 0) {
178
+ // 更新现有实体
179
+ const existingId = existingResult.rows[0].id;
180
+ const currentWeight = existingResult.rows[0].weight;
181
+ await pool.query(`
182
+ UPDATE entities
183
+ SET weight = LEAST(weight + 0.1, 10.0),
184
+ last_seen_at = NOW(),
185
+ confidence = GREATEST(confidence, $1)
186
+ WHERE id = $2
187
+ `, [confidence, existingId]);
188
+ entities.push({
189
+ id: existingId,
190
+ name: extracted.name,
191
+ type: extracted.type
192
+ });
193
+ logger.info(`Updated entity: ${extracted.name} (weight: ${(currentWeight + 0.1).toFixed(2)})`);
194
+ }
195
+ else {
196
+ // 创建新实体
197
+ const tier = determineEntityTier(extracted.type, content);
198
+ const insertResult = await pool.query(`
199
+ INSERT INTO entities (
200
+ session_id, name, type, tier, weight, description,
201
+ confidence, metadata
202
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
203
+ RETURNING id
204
+ `, [
205
+ sessionId,
206
+ extracted.name,
207
+ extracted.type,
208
+ tier,
209
+ 1.0,
210
+ generateEntityDescription(extracted.name, extracted.type, content),
211
+ confidence,
212
+ JSON.stringify({ source: 'message.updated' })
213
+ ]);
214
+ const newId = insertResult.rows[0].id;
215
+ entities.push({
216
+ id: newId,
217
+ name: extracted.name,
218
+ type: extracted.type
219
+ });
220
+ logger.info(`Created entity: ${extracted.name} (${extracted.type})`);
221
+ }
222
+ }
223
+ return entities;
224
+ }
225
+ /**
226
+ * 启发式实体提取(简化版)
227
+ */
228
+ function heuristicEntityExtraction(content) {
229
+ const entities = [];
230
+ const patterns = [
231
+ { regex: /function\s+(\w+)\s*\(/g, type: 'function' },
232
+ { regex: /(?:const|let|var)\s+(\w+)\s*=\s*(?:function|=>)/g, type: 'function' },
233
+ { regex: /class\s+(\w+)/g, type: 'class' },
234
+ { regex: /(?:const|let|var)\s+([A-Z_][A-Z0-9_]*)\s*=/g, type: 'constant' },
235
+ { regex: /['"]([\w\-./]+\.(?:ts|js|tsx|jsx|json|md))['"]/g, type: 'file' },
236
+ { regex: /from\s+['"]([@\w\-/.]+)['"]/g, type: 'module' },
237
+ { regex: /(?:TODO|FIXME|NOTE|HACK):?\s*(.+?)(?:\n|$)/gi, type: 'task' }
238
+ ];
239
+ for (const pattern of patterns) {
240
+ let match;
241
+ while ((match = pattern.regex.exec(content)) !== null) {
242
+ const name = match[1].trim();
243
+ if (name.length >= 2 && !entities.some(e => e.name === name)) {
244
+ entities.push({ name, type: pattern.type });
245
+ }
246
+ }
247
+ }
248
+ return entities;
249
+ }
250
+ /**
251
+ * 确定实体层级
252
+ */
253
+ function determineEntityTier(type, content) {
254
+ if (['constant', 'config', 'setting'].includes(type)) {
255
+ return 'permanent';
256
+ }
257
+ if (['module', 'class', 'interface'].includes(type)) {
258
+ return 'project';
259
+ }
260
+ return 'session';
261
+ }
262
+ /**
263
+ * 生成实体描述
264
+ */
265
+ function generateEntityDescription(name, type, content) {
266
+ const index = content.indexOf(name);
267
+ if (index === -1) {
268
+ return `${type}: ${name}`;
269
+ }
270
+ const start = Math.max(0, index - 100);
271
+ const end = Math.min(content.length, index + name.length + 100);
272
+ const context = content.substring(start, end);
273
+ return `${type}: ${name} - ${context.trim()}`;
274
+ }
275
+ /**
276
+ * 提取并存储实体间关系
277
+ */
278
+ async function extractAndStoreRelations(entities, content, sessionId, pool, config) {
279
+ for (let i = 0; i < entities.length; i++) {
280
+ const source = entities[i];
281
+ let relationsCreated = 0;
282
+ for (let j = 0; j < entities.length && relationsCreated < config.maxRelationsPerEntity; j++) {
283
+ if (i === j)
284
+ continue;
285
+ const target = entities[j];
286
+ const proximity = checkEntityProximity(source.name, target.name, content);
287
+ if (proximity.score > 0.3) {
288
+ const confidence = proximity.score * (0.5 + Math.random() * 0.5);
289
+ if (confidence < config.minConfidence) {
290
+ continue;
291
+ }
292
+ const relationType = inferRelationType(source.type, target.type, content);
293
+ const existingResult = await pool.query(`
294
+ SELECT id FROM relations
295
+ WHERE source_entity_id = $1 AND target_entity_id = $2
296
+ `, [source.id, target.id]);
297
+ if (existingResult.rows.length === 0) {
298
+ await pool.query(`
299
+ INSERT INTO relations (
300
+ source_entity_id, target_entity_id, relation_type,
301
+ confidence, description, session_id
302
+ ) VALUES ($1, $2, $3, $4, $5, $6)
303
+ `, [
304
+ source.id,
305
+ target.id,
306
+ relationType,
307
+ confidence,
308
+ `${source.name} ${relationType} ${target.name}`,
309
+ sessionId
310
+ ]);
311
+ relationsCreated++;
312
+ logger.info(`Created relation: ${source.name} ${relationType} ${target.name}`);
313
+ }
314
+ }
315
+ }
316
+ }
317
+ }
318
+ /**
319
+ * 检查两个实体在文本中的接近程度
320
+ */
321
+ function checkEntityProximity(name1, name2, content) {
322
+ const index1 = content.indexOf(name1);
323
+ const index2 = content.indexOf(name2);
324
+ if (index1 === -1 || index2 === -1) {
325
+ return { score: 0 };
326
+ }
327
+ const distance = Math.abs(index1 - index2);
328
+ const maxDistance = 500;
329
+ const score = Math.max(0, 1 - distance / maxDistance);
330
+ return { score };
331
+ }
332
+ /**
333
+ * 推断关系类型
334
+ */
335
+ function inferRelationType(sourceType, targetType, content) {
336
+ if (sourceType === 'class' && targetType === 'class') {
337
+ return content.includes('extends') ? 'belongs_to' : 'references';
338
+ }
339
+ if (sourceType === 'function' && targetType === 'function') {
340
+ return 'depends_on';
341
+ }
342
+ if (sourceType === 'module' || targetType === 'module') {
343
+ return 'uses';
344
+ }
345
+ return 'references';
346
+ }
347
+ //# sourceMappingURL=message-updated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-updated.js","sourceRoot":"","sources":["../../../src/hooks/message-updated.ts"],"names":[],"mappings":"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"}