@tencent-weixin/openclaw-weixin 2.4.2 → 2.4.4

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 (53) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/CHANGELOG.zh_CN.md +45 -0
  3. package/dist/src/api/api.js +84 -8
  4. package/dist/src/api/api.js.map +1 -1
  5. package/dist/src/api/types.js +2 -0
  6. package/dist/src/api/types.js.map +1 -1
  7. package/dist/src/auth/login-qr.js +1 -0
  8. package/dist/src/auth/login-qr.js.map +1 -1
  9. package/dist/src/channel.js +15 -1
  10. package/dist/src/channel.js.map +1 -1
  11. package/dist/src/config/config-schema.js +1 -0
  12. package/dist/src/config/config-schema.js.map +1 -1
  13. package/dist/src/config/reply-progress.js +5 -0
  14. package/dist/src/config/reply-progress.js.map +1 -0
  15. package/dist/src/media/voice-outbound.js +98 -1
  16. package/dist/src/media/voice-outbound.js.map +1 -1
  17. package/dist/src/messaging/batch-session.js +271 -0
  18. package/dist/src/messaging/batch-session.js.map +1 -0
  19. package/dist/src/messaging/error-notice.js +1 -0
  20. package/dist/src/messaging/error-notice.js.map +1 -1
  21. package/dist/src/messaging/outbound-hooks.js +2 -0
  22. package/dist/src/messaging/outbound-hooks.js.map +1 -1
  23. package/dist/src/messaging/process-message.js +32 -7
  24. package/dist/src/messaging/process-message.js.map +1 -1
  25. package/dist/src/messaging/reply-progress-sender.js +93 -0
  26. package/dist/src/messaging/reply-progress-sender.js.map +1 -0
  27. package/dist/src/messaging/run-context.js +9 -0
  28. package/dist/src/messaging/run-context.js.map +1 -0
  29. package/dist/src/messaging/run-report-session.js +123 -0
  30. package/dist/src/messaging/run-report-session.js.map +1 -0
  31. package/dist/src/messaging/send.js +40 -2
  32. package/dist/src/messaging/send.js.map +1 -1
  33. package/dist/src/monitor/monitor.js +3 -0
  34. package/dist/src/monitor/monitor.js.map +1 -1
  35. package/dist/src/streaming/batch-session.js +271 -0
  36. package/dist/src/streaming/batch-session.js.map +1 -0
  37. package/dist/src/streaming/stream-piece.js +54 -0
  38. package/dist/src/streaming/stream-piece.js.map +1 -0
  39. package/openclaw.plugin.json +1 -1
  40. package/package.json +1 -1
  41. package/src/api/api.ts +92 -8
  42. package/src/api/types.ts +16 -0
  43. package/src/auth/login-qr.ts +8 -0
  44. package/src/channel.ts +16 -1
  45. package/src/config/config-schema.ts +1 -0
  46. package/src/config/reply-progress.ts +10 -0
  47. package/src/messaging/error-notice.ts +2 -0
  48. package/src/messaging/outbound-hooks.ts +4 -0
  49. package/src/messaging/process-message.ts +32 -7
  50. package/src/messaging/reply-progress-sender.ts +122 -0
  51. package/src/messaging/send-media.ts +1 -1
  52. package/src/messaging/send.ts +60 -7
  53. package/src/monitor/monitor.ts +3 -0
@@ -1,6 +1,10 @@
1
+ import { execFile } from "node:child_process";
1
2
  import fs from "node:fs/promises";
3
+ import os from "node:os";
2
4
  import path from "node:path";
5
+ import { promisify } from "node:util";
3
6
  import { logger } from "../util/logger.js";
7
+ const execFileAsync = promisify(execFile);
4
8
  const OGG_CAPTURE = Buffer.from("OggS");
5
9
  const OPUS_HEAD_MAGIC = Buffer.from("OpusHead");
6
10
  const GP_UNKNOWN = 0xffffffffffffffffn;
@@ -13,6 +17,18 @@ export const VOICE_ENCODE_OGG_SPEEX = 8;
13
17
  * `.ogg` is handled separately: only when the file is Ogg Opus (see {@link isWeixinVoiceOutboundPath}).
14
18
  */
15
19
  const VOICE_EXTENSIONS = new Set([".opus", ".silk", ".slk"]);
