Construa uma interface de chat de IA com streaming

Lista de mensagens, respostas em streaming, botão de parar, retry e o comportamento de scroll que faz um chat parecer certo.

Build a chat interface for an LLM-backed assistant. Front end plus a thin server route.

UI
- Message list: user and assistant bubbles, markdown rendering, code blocks with a copy button.
- Composer: auto-growing textarea, Enter sends, Shift+Enter newline, disabled while streaming.
- While streaming: token-by-token rendering, a visible stop button, and a typing indicator before the first token.
- Per message: copy, and retry on the last assistant message.
- Conversation list in a sidebar with rename and delete.

BEHAVIOUR
- Auto-scroll to the newest token only when the user is already at the bottom; otherwise show a "jump to latest" button.
- Errors render as an inline assistant message with a retry action, never as a toast that disappears.
- Stopping keeps the partial response and marks it as stopped.

RULES
- API key stays on the server.
- Handle a dropped connection mid-stream without losing earlier messages.

ACCEPTANCE CRITERIA
- Works at 360px with the composer pinned to the bottom.
- Screen reader announces new assistant messages once, not per token.