Behavior-only chat orchestrator (LLM-streaming module). Author supplies the DOM structure via [data-chat-messages], [data-chat-input], [data-chat-empty], [data-chat-status] elements; chat-shell wires message streaming, markdown rendering, code-block upgrades, and an LLM integration path via proxy-url (or via external submit).
Author provides the structural DOM; the shell binds the LLM streaming behavior and renders chunks into the messages container. This is the original raw-HTML authoring shape — still fully supported.
The bespoke shape uses module-namespaced custom elements per ADR-0023. Each child owns its own behavior + state attributes; queryable from outside via :has(chat-thread[streaming]).
Every queryable state is reflected on the relevant child element. Style cross-cuts via :has():
JS reads the same attributes — shell.querySelector('chat-thread').streaming. The host (<chat-shell>) propagates [streaming] to the bespoke <chat-thread> child automatically when an LLM response is in flight.
| Prop | Type | Default | Description |
|---|---|---|---|
provider | string | — | LLM provider name: anthropic | openai | google | stub. |
model | string | — | Model identifier (e.g. claude-sonnet-4-7, gpt-4o, gemini-1.5-pro). |
system | string | — | System prompt prepended to conversations. |
proxy-url | string | — | API proxy endpoint for LLM calls; enables self-contained chat without external submit handler. |
thinking | boolean | false | Enable Anthropic extended-thinking mode. |
streaming | boolean | — | Reflected — set while a response is streaming. |
| Event | Detail |
|---|---|
submit | { text, model } — fired on user message submit before LLM call begins. |
chunk | { text, role } — fired for each streaming chunk. |
complete | { text } — fired when streaming finishes. |
error | { error } — fired on LLM call failures. |
| Affordance | Author markup | What the shell does |
|---|---|---|
| Message stream | [data-chat-messages] | Each LLM chunk appended; markdown rendered; code-ui upgraded for code blocks. |
| Input submit | [data-chat-input] containing an <input-ui> | Listens for input's submit event; calls LLM via proxy-url or fires submit for external handler. |
| Empty state | [data-chat-empty] | Hidden when messages are present; shown when empty. |
| Status indicator | [data-chat-status] | Updated with streaming/idle text. |
Per ADR-0023, future releases extend the bespoke-children family to the chat cluster. Planned children:
<chat-thread> — replaces [data-chat-messages]; owns scroll-to-bottom, virtualization, message render<chat-composer> — replaces [data-chat-input]; owns file attach, autocomplete, submit-on-enter<chat-message> + <chat-message-list> — message-tier semantic markup<chat-sidebar> — conversation history rail (mirrors <admin-sidebar>)Today's data-* shape is fully supported and will continue to work alongside the bespoke vocabulary when it lands.