Architect Chat UI
This page documents the frontend architecture for the Architect chat experience in apps/frontend/src/app/(protected)/architect/.
The implementation pairs:
- REST session management (
ArchitectClient) - WebSocket event streaming (
useArchitectChat) - chat UI components (
ArchitectChat,ArchitectMessageBubble,StreamingIndicator)
Entry points
| Layer | File | Responsibility |
|---|---|---|
| Route | app/(protected)/architect/page.tsx | Mounts the Architect client page |
| API client | utils/api-client/architect-client.ts | CRUD for architect sessions and messages |
| Hook | hooks/useArchitectChat.ts | WebSocket subscriptions, message state, streaming state |
| Main UI | components/ArchitectChat.tsx | Layout, action buttons, loading flow, plan panel |
| Input | components/ArchitectChatInput.tsx | text input, file attachments, send behavior |
Session and message flow
The UI uses ArchitectClient REST calls for durable session state:
GET /architect/sessionsPOST /architect/sessionsGET /architect/sessions/\{id\}GET /architect/sessions/\{id\}/messages
useArchitectChat then subscribes to architect:\{session_id\} over WebSocket and merges streamed updates into local state.
WebSocket events consumed by the UI
The frontend event enum in utils/websocket/types.ts includes Architect-specific events:
architect.messagearchitect.responsearchitect.thinkingarchitect.tool_startarchitect.tool_endarchitect.plan_updatearchitect.mode_changearchitect.stream_startarchitect.text_chunkarchitect.stream_endarchitect.task_progressarchitect.error
Payloads tracked in UI state
useArchitectChat stores:
- chat messages (
ArchitectChatMessage[]) - streaming state (
isThinking,activeTools,completedTools) - current mode (
discovery,planning,creating,executing) - plan markdown snapshot
isAwaitingTaskflagautoApproveAlltoggle state
Charts arrive as charts on architect.response and are stored on the message; history reloads read them from the message’s metadata_.charts. ArchitectMessageBubble renders each one below the markdown with ArchitectChart, which maps the spec’s chart_type to an @mui/x-charts component (or a color-scaled table for heat_table) and formats axes from each measure’s kind. The spec type and the row-to-series helpers live in utils/architect/charts.ts.
Colors come from theme.chartPalettes.architect, defined per mode: neutral and neutralLine, pale teal for context, and series, four teal shades that step evenly in lightness from the accent, so they read apart without color vision. They stay lighter or darker and less saturated than the solid brand teal, which in the chat marks clickable things. The pale neutral sits below the 3:1 non-text contrast WCAG asks of chart graphics. That is deliberate: the numbers the bars show are also available as text, through the value labels on ranked bar charts and the Show data table on every chart. seriesColors and categoryColors apply the spec’s focus (the values the reply is about, in the accent) or the palette in order. The Export menu (utils/architect/chart-export.ts) writes the rows as CSV, or serializes the rendered SVG with its computed styles inlined plus a drawn title and legend, then rasterizes it to PNG; MUI X’s own export is Pro-only.
architect.task_progress payloads are routed into the same StreamingState shape used for tool calls. The hook ignores progress for other sessions, requires both task_id and label, and only attaches updates when a waiting bubble has been registered from an architect.response payload with awaiting_task: true.
Confirmation and auto-approve behavior
The backend can return needs_confirmation in architect.response.
When true, the UI attaches Accept and Change actions to the latest assistant message.
- Accept sends a confirmation message (
"Yes, go ahead."); the agent decides what that approves (see Write guard) - Change focuses the input for user edits
The UI also includes an Auto-approve switch. When enabled:
- outgoing
architect.messagepayloads includeauto_approve: true - confirmation action buttons are suppressed in the frontend as a safety check
The frontend checks autoApproveAll before rendering confirmation buttons, even if
needs_confirmation is present in a response payload.
Streaming indicators
StreamingIndicator and ToolCallList present in-flight agent activity:
- thinking dots during
architect.thinking - active tool rows during
architect.tool_start - completed tool rows with success/failure and duration on
architect.tool_end; a failed row shows the payload’serroron hover - awaited background task rows during
architect.task_progress - optional per-tool reasoning sections
ToolCallList prioritizes active tools at the top and collapses completed tools when activity is ongoing. Before rendering it drops failures that a later call of the same tool succeeded (unrecoveredTools). The collapsed summary counts the rows it hides that succeeded and that failed apart (“2 completed, 1 failed” is three calls; with no successes it reads “1 failed”) and shows an error icon instead of the check when any failed.
Task progress uses the Celery task ID as the row key. started and progress statuses render as active rows; completed and failed statuses move the row into completed activity. If step and total are present, the UI appends them to the label as progress counts.
File attachment handling
ArchitectChatInput supports multi-file attachments and sends each file as:
filenamecontent_type- base64
data size
Input constraints currently include:
- accepted file extensions configured in
ArchitectChatInput.tsx - per-file size limit of 5 MB in the client