20
+ const AUDIO_AS_VOICE_EXTENSIONS = new Set([
21
+ ".aac",
22
+ ".amr",
23
+ ".m4a",
24
+ ".mp3",
25
+ ".oga",
26
+ ".ogg",
27
+ ".opus",
28
+ ".silk",
29
+ ".slk",
30
+ ".wav",
31
+ ]);
16
32
  function readUint32LE(buf, o) {
17
33
  return buf.readUInt32LE(o);
18
34
  }
@@ -122,6 +138,77 @@ async function silkPlaytimeMsWithOptionalWasm(buf) {
122
138
  return null;
123
139
  }
124
140
  }
141
+ async function ffprobePlaytimeMs(filePath) {
142
+ try {
143
+ const { stdout } = await execFileAsync("ffprobe", [
144
+ "-v",
145
+ "error",
146
+ "-show_entries",
147
+ "format=duration",
148
+ "-of",
149
+ "default=noprint_wrappers=1:nokey=1",
150
+ filePath,
151
+ ]);
152
+ const seconds = Number.parseFloat(stdout.trim());
153
+ if (!Number.isFinite(seconds) || seconds <= 0)
154
+ return null;
155
+ return Math.round(seconds * 1000);
156
+ }
157
+ catch (err) {
158
+ logger.debug(`voice-outbound: ffprobe duration unavailable err=${String(err)}`);
159
+ return null;
160
+ }
161
+ }
162
+ const WEIXIN_VOICE_TRANSCODE_SAMPLE_RATE = 48_000;
163
+ const WEIXIN_VOICE_TRANSCODE_BITRATE = "64k";
164
+ const WEIXIN_VOICE_TRANSCODE_MAX_SECS = 60;
165
+ /**
166
+ * Transcode a generic audio file to Ogg/Opus for Weixin voice messages using ffmpeg.
167
+ * Returns the transcoded buffer on success, or null if ffmpeg is unavailable or fails.
168
+ * The caller should check the returned buffer with resolveWeixinOutboundVoiceMeta
169
+ * before uploading; if that also fails, degrade to a file attachment.
170
+ */
171
+ export async function transcodeToWeixinVoiceOpus(filePath) {
172
+ const tmpPath = path.join(os.tmpdir(), `weixin-voice-${Date.now()}-${Math.random().toString(36).slice(2)}.ogg`);
173
+ try {
174
+ await execFileAsync("ffmpeg", [
175
+ "-hide_banner",
176
+ "-loglevel",
177
+ "error",
178
+ "-y",
179
+ "-i",
180
+ filePath,
181
+ "-vn",
182
+ "-sn",
183
+ "-dn",
184
+ "-t",
185
+ String(WEIXIN_VOICE_TRANSCODE_MAX_SECS),
186
+ "-ar",
187
+ String(WEIXIN_VOICE_TRANSCODE_SAMPLE_RATE),
188
+ "-ac",
189
+ "1",
190
+ "-c:a",
191
+ "libopus",
192
+ "-b:a",
193
+ WEIXIN_VOICE_TRANSCODE_BITRATE,
194
+ "-f",
195
+ "ogg",
196
+ tmpPath,
197
+ ]);
198
+ return await fs.readFile(tmpPath);
199
+ }
200
+ catch (err) {
201
+ logger.warn(`voice-outbound: transcodeToWeixinVoiceOpus failed filePath=${filePath} err=${String(err)}`);
202
+ return null;
203
+ }
204
+ finally {
205
+ await fs.unlink(tmpPath).catch(() => { });
206
+ }
207
+ }
208
+ export function isWeixinAudioAsVoiceOutboundPath(filePath) {
209
+ const ext = path.extname(filePath).toLowerCase();
210
+ return AUDIO_AS_VOICE_EXTENSIONS.has(ext);
211
+ }
125
212
  export async function isWeixinVoiceOutboundPath(filePath) {
126
213
  const ext = path.extname(filePath).toLowerCase();
127
214
  if (VOICE_EXTENSIONS.has(ext))
@@ -144,7 +231,7 @@ export async function isWeixinVoiceOutboundPath(filePath) {
144
231
  * Compute voice playtime (ms) and encoding hints for Weixin VOICE item.
145
232
  * Returns null if duration cannot be determined (caller should send as file).
146
233
  */
147
- export async function resolveWeixinOutboundVoiceMeta(filePath) {
234
+ export async function resolveWeixinOutboundVoiceMeta(filePath, opts = {}) {
148
235
  const ext = path.extname(filePath).toLowerCase();
149
236
  const buf = await fs.readFile(filePath);
150
237
  if (ext === ".opus" || ext === ".ogg") {
@@ -171,6 +258,16 @@ export async function resolveWeixinOutboundVoiceMeta(filePath) {
171
258
  sample_rate: 24_000,
172
259
  };
173
260
  }
261
+ if (opts.allowGenericAudio && AUDIO_AS_VOICE_EXTENSIONS.has(ext)) {
262
+ const ms = await ffprobePlaytimeMs(filePath);
263
+ if (ms == null || ms <= 0) {
264
+ logger.warn(`voice-outbound: cannot resolve playtime for audioAsVoice ${ext} file via ffprobe filePath=${filePath} size=${buf.length}`);
265
+ return null;
266
+ }
267
+ return {
268
+ playtimeMs: ms,
269
+ };
270
+ }
174
271
  logger.warn(`voice-outbound: unsupported voice extension '${ext}' for filePath=${filePath}`);
175
272
  return null;
176
273
  }
@@ -1 +1 @@
1
- {"version":3,"file":"voice-outbound.js","sourceRoot":"","sources":["../../../src/media/voice-outbound.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"voice-outbound.js","sourceRoot":"","sources":["../../../src/media/voice-outbound.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,271 @@
1
+ import crypto from "node:crypto";
2
+ import { onAgentEvent, } from "openclaw/plugin-sdk/agent-harness-runtime";
3
+ import { MessageItemType } from "../api/types.js";
4
+ import { logger } from "../util/logger.js";
5
+ /** Max chars for a tool result summary before truncation. */
6
+ const TOOL_OUTPUT_CHAR_LIMIT = 120_000;
7
+ /** Default size budget for a single batch sendMessage (bytes, JSON estimate). */
8
+ export const BATCH_SIZE_LIMIT_BYTES = 200 * 1024;
9
+ function estimateSizeBytes(items) {
10
+ try {
11
+ return Buffer.byteLength(JSON.stringify(items), "utf8");
12
+ }
13
+ catch {
14
+ return 0;
15
+ }
16
+ }
17
+ function truncateText(text, limit) {
18
+ if (text.length <= limit)
19
+ return text;
20
+ return `${text.slice(0, limit)}\n\n… truncated (${text.length} chars, showing first ${limit}).`;
21
+ }
22
+ function formatToolOutput(value) {
23
+ if (value === null || value === undefined)
24
+ return "";
25
+ if (typeof value === "number" || typeof value === "boolean")
26
+ return String(value);
27
+ let text;
28
+ if (typeof value === "string") {
29
+ text = value;
30
+ }
31
+ else {
32
+ if (typeof value === "object") {
33
+ const rec = value;
34
+ if (typeof rec.text === "string") {
35
+ text = rec.text;
36
+ }
37
+ else if (Array.isArray(rec.content)) {
38
+ const parts = rec.content
39
+ .map((item) => {
40
+ if (item && typeof item === "object") {
41
+ const e = item;
42
+ if (e.type === "text" && typeof e.text === "string")
43
+ return e.text;
44
+ }
45
+ return null;
46
+ })
47
+ .filter((p) => p !== null);
48
+ text = parts.length > 0 ? parts.join("\n") : JSON.stringify(value, null, 2);
49
+ }
50
+ else {
51
+ text = JSON.stringify(value, null, 2);
52
+ }
53
+ }
54
+ else {
55
+ text = String(value);
56
+ }
57
+ }
58
+ return truncateText(text, TOOL_OUTPUT_CHAR_LIMIT);
59
+ }
60
+ function tryStringifyArgs(args) {
61
+ if (args === undefined)
62
+ return undefined;
63
+ try {
64
+ return JSON.stringify(args);
65
+ }
66
+ catch {
67
+ return undefined;
68
+ }
69
+ }
70
+ /**
71
+ * BatchSession — accumulates thinking, tool calls, and text payloads during
72
+ * an AI turn and sends them all in a single sendMessage at finalize time.
73
+ *
74
+ * Drop priority when item_list > BATCH_SIZE_LIMIT_BYTES:
75
+ * 1. Drop ThinkingItem (largest, optional for client UX)
76
+ * 2. Drop all ToolCallStart/Result items
77
+ * 3. Always keep TextItem(s) — the actual reply
78
+ *
79
+ * Usage:
80
+ * const session = new BatchSession({ onSendBatch });
81
+ * // spread replyCallbacks + runId into replyOptions
82
+ * replyOptions = { ...replyOptions, runId: session.runId, ...session.replyCallbacks }
83
+ * // in deliver(): session.addTextPayload(text)
84
+ * // after dispatchReplyFromConfig: await session.finalize()
85
+ * // on error: await session.abort()
86
+ */
87
+ export class BatchSession {
88
+ /** Run id this session listens for on the global agent event bus. */
89
+ runId;
90
+ thinkingText = null;
91
+ toolStarts = [];
92
+ toolResults = [];
93
+ textPayloads = [];
94
+ done = false;
95
+ unsubscribeAgentEvent;
96
+ onSendBatch;
97
+ constructor(deps) {
98
+ this.runId = deps.runId ?? crypto.randomUUID();
99
+ this.onSendBatch = deps.onSendBatch;
100
+ this.unsubscribeAgentEvent = onAgentEvent((evt) => this.handleRawAgentEvent(evt));
101
+ logger.debug(`BatchSession.ctor: runId=${this.runId} agentEventListener=registered`);
102
+ }
103
+ /**
104
+ * Spread into replyOptions so the SDK delivers thinking/tool events here.
105
+ * Also set `replyOptions.runId = session.runId` so agent events carry the
106
+ * matching runId.
107
+ */
108
+ get replyCallbacks() {
109
+ return {
110
+ onReasoningStream: (payload) => this.handleReasoningStream(payload),
111
+ onReasoningEnd: () => { },
112
+ };
113
+ }
114
+ /**
115
+ * Store a text payload from deliver(). Each call appends one TextItem to the
116
+ * final item_list in call order. Skips empty strings.
117
+ */
118
+ addTextPayload(text) {
119
+ if (!text.trim())
120
+ return;
121
+ this.textPayloads.push(text);
122
+ logger.debug(`BatchSession.addTextPayload: len=${text.length} total=${this.textPayloads.length}`);
123
+ }
124
+ // ---- private callbacks --------------------------------------------------
125
+ handleReasoningStream(payload) {
126
+ if (this.done)
127
+ return;
128
+ const text = typeof payload.text === "string" ? payload.text : "";
129
+ if (text) {
130
+ this.thinkingText = text;
131
+ }
132
+ }
133
+ handleRawAgentEvent(evt) {
134
+ if (this.done)
135
+ return;
136
+ if (evt.runId !== this.runId)
137
+ return;
138
+ if (evt.stream !== "tool")
139
+ return;
140
+ const data = evt.data;
141
+ if (typeof data.toolCallId !== "string" || !data.toolCallId)
142
+ return;
143
+ if (data.phase === "start") {
144
+ this.toolStarts.push({
145
+ tool_call_id: data.toolCallId,
146
+ tool_name: typeof data.name === "string" && data.name ? data.name : "tool",
147
+ args_json: tryStringifyArgs(data.args),
148
+ });
149
+ logger.debug(`BatchSession: tool_call_start tool=${data.name ?? "?"} id=${data.toolCallId}` +
150
+ ` totalStarts=${this.toolStarts.length}`);
151
+ return;
152
+ }
153
+ if (data.phase === "result") {
154
+ this.toolResults.push({
155
+ tool_call_id: data.toolCallId,
156
+ summary: formatToolOutput(data.result),
157
+ });
158
+ logger.debug(`BatchSession: tool_call_result id=${data.toolCallId}` +
159
+ ` totalResults=${this.toolResults.length}`);
160
+ }
161
+ }
162
+ // ---- item_list assembly -------------------------------------------------
163
+ /**
164
+ * Build the item_list applying the 200 KB budget.
165
+ *
166
+ * Order: [ThinkingItem?, ToolCallStart+Result pairs..., TextItem(s)...]
167
+ *
168
+ * If full list > maxBytes:
169
+ * - drop ThinkingItem and retry
170
+ * - if still > maxBytes, drop all tool items too
171
+ * - TextItem(s) are always kept
172
+ */
173
+ buildItemList(maxBytes = BATCH_SIZE_LIMIT_BYTES) {
174
+ const textItems = this.textPayloads.map((t) => ({
175
+ type: MessageItemType.TEXT,
176
+ text_item: { text: t },
177
+ }));
178
+ const toolItems = [];
179
+ for (const start of this.toolStarts) {
180
+ toolItems.push({
181
+ type: MessageItemType.TOOL_CALL_START,
182
+ tool_call_start_item: {
183
+ tool_name: start.tool_name,
184
+ tool_call_id: start.tool_call_id,
185
+ args_json: start.args_json,
186
+ },
187
+ });
188
+ const result = this.toolResults.find((r) => r.tool_call_id === start.tool_call_id);
189
+ if (result) {
190
+ toolItems.push({
191
+ type: MessageItemType.TOOL_CALL_RESULT,
192
+ tool_call_result_item: {
193
+ tool_call_id: result.tool_call_id,
194
+ summary: result.summary,
195
+ },
196
+ });
197
+ }
198
+ }
199
+ const thinkingItem = this.thinkingText
200
+ ? { type: MessageItemType.THINKING, thinking_item: { text: this.thinkingText } }
201
+ : null;
202
+ // Attempt 1: full list
203
+ const full = [
204
+ ...(thinkingItem ? [thinkingItem] : []),
205
+ ...toolItems,
206
+ ...textItems,
207
+ ];
208
+ if (full.length === 0)
209
+ return [];
210
+ const fullSize = estimateSizeBytes(full);
211
+ logger.debug(`BatchSession.buildItemList: items=${full.length} size=${fullSize}B` +
212
+ ` thinking=${thinkingItem !== null} tools=${this.toolStarts.length}` +
213
+ ` texts=${this.textPayloads.length}`);
214
+ if (fullSize <= maxBytes)
215
+ return full;
216
+ // Attempt 2: drop thinking
217
+ logger.warn(`BatchSession.buildItemList: size=${fullSize}B > limit=${maxBytes}B,` +
218
+ ` dropping ThinkingItem (len=${this.thinkingText?.length ?? 0} chars).` +
219
+ ` Full thinking content is in the log: ${logger.getLogFilePath()}`);
220
+ const withoutThinking = [...toolItems, ...textItems];
221
+ if (withoutThinking.length === 0)
222
+ return [];
223
+ const noThinkingSize = estimateSizeBytes(withoutThinking);
224
+ if (noThinkingSize <= maxBytes)
225
+ return withoutThinking;
226
+ // Attempt 3: drop tool items too
227
+ logger.warn(`BatchSession.buildItemList: size=${noThinkingSize}B still > limit=${maxBytes}B,` +
228
+ ` dropping ${this.toolStarts.length} tool call(s) (${toolItems.length} items).` +
229
+ ` Full tool content is in the log: ${logger.getLogFilePath()}`);
230
+ return textItems.length > 0 ? textItems : [];
231
+ }
232
+ // ---- lifecycle ----------------------------------------------------------
233
+ /**
234
+ * Assemble item_list, call onSendBatch once, then clean up. Idempotent.
235
+ */
236
+ async finalize() {
237
+ if (this.done)
238
+ return;
239
+ this.done = true;
240
+ this.cleanup();
241
+ const items = this.buildItemList();
242
+ if (items.length === 0) {
243
+ logger.debug("BatchSession.finalize: item_list empty, skipping send");
244
+ return;
245
+ }
246
+ logger.debug(`BatchSession.finalize: sending ${items.length} item(s)` +
247
+ ` thinking=${this.thinkingText !== null}` +
248
+ ` toolStarts=${this.toolStarts.length}` +
249
+ ` texts=${this.textPayloads.length}`);
250
+ await this.onSendBatch(items);
251
+ }
252
+ /**
253
+ * Discard all buffered data, release event listener. Does not send. Idempotent.
254
+ */
255
+ async abort() {
256
+ if (this.done)
257
+ return;
258
+ this.done = true;
259
+ this.cleanup();
260
+ logger.debug("BatchSession.abort: discarded without send");
261
+ }
262
+ cleanup() {
263
+ try {
264
+ this.unsubscribeAgentEvent();
265
+ }
266
+ catch (err) {
267
+ logger.warn(`BatchSession.cleanup: unsubscribe failed err=${String(err)}`);
268
+ }
269
+ }
270
+ }
271
+ //# sourceMappingURL=batch-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-session.js","sourceRoot":"","sources":["../../../src/messaging/batch-session.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ export async function sendWeixinErrorNotice(params) {
14
14
  baseUrl: params.baseUrl,
15
15
  token: params.token,
16
16
  contextToken: params.contextToken,
17
+ ...(params.runId ? { runId: params.runId } : {}),
17
18
  } });
18
19
  logger.debug(`sendWeixinErrorNotice: sent to=${params.to}`);
19
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"error-notice.js","sourceRoot":"","sources":["../../../src/messaging/error-notice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAO3C;IACC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,iDAAiD,MAAM,CAAC,EAAE,2BAA2B,CAAC,CAAC;IACrG,CAAC;IACD,IAAI,CAAC;QACH,MAAM,iBAAiB,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE;gBACnE,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,YAAY,EAAE,MAAM,CAAC,YAAY;aAClC,EAAC,CAAC,CAAC;QACJ,MAAM,CAAC,KAAK,CAAC,kCAAkC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,MAAM,CAAC,4CAA4C,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"error-notice.js","sourceRoot":"","sources":["../../../src/messaging/error-notice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,MAQ3C;IACC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,iDAAiD,MAAM,CAAC,EAAE,2BAA2B,CAAC,CAAC;IACrG,CAAC;IACD,IAAI,CAAC;QACH,MAAM,iBAAiB,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE;gBACnE,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,YAAY,EAAE,MAAM,CAAC,YAAY;gBACjC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjD,EAAC,CAAC,CAAC;QACJ,MAAM,CAAC,KAAK,CAAC,kCAAkC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,MAAM,CAAC,4CAA4C,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzF,CAAC;AACH,CAAC"}
@@ -19,6 +19,7 @@ export async function applyWeixinMessageSendingHook(params) {
19
19
  metadata: {
20
20
  channel: CHANNEL_ID,
21
21
  accountId: params.accountId,
22
+ runId: params.runId,
22
23
  ...(params.mediaUrl ? { mediaUrls: [params.mediaUrl] } : {}),
23
24
  },
24
25
  }, { channelId: CHANNEL_ID, accountId: params.accountId });
@@ -50,6 +51,7 @@ export function emitWeixinMessageSent(params) {
50
51
  channelId: CHANNEL_ID,
51
52
  accountId: params.accountId,
52
53
  conversationId: params.to,
54
+ runId: params.runId,
53
55
  });
54
56
  fireAndForgetHook(Promise.resolve(hookRunner.runMessageSent(toPluginMessageSentEvent(canonical), toPluginMessageContext(canonical))), "weixin: message_sent plugin hook failed");
55
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"outbound-hooks.js","sourceRoot":"","sources":["../../../src/messaging/outbound-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,oCAAoC,EACpC,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEzE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAErC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,MAKnD;IACC,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;IACzC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IACjD,CAAC;IACD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,iBAAiB,CACnD;YACE,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,OAAO,EAAE,MAAM,CAAC,IAAI;YACpB,QAAQ,EAAE;gBACR,OAAO,EAAE,UAAU;gBACnB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC7D;SACF,EACD,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CACvD,CAAC;QACF,IAAI,UAAU,EAAE,MAAM,EAAE,CAAC;YACvB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAChD,CAAC;QACD,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,IAAI,EAAE,UAAU,EAAE,OAAO,IAAI,MAAM,CAAC,IAAI;SACzC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,qDAAqD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChF,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IACjD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAMrC;IACC,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;IACzC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO;IAClD,MAAM,SAAS,GAAG,oCAAoC,CAAC;QACrD,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,UAAU;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,cAAc,EAAE,MAAM,CAAC,EAAE;KAC1B,CAAC,CAAC;IACH,iBAAiB,CACf,OAAO,CAAC,OAAO,CACb,UAAW,CAAC,cAAc,CACxB,wBAAwB,CAAC,SAAS,CAAC,EACnC,sBAAsB,CAAC,SAAS,CAAC,CAClC,CACF,EACD,yCAAyC,CAC1C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"outbound-hooks.js","sourceRoot":"","sources":["../../../src/messaging/outbound-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,oCAAoC,EACpC,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEzE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAErC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,MAMnD;IACC,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;IACzC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IACjD,CAAC;IACD,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,iBAAiB,CACnD;YACE,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,OAAO,EAAE,MAAM,CAAC,IAAI;YACpB,QAAQ,EAAE;gBACR,OAAO,EAAE,UAAU;gBACnB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC7D;SACF,EACD,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CACvD,CAAC;QACF,IAAI,UAAU,EAAE,MAAM,EAAE,CAAC;YACvB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;QAChD,CAAC;QACD,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,IAAI,EAAE,UAAU,EAAE,OAAO,IAAI,MAAM,CAAC,IAAI;SACzC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,qDAAqD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChF,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IACjD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAOrC;IACC,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;IACzC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO;IAClD,MAAM,SAAS,GAAG,oCAAoC,CAAC;QACrD,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,UAAU;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,cAAc,EAAE,MAAM,CAAC,EAAE;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAC;IACH,iBAAiB,CACf,OAAO,CAAC,OAAO,CACb,UAAW,CAAC,cAAc,CACxB,wBAAwB,CAAC,SAAS,CAAC,EACnC,sBAAsB,CAAC,SAAS,CAAC,CAClC,CACF,EACD,yCAAyC,CAC1C,CAAC;AACJ,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import path from "node:path";
2
+ import { randomUUID } from "node:crypto";
2
3
  import { createTypingCallbacks } from "openclaw/plugin-sdk/channel-runtime";
3
4
  import { resolveSenderCommandAuthorizationWithRuntime, resolveDirectDmAuthorizationOutcome, } from "openclaw/plugin-sdk/command-auth";
4
5
  import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/infra-runtime";
@@ -7,6 +8,7 @@ import { MessageItemType, TypingStatus } from "../api/types.js";
7
8
  import { loadWeixinAccount } from "../auth/accounts.js";
8
9
  import { readFrameworkAllowFromList } from "../auth/pairing.js";
9
10
  import { downloadRemoteImageToTemp } from "../cdn/upload.js";
11
+ import { resolveReplyProgressMessagesEnabled } from "../config/reply-progress.js";
10
12
  import { downloadMediaFromItem } from "../media/media-download.js";
11
13
  import { logger } from "../util/logger.js";
12
14
  import { redactBody, redactToken } from "../util/redact.js";
@@ -17,6 +19,7 @@ import { setContextToken, weixinMessageToMsgContext, getContextTokenFromMsgConte
17
19
  import { sendWeixinMediaFile } from "./send-media.js";
18
20
  import { StreamingMarkdownFilter } from "./markdown-filter.js";
19
21
  import { sendMessageWeixin } from "./send.js";
22
+ import { WeixinReplyProgressSender } from "./reply-progress-sender.js";
20
23
  import { handleSlashCommand } from "./slash-commands.js";
21
24
  const MEDIA_OUTBOUND_TEMP_DIR = path.join(resolvePreferredOpenClawTmpDir(), "weixin/media/outbound-temp");
22
25
  /** Extract text body from item_list (for slash command detection). */
@@ -177,6 +180,19 @@ export async function processOneMessage(full, deps) {
177
180
  if (contextToken) {
178
181
  setContextToken(deps.accountId, full.from_user_id ?? "", contextToken);
179
182
  }
183
+ const runId = randomUUID();
184
+ const replyProgressSender = resolveReplyProgressMessagesEnabled(deps.config)
185
+ ? new WeixinReplyProgressSender({
186
+ runId,
187
+ to: ctx.To,
188
+ accountId: deps.accountId,
189
+ opts: {
190
+ baseUrl: deps.baseUrl,
191
+ token: deps.token,
192
+ contextToken,
193
+ },
194
+ })
195
+ : undefined;
180
196
  const humanDelay = deps.channelRuntime.reply.resolveHumanDelayConfig(deps.config, route.agentId);
181
197
  const hasTypingTicket = Boolean(deps.typingTicket);
182
198
  const typingCallbacks = createTypingCallbacks({
@@ -233,6 +249,7 @@ export async function processOneMessage(full, deps) {
233
249
  text,
234
250
  accountId: deps.accountId,
235
251
  mediaUrl,
252
+ runId,
236
253
  });
237
254
  if (sendingResult.cancelled) {
238
255
  logger.info(`outbound: cancelled by message_sending hook to=${ctx.To}`);
@@ -266,8 +283,9 @@ export async function processOneMessage(full, deps) {
266
283
  baseUrl: deps.baseUrl,
267
284
  token: deps.token,
268
285
  contextToken,
286
+ runId,
269
287
  } });
270
- emitWeixinMessageSent({ to: ctx.To, content: text, success: true, accountId: deps.accountId });
288
+ emitWeixinMessageSent({ to: ctx.To, content: text, success: true, accountId: deps.accountId, runId });
271
289
  logger.info(`outbound: text sent to=${ctx.To}`);
272
290
  return;
273
291
  }
@@ -275,10 +293,10 @@ export async function processOneMessage(full, deps) {
275
293
  filePath,
276
294
  to: ctx.To,
277
295
  text,
278
- opts: { baseUrl: deps.baseUrl, token: deps.token, contextToken },
296
+ opts: { baseUrl: deps.baseUrl, token: deps.token, contextToken, runId },
279
297
  cdnBaseUrl: deps.cdnBaseUrl,
280
298
  });
281
- emitWeixinMessageSent({ to: ctx.To, content: text, success: true, accountId: deps.accountId });
299
+ emitWeixinMessageSent({ to: ctx.To, content: text, success: true, accountId: deps.accountId, runId });
282
300
  logger.info(`outbound: media sent OK to=${ctx.To}`);
283
301
  }
284
302
  else {
@@ -287,13 +305,14 @@ export async function processOneMessage(full, deps) {
287
305
  baseUrl: deps.baseUrl,
288
306
  token: deps.token,
289
307
  contextToken,
308
+ runId,
290
309
  } });
