Agent chat
Running an agent through its structured protocol instead of a terminal.
An agent chat pane runs the same vendor CLI a terminal pane would — but over the tool's programmatic protocol instead of a PTY. Nothing is reimplemented and nothing is scraped: the agent streams structured events, and atrium renders them as a real transcript with approval cards, diffs, subagent drill-in, and a composer that knows what the engine can do.
Terminal panes are still first-class. Chat is the better surface when you want to read the work; the terminal is the better surface when you want the tool's own TUI.
Launching into chat
The chat/terminal choice is a surface, resolved the same way at every launch point:
- An explicit flag (
--surface chat/--surface terminal). - The launch profile's surface.
- Your per-adapter preference from the launcher.
- The adapter's capability default.
atrium agent launch <slug> --surface chat
atrium launch <slug> --surface terminal
Detached and background runs always fall back to terminal, with a warning — a chat pane needs a pane to render into. See Task dispatch for the task-side equivalent.
Transports and capabilities
Each adapter declares a chatTransport in its manifest (spec). The transport determines which affordances the pane can offer — the UI is capability-gated, so a chip or card never appears for an engine that cannot honor it.
| Adapter | Transport | Notable capabilities |
| Claude Code | claude-sdk | Checkpointing (rewind), plan mode, images, steering, subagents, background tasks |
| Codex | codex-app-server | Plan mode, images, steering, subagents, background tasks |
| Grok | acp | Steering, subagents, background tasks, command discovery |
| omp | acp | Subagents, background tasks, command discovery |
| opencode | acp | Subagents, command discovery |
| Kimi | acp | Plan mode, images, command discovery |
| cursor-agent | acp | Subagents, command discovery |
| Hermes | acp | Command discovery, context usage |
| pi | pi-rpc | Images, steering, command discovery |
The transcript
- Turn-granular virtualization keeps long sessions responsive; heights are cached and seeded on restore so scroll position survives a restart.
- Markdown, tables, and prose are rendered and sanitized (anchors forced to
noopener, style and code-execution vectors stripped). - A now line and relative timestamps under user and agent bubbles.
- Clickable URLs — open in an atrium browser pane, the system browser, or a split, with the shortcut shown on hover.
- A prompt navigation rail for jumping between your own messages.
- Search (
Cmd+F) with boundary navigation across the transcript. - Reader mode caps the column width for comfortable reading.
Tool calls
Tool calls collapse by default into work groups, and consecutive runs of them bundle into a single row — live, while streaming. File-changing tools auto-expand.
- Diffs render from the tool's own input, syntax-highlighted, with unchanged lines folded and an open-the-file affordance.
- Codex
fileChangeevents are preserved as unified patches and rendered as such. - Always show regex exceptions let you pin specific tools open.
- Subagents appear as drillable child rows with live status, a stop control, and token counts. Workflow agents show up the same way.
- Background shells drill into a terminal view of the engine's output — including shells the engine never named.
Cards
Beyond plain messages, the transcript renders typed cards:
- Approval / permission cards with exactly the options the request offered — allow once, allow for the session, or deny with a message. Tool input renders visually rather than as raw JSON.
- Question cards, with multi-question requests rendered as tabs.
- Plan cards — approve (which restores the prior permission mode before proceeding) or reject with feedback.
- Todo checklists, live.
- Memory cards for atrium memory calls, including episode and superseded metadata.
- Lifecycle cards for interrupted or errored turns, with Resume and Retry.
The composer
The chat composer shares its shell with the launcher and terminal composers, so the grammar is identical everywhere.
- Config chips — model, reasoning effort, and permission mode, edited in place and pushed to the engine over its config RPC. Capability-gated.
- A usage ring showing context consumption, with a breakdown popover and a Compact action.
- Slash commands discovered from the engine, surfaced through the same autocomplete pipeline as sigils.
- Image attachments by paste, drag, or the
+menu, as removable chips. Image-only sends are allowed; oversize images and engine rejections degrade to a notice rather than failing silently. - A changed-files panel — the live turn's digest in the composer drawer, plus a cumulative session panel you can collapse and drill into.
- Ghost-text prompt suggestions and state-aware placeholders that teach the surface, then graduate out of the way.
- A Claude Remote Control chip (Claude Code only) that surfaces inbound prompts from mobile.
Sending, queueing, and steering
- Messages send optimistically and restore your text on failure.
- Sending mid-turn queues rather than interrupting, flushing at the next tool boundary. Consecutive queued sends are preserved in order.
- Explicit
Entersends now, interrupting the turn. Escinterrupts and re-inserts your message, highlighted.- Accepted steers render as Acknowledged user turns, so you can see what the engine actually took.
Rewind
On adapters that support checkpointing (currently Claude Code), hovering a turn offers Rewind. It opens a dry-run preview first — the files it would restore and the ± line counts — and states plainly that bash side effects are not checkpointed. Rewind is disabled while streaming.
Switching to a terminal, and back
A chat pane and a terminal pane can hand the same session back and forth. The header offers the switch; atrium resumes the session natively on the other surface rather than restarting it.
Restore and resume
Chat panes persist their adapter, engine session id, transport kind, and working directory. On restart:
- The restore chooser lists them and relaunches through the transport's own resume — never by shelling out to
--resumein a PTY. - Sessions still running in the daemon are adopted: atrium re-subscribes and replays rather than launching a second copy.
- A daemon restart marks persisted sessions interrupted rather than faking liveness.
- The effective model / effort / permission config rides the resume, so your knobs never silently reset.