# Mission Control TUI
[Mission Control user guide](../user/mission-control.md) · [Technical reference index](README.md) · [Repository README](../../README.md)
## Purpose
Use Mission Control to edit prompts, follow tools and subagents, inspect captured output, and change settings without leaving the terminal.
```sh
magi-code
magi-code --prompt "Summarize this repository."
```
Mission Control is the conversation interface. Both stdin and stdout must be TTYs. `--prompt` rejects whitespace-only input.
## Details
### Startup and readiness
You can edit the prompt as soon as Mission Control draws its first frame, before execution is ready. Settings/config, instructions, skill discovery, and session setup/discovery happen earlier. Background session pruning starts on an unjoined thread before TUI entry. It may overlap startup but does not block readiness.
Execution waits for the current settings/policy snapshot, selected primary agent (or explicit None), enabled subagent profiles, and all enabled MCP servers to connect, initialize, and complete `tools/list`. Failures in the selected profile, an enabled subagent, or strict MCP startup block execution. Diagnostics from unselected or disabled profiles only warn. Autocomplete, titles, Git/branch data, and other decoration are best effort and do not block. This MCP gate is stricter than `magi-code mcp list`; see [MCP tools](mcp-stdio-tools.md).
The controlled `TestBackend` responsiveness gate requires `<50 ms>` from receipt of a process-side edit through bounded event draining and state projection to a completed Ratatui draw. It excludes whole-process startup and physical terminal write/flush. The `<16 ms>` physical-terminal target is non-gating and unverified; no physical TTY test has run.
### Startup prompt queue
During readiness, you can queue one normal prompt. The queued prompt becomes immutable, and the editor clears for a separate draft. A second submission is rejected without replacing either. `Alt-C` cancels the queue and preserves the draft. `/help` and `/quit` work immediately; other slash commands remain blocked until ready.
After readiness, an input fence checks for later queue decisions, then runs the prompt once. An untouched `--prompt` follows the same path. A critical startup failure restores the terminal, exits nonzero, and does not run the queue. Startup queuing is separate from active-run steering.
### Provider connection
`/login` opens Connect Provider at 60% terminal width and 40% height. It lists OpenAI Codex, Anthropic, Claude Subscription, OpenAI, and Custom Provider with current status. Select with `Up`/`Down`, then `Enter`. Enlarge compact terminals when prompted to reveal editable controls.
- Codex OAuth stays in the modal. Click **Open Browser** (`Alt-O`) or **Copy URL** (`Ctrl-Y`) below the URL. `Tab`/`Shift-Tab` moves between these buttons and the redacted redirect field; `Enter` activates the focused control. Copy the final browser redirect URL, paste it into the field, and press `Enter`. `Esc` cancels OAuth.
- Anthropic shows environment/API-key setup guidance. It does not request or store a key.
- Custom Provider accepts a label, base URL, optional API-key environment-variable name (never the key), and optional `models.dev` provider override. The override selects an exact catalog namespace. Blank uses the provider ID and clears an existing override on replacement. `Tab`/`Shift-Tab` moves between fields; compact layouts show the focused field. Reusing an ID requires confirmation: `Enter` replaces it, while `Esc` returns to the form.
- After success, `Enter`/`Esc` closes. After an error, `Enter` retries, `Backspace`/`Left` goes back, and `Esc` closes. Cancellation before Saving preserves settings and credentials. Saving cannot be cancelled after durable custom-provider persistence starts; the modal stays open until completion is reconciled.
### Edit settings
`/settings` opens six tabs (Context, Agent settings, Models, Tools, Internal Tooling, Other) for Global or Project settings. Edits remain drafts until `Ctrl-S`. Saving reloads settings for future actions and refreshes affected Mission Control state. `Tab` switches tabs; `Ctrl-G` switches scope. Models shows cached rows without refreshing. Its **Refresh catalog** button refreshes only when clicked or selected with Up/Down and activated with Enter. See [Configuration](configuration.md#edit-settings-in-mission-control) for all controls and editable groups.
Compaction, Side agent, Summary, Session titles, and View image each use one model picker for paired provider/model settings. It lists enabled cached models, including unsaved availability changes. Enter accepts into the draft; Esc cancels. Tab or Ctrl-G cancels an unaccepted choice before navigating. Opening the picker does not refresh the catalog.
### Side conversation
`/side` opens an independent conversation, including during primary work. It has separate history and display state but uses the same transcript cards, prompt editor, and activity inspection. `Esc` hides it without stopping work; `/side` reopens it. `Alt-C` cancels only side work. Hidden work shows running/unread status at top right.
Inside the modal, only `/reset` is available. Reset preserves old history and waits for worker/MCP cleanup before creating a new UUID session. The live conversation lasts only for this process. Its files live under `sessions/side/`, outside primary session selection. `--no-session` disables it. See [Side agent](side-agent.md) for tools, shared-file risks, settings, and lifetime details.
### Prompt editing and paste
`Enter` submits. `Shift-Enter`, `Ctrl-J`, and `Ctrl-Enter` insert a newline. **Use `Ctrl-J` as the portable fallback.** Some terminals send `Shift-Enter` and `Ctrl-Enter` as plain `Enter`, causing submission. This includes WSL when its host terminal or an intervening multiplexer drops these modifiers.
Autocomplete and modals take precedence over editing. The prompt grows from 1 to 5 visual rows. Use cursor keys for longer prompts; mouse-wheel events over Prompt do nothing.
Paste normalizes CRLF and lone CR to `\n`, keeps tabs/newlines, and strips other C0 controls, `ESC`, and `DEL`. Explicit `Crossterm Event::Paste` and the Windows text-burst fallback share this policy. At least 3 logical lines or more than 800 UTF-8 bytes collapse to `[Pasted #N · X lines]`. Text starting with `/` after optional whitespace or with `!` remains ordinary text so commands still work. Thresholds are fixed.
The expanded normalized prompt, including hidden paste payloads, is capped at 1 MiB. An oversized edit is rejected in full with `Prompt is limited to 1 MiB; edit rejected`; it is not truncated.
Collapsed pastes act as one unit during cursor movement, deletion, selection, mouse hit-testing, and undo/redo. Submission, selected copy, restored history, and provider input use the full normalized payload. Rejected submissions restore label and payload together. Autocomplete sees only visible text and offsets. Labels contain only local IDs and line counts, while debug output excludes payloads. Typed text resembling a paste label remains ordinary text.
#### Editor implementation limits
One `PromptEditor` wraps the canonical `TextArea`, which owns visible text, cursor, selection, viewport mapping, and native edit state. Paste payloads live in a private sidecar. The dependency is pinned:
```toml
tui-textarea = { package = "tui-textarea-2", version = "=0.13.2", default-features = false, features = ["no-backend", "search"] }
```
Ordinary drafts use its bounded 50-entry native history. With a collapsed paste, semantic history uses the same 50-edit limit and restores each payload as one edit, without an application-level mirrored history index. Startup queuing, the paint fence, active steering, and rejected-submit restoration remain application behavior. Rendering uses the visible projection, preserves focus/blink behavior, and uses the rendered textarea mapping for mouse selection. Selected non-empty text copies through OSC52.
Movement is character-based, not guaranteed grapheme-safe. Logical text, cursor, selection, and history are lossless, but measured screen rows/private viewport coordinates use `u16`. Beyond `u16::MAX` rendered rows, the visible window, native cursor, or mouse hit-testing may be wrong. The internal `search` fallback handles logical zero-width scalar positions and clears its temporary pattern after movement; it does not fix viewport limits or grapheme handling. The exact pin stays until a reviewed upstream lossless viewport-row fix permits enabling the ignored real-render diagnostic. Wheel scrolling is disabled because the public scroll API changes cursor/selection and exposes no independent viewport control.
### Follow activity
Transcript has a border titled **Transcript** at the top left and uses the full body width apart from the far-right tab rail unless column modals are pinned. `Shift-Tab` switches Transcript and Changes. Clicking a rail label selects that view. Changes replaces the body with worktree review while retaining Prompt and the rail. Session and branch remain at the left of the full-width header. Its first row ends with `[Alt+1-3] [ ] Activities, [ ] Files, [ ] Summary • [Alt-A] Pin`; the second ends with `[Shift-Tab] Cycle Tabs`. Both control rows are right-aligned above the separator. An open panel has `[•]` and an active-colored label. Pin uses the active color when enabled; `[Alt-A]` always uses the hotkey color.
Header toggles open **Activity Tree** (`Alt-1`), **Session Files** (`Alt-2`), or **Summary** (`Alt-3`) over the right side, below the header and above Prompt. Their width is one third of the transcript, with a 27-column minimum clamped to available space. They start closed unless a saved layout opens them. Open modals stack top-to-bottom in opening order and share available height equally, with leftover rows assigned from the top. Closing one expands the others; reopening adds it at the bottom. Each retains its scroll position. Opening or closing them does not resize the body or change the selected tab, primary focus, or prompt draft. The close button or same toggle closes only that modal. When unpinned, `Esc` closes the focused modal, or the last opened when no modal has focus, after dismissing autocomplete. Rail clicks and `Shift-Tab` switch tabs without closing the stack. Other dialogs take priority.
**Pin** in the header (`Alt-A`) controls all three modals together. Pinning reserves a column beside Transcript instead of covering its text. Turning pin on with no modals open opens Activity Tree, Session Files, and Summary in that order; unpinning then closes the stack. If panels were already open before pinning, unpinning restores overlays on either tab instead. Closing the last modal turns pin off and restores Transcript's width. On narrow terminals the pinned column shrinks to leave at least half the body for Transcript. Pinned modals disappear on Changes without closing; returning restores their order and scroll positions. They ignore `Esc`. All column modals, pinned or not, always show `[Alt-1] Hide`, `[Alt-2] Hide`, or `[Alt-3] Hide` at the top right. Other shortcut hints appear only on the focused modal, which uses the theme's focused border color. The `[X]` buttons remain available. Panel visibility, order, focus, pinning, and the unpin-close behavior survive session switches; session content and its scroll positions reset. Visibility, order, pinning, and unpin-close behavior also persist across application restarts in global `interface.tui.panel_layout` settings. Startup focuses Prompt; focus and scroll are not saved. Panel preferences never enter session history or provider requests.
Letters, numbers, and `/` focus Prompt while keeping header modals open. Clicking Prompt also focuses it. Prompt editing, autocomplete, paste, and submission work normally. Without autocomplete, `Tab` cycles Prompt → Transcript → open modals in opening order → Prompt when pinned; unpinned modals stay outside the Prompt ↔ Transcript cycle. Pinned Transcript remains clickable and scrollable. Clicking a modal focuses it without reordering the stack. Navigation keys act on the focused modal; mouse-wheel scrolling targets the hovered pane.
When focused, Activity Tree retains arrow-key selection and expansion; click a row or press `Enter` to open its detail dialog. Closing detail returns to the tree. Session Files uses Arrow Up/Down, Page Up/Down, or the mouse wheel to scroll. In focused Summary, `Enter` starts/stops generation and the same scrolling keys move through the log. Hiding Summary does not stop generation.
Normal `Tab` cycles Prompt and Transcript. Modals/autocomplete use their own Tab behavior. `Ctrl-T` opens Activity Tree.
In Changes without overlays, `Tab` cycles Prompt, Files, Original, and Diff; `Shift-Tab` returns to Transcript. See [Diff review](diff-review.md) for line comments, refresh behavior, storage, and provider visibility.
The prompt border shows running/cancel status and Bash Mode upper-left, with provider/model/thinking controls and agent selection upper-right. Lower-left shows `Session: 14m18s • 123k(in)│ 18k(out)│ 76%(cache) • Current Ctx: 62% [######..|.] 200k • Compact at 80%`. Session usage fields have fixed widths and theme colors; unknown context shows `—% [..........] —`. Session totals include primary and subagent activity and persist across resume and compaction. Cache share is total cached input divided by total input. While usage is incomplete, the display retains this session's last known cache percentage; `—` appears only before a known value. There is no partial indicator. Older history cannot recover usage that was never recorded.
Session time counts foreground Mission Control prompt workers, Bash Mode, and manual compaction, including provider waits, tools, retries, and cancellation cleanup. Concurrent children share the parent's interval; their times are not added. Idle time, time with the app closed, and background title/summary work are excluded. The footer ticks while work is active, including with reduced motion. Completed worker intervals are saved as local-only session records and survive resume and history rotation. Older sessions start from zero for unrecorded work; an abrupt process exit can lose the unfinished interval.
The bar shows the primary agent's current context against its full window; `|` marks the configured auto-compaction threshold. This is not an exact countdown: compaction checks projected next-request input. Disabled compaction shows `Auto off`. Provider controls show idle `[Alt-M]`, or a login fallback. Narrow layouts omit the bar before clipping text. Context refreshes with estimates; model/session switches hide it until recalculated. The prompt's lower-right border shows `MAGI-CODE vX.Y.Z`. The transcript header shows `Cwd: <cwd> • Branch: <branch>` when available.
When magi-code has a Codex login, the top-right prompt border starts with `Codex 72/100%(w) •` before the model controls, even if another provider is selected. This is percentage **used**, rounded to a whole number: Pro prefers the weekly window (`w`); other or unknown plans prefer five hours (`5h`). If the preferred window is missing, the indicator uses the first available window and its actual duration or label. One background worker serves this indicator and `/usage`. It fetches on connection, then at most once every five minutes while a prompt is running or real agent/subagent events occurred within the preceding five minutes. Idle keyboard/mouse input does not trigger quota refreshes. `/usage` explicitly requests fresh data and shares an in-flight fetch. Local auth checks run off the UI thread every five seconds; disconnects and failed reads hide the indicator. Account changes during a fetch discard that snapshot; same-account token refreshes preserve it.
Transcript cards have single-row, full-width role headers and status marks, with no blank header rows. Body padding and user-card spacing are unchanged. A visual scrollbar replaces textual position labels. Tool cards show bounded, sanitized summaries tailored to browser, bash, read, grep/AST grep, web/code search, find, list-files, write, `hash_edit`, and `view_image`. Write/edit cards update in place from running to success/cancelled/failed. Successful `hash_edit` shows at most four changed diff lines, marked as a limited preview.
Kitty and Ghostty can show [local image previews](terminal-images.md) in `view_image` cards and completed assistant Markdown. Other terminals keep text. Remote URLs and data URLs are never loaded.
#### Inspect complete tool output
Click an activity tree row or select it with Up/Down and press `Enter` to open Selected Activity Detail in a modal. `Escape` closes it and returns focus to the tree. Up/Down, Page Up/Down, and the mouse wheel scroll details without scrolling the panes behind it. Background clicks, typing, and pane shortcuts are blocked while it is open. Left/Right in the tree still collapse/expand activities.
Selected Activity Detail has `Status`, `Tool • <actual name> • <label>`, `Metadata / Params`, and `Sanitized Output`. A successful live `hash_edit` may add `Applied Diff`. Click `▸ Metadata / Params` (or other activities' `▸ Metadata`) to expand; click `▾` to collapse. Selecting another activity resets it to collapsed.
Detail retains all submitted parameters and result-metadata fields with recursive credential redaction and terminal-control sanitization. Output is complete up to each tool's native capture limit; expanded metadata retains truncation details. Parent `subagents` output is not compacted here. Applied diffs are display-only and absent after session hydration.
The rail's [Diff page](diff-review.md) reviews current worktree changes against `HEAD`. Tool-specific diffs remain in activity detail; branch status, `#git-status`, and Git-aware autocomplete remain available.
#### Follow subagents
Live subagent cards show aggregate settled/running/failed/waiting counts, clickable task chips, selected intent, recent activity, and `[View Subagent ↗]`. `interface.tui.subagent_card_rows` controls recent activity rows: default `16`, range `1` to `50`.
Chips prefer configured agent names, falling back to task identity. The selection also shows identity and resolved provider/model/reasoning when available. The first task is selected initially; selecting a chip keeps that task selected until another chip is chosen. Activity updates do not switch tasks. View Subagent opens a live viewer for that task and its batch siblings, with tabs and bounded timeline scrolling. Closing leaves the underlying selection/scroll unchanged. Stalled tasks suppress late start events after terminal failure. Selection, scrolling, and drafts remain local display state.
The viewer's bottom prompt uses the primary prompt's styling and keyboard editor, including selection, undo/redo, multiline input, and collapsed paste. Each task keeps a separate draft. Autocomplete offers only `$skill` tags; slash commands are rejected, and a leading `!` is literal steering text, never a shell command. Mouse editing is not supported in this prompt.
- `Enter` queues steering for the selected active child, or accepts visible autocomplete; `Shift-Enter`, `Ctrl-J`, and `Ctrl-Enter` insert a newline, with the same terminal compatibility limits as the primary prompt.
- `Alt-C` recalls that child's pending steering before any existing draft. If none is pending, it requests cancellation of that child, not the primary run or sibling tasks. A busy injection or oversized recall leaves the queue and draft intact.
- `Esc` closes the viewer. `Tab` / `Shift-Tab` switch sibling tabs.
- `PgUp` / `PgDn` and the mouse wheel scroll output. While the prompt is editable, arrow keys belong to the editor, not output scrolling or tab switching. Clicking sibling tabs switches tasks.
Completed children are read-only, but `Alt-C` can still recall unconsumed steering. Failed or cancelled children retain pending input for recall during the current application session; a new primary run is blocked until it is recalled. Accepted steering uses the child's existing continuation and persistence path, not a separate run. See [compaction and steering](sessions-context-cache.md#configure-automatic-compaction).
#### Show hooks and injected context
`automation.hooks.show_in_tui=true` shows matching before/after hooks under their tool with running/success/failure status and sanitized phase/label/tool metadata. Default `false` keeps successful hooks quiet.
Provider-injection visibility uses separate `automation.hooks.injected_content` settings: `show_in_transcript` adds local/system rows; `show_in_activity_tree` places rows under the related tool/message, or at the root. Both default to `false`. `style` defaults to `content` (redacted/truncated text); `metadata` shows only label, status, item count, and byte count. These settings affect display only and do not enable injection itself.
### Direct shell commands
Submit `!command` with `!` as the first character to run immediately through guarded bash in cwd, without a provider request or authentication. Tool restrictions, hooks, and cancellation still apply. Command and output are local display only, not durable session history. See [direct shell execution](commands-and-interfaces.md#run-a-shell-command-directly).
### Autocomplete
- `/` as the first character suggests slash commands, including `/help`, `/login`, `/logout`, `/fast`, `/model`, `/settings`, `/skills`, `/sessions`, `/system-prompt`, `/new`, `/export`, and `/quit`.
- `@` anywhere suggests regular files under cwd and inserts slash-normalized relative tags such as `@src/lib.rs`.
- `$` anywhere suggests enabled skills and inserts literal tags such as `$rust-dev`. Tags do not auto-load skills or add provider/session metadata.
- `#` anywhere suggests `#tree`, `#git-status`, and `#diff-changes`. Acceptance only inserts text; it does not run commands or submit. After root user submission, `#tree` and `#git-status` expand through guarded bash; `#diff-changes` uses the review backend to add only unresolved comments, without changed code or a file list. See [prompt context](commands-and-interfaces.md#add-prompt-context) and [Diff review](diff-review.md).
### Updates
After the first frame and every four hours, a bounded background check announces newer stable crates.io versions. `/update` requires idle state, leaves the TUI for Cargo's build output, and reopens the exact session only after cleanup and a successful update. It never replays the initial prompt. See [Installation and updates](installation-and-updates.md#update-with-cargo) for platform behavior, supported installations, and recovery.
### Fast mode
`/fast`, `/fast on`, and `/fast off` change the global setting while idle; `/fast status` and invalid usage work during a run. Writes run off the UI loop; memory changes only after disk success. Pending writes block another mutation, new prompt, or compaction and restore input, while status/help/quit stay usable. Accepted writes settle during cleanup. The startup snapshot is authoritative and successful writes update it for later work.
An unacknowledged persistence-worker failure with no event blocks retry until restart. A delivered failure clears when its matching event is handled.
Fast mode highlights the provider/model label instead of showing a separate `Fast:` marker. Use `/fast status` to inspect its state. Eligibility follows Codex catalog/fallback rules or explicit custom-provider `fast_mode` metadata; see [Configuration](configuration.md). It applies to eligible primary turns, subagents, and blocking compaction, not title requests. Color terminals may animate only provider/model text right-to-left in rainbow colors about every 83 ms. Without color, bold and underline mark the label. Thinking, context, separators, spaces, and hotkeys keep normal styles. `Alt-M` is hidden during a run while animation stays paced.
### Switch or export a session
`/sessions` shows newest-first sessions, marks the current one, and previews the selection in a second column when space allows. Bounded reads find first and most recent conversational user/assistant messages; tool-only, hook, context-cache, title, and diagnostic events are ignored. Preview text is sanitized/redacted.
`Tab`/terminal-delivered `Shift-Tab` switches list/preview focus; arrows move the list or scroll the preview. Wheel scrolls the hovered column, `Enter` switches from either focus, and `Esc` closes without switching.
`/export` requires an idle run and active persisted session. It rejects arguments and duplicates, runs off the UI loop, and writes a private ZIP under `$MC_HOME/exports` without overwriting. Completion appears in normal status and is ignored if it belongs to a session changed during export. The unencrypted archive contains raw session data and a manifest and may be sensitive; see [export contents and safety](sessions-context-cache.md#export-a-session).
### Exit and cleanup limits
The terminal is restored before worker cleanup. Cancellation is requested first; each critical startup/provider worker gets a 2 s join before detach/error. Non-cooperative detached workers may still have side effects. Decoration gets only a short grace before detach. Accepted Fast persistence has no fixed total join bound if filesystem work stalls after lock acquisition. Export workers are cancelled and joined so publication cannot continue after teardown.
In-flight blocking HTTP MCP POST/body operations, including `notifications/initialized`, cannot be interrupted. A worker detached after 2 s may remain in that call until the configured timeout (default 30 s, maximum 300 s). Cancellation before request start and stdio/pending-response paths remain responsive.
## Controls
| Key | Action |
| --- | --- |
| `Enter` | Submit from Prompt, queue during startup, or accept visible autocomplete. |
| `Shift-Enter` / `Ctrl-Enter` | Insert a newline when the terminal preserves modifiers; otherwise use `Ctrl-J`. |
| `Ctrl-J` | Insert a newline (portable fallback). |
| `Left` / `Right` | Move the prompt cursor by character. |
| `Up` / `Down` | Move cursor vertically in Prompt; otherwise move selection/scroll by focused pane or modal. |
| Mouse wheel over Prompt | Ignored; use cursor keys. |
| `Ctrl-Z` / `Ctrl-Y` | Undo/redo in Prompt; OAuth uses `Ctrl-Y` to copy its URL. |
| `Alt-O` | Open the OAuth URL during provider connection. |
| `Ctrl-Left` / `Ctrl-Right` | Move by word. |
| `Ctrl-Backspace` / `Ctrl-Delete` | Delete previous/next word. |
| `Shift-Arrow` | Extend prompt selection. |
| `Ctrl-A` | Select all prompt text. |
| `Ctrl-C` | Copy non-empty selection through OSC52; otherwise clear input, or exit if empty. |
| `Ctrl-D` | Exit. |
| `Alt-P` | Cycle primary agent selection. |
| `Esc` | Focus Prompt, close help/unpinned modal, or cancel a modal action; pinned column modals and provider Saving cannot be closed with Esc. |
| `Tab` | Cycle Prompt/Transcript, including open pinned modals; in Changes without overlays, Prompt/Files/Original/Diff; accept autocomplete; move dialog focus. |
| `Alt-1` / `Alt-2` | Show/hide Activity Tree / Session Files. |
| `Alt-3` | Show/hide the right-side Summary modal. |
| `Alt-A` | Pin/unpin all column modals beside Transcript; pinned modals are hidden on Changes. |
| `Shift-Tab` | Switch Transcript/Changes; pinned modals hide on Changes without closing. Other dialogs retain their own controls. |
| `Ctrl-T` | Open Activity Tree. |
| `F1` or `/help` | Toggle/open help. |
| `Alt-E` / `Alt-C` | Expand/collapse activities; during startup `Alt-C` cancels the queue; during a run it restores queued steering for editing, or requests cancellation when none is queued. Never submits editor text. |
| `Alt-F` / `Alt-R` | Select first failed/running activity. |
| Left click / drag | Position/select prompt text; elsewhere select transcript text, disclose metadata, or use subagent controls. Live viewer consumes mouse input: wheel scrolls and clicks switch sibling tabs. |
| Terminal paste | Apply the normalization, collapse, and byte-limit rules above. |
With steering queued, the prompt border shows `[Alt-C] to edit steering`. Alt-C removes all queued messages and restores them to the prompt in queue order, separated by newlines, followed by any existing draft. The run continues. If the combined text exceeds the prompt limit, the queue and draft remain unchanged. With no steering queued, the border shows `[Alt-C] to cancel`. Cancellation settles at safe runtime boundaries; an already-started blocking provider request or tool may finish its call before the next prompt is accepted.