@ai-zen/agents-sdk 1.0.0-alpha.0 → 1.0.0-alpha.10

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 (44) hide show
  1. package/CHANGELOG.md +153 -0
  2. package/README.md +15 -14
  3. package/README.zh.md +15 -14
  4. package/dist/agent-plugins/AutoMigratePlugin.d.ts +33 -7
  5. package/dist/agent-plugins/AutoMigratePlugin.js +20 -6
  6. package/dist/agent-plugins/ContextGuardPlugin.d.ts +13 -3
  7. package/dist/agent-plugins/ContextGuardPlugin.js +9 -6
  8. package/dist/config/ConfigManager.d.ts +29 -1
  9. package/dist/config/ConfigManager.js +84 -2
  10. package/dist/config/constants.d.ts +3 -1
  11. package/dist/config/constants.js +77 -39
  12. package/dist/config/factory-skills.d.ts +33 -0
  13. package/dist/config/factory-skills.js +126 -0
  14. package/dist/index.d.ts +6 -4
  15. package/dist/index.js +5 -2
  16. package/dist/runtime/HandoffGuardPlugin.d.ts +35 -0
  17. package/dist/runtime/HandoffGuardPlugin.js +65 -0
  18. package/dist/runtime/HandoffService.d.ts +199 -0
  19. package/dist/runtime/HandoffService.js +372 -0
  20. package/dist/scope/plugins/builtin/BatchEditTool.js +1 -1
  21. package/dist/scope/plugins/builtin/DownloadFileTool.js +1 -1
  22. package/dist/scope/plugins/builtin/ExecTool.js +2 -2
  23. package/dist/scope/plugins/builtin/FindTextTool.js +6 -6
  24. package/dist/scope/plugins/builtin/GenerateImageTool.d.ts +1 -1
  25. package/dist/scope/plugins/builtin/GenerateImageTool.js +7 -7
  26. package/dist/scope/plugins/builtin/GlobTool.js +1 -1
  27. package/dist/scope/plugins/builtin/InspectFileTool.d.ts +2 -2
  28. package/dist/scope/plugins/builtin/InspectFileTool.js +5 -5
  29. package/dist/scope/plugins/builtin/LsTool.js +1 -1
  30. package/dist/scope/plugins/builtin/{ReadFileTool.d.ts → ReadTool.d.ts} +1 -1
  31. package/dist/scope/plugins/builtin/{ReadFileTool.js → ReadTool.js} +3 -3
  32. package/dist/scope/plugins/builtin/{ExecAsyncTool.d.ts → SpawnTool.d.ts} +1 -1
  33. package/dist/scope/plugins/builtin/{ExecAsyncTool.js → SpawnTool.js} +2 -2
  34. package/dist/scope/plugins/builtin/ViewImageTool.js +2 -2
  35. package/dist/scope/plugins/builtin/{WriteFileTool.d.ts → WriteTool.d.ts} +1 -1
  36. package/dist/scope/plugins/builtin/{WriteFileTool.js → WriteTool.js} +2 -2
  37. package/dist/scope/plugins/builtin/index.d.ts +4 -4
  38. package/dist/scope/plugins/builtin/index.js +7 -7
  39. package/dist/scope/plugins/builtin/outputGuard.d.ts +2 -2
  40. package/dist/scope/plugins/builtin/outputGuard.js +1 -1
  41. package/dist/types/index.d.ts +24 -3
  42. package/package.json +3 -3
  43. package/dist/runtime/TaskMigrationService.d.ts +0 -128
  44. package/dist/runtime/TaskMigrationService.js +0 -211
