Resolve core + TUI integration: add WebSearch event/handler, stabilize client let-chains, wire tools config and overrides; build passes (dev-fast)

This commit is contained in:
James Peter
2025-08-24 19:36:40 +10:00
parent a7c514ac13
commit 6793a2a38b
7 changed files with 60 additions and 23 deletions
+22 -22
View File
@@ -173,13 +173,13 @@ impl ModelClient {
// ChatGPT backend expects the preview name for web search.
if auth_mode == Some(AuthMode::ChatGPT) {
for tool in &mut tools_json {
if let Some(map) = tool.as_object_mut()
&& map.get("type").and_then(|v| v.as_str()) == Some("web_search")
{
map.insert(
"type".to_string(),
serde_json::Value::String("web_search_preview".to_string()),
);
if let Some(map) = tool.as_object_mut() {
if map.get("type").and_then(|v| v.as_str()) == Some("web_search") {
map.insert(
"type".to_string(),
serde_json::Value::String("web_search_preview".to_string()),
);
}
}
}
}
@@ -692,21 +692,21 @@ async fn process_sse<S>(
| "response.in_progress"
| "response.output_item.added"
| "response.output_text.done" => {
if event.kind == "response.output_item.added"
&& let Some(item) = event.item.as_ref()
{
// Detect web_search_call begin and forward a synthetic event upstream.
if let Some(ty) = item.get("type").and_then(|v| v.as_str())
&& ty == "web_search_call"
{
let call_id = item
.get("id")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let ev = ResponseEvent::WebSearchCallBegin { call_id, query: None };
if tx_event.send(Ok(ev)).await.is_err() {
return;
if event.kind == "response.output_item.added" {
if let Some(item) = event.item.as_ref() {
// Detect web_search_call begin and forward a synthetic event upstream.
if let Some(ty) = item.get("type").and_then(|v| v.as_str()) {
if ty == "web_search_call" {
let call_id = item
.get("id")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let ev = ResponseEvent::WebSearchCallBegin { call_id, query: None };
if tx_event.send(Ok(ev)).await.is_err() {
return;
}
}
}
}
}
+14
View File
@@ -34,6 +34,7 @@ use tracing::trace;
use tracing::warn;
use uuid::Uuid;
use codex_login::CodexAuth;
use crate::protocol::WebSearchBeginEvent;
/// Initial submission ID for session configuration
pub(crate) const INITIAL_SUBMIT_ID: &str = "";
@@ -1478,6 +1479,9 @@ async fn submission_loop(
approval_policy,
sandbox_policy.clone(),
config.include_plan_tool,
config.include_apply_patch_tool,
config.tools_web_search_request,
config.use_experimental_streamable_shell_tool,
),
tx_event: tx_event.clone(),
user_instructions,
@@ -2124,6 +2128,16 @@ async fn try_run_turn(
output.push(ProcessedResponseItem { item, response });
}
ResponseEvent::WebSearchCallBegin { call_id, query } => {
let q = query.unwrap_or_else(|| "Searching Web...".to_string());
let _ = sess
.tx_event
.send(Event {
id: sub_id.to_string(),
msg: EventMsg::WebSearchBegin(WebSearchBeginEvent { call_id, query: q }),
})
.await;
}
ResponseEvent::Completed {
response_id: _,
token_usage,
+1 -1
View File
@@ -844,7 +844,7 @@ impl Config {
experimental_resume,
include_plan_tool: include_plan_tool.unwrap_or(false),
include_apply_patch_tool: include_apply_patch_tool.unwrap_or(false),
include_apply_patch_tool: false,
tools_web_search_request,
use_experimental_streamable_shell_tool: false,
responses_originator_header,
+7
View File
@@ -15,6 +15,7 @@ use crate::model_family::ModelFamily;
use crate::plan_tool::PLAN_TOOL;
use crate::protocol::AskForApproval;
use crate::protocol::SandboxPolicy;
use crate::tool_apply_patch::ApplyPatchToolType;
// apply_patch tools are not currently surfaced; keep imports out to avoid warnings.
#[derive(Debug, Clone, Serialize, PartialEq)]
@@ -100,6 +101,12 @@ impl ToolsConfig {
}
}
let apply_patch_tool_type = if include_apply_patch_tool {
model_family.apply_patch_tool_type.clone()
} else {
None
};
Self {
shell_type,
plan_tool: include_plan_tool,
+9
View File
@@ -418,6 +418,9 @@ pub enum EventMsg {
McpToolCallEnd(McpToolCallEndEvent),
/// Model requested a native web search
WebSearchBegin(WebSearchBeginEvent),
/// Custom tool call events for non-MCP tools (browser, agent, etc)
CustomToolCallBegin(CustomToolCallBeginEvent),
CustomToolCallEnd(CustomToolCallEndEvent),
@@ -520,6 +523,12 @@ impl From<TokenUsage> for FinalOutput {
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct WebSearchBeginEvent {
pub call_id: String,
pub query: String,
}
impl fmt::Display for FinalOutput {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let token_usage = &self.token_usage;
+6
View File
@@ -2131,6 +2131,12 @@ impl ChatWidget<'_> {
self.request_redraw();
}
EventMsg::WebSearchBegin(_) => {
// Update status when a web search begins
self.bottom_pane
.update_status_text("searching web".to_string());
self.mark_needs_redraw();
}
EventMsg::AgentMessage(AgentMessageEvent { message }) => {
tracing::debug!("AgentMessage event with message: {:?}...", message.chars().take(100).collect::<String>());
// Use StreamController for final answer
+1
View File
@@ -127,6 +127,7 @@ pub async fn run_main(
disable_response_storage: cli.oss.then_some(true),
show_raw_agent_reasoning: cli.oss.then_some(true),
debug: Some(cli.debug),
tools_web_search_request: cli.web_search.then_some(true),
};
// Parse `-c` overrides from the CLI.