@openclaw-china/qqbot 2026.3.16 → 2026.3.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +36 -0
- package/dist/index.js +102 -3
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +12 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ declare const QQBotC2CMarkdownDeliveryModeSchema: z.ZodDefault<z.ZodOptional<z.Z
|
|
|
4
4
|
type QQBotC2CMarkdownDeliveryMode = z.input<typeof QQBotC2CMarkdownDeliveryModeSchema>;
|
|
5
5
|
declare const QQBotC2CMarkdownChunkStrategySchema: z.ZodDefault<z.ZodOptional<z.ZodEnum<["markdown-block", "length"]>>>;
|
|
6
6
|
type QQBotC2CMarkdownChunkStrategy = z.input<typeof QQBotC2CMarkdownChunkStrategySchema>;
|
|
7
|
+
declare const QQBotTypingHeartbeatModeSchema: z.ZodDefault<z.ZodOptional<z.ZodEnum<["none", "idle", "always"]>>>;
|
|
8
|
+
type QQBotTypingHeartbeatMode = z.input<typeof QQBotTypingHeartbeatModeSchema>;
|
|
7
9
|
declare const QQBotAccountSchema: z.ZodObject<{
|
|
8
10
|
name: z.ZodOptional<z.ZodString>;
|
|
9
11
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -29,6 +31,9 @@ declare const QQBotAccountSchema: z.ZodObject<{
|
|
|
29
31
|
markdownSupport: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
30
32
|
c2cMarkdownDeliveryMode: z.ZodDefault<z.ZodOptional<z.ZodEnum<["passive", "proactive-table-only", "proactive-all"]>>>;
|
|
31
33
|
c2cMarkdownChunkStrategy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["markdown-block", "length"]>>>;
|
|
34
|
+
typingHeartbeatMode: z.ZodDefault<z.ZodOptional<z.ZodEnum<["none", "idle", "always"]>>>;
|
|
35
|
+
typingHeartbeatIntervalMs: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
36
|
+
typingInputSeconds: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
32
37
|
dmPolicy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["open", "pairing", "allowlist"]>>>;
|
|
33
38
|
groupPolicy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["open", "allowlist", "disabled"]>>>;
|
|
34
39
|
requireMention: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -55,6 +60,9 @@ declare const QQBotAccountSchema: z.ZodObject<{
|
|
|
55
60
|
markdownSupport: boolean;
|
|
56
61
|
c2cMarkdownDeliveryMode: "passive" | "proactive-table-only" | "proactive-all";
|
|
57
62
|
c2cMarkdownChunkStrategy: "markdown-block" | "length";
|
|
63
|
+
typingHeartbeatMode: "none" | "idle" | "always";
|
|
64
|
+
typingHeartbeatIntervalMs: number;
|
|
65
|
+
typingInputSeconds: number;
|
|
58
66
|
dmPolicy: "open" | "pairing" | "allowlist";
|
|
59
67
|
groupPolicy: "open" | "allowlist" | "disabled";
|
|
60
68
|
requireMention: boolean;
|
|
@@ -97,6 +105,9 @@ declare const QQBotAccountSchema: z.ZodObject<{
|
|
|
97
105
|
markdownSupport?: boolean | undefined;
|
|
98
106
|
c2cMarkdownDeliveryMode?: "passive" | "proactive-table-only" | "proactive-all" | undefined;
|
|
99
107
|
c2cMarkdownChunkStrategy?: "markdown-block" | "length" | undefined;
|
|
108
|
+
typingHeartbeatMode?: "none" | "idle" | "always" | undefined;
|
|
109
|
+
typingHeartbeatIntervalMs?: number | undefined;
|
|
110
|
+
typingInputSeconds?: number | undefined;
|
|
100
111
|
dmPolicy?: "open" | "pairing" | "allowlist" | undefined;
|
|
101
112
|
groupPolicy?: "open" | "allowlist" | "disabled" | undefined;
|
|
102
113
|
requireMention?: boolean | undefined;
|
|
@@ -139,6 +150,9 @@ declare const QQBotConfigSchema: z.ZodObject<{
|
|
|
139
150
|
markdownSupport: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
140
151
|
c2cMarkdownDeliveryMode: z.ZodDefault<z.ZodOptional<z.ZodEnum<["passive", "proactive-table-only", "proactive-all"]>>>;
|
|
141
152
|
c2cMarkdownChunkStrategy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["markdown-block", "length"]>>>;
|
|
153
|
+
typingHeartbeatMode: z.ZodDefault<z.ZodOptional<z.ZodEnum<["none", "idle", "always"]>>>;
|
|
154
|
+
typingHeartbeatIntervalMs: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
155
|
+
typingInputSeconds: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
142
156
|
dmPolicy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["open", "pairing", "allowlist"]>>>;
|
|
143
157
|
groupPolicy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["open", "allowlist", "disabled"]>>>;
|
|
144
158
|
requireMention: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -188,6 +202,9 @@ declare const QQBotConfigSchema: z.ZodObject<{
|
|
|
188
202
|
markdownSupport: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
189
203
|
c2cMarkdownDeliveryMode: z.ZodDefault<z.ZodOptional<z.ZodEnum<["passive", "proactive-table-only", "proactive-all"]>>>;
|
|
190
204
|
c2cMarkdownChunkStrategy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["markdown-block", "length"]>>>;
|
|
205
|
+
typingHeartbeatMode: z.ZodDefault<z.ZodOptional<z.ZodEnum<["none", "idle", "always"]>>>;
|
|
206
|
+
typingHeartbeatIntervalMs: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
207
|
+
typingInputSeconds: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
191
208
|
dmPolicy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["open", "pairing", "allowlist"]>>>;
|
|
192
209
|
groupPolicy: z.ZodDefault<z.ZodOptional<z.ZodEnum<["open", "allowlist", "disabled"]>>>;
|
|
193
210
|
requireMention: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
@@ -214,6 +231,9 @@ declare const QQBotConfigSchema: z.ZodObject<{
|
|
|
214
231
|
markdownSupport: boolean;
|
|
215
232
|
c2cMarkdownDeliveryMode: "passive" | "proactive-table-only" | "proactive-all";
|
|
216
233
|
c2cMarkdownChunkStrategy: "markdown-block" | "length";
|
|
234
|
+
typingHeartbeatMode: "none" | "idle" | "always";
|
|
235
|
+
typingHeartbeatIntervalMs: number;
|
|
236
|
+
typingInputSeconds: number;
|
|
217
237
|
dmPolicy: "open" | "pairing" | "allowlist";
|
|
218
238
|
groupPolicy: "open" | "allowlist" | "disabled";
|
|
219
239
|
requireMention: boolean;
|
|
@@ -256,6 +276,9 @@ declare const QQBotConfigSchema: z.ZodObject<{
|
|
|
256
276
|
markdownSupport?: boolean | undefined;
|
|
257
277
|
c2cMarkdownDeliveryMode?: "passive" | "proactive-table-only" | "proactive-all" | undefined;
|
|
258
278
|
c2cMarkdownChunkStrategy?: "markdown-block" | "length" | undefined;
|
|
279
|
+
typingHeartbeatMode?: "none" | "idle" | "always" | undefined;
|
|
280
|
+
typingHeartbeatIntervalMs?: number | undefined;
|
|
281
|
+
typingInputSeconds?: number | undefined;
|
|
259
282
|
dmPolicy?: "open" | "pairing" | "allowlist" | undefined;
|
|
260
283
|
groupPolicy?: "open" | "allowlist" | "disabled" | undefined;
|
|
261
284
|
requireMention?: boolean | undefined;
|
|
@@ -277,6 +300,9 @@ declare const QQBotConfigSchema: z.ZodObject<{
|
|
|
277
300
|
markdownSupport: boolean;
|
|
278
301
|
c2cMarkdownDeliveryMode: "passive" | "proactive-table-only" | "proactive-all";
|
|
279
302
|
c2cMarkdownChunkStrategy: "markdown-block" | "length";
|
|
303
|
+
typingHeartbeatMode: "none" | "idle" | "always";
|
|
304
|
+
typingHeartbeatIntervalMs: number;
|
|
305
|
+
typingInputSeconds: number;
|
|
280
306
|
dmPolicy: "open" | "pairing" | "allowlist";
|
|
281
307
|
groupPolicy: "open" | "allowlist" | "disabled";
|
|
282
308
|
requireMention: boolean;
|
|
@@ -309,6 +335,9 @@ declare const QQBotConfigSchema: z.ZodObject<{
|
|
|
309
335
|
markdownSupport: boolean;
|
|
310
336
|
c2cMarkdownDeliveryMode: "passive" | "proactive-table-only" | "proactive-all";
|
|
311
337
|
c2cMarkdownChunkStrategy: "markdown-block" | "length";
|
|
338
|
+
typingHeartbeatMode: "none" | "idle" | "always";
|
|
339
|
+
typingHeartbeatIntervalMs: number;
|
|
340
|
+
typingInputSeconds: number;
|
|
312
341
|
dmPolicy: "open" | "pairing" | "allowlist";
|
|
313
342
|
groupPolicy: "open" | "allowlist" | "disabled";
|
|
314
343
|
requireMention: boolean;
|
|
@@ -352,6 +381,9 @@ declare const QQBotConfigSchema: z.ZodObject<{
|
|
|
352
381
|
markdownSupport?: boolean | undefined;
|
|
353
382
|
c2cMarkdownDeliveryMode?: "passive" | "proactive-table-only" | "proactive-all" | undefined;
|
|
354
383
|
c2cMarkdownChunkStrategy?: "markdown-block" | "length" | undefined;
|
|
384
|
+
typingHeartbeatMode?: "none" | "idle" | "always" | undefined;
|
|
385
|
+
typingHeartbeatIntervalMs?: number | undefined;
|
|
386
|
+
typingInputSeconds?: number | undefined;
|
|
355
387
|
dmPolicy?: "open" | "pairing" | "allowlist" | undefined;
|
|
356
388
|
groupPolicy?: "open" | "allowlist" | "disabled" | undefined;
|
|
357
389
|
requireMention?: boolean | undefined;
|
|
@@ -384,6 +416,9 @@ declare const QQBotConfigSchema: z.ZodObject<{
|
|
|
384
416
|
markdownSupport?: boolean | undefined;
|
|
385
417
|
c2cMarkdownDeliveryMode?: "passive" | "proactive-table-only" | "proactive-all" | undefined;
|
|
386
418
|
c2cMarkdownChunkStrategy?: "markdown-block" | "length" | undefined;
|
|
419
|
+
typingHeartbeatMode?: "none" | "idle" | "always" | undefined;
|
|
420
|
+
typingHeartbeatIntervalMs?: number | undefined;
|
|
421
|
+
typingInputSeconds?: number | undefined;
|
|
387
422
|
dmPolicy?: "open" | "pairing" | "allowlist" | undefined;
|
|
388
423
|
groupPolicy?: "open" | "allowlist" | "disabled" | undefined;
|
|
389
424
|
requireMention?: boolean | undefined;
|
|
@@ -419,6 +454,7 @@ interface ResolvedQQBotAccount {
|
|
|
419
454
|
markdownSupport?: boolean;
|
|
420
455
|
c2cMarkdownDeliveryMode?: QQBotC2CMarkdownDeliveryMode;
|
|
421
456
|
c2cMarkdownChunkStrategy?: QQBotC2CMarkdownChunkStrategy;
|
|
457
|
+
typingHeartbeatMode?: QQBotTypingHeartbeatMode;
|
|
422
458
|
}
|
|
423
459
|
interface QQBotSendResult {
|
|
424
460
|
channel: "qqbot";
|
package/dist/index.js
CHANGED
|
@@ -4228,6 +4228,10 @@ var displayAliasesSchema = external_exports.record(
|
|
|
4228
4228
|
).optional();
|
|
4229
4229
|
var QQBotC2CMarkdownDeliveryModeSchema = external_exports.enum(["passive", "proactive-table-only", "proactive-all"]).optional().default("proactive-table-only");
|
|
4230
4230
|
var QQBotC2CMarkdownChunkStrategySchema = external_exports.enum(["markdown-block", "length"]).optional().default("markdown-block");
|
|
4231
|
+
var QQBotTypingHeartbeatModeSchema = external_exports.enum(["none", "idle", "always"]).optional().default("idle");
|
|
4232
|
+
var DEFAULT_QQBOT_TYPING_HEARTBEAT_MODE = "idle";
|
|
4233
|
+
var DEFAULT_QQBOT_TYPING_HEARTBEAT_INTERVAL_MS = 5e3;
|
|
4234
|
+
var DEFAULT_QQBOT_TYPING_INPUT_SECONDS = 60;
|
|
4231
4235
|
var QQBotAccountSchema = external_exports.object({
|
|
4232
4236
|
name: external_exports.string().optional(),
|
|
4233
4237
|
enabled: external_exports.boolean().optional(),
|
|
@@ -4243,6 +4247,13 @@ var QQBotAccountSchema = external_exports.object({
|
|
|
4243
4247
|
markdownSupport: external_exports.boolean().optional().default(true),
|
|
4244
4248
|
c2cMarkdownDeliveryMode: QQBotC2CMarkdownDeliveryModeSchema,
|
|
4245
4249
|
c2cMarkdownChunkStrategy: QQBotC2CMarkdownChunkStrategySchema,
|
|
4250
|
+
typingHeartbeatMode: QQBotTypingHeartbeatModeSchema,
|
|
4251
|
+
typingHeartbeatIntervalMs: external_exports.number().int().positive().optional().default(
|
|
4252
|
+
DEFAULT_QQBOT_TYPING_HEARTBEAT_INTERVAL_MS
|
|
4253
|
+
),
|
|
4254
|
+
typingInputSeconds: external_exports.number().int().positive().optional().default(
|
|
4255
|
+
DEFAULT_QQBOT_TYPING_INPUT_SECONDS
|
|
4256
|
+
),
|
|
4246
4257
|
dmPolicy: external_exports.enum(["open", "pairing", "allowlist"]).optional().default("open"),
|
|
4247
4258
|
groupPolicy: external_exports.enum(["open", "allowlist", "disabled"]).optional().default("open"),
|
|
4248
4259
|
requireMention: external_exports.boolean().optional().default(true),
|
|
@@ -4292,6 +4303,15 @@ function resolveInboundMediaKeepDays(config) {
|
|
|
4292
4303
|
function resolveQQBotAutoSendLocalPathMedia(config) {
|
|
4293
4304
|
return config?.autoSendLocalPathMedia ?? true;
|
|
4294
4305
|
}
|
|
4306
|
+
function resolveQQBotTypingHeartbeatMode(config) {
|
|
4307
|
+
return config?.typingHeartbeatMode ?? DEFAULT_QQBOT_TYPING_HEARTBEAT_MODE;
|
|
4308
|
+
}
|
|
4309
|
+
function resolveQQBotTypingHeartbeatIntervalMs(config) {
|
|
4310
|
+
return config?.typingHeartbeatIntervalMs ?? DEFAULT_QQBOT_TYPING_HEARTBEAT_INTERVAL_MS;
|
|
4311
|
+
}
|
|
4312
|
+
function resolveQQBotTypingInputSeconds(config) {
|
|
4313
|
+
return config?.typingInputSeconds ?? DEFAULT_QQBOT_TYPING_INPUT_SECONDS;
|
|
4314
|
+
}
|
|
4295
4315
|
function resolveInboundMediaTempDir() {
|
|
4296
4316
|
return DEFAULT_INBOUND_MEDIA_TEMP_DIR;
|
|
4297
4317
|
}
|
|
@@ -9623,6 +9643,37 @@ function startLongTaskNoticeTimer(params) {
|
|
|
9623
9643
|
}
|
|
9624
9644
|
};
|
|
9625
9645
|
}
|
|
9646
|
+
function startQQBotTypingHeartbeat(params) {
|
|
9647
|
+
const { intervalMs, renew, shouldRenew } = params;
|
|
9648
|
+
let stopped = false;
|
|
9649
|
+
let timer = null;
|
|
9650
|
+
let renewalInFlight = false;
|
|
9651
|
+
const clear = () => {
|
|
9652
|
+
if (!timer) return;
|
|
9653
|
+
clearInterval(timer);
|
|
9654
|
+
timer = null;
|
|
9655
|
+
};
|
|
9656
|
+
const stop = () => {
|
|
9657
|
+
if (stopped) return;
|
|
9658
|
+
stopped = true;
|
|
9659
|
+
clear();
|
|
9660
|
+
};
|
|
9661
|
+
if (intervalMs > 0) {
|
|
9662
|
+
timer = setInterval(() => {
|
|
9663
|
+
if (stopped || renewalInFlight) return;
|
|
9664
|
+
if (shouldRenew && !shouldRenew()) return;
|
|
9665
|
+
renewalInFlight = true;
|
|
9666
|
+
void renew().catch(() => void 0).finally(() => {
|
|
9667
|
+
renewalInFlight = false;
|
|
9668
|
+
});
|
|
9669
|
+
}, intervalMs);
|
|
9670
|
+
timer.unref?.();
|
|
9671
|
+
}
|
|
9672
|
+
return {
|
|
9673
|
+
stop,
|
|
9674
|
+
dispose: stop
|
|
9675
|
+
};
|
|
9676
|
+
}
|
|
9626
9677
|
function isHttpUrl3(value) {
|
|
9627
9678
|
return /^https?:\/\//i.test(value);
|
|
9628
9679
|
}
|
|
@@ -11029,6 +11080,9 @@ async function dispatchToAgent(params) {
|
|
|
11029
11080
|
};
|
|
11030
11081
|
const target = resolveChatTarget(inbound);
|
|
11031
11082
|
const outboundAccountId = route.accountId ?? accountId;
|
|
11083
|
+
const typingHeartbeatMode = resolveQQBotTypingHeartbeatMode(qqCfg);
|
|
11084
|
+
const typingHeartbeatIntervalMs = resolveQQBotTypingHeartbeatIntervalMs(qqCfg);
|
|
11085
|
+
const typingInputSeconds = resolveQQBotTypingInputSeconds(qqCfg);
|
|
11032
11086
|
let typingRefIdx;
|
|
11033
11087
|
if (inbound.c2cOpenid && !isFastAbortCommand && !shouldSuppressVisibleReplies()) {
|
|
11034
11088
|
const typing = await qqbotOutbound.sendTyping({
|
|
@@ -11036,7 +11090,7 @@ async function dispatchToAgent(params) {
|
|
|
11036
11090
|
to: `user:${inbound.c2cOpenid}`,
|
|
11037
11091
|
replyToId: inbound.messageId,
|
|
11038
11092
|
replyEventId: inbound.eventId,
|
|
11039
|
-
inputSecond:
|
|
11093
|
+
inputSecond: typingInputSeconds,
|
|
11040
11094
|
accountId: outboundAccountId
|
|
11041
11095
|
});
|
|
11042
11096
|
if (typing.error) {
|
|
@@ -11052,10 +11106,15 @@ async function dispatchToAgent(params) {
|
|
|
11052
11106
|
}
|
|
11053
11107
|
let replyDelivered = false;
|
|
11054
11108
|
let groupMessageInterfaceBlocked = false;
|
|
11109
|
+
let lastVisibleOutboundAt = Date.now();
|
|
11110
|
+
let typingHeartbeat = null;
|
|
11055
11111
|
const markReplyDelivered = () => {
|
|
11056
11112
|
replyDelivered = true;
|
|
11057
11113
|
longTaskNotice.markReplyDelivered();
|
|
11058
11114
|
};
|
|
11115
|
+
const markVisibleOutboundStarted = () => {
|
|
11116
|
+
lastVisibleOutboundAt = Date.now();
|
|
11117
|
+
};
|
|
11059
11118
|
const markGroupMessageInterfaceBlocked = (error) => {
|
|
11060
11119
|
if (!isQQBotGroupMessageInterfaceBlocked(error)) return;
|
|
11061
11120
|
if (!groupMessageInterfaceBlocked) {
|
|
@@ -11063,11 +11122,40 @@ async function dispatchToAgent(params) {
|
|
|
11063
11122
|
}
|
|
11064
11123
|
groupMessageInterfaceBlocked = true;
|
|
11065
11124
|
};
|
|
11125
|
+
if (inbound.c2cOpenid && typingHeartbeatMode !== "none" && !isFastAbortCommand && !shouldSuppressVisibleReplies()) {
|
|
11126
|
+
typingHeartbeat = startQQBotTypingHeartbeat({
|
|
11127
|
+
intervalMs: typingHeartbeatIntervalMs,
|
|
11128
|
+
shouldRenew: () => {
|
|
11129
|
+
if (shouldSuppressVisibleReplies()) {
|
|
11130
|
+
return false;
|
|
11131
|
+
}
|
|
11132
|
+
if (typingHeartbeatMode === "always") {
|
|
11133
|
+
return true;
|
|
11134
|
+
}
|
|
11135
|
+
return Date.now() - lastVisibleOutboundAt >= typingHeartbeatIntervalMs;
|
|
11136
|
+
},
|
|
11137
|
+
renew: async () => {
|
|
11138
|
+
try {
|
|
11139
|
+
const typing = await qqbotOutbound.sendTyping({
|
|
11140
|
+
cfg: { channels: { qqbot: qqCfg } },
|
|
11141
|
+
to: `user:${inbound.c2cOpenid}`,
|
|
11142
|
+
replyToId: inbound.messageId,
|
|
11143
|
+
replyEventId: inbound.eventId,
|
|
11144
|
+
inputSecond: typingInputSeconds,
|
|
11145
|
+
accountId: outboundAccountId
|
|
11146
|
+
});
|
|
11147
|
+
void typing;
|
|
11148
|
+
} catch {
|
|
11149
|
+
}
|
|
11150
|
+
}
|
|
11151
|
+
});
|
|
11152
|
+
}
|
|
11066
11153
|
const longTaskNotice = startLongTaskNoticeTimer({
|
|
11067
11154
|
delayMs: qqCfg.longTaskNoticeDelayMs ?? DEFAULT_LONG_TASK_NOTICE_DELAY_MS,
|
|
11068
11155
|
logger,
|
|
11069
11156
|
sendNotice: async () => {
|
|
11070
11157
|
if (groupMessageInterfaceBlocked || isFastAbortCommand || shouldSuppressVisibleReplies()) return;
|
|
11158
|
+
markVisibleOutboundStarted();
|
|
11071
11159
|
const result = await qqbotOutbound.sendText({
|
|
11072
11160
|
cfg: { channels: { qqbot: qqCfg } },
|
|
11073
11161
|
to: target.to,
|
|
@@ -11080,7 +11168,7 @@ async function dispatchToAgent(params) {
|
|
|
11080
11168
|
logger.warn(`send long-task notice failed: ${result.error}`);
|
|
11081
11169
|
markGroupMessageInterfaceBlocked(result.error);
|
|
11082
11170
|
} else {
|
|
11083
|
-
|
|
11171
|
+
markReplyDelivered();
|
|
11084
11172
|
}
|
|
11085
11173
|
}
|
|
11086
11174
|
});
|
|
@@ -11104,6 +11192,7 @@ async function dispatchToAgent(params) {
|
|
|
11104
11192
|
if (shouldSuppressVisibleReplies()) {
|
|
11105
11193
|
return;
|
|
11106
11194
|
}
|
|
11195
|
+
markVisibleOutboundStarted();
|
|
11107
11196
|
const fallback = await qqbotOutbound.sendText({
|
|
11108
11197
|
cfg: { channels: { qqbot: qqCfg } },
|
|
11109
11198
|
to: target.to,
|
|
@@ -11116,7 +11205,7 @@ async function dispatchToAgent(params) {
|
|
|
11116
11205
|
logger.error(`sendText ASR fallback failed: ${fallback.error}`);
|
|
11117
11206
|
markGroupMessageInterfaceBlocked(fallback.error);
|
|
11118
11207
|
} else {
|
|
11119
|
-
|
|
11208
|
+
markReplyDelivered();
|
|
11120
11209
|
}
|
|
11121
11210
|
return;
|
|
11122
11211
|
}
|
|
@@ -11322,6 +11411,9 @@ async function dispatchToAgent(params) {
|
|
|
11322
11411
|
`delivery=${deliveryLabel} to=${target.to} chunks=${textChunks.length} media=${mediaQueue.length} replyToId=${textReplyRefs.replyToId ? "yes" : "no"} replyEventId=${textReplyRefs.replyEventId ? "yes" : "no"} phase=${params2.phase} tableMode=${String(resolvedTableMode)} chunkMode=${String(chunkMode ?? "default")} chunkStrategy=${c2cMarkdownChunkStrategy}`
|
|
11323
11412
|
);
|
|
11324
11413
|
if (!shouldSuppressVisibleReplies()) {
|
|
11414
|
+
if (mediaQueue.length > 0) {
|
|
11415
|
+
markVisibleOutboundStarted();
|
|
11416
|
+
}
|
|
11325
11417
|
await sendQQBotMediaWithFallback({
|
|
11326
11418
|
qqCfg,
|
|
11327
11419
|
to: target.to,
|
|
@@ -11350,6 +11442,7 @@ async function dispatchToAgent(params) {
|
|
|
11350
11442
|
logger.info(
|
|
11351
11443
|
`delivery=${deliveryLabel} segment=1/1 chunk=${chunkIndex + 1}/${textChunks.length} phase=${params2.phase} preview=${formatQQBotOutboundPreview(chunk)}`
|
|
11352
11444
|
);
|
|
11445
|
+
markVisibleOutboundStarted();
|
|
11353
11446
|
const result = await qqbotOutbound.sendText({
|
|
11354
11447
|
cfg: { channels: { qqbot: qqCfg } },
|
|
11355
11448
|
to: target.to,
|
|
@@ -11464,6 +11557,7 @@ async function dispatchToAgent(params) {
|
|
|
11464
11557
|
if (shouldSuppressVisibleReplies()) {
|
|
11465
11558
|
return;
|
|
11466
11559
|
}
|
|
11560
|
+
markVisibleOutboundStarted();
|
|
11467
11561
|
const result = await qqbotOutbound.sendText({
|
|
11468
11562
|
cfg: { channels: { qqbot: qqCfg } },
|
|
11469
11563
|
to: target.to,
|
|
@@ -11483,6 +11577,9 @@ async function dispatchToAgent(params) {
|
|
|
11483
11577
|
if (shouldSuppressVisibleReplies()) {
|
|
11484
11578
|
return;
|
|
11485
11579
|
}
|
|
11580
|
+
if (mediaQueue.length > 0) {
|
|
11581
|
+
markVisibleOutboundStarted();
|
|
11582
|
+
}
|
|
11486
11583
|
await sendQQBotMediaWithFallback({
|
|
11487
11584
|
qqCfg,
|
|
11488
11585
|
to: target.to,
|
|
@@ -11587,6 +11684,7 @@ async function dispatchToAgent(params) {
|
|
|
11587
11684
|
});
|
|
11588
11685
|
if (noReplyFallback && !groupMessageInterfaceBlocked && !isFastAbortCommand && !shouldSuppressVisibleReplies()) {
|
|
11589
11686
|
logger.info("no visible reply generated for group mention; sending fallback text");
|
|
11687
|
+
markVisibleOutboundStarted();
|
|
11590
11688
|
const fallbackResult = await qqbotOutbound.sendText({
|
|
11591
11689
|
cfg: { channels: { qqbot: qqCfg } },
|
|
11592
11690
|
to: target.to,
|
|
@@ -11603,6 +11701,7 @@ async function dispatchToAgent(params) {
|
|
|
11603
11701
|
}
|
|
11604
11702
|
}
|
|
11605
11703
|
} finally {
|
|
11704
|
+
typingHeartbeat?.dispose();
|
|
11606
11705
|
longTaskNotice.dispose();
|
|
11607
11706
|
try {
|
|
11608
11707
|
await pruneInboundMediaDir({
|