@xgjktech/xg_cwork_im 1.17.32 → 1.17.34

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/README.md +484 -484
  2. package/dist/src/action-run-event.d.ts +14 -2
  3. package/dist/src/action-run-event.d.ts.map +1 -1
  4. package/dist/src/action-run-event.js +37 -10
  5. package/dist/src/action-run-event.js.map +1 -1
  6. package/dist/src/action-run-event.test.js +39 -7
  7. package/dist/src/action-run-event.test.js.map +1 -1
  8. package/dist/src/build-project-prompt.test.js +18 -18
  9. package/dist/src/deliver-text.test.js +22 -22
  10. package/dist/src/gateway-session-queue.d.ts +6 -2
  11. package/dist/src/gateway-session-queue.d.ts.map +1 -1
  12. package/dist/src/gateway-session-queue.js +21 -78
  13. package/dist/src/gateway-session-queue.js.map +1 -1
  14. package/dist/src/modified-file-push-tracker.d.ts +24 -0
  15. package/dist/src/modified-file-push-tracker.d.ts.map +1 -0
  16. package/dist/src/modified-file-push-tracker.js +125 -0
  17. package/dist/src/modified-file-push-tracker.js.map +1 -0
  18. package/dist/src/plan-store-access.test.js +9 -9
  19. package/dist/src/progress-display.d.ts +77 -0
  20. package/dist/src/progress-display.d.ts.map +1 -0
  21. package/dist/src/progress-display.js +420 -0
  22. package/dist/src/progress-display.js.map +1 -0
  23. package/dist/src/send-file-event.d.ts +26 -0
  24. package/dist/src/send-file-event.d.ts.map +1 -0
  25. package/dist/src/send-file-event.js +33 -0
  26. package/dist/src/send-file-event.js.map +1 -0
  27. package/dist/src/send-file-event.test.d.ts +2 -0
  28. package/dist/src/send-file-event.test.d.ts.map +1 -0
  29. package/dist/src/send-file-event.test.js +86 -0
  30. package/dist/src/send-file-event.test.js.map +1 -0
  31. package/dist/src/send-file-tool.d.ts.map +1 -1
  32. package/dist/src/send-file-tool.js +9 -0
  33. package/dist/src/send-file-tool.js.map +1 -1
  34. package/dist/src/subagent-delivery-phase.d.ts +10 -0
  35. package/dist/src/subagent-delivery-phase.d.ts.map +1 -0
  36. package/dist/src/subagent-delivery-phase.js +4 -0
  37. package/dist/src/subagent-delivery-phase.js.map +1 -0
  38. package/dist/src/subagent-delivery-phase.test.d.ts +2 -0
  39. package/dist/src/subagent-delivery-phase.test.d.ts.map +1 -0
  40. package/dist/src/subagent-delivery-phase.test.js +12 -0
  41. package/dist/src/subagent-delivery-phase.test.js.map +1 -0
  42. package/dist/src/turn-deliver-buffer.test.js +25 -25
  43. package/openclaw.plugin.json +27 -27
  44. package/package.json +78 -78
@@ -1,6 +1,18 @@
1
1
  import type { ActionDispatchEvent } from "./action-store-access.js";
2
- /** 剥离仅用于服务端路由的 origin,避免 sessionKey 等内部字段泄露到前端。 */
3
- export declare function toWireAction(action: ActionDispatchEvent): Omit<ActionDispatchEvent, "origin">;
2
+ /**
3
+ * 构造 ACTION_DISPATCH 的前端数据,只保留前端消费动作所需的业务字段。
4
+ * `origin` 是内部路由信息,`event` 与 `version` 不属于该事件的 wire 契约,均不透传。
5
+ */
6
+ export declare function toWireAction(action: ActionDispatchEvent): {
7
+ eventId: string;
8
+ action: string;
9
+ topic?: string;
10
+ target: string;
11
+ status: ActionDispatchEvent["status"];
12
+ scopeControl?: ActionDispatchEvent["scopeControl"];
13
+ payload: ActionDispatchEvent["payload"];
14
+ timestamp: string;
15
+ };
4
16
  /**
5
17
  * 将权威 action 状态发给前端。必须保持同步返回:网络发送在内部 fire-and-forget。
6
18
  */