@@ -1,211 +0,0 @@
1
- import { Message } from "@ai-zen/agents-core";
2
- import { getLogger } from "../shared/logger.js";
3
- /**
4
- * 任务迁移服务。
5
- *
6
- * 一个服务实例对应一次迁移上下文。它**不持有**任何模型调用——生成交接文档时
7
- * 默认复用传入 `agent`(`SdkAgent`)自身的 `client` / `model` / `modelConfig`,
8
- * 因此无需 Scope、无需独立「迁移 Agent」对象,也无需自建 OpenAI 客户端。
9
- * 如需用不同模型生成交接文档,可在构造时显式传入 `client` / `model` / `modelConfig`,
10
- * 未传则 migrate 时回退到 agent 自带的配置。
11
- *
12
- * 职责:
13
- * 1. 生成交接文档的提示词 / 注入格式(静态纯工具,供上层使用)
14
- * 2. 执行完整迁移(串行化 → 模型生成 → 按策略处理历史 + 追加对话断点),并暴露迁移前后钩子(实例方法)
15
- *
16
- * 设计上,`AutoMigratePlugin` 只负责「何时触发」(检测 token 超限),
17
- * 实际迁移逻辑统一收敛到本服务,从而让手动迁移与自动迁移复用同一条链路。
18
- */
19
- export class TaskMigrationService {
20
- static HANDOFF_SECTIONS = {
21
- breakpoint: "## 💬 对话断点",
22
- completed: "## ✅ 已完成的任务",
23
- pending: "## 📋 未完成的任务",
24
- memory: "## 🧠 重要记忆",
25
- files: "## 📁 文件索引",
26
- instructions: "## 🔔 接手指令",
27
- };
28
- onBeforeMigrate;
29
- onMigrated;
30
- client;
31
- model;
32
- modelConfig;
33
- strategy;
34
- logger;
35
- constructor(options = {}) {
36
- const { onBeforeMigrate, onMigrated, logger, client, model, modelConfig, strategy } = options;
37
- this.onBeforeMigrate = onBeforeMigrate;
38
- this.onMigrated = onMigrated;
39
- this.client = client;
40
- this.model = model;
41
- this.modelConfig = modelConfig;
42
- this.strategy = strategy ?? "omit";
43
- this.logger = logger ?? getLogger();
44
- }
45
- static createPrompt() {
46
- return [
47
- "根据以下对话历史,生成一篇结构化交接文档。不要做任何解释,只输出交接文档。",
48
- "",
49
- `文档必须包含以下章节:`,
50
- `${TaskMigrationService.HANDOFF_SECTIONS.breakpoint}`,
51
- `- 用户最后说了什么,AI 最后回复了什么`,
52
- "",
53
- `${TaskMigrationService.HANDOFF_SECTIONS.completed}`,
54
- `- 列出已完成的每项任务及其关键产出`,
55
- "",
56
- `${TaskMigrationService.HANDOFF_SECTIONS.pending}`,
57
- `- 按优先级列出未完成的任务、当前进度、下一步`,
58
- "",
59
- `${TaskMigrationService.HANDOFF_SECTIONS.memory}`,
60
- `- 需要新 Agent 记住的关键信息(设计决策、偏好、约定等)`,
61
- "",
62
- `${TaskMigrationService.HANDOFF_SECTIONS.files}`,
63
- `- 涉及的文件及其用途`,
64
- "",
65
- `${TaskMigrationService.HANDOFF_SECTIONS.instructions}`,
66
- `- 接手后建议的操作步骤`,
67
- ].join("\n");
68
- }
69
- /**
70
- * 生成迁移后追加的「对话断点」消息(role=user):交接文档 + 接手指令。
71
- * 该消息是 omit 迁移方案中新上下文的起点,模型看到的序列为
72
- * `[definition.messages, 断点消息]`(历史消息已被标记 omit,不再发送)。
73
- */
74
- static createPostMessages(handoffDoc) {
75
- const content = [
76
- "这是上一轮对话的任务交接文档。请先阅读交接文档,理解上下文后再继续协助用户完成任务。",
77
- "",
78
- "---",
79
- "",
80
- handoffDoc,
81
- "",
82
- "---",
83
- "",
84
- "请确认你已理解以上内容,然后询问用户接下来需要什么帮助。",
85
- ].join("\n");
86
- return [Message.User(content)];
87
- }
88
- /**
89
- * 序列化消息为 `[role]: content` 文本,供模型理解完整对话历史。
90
- */
91
- static serializeMessages(messages) {
92
- return messages
93
- .map((m) => {
94
- const role = m.role ?? "unknown";
95
- const content = typeof m.content === "string" ? m.content : JSON.stringify(m.content);
96
- return `[${role}]: ${content}`;
97
- })
98
- .join("\n\n");
99
- }
100
- /**
101
- * 生成交接文档:使用指定的 client / model / modelConfig 带交接 prompt 生成结构化文档。
102
- */
103
- async generateHandoff(client, model, modelConfig, historyText) {
104
- const response = await client.chat.completions.create({
105
- model,
106
- ...(modelConfig ?? {}),
107
- messages: [
108
- { role: "system", content: TaskMigrationService.createPrompt() },
109
- { role: "user", content: historyText },
110
- ],
111
- });
112
- const handoffDoc = response.choices[0]?.message?.content;
113
- if (!handoffDoc) {
114
- throw new Error("未能生成任务交接文档");
115
- }
116
- return handoffDoc;
117
- }
118
- /**
119
- * 执行完整迁移:序列化历史 → 模型生成交接文档 → 按策略处理历史并追加对话断点 → 触发钩子。
120
- *
121
- * 策略(`strategy`,构造函数默认 / 本参数可覆盖):
122
- * - `omit`(默认):`agent.definition.messages`(模板)保留,其余既有历史标记 `omit: true`(仍存于
123
- * `agent.messages` 可审计/回放但不再发送给模型),末尾追加「对话断点」消息。因此 `formatHistory()`
124
- * 发送给模型的是 `[definition.messages, 断点消息]` —— 历史被压缩但并不删除。
125
- * - `prune`:物理剔除历史,只保留 `definition.messages` + 断点消息(即原先的替换行为)。
126
- *
127
- * 设计约束:
128
- * - 不重建 Agent,保留所有引用与插件绑定(仅重建消息列表)
129
- * - 钩子(onBeforeMigrate / onMigrated)抛错会被捕获并记录,**不中断**迁移流程
130
- * - 生成失败 / 未取到交接文档时抛错,此时 `agent.messages` 保持原样(不会被部分修改)
131
- *
132
- * @param params.agent 当前对话 Agent
133
- * @param params.promptTokens 当前 prompt token 用量(可选)
134
- * @param params.maxTokens 上下文阈值(可选)
135
- * @param params.strategy 本次迁移的历史处理策略(可选,覆盖构造时的默认值)
136
- * @returns 完整的迁移上下文(含生成的交接文档)
137
- */
138
- async migrate(params) {
139
- const { agent, promptTokens, maxTokens, strategy: overrideStrategy } = params;
140
- const strategy = overrideStrategy ?? this.strategy;
141
- // 序列化有效上下文:过滤已标记 omit 的历史,避免重复迁移时把旧省略历史再次喂给模型。
142
- // historyText 供模型生成交接文档,而 messageCountBefore 仍记录本次迁移前的消息总数。
143
- const historyText = TaskMigrationService.serializeMessages(agent.messages.filter((m) => !m.omit));
144
- const messageCountBefore = agent.messages.length;
145
- // 生成交接文档所用模型调用:优先使用构造时传入的 client/model/modelConfig,
146
- // 未传则回退到 agent 自带的(无需 Scope / 独立迁移 Agent)。
147
- const client = this.client ?? agent.client;
148
- const model = this.model ?? agent.model;
149
- const modelConfig = this.modelConfig ?? agent.modelConfig;
150
- // 迁移前上下文(不含 handoffDoc,独立对象,语义固定)
151
- const beforeCtx = {
152
- agent,
153
- model,
154
- maxTokens,
155
- promptTokens,
156
- historyText,
157
- messageCountBefore,
158
- };
159
- // 迁移前钩子(容错,不中断)
160
- if (this.onBeforeMigrate) {
161
- try {
162
- await this.onBeforeMigrate(beforeCtx);
163
- }
164
- catch (err) {
165
- this.logger.error(`[migrate] onBeforeMigrate 回调失败: ${err?.message ?? err}`);
166
- }
167
- }
168
- // 生成交接文档
169
- const handoffDoc = await this.generateHandoff(client, model, modelConfig, historyText);
170
- // 重建消息列表:按策略处理历史(omit 标记保留 / prune 物理剔除),并追加「对话断点」消息。
171
- // 均用浅拷贝/新数组,避免直接修改 definition.messages 引用的对象(防止污染模板)。
172
- const breakpointMessages = TaskMigrationService.createPostMessages(handoffDoc);
173
- let nextMessages;
174
- if (strategy === "prune") {
175
- // 物理剔除:只保留模板消息 + 断点
176
- nextMessages = [...agent.definition.messages, ...breakpointMessages];
177
- }
178
- else {
179
- // omit(默认):以 definition.messages 长度为界保留模板消息,其余历史统一标记 omit
180
- const preserveCount = Math.min(agent.definition.messages.length, agent.messages.length);
181
- nextMessages = [
182
- ...agent.messages.map((m, i) => ({
183
- ...m,
184
- omit: i >= preserveCount ? true : m.omit,
185
- })),
186
- ...breakpointMessages,
187
- ];
188
- }
189
- agent.messages = nextMessages;
190
- // 迁移后上下文(含 handoffDoc,与迁移前上下文独立)
191
- const afterCtx = {
192
- agent,
193
- model,
194
- maxTokens,
195
- promptTokens,
196
- historyText,
197
- messageCountBefore,
198
- handoffDoc,
199
- };
200
- // 迁移后钩子(容错,不中断;此时交接文档已注入)
201
- if (this.onMigrated) {
202
- try {
203
- await this.onMigrated(afterCtx);
204
- }
205
- catch (err) {
206
- this.logger.error(`[migrate] onMigrated 回调失败: ${err?.message ?? err}`);
207
- }
208
- }
209
- return afterCtx;
210
- }
211
- }