import { describe, expect, it } from "bun:test"; import { mapAgentSessionEventToAcpSessionUpdates } from "../src/modes/acp/acp-event-mapper"; import type { AgentSessionEvent } from "../src/session/agent-session"; function makeAssistantMessage(text: string) { return { role: "assistant" as const, content: [{ type: "text" as const, text }], api: "anthropic-messages" as const, provider: "anthropic" as const, model: "claude-sonnet-4-20250514", usage: { input: 10, output: 5, cacheRead: 0, cacheWrite: 0, totalTokens: 15, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }, }, stopReason: "stop" as const, timestamp: Date.now(), }; } function getChunkMessageId(event: { update: object }): string | undefined { const update = event.update as { messageId?: string | null }; return typeof update.messageId === "string" ? update.messageId : undefined; } describe("ACP event mapper", () => { it("attaches a stable messageId to live assistant chunks", () => { const assistantMessage = makeAssistantMessage("chunk"); const getMessageId = (message: unknown): string | undefined => message === assistantMessage ? "a80f1ff7-4f0a-4e6b-9f09-c94857b62a4a" : undefined; const textUpdates = mapAgentSessionEventToAcpSessionUpdates( { type: "message_update", message: assistantMessage, assistantMessageEvent: { type: "text_delta", delta: "chunk" }, } as AgentSessionEvent, "session-1", { getMessageId }, ); const thoughtUpdates = mapAgentSessionEventToAcpSessionUpdates( { type: "message_update", message: assistantMessage, assistantMessageEvent: { type: "thinking_delta", delta: "plan" }, } as AgentSessionEvent, "session-1", { getMessageId }, ); expect(textUpdates).toHaveLength(1); expect(thoughtUpdates).toHaveLength(1); expect(textUpdates[0] ? getChunkMessageId(textUpdates[0]) : undefined).toBe( "a80f1ff7-4f0a-4e6b-9f09-c94857b62a4a", ); expect(thoughtUpdates[0] ? getChunkMessageId(thoughtUpdates[0]) : undefined).toBe( "a80f1ff7-4f0a-4e6b-9f09-c94857b62a4a", ); }); });