@@ -1 +1 @@
1
- {"version":3,"file":"action-run-event.d.ts","sourceRoot":"","sources":["../../src/action-run-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAKpE,mDAAmD;AACnD,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAG7F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CAyBpE"}
1
+ {"version":3,"file":"action-run-event.d.ts","sourceRoot":"","sources":["../../src/action-run-event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAsBpE;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACtC,YAAY,CAAC,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAC;IACnD,OAAO,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;CACrB,CAWA;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,CA2BpE"}
@@ -1,9 +1,35 @@
1
1
  import { getPlanWsClient } from "./plan-ws-registry.js";
2
2
  const LOG_PREFIX = "[xg_cwork_im] [action-run-event]";
3
- /** 剥离仅用于服务端路由的 origin,避免 sessionKey 等内部字段泄露到前端。 */
3
+ function isRecord(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5
+ }
6
+ /**
7
+ * action 存储契约为 `payload.data`,但当前上游会将实际业务参数再包进 `payload.data.data`。
8
+ * 仅当外层没有其他字段时才解包,防止丢失未来上游追加的元数据。
9
+ */
10
+ function toWirePayload(payload) {
11
+ const outerData = payload.data;
12
+ const nestedData = outerData.data;
13
+ if (Object.keys(outerData).length === 1 && isRecord(nestedData)) {
14
+ return { data: nestedData };
15
+ }
16
+ return payload;
17
+ }
18
+ /**
19
+ * 构造 ACTION_DISPATCH 的前端数据,只保留前端消费动作所需的业务字段。
20
+ * `origin` 是内部路由信息,`event` 与 `version` 不属于该事件的 wire 契约,均不透传。
21
+ */
4
22
  export function toWireAction(action) {
5
- const { origin: _origin, ...wireAction } = action;
6
- return wireAction;
23
+ return {
24
+ eventId: action.eventId,
25
+ action: action.action,
26
+ ...(action.topic ? { topic: action.topic } : {}),
27
+ target: action.target,
28
+ status: action.status,
29
+ ...(action.scopeControl ? { scopeControl: action.scopeControl } : {}),
30
+ payload: toWirePayload(action.payload),
31
+ timestamp: action.timestamp,
32
+ };
7
33
  }
8
34
  /**
9
35
  * 将权威 action 状态发给前端。必须保持同步返回:网络发送在内部 fire-and-forget。
@@ -12,22 +38,23 @@ export function sendActionRunEvent(action) {
12
38
  const channel = action.origin?.channel;
13
39
  const to = action.origin?.to;
14
40
  if (channel !== "xg_cwork_im" || !to) {
15
- console.warn(`${LOG_PREFIX} action.origin 缺失或非本通道,跳过 RUN_EVENT eventId=${action.eventId}`);
41
+ console.warn(`${LOG_PREFIX} action.origin 缺失或非本通道,跳过 ACTION_DISPATCH eventId=${action.eventId}`);
16
42
  return;
17
43
  }
18
44
  const target = getPlanWsClient(to);
19
45
  if (!target) {
20
- console.warn(`${LOG_PREFIX} 未登记 WS client,跳过 RUN_EVENT eventId=${action.eventId} groupId=${to}`);
46
+ console.warn(`${LOG_PREFIX} 未登记 WS client,跳过 ACTION_DISPATCH eventId=${action.eventId} groupId=${to}`);
21
47
  return;
22
48
  }
49
+ const logContext = `eventId=${action.eventId} groupId=${to} action=${action.action} target=${action.target}`;
50
+ console.info(`${LOG_PREFIX} 准备发送 ACTION_DISPATCH ${logContext}`);
23
51
  void target.client.sendEvent({
24
52
  groupId: to,
25
53
  replyToMsgId: target.replyToMsgId,
26
- event: "RUN_EVENT",
27
- data: {
28
- displayText: `动作「${action.action}」已完成:${action.target}`,
29
- summary: toWireAction(action),
30
- },
54
+ event: "ACTION_DISPATCH",
55
+ data: toWireAction(action),
56
+ }).then(() => {
57
+ console.info(`${LOG_PREFIX} ACTION_DISPATCH 已发送 ${logContext}`);
31
58
  }).catch((err) => {
32
59
  console.warn(`${LOG_PREFIX} 发送失败 eventId=${action.eventId} groupId=${to}: ${String(err)}`);
33
60
  });
@@ -1 +1 @@
1
- {"version":3,"file":"action-run-event.js","sourceRoot":"","sources":["../../src/action-run-event.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,UAAU,GAAG,kCAAkC,CAAC;AAEtD,mDAAmD;AACnD,MAAM,UAAU,YAAY,CAAC,MAA2B;IACpD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,CAAC;IAClD,OAAO,UAAU,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAA2B;IAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;IAC7B,IAAI,OAAO,KAAK,aAAa,IAAI,CAAC,EAAE,EAAE,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,+CAA+C,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3F,OAAO;IACX,CAAC;IAED,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,uCAAuC,MAAM,CAAC,OAAO,YAAY,EAAE,EAAE,CAAC,CAAC;QACjG,OAAO;IACX,CAAC;IAED,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QACzB,OAAO,EAAE,EAAE;QACX,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE;YACF,WAAW,EAAE,MAAM,MAAM,CAAC,MAAM,QAAQ,MAAM,CAAC,MAAM,EAAE;YACvD,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC;SAChC;KACJ,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QACtB,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,iBAAiB,MAAM,CAAC,OAAO,YAAY,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"action-run-event.js","sourceRoot":"","sources":["../../src/action-run-event.ts"],"names":[],"mappings":"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"}
@@ -21,18 +21,40 @@ function makeRecordingClient() {
21
21
  }
22
22
  beforeEach(() => resetPlanWsRegistryForTest());
23
23
  describe("sendActionRunEvent", () => {
24
- it("按 origin 路由为 RUN_EVENT,summary 保留 action 契约而剥离 origin", () => {
24
+ it("按 origin 路由为 ACTION_DISPATCH,透传精简 action 字段且剥离 origin", () => {
25
25
  const { client, calls } = makeRecordingClient();
26
26
  setPlanWsClient("g-1", client, "msg-1");
27
- const action = makeAction({ origin: { channel: "xg_cwork_im", to: "g-1", sessionKey: "secret" } });
27
+ const action = makeAction({
28
+ origin: { channel: "xg_cwork_im", to: "g-1", sessionKey: "secret" },
29
+ payload: {
30
+ data: {
31
+ data: {
32
+ target_kind: "ops",
33
+ trigger: "user_request",
34
+ source: "xg_cwork_im",
35
+ },
36
+ },
37
+ },
38
+ });
28
39
  sendActionRunEvent(action);
29
40
  assert.equal(calls.length, 1);
30
- assert.equal(calls[0].event, "RUN_EVENT");
41
+ assert.equal(calls[0].event, "ACTION_DISPATCH");
31
42
  assert.equal(calls[0].groupId, "g-1");
32
- const summary = calls[0].data.summary;
33
- assert.equal(summary.event, "action_dispatch");
34
- assert.equal(summary.eventId, action.eventId);
35
- assert.equal(summary.origin, undefined);
43
+ assert.equal(calls[0].replyToMsgId, "msg-1");
44
+ assert.deepEqual(calls[0].data, {
45
+ eventId: "evt-1",
46
+ action: "ui_refresh",
47
+ target: "order_detail",
48
+ status: "completed",
49
+ payload: {
50
+ data: {
51
+ target_kind: "ops",
52
+ trigger: "user_request",
53
+ source: "xg_cwork_im",
54
+ },
55
+ },
56
+ timestamp: "2026-08-13T00:00:00.000Z",
57
+ });
36
58
  assert.equal(action.origin?.sessionKey, "secret", "不 mutate 入参");
37
59
  });
38
60
  it("缺少当前通道 origin 时不发送", () => {
@@ -45,7 +67,17 @@ describe("sendActionRunEvent", () => {
45
67
  const action = makeAction({ origin: { channel: "xg_cwork_im", to: "g-1" } });
46
68
  const wire = toWireAction(action);
47
69
  assert.equal("origin" in wire, false);
70
+ assert.equal("event" in wire, false);
71
+ assert.equal("version" in wire, false);
48
72
  assert.deepEqual(action.origin, { channel: "xg_cwork_im", to: "g-1" });
49
73
  });
74
+ it("payload.data 含其他字段时不解包,避免丢失上游元数据", () => {
75
+ const wire = toWireAction(makeAction({
76
+ payload: { data: { data: { id: "ORD-1" }, source: "upstream" } },
77
+ }));
78
+ assert.deepEqual(wire.payload, {
79
+ data: { data: { id: "ORD-1" }, source: "upstream" },
80
+ });
81
+ });
50
82
  });
51
83
  //# sourceMappingURL=action-run-event.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-run-event.test.js","sourceRoot":"","sources":["../../src/action-run-event.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"action-run-event.test.js","sourceRoot":"","sources":["../../src/action-run-event.test.ts"],"names":[],"mappings":"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"}
@@ -76,24 +76,24 @@ describe("buildAgentContextPromptBlock nasVolumes", () => {
76
76
  background,
77
77
  },
78
78
  });
79
- assert.equal(result.block, `## 当前项目
80
-
81
- ### 本次会话文件目录
82
- 本次会话需要读取的文件位于以下已授权目录:
83
- - \`/workspace/touqian/2026/08/3090270000000000307/CP202205250005/deliverables\`(只读)
84
- - \`/workspace/touqian/2026/08/3090270000000000307/CP202205250005/sequences/0000\`(只读)
85
- - \`/workspace/touqian/2026/08/3090270000000000307/CP202205250005/sequences/0001/input\`(可读写)
86
- - 首选文件写入目录:\`/workspace/touqian/2026/08/3090270000000000307/CP202205250005/sequences/0001/input\`
87
-
88
- ### 目录用途
89
- - **项目产出**:项目相关文件优先保存到可写目录 \`/workspace/touqian/2026/08/3090270000000000307/CP202205250005/sequences/0001/input\` 或其子目录。
90
-
91
- ### 操作约束
92
- - 仅在上述已授权 NAS 目录下读取或处理项目文件;不要在 workspace 其他位置查找类似目录。
93
- - 对用户统一称为「本项目」,不要提及 OpenClaw workspace 等实现细节。
94
-
95
- ## 项目背景
96
-
79
+ assert.equal(result.block, `## 当前项目
80
+
81
+ ### 本次会话文件目录
82
+ 本次会话需要读取的文件位于以下已授权目录:
83
+ - \`/workspace/touqian/2026/08/3090270000000000307/CP202205250005/deliverables\`(只读)
84
+ - \`/workspace/touqian/2026/08/3090270000000000307/CP202205250005/sequences/0000\`(只读)
85
+ - \`/workspace/touqian/2026/08/3090270000000000307/CP202205250005/sequences/0001/input\`(可读写)
86
+ - 首选文件写入目录:\`/workspace/touqian/2026/08/3090270000000000307/CP202205250005/sequences/0001/input\`
87
+
88
+ ### 目录用途
89
+ - **项目产出**:项目相关文件优先保存到可写目录 \`/workspace/touqian/2026/08/3090270000000000307/CP202205250005/sequences/0001/input\` 或其子目录。
90
+
91
+ ### 操作约束
92
+ - 仅在上述已授权 NAS 目录下读取或处理项目文件;不要在 workspace 其他位置查找类似目录。
93
+ - 对用户统一称为「本项目」,不要提及 OpenClaw workspace 等实现细节。
94
+
95
+ ## 项目背景
96
+
97
97
  ${background}`);
98
98
  });
99
99
  });
@@ -2,30 +2,30 @@ import assert from "node:assert/strict";
2
2
  import { describe, it } from "node:test";
3
3
  import { normalizeDeliverComparableText, shouldOmitDuplicateFileCaption, shouldSuppressDuplicateTextDeliver, stripMediaDirectiveLines, stripModelUsageFooter, } from "./deliver-text.js";
4
4
  // 生产 incident 回归:侯桐 2026-07-10 终态三连发(空行/footer 微差)
5
- const HOUTONG_BODY_LOOSE = `确实是这个问题:昨天那版虽然用了内嵌 SVG,但你现在的文档预览器没有把 SVG 正常渲染出来,所以流程看不到。
6
-
7
- 我已经重新生成了一版**纯 Markdown 可读版**:
8
-
9
- - 不用 SVG
10
- - 不用 Mermaid
11
- - 不用图片
12
- - 全部用 Markdown 表格 + 文本流程图 + 状态表表达
13
-
14
- 这样在 IM 文件预览里也能直接看懂完整流程。
15
-
16
- 新文件:
17
-
5
+ const HOUTONG_BODY_LOOSE = `确实是这个问题:昨天那版虽然用了内嵌 SVG,但你现在的文档预览器没有把 SVG 正常渲染出来,所以流程看不到。
6
+
7
+ 我已经重新生成了一版**纯 Markdown 可读版**:
8
+
9
+ - 不用 SVG
10
+ - 不用 Mermaid
11
+ - 不用图片
12
+ - 全部用 Markdown 表格 + 文本流程图 + 状态表表达
13
+
14
+ 这样在 IM 文件预览里也能直接看懂完整流程。
15
+
16
+ 新文件:
17
+
18
18
  -----`;
19
- const HOUTONG_BODY_TIGHT = `确实是这个问题:昨天那版虽然用了内嵌 SVG,但你现在的文档预览器没有把 SVG 正常渲染出来,所以流程看不到。
20
- 我已经重新生成了一版**纯 Markdown 可读版**:
21
- - 不用 SVG
22
- - 不用 Mermaid
23
- - 不用图片
24
- - 全部用 Markdown 表格 + 文本流程图 + 状态表表达
25
- 这样在 IM 文件预览里也能直接看懂完整流程。
19
+ const HOUTONG_BODY_TIGHT = `确实是这个问题:昨天那版虽然用了内嵌 SVG,但你现在的文档预览器没有把 SVG 正常渲染出来,所以流程看不到。
20
+ 我已经重新生成了一版**纯 Markdown 可读版**:
21
+ - 不用 SVG
22
+ - 不用 Mermaid
23
+ - 不用图片
24
+ - 全部用 Markdown 表格 + 文本流程图 + 状态表表达
25
+ 这样在 IM 文件预览里也能直接看懂完整流程。
26
26
  新文件:`;
27
- const HOUTONG_BODY_WITH_FOOTER = `${HOUTONG_BODY_TIGHT}
28
-
27
+ const HOUTONG_BODY_WITH_FOOTER = `${HOUTONG_BODY_TIGHT}
28
+
29
29
  _🟡 ↑111k ↓164 · 63%ctx · openai/gpt-5.5_`;
30
30
  describe("stripMediaDirectiveLines", () => {
31
31
  it("removes MEDIA directive lines", () => {
@@ -1,5 +1,6 @@
1
1
  /**
2
- * 网关内:按 sessionKey 串行派发 + FIFO 排队 + /stop 清队列与租约。
2
+ * 历史会话派发调度层。
3
+ * 注意:插件内部已移除阻塞式 FIFO 队列与租约占用,任务排队、插话与中断统一交由 OpenClaw 原生管理。
3
4
  */
4
5
  import type { OpenClawConfig } from "openclaw/plugin-sdk";
5
6
  import type { Logger } from "./channel-log.js";
@@ -7,6 +8,7 @@ import type { ImStreamClient } from "./connection.js";
7
8
  import type { BotIdentity, WsMessageParams, XgImConfig } from "./types.js";
8
9
  import type { AutoRouteResult } from "./auto-model-router.js";
9
10
  import type { InboundTrigger } from "./inbound-terminal-state.js";
11
+ import type { NasVolume } from "./agent-context-types.js";
10
12
  export interface PendingDispatch {
11
13
  route: {
12
14
  sessionKey: string;
@@ -16,6 +18,8 @@ export interface PendingDispatch {
16
18
  params: WsMessageParams;
17
19
  currentIdentity: BotIdentity;
18
20
  agentWorkspaceDir?: string;
21
+ /** 本会话 NAS 挂载声明;同一 sessionKey 下必须保持不变。 */
22
+ nasVolumes?: NasVolume[];
19
23
  /** 本条消息单轮模型(OpenClaw replyOptions.modelOverride) */
20
24
  modelOverride?: string;
21
25
  /** 本条消息单轮推理等级(OpenClaw replyOptions.thinkingLevelOverride;用户显式 /think 时不设) */
@@ -24,7 +28,7 @@ export interface PendingDispatch {
24
28
  autoRouteMeta?: AutoRouteResult;
25
29
  /** 入站触发源 */
26
30
  inboundTrigger?: InboundTrigger;
27
- /** /stop:立即交给 OpenClaw;并作废当前会话占用、清空排队 */
31
+ /** /stop:立即交给 OpenClaw */
28
32
  skipSessionQueue?: boolean;
29
33
  }
30
34
  export declare function createRunWithSessionQueue(options: {
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-session-queue.d.ts","sourceRoot":"","sources":["../../src/gateway-session-queue.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,eAAe,EAAE,WAAW,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gDAAgD;IAChD,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,YAAY;IACZ,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IAC/C,cAAc,EAAE,MAAM,UAAU,CAAC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,GAAG,CAAC;IACR,WAAW,EAAE,MAAM,cAAc,CAAC;CACrC,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CA6GhG"}
1
+ {"version":3,"file":"gateway-session-queue.d.ts","sourceRoot":"","sources":["../../src/gateway-session-queue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,eAAe,CAAC;IACxB,eAAe,EAAE,WAAW,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gDAAgD;IAChD,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC,YAAY;IACZ,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,0BAA0B;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IAC/C,cAAc,EAAE,MAAM,UAAU,CAAC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,GAAG,CAAC;IACR,WAAW,EAAE,MAAM,cAAc,CAAC;CACrC,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CA2BhG"}
@@ -1,86 +1,29 @@
1
1
  /**
2
- * 网关内:按 sessionKey 串行派发 + FIFO 排队 + /stop 清队列与租约。
2
+ * 历史会话派发调度层。
3
+ * 注意:插件内部已移除阻塞式 FIFO 队列与租约占用,任务排队、插话与中断统一交由 OpenClaw 原生管理。
3
4
  */
4
5
  import { dispatchMentionedReply } from "./dispatch-mentioned-reply.js";
5
- import { sendTextMessage } from "./send-service.js";
6
6
  export function createRunWithSessionQueue(options) {
7
7
  const { configProvider, log, logPrefix, rt, cfgProvider } = options;
8
- const sessionBusyLease = new Map();
9
- const sessionQueues = new Map();
10
- const maxPendingMsgs = configProvider().maxPendingMessages ?? 5;
11
- const runWithSessionQueue = async (sessionKey, pending, streamClient) => {
12
- if (!pending.skipSessionQueue && sessionBusyLease.has(sessionKey)) {
13
- const queue = sessionQueues.get(sessionKey) ?? [];
14
- if (maxPendingMsgs === 0 || queue.length >= maxPendingMsgs) {
15
- const reason = maxPendingMsgs === 0
16
- ? "当前不支持任务排队,请等待处理完成后再发送。"
17
- : `当前任务队列已满(最多 ${maxPendingMsgs} 条),请等待处理完成后再重新发送。`;
18
- log.warn(`${logPrefix} [queue] Session ${sessionKey} busy & queue full/disabled (max=${maxPendingMsgs}), dropping`);
19
- sendTextMessage(configProvider(), pending.currentIdentity.token, pending.params.groupId, reason, [pending.params.userInfo?.id ?? ""], log).catch((notifyErr) => {
20
- log.error(`${logPrefix} [queue] Failed to send queue-full notice: ${String(notifyErr)}`);
21
- });
22
- return;
23
- }
24
- const queuePos = queue.length + 1;
25
- queue.push(pending);
26
- sessionQueues.set(sessionKey, queue);
27
- log.info(`${logPrefix} [queue] Session ${sessionKey} busy, queued message (pos=${queuePos})`);
28
- sendTextMessage(configProvider(), pending.currentIdentity.token, pending.params.groupId, `收到,当前正在处理其他任务,您的消息已排队(队列第 ${queuePos} 位),处理完成后将自动回复。`, [pending.params.userInfo?.id ?? ""], log).catch((notifyErr) => {
29
- log.warn(`${logPrefix} [queue] Failed to send queue notification: ${String(notifyErr)}`);
30
- });
31
- return;
32
- }
33
- if (pending.skipSessionQueue) {
34
- const hadLease = sessionBusyLease.has(sessionKey);
35
- if (hadLease) {
36
- sessionBusyLease.delete(sessionKey);
37
- const dropped = sessionQueues.get(sessionKey)?.length ?? 0;
38
- sessionQueues.delete(sessionKey);
39
- log.info(`${logPrefix} [queue] /stop: invalidated busy lease, cleared fifo (droppedQueued=${dropped})`);
40
- }
41
- }
42
- let myLease;
43
- if (!pending.skipSessionQueue) {
44
- myLease = Symbol("xg_cwork_im-session-busy");
45
- sessionBusyLease.set(sessionKey, myLease);
46
- }
47
- try {
48
- await dispatchMentionedReply({
49
- rt,
50
- cfg: cfgProvider(),
51
- config: configProvider(),
52
- log,
53
- logPrefix,
54
- route: pending.route,
55
- inboundCtx: pending.inboundCtx,
56
- params: pending.params,
57
- currentIdentity: pending.currentIdentity,
58
- streamClient,
59
- agentWorkspaceDir: pending.agentWorkspaceDir,
60
- modelOverride: pending.modelOverride,
61
- thinkingLevelOverride: pending.thinkingLevelOverride,
62
- autoRouteMeta: pending.autoRouteMeta,
63
- inboundTrigger: pending.inboundTrigger,
64
- });
65
- }
66
- finally {
67
- if (!pending.skipSessionQueue && myLease !== undefined) {
68
- if (sessionBusyLease.get(sessionKey) === myLease) {
69
- sessionBusyLease.delete(sessionKey);
70
- const queue = sessionQueues.get(sessionKey);
71
- if (queue && queue.length > 0) {
72
- const next = queue.shift();
73
- if (queue.length === 0)
74
- sessionQueues.delete(sessionKey);
75
- log.info(`${logPrefix} [queue] Dispatching next queued message for session ${sessionKey} (remaining=${queue.length})`);
76
- runWithSessionQueue(sessionKey, next, streamClient).catch((err) => {
77
- log.error(`${logPrefix} [queue] Error processing queued dispatch: ${String(err)}`);
78
- });
79
- }
80
- }
81
- }
82
- }
8
+ return async (_sessionKey, pending, streamClient) => {
9
+ await dispatchMentionedReply({
10
+ rt,
11
+ cfg: cfgProvider(),
12
+ config: configProvider(),
13
+ log,
14
+ logPrefix,
15
+ route: pending.route,
16
+ inboundCtx: pending.inboundCtx,
17
+ params: pending.params,
18
+ currentIdentity: pending.currentIdentity,
19
+ streamClient,
20
+ agentWorkspaceDir: pending.agentWorkspaceDir,
21
+ nasVolumes: pending.nasVolumes,
22
+ modelOverride: pending.modelOverride,
23
+ thinkingLevelOverride: pending.thinkingLevelOverride,
24
+ autoRouteMeta: pending.autoRouteMeta,
25
+ inboundTrigger: pending.inboundTrigger,
26
+ });
83
27
  };
84
- return runWithSessionQueue;
85
28
  }
86
29
  //# sourceMappingURL=gateway-session-queue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gateway-session-queue.js","sourceRoot":"","sources":["../../src/gateway-session-queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gateway-session-queue.js","sourceRoot":"","sources":["../../src/gateway-session-queue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AA0BvE,MAAM,UAAU,yBAAyB,CAAC,OAMzC;IACG,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAEpE,OAAO,KAAK,EACR,WAAmB,EACnB,OAAwB,EACxB,YAA4B,EACf,EAAE;QACf,MAAM,sBAAsB,CAAC;YACzB,EAAE;YACF,GAAG,EAAE,WAAW,EAAE;YAClB,MAAM,EAAE,cAAc,EAAE;YACxB,GAAG;YACH,SAAS;YACT,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,YAAY;YACZ,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;YAC5C,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;YACpD,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,cAAc,EAAE,OAAO,CAAC,cAAc;SACzC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Logger } from "./channel-log.js";
2
+ import { type ReplyDeliverPayload } from "./send-service.js";
3
+ import type { WsMessageParams, XgImConfig } from "./types.js";
4
+ export type PatchSummaryPayload = {
5
+ added?: string[];
6
+ modified?: string[];
7
+ deleted?: string[];
8
+ };
9
+ type FlushArgs = {
10
+ config: XgImConfig;
11
+ token: string;
12
+ params: WsMessageParams;
13
+ };
14
+ export declare function createModifiedFilePushTracker(options: {
15
+ agentWorkspaceDir?: string;
16
+ log: Logger;
17
+ logPrefix: string;
18
+ }): {
19
+ recordPatchSummary: (payload: PatchSummaryPayload) => void;
20
+ markDelivered: (payload: ReplyDeliverPayload) => void;
21
+ flush: (args: FlushArgs) => Promise<void>;
22
+ };
23
+ export {};
24
+ //# sourceMappingURL=modified-file-push-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modified-file-push-tracker.d.ts","sourceRoot":"","sources":["../../src/modified-file-push-tracker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAyB,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE9D,MAAM,MAAM,mBAAmB,GAAG;IAC9B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEF,KAAK,SAAS,GAAG;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,CAAC;CAC3B,CAAC;AAwFF,wBAAgB,6BAA6B,CAAC,OAAO,EAAE;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACrB,GAAG;IACA,kBAAkB,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC3D,aAAa,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACtD,KAAK,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C,CAgDA"}
@@ -0,0 +1,125 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { buildTargetReplyMeta } from "./inbound-display.js";
5
+ import { resolveLocalFsPath, resolveWorkspaceCandidatePaths } from "./resource-file.js";
6
+ import { sendReplyDeliverBlock } from "./send-service.js";
7
+ function isUrlLike(value) {
8
+ return /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(value.trim());
9
+ }
10
+ function normalizePushPath(filePath, workspaceDir) {
11
+ const clean = filePath.trim();
12
+ if (clean.startsWith("/workspace/") || clean === "/workspace") {
13
+ return clean;
14
+ }
15
+ if (isUrlLike(clean)) {
16
+ return clean;
17
+ }
18
+ const wsDir = workspaceDir?.trim();
19
+ if (wsDir) {
20
+ const wsResolved = path.resolve(wsDir);
21
+ const fileResolved = path.isAbsolute(clean) ? path.resolve(clean) : path.resolve(wsResolved, clean);
22
+ const relToWorkspace = path.relative(wsResolved, fileResolved);
23
+ if (!relToWorkspace.startsWith("..") && !path.isAbsolute(relToWorkspace)) {
24
+ return relToWorkspace ? `/workspace/${relToWorkspace.replace(/\\/g, "/")}` : "/workspace";
25
+ }
26
+ }
27
+ return clean;
28
+ }
29
+ function pushPathCandidates(filePath, workspaceDir) {
30
+ const clean = filePath.trim();
31
+ if (!clean)
32
+ return [];
33
+ if (clean.startsWith("/workspace/") || clean === "/workspace") {
34
+ try {
35
+ return resolveWorkspaceCandidatePaths(clean, workspaceDir);
36
+ }
37
+ catch {
38
+ return [];
39
+ }
40
+ }
41
+ if (clean.startsWith("file://")) {
42
+ try {
43
+ return [fileURLToPath(clean)];
44
+ }
45
+ catch {
46
+ return [];
47
+ }
48
+ }
49
+ const local = resolveLocalFsPath(clean);
50
+ if (local)
51
+ return [local.fsPath];
52
+ const wsDir = workspaceDir?.trim();
53
+ if (wsDir && !path.isAbsolute(clean)) {
54
+ return [path.resolve(wsDir, clean)];
55
+ }
56
+ return [];
57
+ }
58
+ async function isExistingRegularPushFile(filePath, workspaceDir) {
59
+ for (const candidate of pushPathCandidates(filePath, workspaceDir)) {
60
+ try {
61
+ const stat = await fs.stat(candidate);
62
+ if (stat.isFile())
63
+ return true;
64
+ }
65
+ catch {
66
+ /* try next candidate */
67
+ }
68
+ }
69
+ return false;
70
+ }
71
+ async function filterExistingPushFiles(files, workspaceDir, log, logPrefix) {
72
+ const out = [];
73
+ for (const file of files) {
74
+ if (await isExistingRegularPushFile(file, workspaceDir)) {
75
+ out.push(file);
76
+ }
77
+ else {
78
+ log.warn(`${logPrefix} [sync-push] Skip non-existing or non-file path: ${JSON.stringify(file)}`);
79
+ }
80
+ }
81
+ return out;
82
+ }
83
+ function payloadMediaUrls(payload) {
84
+ return [
85
+ ...(payload.mediaUrl ? [payload.mediaUrl] : []),
86
+ ...(payload.mediaUrls ?? []),
87
+ ].filter((u) => typeof u === "string" && u.trim());
88
+ }
89
+ export function createModifiedFilePushTracker(options) {
90
+ const { agentWorkspaceDir, log, logPrefix } = options;
91
+ const modifiedFiles = new Set();
92
+ return {
93
+ recordPatchSummary(payload) {
94
+ payload.added?.forEach((f) => modifiedFiles.add(normalizePushPath(f, agentWorkspaceDir)));
95
+ payload.modified?.forEach((f) => modifiedFiles.add(normalizePushPath(f, agentWorkspaceDir)));
96
+ },
97
+ markDelivered(payload) {
98
+ for (const url of payloadMediaUrls(payload)) {
99
+ modifiedFiles.delete(normalizePushPath(url, agentWorkspaceDir));
100
+ }
101
+ },
102
+ async flush(args) {
103
+ if (modifiedFiles.size === 0)
104
+ return;
105
+ const mediaUrls = await filterExistingPushFiles(modifiedFiles, agentWorkspaceDir, log, logPrefix);
106
+ if (mediaUrls.length === 0) {
107
+ log.info(`${logPrefix} [sync-push] No existing modified files to push`);
108
+ return;
109
+ }
110
+ log.info(`${logPrefix} [sync-push] 自动推送变动文件至客户端: ${JSON.stringify(mediaUrls)}`);
111
+ try {
112
+ const reply = buildTargetReplyMeta(args.params);
113
+ await sendReplyDeliverBlock(args.config, args.token, args.params.groupId, {
114
+ text: "已自动将本次修改的文件同步到工作区,您可以在右侧面板进行审阅:",
115
+ isThinking: false,
116
+ mediaUrls,
117
+ }, [reply.targetUserId], log, undefined, reply, agentWorkspaceDir);
118
+ }
119
+ catch (err) {
120
+ log.error(`${logPrefix} [sync-push] 自动推送文件附件失败: ${String(err)}`);
121
+ }
122
+ },
123
+ };
124
+ }
125
+ //# sourceMappingURL=modified-file-push-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modified-file-push-tracker.js","sourceRoot":"","sources":["../../src/modified-file-push-tracker.ts"],"names":[],"mappings":"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"}