mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Make parent-owned sub-agent threads read-only in the TUI (#33841)
## Why Multi-agent V2 spawned threads are controlled by their parent and reject direct app-server input. The TUI should expose that ownership instead of presenting an input flow that the server will reject. ## What changed - Add the experimental `Thread.canAcceptDirectInput` capability for loaded threads and populate it from the same policy used to validate `turn/start` and `turn/steer`. Stored, unloaded threads report `null`. - Carry the capability through TUI thread discovery, selection, startup, and resume flows, with a compatibility fallback for older app servers. - Present parent-owned threads as view-only, preserve drafts and queued input, block agent-directed commands and settings shortcuts, and keep local navigation and inspection commands available. ## Testing - Cover V1 writable and V2 view-only spawned threads through selection and resume. - Cover composer submission paths, queued and initial input preservation, allowed navigation commands, settings shortcuts, and the view-only UI. GitOrigin-RevId: 495ad051249e5577fb0b0c1cc8c40a0998d04918
This commit is contained in:
1 parent
315195492c
commit
3f0669dbd6
37 files changed
+781
-99
No files matched your search
@@ -202,6 +202,8 @@ const CONNECTORS_SELECTION_VIEW_ID: &str = "connectors-selection";
|
||||
const PET_SELECTION_LOADING_VIEW_ID: &str = "pet-selection-loading";
|
||||
const AMBIENT_PET_WRAP_GAP_COLUMNS: u16 = 2;
|
||||
const TUI_STUB_MESSAGE: &str = "Not available in TUI yet.";
|
||||
const PARENT_OWNED_INPUT_MESSAGE: &str =
|
||||
"This sub-agent is controlled by its parent. Direct input is disabled.";
|
||||
|
||||
/// Choose the keybinding used to edit the most-recently queued message.
|
||||
///
|
||||
@@ -650,6 +652,7 @@ pub(crate) struct ChatWidget {
|
||||
thread_name: Option<String>,
|
||||
thread_rename_block_message: Option<String>,
|
||||
active_side_conversation: bool,
|
||||
blocks_direct_input: bool,
|
||||
normal_placeholder_text: String,
|
||||
side_placeholder_text: String,
|
||||
forked_from: Option<ThreadId>,
|
||||
@@ -1732,6 +1735,15 @@ impl ChatWidget {
|
||||
T: Into<AppCommand>,
|
||||
{
|
||||
let op: AppCommand = op.into();
|
||||
if self.blocks_direct_input
|
||||
&& matches!(
|
||||
&op,
|
||||
AppCommand::UserTurn { .. } | AppCommand::Review { .. } | AppCommand::Compact
|
||||
)
|
||||
{
|
||||
self.add_error_message(PARENT_OWNED_INPUT_MESSAGE.to_string());
|
||||
return false;
|
||||
}
|
||||
self.prepare_local_op_submission(&op);
|
||||
if op.is_review() && !self.bottom_pane.is_task_running() {
|
||||
self.bottom_pane.set_task_running(/*running*/ true);
|
||||
|
||||
Reference in new issue
Block a user