291
- emitWeixinMessageSent({ to: ctx.To, content: text, success: true, accountId: deps.accountId });
310
+ emitWeixinMessageSent({ to: ctx.To, content: text, success: true, accountId: deps.accountId, runId });
292
311
  logger.info(`outbound: text sent OK to=${ctx.To}`);
293
312
  }
294
313
  }
295
314
  catch (err) {
296
- emitWeixinMessageSent({ to: ctx.To, content: text, success: false, error: String(err), accountId: deps.accountId });
315
+ emitWeixinMessageSent({ to: ctx.To, content: text, success: false, error: String(err), accountId: deps.accountId, runId });
297
316
  logger.error(`outbound: FAILED to=${ctx.To} mediaUrl=${mediaUrl ?? "none"} err=${String(err)} stack=${err.stack ?? ""}`);
298
317
  throw err;
299
318
  }
@@ -319,6 +338,7 @@ export async function processOneMessage(full, deps) {
319
338
  message: notice,
320
339
  baseUrl: deps.baseUrl,
321
340
  token: deps.token,
341
+ runId,
322
342
  errLog: deps.errLog,
323
343
  });
324
344
  },
@@ -331,7 +351,11 @@ export async function processOneMessage(full, deps) {
331
351
  ctx: finalized,
332
352
  cfg: deps.config,
333
353
  dispatcher,
334
- replyOptions: { ...replyOptions, disableBlockStreaming: true },
354
+ replyOptions: {
355
+ ...replyOptions,
356
+ ...(replyProgressSender?.replyOptions ?? {}),
357
+ disableBlockStreaming: true,
358
+ },
335
359
  }),
336
360
  });
337
361
  logger.debug(`dispatchReplyFromConfig: done agentId=${route.agentId ?? "(none)"}`);
@@ -342,6 +366,7 @@ export async function processOneMessage(full, deps) {
342
366
  }
343
367
  finally {
344
368
  markDispatchIdle();
369
+ await replyProgressSender?.finalize();
345
370
  logger.info(`debug-check: accountId=${deps.accountId} debug=${String(debug)} hasContextToken=${Boolean(contextToken)}`);
346
371
  if (debug && contextToken) {
347
372
  const dispatchDoneAt = Date.now();
@@ -368,7 +393,7 @@ export async function processOneMessage(full, deps) {
368
393
  await sendMessageWeixin({
369
394
  to: ctx.To,
370
395
  text: timingText,
371
- opts: { baseUrl: deps.baseUrl, token: deps.token, contextToken },
396
+ opts: { baseUrl: deps.baseUrl, token: deps.token, contextToken, runId },
372
397
  });
373
398
  logger.info(`debug-timing: sent OK`);
374
399
  }