@xgjktech/xg_cwork_im 1.17.12 → 1.17.15

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.
@@ -0,0 +1,420 @@
1
+ /** 用户可见的任务进度展示:把 OpenClaw 原始 hook 事件翻译成产品化文案。 */
2
+ const WS_DISPLAY_TEXT_MAX = 200;
3
+ const WS_PROGRESS_SUMMARY_MAX = 200;
4
+ const TOOL_LABEL_ZH = {
5
+ exec: "命令执行",
6
+ read: "读取文件",
7
+ read_file: "读取文件",
8
+ write: "写入文件",
9
+ write_file: "写入文件",
10
+ write_to_file: "写入文件",
11
+ edit: "编辑文件",
12
+ replace_file_content: "编辑文件",
13
+ multi_replace_file_content: "编辑文件",
14
+ grep: "内容搜索",
15
+ glob_file_search: "文件搜索",
16
+ memory_search: "记忆检索",
17
+ sessions_list: "会话列表",
18
+ sessions_history: "会话历史",
19
+ xg_cwork_im_get_group_chat_history: "群聊历史",
20
+ pdf: "PDF解析",
21
+ web_search: "网页搜索",
22
+ google_search: "网页搜索",
23
+ fetch_webpage: "网页读取",
24
+ browse: "网页浏览",
25
+ };
26
+ function clipWsDisplayText(text, max = WS_DISPLAY_TEXT_MAX) {
27
+ const t = text.trim();
28
+ if (!t)
29
+ return "";
30
+ if (t.length <= max)
31
+ return t;
32
+ return `${t.slice(0, Math.max(0, max - 1))}…`;
33
+ }
34
+ function clipWsProgressSummary(text, max = WS_PROGRESS_SUMMARY_MAX) {
35
+ const t = text.trim().replace(/\r\n/g, "\n").replace(/\n+/g, " ");
36
+ if (!t)
37
+ return "";
38
+ if (t.length <= max)
39
+ return t;
40
+ return `${t.slice(0, Math.max(0, max - 1))}…`;
41
+ }
42
+ function firstStringField(args, keys) {
43
+ for (const k of keys) {
44
+ const v = args[k];
45
+ if (typeof v === "string" && v.trim().length > 0)
46
+ return v.trim();
47
+ }
48
+ return undefined;
49
+ }
50
+ function friendlyToolLabel(raw, simplify = false) {
51
+ const k = raw.trim();
52
+ if (!k)
53
+ return "工具";
54
+ if (simplify) {
55
+ if (k === "exec")
56
+ return "数据处理";
57
+ if (k === "process")
58
+ return "数据分析";
59
+ }
60
+ return TOOL_LABEL_ZH[k] ?? k;
61
+ }
62
+ function getFriendlyFileType(fileName) {
63
+ const clean = fileName.trim();
64
+ if (clean.endsWith("/") || clean.endsWith("\\") || (!clean.includes(".") && clean !== "")) {
65
+ return "目录";
66
+ }
67
+ const lower = clean.toLowerCase();
68
+ const ext = lower.includes(".") ? lower.split(".").pop() : "";
69
+ if (ext === "docx" || ext === "doc")
70
+ return "Word 文档";
71
+ if (ext === "xlsx" || ext === "xls")
72
+ return "Excel 表格";
73
+ if (ext === "pptx" || ext === "ppt")
74
+ return "PPT 幻灯片";
75
+ if (ext === "pdf")
76
+ return "PDF 文档";
77
+ if (ext === "zip" || ext === "rar" || ext === "tar" || ext === "gz")
78
+ return "压缩文件";
79
+ if (ext === "md" || ext === "markdown")
80
+ return "Markdown 文档";
81
+ if (ext === "txt")
82
+ return "文本文件";
83
+ if (ext === "csv")
84
+ return "CSV 数据表";
85
+ return "文件";
86
+ }
87
+ function commandIncludesAny(clean, needles) {
88
+ return needles.some((needle) => clean.includes(needle));
89
+ }
90
+ function getFriendlyCommandDescription(cmd) {
91
+ const clean = cmd.trim();
92
+ const lower = clean.toLowerCase();
93
+ if (!clean)
94
+ return "正在进行数据分析与处理…";
95
+ if (commandIncludesAny(lower, ["matplotlib", "seaborn", "plt.", "plot(", "chart("])) {
96
+ return "正在生成数据分析可视化图表…";
97
+ }
98
+ if (commandIncludesAny(lower, ["pandas", "pd.", "openpyxl", "load_workbook", ".csv", "csv."])) {
99
+ return "正在分析和处理数据表格…";
100
+ }
101
+ if (commandIncludesAny(lower, ["docx", "document("])) {
102
+ return "正在提取 Word 文档内容…";
103
+ }
104
+ if (commandIncludesAny(lower, ["pdfplumber", "pypdf"]) || /\bpdf\b/.test(lower)) {
105
+ return "正在提取 PDF 文档内容…";
106
+ }
107
+ if (lower.startsWith("curl ") || lower.startsWith("wget ") || commandIncludesAny(lower, ["requests.", "urllib"])) {
108
+ return "正在获取远程网络数据…";
109
+ }
110
+ if (commandIncludesAny(lower, ["zipfile", "unzip", "tar ", "gzip"])) {
111
+ return "正在解压缩或打包文件数据…";
112
+ }
113
+ if (lower.startsWith("git ") || lower.includes(" git ")) {
114
+ if (lower.includes(" commit"))
115
+ return "正在提交本地代码变更";
116
+ if (lower.includes(" push"))
117
+ return "正在将本地代码推送到远程仓库";
118
+ if (lower.includes(" status"))
119
+ return "正在检查 Git 仓库状态";
120
+ if (lower.includes(" diff"))
121
+ return "正在生成代码差异对比";
122
+ if (lower.includes(" log"))
123
+ return "正在获取 Git 提交历史记录";
124
+ if (lower.includes(" add"))
125
+ return "正在暂存文件变更";
126
+ if (lower.includes(" pull") || lower.includes(" fetch"))
127
+ return "正在拉取远程仓库最新代码";
128
+ if (lower.includes(" clone"))
129
+ return "正在克隆远程代码仓库";
130
+ if (lower.includes(" checkout") || lower.includes(" switch"))
131
+ return "正在切换 Git 分支";
132
+ if (lower.includes(" branch"))
133
+ return "正在查看 Git 分支清单";
134
+ return "正在执行 Git 仓库操作";
135
+ }
136
+ if (lower.includes("pip install") || lower.includes("pip3 install")) {
137
+ const pkgMatch = clean.match(/install\s+(?:--user\s+)?([a-zA-Z0-9_\-\[\]]+)/);
138
+ return pkgMatch ? `正在准备运行环境:安装依赖包「${pkgMatch[1]}」…` : "正在准备所需的运行环境…";
139
+ }
140
+ if (commandIncludesAny(lower, ["npm install", "pnpm install", "yarn install", "pnpm i ", "npm i "])) {
141
+ return "正在准备所需的运行环境…";
142
+ }
143
+ if (commandIncludesAny(lower, ["npm run build", "pnpm build", "yarn build"])) {
144
+ return "正在编译构建项目代码";
145
+ }
146
+ if (lower.includes("npm run ") || lower.startsWith("npm ") || lower.startsWith("pnpm ") || lower.startsWith("yarn ")) {
147
+ return "正在运行项目开发命令";
148
+ }
149
+ if (lower.startsWith("find ") || lower.includes(" find ") || lower.startsWith("grep ") || lower.includes(" grep ")) {
150
+ return "正在检索匹配的文本内容…";
151
+ }
152
+ if (lower.startsWith("ls ") || lower === "ls" || lower.includes(" ls ")) {
153
+ return "正在读取目录文件列表";
154
+ }
155
+ if (lower.includes("import ") || lower.includes("from ")) {
156
+ if (lower.includes("sys.path") || lower.includes("import sys"))
157
+ return "正在检测系统运行环境";
158
+ if (commandIncludesAny(lower, ["import docx", "import openpyxl", "import pdfplumber", "import zipfile"])) {
159
+ if (lower.includes("try:") || clean.length < 100)
160
+ return "正在检测文档解析器依赖性";
161
+ }
162
+ return "正在通过 Python 执行数据提取与转换";
163
+ }
164
+ if (lower.startsWith("cat ") || lower.includes(" cat "))
165
+ return "正在读取文件原始文本";
166
+ if (lower.startsWith("rm ") || lower.includes(" rm "))
167
+ return "正在清理临时缓存文件";
168
+ if (lower.startsWith("mkdir ") || lower.includes(" mkdir "))
169
+ return "正在创建目录结构";
170
+ if (lower.startsWith("cp ") || lower.includes(" cp ") || lower.startsWith("mv ") || lower.includes(" mv ")) {
171
+ return "正在移动或备份文件";
172
+ }
173
+ return "正在进行数据分析与处理…";
174
+ }
175
+ function buildToolStartSummary(toolRaw, args, simplify = false) {
176
+ if (!args || typeof args !== "object")
177
+ return undefined;
178
+ if (simplify) {
179
+ if (toolRaw === "exec") {
180
+ const cmd = typeof args.command === "string" ? args.command.trim() : "";
181
+ if (!cmd)
182
+ return undefined;
183
+ const cdRegex = /^cd\s+("[^"]*"|'[^']*'|[^\s&;]+)\s*(&&|;)\s*/;
184
+ const cleanCmd = cmd.replace(cdRegex, "").trim();
185
+ if (cleanCmd.includes("dws_agent.py auth status") ||
186
+ cleanCmd.includes("get_device_auth_link.py") ||
187
+ cleanCmd.includes("install.sh")) {
188
+ return undefined;
189
+ }
190
+ const fileMatch = cleanCmd.match(/([^'"]+?\.(?:docx|doc|xlsx|xls|pptx|ppt|pdf|zip|md|markdown|txt|csv))/i);
191
+ if (fileMatch) {
192
+ const matchedPath = fileMatch[1];
193
+ const fileName = matchedPath.split(/[/\\]/).pop() || "";
194
+ const cleanName = fileName.endsWith("…") ? fileName.slice(0, -1) : fileName;
195
+ const fileType = getFriendlyFileType(cleanName);
196
+ if (fileType !== "目录" && fileType !== "文件" && cleanName.includes(".")) {
197
+ return `正在解析 ${fileType}「${cleanName}」`;
198
+ }
199
+ }
200
+ return getFriendlyCommandDescription(cleanCmd);
201
+ }
202
+ if (toolRaw === "read" || toolRaw === "read_file") {
203
+ const targetPath = firstStringField(args, ["TargetFile", "target_file", "path", "file_path"]);
204
+ if (targetPath) {
205
+ const fileName = targetPath.split(/[/\\]/).pop() || "";
206
+ return `正在读取 ${getFriendlyFileType(fileName)}「${fileName}」`;
207
+ }
208
+ }
209
+ const isWrite = toolRaw === "write" || toolRaw === "write_file" || toolRaw === "write_to_file";
210
+ const isEdit = toolRaw === "edit" || toolRaw === "replace_file_content" || toolRaw === "multi_replace_file_content";
211
+ if (isWrite || isEdit) {
212
+ const targetPath = firstStringField(args, ["TargetFile", "target_file", "path", "file_path"]);
213
+ if (targetPath) {
214
+ const fileName = targetPath.split(/[/\\]/).pop() || "";
215
+ const actionText = isWrite ? "保存" : "编辑";
216
+ return `正在${actionText} ${getFriendlyFileType(fileName)}「${fileName}」`;
217
+ }
218
+ }
219
+ if (toolRaw.includes("get_group_chat_history"))
220
+ return "正在获取群聊历史记录";
221
+ return undefined;
222
+ }
223
+ if (toolRaw === "exec") {
224
+ const cmd = typeof args.command === "string" ? args.command.replace(/\s+/g, " ").trim() : "";
225
+ const wdRaw = typeof args.workdir === "string" ? args.workdir.trim() : "";
226
+ const wd = wdRaw ? wdRaw.replace(/\\/g, "/") : "";
227
+ if (!cmd && !wd)
228
+ return undefined;
229
+ const head = cmd ? `run ${cmd}` : "run";
230
+ return clipWsProgressSummary(wd ? `${head} (in ${wd})` : head);
231
+ }
232
+ if (toolRaw === "read" || toolRaw === "read_file") {
233
+ const targetPath = firstStringField(args, ["TargetFile", "target_file", "path", "file_path"]);
234
+ if (targetPath)
235
+ return clipWsProgressSummary(targetPath.replace(/\\/g, "/"));
236
+ }
237
+ const isWrite = toolRaw === "write" || toolRaw === "write_file" || toolRaw === "write_to_file";
238
+ const isEdit = toolRaw === "edit" || toolRaw === "replace_file_content" || toolRaw === "multi_replace_file_content";
239
+ if (isWrite || isEdit) {
240
+ const targetPath = firstStringField(args, ["TargetFile", "target_file", "path", "file_path"]);
241
+ if (targetPath)
242
+ return clipWsProgressSummary(targetPath.replace(/\\/g, "/"));
243
+ }
244
+ if (toolRaw.includes("get_group_chat_history")) {
245
+ const gid = firstStringField(args, ["groupId", "group_id"]);
246
+ const lim = typeof args.limit === "number" ? args.limit : undefined;
247
+ const bits = [];
248
+ if (gid)
249
+ bits.push(`group=${gid}`);
250
+ if (lim != null)
251
+ bits.push(`limit=${lim}`);
252
+ if (bits.length > 0)
253
+ return clipWsProgressSummary(bits.join(", "));
254
+ }
255
+ const hint = firstStringField(args, ["query", "prompt", "url", "command"]) ??
256
+ (typeof args.tool === "string" ? args.tool : undefined);
257
+ if (hint && toolRaw !== "exec")
258
+ return clipWsProgressSummary(hint.replace(/\\/g, "/"));
259
+ return undefined;
260
+ }
261
+ function toolResultOutputSummary(payload) {
262
+ const body = (payload.markdown ?? payload.text ?? "").trim();
263
+ return body ? clipWsProgressSummary(body) : undefined;
264
+ }
265
+ function isTerminalCommandEvent(payload) {
266
+ const phase = typeof payload.phase === "string" ? payload.phase.toLowerCase() : "";
267
+ if (phase === "delta" || phase === "stream" || phase === "progress")
268
+ return false;
269
+ const status = typeof payload.status === "string" ? payload.status.toLowerCase() : "";
270
+ return (["completed", "complete", "done", "end", "failed", "fail", "error"].includes(phase) ||
271
+ ["completed", "failed", "error", "done"].includes(status) ||
272
+ payload.exitCode != null);
273
+ }
274
+ function isFailedCommandEvent(payload) {
275
+ const phase = typeof payload.phase === "string" ? payload.phase.toLowerCase() : "";
276
+ const status = typeof payload.status === "string" ? payload.status.toLowerCase() : "";
277
+ return phase === "failed" || phase === "fail" || phase === "error" || status === "failed" || status === "error" || (payload.exitCode != null && payload.exitCode !== 0);
278
+ }
279
+ export function createProgressDisplayController(options) {
280
+ const { simplify, stream } = options;
281
+ const toolNameStack = [];
282
+ let hasSentPlanUpdate = false;
283
+ let lastSentDisplayText = "";
284
+ async function send(message) {
285
+ const displayText = clipWsDisplayText(message.displayText);
286
+ if (!displayText)
287
+ return;
288
+ if (simplify && displayText === lastSentDisplayText)
289
+ return;
290
+ lastSentDisplayText = displayText;
291
+ await stream({
292
+ event: message.event,
293
+ displayText,
294
+ ...(message.summary?.trim() ? { summary: clipWsProgressSummary(message.summary) } : {}),
295
+ });
296
+ }
297
+ return {
298
+ async onToolStart(payload) {
299
+ const name = typeof payload.name === "string" && payload.name.trim().length > 0 ? payload.name.trim() : "tool";
300
+ const rawPhase = typeof payload.phase === "string" ? payload.phase.toLowerCase() : "";
301
+ if (rawPhase === "update" || rawPhase === "delta" || rawPhase === "progress")
302
+ return;
303
+ if (rawPhase === "end" || rawPhase === "fail" || rawPhase === "error")
304
+ return;
305
+ if (!rawPhase || rawPhase === "start")
306
+ toolNameStack.push(name);
307
+ if (simplify) {
308
+ const displayText = buildToolStartSummary(name, payload.args, true) ??
309
+ (name === "exec"
310
+ ? "正在进行数据分析与处理…"
311
+ : name === "read" || name === "read_file"
312
+ ? "正在读取文件内容…"
313
+ : name === "write" || name === "write_file"
314
+ ? "正在保存文件内容…"
315
+ : name === "grep"
316
+ ? "正在检索相关文本信息…"
317
+ : name === "glob_file_search"
318
+ ? "正在搜索相关文件…"
319
+ : name === "memory_search"
320
+ ? "正在检索关联背景知识…"
321
+ : name === "pdf"
322
+ ? "正在解析 PDF 文档…"
323
+ : name === "web_search" || name === "google_search"
324
+ ? "正在搜索网页相关资料…"
325
+ : name === "fetch_webpage" || name === "browse"
326
+ ? "正在读取网页内容…"
327
+ : name.includes("get_group_chat_history")
328
+ ? "正在获取群聊历史记录…"
329
+ : `正在执行「${friendlyToolLabel(name, true)}」操作…`);
330
+ await send({ event: "TOOL_PHASE", displayText });
331
+ return;
332
+ }
333
+ await send({
334
+ event: "TOOL_PHASE",
335
+ displayText: `正在调用「${friendlyToolLabel(name, false)}」工具…`,
336
+ summary: buildToolStartSummary(name, payload.args, false),
337
+ });
338
+ },
339
+ async onToolResult(payload) {
340
+ const toolName = toolNameStack.length > 0 ? toolNameStack.pop() : "tool";
341
+ if (simplify) {
342
+ if (payload.isError) {
343
+ await send({
344
+ event: "TOOL_PHASE",
345
+ displayText: "处理遇到一点问题,正在调整方式…",
346
+ });
347
+ }
348
+ return;
349
+ }
350
+ const label = friendlyToolLabel(toolName, false);
351
+ await send({
352
+ event: "TOOL_PHASE",
353
+ displayText: payload.isError ? `「${label}」工具处理失败` : `「${label}」工具已完成`,
354
+ summary: toolResultOutputSummary(payload),
355
+ });
356
+ },
357
+ async onPlanUpdate(payload) {
358
+ if (simplify) {
359
+ if (!hasSentPlanUpdate) {
360
+ hasSentPlanUpdate = true;
361
+ await send({ event: "PLAN_UPDATE", displayText: "正在规划任务执行步骤…" });
362
+ }
363
+ return;
364
+ }
365
+ const title = typeof payload.title === "string" ? payload.title.trim() : "";
366
+ if (title.length > 0) {
367
+ await send({
368
+ event: "PLAN_UPDATE",
369
+ displayText: `正在更新计划:${title}`,
370
+ summary: typeof payload.explanation === "string" ? payload.explanation.trim() : undefined,
371
+ });
372
+ return;
373
+ }
374
+ if (typeof payload.explanation === "string" && payload.explanation.trim().length > 0) {
375
+ await send({ event: "PLAN_UPDATE", displayText: `计划更新:${payload.explanation.trim()}` });
376
+ return;
377
+ }
378
+ await send({ event: "PLAN_UPDATE", displayText: "正在更新执行计划…" });
379
+ },
380
+ async onCompactionStart() {
381
+ if (!simplify)
382
+ await send({ event: "RUN_EVENT", displayText: "正在整理上下文…" });
383
+ },
384
+ async onCompactionEnd() {
385
+ if (!simplify)
386
+ await send({ event: "RUN_EVENT", displayText: "上下文整理完成" });
387
+ },
388
+ async onApprovalEvent(payload) {
389
+ const raw = typeof payload.title === "string" && payload.title.trim().length > 0
390
+ ? payload.title.trim()
391
+ : typeof payload.message === "string" && payload.message.trim().length > 0
392
+ ? payload.message.trim()
393
+ : "审批状态更新";
394
+ await send({ event: "RUN_EVENT", displayText: raw });
395
+ },
396
+ async onCommandOutput(payload) {
397
+ if (!isTerminalCommandEvent(payload))
398
+ return;
399
+ if (simplify) {
400
+ if (isFailedCommandEvent(payload)) {
401
+ await send({ event: "RUN_EVENT", displayText: "处理遇到一点问题,正在调整方式…" });
402
+ }
403
+ return;
404
+ }
405
+ const outRaw = typeof payload.output === "string" ? payload.output.trim() : "";
406
+ const summary = outRaw ? clipWsProgressSummary(outRaw) : undefined;
407
+ if (isFailedCommandEvent(payload)) {
408
+ const exitText = payload.exitCode != null && payload.exitCode !== 0 ? `(退出码 ${payload.exitCode})` : "";
409
+ await send({ event: "RUN_EVENT", displayText: `命令执行失败${exitText}`, summary });
410
+ return;
411
+ }
412
+ await send({ event: "RUN_EVENT", displayText: "命令已执行完毕", summary });
413
+ },
414
+ async onPatchSummary() {
415
+ if (!simplify)
416
+ await send({ event: "RUN_EVENT", displayText: "已记录文件变更摘要" });
417
+ },
418
+ };
419
+ }
420
+ //# sourceMappingURL=progress-display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-display.js","sourceRoot":"","sources":["../../src/progress-display.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,10 @@ export declare function startMonitor(params: {
14
14
  }): void;
15
15
  /** dispatch 中 BEGIN 后调用:写入 replyToMsgId */
16
16
  export declare function storeReplyToMsgId(groupId: string, replyToMsgId: string): void;
17
+ /** 检查指定 groupId 是否有活跃的 subagent(用于判断是否延迟 FINISHED) */
18
+ export declare function hasActiveSubagents(groupId: string): boolean;
19
+ /** 记录延迟的 FINISHED,等所有 subagent 完成后发送 */
20
+ export declare function deferFinished(groupId: string, reason: string, replyToMsgId: string): void;
17
21
  /** subagent_ended hook 调用 */
18
22
  export declare function markSubagentCompleted(childSessionKey: string, runId: string): void;
19
23
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"subagent-monitor.d.ts","sourceRoot":"","sources":["../../src/subagent-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAM7D,UAAU,iBAAiB;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaD,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AA8B5D,wBAAgB,YAAY,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAGzD;AAED,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,iBAAiB,CAAC;CAC1B,GAAG,IAAI,CA8CP;AAED,2CAA2C;AAC3C,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAc7E;AAED,6BAA6B;AAC7B,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CA2BlF"}
1
+ {"version":3,"file":"subagent-monitor.d.ts","sourceRoot":"","sources":["../../src/subagent-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAM7D,UAAU,iBAAiB;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaD,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAiC5D,wBAAgB,YAAY,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAGzD;AAED,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,iBAAiB,CAAC;CAC1B,GAAG,IAAI,CA8CP;AAED,2CAA2C;AAC3C,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAc7E;AAED,sDAAsD;AACtD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAS3D;AAED,wCAAwC;AACxC,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAGzF;AA8BD,6BAA6B;AAC7B,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CA8ElF"}
@@ -6,6 +6,8 @@ const childToGroup = new Map();
6
6
  const groupMonitors = new Map();
7
7
  /** groupId → replyToMsgId(dispatch 写入,startMonitor 读取) */
8
8
  const groupReplyTo = new Map();
9
+ /** 延迟的 FINISHED 信息:groupId → { reason, groupId, replyToMsgId } */
10
+ const deferredFinished = new Map();
9
11
  let tickerTimer = null;
10
12
  let pluginApi = null;
11
13
  const POLL_INTERVAL_MS = 15000;
@@ -74,6 +76,49 @@ export function storeReplyToMsgId(groupId, replyToMsgId) {
74
76
  console.log(`[subagent-monitor] storeReplyToMsgId: no monitor yet for groupId=${groupId}`);
75
77
  }
76
78
  }
79
+ /** 检查指定 groupId 是否有活跃的 subagent(用于判断是否延迟 FINISHED) */
80
+ export function hasActiveSubagents(groupId) {
81
+ const monitor = groupMonitors.get(groupId);
82
+ if (!monitor) {
83
+ console.log(`[subagent-monitor] hasActiveSubagents: no monitor for groupId=${groupId}`);
84
+ return false;
85
+ }
86
+ const active = Array.from(monitor.subagents.values()).some(r => !r.completed);
87
+ console.log(`[subagent-monitor] hasActiveSubagents groupId=${groupId}: ${active} (total=${monitor.subagents.size})`);
88
+ return active;
89
+ }
90
+ /** 记录延迟的 FINISHED,等所有 subagent 完成后发送 */
91
+ export function deferFinished(groupId, reason, replyToMsgId) {
92
+ console.log(`[subagent-monitor] deferFinished groupId=${groupId} reason=${reason}`);
93
+ deferredFinished.set(groupId, { reason, groupId, replyToMsgId });
94
+ }
95
+ /** 发送延迟的 FINISHED(在所有 subagent 完成时调用) */
96
+ async function sendDeferredFinished(groupId, monitor) {
97
+ const deferred = deferredFinished.get(groupId);
98
+ if (!deferred) {
99
+ console.log(`[subagent-monitor] sendDeferredFinished: no deferred FINISHED for groupId=${groupId}`);
100
+ return;
101
+ }
102
+ const client = getStreamClient(monitor.agentId);
103
+ if (!client) {
104
+ console.warn(`[subagent-monitor] sendDeferredFinished: no stream client for agentId=${monitor.agentId}`);
105
+ deferredFinished.delete(groupId);
106
+ return;
107
+ }
108
+ try {
109
+ await client.end(deferred.reason, {
110
+ groupId: deferred.groupId,
111
+ replyToMsgId: deferred.replyToMsgId,
112
+ });
113
+ console.log(`[subagent-monitor] sendDeferredFinished: FINISHED sent for groupId=${groupId} reason=${deferred.reason}`);
114
+ }
115
+ catch (err) {
116
+ console.error(`[subagent-monitor] sendDeferredFinished: error sending FINISHED: ${String(err)}`);
117
+ }
118
+ finally {
119
+ deferredFinished.delete(groupId);
120
+ }
121
+ }
77
122
  /** subagent_ended hook 调用 */
78
123
  export function markSubagentCompleted(childSessionKey, runId) {
79
124
  console.log(`[subagent-monitor] markSubagentCompleted childSessionKey=${childSessionKey} runId=${runId}`);
@@ -93,13 +138,61 @@ export function markSubagentCompleted(childSessionKey, runId) {
93
138
  return;
94
139
  }
95
140
  // 立即读取最新消息(补全 tick 间隔中可能遗漏的内容)
96
- if (pluginApi) {
97
- readSubagentMessages(record).catch((err) => {
98
- console.error(`[subagent-monitor] markSubagentCompleted: read error: ${String(err)}`);
99
- });
100
- }
101
- record.completed = true;
102
- console.log(`[subagent-monitor] markSubagentCompleted: marked completed for runId=${runId}`);
141
+ const readAndCheckCompletion = async () => {
142
+ if (pluginApi) {
143
+ try {
144
+ await readSubagentMessages(record);
145
+ }
146
+ catch (err) {
147
+ console.error(`[subagent-monitor] markSubagentCompleted: read error: ${String(err)}`);
148
+ }
149
+ }
150
+ record.completed = true;
151
+ console.log(`[subagent-monitor] markSubagentCompleted: marked completed for runId=${runId}`);
152
+ // ✅ 检查是否所有 subagent 都完成了
153
+ const allCompleted = Array.from(monitor.subagents.values()).every(r => r.completed);
154
+ if (allCompleted) {
155
+ console.log(`[subagent-monitor] markSubagentCompleted: all subagents completed for groupId=${entry.groupId}`);
156
+ // 发送最终 SUBAGENT_STAT
157
+ const client = getStreamClient(monitor.agentId);
158
+ if (client && monitor.replyToMsgId) {
159
+ try {
160
+ const subagentList = Array.from(monitor.subagents.entries()).map(([rid, rec]) => ({
161
+ runId: rid,
162
+ label: rec.label ?? rid.slice(0, 8),
163
+ status: rec.completed ? "completed" : "running",
164
+ messages: rec.messages.slice(rec.sendFrom),
165
+ }));
166
+ await client.sendEvent({
167
+ groupId: entry.groupId,
168
+ replyToMsgId: monitor.replyToMsgId,
169
+ event: "SUBAGENT_STAT",
170
+ data: { subagentList },
171
+ });
172
+ console.log(`[subagent-monitor] markSubagentCompleted: final SUBAGENT_STAT sent`);
173
+ }
174
+ catch (err) {
175
+ console.error(`[subagent-monitor] markSubagentCompleted: sendEvent error: ${String(err)}`);
176
+ }
177
+ }
178
+ // ✅ 发送延迟的 FINISHED(如果有的话)
179
+ await sendDeferredFinished(entry.groupId, monitor);
180
+ // 清理资源
181
+ console.log(`[subagent-monitor] markSubagentCompleted: cleaning up groupId=${entry.groupId}`);
182
+ for (const [childKey] of childToGroup) {
183
+ if (childToGroup.get(childKey)?.groupId === entry.groupId) {
184
+ childToGroup.delete(childKey);
185
+ }
186
+ }
187
+ groupReplyTo.delete(entry.groupId);
188
+ groupMonitors.delete(entry.groupId);
189
+ stopTickerIfIdle();
190
+ }
191
+ };
192
+ // 异步执行,不阻塞
193
+ readAndCheckCompletion().catch((err) => {
194
+ console.error(`[subagent-monitor] markSubagentCompleted: async error: ${String(err)}`);
195
+ });
103
196
  }
104
197
  async function readSubagentMessages(record) {
105
198
  const result = await pluginApi.runtime.subagent.getSessionMessages({
@@ -163,6 +256,8 @@ async function tick() {
163
256
  data: { subagentList },
164
257
  });
165
258
  console.log(`[subagent-monitor] final SUBAGENT_STAT sent for groupId=${groupId}`);
259
+ // ✅ 发送延迟的 FINISHED
260
+ await sendDeferredFinished(groupId, monitor);
166
261
  }
167
262
  catch {
168
263
  console.log(`[subagent-monitor] WS unavailable, defer cleanup for groupId=${groupId}`);