fix(feishu): prevent duplicate message after streaming card close (#6… · openclaw/openclaw@2aa313c
MoerAI
·
2026-04-25
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -364,6 +364,27 @@ describe("createFeishuReplyDispatcher streaming behavior", () => {
|
364 | 364 | expect(sendMessageFeishuMock).not.toHaveBeenCalled(); |
365 | 365 | expect(sendMarkdownCardFeishuMock).not.toHaveBeenCalled(); |
366 | 366 | }); |
| 367 | + |
| 368 | +it("skips final text already closed by idle streaming", async () => { |
| 369 | +const { result, options } = createDispatcherHarness({ |
| 370 | +runtime: createRuntimeLogger(), |
| 371 | +}); |
| 372 | + |
| 373 | +await options.onReplyStart?.(); |
| 374 | +result.replyOptions.onPartialReply?.({ text: "```md\nidle streamed reply\n```" }); |
| 375 | +await options.onIdle?.(); |
| 376 | +await options.deliver({ text: "```md\nidle streamed reply\n```" }, { kind: "final" }); |
| 377 | + |
| 378 | +expect(streamingInstances).toHaveLength(1); |
| 379 | +expect(streamingInstances[0].close).toHaveBeenCalledTimes(1); |
| 380 | +expect(streamingInstances[0].close).toHaveBeenCalledWith("```md\nidle streamed reply\n```", { |
| 381 | +note: "Agent: agent", |
| 382 | +}); |
| 383 | +expect(sendMessageFeishuMock).not.toHaveBeenCalled(); |
| 384 | +expect(sendMarkdownCardFeishuMock).not.toHaveBeenCalled(); |
| 385 | +expect(sendStructuredCardFeishuMock).not.toHaveBeenCalled(); |
| 386 | +}); |
| 387 | + |
367 | 388 | it("suppresses duplicate final text while still sending media", async () => { |
368 | 389 | const options = setupNonStreamingAutoDispatcher(); |
369 | 390 | await options.deliver({ text: "plain final" }, { kind: "final" }); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -311,6 +311,12 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
|
311 | 311 | } |
312 | 312 | const finalNote = resolveCardNote(agentId, identity, prefixContext.prefixContext); |
313 | 313 | await streaming.close(text, { note: finalNote }); |
| 314 | +// Track the raw streamed text so the duplicate-final check in deliver() |
| 315 | +// can skip the redundant text delivery that arrives after onIdle closes |
| 316 | +// the streaming card. |
| 317 | +if (streamText) { |
| 318 | +deliveredFinalTexts.add(streamText); |
| 319 | +} |
314 | 320 | } |
315 | 321 | streaming = null; |
316 | 322 | streamingStartPromise = null; |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。