import assert from "node:assert/strict"; import test from "node:test"; import { appendStreamingDelta, asStreamingAssistantMetadata, clearStreamingAssistantTrace, createStreamingAssistantMetadata, createStreamingAttemptState, finalizeStreamingAssistant, promoteStreamingAssistantTrace, setStreamingAssistantSegment, transitionStreamingToolCall, } from "../src/lib/chat-stream-presentation.ts"; function assistantMessage(content = "") { return { id: "temp-assistant-test", createdAt: "2026-08-30T00:00:00.000Z", role: "assistant", content, name: null, metadata: createStreamingAssistantMetadata(), }; } function metadata(messages) { return asStreamingAssistantMetadata(messages.at(-1)?.metadata); } test("a tool boundary promotes the current segment and the next delta starts the answer in its place", () => { let messages = [assistantMessage()]; let attempt = appendStreamingDelta(createStreamingAttemptState(), "I'll search for that."); messages = setStreamingAssistantSegment(messages, "temp-assistant-", attempt.segmentText); const toolTransition = transitionStreamingToolCall(attempt, { toolCallId: "search-1", status: "initiated", }); attempt = toolTransition.attempt; messages = promoteStreamingAssistantTrace(messages, "temp-assistant-", toolTransition.traceText ?? ""); assert.equal(messages.at(-1).content, ""); assert.deepEqual(metadata(messages), { kind: "streaming_assistant", ephemeralTrace: "I'll search for that.", traceRevision: 1, }); attempt = appendStreamingDelta(attempt, "Here is the answer"); messages = setStreamingAssistantSegment(messages, "temp-assistant-", attempt.segmentText); assert.equal(messages.at(-1).content, "Here is the answer"); assert.equal(metadata(messages)?.ephemeralTrace, null); messages = finalizeStreamingAssistant(messages, "temp-assistant-", "Here is the answer."); assert.equal(messages.at(-1).content, "Here is the answer."); assert.equal(metadata(messages)?.ephemeralTrace, null); }); test("a later tool round replaces the previous trace and parallel initiated calls do not erase it", () => { let messages = [assistantMessage("First trace")]; let attempt = appendStreamingDelta(createStreamingAttemptState(), "First trace"); let transition = transitionStreamingToolCall(attempt, { toolCallId: "tool-1", status: "initiated" }); attempt = transition.attempt; messages = promoteStreamingAssistantTrace(messages, "temp-assistant-", transition.traceText ?? ""); attempt = appendStreamingDelta(attempt, "I need one more lookup."); messages = setStreamingAssistantSegment(messages, "temp-assistant-", attempt.segmentText); transition = transitionStreamingToolCall(attempt, { toolCallId: "tool-2", status: "initiated" }); attempt = transition.attempt; messages = promoteStreamingAssistantTrace(messages, "temp-assistant-", transition.traceText ?? ""); assert.equal(metadata(messages)?.ephemeralTrace, "I need one more lookup."); assert.equal(metadata(messages)?.traceRevision, 2); transition = transitionStreamingToolCall(attempt, { toolCallId: "tool-3", status: "initiated" }); assert.equal(transition.startedNewToolCall, true); assert.equal(transition.traceText, null); messages = promoteStreamingAssistantTrace(messages, "temp-assistant-", transition.traceText ?? ""); assert.equal(metadata(messages)?.ephemeralTrace, "I need one more lookup."); assert.equal(metadata(messages)?.traceRevision, 2); }); test("terminal and duplicate tool events never promote or reset the in-progress segment", () => { const initial = appendStreamingDelta(createStreamingAttemptState(), "candidate"); const completed = transitionStreamingToolCall(initial, { toolCallId: "tool-1", status: "completed" }); assert.equal(completed.startedNewToolCall, false); assert.strictEqual(completed.attempt, initial); const initiated = transitionStreamingToolCall(initial, { toolCallId: "tool-1", status: "initiated" }); const withNextSegment = appendStreamingDelta(initiated.attempt, "next segment"); const duplicate = transitionStreamingToolCall(withNextSegment, { toolCallId: "tool-1", status: "initiated" }); assert.equal(duplicate.startedNewToolCall, false); assert.strictEqual(duplicate.attempt, withNextSegment); assert.equal(duplicate.attempt.segmentText, "next segment"); }); test("a fresh per-attempt accumulator can replay and reclassify an already-seen tool round", () => { let messages = [assistantMessage("stale partial answer")]; let replayAttempt = appendStreamingDelta(createStreamingAttemptState(), "Replayed trace"); messages = setStreamingAssistantSegment(messages, "temp-assistant-", replayAttempt.segmentText); const replayedTool = transitionStreamingToolCall(replayAttempt, { toolCallId: "same-tool-id", status: "initiated" }); messages = promoteStreamingAssistantTrace(messages, "temp-assistant-", replayedTool.traceText ?? ""); assert.equal(replayedTool.startedNewToolCall, true); assert.equal(messages.at(-1).content, ""); assert.equal(metadata(messages)?.ephemeralTrace, "Replayed trace"); }); test("message helpers preserve identity when no matching temporary assistant exists", () => { const messages = [ { id: "persisted-assistant", createdAt: "2026-08-30T00:00:00.000Z", role: "assistant", content: "Persisted", name: null, metadata: null, }, ]; assert.strictEqual(setStreamingAssistantSegment(messages, "temp-assistant-", "new"), messages); assert.strictEqual(promoteStreamingAssistantTrace(messages, "temp-assistant-", "trace"), messages); assert.strictEqual(finalizeStreamingAssistant(messages, "temp-assistant-", "done"), messages); assert.strictEqual(clearStreamingAssistantTrace(messages, "temp-assistant-"), messages); }); test("a terminal error clears the ephemeral trace without discarding a partial answer", () => { let messages = [ { ...assistantMessage("Partial answer"), metadata: { ...createStreamingAssistantMetadata(), ephemeralTrace: "Still checking one source.", traceRevision: 1, }, }, ]; messages = clearStreamingAssistantTrace(messages, "temp-assistant-"); assert.equal(messages.at(-1).content, "Partial answer"); assert.equal(metadata(messages)?.ephemeralTrace, null); });