Markdown rendering
Every assistant turn is rendered as GitHub-flavoured Markdown as the response streams. You see formatted output the moment the tokens arrive, not after the model finishes.
What works out of the box
- Headings, lists, blockquotes - standard CommonMark.
- Tables - GitHub-style pipe tables with alignment.
- Task lists - items written as
- [ ]and- [x]render as read-only checkboxes. - Strikethrough and autolinks -
~~text~~is struck through, and bare URLs become links. - Footnotes - reference markers in the text, with the definitions collected at the end of the reply.
- Math - LaTeX formulas typeset with KaTeX:
$$…$$,\(…\),\[…\], currency-safe$…$and```mathfences. See LaTeX math. - Fenced code - language-aware syntax highlighting and line numbers, plus a toolbar for open in canvas (and preview, on HTML), export and copy. A block that is still being written shows as plain text and picks up its highlighting once it’s complete. A block over 50,000 characters stays plain text, so it can’t hold up the window.
- Links - open in your default browser or mail app. Only
http,httpsandmailtolinks do anything; other schemes are ignored.
Two things are deliberately not rendered: HTML tags in a reply show as plain text, and images the model links from the web () don’t load, because the app window never fetches remote content.
Copying and selecting
Right-click any message bubble for a quick menu: Copy - the text you have selected inside that bubble, or the whole message when nothing is selected - and Select all, which highlights just the body text and leaves the metrics line and toggles out of the selection.
Each bubble also has a … menu below it for the deliberate, full-message actions: Copy message and Share on every bubble; Save as Snippet on your own prompts, plus Save attachment to Library (or attachments) on one with attached files or images; and on assistant replies Save to Library, Pin this response, Regenerate (on the last reply only) and Fork from here (unavailable while that reply is still streaming). On a reply, Copy message copies the raw Markdown, so fences and tables survive a paste into an editor. The /copy slash command does the same for the last reply, or the Nth-latest with /copy N.
Your own messages
Your own messages are not rendered as Markdown: they show exactly as you typed them, line breaks included. Bubbles that paste in dozens of lines clamp to the first ten lines with a Show more toggle (and Show less to fold them again), so the assistant’s reply does not get pushed off-screen by your own input.
Regenerate the last reply
The last assistant message in a chat carries a Regenerate action, and the /regenerate slash command does the same. Triggering it drops the existing reply, re-sends the preceding user turn - images included - and streams a fresh answer in its place. Useful when the model wanders off, hallucinates, or you just want a second take without retyping the prompt.
Only the most recent assistant message can be regenerated, and only while the chat isn’t busy. Earlier turns stay intact so the rest of the conversation history is preserved. A reply that came in through an imported conversation can’t be regenerated.
Thinking traces
For reasoning-capable models, the chain-of-thought stream is rendered into a separate block above the answer, collapsed under a Thinking header (Thinking… while it streams). Expand it to audit how the model got there, and fold it away again when you only care about the final answer. Below it, a reply that drew on Library sources carries a chip saying what it read (see the sources chip).
Tool-call blocks
When the model calls tools - whether a built-in tool or one served by an MCP server - the calls collapse into a single header above the answer, styled like the thinking block: “Called tool tool” for one call, “Called N tools” for more, “Calling tool tool…” or “Calling tools…” while they run, and “Waiting for your approval…” while a call needs your answer. Expand it to read each call’s name, arguments and result - or its error, or a Denied, No answer or Interrupted tag for a call that didn’t complete. A call that needs your approval shows an approval card above the block, and the reply waits until you answer (see Approving tool calls).