mirror of
https://github.com/openai/codex.git
synced 2026-10-28 18:58:46 +00:00
## 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
39 lines
1.3 KiB
Rust
39 lines
1.3 KiB
Rust
//! Chat widget hooks for side-conversation mode.
|
|
//!
|
|
//! App-level side-thread lifecycle lives in `app::side`; this module owns the
|
|
//! chat-surface pieces that side mode toggles, such as the composer placeholder,
|
|
//! footer label, and inline `/side` message submission behavior.
|
|
|
|
use super::*;
|
|
|
|
impl ChatWidget {
|
|
pub(crate) fn submit_user_message_as_plain_user_turn(
|
|
&mut self,
|
|
user_message: UserMessage,
|
|
) -> Option<AppCommand> {
|
|
self.submit_user_message_with_shell_escape_policy(user_message, ShellEscapePolicy::Disallow)
|
|
}
|
|
|
|
pub(crate) fn set_side_conversation_active(&mut self, active: bool) {
|
|
self.active_side_conversation = active;
|
|
let placeholder = if active {
|
|
self.side_placeholder_text.clone()
|
|
} else {
|
|
self.normal_placeholder_text.clone()
|
|
};
|
|
self.bottom_pane.set_placeholder_text(placeholder);
|
|
self.bottom_pane.set_side_conversation_active(active);
|
|
if self.blocks_direct_input && !active {
|
|
self.bottom_pane.set_parent_owned_thread();
|
|
}
|
|
}
|
|
|
|
pub(crate) fn side_conversation_active(&self) -> bool {
|
|
self.active_side_conversation
|
|
}
|
|
|
|
pub(crate) fn set_side_conversation_context_label(&mut self, label: Option<String>) {
|
|
self.bottom_pane.set_side_conversation_context_label(label);
|
|
}
|
|
}
|