feat(web): add agent message comments (#1835)

* feat(web): add agent message comments

* fix(web): harden agent message comments

* fix(web): address message comment review findings

* fix(web): allow comments on legacy agent messages

* fix(web): address latest message comment review

* fix(web): address follow-up message comment review

* fix(web): address remaining message comment review

* fix(web): keep failed mobile comments open

* fix(web): preserve selections over message comments
This commit is contained in:
José Almeida
2026-07-21 13:32:19 +01:00
committed by GitHub
parent 30e6cba810
commit 8f2fe7a8e6
62 changed files with 3309 additions and 188 deletions
@@ -23,6 +23,10 @@ vi.mock("@/components/shared/markdown-components", () => ({
import { MemoizedMarkdown } from "@/components/shared/memoized-markdown";
import { __markdownParseCount, __resetMarkdownCounters } from "@/lib/markdown/normalize-cache";
import {
createMessageTextAnchor,
getMessageCommentDecorations,
} from "@/lib/chat/agent-message-comments";
type Row = { id: string; content: string };
@@ -121,4 +125,30 @@ describe("chat render-cost evals", () => {
render(<MessageList rows={rows} panel={false} />);
expect(__markdownParseCount()).toBe(1);
});
it("scenario 5: restoring many inline highlights does not reparse markdown rows", () => {
const content = Array.from({ length: 20 }, (_, index) => `reply-${index}`).join(" ");
const root = document.createElement("div");
root.textContent = content;
const comments = Array.from({ length: 20 }, (_, index) => {
const selectedText = `reply-${index}`;
const start = content.indexOf(selectedText);
return {
id: `comment-${index}`,
sessionId: "session-1",
source: "agent-message" as const,
messageId: "reply-1",
selectedText,
text: "feedback",
createdAt: "2026-07-20T00:00:00Z",
status: "pending" as const,
anchor: createMessageTextAnchor("reply-1", content, start, start + selectedText.length),
};
});
const parsesBefore = __markdownParseCount();
expect(getMessageCommentDecorations(root, comments)).toHaveLength(20);
expect(root.querySelectorAll("mark[data-agent-message-comment-id]")).toHaveLength(0);
expect(__markdownParseCount() - parsesBefore).toBe(0);
});
});