Transcript: a sent prompt of megabytes never freezes the chat (literal, collapsed to its head)
Leo, 2026-10-31: "surface_id=tab_c487e18b4f0083b34190540cd40eaa7a this is completely hardlocked bc of message size"
The transport side of this ask has already landed: #29670 (acpmux message limit 15 MiB ā 31 MiB), #28754 (a chat whose records add up past one message still opens), #28778 (an oversized prompt or chat is never retried unchanged), #29500 (a prompt's attachments never add up past one message). This PR covers the render side: a chat that holds a prompt of megabytes no longer freezes the pane once it opens.
Before
A sent prompt draws through PromptText. A long prompt is collapsed with CSS only, so the whole text is still rendered: it goes through Markdown when it looks like Markdown, gets a URL scan, and softBreaks adds a <wbr> after every / - _ . : = & ? # @ , in each long token. For a multi-MB paste or a base64 blob that means hundreds of thousands of DOM nodes, laid out on the main thread for text the clamp hides. The row estimate (model.ts) also lexed or prepared the whole text.
After
- A prompt longer than
HUGE_PROMPT_CHARS(200k characters) draws as one literal text node: no Markdown, no link scan, no break points. - While collapsed, it renders only its first
HUGE_PROMPT_HEAD_CHARS(4,000 characters, which is well over ten lines at any width). Show more renders the whole text, still as one text node. Copy, Edit, Retry and Find still use the whole prompt (Find opens it on a match, as before). - The row estimate for a huge prompt is its collapsed height (ten lines plus Show more), the same height any long prompt gets, without lexing or measuring the text.
- Prompts under 200k characters are unchanged.
Tests
conversation/hugePrompt.test.tsx: checks that a huge Markdown-shaped part renders literally with no <wbr>, a 5 MiB blob renders only its head while collapsed, the head never splits a surrogate pair, and a 20 MiB prompt's row estimate matches a long prompt's collapsed height in under 500 ms.
Risk
Low. The change is limited to the sent-prompt bubble and its row estimate, and it only applies to prompts over 200k characters. A huge prompt that is Markdown now shows as plain text, which is intended.
Agent session: agent session
š¤ Generated with Claude Code