This page documents the interactive overlay system in the TUI, focusing on approval flows for tool execution, patch application, and MCP elicitation. These overlays are modal UI components displayed in the BottomPane that pause normal input processing to collect user decisions before tool calls proceed.
For general bottom pane architecture and input routing, see 4.1.3. For tool execution mechanics after approval, see 5.5.
Interactive overlays are full-screen modal views that replace the normal chat composer to request explicit user consent for potentially destructive operations. The TUI supports three primary overlay types:
| Overlay Type | Protocol Event | User Response Op | Purpose |
|---|---|---|---|
ApprovalOverlay | ExecApprovalRequestEvent | Op::ExecApproval | Approve/deny shell command execution |
ApprovalOverlay | ApplyPatchApprovalRequestEvent | Op::PatchApproval | Approve/deny file patch application |
RequestUserInputOverlay | RequestUserInputEvent | Op::UserInputAnswer | Answer structured questions from tools |
| (inline) | ElicitationRequestEvent | Op::ResolveElicitation | Approve/deny MCP resource access |
All overlays are rendered via the BottomPane view stack and consume input until the user makes a decision or dismisses the overlay.
Sources: codex-rs/tui/src/bottom_pane/mod.rs42-50 codex-rs/protocol/src/protocol.rs54-60 codex-rs/protocol/src/protocol.rs248-284
Approval Request Event Flow
When codex-core determines that a tool call requires user approval (based on AskForApproval policy), it emits an approval request event. The TUI receives this via the event stream, constructs an ApprovalRequest structure containing the tool context (command, justification, policy amendment options), and pushes an ApprovalOverlay onto the bottom pane view stack. The overlay blocks normal input until the user makes a decision, then submits the corresponding Op back to core.
Sources: codex-rs/tui/src/chatwidget.rs73-99 codex-rs/tui/src/app_event.rs21 codex-rs/tui/src/app_event.rs339
ApprovalOverlay is a BottomPaneView implementation that displays:
The overlay occupies the full bottom pane area and is styled distinctly from the normal composer to signal that user action is required.
Sources: codex-rs/tui/src/bottom_pane/mod.rs42 codex-rs/tui/src/bottom_pane/mod.rs48-49
The ApprovalRequest carries:
Sources: codex-rs/tui/src/bottom_pane/mod.rs49 codex-rs/protocol/src/protocol.rs54-59
When the user selects an option, the overlay transitions to complete state and the BottomPane pops it from the view stack. The decision is translated into an Op::ExecApproval or Op::PatchApproval submission with:
ReviewDecision::Approved, ReviewDecision::Rejected, or ReviewDecision::EditAndResubmitThe core agent receives the decision and either proceeds with execution or aborts the tool call based on the response.
Sources: codex-rs/protocol/src/protocol.rs248-265 codex-rs/tui/src/bottom_pane/mod.rs400-420
The request_user_input tool allows the model to ask structured questions during a turn (for example, "Which authentication method should I use?" with enumerated choices). Unlike approval overlays that gate execution, request_user_input overlays collect arbitrary user answers and resume the turn with those answers as tool output.
Sources: codex-rs/tui/src/bottom_pane/mod.rs44 codex-rs/tui/src/bottom_pane/mod.rs50 codex-rs/protocol/src/protocol.rs60
The overlay renders:
Op::UserInputAnswerThe agent receives the response, formats it as the tool call result, and continues the turn with the model observing the user's answers.
Sources: codex-rs/protocol/src/protocol.rs277-284 codex-rs/tui/src/bottom_pane/mod.rs44-50
MCP servers can issue "elicitations" to request user consent for sensitive operations (for example, accessing private files or making API calls). Unlike exec/patch approvals which use full-screen overlays, elicitations are handled inline as history cells with approve/deny buttons.
Sources: codex-rs/tui/src/chatwidget.rs73 codex-rs/protocol/src/protocol.rs267-275
When core receives ElicitationRequestEvent from an MCP server:
ElicitationHistoryCell into the transcript with approve/deny buttonsOp::ResolveElicitation with the decisionThis inline approach avoids blocking the entire UI for MCP-specific consent flows while maintaining the same approval protocol pattern.
Sources: codex-rs/protocol/src/protocol.rs16 codex-rs/protocol/src/protocol.rs267-275
The BottomPane maintains a view_stack: Vec<Box<dyn BottomPaneView>> where overlays are pushed to replace the composer. Input routing prioritizes the top view:
When an overlay is active:
BottomPaneView::handle_key_eventon_ctrl_c(), which can dismiss the overlayrender() implementation instead of the composerThe composer retains its state (text buffer, attachments, history position) while overlays are displayed, so dismissing an overlay restores the draft message exactly as it was.
Sources: codex-rs/tui/src/bottom_pane/mod.rs322-389 codex-rs/tui/src/bottom_pane/mod.rs145-152
ChatWidget orchestrates the approval flow by:
ExecApprovalRequestEvent or similar from the event streamApprovalRequest with the necessary contextAppEvent::FullScreenApprovalRequestApp handles this event by calling BottomPane::show_approval()ChatWidget submits the corresponding OpThis separation allows the approval UI to be independent of the core agent implementation while maintaining a clean request/response protocol.
Sources: codex-rs/tui/src/chatwidget.rs91-99 codex-rs/tui/src/app_event.rs339 codex-rs/tui/src/bottom_pane/mod.rs322-366
Submitted in response to ExecApprovalRequestEvent to approve or deny shell command execution:
Op::ExecApproval {
id: String, // Original event submission id
turn_id: Option<String>, // Turn context
decision: ReviewDecision, // Approved/Rejected/EditAndResubmit
}
The decision field determines what happens next:
Op::UserTurn)Sources: codex-rs/protocol/src/protocol.rs248-257
Submitted in response to ApplyPatchApprovalRequestEvent to approve or deny file modifications:
Op::PatchApproval {
id: String, // Original event submission id
decision: ReviewDecision, // Approved/Rejected/EditAndResubmit
}
Patch approvals follow the same decision model as exec approvals. When approved, core applies the patch and reports success/failure via PatchApplyEndEvent.
Sources: codex-rs/protocol/src/protocol.rs259-265
All approval decisions use the ReviewDecision enum:
This shared enum maintains consistency across all approval flows and simplifies downstream handling in core.
Sources: codex-rs/protocol/src/protocol.rs248-265
Approval overlays implement special Ctrl+C semantics to allow dismissal without approving:
When an overlay consumes Ctrl+C via on_ctrl_c(), it returns CancellationEvent::Handled and the overlay is popped. If not handled, Ctrl+C propagates to ChatWidget where it may trigger the quit shortcut flow.
This ensures users can always escape approval prompts without making a choice, which is critical for avoiding locked UI states.
Sources: codex-rs/tui/src/bottom_pane/mod.rs393-420 codex-rs/tui/src/bottom_pane/mod.rs121-127
The bottom pane input routing follows this priority:
view_stack gets first chance at all inputOp::Interrupt when task is runningThis layered routing ensures that modal interactions take precedence without disrupting the normal input flow when overlays are dismissed.
Sources: codex-rs/tui/src/bottom_pane/mod.rs328-389
Approval overlays are only shown when the agent's AskForApproval policy requires user consent. The policy is configured per-session and can be updated via Op::OverrideTurnContext or approval presets. Common policies:
The overlay displays the current policy context so users understand why they're being prompted.
Sources: codex-rs/protocol/src/protocol.rs390-450 codex-rs/tui/src/chatwidget.rs91-99
Some approval overlays offer a "Trust this command" or "Always allow" checkbox that applies a policy amendment. When checked and approved, core updates the persistent exec policy rules to auto-approve matching commands in future turns.
Policy amendments use pattern matching (for exec commands) or file path patterns (for patch operations) to define trust boundaries. This allows users to gradually build up trust rules without fully disabling approval prompts.
Sources: codex-rs/protocol/src/protocol.rs54-59
Interactive overlays provide the TUI's approval flow for tool execution, patch application, and MCP resource access. The system uses:
ApprovalOverlay for exec and patch approvals (full-screen modal)RequestUserInputOverlay for structured model questions (full-screen modal)All overlays use the same view stack architecture in BottomPane, ensuring consistent input routing and Ctrl+C dismissal semantics. The approval protocol is bidirectional: core emits approval request events, the TUI displays overlays and collects user decisions, and submits response ops back to core to continue execution.
Refresh this wiki