@jerryliang122/openclaw-qqbot 1.0.4 → 1.0.5
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.cjs +21 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/package.json +1 -1
- package/src/dispatch/dispatch.ts +4 -0
- package/src/outbound/streaming-controller.ts +21 -4
package/dist/index.d.cts
CHANGED
|
@@ -860,8 +860,13 @@ declare class StreamingController {
|
|
|
860
860
|
private session;
|
|
861
861
|
/** QQ 已接受的最新文本 — 单源真理 */
|
|
862
862
|
private lastAcceptedFull;
|
|
863
|
-
/** 已成功发送的分片数(降级:=0
|
|
863
|
+
/** 已成功发送的分片数(降级:=0 且无外部投递则走静态消息兜底) */
|
|
864
864
|
private sentChunkCount;
|
|
865
|
+
/**
|
|
866
|
+
* 标记:内容已通过非流式通道成功投递(如 ask_user 按钮卡片)。
|
|
867
|
+
* 置 true 后 handleFinalize 不再走 fallback 路径,避免框架误报 outcome=error。
|
|
868
|
+
*/
|
|
869
|
+
private _deliveredExternally;
|
|
865
870
|
/** 同步标志:收到第一个 onPartialReply 即置 true(不等 async 完成) */
|
|
866
871
|
private _hasStarted;
|
|
867
872
|
/** 串行队列 */
|
|
@@ -882,6 +887,11 @@ declare class StreamingController {
|
|
|
882
887
|
get hasStarted(): boolean;
|
|
883
888
|
get isTerminal(): boolean;
|
|
884
889
|
get shouldFallbackToStatic(): boolean;
|
|
890
|
+
/**
|
|
891
|
+
* 告知控制器内容已通过外部通道投递(如 ask_user 卡片)。
|
|
892
|
+
* 后续 finalize() 不会走 fallback 路径,框架不会误报 outcome=error。
|
|
893
|
+
*/
|
|
894
|
+
markDeliveredExternally(): void;
|
|
885
895
|
onPartialReply(text: string): Promise<void>;
|
|
886
896
|
finalize(): Promise<void>;
|
|
887
897
|
/**
|
package/package.json
CHANGED
package/src/dispatch/dispatch.ts
CHANGED
|
@@ -298,6 +298,8 @@ export async function dispatchToOpenClaw(
|
|
|
298
298
|
try {
|
|
299
299
|
await bot.sendTextWithKeyboard(replyTarget, text, keyboard as never);
|
|
300
300
|
outboundSendOk++;
|
|
301
|
+
// 标记流式控制器:内容已通过外部通道投递,finalize 不走 fallback
|
|
302
|
+
streamingController?.markDeliveredExternally();
|
|
301
303
|
dlog?.debug(`[question] sent ask_user with keyboard questionId=${questionId} options=${optionValues.length}`);
|
|
302
304
|
return;
|
|
303
305
|
} catch (err) {
|
|
@@ -331,6 +333,8 @@ export async function dispatchToOpenClaw(
|
|
|
331
333
|
await bot.sendTextWithKeyboard(replyTarget, cardText, keyboard as never);
|
|
332
334
|
outboundSendOk++;
|
|
333
335
|
}
|
|
336
|
+
// 标记流式控制器:内容已通过外部通道投递,finalize 不走 fallback
|
|
337
|
+
streamingController?.markDeliveredExternally();
|
|
334
338
|
dlog?.debug(`[question] sent multi-question ask_user questionId=${questionId} questions=${questions.length}`);
|
|
335
339
|
return;
|
|
336
340
|
} catch (err) {
|
|
@@ -51,9 +51,15 @@ export class StreamingController {
|
|
|
51
51
|
/** QQ 已接受的最新文本 — 单源真理 */
|
|
52
52
|
private lastAcceptedFull = '';
|
|
53
53
|
|
|
54
|
-
/** 已成功发送的分片数(降级:=0
|
|
54
|
+
/** 已成功发送的分片数(降级:=0 且无外部投递则走静态消息兜底) */
|
|
55
55
|
private sentChunkCount = 0;
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* 标记:内容已通过非流式通道成功投递(如 ask_user 按钮卡片)。
|
|
59
|
+
* 置 true 后 handleFinalize 不再走 fallback 路径,避免框架误报 outcome=error。
|
|
60
|
+
*/
|
|
61
|
+
private _deliveredExternally = false;
|
|
62
|
+
|
|
57
63
|
/** 同步标志:收到第一个 onPartialReply 即置 true(不等 async 完成) */
|
|
58
64
|
private _hasStarted = false;
|
|
59
65
|
|
|
@@ -87,7 +93,15 @@ export class StreamingController {
|
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
get shouldFallbackToStatic(): boolean {
|
|
90
|
-
return this.isTerminal && this.sentChunkCount === 0;
|
|
96
|
+
return this.isTerminal && this.sentChunkCount === 0 && !this._deliveredExternally;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 告知控制器内容已通过外部通道投递(如 ask_user 卡片)。
|
|
101
|
+
* 后续 finalize() 不会走 fallback 路径,框架不会误报 outcome=error。
|
|
102
|
+
*/
|
|
103
|
+
markDeliveredExternally(): void {
|
|
104
|
+
this._deliveredExternally = true;
|
|
91
105
|
}
|
|
92
106
|
|
|
93
107
|
// ── 入口 ──
|
|
@@ -212,6 +226,9 @@ export class StreamingController {
|
|
|
212
226
|
} else if (this.sentChunkCount > 0 && this.lastAcceptedFull) {
|
|
213
227
|
// 未提供 sendStatic → 降级标记,由上层兜底发送
|
|
214
228
|
this.transition('failed', 'finalize:no_sendstatic');
|
|
229
|
+
} else if (this._deliveredExternally) {
|
|
230
|
+
// 内容已通过外部通道投递(如 ask_user 卡片),非失败
|
|
231
|
+
this.transition('done', 'finalize');
|
|
215
232
|
} else {
|
|
216
233
|
this.transition('done', 'finalize:fallback');
|
|
217
234
|
}
|
|
@@ -227,8 +244,8 @@ export class StreamingController {
|
|
|
227
244
|
}
|
|
228
245
|
|
|
229
246
|
// 无会话 — 视有无下发决定终态
|
|
230
|
-
if (this.sentChunkCount > 0) {
|
|
231
|
-
this.transition('done', 'finalize:no_session');
|
|
247
|
+
if (this.sentChunkCount > 0 || this._deliveredExternally) {
|
|
248
|
+
this.transition('done', this.sentChunkCount > 0 ? 'finalize:no_session' : 'finalize');
|
|
232
249
|
} else {
|
|
233
250
|
this.transition('done', 'finalize:fallback');
|
|
234
251
|
}
|