@aalis/plugin-user-relation 0.4.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 (50) hide show
  1. package/LICENSE +21 -0
  2. package/dist/actions.d.ts +13 -0
  3. package/dist/actions.d.ts.map +1 -0
  4. package/dist/actions.js +705 -0
  5. package/dist/actions.js.map +1 -0
  6. package/dist/commands.d.ts +46 -0
  7. package/dist/commands.d.ts.map +1 -0
  8. package/dist/commands.js +601 -0
  9. package/dist/commands.js.map +1 -0
  10. package/dist/consolidate-llm.d.ts +150 -0
  11. package/dist/consolidate-llm.d.ts.map +1 -0
  12. package/dist/consolidate-llm.js +373 -0
  13. package/dist/consolidate-llm.js.map +1 -0
  14. package/dist/extractor.d.ts +308 -0
  15. package/dist/extractor.d.ts.map +1 -0
  16. package/dist/extractor.js +1356 -0
  17. package/dist/extractor.js.map +1 -0
  18. package/dist/index.d.ts +33 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +626 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/middleware.d.ts +41 -0
  23. package/dist/middleware.d.ts.map +1 -0
  24. package/dist/middleware.js +281 -0
  25. package/dist/middleware.js.map +1 -0
  26. package/dist/rename-watcher.d.ts +16 -0
  27. package/dist/rename-watcher.d.ts.map +1 -0
  28. package/dist/rename-watcher.js +16 -0
  29. package/dist/rename-watcher.js.map +1 -0
  30. package/dist/service.d.ts +1108 -0
  31. package/dist/service.d.ts.map +1 -0
  32. package/dist/service.js +4462 -0
  33. package/dist/service.js.map +1 -0
  34. package/dist/store.d.ts +89 -0
  35. package/dist/store.d.ts.map +1 -0
  36. package/dist/store.js +207 -0
  37. package/dist/store.js.map +1 -0
  38. package/dist/tools.d.ts +48 -0
  39. package/dist/tools.d.ts.map +1 -0
  40. package/dist/tools.js +1630 -0
  41. package/dist/tools.js.map +1 -0
  42. package/dist/types.d.ts +432 -0
  43. package/dist/types.d.ts.map +1 -0
  44. package/dist/types.js +94 -0
  45. package/dist/types.js.map +1 -0
  46. package/dist/utils.d.ts +419 -0
  47. package/dist/utils.d.ts.map +1 -0
  48. package/dist/utils.js +1630 -0
  49. package/dist/utils.js.map +1 -0
  50. package/package.json +57 -0
