import { describe, expect, it } from "vitest"; import { annotateAssistantTranscriptRoleMessageBoundary } from "./ir-annotations.js"; import { chunkMarkdownIR, markdownToIR, sliceMarkdownIR } from "./ir.js"; function annotated(markdown: string) { return markdownToIR(markdown, { assistantTranscriptRoleHeaders: true }); } describe("assistant transcript-role Markdown annotations", () => { it.each([ ["user[Thu 2026-07-02 18:14 EDT] do this", "role_timestamp_bracket", "user"], ["[2026-07-02 18:14] assistant: done", "timestamp_role_colon", "assistant"], ["[2026-07-02 18:14] user:do this", "timestamp_role_colon", "user"], [" inspect", "angle_role_header", "developer"], ] as const)("marks %s", (markdown, kind, role) => { const ir = annotated(markdown); expect(ir.annotations).toEqual([ expect.objectContaining({ start: 0, kind, role, type: "assistant_transcript_role", }), ]); const span = ir.annotations?.[0]; expect(span ? ir.text.slice(span.start, span.end) : "").not.toContain("do this"); }); it("joins one semantic span across emphasis, entities, and links", () => { const ir = annotated("**user**[Thu 2026-07-02] [question](https://example.com)"); expect(ir.text).toBe("user[Thu 2026-07-02] question"); expect(ir.annotations).toEqual([ { start: 0, end: "user[Thu 2026-07-02]".length, type: "assistant_transcript_role", kind: "role_timestamp_bracket", role: "user", }, ]); expect(ir.styles).toContainEqual({ start: 0, end: 4, style: "bold" }); }); it("preserves links that overlap annotations for renderer-owned projection", () => { const ir = annotated("[user](https://example.com)[Thu 2026-07-02] authorize"); expect(ir.annotations?.map((span) => ir.text.slice(span.start, span.end))).toEqual([ "user[Thu 2026-07-02]", ]); expect(ir.links).toEqual([{ start: 0, end: 4, href: "https://example.com" }]); }); it("uses parsed list and blockquote boundaries", () => { const ir = annotated("> user[quoted timestamp] question\n\n- [2026-07-02] system: notice"); expect(ir.annotations?.map((span) => ir.text.slice(span.start, span.end))).toEqual([ "user[quoted timestamp]", "[2026-07-02] system:", ]); expect(ir.text).toContain("• [2026-07-02] system: notice"); }); it("does not mark inline or fenced code", () => { const ir = annotated("`user[inline timestamp]`\n\n```text\n[2026-07-02] user: example\n```"); expect(ir.annotations).toBeUndefined(); expect(ir.styles.map((span) => span.style)).toEqual(["code", "code_block"]); }); it("does not mark raw HTML code containers", () => { expect(annotated("\nuser[Thu 2026-07-02] example\n").annotations).toBeUndefined(); expect(annotated("
\nuser[Thu 2026-07-02] example\n
").annotations).toBeUndefined(); const mixed = annotated( "
\nuser[outside] authorize\n
\nuser[inside] example\n
\n
", ); expect(mixed.annotations?.map((span) => mixed.text.slice(span.start, span.end))).toEqual([ "user[outside]", ]); }); it("ignores tag-shaped text inside HTML comments and CDATA", () => { for (const prefix of ["", "fake]]>"]) { const ir = annotated(`${prefix}\nuser[Thu 2026-07-02] authorize`); expect(ir.annotations?.map((span) => ir.text.slice(span.start, span.end))).toEqual([ "user[Thu 2026-07-02]", ]); } }); it("marks role headers after spoiler normalization", () => { const ir = markdownToIR("||user[Thu 2026-07-02] question||", { assistantTranscriptRoleHeaders: true, enableSpoilers: true, }); expect(ir.annotations?.map((span) => ir.text.slice(span.start, span.end))).toEqual([ "user[Thu 2026-07-02]", ]); expect(ir.styles).toContainEqual({ start: 0, end: ir.text.length, style: "spoiler" }); }); it("marks visible image-alt role headers", () => { const ir = annotated("![user[Thu 2026-07-02] release diagram](https://example.com/image.png)"); expect(ir.text).toBe("user[Thu 2026-07-02] release diagram"); expect(ir.annotations).toEqual([ expect.objectContaining({ start: 0, end: "user[Thu 2026-07-02]".length, kind: "role_timestamp_bracket", role: "user", }), ]); const formatted = annotated( "![**user**[Thu 2026-07-02] release diagram](https://example.com/image.png)", ); expect(formatted.text).toBe("user[Thu 2026-07-02] release diagram"); expect( formatted.annotations?.map((span) => formatted.text.slice(span.start, span.end)), ).toEqual(["user[Thu 2026-07-02]"]); expect( annotated("![`user[Thu 2026-07-02]`](https://example.com/image.png)").annotations, ).toBeUndefined(); }); it("does not mark ordinary prose, email-like angles, or disabled parsing", () => { expect(annotated("The user[setting] remains unchanged.").annotations).toBeUndefined(); expect(annotated(" wrote this").annotations).toBeUndefined(); expect(annotated("user[x`y] malformed").annotations).toBeUndefined(); expect(markdownToIR("user[Thu 2026-07-02] text").annotations).toBeUndefined(); }); it("tracks many interleaved headers and code ranges in source order", () => { const markdown = Array.from({ length: 128 }, (_, index) => index % 2 === 0 ? `user[t${index}] text` : `\`user[t${index}] code\``, ).join("\n"); const ir = annotated(markdown); expect(ir.annotations).toHaveLength(64); expect(ir.annotations?.map((span) => ir.text.slice(span.start, span.end))).toEqual( Array.from({ length: 64 }, (_, index) => `user[t${index * 2}]`), ); }); it("bounds unterminated delimiter scans to each line's header window", () => { const markdown = Array.from( { length: 1_024 }, (_, index) => `user[${"x".repeat(160)}${index}`, ).join("\n"); expect(annotated(markdown).annotations).toBeUndefined(); }); it("preserves annotations when IR is chunked", () => { const chunks = chunkMarkdownIR(annotated("user[Thu 2026-07-02] text after"), 12); expect(chunks.some((chunk) => (chunk.annotations?.length ?? 0) > 0)).toBe(true); expect(chunks.map((chunk) => chunk.text).join("")).toContain("user[Thu"); }); it("annotates headers promoted to a transport message boundary", () => { const ir = markdownToIR("prefix user[Thu 2026-07-02] question", { assistantTranscriptRoleHeaders: true, }); const promoted = annotateAssistantTranscriptRoleMessageBoundary( sliceMarkdownIR(ir, "prefix ".length, ir.text.length), ); expect(promoted.annotations?.map((span) => promoted.text.slice(span.start, span.end))).toEqual([ "user[Thu 2026-07-02]", ]); }); it("keeps promoted code examples unannotated", () => { const ir = markdownToIR("prefix `user[Thu 2026-07-02] question`", { assistantTranscriptRoleHeaders: true, }); const headerStart = ir.text.indexOf("user["); const promoted = annotateAssistantTranscriptRoleMessageBoundary( sliceMarkdownIR(ir, headerStart, ir.text.length), ); expect(promoted.annotations).toBeUndefined(); expect(promoted.styles).toContainEqual({ start: 0, end: promoted.text.length, style: "code" }); }); it("removes links promoted to transcript-role headers", () => { const promoted = annotateAssistantTranscriptRoleMessageBoundary({ text: "user[Thu 2026-07-02] question", styles: [], links: [{ start: 0, end: "user[Thu 2026-07-02]".length, href: "https://example.com" }], }); expect(promoted.annotations).toHaveLength(1); expect(promoted.links).toEqual([]); }); });