Chat
The planning chat surface where the agent reads, drafts, and edits your records, runs code in a sandbox, kicks off Flows, and stays coherent across long sessions. The conversational surface where the work actually happens.
When you want the agent to do something with your work, you open Chat. Chat is the multi-turn planning surface where the agent reads what is in front of it, drafts new plans, edits an existing spec, runs a tool inside the sandbox, or kicks off a Flow on your behalf. The conversation can run for one turn or one hundred; it can hold a paused tool call across a tab close and pick up where it left off; it can hand the work off to a background task when a step takes longer than you want to watch. The agent has the tools to act on your real records.
Chat is the planning sibling to Ask. Ask is the read-only surface where the agent answers questions without touching anything. Chat is where the agent does the work.
Chat vs Ask at a glance
The two surfaces share the same conversational shape and the same underlying chat infrastructure. They differ in the ceiling.
| Chat | Ask | |
|---|---|---|
| Where it lives | Resizable drawer on every initiative and plan detail page; also on platform-configuration records | Its own area in the navigation |
| Conversation kind | coding (planning) or platform-surface, both fixed at creation | inquiry, fixed at creation |
| Tool ceiling | Full agent tool set plus the sandbox primitives, MCP, and managed commands | Six tools, read-only by construction |
| Mutation | The agent writes files; the platform reconciles after the turn | None |
| Long-running work | start_flow, send-to-background | None |
| Best for | Draft, edit, run code, launch Flows | Ask the codebase, ask the records, tie the two together |
The same conversational shape; different ceilings.
Where Chat lives
Initiative and plan detail pages each carry a chat panel. The panel is a resizable, persistent drawer anchored to the right edge of the viewport; you click the chat icon in the page header to open it, you drag the left edge to resize it (the platform persists your width to localStorage so it sticks across navigations), and a fullscreen toggle expands it to take over the page when you want a wider canvas. The minimum width is 420 pixels and the maximum is 70 percent of the viewport. Bug detail pages do not carry their own chat panel today; chat actions started from a bug page route to the parent plan's chat with the bug context threaded in, so the planning surface stays anchored to the parent plan. A chat is anchored to the record you opened it on, which means the agent sees that record (the body, the status, the metadata) without you having to paste it in.
Platform configuration surfaces carry their own chat panels too, with a tool surface tuned for editing those platform records. The same panel renders both planning chats and platform chats; the surface a chat is on (planning vs platform) is fixed at conversation creation and determines which tool catalog the agent receives.
Skills, Agent Instructions, MCP server configurations, and sandbox profiles all carry chat panels too. A platform-surface chat is shaped for editing those records: it does not get start_flow or fetch_related_planning_artifacts, and it does get a 27-tool authoring catalog including a 13-tool typed-delta suite for sandbox-profile authoring (addSandboxProfileRepo, setSandboxProfileRuntime, setSandboxProfileEnvVar, validateSandboxProfile, testSandboxProfile, finalizeSandboxProfile, and so on). The conversation's surface is fixed at creation; a planning chat cannot pivot into a platform chat mid-life and vice versa.
A finished chat shows up in the unified Sessions list alongside Ask conversations, Flow runs, and background tasks. The Sessions index gives you one place to scan everything active across your team; clicking a chat row opens its read-only transcript view with the aggregate cost summary, the model badge, and a button to launch the same conversation in the desktop IDE when you want to keep working in your editor.
A chat turn, end to end
A chat turn is the unit of work between you hitting Send and the agent finishing its reply.
- You send a message. The text, plus any image or text attachments, lands at the platform. The platform validates the message, the conversation context, and the scope IDs (which record the chat is anchored to). If the conversation has a
pendingToolCallfrom a previous turn, your message is wrapped as the answer to that paused tool call so the agent continues exactly where it stopped. - The platform routes the turn to the agent. If a previous turn already started a sidecar SDK session in the same sandbox, the platform fast-resumes onto that session so the agent keeps its working memory of the conversation. If not (a fresh conversation, a sandbox that was destroyed, a sidecar session that was lost), the platform spins up the sandbox, resolves the model and runtime cascade, builds a system prompt with the prior conversation messages concatenated in, and starts a new SDK session.
- The agent thinks and acts. The agent reads the system prompt and the latest user message, decides whether it needs to call any tools, and starts streaming. Every tool call streams back to your chat panel as a tool-call card you can expand or collapse; the agent waits for the tool result; the result streams back; the agent decides what to do next. A single turn can include many tool calls. The turn ends when the agent stops calling tools and emits its final text response.
- The platform reconciles. After the turn finishes, the platform sweeps the sandbox workspace for changes the agent wrote and reconciles them back into the planning records. Version history rows are written, audit log entries are emitted, and SSE events broadcast so every connected client picks up the new state.
Most real turns finish in two to six tool calls. The 30-iteration cap is a backstop documented in Limits below.
A simple turn, walked through
Sarah opens the chat panel on the CSV download button plan and types:
Fix the typo on the third acceptance criterion. "Downlaod" should be "download."
She hits Send. The agent reads the plan body (already in the system prompt) and calls the Edit tool once on the plan's Markdown file with old: "Downlaod" and new: "download". The Edit tool returns success; the chat panel shows the tool call as a collapsed card with a green status dot in the timeline gutter; the agent emits a one-line text response confirming the fix. The turn ends. The platform's post-turn sweep detects the changed plan file, writes a new version-history row on the plan with editSource: ai, and the next render of the plan body shows the corrected spelling.
One user message, one agent call, one tool invocation, one reconciliation. That is the turn loop at its smallest. The Sarah end-to-end scenario later in this page shows the same loop at its widest, with multiple tool calls, a Flow kickoff, a tab close, and a checkpoint approval.
The tool surface the agent gets in chat
The agent in a planning chat has a tool catalog built per turn against your conversation's surface. The catalog below is the planning-chat (project-surface) set; a platform-surface chat gets the authoring catalog described in the Note above, which excludes start_flow and fetch_related_planning_artifacts. The architecture of that surface, the four kinds of tools and the gate every authoring write passes, is in the agent runtime and tool surface.
Platform tools
| Tool | Category | What it does |
|---|---|---|
ask_user | Pause | Pause the turn with a 2-4 option question; your pick continues the turn. |
present_plan | Pause | Pause the turn with a structured plan card for Approve / Reject. |
fetch_related_planning_artifacts | Read | Read the anchor record plus the related-context graph; capped at six calls per turn. Planning-surface only. |
start_flow | Orchestration | Start a Flow run; the Flow runs in the background while the chat continues. Planning-surface only. |
request_credential_lease | Credentials | Preflight a just-in-time credential grant; returns a leaseId and an expiresAt, with audit-log rows at request / grant / deny. The credential itself is delivered to a profile-defined managed command at execution time, not back to the agent. |
managed_command_exec | Managed commands | Run a workspace-level command (build, test, lint, run) the sandbox profile declares. Three enforcement modes: advisory (model sees commands as hints), redirect-known (model is told to prefer the managed command for known invocations), strict-command (raw Bash is removed and the model can only invoke the managed registry; per-server MCP allowlists also become mandatory under strict mode). |
fanout_spawnAgents, fanout_waitForAgents, fanout_reportResult | Fan-out | Spawn up to twenty sub-agents on the same parent sandbox. Planning-surface only; cannot recursively spawn from inside a sub-agent. |
| MCP per-server tools | Integrations | Whatever the MCP server allowlist exposes. An empty allowlist passes every tool the server publishes (except under strict-command, which requires explicit allowlists). |
Sandbox primitives
The sandbox primitives are SDK-level tools the agent runs inside the per-session sandbox via the sidecar. They ship for planning chats; the Bash primitive is removed from the allowlist when the profile's command-enforcement mode is strict-command.
| Tool | What it does | UI notes |
|---|---|---|
Read | Read a file from the sandbox-mounted workspace. | Card shows file path; no inline rendering. |
Write | Write a new file to the workspace. | Card shows the new file's content as the diff. |
Edit | Make a targeted change to an existing file. | Card shows an inline diff of the change. |
Bash | Run a shell command in the sandbox. | Removed entirely under strict-command. |
Grep | Search the workspace by pattern. | Card shows pattern + match list. |
Glob | Enumerate files matching a path pattern. | Card shows pattern + matched paths. |
WebFetch | Retrieve content from a URL. | Card shows URL + body preview with a copy button. |
TodoWrite | Track the agent's own working todos. | Card renders the checklist with completion indicators. |
How the agent changes a record
Disco Parrot's planning records are not mutated through direct API tools the agent calls. The agent works in a regular workspace with files; the platform reconciles the file changes back into records after the turn. The design choice is deliberate, and it shapes everything else about how chat works.
The agent writes or edits Markdown files in the sandbox-mounted workspace; after the turn finishes, the platform sweeps the workspace, detects which files moved, and reconciles the changes into planning records: a new initiative file becomes a new InitiativeRecord, an edited plan body becomes a new version row on the existing PlanRecord, an added open-question becomes part of the next snapshot. Version history rows are written with editSource: ai; audit log entries are emitted; the SSE stream tells every connected client to refresh.
The model has two practical consequences worth knowing. First, the agent's working material is files, so the change is reviewable as a diff before the next reconciliation runs; the chat panel renders an edit card showing exactly what changed. You see the version-history row appear in the right-rail History section on the record's detail page within seconds of the turn ending; if your tenant's notification rules listen for editSource: ai, the team gets notified. Second, the reconciliation runs once per turn after the agent finishes, which means a record's version-history row reflects the editorial state at the end of the turn, not the intermediate states the agent passed through. A turn that edited the spec twice produces one new version, not two.
The file-write-then-reconcile shape is also what makes the version history and audit trail honest about AI edits. Because the platform writes the version row in the reconciliation step rather than at the API layer, every agent-driven save is tagged with editSource: ai at the source; the workspace audit log filter for AI edits returns exactly the rows the agent produced.
Attachments
You can drag and drop, paste, or pick files into the chat input. A message can carry up to five attachments, ten megabytes each. The supported extensions are the common code, configuration, document, and image formats: .txt, .md, .tsx, .ts, .jsx, .js, .json, .css, .html, .xml, .yaml, .yml, .csv, .py, .go, .rs, .java, .c, .cpp, .h, .sql, .sh, .png, .jpg, .jpeg, .gif, .svg, .webp.
| Attachment type | How it reaches the agent |
|---|---|
Image (.png, .jpg, .svg, etc.) | Inline multimodal content block on the user message; the agent sees it as part of the prompt. |
Text and code (.md, .tsx, .json, etc.) | Forwarded through the SDK's attachment channel; the content is available to the agent's reasoning without occupying sandbox file slots. |
The status-scoped slash menu
Type / in the chat input and a menu opens with the skills bound to the record's current status. The menu is the same registry the action launcher reads; whatever your tenant's admin has bound to "Plan in In progress" on the Plan workflow is what appears in the slash menu for a plan currently sitting at In progress. Curating those bindings, and writing the skills behind them, is covered on the Skills page.
Pick a skill and the input changes shape. The selected command appears as a Fluent Badge anchored above the textarea (with a dismiss icon to clear it if you change your mind); the textarea stays empty for you to type the prose that becomes the skill's $ARGUMENTS substitution. When you hit Send, the platform receives both the command slug and your prose as separate fields, resolves the skill's template server-side, and runs the agent with the assembled prompt.
The slash menu's catalog is layered. The tenant's resolved command registry (built-in skills plus tenant-authored plus user-scoped) is filtered by the active integrations, the sandbox profile's commandSlugs allowlist, and the session's status-skill bindings before the menu renders. Until the resolver returns, the menu shows the four built-in defaults (/plan, /implement, /verify, /review) as the offline fallback so you can start typing immediately; after the resolver returns, the menu reflects whatever your tenant has registered, filtered for the current status.
The slash menu reads the same (entity, status) registry the action launcher reads. An admin who binds a new skill to the Plan workflow's In-progress status via Customizing workflows sees that skill in the slash menu on every plan in In-progress the next time the chat panel opens.
The status-skill bindings are resolved when the chat opens; the resolver freezes on the first non-empty status value to avoid the slash menu silently swapping mid-conversation if the entity's status changes underneath the agent. If you want the menu to refresh against a new status, close and reopen the chat panel.
Starting a Flow from chat
start_flow is a chat tool, which means the agent can kick off a Flow when the conversation calls for it. A common shape: you ask the agent to implement a plan; the agent decides the right move is the sdlc-full Flow on the plan; it calls start_flow with the parameters; the platform launches the Flow as a background runner; the chat panel shows a Flow progress overlay tracking the run. You can keep chatting in the same conversation while the Flow proceeds; when the Flow finishes the overlay appends a completion message to the transcript locally so you see the outcome in line.
The Flow runs as its own run, not as part of the chat turn. It has its own session in the Sessions index, its own checkpoint surface, and its own audit trail. Run a Flow & manage checkpoints covers the run from the other side; Build a Flow is where the Flow the agent starts was authored.
Cancelling the chat does not cancel the Flow; cancelling the Flow does not cancel the chat. The two are linked through the conversation's activeFlowInstanceId field so the chat panel can render the overlay, and the chat's completion message is appended locally to the transcript when the overlay receives the Flow's terminal event. The Flow's own checkpoint records, version-history rows, and audit log entries are the canonical source of truth for what the Flow did; the chat overlay is the local view.
Send-to-background, Stop, and end
A chat turn has three exits while it is running, plus one lifecycle gesture for ending the conversation.
Once a turn is backgrounded, the platform auto-resolves four host tools so the agent does not hang waiting for input that is not coming:
| Tool | What happens on background |
|---|---|
present_plan | Auto-approves with "Approved, proceed with the plan." |
ask_user | Auto-answers with "Proceed with your best judgment." |
commands_beginMcpServerOAuth | Fails with session_backgrounded. |
commands_finalizeSandboxProfile | Fails with session_backgrounded. |
Backgrounding is the right move for long-running work that does not need your input; it is the wrong move for work that does. The Background button is hidden when a tool call is already paused, so you cannot accidentally send a paused turn to background; the trade-off only kicks in when the agent is actively running and reaches a pause tool after you have left.
Send-to-background is the cloud-arrow-up icon next to the chat input; it appears while a turn is actively streaming and is not currently paused on a tool call. Click it and the platform converts the in-flight turn into a background task: the conversation's sandbox is re-keyed from chat- to background-, a task record is created, and the agent continues running with its output flowing to the task-progress SSE channel instead of the open chat panel. You can come back to the conversation later by resuming the task from the Background tasks panel; the chat reopens with the same SDK session, the same sandbox, and the same conversation state. Send-to-background requires the chat.background.manage scope, which is separate from the standard chat.use.
Stop is the dismiss-icon button next to Send while a turn is streaming; click it and the platform aborts the agent loop server-side. The turn ends; any tool calls already in flight finish or error; the next user message starts a fresh turn. Stop is the cancel-this-turn gesture; it does not end the conversation.
End the conversation is the Delete action on the conversation detail page (or the page header on the chat-detail transcript view). Delete soft-ends the conversation: it sets endedAt, releases the per-conversation sandbox, and clears any pendingToolCall. A POST to a soft-ended conversation returns HTTP 410 with the hint "Start a new chat to continue this work." The conversation row stays in Sessions for history; the chat itself is over.
A chat survives a tab close, a network blip, or a deploy
Three kinds of recovery keep a chat coherent across the small disruptions of a workday.
A paused tool call survives a tab close (for 30 minutes)
When the agent calls ask_user, present_plan, or any other pause tool, the platform persists the pendingToolCall on the conversation record before the turn parks, with a expiresAt stamp 30 minutes out. Close the tab; come back inside 30 minutes; the chat reopens with the question (or the plan) ready for you to answer. Your reply continues the same turn on the same SDK session, with the agent's working memory intact. If you come back after the TTL expires, the resume is rejected and the next message starts a fresh turn; the conversation is preserved, but the specific paused turn does not pick up where it left off. The pause is durable for half an hour, not forever.
A live turn survives a network blip
While a turn is streaming, the platform persists an activeStream cursor record so a brief disconnect does not abort the run. When your client reconnects, the chat panel sends the last cursor it saw; the platform reattaches to the existing dispatch and replays the events you missed. The turn continues live; you see the text fill in where it left off; tool calls keep streaming. The cursor-and-replay mechanism behind this is described in real-time architecture.
A turn that lost its SDK session restarts on history-in-prompt
If the sandbox or sidecar SDK session is missing when a new turn arrives (a fresh conversation, a sandbox that was destroyed, a deploy that interrupted the runner), the platform falls back to history-in-prompt continuation: a new SDK session is started with the prior conversation messages concatenated into the system prompt so the agent's context survives the interruption. The chat panel shows the turn restart cleanly; the agent's working memory is rebuilt from the persisted conversation rather than from the in-memory session.
The chat panel UI
The panel renders the streaming agent output as it arrives. The patterns:
- Tool calls render as collapsible cards. Tool calls render collapsed by default, with a tool icon, a tool name, and a short label on the header row; expand to see the input parameters and the output result. The card's status is communicated by a colored dot in the timeline gutter beside the card: active while the tool is running, success when it returns, error when it fails. Edit tool calls render an inline diff preview inside the card; Write tool calls render the new file content the agent wrote.
- WebFetch tool calls render a card showing the URL and a body preview. The agent's web fetches are visible at a glance; nothing pulls in remote content without a record.
- TodoWrite tool calls render the agent's todo list inline. A complex turn that breaks itself into steps surfaces those steps in the chat so you can see the agent's plan-of-attack.
- Errors render with an error state on the card and, where appropriate, a sandbox-status banner above the conversation explaining what went wrong (a denied MCP credential, a managed-command policy block, an MCP server that came up unauthenticated).
- The model the agent ran as is shown as a timeline entry. Above each assistant turn, the chat renders a small caption with the SDK runtime and the model id (for example,
/plan · Claude · claude-sonnet-4-20250514). The default when your tenant has no SDK config override is Claude Sonnet on the Claude agent SDK; tenants can configure Codex, GitHub Copilot, or OpenAI-compatible runtimes through SDK configs. - Per-turn cost is in the SSE event stream and surfaced on the Sessions detail. The
agent_resultevent for each turn carriescostUsdandnumTurns; the live chat panel does not render the USD figure inline, but the Sessions detail page for the conversation carries the aggregate AI cost (input tokens, output tokens, cache reads and writes, reasoning tokens, AI credits, tool-call count, per-turn breakdown, total cost in USD). - The OverflowBreadcrumb at the top of the drawer carries the conversation's pivot history. When the agent calls a tool that opens a related record (a Skill, an MCP config, a sandbox profile) and the conversation pushes a frame onto its
sourceActionStack, the breadcrumb shows the trail you walked so you can read the context back. - A small "N other chats" chip in the panel header indicates how many other conversations exist on the same record. Click it and you switch between them without leaving the drawer.
Scope: chats anchored to a record
A chat is always anchored to something. Open the chat panel on an initiative and the conversation is scoped to that initiative; the agent sees the initiative body in its system prompt and the platform records the link on the conversation row. Open chat on a plan and the agent gets the plan plus its parent initiative. Open chat on a bug and the platform routes you to the parent plan's chat with the bug context threaded in.
The conversation record carries the anchor fields: surface (planning vs platform), projectId, initiativeId, planId, sandboxProfileId, plus the sourceActionStack that records mid-conversation pivots within the surface. The surface and kind fields are both fixed at creation; a planning chat cannot pivot into a platform chat or an inquiry mid-life. Pivots within a surface push frames onto sourceActionStack and the breadcrumb at the top of the chat panel shows the trail.
The scope shapes three things. First, the agent's read tools default to the right record without you having to point at it. Second, any new records the agent writes during the turn are bound to the right parent: a plan the agent creates from a chat opened on an initiative lands as a plan under that initiative. Third, the conversation is recoverable from the record; opening the same initiative tomorrow shows you the chats that already exist against it, so the conversation history is anchored to the work.
A worked end-to-end example
Sarah opens her CSV Export on the Reporting Page initiative and clicks the chat icon. The drawer opens on the right. She types:
Draft three plans for this initiative based on the spec. One for the server endpoint, one for the download button, one for verification against five customer fixtures.
She hits Send. The agent reads the initiative body (it is already in the system prompt), calls fetch_related_planning_artifacts to read the existing related plans so it does not duplicate work, and then writes three plan Markdown files into the sandbox workspace. Three Write tool calls appear as cards in the chat; each one shows the new plan file the agent created. The agent emits its final text response: a paragraph summarizing the three plans and pointing Sarah to review them on the Plans tab.
The turn ends. The platform sweeps the workspace, detects the three new plan files, and creates three PlanRecords underneath the CSV Export initiative. Version history rows are written; an audit log row records the AI-attributed creation. The Initiatives kanban updates the plans count rollup on Sarah's card within seconds.
Sarah scrolls to the Plans tab to verify; the three plans are there. She comes back to the chat and types her next message:
Now kick off the sdlc-full Flow on the CSV download button plan to start implementation.
The agent calls start_flow with the right parameters. The Flow launches as a background runner; an overlay appears at the top of the chat drawer showing the Flow's step timeline. The agent emits a short text response confirming the run started.
Sarah closes the tab and grabs coffee. The Flow runs for forty minutes through three steps. The third step is a verification checkpoint that requires Sarah's approval before the implementation merges. The Flow pauses at the checkpoint; the Background tasks panel shows the task in review; Sarah comes back, opens the panel, sees the checkpoint with the implementation diff, reads it, and approves. The Flow continues; the implementation merges; the chat overlay shows the run as complete and appends a summary message to the original conversation.
The whole loop is one Sarah-initiated session, kept coherent across a tab close and a forty-minute background runner, with every step auditable and reversible.
Hard limits worth knowing
Most teams never hit these; the numbers are documented so a planner who does hit one knows what is happening.
| Limit | Value | What hits it |
|---|---|---|
| Agent-loop iterations per turn | 30 | A pathological loop terminates; real turns finish in two to six. |
fetch_related_planning_artifacts calls per turn | 6 | A single response cannot pull in unbounded planning context. |
| Attachments per message | 5, 10 MB each | Larger files should go through the record's document upload. |
pendingToolCall TTL | 30 minutes | A paused turn that you do not answer within 30 minutes will not resume as the same turn. |
| Sub-agents per fan-out batch | 20 | The user's chat agent can call fanout_spawnAgents to spawn co-located sub-agents on the parent sandbox, capped at twenty per batch. Recursive fan-out (a sub-agent spawning more sub-agents) is rejected. |
Permissions
Opening Chat and sending messages requires chat.use, which ships on every content-facing built-in role. Reading conversations created by other users requires conversations.read.any (Lead, Admin, Owner by default). Mutating records through the chat requires the standard write scopes on the targeted records (initiatives.manage, plans.manage, bugs.manage); the agent only ever writes through your scopes, never escalates.
Send-to-background and resume-from-background require the separate chat.background.manage scope (elevated danger level). Mutating a conversation (edit title, end, restore) requires conversations.manage.own. Starting a Flow from chat requires flows.run. Configuring MCP servers from a platform-surface chat requires mcp.manage. The per-surface scope rules apply to whatever the agent is asked to do, exactly as they would if you did it yourself.
Why the shape is what it is
A planning chat that mattered for serious work used to mean one of two compromises. Either the chat was a thin layer over a model that did not know what your records were (a generic assistant pasting back text you had to translate into action), or the chat had full access to do anything anywhere with no structural enforcement of the boundaries (a long-running agent loose in your system with policy as the only seatbelt).
Disco Parrot's chat is the third path between them.
The shape is what makes the third path work. The agent works in a sandboxed workspace with files, the way an engineer does; the file-write-then-reconcile sweep is what gives every save a version-history row, an audit-log entry, and an SSE refresh on every connected client, without the agent having to know about any of them. The agent uses the same skill registry the rest of your tenant uses, so a binding edited once on the Skills sub-tab shows up in the slash menu, in the action launcher, and in the agent's reach for the rest of the tenant. start_flow is the escape hatch for the long work that does not need to sit inside one turn; send-to-background is the escape hatch for the long work that does not need you to watch; the durable pendingToolCall is what lets a paused turn survive a closed tab; the per-surface scope cascade is what keeps a chat opened on a record anchored to that record. Each one of those mechanisms is the answer to a problem the generic chat couldn't solve and the loose agent couldn't survive.
For a senior PM evaluating Disco Parrot, Chat is the answer to "what does it mean to work with the agent on my real records?" The answer is conversational where conversation makes sense, structured where structure matters, and reversible where reversibility is the right safety net. For an engineer in the editor, Chat is the place where the agent reads the code as files and writes back as diffs the engineer reviews. For a tech lead reviewing a Flow run their team kicked off from chat, the chat panel is where the run started and where the completion message lands. For a planner who needs to step away mid-turn, send-to-background is the contract: the agent keeps going, the team's work proceeds, the conversation comes back. For a new hire meeting the agent for the first time, the slash menu, the model badge, and the per-turn cost are what make the agent's work legible rather than mysterious. Chat is the surface where the agent does real work, with an honest trail of every step it took.
The read-only sibling to Chat. Same conversational shape; narrower tool ceiling.
The reusable multi-step runs Chat can kick off with start_flow.
The status-skill registry that drives the slash menu and the action launcher. One edit, four surfaces.
The operating model. Chat is where the agent does real work without being a black box.