





















@@ -9,6 +9,21 @@ import {
99import type { OpenClawConfig } from "../../src/config/types.openclaw.js";
10101111describe("channel message flows dev runner", () => {
12+function createTestDraftStream(params?: {
13+update?: (text: string) => void;
14+flush?: () => Promise<void>;
15+clear?: () => Promise<void>;
16+}) {
17+return {
18+update: vi.fn(params?.update ?? (() => {})),
19+flush: vi.fn(params?.flush ?? (async () => {})),
20+clear: vi.fn(params?.clear ?? (async () => {})),
21+stop: vi.fn(async () => {}),
22+messageId: vi.fn(() => 17),
23+forceNewMessage: vi.fn(),
24+};
25+}
26+1227it("parses the Telegram thinking-final flow from channel/target flags", () => {
1328const parsed = parseChannelMessageFlowArgs([
1429"--channel",
@@ -168,11 +183,8 @@ describe("channel message flows dev runner", () => {
168183).rejects.toThrow("thinking-final final send did not return a durable Telegram message id");
169184});
170185171-it("streams working updates through native message drafts before the final answer", async () => {
172-const draft = {
173-update: vi.fn(async () => true),
174-stop: vi.fn(async () => {}),
175-};
186+it("streams working updates through rich message drafts before the final answer", async () => {
187+const stream = createTestDraftStream();
176188const sendFinal = vi.fn(async () => ({ messageId: "100", chatId: "123" }));
177189178190const result = await runTelegramWorkingFinalFlow(
@@ -183,42 +195,41 @@ describe("channel message flows dev runner", () => {
183195target: "123",
184196},
185197{
186-createNativeToolProgressDraft: vi.fn(() => draft),
198+createDraftStream: vi.fn(() => stream),
187199 sendFinal,
188200sleep: vi.fn(async () => {}),
189201},
190202);
191203192-expect(draft.update).toHaveBeenNthCalledWith(1, "Working");
193-expect(draft.update.mock.calls[2]?.[0]).toContain("🛠️ pgrep -fl Discord || true (agent)");
194-expect(draft.update.mock.calls[2]?.[0]).toContain(
204+expect(stream.update).toHaveBeenNthCalledWith(1, "Working");
205+expect(stream.update.mock.calls[2]?.[0]).toContain("🛠️ pgrep -fl Discord || true (agent)");
206+expect(stream.update.mock.calls[2]?.[0]).toContain(
195207"🛠️ list files in /Applications/Discord.app -> run true (agent)",
196208);
197-expect(draft.update.mock.calls[4]?.[0]).toContain(
209+expect(stream.update.mock.calls[4]?.[0]).toContain(
198210"• Discord is installed as a normal '/Applications/Discord.app'",
199211);
200-expect(draft.update).toHaveBeenCalledWith(
212+expect(stream.update).toHaveBeenCalledWith(
201213expect.stringContaining("Working\n\n🛠️ pgrep -fl Discord || true (agent)"),
202214);
203-expect(draft.stop).toHaveBeenCalledBefore(sendFinal);
215+expect(stream.clear).toHaveBeenCalledBefore(sendFinal);
204216expect(sendFinal).toHaveBeenCalledWith({
205217accountId: undefined,
206218cfg: {},
207219target: "123",
208220text: "Final answer: the Telegram working preview cleared and this durable reply landed.",
209221threadId: undefined,
210222});
211-expect(draft.update).not.toHaveBeenCalledWith(expect.stringContaining("Working for"));
223+expect(stream.update).not.toHaveBeenCalledWith(expect.stringContaining("Working for"));
212224expect(result).toEqual({ finalMessageId: "100", previewUpdates: 6 });
213225});
214226215-it("stops native working drafts when progress updates fail before the final answer", async () => {
216-const draft = {
217-update: vi.fn(async () => {
227+it("clears rich working drafts when progress updates fail before the final answer", async () => {
228+const stream = createTestDraftStream({
229+update: () => {
218230throw new Error("draft update failed");
219-}),
220-stop: vi.fn(async () => {}),
221-};
231+},
232+});
222233const sendFinal = vi.fn(async () => ({ messageId: "100", chatId: "123" }));
223234224235await expect(
@@ -230,22 +241,19 @@ describe("channel message flows dev runner", () => {
230241target: "123",
231242},
232243{
233-createNativeToolProgressDraft: vi.fn(() => draft),
244+createDraftStream: vi.fn(() => stream),
234245 sendFinal,
235246sleep: vi.fn(async () => {}),
236247},
237248),
238249).rejects.toThrow("draft update failed");
239250240-expect(draft.stop).toHaveBeenCalledOnce();
251+expect(stream.clear).toHaveBeenCalledOnce();
241252expect(sendFinal).not.toHaveBeenCalled();
242253});
243254244255it("fails working-final when the final send does not return a message id", async () => {
245-const draft = {
246-update: vi.fn(async () => true),
247-stop: vi.fn(async () => {}),
248-};
256+const stream = createTestDraftStream();
249257250258await expect(
251259runTelegramWorkingFinalFlow(
@@ -256,7 +264,7 @@ describe("channel message flows dev runner", () => {
256264target: "123",
257265},
258266{
259-createNativeToolProgressDraft: vi.fn(() => draft),
267+createDraftStream: vi.fn(() => stream),
260268sendFinal: vi.fn(async () => ({})),
261269sleep: vi.fn(async () => {}),
262270},
@@ -265,10 +273,7 @@ describe("channel message flows dev runner", () => {
265273});
266274267275it("uses two second progress update cadence by default", async () => {
268-const draft = {
269-update: vi.fn(async () => true),
270-stop: vi.fn(async () => {}),
271-};
276+const stream = createTestDraftStream();
272277const sleep = vi.fn(async () => {});
273278274279const result = await runTelegramWorkingFinalFlow(
@@ -278,7 +283,7 @@ describe("channel message flows dev runner", () => {
278283target: "123",
279284},
280285{
281-createNativeToolProgressDraft: vi.fn(() => draft),
286+createDraftStream: vi.fn(() => stream),
282287sendFinal: vi.fn(async () => ({ messageId: "101", chatId: "123" })),
283288 sleep,
284289},
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。