Migrate tui to use UserTurn (#9497)

- `tui/` and `tui2/` submit `Op::UserTurn` and own full turn context
(cwd/approval/sandbox/model/etc.).
- `Op::UserInput` is documented as legacy in `codex-protocol` (doc-only;
no `#[deprecated]` to avoid `-D warnings` fallout).
- Remove obsolete `#[allow(deprecated)]` and the unused `ConversationId`
alias/re-export.
This commit is contained in:
Ahmed Ibrahim
2026-01-19 13:40:39 -08:00
committed by GitHub
parent 0c0c5aeddc
commit 65d3b9e145
8 changed files with 61 additions and 69 deletions

View File

@@ -2296,6 +2296,14 @@ impl ChatWidget {
}
fn submit_user_message(&mut self, user_message: UserMessage) {
let Some(model) = self.current_model().or(self.config.model.as_deref()) else {
tracing::warn!("cannot submit user message before model is known; queueing");
self.queued_user_messages.push_front(user_message);
self.refresh_queued_user_messages();
return;
};
let model = model.to_string();
let UserMessage { text, image_paths } = user_message;
if text.is_empty() && image_paths.is_empty() {
return;
@@ -2343,36 +2351,24 @@ impl ChatWidget {
}
}
// TODO(aibrahim): migrate the TUI to submit `Op::UserTurn` by default (and rely less on
// `Op::UserInput`) so session-level settings like collaboration mode are consistently
// applied.
let op = if self.collaboration_modes_enabled() {
let model = self
.current_model()
.unwrap_or(DEFAULT_MODEL_DISPLAY_NAME)
.to_string();
let collaboration_mode = collaboration_modes::resolve_mode_or_fallback(
let collaboration_mode = self.collaboration_modes_enabled().then(|| {
collaboration_modes::resolve_mode_or_fallback(
self.models_manager.as_ref(),
self.collaboration_mode,
model.as_str(),
self.config.model_reasoning_effort,
);
Op::UserTurn {
items,
cwd: self.config.cwd.clone(),
approval_policy: self.config.approval_policy.value(),
sandbox_policy: self.config.sandbox_policy.get().clone(),
model,
effort: self.config.model_reasoning_effort,
summary: self.config.model_reasoning_summary,
final_output_json_schema: None,
collaboration_mode: Some(collaboration_mode),
}
} else {
Op::UserInput {
items,
final_output_json_schema: None,
}
)
});
let op = Op::UserTurn {
items,
cwd: self.config.cwd.clone(),
approval_policy: self.config.approval_policy.value(),
sandbox_policy: self.config.sandbox_policy.get().clone(),
model,
effort: self.config.model_reasoning_effort,
summary: self.config.model_reasoning_summary,
final_output_json_schema: None,
collaboration_mode,
};
self.codex_op_tx.send(op).unwrap_or_else(|e| {

View File

@@ -457,7 +457,6 @@ fn next_submit_op(op_rx: &mut tokio::sync::mpsc::UnboundedReceiver<Op>) -> Op {
loop {
match op_rx.try_recv() {
Ok(op @ Op::UserTurn { .. }) => return op,
Ok(op @ Op::UserInput { .. }) => return op,
Ok(_) => continue,
Err(TryRecvError::Empty) => panic!("expected a submit op but queue was empty"),
Err(TryRecvError::Disconnected) => panic!("expected submit op but channel closed"),