From 7c7fcf46c2307a0fa0348d8af9012791eb9ebb2d Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Thu, 5 Mar 2026 10:06:47 -0800 Subject: [PATCH] Handle system timeline messages with assistant height rules - Route `system` messages through assistant height estimation - Keep user attachment height logic scoped to user messages - Add regression test for system-message sizing behavior --- .../web/src/components/timelineHeight.test.ts | 9 +++++++++ apps/web/src/components/timelineHeight.ts | 20 +++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/apps/web/src/components/timelineHeight.test.ts b/apps/web/src/components/timelineHeight.test.ts index 613b20957162a07eff62234ca85d721e211a10b1..73a21cd08d23af59f8ca14eb1b05c59cb6ae9231 100644 --- a/apps/web/src/components/timelineHeight.test.ts +++ b/apps/web/src/components/timelineHeight.test.ts @@ -12,6 +12,15 @@ describe("estimateTimelineMessageHeight", () => { ).toBe(122); }); + it("uses assistant sizing rules for system messages", () => { + expect( + estimateTimelineMessageHeight({ + role: "system", + text: "a".repeat(144), + }), + ).toBe(122); + }); + it("adds one attachment row for one or two user attachments", () => { expect( estimateTimelineMessageHeight({ diff --git a/apps/web/src/components/timelineHeight.ts b/apps/web/src/components/timelineHeight.ts index 993736789a5717509d13b20fadb1fd23bd26be09..78a5f6539b391b91658f54eab616e07eae7304d9 100644 --- a/apps/web/src/components/timelineHeight.ts +++ b/apps/web/src/components/timelineHeight.ts @@ -67,16 +67,24 @@ export function estimateTimelineMessageHeight( message: TimelineMessageHeightInput, layout: TimelineHeightEstimateLayout = { timelineWidthPx: null }, ): number { - if (message.role !== "user") { + if (message.role === "assistant") { const charsPerLine = estimateCharsPerLineForAssistant(layout.timelineWidthPx); const estimatedLines = estimateWrappedLineCount(message.text, charsPerLine); return ASSISTANT_BASE_HEIGHT_PX + estimatedLines * LINE_HEIGHT_PX; } - const charsPerLine = estimateCharsPerLineForUser(layout.timelineWidthPx); + if (message.role === "user") { + const charsPerLine = estimateCharsPerLineForUser(layout.timelineWidthPx); + const estimatedLines = estimateWrappedLineCount(message.text, charsPerLine); + const attachmentCount = message.attachments?.length ?? 0; + const attachmentRows = Math.ceil(attachmentCount / ATTACHMENTS_PER_ROW); + const attachmentHeight = attachmentRows * USER_ATTACHMENT_ROW_HEIGHT_PX; + return USER_BASE_HEIGHT_PX + estimatedLines * LINE_HEIGHT_PX + attachmentHeight; + } + + // `system` messages are not rendered in the chat timeline, but keep a stable + // explicit branch in case they are present in timeline data. + const charsPerLine = estimateCharsPerLineForAssistant(layout.timelineWidthPx); const estimatedLines = estimateWrappedLineCount(message.text, charsPerLine); - const attachmentCount = message.attachments?.length ?? 0; - const attachmentRows = Math.ceil(attachmentCount / ATTACHMENTS_PER_ROW); - const attachmentHeight = attachmentRows * USER_ATTACHMENT_ROW_HEIGHT_PX; - return USER_BASE_HEIGHT_PX + estimatedLines * LINE_HEIGHT_PX + attachmentHeight; + return ASSISTANT_BASE_HEIGHT_PX + estimatedLines * LINE_HEIGHT_PX; } -- 2.54.0