mirror of
https://github.com/openai/codex.git
synced 2026-04-26 23:55:25 +00:00
fix: handle all web_search actions and in progress invocations (#9960)
### Summary - Parse all `web_search` tool actions (`search`, `find_in_page`, `open_page`). - Previously we only parsed + displayed `search`, which made the TUI appear to pause when the other actions were being used. - Show in progress `web_search` calls as `Searching the web` - Previously we only showed completed tool calls <img width="308" height="149" alt="image" src="https://github.com/user-attachments/assets/90a4e8ff-b06a-48ff-a282-b57b31121845" /> ### Tests Added + updated tests, tested locally ### Follow ups Update VSCode extension to display these as well
This commit is contained in:
@@ -32,6 +32,7 @@ use codex_core::protocol::TurnCompleteEvent;
|
||||
use codex_core::protocol::TurnDiffEvent;
|
||||
use codex_core::protocol::WarningEvent;
|
||||
use codex_core::protocol::WebSearchEndEvent;
|
||||
use codex_core::web_search::web_search_detail;
|
||||
use codex_protocol::num_format::format_with_separators;
|
||||
use owo_colors::OwoColorize;
|
||||
use owo_colors::Style;
|
||||
@@ -370,8 +371,20 @@ impl EventProcessor for EventProcessorWithHumanOutput {
|
||||
}
|
||||
}
|
||||
}
|
||||
EventMsg::WebSearchEnd(WebSearchEndEvent { call_id: _, query }) => {
|
||||
ts_msg!(self, "🌐 Searched: {query}");
|
||||
EventMsg::WebSearchBegin(_) => {
|
||||
ts_msg!(self, "🌐 Searching the web...");
|
||||
}
|
||||
EventMsg::WebSearchEnd(WebSearchEndEvent {
|
||||
call_id: _,
|
||||
query,
|
||||
action,
|
||||
}) => {
|
||||
let detail = web_search_detail(Some(&action), &query);
|
||||
if detail.is_empty() {
|
||||
ts_msg!(self, "🌐 Searched the web");
|
||||
} else {
|
||||
ts_msg!(self, "🌐 Searched: {detail}");
|
||||
}
|
||||
}
|
||||
EventMsg::PatchApplyBegin(PatchApplyBeginEvent {
|
||||
call_id,
|
||||
@@ -737,8 +750,7 @@ impl EventProcessor for EventProcessorWithHumanOutput {
|
||||
);
|
||||
}
|
||||
EventMsg::ShutdownComplete => return CodexStatus::Shutdown,
|
||||
EventMsg::WebSearchBegin(_)
|
||||
| EventMsg::ExecApprovalRequest(_)
|
||||
EventMsg::ExecApprovalRequest(_)
|
||||
| EventMsg::ApplyPatchApprovalRequest(_)
|
||||
| EventMsg::TerminalInteraction(_)
|
||||
| EventMsg::ExecCommandOutputDelta(_)
|
||||
|
||||
@@ -49,6 +49,7 @@ use codex_core::protocol::CollabCloseBeginEvent;
|
||||
use codex_core::protocol::CollabCloseEndEvent;
|
||||
use codex_core::protocol::CollabWaitingBeginEvent;
|
||||
use codex_core::protocol::CollabWaitingEndEvent;
|
||||
use codex_protocol::models::WebSearchAction;
|
||||
use codex_protocol::plan_tool::StepStatus;
|
||||
use codex_protocol::plan_tool::UpdatePlanArgs;
|
||||
use serde_json::Value as JsonValue;
|
||||
@@ -66,6 +67,7 @@ pub struct EventProcessorWithJsonOutput {
|
||||
last_total_token_usage: Option<codex_core::protocol::TokenUsage>,
|
||||
running_mcp_tool_calls: HashMap<String, RunningMcpToolCall>,
|
||||
running_collab_tool_calls: HashMap<String, RunningCollabToolCall>,
|
||||
running_web_search_calls: HashMap<String, String>,
|
||||
last_critical_error: Option<ThreadErrorEvent>,
|
||||
}
|
||||
|
||||
@@ -107,6 +109,7 @@ impl EventProcessorWithJsonOutput {
|
||||
last_total_token_usage: None,
|
||||
running_mcp_tool_calls: HashMap::new(),
|
||||
running_collab_tool_calls: HashMap::new(),
|
||||
running_web_search_calls: HashMap::new(),
|
||||
last_critical_error: None,
|
||||
}
|
||||
}
|
||||
@@ -138,7 +141,7 @@ impl EventProcessorWithJsonOutput {
|
||||
protocol::EventMsg::CollabCloseEnd(ev) => self.handle_collab_close_end(ev),
|
||||
protocol::EventMsg::PatchApplyBegin(ev) => self.handle_patch_apply_begin(ev),
|
||||
protocol::EventMsg::PatchApplyEnd(ev) => self.handle_patch_apply_end(ev),
|
||||
protocol::EventMsg::WebSearchBegin(_) => Vec::new(),
|
||||
protocol::EventMsg::WebSearchBegin(ev) => self.handle_web_search_begin(ev),
|
||||
protocol::EventMsg::WebSearchEnd(ev) => self.handle_web_search_end(ev),
|
||||
protocol::EventMsg::TokenCount(ev) => {
|
||||
if let Some(info) = &ev.info {
|
||||
@@ -195,11 +198,36 @@ impl EventProcessorWithJsonOutput {
|
||||
})]
|
||||
}
|
||||
|
||||
fn handle_web_search_end(&self, ev: &protocol::WebSearchEndEvent) -> Vec<ThreadEvent> {
|
||||
fn handle_web_search_begin(&mut self, ev: &protocol::WebSearchBeginEvent) -> Vec<ThreadEvent> {
|
||||
if self.running_web_search_calls.contains_key(&ev.call_id) {
|
||||
return Vec::new();
|
||||
}
|
||||
let item_id = self.get_next_item_id();
|
||||
self.running_web_search_calls
|
||||
.insert(ev.call_id.clone(), item_id.clone());
|
||||
let item = ThreadItem {
|
||||
id: self.get_next_item_id(),
|
||||
id: item_id,
|
||||
details: ThreadItemDetails::WebSearch(WebSearchItem {
|
||||
id: ev.call_id.clone(),
|
||||
query: String::new(),
|
||||
action: WebSearchAction::Other,
|
||||
}),
|
||||
};
|
||||
|
||||
vec![ThreadEvent::ItemStarted(ItemStartedEvent { item })]
|
||||
}
|
||||
|
||||
fn handle_web_search_end(&mut self, ev: &protocol::WebSearchEndEvent) -> Vec<ThreadEvent> {
|
||||
let item_id = self
|
||||
.running_web_search_calls
|
||||
.remove(&ev.call_id)
|
||||
.unwrap_or_else(|| self.get_next_item_id());
|
||||
let item = ThreadItem {
|
||||
id: item_id,
|
||||
details: ThreadItemDetails::WebSearch(WebSearchItem {
|
||||
id: ev.call_id.clone(),
|
||||
query: ev.query.clone(),
|
||||
action: ev.action.clone(),
|
||||
}),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use codex_protocol::models::WebSearchAction;
|
||||
use mcp_types::ContentBlock as McpContentBlock;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
@@ -280,7 +281,9 @@ pub struct McpToolCallItem {
|
||||
/// A web search request.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, TS)]
|
||||
pub struct WebSearchItem {
|
||||
pub id: String,
|
||||
pub query: String,
|
||||
pub action: WebSearchAction,
|
||||
}
|
||||
|
||||
/// An error notification.
|
||||
|
||||
Reference in New Issue
Block a user