1754 lines · 53.1 KB · TypeScript
RawDownload
import { describe, expect, it } from "vite-plus/test";import { MessageId, TurnId } from "@t3tools/contracts";import {  computeStableMessagesTimelineRows,  computeMessageDurationStart,  deriveMessagesTimelineRows,  normalizeCompactToolLabel,  resolveAssistantMessageCopyState,  shouldPreserveAssistantLineBreaks,} from "./MessagesTimeline.logic"; describe("shouldPreserveAssistantLineBreaks", () => {  it("preserves Claude insight formatting without changing regular markdown", () => {    expect(      shouldPreserveAssistantLineBreaks(        "★ Insight ─────────────────\\nFirst observation\\nSecond observation\\n─────────────────",      ),    ).toBe(true);    expect(shouldPreserveAssistantLineBreaks("A normal\\nmarkdown paragraph")).toBe(false);  });}); describe("computeMessageDurationStart", () => {  it("returns message createdAt when there is no preceding user message", () => {    const result = computeMessageDurationStart([      {        id: "a1",        role: "assistant",        createdAt: "2026-01-01T00:00:05Z",        updatedAt: "2026-01-01T00:00:10Z",        streaming: false,      },    ]);    expect(result).toEqual(new Map([["a1", "2026-01-01T00:00:05Z"]]));  });   it("uses the user message createdAt for the first assistant response", () => {    const result = computeMessageDurationStart([      {        id: "u1",        role: "user",        createdAt: "2026-01-01T00:00:00Z",        updatedAt: "2026-01-01T00:00:00Z",        streaming: false,      },      {        id: "a1",        role: "assistant",        createdAt: "2026-01-01T00:00:30Z",        updatedAt: "2026-01-01T00:00:30Z",        streaming: false,      },    ]);     expect(result).toEqual(      new Map([        ["u1", "2026-01-01T00:00:00Z"],        ["a1", "2026-01-01T00:00:00Z"],      ]),    );  });   it("uses the previous completed assistant updatedAt for subsequent assistant responses", () => {    const result = computeMessageDurationStart([      {        id: "u1",        role: "user",        createdAt: "2026-01-01T00:00:00Z",        updatedAt: "2026-01-01T00:00:00Z",        streaming: false,      },      {        id: "a1",        role: "assistant",        createdAt: "2026-01-01T00:00:30Z",        updatedAt: "2026-01-01T00:00:30Z",        streaming: false,      },      {        id: "a2",        role: "assistant",        createdAt: "2026-01-01T00:00:55Z",        updatedAt: "2026-01-01T00:00:55Z",        streaming: false,      },    ]);     expect(result).toEqual(      new Map([        ["u1", "2026-01-01T00:00:00Z"],        ["a1", "2026-01-01T00:00:00Z"],        ["a2", "2026-01-01T00:00:30Z"],      ]),    );  });   it("does not advance the boundary for a streaming message", () => {    const result = computeMessageDurationStart([      {        id: "u1",        role: "user",        createdAt: "2026-01-01T00:00:00Z",        updatedAt: "2026-01-01T00:00:00Z",        streaming: false,      },      {        id: "a1",        role: "assistant",        createdAt: "2026-01-01T00:00:30Z",        updatedAt: "2026-01-01T00:00:40Z",        streaming: true,      },      {        id: "a2",        role: "assistant",        createdAt: "2026-01-01T00:00:55Z",        updatedAt: "2026-01-01T00:00:55Z",        streaming: false,      },    ]);     expect(result).toEqual(      new Map([        ["u1", "2026-01-01T00:00:00Z"],        ["a1", "2026-01-01T00:00:00Z"],        ["a2", "2026-01-01T00:00:00Z"],      ]),    );  });   it("resets the boundary on a new user message", () => {    const result = computeMessageDurationStart([      {        id: "u1",        role: "user",        createdAt: "2026-01-01T00:00:00Z",        updatedAt: "2026-01-01T00:00:00Z",        streaming: false,      },      {        id: "a1",        role: "assistant",        createdAt: "2026-01-01T00:00:30Z",        updatedAt: "2026-01-01T00:00:30Z",        streaming: false,      },      {        id: "u2",        role: "user",        createdAt: "2026-01-01T00:01:00Z",        updatedAt: "2026-01-01T00:01:00Z",        streaming: false,      },      {        id: "a2",        role: "assistant",        createdAt: "2026-01-01T00:01:20Z",        updatedAt: "2026-01-01T00:01:20Z",        streaming: false,      },    ]);     expect(result).toEqual(      new Map([        ["u1", "2026-01-01T00:00:00Z"],        ["a1", "2026-01-01T00:00:00Z"],        ["u2", "2026-01-01T00:01:00Z"],        ["a2", "2026-01-01T00:01:00Z"],      ]),    );  });   it("handles system messages without affecting the boundary", () => {    const result = computeMessageDurationStart([      {        id: "u1",        role: "user",        createdAt: "2026-01-01T00:00:00Z",        updatedAt: "2026-01-01T00:00:00Z",        streaming: false,      },      {        id: "s1",        role: "system",        createdAt: "2026-01-01T00:00:01Z",        updatedAt: "2026-01-01T00:00:01Z",        streaming: false,      },      {        id: "a1",        role: "assistant",        createdAt: "2026-01-01T00:00:30Z",        updatedAt: "2026-01-01T00:00:30Z",        streaming: false,      },    ]);     expect(result).toEqual(      new Map([        ["u1", "2026-01-01T00:00:00Z"],        ["s1", "2026-01-01T00:00:00Z"],        ["a1", "2026-01-01T00:00:00Z"],      ]),    );  });   it("returns empty map for empty input", () => {    expect(computeMessageDurationStart([])).toEqual(new Map());  });}); describe("normalizeCompactToolLabel", () => {  it("removes trailing completion wording from command labels", () => {    expect(normalizeCompactToolLabel("Ran command complete")).toBe("Ran command");  });   it("removes trailing completion wording from other labels", () => {    expect(normalizeCompactToolLabel("Read file completed")).toBe("Read file");  });}); describe("resolveAssistantMessageCopyState", () => {  it("returns enabled copy state for completed assistant messages", () => {    expect(      resolveAssistantMessageCopyState({        showCopyButton: true,        text: "Ship it",        streaming: false,      }),    ).toEqual({      text: "Ship it",      visible: true,    });  });   it("hides copy while an assistant message is still streaming", () => {    expect(      resolveAssistantMessageCopyState({        showCopyButton: true,        text: "Still streaming",        streaming: true,      }),    ).toEqual({      text: "Still streaming",      visible: false,    });  });   it("hides copy for empty completed assistant messages", () => {    expect(      resolveAssistantMessageCopyState({        showCopyButton: true,        text: "   ",        streaming: false,      }),    ).toEqual({      text: null,      visible: false,    });  });   it("hides copy for non-terminal assistant messages", () => {    expect(      resolveAssistantMessageCopyState({        showCopyButton: false,        text: "Interim thought",        streaming: false,      }),    ).toEqual({      text: "Interim thought",      visible: false,    });  });   it("copies the rendered representation of Codex directives", () => {    expect(      resolveAssistantMessageCopyState({        showCopyButton: true,        text: [          'Created :codex-file-citation{path="outputs/report.xlsx" purpose="output"}.',          "",          '::artifact-template{skill_name="artifact-template-hello-world" skill_directory="/Users/test/.codex/skills/artifact-template-hello-world" display_name="Hello World" artifact_kind="document"}',        ].join("\n"),        streaming: false,      }),    ).toEqual({      text: "Created [report.xlsx](<outputs/report.xlsx>).\n\nHello World (Document template)",      visible: true,    });  });}); describe("deriveMessagesTimelineRows", () => {  it("only enables assistant copy for the terminal assistant message in a turn", () => {    const rows = deriveMessagesTimelineRows({      timelineEntries: [        {          id: "user-1-entry",          kind: "message",          createdAt: "2026-01-01T00:00:00Z",          message: {            id: "user-1" as never,            role: "user",            text: "Write a poem",            turnId: null,            createdAt: "2026-01-01T00:00:00Z",            updatedAt: "2026-01-01T00:00:00Z",            streaming: false,          },        },        {          id: "assistant-thought-entry",          kind: "message",          createdAt: "2026-01-01T00:00:10Z",          message: {            id: "assistant-thought" as never,            role: "assistant",            text: "I should ground this first.",            turnId: "turn-1" as never,            createdAt: "2026-01-01T00:00:10Z",            updatedAt: "2026-01-01T00:00:11Z",            streaming: false,          },        },        {          id: "assistant-final-entry",          kind: "message",          createdAt: "2026-01-01T00:00:20Z",          message: {            id: "assistant-final" as never,            role: "assistant",            text: "Here is the poem.",            turnId: "turn-1" as never,            createdAt: "2026-01-01T00:00:20Z",            updatedAt: "2026-01-01T00:00:30Z",            streaming: false,          },        },      ],      expandedTurnIds: new Set(["turn-1" as never]),      isWorking: false,      activeTurnStartedAt: null,      turnDiffSummaryByAssistantMessageId: new Map(),      revertTurnCountByUserMessageId: new Map(),    });     const assistantRows = rows.filter(      (row): row is Extract<(typeof rows)[number], { kind: "message" }> =>        row.kind === "message" && row.message.role === "assistant",    );     expect(assistantRows).toHaveLength(2);    expect(assistantRows[0]?.showAssistantCopyButton).toBe(false);    expect(assistantRows[1]?.showAssistantCopyButton).toBe(true);  });   it("marks only the active assistant turn as streaming for copy controls", () => {    const rows = deriveMessagesTimelineRows({      timelineEntries: [        {          id: "assistant-one-entry",          kind: "message",          createdAt: "2026-01-01T00:00:10Z",          message: {            id: "assistant-one" as never,            role: "assistant",            text: "Earlier response.",            turnId: "turn-1" as never,            createdAt: "2026-01-01T00:00:10Z",            updatedAt: "2026-01-01T00:00:11Z",            streaming: false,          },        },        {          id: "assistant-two-entry",          kind: "message",          createdAt: "2026-01-01T00:00:20Z",          message: {            id: "assistant-two" as never,            role: "assistant",            text: "Active response.",            turnId: "turn-2" as never,            createdAt: "2026-01-01T00:00:20Z",            updatedAt: "2026-01-01T00:00:30Z",            streaming: false,          },        },      ],      latestTurn: {        turnId: "turn-2" as never,        state: "running",        startedAt: "2026-01-01T00:00:19Z",        completedAt: null,      },      isWorking: false,      activeTurnStartedAt: null,      turnDiffSummaryByAssistantMessageId: new Map(),      revertTurnCountByUserMessageId: new Map(),    });     const assistantRows = rows.filter(      (row): row is Extract<(typeof rows)[number], { kind: "message" }> =>        row.kind === "message" && row.message.role === "assistant",    );     expect(assistantRows[0]?.assistantCopyStreaming).toBe(false);    expect(assistantRows[1]?.assistantCopyStreaming).toBe(true);  });   it("projects assistant diff summaries and user revert counts onto the affected rows", () => {    const assistantTurnDiffSummary = {      turnId: "turn-1" as never,      completedAt: "2026-01-01T00:00:30Z",      assistantMessageId: "assistant-1" as never,      checkpointTurnCount: 2,      checkpointRef: "checkpoint-1" as never,      status: "ready" as const,      files: [{ path: "src/index.ts", kind: "modified", additions: 3, deletions: 1 }],    };     const rows = deriveMessagesTimelineRows({      timelineEntries: [        {          id: "user-entry",          kind: "message",          createdAt: "2026-01-01T00:00:00Z",          message: {            id: "user-1" as never,            role: "user",            text: "Do the thing",            turnId: null,            createdAt: "2026-01-01T00:00:00Z",            updatedAt: "2026-01-01T00:00:00Z",            streaming: false,          },        },        {          id: "assistant-entry",          kind: "message",          createdAt: "2026-01-01T00:00:20Z",          message: {            id: "assistant-1" as never,            role: "assistant",            text: "Done",            turnId: "turn-1" as never,            createdAt: "2026-01-01T00:00:20Z",            updatedAt: "2026-01-01T00:00:30Z",            streaming: false,          },        },      ],      isWorking: false,      activeTurnStartedAt: null,      turnDiffSummaryByAssistantMessageId: new Map([        ["assistant-1" as never, assistantTurnDiffSummary],      ]),      revertTurnCountByUserMessageId: new Map([["user-1" as never, 1]]),    });     const userRow = rows.find(      (row): row is Extract<(typeof rows)[number], { kind: "message" }> =>        row.kind === "message" && row.message.role === "user",    );    const assistantRow = rows.find(      (row): row is Extract<(typeof rows)[number], { kind: "message" }> =>        row.kind === "message" && row.message.role === "assistant",    );     expect(userRow?.revertTurnCount).toBe(1);    expect(assistantRow?.assistantTurnDiffSummary).toBe(assistantTurnDiffSummary);  });   it("folds the first assistant message and settled work before the terminal response", () => {    const timelineEntries = [      {        id: "user-entry",        kind: "message" as const,        createdAt: "2026-01-01T00:00:00Z",        message: {          id: "user-1" as never,          role: "user" as const,          text: "Build it",          turnId: null,          createdAt: "2026-01-01T00:00:00Z",          updatedAt: "2026-01-01T00:00:00Z",          streaming: false,        },      },      {        id: "assistant-first-entry",        kind: "message" as const,        createdAt: "2026-01-01T00:00:05Z",        message: {          id: "assistant-first" as never,          role: "assistant" as const,          text: "Synthetic deployment checklist\n1. Confirm the deployment is ready.",          turnId: "turn-1" as never,          createdAt: "2026-01-01T00:00:05Z",          updatedAt: "2026-01-01T00:00:06Z",          streaming: false,

Lines 1–500 of 1754.