diff --git a/src/auto-reply/reply/agent-runner.block-streaming.test.ts b/src/auto-reply/reply/agent-runner.block-streaming.test.ts index fed7dc14a91..43d6786ce65 100644 --- a/src/auto-reply/reply/agent-runner.block-streaming.test.ts +++ b/src/auto-reply/reply/agent-runner.block-streaming.test.ts @@ -38,27 +38,21 @@ vi.mock("./queue.js", async () => { import { runReplyAgent } from "./agent-runner.js"; describe("runReplyAgent block streaming", () => { - it("coalesces duplicate text_end block replies", async () => { - const onBlockReply = vi.fn(); - runEmbeddedPiAgentMock.mockImplementationOnce(async (params) => { - const block = params.onBlockReply as ((payload: { text?: string }) => void) | undefined; - block?.({ text: "Hello" }); - block?.({ text: "Hello" }); - return { - payloads: [{ text: "Final message" }], - meta: {}, - }; - }); + function createBaseContext() { + return { + typing: createMockTypingController(), + sessionCtx: { + Provider: "discord", + OriginatingTo: "channel:C1", + AccountId: "primary", + MessageSid: "msg", + } as unknown as TemplateContext, + resolvedQueue: { mode: "interrupt" } as unknown as QueueSettings, + }; + } - const typing = createMockTypingController(); - const sessionCtx = { - Provider: "discord", - OriginatingTo: "channel:C1", - AccountId: "primary", - MessageSid: "msg", - } as unknown as TemplateContext; - const resolvedQueue = { mode: "interrupt" } as unknown as QueueSettings; - const followupRun = { + function createBaseFollowupRun() { + return { prompt: "hello", summaryLine: "hello", enqueuedAt: Date.now(), @@ -94,17 +88,20 @@ describe("runReplyAgent block streaming", () => { blockReplyBreak: "text_end", }, } as unknown as FollowupRun; + } - const result = await runReplyAgent({ + function createBaseRunArgs(params: { onBlockReply: unknown; blockReplyTimeoutMs?: number }) { + const { typing, sessionCtx, resolvedQueue } = createBaseContext(); + return { commandBody: "hello", - followupRun, + followupRun: createBaseFollowupRun(), queueKey: "main", resolvedQueue, shouldSteer: false, shouldFollowup: false, isActive: false, isStreaming: false, - opts: { onBlockReply }, + opts: { onBlockReply: params.onBlockReply, blockReplyTimeoutMs: params.blockReplyTimeoutMs }, typing, sessionCtx, defaultModel: "anthropic/claude-opus-4-5", @@ -119,8 +116,23 @@ describe("runReplyAgent block streaming", () => { resolvedBlockStreamingBreak: "text_end", shouldInjectGroupIntro: false, typingMode: "instant", + }; + } + + it("coalesces duplicate text_end block replies", async () => { + const onBlockReply = vi.fn(); + runEmbeddedPiAgentMock.mockImplementationOnce(async (params) => { + const block = params.onBlockReply as ((payload: { text?: string }) => void) | undefined; + block?.({ text: "Hello" }); + block?.({ text: "Hello" }); + return { + payloads: [{ text: "Final message" }], + meta: {}, + }; }); + const result = await runReplyAgent(createBaseRunArgs({ onBlockReply })); + expect(onBlockReply).toHaveBeenCalledTimes(1); expect(onBlockReply.mock.calls[0][0].text).toBe("Hello"); expect(result).toBeUndefined(); @@ -152,76 +164,9 @@ describe("runReplyAgent block streaming", () => { }; }); - const typing = createMockTypingController(); - const sessionCtx = { - Provider: "discord", - OriginatingTo: "channel:C1", - AccountId: "primary", - MessageSid: "msg", - } as unknown as TemplateContext; - const resolvedQueue = { mode: "interrupt" } as unknown as QueueSettings; - const followupRun = { - prompt: "hello", - summaryLine: "hello", - enqueuedAt: Date.now(), - run: { - sessionId: "session", - sessionKey: "main", - messageProvider: "discord", - sessionFile: "/tmp/session.jsonl", - workspaceDir: "/tmp", - config: { - agents: { - defaults: { - blockStreamingCoalesce: { - minChars: 1, - maxChars: 200, - idleMs: 0, - }, - }, - }, - }, - skillsSnapshot: {}, - provider: "anthropic", - model: "claude", - thinkLevel: "low", - verboseLevel: "off", - elevatedLevel: "off", - bashElevated: { - enabled: false, - allowed: false, - defaultLevel: "off", - }, - timeoutMs: 1_000, - blockReplyBreak: "text_end", - }, - } as unknown as FollowupRun; - - const resultPromise = runReplyAgent({ - commandBody: "hello", - followupRun, - queueKey: "main", - resolvedQueue, - shouldSteer: false, - shouldFollowup: false, - isActive: false, - isStreaming: false, - opts: { onBlockReply, blockReplyTimeoutMs: 1 }, - typing, - sessionCtx, - defaultModel: "anthropic/claude-opus-4-5", - resolvedVerboseLevel: "off", - isNewSession: false, - blockStreamingEnabled: true, - blockReplyChunking: { - minChars: 1, - maxChars: 200, - breakPreference: "paragraph", - }, - resolvedBlockStreamingBreak: "text_end", - shouldInjectGroupIntro: false, - typingMode: "instant", - }); + const resultPromise = runReplyAgent( + createBaseRunArgs({ onBlockReply, blockReplyTimeoutMs: 1 }), + ); await vi.advanceTimersByTimeAsync(5); const result = await resultPromise;