@aalis/plugin-memory-summary 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # @aalis/plugin-memory-summary
2
+
3
+ 运行时插件
4
+
5
+ ## 角色
6
+
7
+ 运行时插件
8
+
9
+ ## 安装
10
+
11
+ ```bash
12
+ pnpm add @aalis/plugin-memory-summary
13
+ ```
14
+
15
+ ## 文档
16
+
17
+ 详见 [docs/plugins/plugin-memory-summary.md](../../docs/plugins/plugin-memory-summary.md)。
18
+
19
+ ## 许可
20
+
21
+ 见仓库根目录 LICENSE。
package/dist/i18n.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { I18nResources } from '@aalis/core';
2
+ export declare const DEFAULT_SUMMARY_PROMPT_ZH = "\u4F60\u662F\u4E00\u4E2A\u5BF9\u8BDD\u6458\u8981\u52A9\u624B\u3002\u8BF7\u5C06\u4EE5\u4E0B\u5BF9\u8BDD\u5185\u5BB9\u538B\u7F29\u6210\u4E00\u6BB5\u4FE1\u606F\u4E30\u5BCC\u7684\u6458\u8981\u3002\n\n\u8981\u6C42\uFF1A\n1. \u4FDD\u7559\u5173\u952E\u4FE1\u606F\uFF1A\u7528\u6237\u7684\u6838\u5FC3\u9700\u6C42\u3001\u91CD\u8981\u51B3\u7B56\u3001\u8FBE\u6210\u7684\u5171\u8BC6\n2. \u4FDD\u7559\u91CD\u8981\u7684\u4E8B\u5B9E\u548C\u6570\u636E\n3. \u4FDD\u7559\u5BF9\u8BDD\u4E2D\u63D0\u5230\u7684\u4EBA\u540D\u3001\u5730\u70B9\u3001\u65F6\u95F4\u7B49\u5173\u952E\u5B9E\u4F53\n4. \u4FDD\u7559\u7528\u6237\u7684\u504F\u597D\u548C\u4E60\u60EF\u4FE1\u606F\n5. \u4FDD\u7559\u60C5\u611F\u72B6\u6001\u53D8\u5316\u3001\u5173\u7CFB\u52A8\u6001\u3001\u8BA8\u8BBA\u4E2D\u5F62\u6210\u7684\u89C2\u70B9\n6. **\u7279\u522B\u91CD\u8981**\uFF1A\u4FDD\u7559\u6BCF\u4E2A\u53D1\u8A00\u8005\u7684\u6635\u79F0\u4E0EID\u7684\u5BF9\u5E94\u5173\u7CFB\u3002\u6D88\u606F\u4E2D [\u6635\u79F0(ID)] \u683C\u5F0F\u6807\u6CE8\u4E86\u53D1\u8A00\u8005\u8EAB\u4EFD\uFF0C\u6458\u8981\u4E2D\u5FC5\u987B\u4FDD\u7559\u8FD9\u79CD\u5BF9\u5E94\u5173\u7CFB\uFF08\u5982\"\u5C0F\u660E(123456)\"\uFF09\uFF0C\u4EE5\u4FBF\u540E\u7EED\u80FD\u901A\u8FC7ID\u6216\u6635\u79F0\u8BC6\u522B\u540C\u4E00\u4E2A\u4EBA\n6. \u5FFD\u7565\u7EAF\u7CB9\u7684\u5BD2\u6684\u548C\u65E0\u4FE1\u606F\u91CF\u7684\u91CD\u590D\u5185\u5BB9\n7. \u5982\u679C\u6709\u4E4B\u524D\u7684\u6458\u8981\uFF0C\u5728\u6B64\u57FA\u7840\u4E0A\u6574\u5408\u65B0\u5185\u5BB9\uFF0C\u786E\u4FDD\u65E7\u6458\u8981\u4E2D\u7684\u91CD\u8981\u4FE1\u606F\u4E0D\u56E0\u65B0\u5185\u5BB9\u52A0\u5165\u800C\u88AB\u4E22\u5F03\n8. \u4F7F\u7528\u7B2C\u4E09\u65B9\u89C6\u89D2\u63CF\u8FF0\uFF0C\u6807\u6CE8\u53D1\u8A00\u8005\u8EAB\u4EFD\uFF08\u5982\"\u7528\u6237[\u5C0F\u660E]...\"\u3001\"\u52A9\u624B...\"\uFF09\n9. \u6309\u8BDD\u9898\u6216\u65F6\u95F4\u5206\u6BB5\u7EC4\u7EC7\uFF0C\u4FBF\u4E8E\u540E\u7EED\u68C0\u7D22\n10. **\u7279\u522B\u91CD\u8981**\uFF1A\u5982\u679C\u5BF9\u8BDD\u4E2D\u5B58\u5728\u6B63\u5728\u8FDB\u884C\u7684\u591A\u6B65\u9AA4\u4EFB\u52A1\u6216\u8BA1\u5212\uFF08\u5982\u4EFB\u52A1\u5217\u8868\u3001\u5F85\u529E\u4E8B\u9879\u3001\u5206\u6B65\u5B9E\u65BD\u65B9\u6848\uFF09\uFF0C\u5FC5\u987B\u5B8C\u6574\u4FDD\u7559\u4EFB\u52A1\u7684\u76EE\u6807\u3001\u5DF2\u5B8C\u6210\u7684\u6B65\u9AA4\u3001\u5C1A\u672A\u5B8C\u6210\u7684\u6B65\u9AA4\u53CA\u5176\u72B6\u6001\u3002\u5728\u6458\u8981\u672B\u5C3E\u7528\u72EC\u7ACB\u6BB5\u843D\u5217\u51FA\uFF0C\u683C\u5F0F\u5982\uFF1A\n \u3010\u8FDB\u884C\u4E2D\u7684\u4EFB\u52A1\u3011\n - \u76EE\u6807\uFF1A...\n - \u5DF2\u5B8C\u6210\uFF1A...\n - \u5F85\u5B8C\u6210\uFF1A...\n11. \u4FDD\u7559\u52A9\u624B\u5728\u5BF9\u8BDD\u4E2D\u5236\u5B9A\u7684\u5DE5\u4F5C\u8BA1\u5212\u3001\u627F\u8BFA\u8981\u505A\u7684\u4E8B\u60C5\u3001\u4EE5\u53CA\u7528\u6237\u5C1A\u672A\u88AB\u6EE1\u8DB3\u7684\u8BF7\u6C42";
3
+ export declare const i18n: I18nResources;
4
+ //# sourceMappingURL=i18n.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,yBAAyB,oyFAkBG,CAAC;AAsB1C,eAAO,MAAM,IAAI,EAAE,aA6BlB,CAAC"}
package/dist/i18n.js ADDED
@@ -0,0 +1,69 @@
1
+ export const DEFAULT_SUMMARY_PROMPT_ZH = `你是一个对话摘要助手。请将以下对话内容压缩成一段信息丰富的摘要。
2
+
3
+ 要求:
4
+ 1. 保留关键信息:用户的核心需求、重要决策、达成的共识
5
+ 2. 保留重要的事实和数据
6
+ 3. 保留对话中提到的人名、地点、时间等关键实体
7
+ 4. 保留用户的偏好和习惯信息
8
+ 5. 保留情感状态变化、关系动态、讨论中形成的观点
9
+ 6. **特别重要**:保留每个发言者的昵称与ID的对应关系。消息中 [昵称(ID)] 格式标注了发言者身份,摘要中必须保留这种对应关系(如"小明(123456)"),以便后续能通过ID或昵称识别同一个人
10
+ 6. 忽略纯粹的寒暄和无信息量的重复内容
11
+ 7. 如果有之前的摘要,在此基础上整合新内容,确保旧摘要中的重要信息不因新内容加入而被丢弃
12
+ 8. 使用第三方视角描述,标注发言者身份(如"用户[小明]..."、"助手...")
13
+ 9. 按话题或时间分段组织,便于后续检索
14
+ 10. **特别重要**:如果对话中存在正在进行的多步骤任务或计划(如任务列表、待办事项、分步实施方案),必须完整保留任务的目标、已完成的步骤、尚未完成的步骤及其状态。在摘要末尾用独立段落列出,格式如:
15
+ 【进行中的任务】
16
+ - 目标:...
17
+ - 已完成:...
18
+ - 待完成:...
19
+ 11. 保留助手在对话中制定的工作计划、承诺要做的事情、以及用户尚未被满足的请求`;
20
+ const DEFAULT_SUMMARY_PROMPT_EN = `You are a conversation summarization assistant. Compress the following conversation into an information-rich summary.
21
+
22
+ Requirements:
23
+ 1. Preserve key information: the user's core needs, important decisions, and agreements reached.
24
+ 2. Preserve important facts and data.
25
+ 3. Preserve key entities such as names, places, and times.
26
+ 4. Preserve user preferences and habits.
27
+ 5. Preserve emotional state changes, relationship dynamics, and opinions formed during discussion.
28
+ 6. Especially important: preserve the mapping between every speaker's nickname and ID. Messages mark speakers as [nickname(ID)], and the summary must keep that mapping, such as "Ming(123456)", so later turns can identify the same person by either ID or nickname.
29
+ 7. Ignore pure greetings and repeated content with no information value.
30
+ 8. If a previous summary exists, merge new content into it without losing important information from the old summary.
31
+ 9. Use a third-person perspective and identify speakers, such as "user[Ming]..." and "assistant...".
32
+ 10. Organize by topic or timeline for later retrieval.
33
+ 11. Especially important: if there is an in-progress multi-step task or plan, preserve the goal, completed steps, unfinished steps, and status. End with a separate section, for example:
34
+ In-progress tasks:
35
+ - Goal: ...
36
+ - Completed: ...
37
+ - Pending: ...
38
+ 12. Preserve work plans, commitments made by the assistant, and user requests that have not yet been satisfied.`;
39
+ export const i18n = {
40
+ 'zh-CN': {
41
+ 'plugin.memorySummary.displayName': '记忆摘要',
42
+ 'config.memorySummary.promptLocale.label': 'Prompt 语言',
43
+ 'config.memorySummary.promptLocale.description': '默认摘要提示词和摘要注入消息使用的语言。自定义摘要提示词不受此项影响。',
44
+ 'config.memorySummary.promptLocale.auto': '跟随全局设置',
45
+ 'prompt.memorySummary.system': DEFAULT_SUMMARY_PROMPT_ZH,
46
+ 'prompt.memorySummary.budgetHint': '\n\n重要:你的摘要输出上限为 {tokens} tokens(约 {englishChars} 个英文字符,或约 {chineseChars} 个中文字符)。请合理分配篇幅,确保“【进行中的任务】”等关键结构能完整输出。',
47
+ 'prompt.memorySummary.previous': '以下是之前的对话摘要:\n{summary}\n\n以下是新增的对话内容,请在之前摘要的基础上整合生成更新的摘要:\n{messages}',
48
+ 'prompt.memorySummary.new': '请为以下对话生成摘要:\n{messages}',
49
+ 'prompt.memorySummary.inject': '以下是之前对话的摘要,包含了较早的对话上下文:\n{summary}',
50
+ 'prompt.memorySummary.truncated': '\n... [摘要已截断]',
51
+ 'prompt.memorySummary.todoContext': '\n\n当前任务列表状态:\n{todo}',
52
+ 'prompt.memorySummary.autoTaskHint': '\n\n注意:此次压缩是在任务执行过程中自动触发的,助手可能正在进行多步骤工作。请特别注意保留所有未完成的任务状态和下一步计划。',
53
+ },
54
+ 'en-US': {
55
+ 'plugin.memorySummary.displayName': 'Memory Summary',
56
+ 'config.memorySummary.promptLocale.label': 'Prompt Language',
57
+ 'config.memorySummary.promptLocale.description': 'Language used by default summary prompts and injected summary messages. Custom summary prompts are left unchanged.',
58
+ 'config.memorySummary.promptLocale.auto': 'Follow Global Setting',
59
+ 'prompt.memorySummary.system': DEFAULT_SUMMARY_PROMPT_EN,
60
+ 'prompt.memorySummary.budgetHint': '\n\nImportant: your summary output limit is {tokens} tokens (about {englishChars} English characters or {chineseChars} Chinese characters). Allocate the space carefully and keep key structures such as “In-progress tasks” complete.',
61
+ 'prompt.memorySummary.previous': 'Previous conversation summary:\n{summary}\n\nNew conversation content follows. Merge it into the previous summary and produce an updated summary:\n{messages}',
62
+ 'prompt.memorySummary.new': 'Summarize the following conversation:\n{messages}',
63
+ 'prompt.memorySummary.inject': 'Earlier conversation summary for context:\n{summary}',
64
+ 'prompt.memorySummary.truncated': '\n... [summary truncated]',
65
+ 'prompt.memorySummary.todoContext': '\n\nCurrent todo-list state:\n{todo}',
66
+ 'prompt.memorySummary.autoTaskHint': '\n\nNote: this compression was triggered automatically while a task may be in progress. Preserve every unfinished task state and the next planned steps.',
67
+ },
68
+ };
69
+ //# sourceMappingURL=i18n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,yBAAyB,GAAG;;;;;;;;;;;;;;;;;;yCAkBA,CAAC;AAE1C,MAAM,yBAAyB,GAAG;;;;;;;;;;;;;;;;;;gHAkB8E,CAAC;AAEjH,MAAM,CAAC,MAAM,IAAI,GAAkB;IACjC,OAAO,EAAE;QACP,kCAAkC,EAAE,MAAM;QAC1C,yCAAyC,EAAE,WAAW;QACtD,+CAA+C,EAAE,qCAAqC;QACtF,wCAAwC,EAAE,QAAQ;QAClD,6BAA6B,EAAE,yBAAyB;QACxD,iCAAiC,EAAE,kHAAkH;QACrJ,+BAA+B,EAAE,uEAAuE;QACxG,0BAA0B,EAAE,yBAAyB;QACrD,6BAA6B,EAAE,oCAAoC;QACnE,gCAAgC,EAAE,eAAe;QACjD,kCAAkC,EAAE,uBAAuB;QAC3D,mCAAmC,EAAE,kEAAkE;KACxG;IACD,OAAO,EAAE;QACP,kCAAkC,EAAE,gBAAgB;QACpD,yCAAyC,EAAE,iBAAiB;QAC5D,+CAA+C,EAAE,oHAAoH;QACrK,wCAAwC,EAAE,uBAAuB;QACjE,6BAA6B,EAAE,yBAAyB;QACxD,iCAAiC,EAAE,wOAAwO;QAC3Q,+BAA+B,EAAE,+JAA+J;QAChM,0BAA0B,EAAE,mDAAmD;QAC/E,6BAA6B,EAAE,sDAAsD;QACrF,gCAAgC,EAAE,2BAA2B;QAC7D,kCAAkC,EAAE,sCAAsC;QAC1E,mCAAmC,EAAE,0JAA0J;KAChM;CACF,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { ConfigSchema, Context } from '@aalis/core';
2
+ import '@aalis/plugin-agent-api';
3
+ export declare const name = "@aalis/plugin-memory-summary";
4
+ export declare const displayName = "\u8BB0\u5FC6\u6458\u8981";
5
+ export declare const subsystem = "memory";
6
+ export declare const inject: {
7
+ required: string[];
8
+ optional: string[];
9
+ };
10
+ export declare const configSchema: ConfigSchema;
11
+ export declare const defaultConfig: {
12
+ threshold: number;
13
+ keepRecent: number;
14
+ summaryTokenRatio: number;
15
+ autoCompressThreshold: number;
16
+ summaryPrompt: string;
17
+ summaryModelMode: string;
18
+ };
19
+ export declare function apply(ctx: Context, config: Record<string, unknown>): Promise<void>;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,yBAAyB,CAAC;AAQjC,eAAO,MAAM,IAAI,iCAAiC,CAAC;AACnD,eAAO,MAAM,WAAW,6BAAS,CAAC;AAClC,eAAO,MAAM,SAAS,WAAW,CAAC;AAClC,eAAO,MAAM,MAAM;;;CAGlB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAgD1B,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;;;CAOzB,CAAC;AA4GF,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAicxF"}
package/dist/index.js ADDED
@@ -0,0 +1,542 @@
1
+ import { WellKnownKinds } from '@aalis/plugin-message-api';
2
+ import '@aalis/plugin-agent-api';
3
+ import { resolveLLMModel } from '@aalis/plugin-llm-api';
4
+ // ===== 插件元数据 =====
5
+ export const name = '@aalis/plugin-memory-summary';
6
+ export const displayName = '记忆摘要';
7
+ export const subsystem = 'memory';
8
+ export const inject = {
9
+ required: ['memory', 'llm'],
10
+ optional: ['message-archive'],
11
+ };
12
+ export const configSchema = {
13
+ threshold: {
14
+ type: 'number',
15
+ label: '摘要触发阈值',
16
+ default: 30,
17
+ description: '当会话历史超过此条数时,触发旧消息摘要',
18
+ },
19
+ keepRecent: {
20
+ type: 'number',
21
+ label: '保留最近消息数',
22
+ default: 20,
23
+ description: '摘要后保留的最近消息条数(不参与摘要的部分)',
24
+ },
25
+ summaryTokenRatio: {
26
+ type: 'number',
27
+ label: '摘要 Token 占比',
28
+ default: 0.05,
29
+ description: '摘要占模型上下文窗口的比例 (0~1),例如 0.05 表示 5%。 实际 token 上限 = contextLength × 比例,自动适配不同模型',
30
+ },
31
+ autoCompressThreshold: {
32
+ type: 'number',
33
+ label: 'Token 预压缩阈值',
34
+ default: 0.7,
35
+ description: '监听 agent 发出的 token:usage 事件,当使用率超过此比例 (0~1) 时启动后台压缩。默认 0.7 实现“临界前预压缩”,让本轮调用仍然能用原始上下文完成,压缩后的成果下一轮生效。设为 0 则禁用 token 触发。',
36
+ },
37
+ summaryPrompt: {
38
+ type: 'string',
39
+ label: '摘要生成提示词',
40
+ description: '用于指导 LLM 生成摘要的系统提示词',
41
+ },
42
+ summaryModelMode: {
43
+ type: 'select',
44
+ label: '摘要模型来源',
45
+ default: 'global',
46
+ options: [
47
+ { label: '沿用全局默认 LLM', value: 'global' },
48
+ { label: '自定义 provider/model', value: 'custom' },
49
+ ],
50
+ description: 'global=沿用全局默认 LLM;custom=使用下方 summaryLLM 指定的模型。session(沿用会话当轮模型)暂未实现。',
51
+ },
52
+ summaryLLM: {
53
+ type: 'llm-ref',
54
+ label: '摘要模型',
55
+ description: '仅当 summaryModelMode=custom 时生效;provider 为 LLM 插件实例 contextId,model 为实例内某个模型名。',
56
+ },
57
+ };
58
+ export const defaultConfig = {
59
+ threshold: 30,
60
+ keepRecent: 20,
61
+ summaryTokenRatio: 0.05,
62
+ autoCompressThreshold: 0.7,
63
+ summaryPrompt: '',
64
+ summaryModelMode: 'global',
65
+ };
66
+ // ===== 默认摘要生成提示词 =====
67
+ const DEFAULT_SUMMARY_PROMPT = `你是一个对话摘要助手。请将以下对话内容压缩成一段信息丰富的摘要。
68
+
69
+ 要求:
70
+ 1. 保留关键信息:用户的核心需求、重要决策、达成的共识
71
+ 2. 保留重要的事实和数据
72
+ 3. 保留对话中提到的人名、地点、时间等关键实体
73
+ 4. 保留用户的偏好和习惯信息
74
+ 5. 保留情感状态变化、关系动态、讨论中形成的观点
75
+ 6. **特别重要**:保留每个发言者的昵称与ID的对应关系。消息中 [昵称(ID)] 格式标注了发言者身份,摘要中必须保留这种对应关系(如"小明(123456)"),以便后续能通过ID或昵称识别同一个人
76
+ 6. 忽略纯粹的寒暄和无信息量的重复内容
77
+ 7. 如果有之前的摘要,在此基础上整合新内容,确保旧摘要中的重要信息不因新内容加入而被丢弃
78
+ 8. 使用第三方视角描述,标注发言者身份(如"用户[小明]..."、"助手...")
79
+ 9. 按话题或时间分段组织,便于后续检索
80
+ 10. **特别重要**:如果对话中存在正在进行的多步骤任务或计划(如任务列表、待办事项、分步实施方案),必须完整保留任务的目标、已完成的步骤、尚未完成的步骤及其状态。在摘要末尾用独立段落列出,格式如:
81
+ 【进行中的任务】
82
+ - 目标:...
83
+ - 已完成:...
84
+ - 待完成:...
85
+ 11. 保留助手在对话中制定的工作计划、承诺要做的事情、以及用户尚未被满足的请求`;
86
+ // ===== 摘要存储 =====
87
+ //
88
+ // 通过 MemoryService 的 metadata API 持久化摘要,让摘要与对话历史共享同一存储后端
89
+ // (sqlite/mongodb/inmemory)。namespace 固定为 'summary',key 为 sessionId。
90
+ // metadata payload 形如 { summary, coveredUpTo, messageCount, updatedAt }。
91
+ const SUMMARY_NAMESPACE = 'summary';
92
+ class SummaryStore {
93
+ ctx;
94
+ constructor(ctx) {
95
+ this.ctx = ctx;
96
+ const memory = ctx.getService('memory');
97
+ if (!memory?.saveMetadata || !memory?.getMetadata) {
98
+ throw new Error('[memory-summary] 当前 memory 实现缺少 metadata 能力(saveMetadata/getMetadata),无法存储摘要');
99
+ }
100
+ }
101
+ /** 每次惰性查询 memory provider,避免 apply 时缓存裸引用在 provider 重载后失效。 */
102
+ get memory() {
103
+ const m = this.ctx.getService('memory');
104
+ if (!m)
105
+ throw new Error('[memory-summary] memory 服务不可用');
106
+ return m;
107
+ }
108
+ async getSummary(sessionId) {
109
+ const data = await this.memory.getMetadata(SUMMARY_NAMESPACE, sessionId);
110
+ if (!data)
111
+ return null;
112
+ return {
113
+ summary: String(data.summary ?? ''),
114
+ coveredUpTo: Number(data.coveredUpTo ?? 0),
115
+ messageCount: Number(data.messageCount ?? 0),
116
+ };
117
+ }
118
+ async upsertSummary(sessionId, summary, coveredUpTo, messageCount) {
119
+ await this.memory.saveMetadata(SUMMARY_NAMESPACE, sessionId, {
120
+ summary,
121
+ coveredUpTo,
122
+ messageCount,
123
+ updatedAt: new Date().toISOString(),
124
+ });
125
+ }
126
+ async clearSession(sessionId) {
127
+ if (this.memory.deleteMetadata) {
128
+ await this.memory.deleteMetadata(SUMMARY_NAMESPACE, sessionId);
129
+ }
130
+ }
131
+ async clearAll() {
132
+ if (!this.memory.listMetadata || !this.memory.deleteMetadata)
133
+ return;
134
+ const items = await this.memory.listMetadata(SUMMARY_NAMESPACE);
135
+ for (const item of items) {
136
+ await this.memory.deleteMetadata(SUMMARY_NAMESPACE, item.key);
137
+ }
138
+ }
139
+ }
140
+ // ===== 插件入口 =====
141
+ export async function apply(ctx, config) {
142
+ const cfg = {
143
+ threshold: config.threshold ?? 30,
144
+ keepRecent: config.keepRecent ?? 20,
145
+ summaryTokenRatio: config.summaryTokenRatio ?? 0.05,
146
+ autoCompressThreshold: config.autoCompressThreshold ?? 0.7,
147
+ summaryPrompt: config.summaryPrompt ?? '',
148
+ summaryModelMode: config.summaryModelMode === 'custom' ? 'custom' : 'global',
149
+ summaryLLM: config.summaryLLM &&
150
+ typeof config.summaryLLM === 'object' &&
151
+ config.summaryLLM.provider &&
152
+ config.summaryLLM.model
153
+ ? config.summaryLLM
154
+ : undefined,
155
+ };
156
+ const memory = ctx.getService('memory');
157
+ if (!memory) {
158
+ ctx.logger.warn('memory 服务不可用,摘要插件将不会启动');
159
+ return;
160
+ }
161
+ const store = new SummaryStore(ctx);
162
+ ctx.logger.info('会话摘要插件已启动(摘要持久化经由 memory.metadata)');
163
+ // 正在摘要中的 session,避免并发重复摘要
164
+ const summarizing = new Set();
165
+ /**
166
+ * 根据 summaryModelMode 解析出用于生成摘要的 LLMModel entry。
167
+ * - global:按默认优先级/preference 选首个 chat-capable entry
168
+ * - custom:按 cfg.summaryLLM 精确匹配
169
+ */
170
+ function resolveSummaryModel() {
171
+ const ref = cfg.summaryModelMode === 'custom' ? cfg.summaryLLM : undefined;
172
+ return resolveLLMModel(ctx, ref, ['chat'])?.instance;
173
+ }
174
+ /**
175
+ * 根据实际使用的 LLMModel 计算摘要 token 上限。
176
+ * service-granularity 后每个 entry 直接拥有 contextLength,无需再反查 router。
177
+ */
178
+ function getSummaryTokenBudget() {
179
+ const model = resolveSummaryModel();
180
+ const contextLength = model?.contextLength ?? 4096;
181
+ return Math.max(512, Math.floor(contextLength * cfg.summaryTokenRatio));
182
+ }
183
+ // 摘要生成提示词
184
+ const summarySystemPrompt = cfg.summaryPrompt || DEFAULT_SUMMARY_PROMPT;
185
+ /**
186
+ * 为指定 session 生成/更新摘要
187
+ *
188
+ * 流程:
189
+ * 1. 从 memory 获取完整历史
190
+ * 2. 如果总消息数 < threshold,不需要摘要
191
+ * 3. 取 [0, total - keepRecent) 区间的消息作为待摘要内容
192
+ * 4. 联合已有摘要 → 调用 LLM 生成新摘要
193
+ * 5. 存入 DB
194
+ */
195
+ async function generateSummary(sessionId) {
196
+ if (summarizing.has(sessionId))
197
+ return;
198
+ summarizing.add(sessionId);
199
+ try {
200
+ const memory = ctx.getService('memory');
201
+ const summaryModel = resolveSummaryModel();
202
+ if (!memory || !summaryModel)
203
+ return;
204
+ // 获取较多的历史消息来判断是否需要摘要
205
+ const allHistory = await memory.getHistory(sessionId, 200);
206
+ const totalCount = allHistory.length;
207
+ if (totalCount < cfg.threshold)
208
+ return;
209
+ // 检查是否已有摘要
210
+ const existing = await store.getSummary(sessionId);
211
+ // 取所有待摘要的旧消息(除最近 keepRecent 条之外的)
212
+ const messagesToSummarize = allHistory.slice(0, totalCount - cfg.keepRecent);
213
+ if (messagesToSummarize.length === 0)
214
+ return;
215
+ // 格式化消息用于摘要
216
+ const formattedMessages = messagesToSummarize
217
+ .filter(m => m.role === 'user' || m.role === 'assistant')
218
+ .map(m => {
219
+ // user content 中已含 [昵称(ID)] 前缀,无需再加 name
220
+ const role = m.role === 'user' ? '用户' : '助手';
221
+ return `${role}: ${m.content ?? '(空)'}`;
222
+ })
223
+ .join('\n');
224
+ // 构建摘要请求
225
+ const summaryBudget = getSummaryTokenBudget();
226
+ const budgetHint = `\n\n重要:你的摘要输出上限为 ${summaryBudget} tokens(约 ${summaryBudget * 4} 个英文字符,或约 ${Math.floor(summaryBudget / 1.5)} 个中文字符)。请合理分配篇幅,确保“【进行中的任务】”等关键结构能完整输出。`;
227
+ const summaryMessages = [{ role: 'system', content: summarySystemPrompt + budgetHint }];
228
+ // 如果已有旧摘要,在提示中包含它
229
+ if (existing?.summary) {
230
+ summaryMessages.push({
231
+ role: 'user',
232
+ content: `以下是之前的对话摘要:\n${existing.summary}\n\n以下是新增的对话内容,请在之前摘要的基础上整合生成更新的摘要:\n${formattedMessages}`,
233
+ });
234
+ }
235
+ else {
236
+ summaryMessages.push({
237
+ role: 'user',
238
+ content: `请为以下对话生成摘要:\n${formattedMessages}`,
239
+ });
240
+ }
241
+ ctx.logger.debug(`正在为 session=${sessionId} 生成摘要 (${messagesToSummarize.length} 条旧消息 → 摘要,保留最近 ${cfg.keepRecent} 条)`);
242
+ // 调用 LLM 生成摘要
243
+ let summaryText = '';
244
+ const stream = summaryModel.chatStream?.({
245
+ messages: summaryMessages,
246
+ temperature: 0.3,
247
+ maxTokens: summaryBudget,
248
+ });
249
+ if (!stream) {
250
+ const resp = await summaryModel.chat({
251
+ messages: summaryMessages,
252
+ temperature: 0.3,
253
+ maxTokens: summaryBudget,
254
+ });
255
+ summaryText = resp.content ?? '';
256
+ }
257
+ else {
258
+ for await (const chunk of stream) {
259
+ if (chunk.contentDelta) {
260
+ summaryText += chunk.contentDelta;
261
+ }
262
+ }
263
+ }
264
+ if (summaryText.trim()) {
265
+ const finalSummary = summaryText.trim();
266
+ const summaryTs = Date.now();
267
+ await store.upsertSummary(sessionId, finalSummary, messagesToSummarize.length, totalCount);
268
+ // 真正的压缩:将旧消息标记为 archived,只保留最近 keepRecent 条作为热上下文
269
+ // 安全调整:避免裁剪点落在 tool call 组中间(assistant(toolCalls) 被删但 tool 响应被保留)
270
+ let safeKeepRecent = cfg.keepRecent;
271
+ while (safeKeepRecent < allHistory.length) {
272
+ const firstKeptMsg = allHistory[allHistory.length - safeKeepRecent];
273
+ if (firstKeptMsg.role === 'tool') {
274
+ safeKeepRecent++;
275
+ }
276
+ else {
277
+ break;
278
+ }
279
+ }
280
+ if (memory.trimHistory) {
281
+ const deleted = await memory.trimHistory(sessionId, safeKeepRecent);
282
+ ctx.logger.info(`会话已压缩: session=${sessionId}, 归档 ${deleted} 条旧消息,保留 ${safeKeepRecent} 条`);
283
+ }
284
+ else {
285
+ ctx.logger.warn('记忆服务不支持 trimHistory,旧消息未归档');
286
+ }
287
+ // 保存系统事件消息,供前端持久化显示压缩分隔线
288
+ const archive = ctx.getService('message-archive');
289
+ if (archive)
290
+ await archive.saveMessage(sessionId, {
291
+ role: 'system',
292
+ kind: WellKnownKinds.EventMarker,
293
+ content: '对话已压缩',
294
+ timestamp: summaryTs,
295
+ });
296
+ }
297
+ }
298
+ catch (err) {
299
+ ctx.logger.warn('生成会话摘要失败:', err);
300
+ }
301
+ finally {
302
+ summarizing.delete(sessionId);
303
+ }
304
+ }
305
+ // === 中间件:在 LLM 调用前注入摘要 ===
306
+ // 优先级 40(低于 vector-memory 的 50,确保摘要在向量记忆之后注入)
307
+ ctx.middleware('agent:llm:before', async (data, next) => {
308
+ const sessionId = data.sessionId;
309
+ if (!sessionId) {
310
+ await next();
311
+ return;
312
+ }
313
+ const existing = await store.getSummary(sessionId);
314
+ if (existing?.summary) {
315
+ if (data.messages.some(m => m.role === 'system' && m.metadata?.injector === 'memory-summary')) {
316
+ await next();
317
+ return;
318
+ }
319
+ // 动态计算摘要 token 预算
320
+ const summaryBudget = getSummaryTokenBudget();
321
+ const summaryTokens = Math.ceil(existing.summary.length / 3);
322
+ let summaryContent = existing.summary;
323
+ // 如果超出预算,截断
324
+ if (summaryTokens > summaryBudget) {
325
+ const maxChars = summaryBudget * 3;
326
+ summaryContent = `${summaryContent.slice(0, maxChars)}\n... [摘要已截断]`;
327
+ }
328
+ const summaryMsg = {
329
+ role: 'system',
330
+ content: `以下是之前对话的摘要,包含了较早的对话上下文:\n${summaryContent}`,
331
+ metadata: { injector: 'memory-summary' },
332
+ };
333
+ // 插入到第一个 system 消息之后、其他消息之前
334
+ const idx = data.messages.findIndex(m => m.role !== 'system');
335
+ const insertIdx = idx === -1 ? data.messages.length : idx;
336
+ data.messages.splice(insertIdx, 0, summaryMsg);
337
+ }
338
+ await next();
339
+ });
340
+ // === 在 agent:turn:after 钩子触发摘要生成 ===
341
+ // 每轮对话结束后,异步检查是否需要生成摘要
342
+ ctx.middleware('agent:turn:after', async (data, next) => {
343
+ await next();
344
+ // 中止/异常回合不触发摘要:本轮没有产生有效新内容(用户停止或报错),
345
+ // 摘要无意义且浪费算力。turn:after 现已在 aborted/error 路径也触发(生命周期收口),
346
+ // 故此处需显式跳过这两种 outcome。
347
+ if (data.outcome === 'aborted' || data.outcome === 'error')
348
+ return;
349
+ // 异步触发,不阻塞主流程
350
+ generateSummary(data.sessionId).catch(err => {
351
+ ctx.logger.warn('异步摘要生成失败:', err);
352
+ });
353
+ });
354
+ // === 监听 token:usage 事件,预压缩触发 ===
355
+ // agent 在每次 LLM 调用前发出 token 使用统计;
356
+ // 当使用率超过 autoCompressThreshold(默认 0.7)时,转发为 session:compress(reason='auto') 启动后台压缩。
357
+ // 注意:generateSummary/session:compress 内部已有 summarizing 锁,这里再做一次提前判断避免无谓 emit。
358
+ ctx.on('token:usage', async (...args) => {
359
+ const data = args[0];
360
+ if (!data?.sessionId)
361
+ return;
362
+ if (cfg.autoCompressThreshold <= 0)
363
+ return;
364
+ if (data.usageRatio < cfg.autoCompressThreshold)
365
+ return;
366
+ if (summarizing.has(data.sessionId))
367
+ return;
368
+ ctx.logger.info(`Token 使用率 ${(data.usageRatio * 100).toFixed(1)}% 超过阈值 ${(cfg.autoCompressThreshold * 100).toFixed(0)}%,触发后台压缩`);
369
+ ctx
370
+ .emit('session:compress', { sessionId: data.sessionId, reason: 'auto', usageRatio: data.usageRatio })
371
+ .catch(() => { });
372
+ });
373
+ // === 监听手动/自动压缩事件 ===
374
+ ctx.on('session:compress', async (...args) => {
375
+ const data = args[0];
376
+ ctx.logger.info(`收到压缩请求: session=${data.sessionId}, reason=${data.reason ?? 'unknown'}`);
377
+ // 手动压缩时降低阈值要求:即使消息数不到 threshold 也强制执行
378
+ if (data.reason === 'manual' || data.reason === 'auto') {
379
+ if (summarizing.has(data.sessionId))
380
+ return;
381
+ summarizing.add(data.sessionId);
382
+ // 通知前端:压缩开始
383
+ ctx.emit('session:compressing', { sessionId: data.sessionId, status: 'start' }).catch(() => { });
384
+ try {
385
+ const memory = ctx.getService('memory');
386
+ const summaryModel = resolveSummaryModel();
387
+ if (!memory || !summaryModel) {
388
+ ctx.emit('session:compressing', { sessionId: data.sessionId, status: 'done' }).catch(() => { });
389
+ return;
390
+ }
391
+ const allHistory = await memory.getHistory(data.sessionId, 200);
392
+ // 手动压缩:只要有 > keepRecent 条消息就压缩
393
+ if (allHistory.length <= cfg.keepRecent) {
394
+ ctx.logger.info(`会话消息数 ${allHistory.length} ≤ keepRecent(${cfg.keepRecent}),无需压缩`);
395
+ ctx.emit('session:compressing', { sessionId: data.sessionId, status: 'done' }).catch(() => { });
396
+ return;
397
+ }
398
+ const messagesToSummarize = allHistory.slice(0, allHistory.length - cfg.keepRecent);
399
+ if (messagesToSummarize.length === 0) {
400
+ ctx.emit('session:compressing', { sessionId: data.sessionId, status: 'done' }).catch(() => { });
401
+ return;
402
+ }
403
+ const existing = await store.getSummary(data.sessionId);
404
+ const formattedMessages = messagesToSummarize
405
+ .filter(m => m.role === 'user' || m.role === 'assistant')
406
+ .map(m => `${m.role === 'user' ? (m.name ? `用户[${m.name}]` : '用户') : '助手'}: ${m.content ?? '(空)'}`)
407
+ .join('\\n');
408
+ // 从历史消息中提取最近的 todo-list 状态,注入到压缩上下文中
409
+ let todoContext = '';
410
+ try {
411
+ const recentMessages = allHistory.slice(-cfg.keepRecent);
412
+ const todoMsgs = recentMessages.filter(m => m.role === 'assistant' &&
413
+ m.toolCalls?.some(tc => tc.function.name === 'manage_todo_list' || tc.function.name === 'todo_manage'));
414
+ if (todoMsgs.length > 0) {
415
+ const lastTodo = todoMsgs[todoMsgs.length - 1];
416
+ const tc = lastTodo.toolCalls?.find(tc => tc.function.name === 'manage_todo_list' || tc.function.name === 'todo_manage');
417
+ if (tc?.function.arguments) {
418
+ todoContext = `\\n\\n当前任务列表状态:\\n${tc.function.arguments}`;
419
+ }
420
+ }
421
+ }
422
+ catch {
423
+ /* ignore */
424
+ }
425
+ const summaryBudget = getSummaryTokenBudget();
426
+ const budgetHint = `\n\n重要:你的摘要输出上限为 ${summaryBudget} tokens(约 ${summaryBudget * 4} 个英文字符,或约 ${Math.floor(summaryBudget / 1.5)} 个中文字符)。请合理分配篇幅,确保“【进行中的任务】”等关键结构能完整输出。`;
427
+ const summaryMessages = [{ role: 'system', content: summarySystemPrompt + budgetHint }];
428
+ const taskHint = data.reason === 'auto'
429
+ ? '\\n\\n注意:此次压缩是在任务执行过程中自动触发的,助手可能正在进行多步骤工作。请特别注意保留所有未完成的任务状态和下一步计划。'
430
+ : '';
431
+ if (existing?.summary) {
432
+ summaryMessages.push({
433
+ role: 'user',
434
+ content: `以下是之前的对话摘要:\\n${existing.summary}\\n\\n以下是新增的对话内容,请在之前摘要的基础上整合生成更新的摘要:\\n${formattedMessages}${todoContext}${taskHint}`,
435
+ });
436
+ }
437
+ else {
438
+ summaryMessages.push({
439
+ role: 'user',
440
+ content: `请为以下对话生成摘要:\\n${formattedMessages}${todoContext}${taskHint}`,
441
+ });
442
+ }
443
+ ctx.logger.debug(`正在压缩 session=${data.sessionId} (${messagesToSummarize.length} 条旧消息)`);
444
+ let summaryText = '';
445
+ const stream2 = summaryModel.chatStream?.({
446
+ messages: summaryMessages,
447
+ temperature: 0.3,
448
+ maxTokens: summaryBudget,
449
+ });
450
+ if (!stream2) {
451
+ const resp = await summaryModel.chat({
452
+ messages: summaryMessages,
453
+ temperature: 0.3,
454
+ maxTokens: summaryBudget,
455
+ });
456
+ summaryText = resp.content ?? '';
457
+ }
458
+ else {
459
+ for await (const chunk of stream2) {
460
+ if (chunk.contentDelta) {
461
+ summaryText += chunk.contentDelta;
462
+ }
463
+ }
464
+ }
465
+ if (summaryText.trim()) {
466
+ const finalSummary = summaryText.trim();
467
+ const summaryTs = Date.now();
468
+ await store.upsertSummary(data.sessionId, finalSummary, messagesToSummarize.length, allHistory.length);
469
+ // 安全调整:避免裁剪点落在 tool call 组中间
470
+ let safeKeepRecent = cfg.keepRecent;
471
+ while (safeKeepRecent < allHistory.length) {
472
+ const firstKeptMsg = allHistory[allHistory.length - safeKeepRecent];
473
+ if (firstKeptMsg.role === 'tool') {
474
+ safeKeepRecent++;
475
+ }
476
+ else {
477
+ break;
478
+ }
479
+ }
480
+ if (memory.trimHistory) {
481
+ const deleted = await memory.trimHistory(data.sessionId, safeKeepRecent);
482
+ ctx.logger.info(`压缩完成: session=${data.sessionId}, 归档 ${deleted} 条旧消息,保留 ${safeKeepRecent} 条`);
483
+ }
484
+ // 保存系统事件消息,供前端持久化显示压缩分隔线
485
+ const archive = ctx.getService('message-archive');
486
+ if (archive)
487
+ await archive.saveMessage(data.sessionId, {
488
+ role: 'system',
489
+ kind: WellKnownKinds.EventMarker,
490
+ content: '对话已压缩',
491
+ timestamp: summaryTs,
492
+ });
493
+ // 通知前端:压缩完成
494
+ ctx.emit('session:compressing', { sessionId: data.sessionId, status: 'done' }).catch(() => { });
495
+ }
496
+ }
497
+ catch (err) {
498
+ ctx.logger.warn('压缩会话失败:', err);
499
+ // 通知前端:压缩失败
500
+ ctx.emit('session:compressing', { sessionId: data.sessionId, status: 'error' }).catch(() => { });
501
+ }
502
+ finally {
503
+ summarizing.delete(data.sessionId);
504
+ }
505
+ }
506
+ else {
507
+ // 其他情况走标准流程
508
+ await generateSummary(data.sessionId);
509
+ }
510
+ });
511
+ // 统一记忆清除:通过 memory:clear hook 参与编排
512
+ ctx.middleware('memory:clear', async (data, next) => {
513
+ // 类型过滤:如果指定了 types 且不包含 summary,跳过
514
+ if (data.types && !data.types.includes('summary')) {
515
+ await next();
516
+ return;
517
+ }
518
+ try {
519
+ if (data.scope === 'all') {
520
+ await store.clearAll();
521
+ data.results.push({ source: 'summary', success: true, message: '所有会话摘要已清空' });
522
+ ctx.logger.info('所有会话摘要已清空');
523
+ }
524
+ else if (data.sessionId) {
525
+ await store.clearSession(data.sessionId);
526
+ data.results.push({ source: 'summary', success: true, message: '当前会话摘要已清空' });
527
+ ctx.logger.info(`会话摘要已清空: session=${data.sessionId}`);
528
+ }
529
+ }
530
+ catch (err) {
531
+ const msg = err instanceof Error ? err.message : String(err);
532
+ data.results.push({ source: 'summary', success: false, message: `摘要清空失败: ${msg}` });
533
+ ctx.logger.warn('摘要清空失败:', err);
534
+ }
535
+ await next();
536
+ });
537
+ // 清理
538
+ ctx.onDispose(() => {
539
+ ctx.logger.info('会话摘要插件已卸载');
540
+ });
541
+ }
542
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@aalis/plugin-memory-summary",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "keywords": [
6
+ "aalis-plugin"
7
+ ],
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "dependencies": {
14
+ "@aalis/plugin-agent-api": "^0.1.0",
15
+ "@aalis/plugin-llm-api": "^0.1.0",
16
+ "@aalis/plugin-message-api": "^0.1.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^22.0.0",
20
+ "typescript": "^5.7.0",
21
+ "@aalis/plugin-memory-api": "0.1.0",
22
+ "@aalis/core": "0.1.0",
23
+ "@aalis/plugin-message-archive-api": "0.1.0"
24
+ },
25
+ "peerDependencies": {
26
+ "@aalis/core": "^0.1.0"
27
+ },
28
+ "aalis": {
29
+ "service": {
30
+ "required": [
31
+ "memory",
32
+ "llm"
33
+ ],
34
+ "optional": [
35
+ "message-archive"
36
+ ]
37
+ }
38
+ },
39
+ "scripts": {
40
+ "build": "tsc",
41
+ "dev": "tsc --watch"
42
+ }
43
+ }