AI Chat
A full streaming chat surface — Chat shell + ChatMessageList + PromptInput — wired to a SvelteKit SSE endpoint that relays a Claude/LLM stream. Client reads the response as a ReadableStream (POST body, not EventSource), appends tokens in place to the last assistant message, and stops mid-stream via an AbortController.
Live Preview
This preview replays canned answers on a timer — no network — so it is reproducible offline. The code below streams from a real SSE endpoint, but drives the same surface and the same append/abort state machine. Send a message, then scroll up mid-stream or press Stop.
Start the conversation
Send a message to watch a reply stream in.
Features
- Chat shell with pinned header, scrollable log, and pinned composer (min-h-0 chain, full height)
- ChatMessageList's stick-to-bottom engine: follows tokens at the bottom, breaks on upward scroll
- PromptInput composer with a send button that flips to Stop while a response streams
- SvelteKit +server.ts POST endpoint relaying an Anthropic stream as text/event-stream
- Client fetch + ReadableStream reader (POST body needed → not EventSource)
- In-place token append to the last assistant message (never mutate the array element)
- AbortController Stop → status "aborted"; onRegenerate / onRetry re-run the last turn
- Streaming lifecycle: streaming → complete / error / aborted
Server — the SSE endpoint
A plain SvelteKit +server.ts that relays the model
stream as text/event-stream. (The @urbicon-ui/auth package ships createStreamHandler, but that is a notification SSE fan-out — GET-only, backed by an SSEManager — not an LLM chat relay, which needs a POST body.
Write the endpoint directly, as here.)