mirror of
https://github.com/openai/codex.git
synced 2026-02-01 22:47:52 +00:00
Remove request_user_input call_id plumbing
This commit is contained in:
@@ -294,25 +294,17 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
}),
|
||||
})
|
||||
.collect();
|
||||
let call_id = request.call_id.clone();
|
||||
let params = ToolRequestUserInputParams {
|
||||
thread_id: conversation_id.to_string(),
|
||||
turn_id: request.turn_id,
|
||||
item_id: call_id.clone(),
|
||||
item_id: request.call_id,
|
||||
questions,
|
||||
};
|
||||
let rx = outgoing
|
||||
.send_request(ServerRequestPayload::ToolRequestUserInput(params))
|
||||
.await;
|
||||
let response_call_id = call_id.clone();
|
||||
tokio::spawn(async move {
|
||||
on_request_user_input_response(
|
||||
event_turn_id,
|
||||
response_call_id,
|
||||
rx,
|
||||
conversation,
|
||||
)
|
||||
.await;
|
||||
on_request_user_input_response(event_turn_id, rx, conversation).await;
|
||||
});
|
||||
} else {
|
||||
error!(
|
||||
@@ -325,7 +317,6 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
if let Err(err) = conversation
|
||||
.submit(Op::UserInputAnswer {
|
||||
id: event_turn_id,
|
||||
call_id: Some(request.call_id.clone()),
|
||||
response: empty,
|
||||
})
|
||||
.await
|
||||
@@ -1492,7 +1483,6 @@ async fn on_exec_approval_response(
|
||||
|
||||
async fn on_request_user_input_response(
|
||||
event_turn_id: String,
|
||||
call_id: String,
|
||||
receiver: oneshot::Receiver<JsonValue>,
|
||||
conversation: Arc<CodexThread>,
|
||||
) {
|
||||
@@ -1507,7 +1497,6 @@ async fn on_request_user_input_response(
|
||||
if let Err(err) = conversation
|
||||
.submit(Op::UserInputAnswer {
|
||||
id: event_turn_id,
|
||||
call_id: Some(call_id.clone()),
|
||||
response: empty,
|
||||
})
|
||||
.await
|
||||
@@ -1543,7 +1532,6 @@ async fn on_request_user_input_response(
|
||||
if let Err(err) = conversation
|
||||
.submit(Op::UserInputAnswer {
|
||||
id: event_turn_id,
|
||||
call_id: Some(call_id),
|
||||
response,
|
||||
})
|
||||
.await
|
||||
|
||||
@@ -31,7 +31,6 @@ use crate::stream_events_utils::HandleOutputCtx;
|
||||
use crate::stream_events_utils::handle_non_tool_response_item;
|
||||
use crate::stream_events_utils::handle_output_item_done;
|
||||
use crate::stream_events_utils::last_assistant_message_from_item;
|
||||
use crate::stream_events_utils::response_input_to_response_item;
|
||||
use crate::terminal;
|
||||
use crate::transport_manager::TransportManager;
|
||||
use crate::truncate::TruncationPolicy;
|
||||
@@ -209,7 +208,6 @@ use codex_protocol::config_types::ReasoningSummary as ReasoningSummaryConfig;
|
||||
use codex_protocol::config_types::WindowsSandboxLevel;
|
||||
use codex_protocol::models::ContentItem;
|
||||
use codex_protocol::models::DeveloperInstructions;
|
||||
use codex_protocol::models::FunctionCallOutputPayload;
|
||||
use codex_protocol::models::ResponseInputItem;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::models::render_command_prefix_list;
|
||||
@@ -1682,7 +1680,6 @@ impl Session {
|
||||
pub async fn notify_user_input_response(
|
||||
&self,
|
||||
sub_id: &str,
|
||||
call_id: Option<String>,
|
||||
response: RequestUserInputResponse,
|
||||
) {
|
||||
let entry = {
|
||||
@@ -1701,36 +1698,6 @@ impl Session {
|
||||
}
|
||||
None => {
|
||||
warn!("No pending user input found for sub_id: {sub_id}");
|
||||
if response.answers.is_empty() {
|
||||
warn!(
|
||||
"dropping empty request_user_input response for sub_id: {sub_id}; likely cancelled"
|
||||
);
|
||||
return;
|
||||
}
|
||||
let call_id = call_id.unwrap_or_else(|| sub_id.to_string());
|
||||
let content = match response.to_tool_output_content() {
|
||||
Ok(content) => content,
|
||||
Err(err) => {
|
||||
warn!(
|
||||
"failed to serialize request_user_input response for call_id: {call_id}: {err}"
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let response_input = ResponseInputItem::FunctionCallOutput {
|
||||
call_id: call_id.clone(),
|
||||
output: FunctionCallOutputPayload {
|
||||
content,
|
||||
success: Some(true),
|
||||
..Default::default()
|
||||
},
|
||||
};
|
||||
let Some(response_item) = response_input_to_response_item(&response_input) else {
|
||||
return;
|
||||
};
|
||||
let turn_context = self.new_default_turn_with_sub_id(sub_id.to_string()).await;
|
||||
self.record_conversation_items(&turn_context, &[response_item])
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2554,12 +2521,8 @@ async fn submission_loop(sess: Arc<Session>, config: Arc<Config>, rx_sub: Receiv
|
||||
Op::PatchApproval { id, decision } => {
|
||||
handlers::patch_approval(&sess, id, decision).await;
|
||||
}
|
||||
Op::UserInputAnswer {
|
||||
id,
|
||||
call_id,
|
||||
response,
|
||||
} => {
|
||||
handlers::request_user_input_response(&sess, id, call_id, response).await;
|
||||
Op::UserInputAnswer { id, response } => {
|
||||
handlers::request_user_input_response(&sess, id, response).await;
|
||||
}
|
||||
Op::DynamicToolResponse { id, response } => {
|
||||
handlers::dynamic_tool_response(&sess, id, response).await;
|
||||
@@ -2927,11 +2890,9 @@ mod handlers {
|
||||
pub async fn request_user_input_response(
|
||||
sess: &Arc<Session>,
|
||||
id: String,
|
||||
call_id: Option<String>,
|
||||
response: RequestUserInputResponse,
|
||||
) {
|
||||
sess.notify_user_input_response(&id, call_id, response)
|
||||
.await;
|
||||
sess.notify_user_input_response(&id, response).await;
|
||||
}
|
||||
|
||||
pub async fn dynamic_tool_response(
|
||||
|
||||
@@ -380,13 +380,7 @@ async fn handle_request_user_input(
|
||||
cancel_token,
|
||||
)
|
||||
.await;
|
||||
let _ = codex
|
||||
.submit(Op::UserInputAnswer {
|
||||
id,
|
||||
call_id: Some(event.call_id.clone()),
|
||||
response,
|
||||
})
|
||||
.await;
|
||||
let _ = codex.submit(Op::UserInputAnswer { id, response }).await;
|
||||
}
|
||||
|
||||
async fn await_user_input_with_cancel<F>(
|
||||
@@ -405,7 +399,7 @@ where
|
||||
answers: HashMap::new(),
|
||||
};
|
||||
parent_session
|
||||
.notify_user_input_response(sub_id, None, empty.clone())
|
||||
.notify_user_input_response(sub_id, empty.clone())
|
||||
.await;
|
||||
empty
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ async fn should_install_mcp_dependencies(
|
||||
let empty = RequestUserInputResponse {
|
||||
answers: HashMap::new(),
|
||||
};
|
||||
sess.notify_user_input_response(sub_id, None, empty.clone())
|
||||
sess.notify_user_input_response(sub_id, empty.clone())
|
||||
.await;
|
||||
empty
|
||||
}
|
||||
|
||||
@@ -165,7 +165,6 @@ async fn request_user_input_round_trip_resolves_pending() -> anyhow::Result<()>
|
||||
codex
|
||||
.submit(Op::UserInputAnswer {
|
||||
id: request.turn_id.clone(),
|
||||
call_id: Some(request.call_id.clone()),
|
||||
response,
|
||||
})
|
||||
.await?;
|
||||
|
||||
@@ -69,7 +69,7 @@ For complete documentation of the `Op` and `EventMsg` variants, refer to [protoc
|
||||
- `Op::UserInput` – Legacy form of user input
|
||||
- `Op::Interrupt` – Interrupts a running turn
|
||||
- `Op::ExecApproval` – Approve or deny code execution
|
||||
- `Op::UserInputAnswer` – Provide answers for a `request_user_input` tool call (optionally include `call_id`)
|
||||
- `Op::UserInputAnswer` – Provide answers for a `request_user_input` tool call
|
||||
- `Op::ListSkills` – Request skills for one or more cwd values (optionally `force_reload`)
|
||||
- `Op::UserTurn` and `Op::OverrideTurnContext` accept an optional `personality` override that updates the model’s communication style
|
||||
- `EventMsg`
|
||||
|
||||
@@ -222,9 +222,6 @@ pub enum Op {
|
||||
UserInputAnswer {
|
||||
/// Turn id for the in-flight request.
|
||||
id: String,
|
||||
/// Tool call id for the in-flight request, if available.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
call_id: Option<String>,
|
||||
/// User-provided answers.
|
||||
response: RequestUserInputResponse,
|
||||
},
|
||||
|
||||
@@ -43,12 +43,6 @@ pub struct RequestUserInputResponse {
|
||||
pub answers: HashMap<String, RequestUserInputAnswer>,
|
||||
}
|
||||
|
||||
impl RequestUserInputResponse {
|
||||
pub fn to_tool_output_content(&self) -> Result<String, serde_json::Error> {
|
||||
serde_json::to_string(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
pub struct RequestUserInputEvent {
|
||||
/// Responses API call id for the associated tool call, if available.
|
||||
|
||||
@@ -722,7 +722,6 @@ impl RequestUserInputOverlay {
|
||||
self.app_event_tx
|
||||
.send(AppEvent::CodexOp(Op::UserInputAnswer {
|
||||
id: self.request.turn_id.clone(),
|
||||
call_id: Some(self.request.call_id.clone()),
|
||||
response: RequestUserInputResponse { answers },
|
||||
}));
|
||||
if let Some(next) = self.queue.pop_front() {
|
||||
@@ -1404,16 +1403,10 @@ mod tests {
|
||||
overlay.submit_answers();
|
||||
|
||||
let event = rx.try_recv().expect("expected AppEvent");
|
||||
let AppEvent::CodexOp(Op::UserInputAnswer {
|
||||
id,
|
||||
call_id,
|
||||
response,
|
||||
}) = event
|
||||
else {
|
||||
let AppEvent::CodexOp(Op::UserInputAnswer { id, response }) = event else {
|
||||
panic!("expected UserInputAnswer");
|
||||
};
|
||||
assert_eq!(id, "turn-1");
|
||||
assert_eq!(call_id.as_deref(), Some("call-1"));
|
||||
let answer = response.answers.get("q1").expect("answer missing");
|
||||
assert_eq!(answer.answers, Vec::<String>::new());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user