package/dist/index.js ADDED
@@ -0,0 +1,626 @@
1
+ import { useWebuiService } from '@aalis/plugin-webui-api';
2
+ import { actions as baseActions } from './actions.js';
3
+ import { registerRelationCommands } from './commands.js';
4
+ import { RelationExtractor } from './extractor.js';
5
+ import { registerRelationMiddleware } from './middleware.js';
6
+ import { startRenameWatcher } from './rename-watcher.js';
7
+ import { RelationService } from './service.js';
8
+ import { RELATION_NAMESPACE, RelationStore } from './store.js';
9
+ import { registerRelationTools } from './tools.js';
10
+ export const name = '@aalis/plugin-user-relation';
11
+ export const displayName = '人物关系图';
12
+ export const subsystem = 'memory';
13
+ export const provides = ['user-relation'];
14
+ export const inject = {
15
+ required: ['memory'],
16
+ optional: ['llm', 'webui-server', 'agent', 'tools', 'embedding'],
17
+ };
18
+ export const configSchema = {
19
+ // ────── 抽取(写入)侧 ──────
20
+ extractionEnabled: {
21
+ type: 'boolean',
22
+ label: '允许从对话中提取新关系(写入总开关)',
23
+ description: '**写入总开关**:关闭后插件停止生成任何新关系节点/边(自动触发、手动 /relation extract、Agent upsert_* 工具全部失效);但 middleware 仍读取并注入旧关系、actions 仍可查/删。若只想停掉"自动触发"而保留手动命令,请用 triggerEveryNMessages=0 而非关此项。彻底卸载请整体停用该插件。',
24
+ default: true,
25
+ },
26
+ triggerEveryNMessages: {
27
+ type: 'number',
28
+ label: '自动触发阈值(每 N 条消息)',
29
+ description: '**仅控制"自动触发"**:每会话累计 N 条入站消息后自动跑一次 LLM 提取。0=**仅手动**(slash 命令 /relation extract 仍可触发,Agent 工具仍可用——与 extractionEnabled 不同)。',
30
+ default: 20,
31
+ },
32
+ readWindowSize: {
33
+ type: 'number',
34
+ label: '提取读取窗口大小',
35
+ description: '每次提取时回读的最近消息数。建议略大于触发阈值(如阈值 20、窗口 30),让相邻批次窗口重叠 10 条左右、便于 LLM 跨批次稳定识别同一事件与关系',
36
+ default: 30,
37
+ },
38
+ mode: {
39
+ type: 'select',
40
+ label: '提取模式',
41
+ description: 'incremental: 固定窗口;all-new: 一次性读所有累积(注意 context 上限)',
42
+ options: [
43
+ { value: 'incremental', label: '增量窗口(推荐)' },
44
+ { value: 'all-new', label: '全量累积(慎用)' },
45
+ ],
46
+ default: 'incremental',
47
+ },
48
+ allNewMaxMessages: {
49
+ type: 'number',
50
+ label: 'all-new 模式下的最大消息数',
51
+ description: '仅 mode=all-new 时生效;硬上限以防 context 溢出',
52
+ default: 200,
53
+ },
54
+ readScope: {
55
+ type: 'select',
56
+ label: '提取读取范围',
57
+ description: '决定每次提取从哪些会话拉取消息送给 LLM:\n- same-session(默认):只读当前 sessionId(同群/同私聊),证据 100% 在原 session 内;\n- same-platform:把同 platform 下所有会话最近消息合并送 LLM,每行带 [sid:xxx] 前缀,evidence 按真实来源记录;适合识别跨群共享话题;\n- cross-platform:跨所有平台聚合(同上),适合识别跨平台同一用户/同一事件。\n跨会话模式仅在 memory 后端实现 getRecentMessagesAcrossSessions 时生效,否则自动降级到 same-session。',
58
+ options: [
59
+ { value: 'same-session', label: '仅当前会话(默认)' },
60
+ { value: 'same-platform', label: '同平台跨会话' },
61
+ { value: 'cross-platform', label: '全平台跨会话' },
62
+ ],
63
+ default: 'same-session',
64
+ },
65
+ crossSessionMaxAgeMinutes: {
66
+ type: 'number',
67
+ label: '跨会话拉取最大时间窗口(分钟)',
68
+ description: '仅 readScope!=same-session 时生效;只取最近 N 分钟内的消息。0=不限',
69
+ default: 60,
70
+ },
71
+ candidateEventDays: {
72
+ type: 'number',
73
+ label: '候选事件回溯天数',
74
+ description: '提取时把最近 N 天的活跃事件作为候选清单交给 LLM,避免重复创建同名事件',
75
+ default: 7,
76
+ },
77
+ candidateEventLimit: {
78
+ type: 'number',
79
+ label: '候选事件最大数量',
80
+ description: '控制 prompt 体积',
81
+ default: 20,
82
+ },
83
+ senderNeighborhoodEdgeLimit: {
84
+ type: 'number',
85
+ label: '候选人 1 跳邻居展示上限',
86
+ description: '提取时,对窗口内每位已知发言人附带其 1 跳邻居子图(已关联的事件/实体/人际关系,按权重降序),上限条数。0 = 关闭',
87
+ default: 8,
88
+ },
89
+ extractionModel: {
90
+ type: 'llm-ref',
91
+ label: '提取使用的 LLM',
92
+ description: '建议挑一个具备 chat 能力的便宜模型;留空则使用默认 llm 服务',
93
+ },
94
+ extractionDisableThinking: {
95
+ type: 'boolean',
96
+ label: '提取:禁用思考模式',
97
+ description: '提取是结构化输出任务,思考型模型(如 deepseek-v4-flash)开启思考后可能把 token budget 全花在 reasoning 上、返回空内容。默认禁用',
98
+ default: true,
99
+ },
100
+ // ────── Consolidate(图整理 + 自动别名合并 + 可选 LLM 增强)──────
101
+ consolidationModel: {
102
+ type: 'llm-ref',
103
+ label: 'Consolidate 使用的 LLM',
104
+ description: '可选。配置后 /relation.consolidate 与淘汰后自动整理会调用该模型做 (A) 别名候选语义核验、(B) 合并后摘要重写、(C) 实体层级推断。推荐选大上下文模型(如 GPT-4o、Claude Opus),留空则保持纯算法行为。',
105
+ },
106
+ consolidationDisableThinking: {
107
+ type: 'boolean',
108
+ label: 'Consolidate LLM:禁用思考模式',
109
+ description: '同 extractionDisableThinking。默认禁用',
110
+ default: true,
111
+ },
112
+ consolidationAutoLink: {
113
+ type: 'boolean',
114
+ label: 'Consolidate autoLink',
115
+ description: '为 true 时自动合并别名实体、建层级边(结合 consolidationModel 可由 LLM 核验);false 仅打印候选不动数据。',
116
+ default: false,
117
+ },
118
+ consolidationSkipLowScorePairs: {
119
+ type: 'boolean',
120
+ label: 'Consolidate:跳过低权候选 pair',
121
+ description: '启用后,宽召回阶段双方 compositeScore 均低于阈值的候选不送 LLM 核验(两端都是 edge tier,合并价值低)。默认启用以节省 LLM 调用。',
122
+ default: true,
123
+ },
124
+ consolidationLowScoreThreshold: {
125
+ type: 'number',
126
+ label: 'Consolidate:低权阈值',
127
+ description: 'compositeScore 阈值(0~1,与 scoreToTier 的 edge 边界一致,默认 0.2)。设 0 等同关闭跳过;仅在 consolidationSkipLowScorePairs=true 时生效。',
128
+ default: 0.2,
129
+ },
130
+ consolidateAfterEviction: {
131
+ type: 'boolean',
132
+ label: '淘汰时自动 consolidate',
133
+ description: '每次触发容量淘汰时,先自动运行一次 consolidate(去重 / 整理 / 层级推断),再执行淘汰。与 /relation maintain 顺序一致,使 PageRank 入出度更完整。',
134
+ default: true,
135
+ },
136
+ // ────── 自动老化(写后顺手扫,profile 风格,不开独立调度器)──────
137
+ evictionEnabled: {
138
+ type: 'boolean',
139
+ label: '启用自动老化',
140
+ description: '每次提取完成后扫一遍当前图:先删孤儿节点(无任何边),再按"超出配额"逐项删除"老旧 + 低权重 + PageRank 边缘"的人物/事件/实体/边。不再有硬豁免,重要性完全由 PageRank 、weight 衰减与 mentionCount 表达。配额设为 0 则允许该类节点无限增长。',
141
+ default: true,
142
+ },
143
+ maxPersons: {
144
+ type: 'number',
145
+ label: '人物总数上限',
146
+ description: '超过则按 (now - lastMentionedAt) / (mentionCount · PR) 排序,先删老旧低活跃人物。0=不限(允许人物无限增长)。',
147
+ default: 1500,
148
+ },
149
+ maxEvents: {
150
+ type: 'number',
151
+ label: '事件总数上限',
152
+ description: '超过则按 (now - lastReinforcedAt) / weight 排序,先删老旧低权重事件。0=不限。',
153
+ default: 2500,
154
+ },
155
+ maxEntities: {
156
+ type: 'number',
157
+ label: '实体总数上限',
158
+ description: '同上策略。0=不限。',
159
+ default: 1500,
160
+ },
161
+ maxEdges: {
162
+ type: 'number',
163
+ label: '边总数上限',
164
+ description: '超过则保留 weight · 端点PR平均 最高的边。0=不限。',
165
+ default: 10000,
166
+ },
167
+ pagerankDamping: {
168
+ type: 'number',
169
+ label: 'PageRank 阻尼系数',
170
+ description: '淘汰打分用。常用 0.85。',
171
+ default: 0.85,
172
+ },
173
+ pagerankIterations: {
174
+ type: 'number',
175
+ label: 'PageRank 最大迭代次数',
176
+ description: '20 通常够用;图较大、邻接稠密可调到 30~50。',
177
+ default: 20,
178
+ },
179
+ pagerankEpsilon: {
180
+ type: 'number',
181
+ label: 'PageRank 收敛阈值',
182
+ description: 'L1 误差小于该值即提前停止迭代。',
183
+ default: 0.0001,
184
+ },
185
+ communityAlgorithm: {
186
+ type: 'select',
187
+ label: '社群发现默认算法',
188
+ description: 'evictByQuota 之后顺手跑的社群发现算法。louvain=经典快、硬划分;leiden=Louvain + 内部连通性 refinement;slpa=Speaker-Listener Label Propagation,原生重叠社区(跨群人物能获得多个社群隶属度)。agent 调 community_* 工具时可临时指定 algorithm 参数覆盖此默认。',
189
+ options: [
190
+ { value: 'louvain', label: 'Louvain(默认,快,硬划分)' },
191
+ { value: 'leiden', label: 'Leiden-lite(硬划分,保证内部连通)' },
192
+ { value: 'slpa', label: 'SLPA(原生重叠社区,软划分)' },
193
+ ],
194
+ default: 'louvain',
195
+ },
196
+ evictHysteresisPct: {
197
+ type: 'number',
198
+ label: '淘汰滞回 (0~1)',
199
+ description: 'count > quota·(1+该值) 才触发淘汰;设为 0.2 时,quota=500 在 600 触发。用以避免"写一条删一条"。',
200
+ default: 0.2,
201
+ },
202
+ evictTargetPct: {
203
+ type: 'number',
204
+ label: '淘汰回落目标 (0~1)',
205
+ description: '触发后裁到 floor(quota·该值);配合 hysteresisPct=0.2 与该值=0.8,单次裁 ~40% quota(quota=500 → 一次裁 ~200 条)。',
206
+ default: 0.8,
207
+ },
208
+ weightDecayHalfLifeDays: {
209
+ type: 'number',
210
+ label: 'Weight 时间衰减半衰期(天)',
211
+ description: '淘汰/排序时把 weight 按半衰期折算:effW = raw × max(0.5^(天数/halfLife), floor)。让长期不被强化的"老高 weight"自动让出保护名额。0 = 关闭衰减。',
212
+ default: 180,
213
+ },
214
+ weightDecayFloor: {
215
+ type: 'number',
216
+ label: 'Weight 衰减下限因子 (0~1)',
217
+ description: 'effW 不会低于 raw × 该值。保留"老朋友"底色,避免完全失忆。默认 0.3。',
218
+ default: 0.3,
219
+ },
220
+ // ────── Middleware 注入侧 ──────
221
+ agentInjection: {
222
+ type: 'boolean',
223
+ label: '向 agent 注入关系上下文',
224
+ description: '在 agent:llm:before 时把当前用户的子图速览注入 system prompt',
225
+ default: true,
226
+ },
227
+ injectionMaxDepth: {
228
+ type: 'number',
229
+ label: '注入:BFS 最大深度',
230
+ description: '0=仅起点;1=直接邻居;2=同事件其他参与者 / 朋友的朋友。token 敏感,默认 2',
231
+ default: 2,
232
+ },
233
+ injectionMaxBreadth: {
234
+ type: 'number',
235
+ label: '注入:单节点展开邻居上限',
236
+ description: '按 weight 降序展开。默认 10',
237
+ default: 10,
238
+ },
239
+ maxInjectedEvents: {
240
+ type: 'number',
241
+ label: '注入:事件条数上限',
242
+ default: 5,
243
+ },
244
+ maxInjectedRelations: {
245
+ type: 'number',
246
+ label: '注入:人际关系条数上限',
247
+ default: 8,
248
+ },
249
+ maxParticipantsPerEvent: {
250
+ type: 'number',
251
+ label: '注入:每事件展示参与者数',
252
+ description: '超出会显示 +N 人。默认 5',
253
+ default: 5,
254
+ },
255
+ maxCooccurrencePartners: {
256
+ type: 'number',
257
+ label: '注入:共现伙伴展示数',
258
+ description: '基于事件桥统计的隐式二跳;0 关闭该小节',
259
+ default: 5,
260
+ },
261
+ maxGlobalHotEvents: {
262
+ type: 'number',
263
+ label: '注入:全局热点事件数',
264
+ description: '与当前用户子图无关,按全局 lastMentionedAt 排序的最近事件;0 关闭',
265
+ default: 5,
266
+ },
267
+ maxGlobalHotEntities: {
268
+ type: 'number',
269
+ label: '注入:全局热点实体数',
270
+ description: '与当前用户子图无关,按全局 lastMentionedAt 排序的最近实体;0 关闭',
271
+ default: 5,
272
+ },
273
+ groupOnly: {
274
+ type: 'boolean',
275
+ label: '仅在群聊中注入',
276
+ description: '私聊一般无需关系图上下文',
277
+ default: false,
278
+ },
279
+ // ────── Agent 工具侧 ──────
280
+ toolsEnabled: {
281
+ type: 'boolean',
282
+ label: '向 Agent 暴露 dig 工具',
283
+ description: '允许 LLM 主动调用:expand_person / find_path / search_events / upsert_* / link / unlink',
284
+ default: true,
285
+ },
286
+ commandsEnabled: {
287
+ type: 'boolean',
288
+ label: '注册 /relation 指令',
289
+ description: '注册 show / orphans / cleanup 系列指令(cleanup 需 authority ≥ 3)',
290
+ default: true,
291
+ },
292
+ strictSelfAssertion: {
293
+ type: 'boolean',
294
+ label: '严格自证模式',
295
+ description: '开启后,提取/工具只允许把关系归到「说过那条原话的人」名下:每条人-* 边必须有 evidence,且至少一条 evidence.messageId 对应消息的发言者 == fromPersonId;agent 工具调用 link/upsert_person 时 from 必须 == 当前发言者。person-person 边的 to 必须已存在 PersonNode。',
296
+ default: true,
297
+ },
298
+ digToolDefaultMaxDepth: {
299
+ type: 'number',
300
+ label: 'dig 工具:默认深度',
301
+ default: 2,
302
+ },
303
+ digToolDefaultMaxBreadth: {
304
+ type: 'number',
305
+ label: 'dig 工具:默认宽度',
306
+ default: 8,
307
+ },
308
+ digToolHardMaxDepth: {
309
+ type: 'number',
310
+ label: 'dig 工具:硬上限深度',
311
+ description: 'Agent 传入更大值会被截断',
312
+ default: 4,
313
+ },
314
+ digToolHardMaxBreadth: {
315
+ type: 'number',
316
+ label: 'dig 工具:硬上限宽度',
317
+ default: 20,
318
+ },
319
+ findPathDefaultMaxDepth: {
320
+ type: 'number',
321
+ label: 'find_path 默认深度',
322
+ default: 4,
323
+ },
324
+ findPathHardMaxDepth: {
325
+ type: 'number',
326
+ label: 'find_path 硬上限',
327
+ default: 6,
328
+ },
329
+ searchEventsDefaultLimit: {
330
+ type: 'number',
331
+ label: 'search_events 默认 limit',
332
+ default: 10,
333
+ },
334
+ searchEventsHardMaxLimit: {
335
+ type: 'number',
336
+ label: 'search_events 硬上限 limit',
337
+ default: 50,
338
+ },
339
+ // ────── 通用 ──────
340
+ debug: {
341
+ type: 'boolean',
342
+ label: 'Debug 日志',
343
+ description: '开启后会输出提取/注入/工具调用的详细日志',
344
+ default: false,
345
+ },
346
+ };
347
+ const webuiPages = [
348
+ {
349
+ key: 'user-relation',
350
+ label: '人物关系图',
351
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="3"/><circle cx="18" cy="6" r="3"/><circle cx="12" cy="18" r="3"/><line x1="6" y1="9" x2="12" y2="15"/><line x1="18" y1="9" x2="12" y2="15"/><line x1="6" y1="6" x2="18" y2="6"/></svg>',
352
+ order: 58,
353
+ content: [
354
+ {
355
+ type: 'graph',
356
+ label: '关系图(点击节点查看详情;可设置焦点重做子图)',
357
+ source: 'getRelationGraph',
358
+ detailSource: 'getGraphNodeDetail',
359
+ defaultMaxDepth: 2,
360
+ defaultMaxBreadth: 10,
361
+ refresh: 0,
362
+ },
363
+ ],
364
+ },
365
+ {
366
+ key: 'user-relation-raw',
367
+ label: '关系图·原始数据',
368
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="2"/><line x1="3" y1="10" x2="21" y2="10"/><line x1="9" y1="4" x2="9" y2="20"/></svg>',
369
+ order: 59,
370
+ content: [
371
+ {
372
+ type: 'tabs',
373
+ label: '原始数据(与关系图共用同一份存储)',
374
+ items: [
375
+ {
376
+ key: 'persons',
377
+ label: '人物列表',
378
+ content: [
379
+ {
380
+ type: 'table',
381
+ source: 'listPersons',
382
+ searchable: true,
383
+ columns: [
384
+ { key: 'id', label: 'ID', nowrap: true },
385
+ { key: 'platform', label: '平台', nowrap: true },
386
+ { key: 'userId', label: '用户 ID', nowrap: true },
387
+ { key: 'displayName', label: '显示名', nowrap: true },
388
+ { key: 'firstSeenAt', label: '首次出现', nowrap: true },
389
+ { key: 'lastSeenAt', label: '最近活跃', nowrap: true },
390
+ ],
391
+ actions: [
392
+ { label: '删除', method: 'deletePerson', confirm: '确认删除该人物及其所有相关边?', danger: true },
393
+ ],
394
+ refresh: 60,
395
+ },
396
+ ],
397
+ },
398
+ {
399
+ key: 'events',
400
+ label: '事件列表',
401
+ content: [
402
+ {
403
+ type: 'table',
404
+ source: 'listEvents',
405
+ searchable: true,
406
+ columns: [
407
+ { key: 'title', label: '标题', minWidth: 160 },
408
+ { key: 'category', label: '类别', nowrap: true },
409
+ { key: 'sessionScope', label: '会话', nowrap: true },
410
+ { key: 'summary', label: '摘要', minWidth: 200, maxWidth: 360, render: 'expandable-text' },
411
+ { key: 'preview', label: '最新证据', minWidth: 160, render: 'expandable-text' },
412
+ { key: 'evidenceCount', label: '证据数', nowrap: true },
413
+ { key: 'lastReinforcedAt', label: '最近强化', nowrap: true },
414
+ ],
415
+ actions: [
416
+ { label: '删除', method: 'deleteEvent', confirm: '确认删除该事件及其所有相关边?', danger: true },
417
+ ],
418
+ refresh: 60,
419
+ },
420
+ ],
421
+ },
422
+ {
423
+ key: 'entities',
424
+ label: '实体列表',
425
+ content: [
426
+ {
427
+ type: 'table',
428
+ source: 'listEntities',
429
+ searchable: true,
430
+ columns: [
431
+ { key: 'name', label: '名称', minWidth: 140 },
432
+ { key: 'entityKind', label: '类型', nowrap: true },
433
+ { key: 'aliases', label: '别名', minWidth: 140, render: 'expandable-text' },
434
+ { key: 'summary', label: '摘要', minWidth: 200, maxWidth: 360, render: 'expandable-text' },
435
+ { key: 'evidenceCount', label: '证据数', nowrap: true },
436
+ { key: 'lastReinforcedAt', label: '最近强化', nowrap: true },
437
+ ],
438
+ actions: [
439
+ { label: '删除', method: 'deleteEntity', confirm: '确认删除该实体及其所有相关边?', danger: true },
440
+ ],
441
+ refresh: 60,
442
+ },
443
+ ],
444
+ },
445
+ ],
446
+ },
447
+ ],
448
+ },
449
+ ];
450
+ export function apply(ctx, config) {
451
+ const memory = ctx.getService('memory');
452
+ if (!memory) {
453
+ throw new Error('[plugin-user-relation] memory 服务不可用,无法初始化关系图存储');
454
+ }
455
+ const store = new RelationStore(memory);
456
+ const service = new RelationService(store, ctx);
457
+ ctx.provide('user-relation', service);
458
+ // 平台 displayName 同步:与 extractionEnabled 解耦,即便关掉写入提取,
459
+ // 改名也应反映到已存在的 Person 节点(仅同步,不创建新节点)。
460
+ startRenameWatcher(ctx, service);
461
+ const debug = config.debug === true;
462
+ // ─── 提取(写入)─── 受 extractionEnabled 控制
463
+ // 注意:triggerEveryN=0 时不再绕过 extractor 构造,仅 disable 自动触发;
464
+ // 这样 slash 命令 /relation extract 与 Agent 工具仍能调用。
465
+ const extractionEnabled = config.extractionEnabled !== false;
466
+ const triggerEveryN = numCfg(config.triggerEveryNMessages, 20);
467
+ if (extractionEnabled) {
468
+ const extractor = new RelationExtractor(ctx, service, {
469
+ triggerEveryNMessages: triggerEveryN,
470
+ readWindowSize: numCfg(config.readWindowSize, 30),
471
+ mode: config.mode === 'all-new' ? 'all-new' : 'incremental',
472
+ allNewMaxMessages: numCfg(config.allNewMaxMessages, 200),
473
+ readScope: config.readScope === 'cross-platform'
474
+ ? 'cross-platform'
475
+ : config.readScope === 'same-platform'
476
+ ? 'same-platform'
477
+ : 'same-session',
478
+ crossSessionMaxAgeMinutes: numCfg(config.crossSessionMaxAgeMinutes, 60),
479
+ candidateEventDays: numCfg(config.candidateEventDays, 7),
480
+ candidateEventLimit: numCfg(config.candidateEventLimit, 20),
481
+ senderNeighborhoodEdgeLimit: numCfg(config.senderNeighborhoodEdgeLimit, 8),
482
+ extractionModel: config.extractionModel,
483
+ disableThinking: config.extractionDisableThinking !== false,
484
+ strictSelfAssertion: config.strictSelfAssertion !== false,
485
+ evictionEnabled: config.evictionEnabled !== false,
486
+ maxPersons: numCfg(config.maxPersons, 1500),
487
+ maxEvents: numCfg(config.maxEvents, 2500),
488
+ maxEntities: numCfg(config.maxEntities, 1500),
489
+ maxEdges: numCfg(config.maxEdges, 10000),
490
+ pagerankDamping: numCfg(config.pagerankDamping, 0.85),
491
+ pagerankIterations: numCfg(config.pagerankIterations, 20),
492
+ pagerankEpsilon: numCfg(config.pagerankEpsilon, 0.0001),
493
+ evictHysteresisPct: numCfg(config.evictHysteresisPct, 0.2),
494
+ evictTargetPct: numCfg(config.evictTargetPct, 0.8),
495
+ weightDecayHalfLifeDays: numCfg(config.weightDecayHalfLifeDays, 180),
496
+ weightDecayFloor: numCfg(config.weightDecayFloor, 0.3),
497
+ communityAlgorithm: (() => {
498
+ const raw = config.communityAlgorithm;
499
+ return raw === 'leiden' || raw === 'slpa' ? raw : 'louvain';
500
+ })(),
501
+ consolidateAfterEviction: config.consolidateAfterEviction !== false,
502
+ consolidateLLMModelRef: config.consolidationModel,
503
+ consolidateLLMDisableThinking: config.consolidationDisableThinking !== false,
504
+ consolidateAutoLink: config.consolidationAutoLink === true,
505
+ consolidateSkipLowScorePairs: config.consolidationSkipLowScorePairs !== false,
506
+ consolidateLowScoreThreshold: numCfg(config.consolidationLowScoreThreshold, 0.2),
507
+ debug,
508
+ });
509
+ extractor.start();
510
+ service.setTriggerExtractionHandler(sessionId => extractor.triggerNow(sessionId));
511
+ }
512
+ // ─── Middleware 注入(读取)─── 受 agentInjection 控制
513
+ if (config.agentInjection !== false) {
514
+ registerRelationMiddleware(ctx, service, {
515
+ enabled: true,
516
+ maxDepth: numCfg(config.injectionMaxDepth, 2),
517
+ maxBreadth: numCfg(config.injectionMaxBreadth, 10),
518
+ maxEvents: numCfg(config.maxInjectedEvents, 5),
519
+ maxRelations: numCfg(config.maxInjectedRelations, 8),
520
+ maxParticipantsPerEvent: numCfg(config.maxParticipantsPerEvent, 5),
521
+ maxCooccurrencePartners: numCfg(config.maxCooccurrencePartners, 5),
522
+ maxGlobalHotEvents: numCfg(config.maxGlobalHotEvents, 5),
523
+ maxGlobalHotEntities: numCfg(config.maxGlobalHotEntities, 5),
524
+ groupOnly: config.groupOnly === true,
525
+ debug,
526
+ });
527
+ }
528
+ // ─── Agent 工具 ─── 受 toolsEnabled 控制
529
+ if (config.toolsEnabled !== false) {
530
+ registerRelationTools(ctx, service, {
531
+ enabled: true,
532
+ group: 'user-relation',
533
+ defaultMaxDepth: numCfg(config.digToolDefaultMaxDepth, 2),
534
+ defaultMaxBreadth: numCfg(config.digToolDefaultMaxBreadth, 8),
535
+ hardMaxDepth: numCfg(config.digToolHardMaxDepth, 4),
536
+ hardMaxBreadth: numCfg(config.digToolHardMaxBreadth, 20),
537
+ findPathDefaultMaxDepth: numCfg(config.findPathDefaultMaxDepth, 4),
538
+ findPathHardMaxDepth: numCfg(config.findPathHardMaxDepth, 6),
539
+ searchEventsDefaultLimit: numCfg(config.searchEventsDefaultLimit, 10),
540
+ searchEventsHardMaxLimit: numCfg(config.searchEventsHardMaxLimit, 50),
541
+ debug,
542
+ });
543
+ }
544
+ // WebUI 页面
545
+ const webui = useWebuiService(ctx);
546
+ for (const page of webuiPages)
547
+ webui.registerPage(page);
548
+ // /relation 指令
549
+ if (config.commandsEnabled !== false) {
550
+ const consolidateModel = config.consolidationModel;
551
+ registerRelationCommands(ctx, service, {
552
+ ...(consolidateModel
553
+ ? {
554
+ consolidateLLM: {
555
+ modelRef: consolidateModel,
556
+ disableThinking: config.consolidationDisableThinking !== false,
557
+ },
558
+ }
559
+ : {}),
560
+ eviction: {
561
+ maxPersons: numCfg(config.maxPersons, 1500),
562
+ maxEvents: numCfg(config.maxEvents, 2500),
563
+ maxEntities: numCfg(config.maxEntities, 1500),
564
+ maxEdges: numCfg(config.maxEdges, 10000),
565
+ pagerankDamping: numCfg(config.pagerankDamping, 0.85),
566
+ pagerankIterations: numCfg(config.pagerankIterations, 20),
567
+ pagerankEpsilon: numCfg(config.pagerankEpsilon, 0.0001),
568
+ hysteresisPct: numCfg(config.evictHysteresisPct, 0.2),
569
+ targetPct: numCfg(config.evictTargetPct, 0.8),
570
+ weightDecayHalfLifeDays: numCfg(config.weightDecayHalfLifeDays, 180),
571
+ weightDecayFloor: numCfg(config.weightDecayFloor, 0.3),
572
+ communityAlgorithm: (() => {
573
+ const raw = config.communityAlgorithm;
574
+ return raw === 'leiden' || raw === 'slpa' ? raw : 'louvain';
575
+ })(),
576
+ },
577
+ consolidateAutoLink: config.consolidationAutoLink === true,
578
+ consolidateSkipLowScorePairs: config.consolidationSkipLowScorePairs !== false,
579
+ consolidateLowScoreThreshold: numCfg(config.consolidationLowScoreThreshold, 0.2),
580
+ });
581
+ }
582
+ // ─── 参与统一的 memory:clear(与 plugin-user-profile 对称) ───
583
+ // scope='all':清空整个关系图;scope='session':跨会话存储,不动。
584
+ // types 过滤:未指定 / 包含 'user-relation' 时执行。
585
+ ctx.middleware('memory:clear', async (data, next) => {
586
+ if (data.types && !data.types.includes('user-relation')) {
587
+ await next();
588
+ return;
589
+ }
590
+ if (data.scope !== 'all') {
591
+ await next();
592
+ return;
593
+ }
594
+ if (!memory.listMetadata || !memory.deleteMetadata) {
595
+ await next();
596
+ return;
597
+ }
598
+ try {
599
+ const items = await memory.listMetadata(RELATION_NAMESPACE);
600
+ for (const it of items)
601
+ await memory.deleteMetadata(RELATION_NAMESPACE, it.key);
602
+ ctx.logger.info(`[user-relation] 关系图已清空 (${items.length} 条)`);
603
+ data.results.push({
604
+ source: 'user-relation',
605
+ success: true,
606
+ message: `关系图已清空 (${items.length} 条)`,
607
+ });
608
+ }
609
+ catch (err) {
610
+ const m = err instanceof Error ? err.message : String(err);
611
+ ctx.logger.warn(`[user-relation] 清空失败: ${m}`);
612
+ data.results.push({ source: 'user-relation', success: false, message: `关系图清空失败: ${m}` });
613
+ }
614
+ await next();
615
+ });
616
+ }
617
+ function numCfg(v, fallback) {
618
+ if (typeof v === 'number' && Number.isFinite(v))
619
+ return v;
620
+ return fallback;
621
+ }
622
+ export const actions = baseActions;
623
+ export { RelationService } from './service.js';
624
+ export { RelationStore } from './store.js';
625
+ export * from './types.js';
626
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}