mirror of
https://github.com/openai/codex.git
synced 2026-04-30 19:32:04 +03:00
add WebSearchMode enum (#9216)
### What Add `WebSearchMode` enum (disabled, cached live, defaults to cached) to config + V2 protocol. This enum takes precedence over legacy flags: `web_search_cached`, `web_search_request`, and `tools.web_search`. Keep `--search` as live. ### Tests Added tests
This commit is contained in:
@@ -8,6 +8,7 @@ use crate::tools::handlers::apply_patch::create_apply_patch_json_tool;
|
||||
use crate::tools::handlers::collab::DEFAULT_WAIT_TIMEOUT_MS;
|
||||
use crate::tools::handlers::collab::MAX_WAIT_TIMEOUT_MS;
|
||||
use crate::tools::registry::ToolRegistryBuilder;
|
||||
use codex_protocol::config_types::WebSearchMode;
|
||||
use codex_protocol::models::VIEW_IMAGE_TOOL_NAME;
|
||||
use codex_protocol::openai_models::ApplyPatchToolType;
|
||||
use codex_protocol::openai_models::ConfigShellToolType;
|
||||
@@ -23,8 +24,7 @@ use std::collections::HashMap;
|
||||
pub(crate) struct ToolsConfig {
|
||||
pub shell_type: ConfigShellToolType,
|
||||
pub apply_patch_tool_type: Option<ApplyPatchToolType>,
|
||||
pub web_search_request: bool,
|
||||
pub web_search_cached: bool,
|
||||
pub web_search_mode: WebSearchMode,
|
||||
pub collab_tools: bool,
|
||||
pub experimental_supported_tools: Vec<String>,
|
||||
}
|
||||
@@ -32,6 +32,7 @@ pub(crate) struct ToolsConfig {
|
||||
pub(crate) struct ToolsConfigParams<'a> {
|
||||
pub(crate) model_info: &'a ModelInfo,
|
||||
pub(crate) features: &'a Features,
|
||||
pub(crate) web_search_mode: WebSearchMode,
|
||||
}
|
||||
|
||||
impl ToolsConfig {
|
||||
@@ -39,10 +40,9 @@ impl ToolsConfig {
|
||||
let ToolsConfigParams {
|
||||
model_info,
|
||||
features,
|
||||
web_search_mode,
|
||||
} = params;
|
||||
let include_apply_patch_tool = features.enabled(Feature::ApplyPatchFreeform);
|
||||
let include_web_search_request = features.enabled(Feature::WebSearchRequest);
|
||||
let include_web_search_cached = features.enabled(Feature::WebSearchCached);
|
||||
let include_collab_tools = features.enabled(Feature::Collab);
|
||||
|
||||
let shell_type = if !features.enabled(Feature::ShellTool) {
|
||||
@@ -73,8 +73,7 @@ impl ToolsConfig {
|
||||
Self {
|
||||
shell_type,
|
||||
apply_patch_tool_type,
|
||||
web_search_request: include_web_search_request,
|
||||
web_search_cached: include_web_search_cached,
|
||||
web_search_mode: *web_search_mode,
|
||||
collab_tools: include_collab_tools,
|
||||
experimental_supported_tools: model_info.experimental_supported_tools.clone(),
|
||||
}
|
||||
@@ -1225,15 +1224,18 @@ pub(crate) fn build_specs(
|
||||
builder.register_handler("test_sync_tool", test_sync_handler);
|
||||
}
|
||||
|
||||
// Prefer web_search_cached flag over web_search_request
|
||||
if config.web_search_cached {
|
||||
builder.push_spec(ToolSpec::WebSearch {
|
||||
external_web_access: Some(false),
|
||||
});
|
||||
} else if config.web_search_request {
|
||||
builder.push_spec(ToolSpec::WebSearch {
|
||||
external_web_access: Some(true),
|
||||
});
|
||||
match config.web_search_mode {
|
||||
WebSearchMode::Disabled => {}
|
||||
WebSearchMode::Cached => {
|
||||
builder.push_spec(ToolSpec::WebSearch {
|
||||
external_web_access: Some(false),
|
||||
});
|
||||
}
|
||||
WebSearchMode::Live => {
|
||||
builder.push_spec(ToolSpec::WebSearch {
|
||||
external_web_access: Some(true),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
builder.push_spec_with_parallel_support(create_view_image_tool(), true);
|
||||
@@ -1374,10 +1376,10 @@ mod tests {
|
||||
let model_info = ModelsManager::construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
features.enable(Feature::WebSearchRequest);
|
||||
let config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Live,
|
||||
});
|
||||
let (tools, _) = build_specs(&config, None).build();
|
||||
|
||||
@@ -1439,6 +1441,7 @@ mod tests {
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Cached,
|
||||
});
|
||||
let (tools, _) = build_specs(&tools_config, None).build();
|
||||
assert_contains_tool_names(
|
||||
@@ -1447,12 +1450,18 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
fn assert_model_tools(model_slug: &str, features: &Features, expected_tools: &[&str]) {
|
||||
fn assert_model_tools(
|
||||
model_slug: &str,
|
||||
features: &Features,
|
||||
web_search_mode: WebSearchMode,
|
||||
expected_tools: &[&str],
|
||||
) {
|
||||
let config = test_config();
|
||||
let model_info = ModelsManager::construct_model_info_offline(model_slug, &config);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features,
|
||||
web_search_mode,
|
||||
});
|
||||
let (tools, _) = build_specs(&tools_config, Some(HashMap::new())).build();
|
||||
let tool_names = tools.iter().map(|t| t.spec.name()).collect::<Vec<_>>();
|
||||
@@ -1460,15 +1469,15 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn web_search_cached_sets_external_web_access_false() {
|
||||
fn web_search_mode_cached_sets_external_web_access_false() {
|
||||
let config = test_config();
|
||||
let model_info = ModelsManager::construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::WebSearchCached);
|
||||
let features = Features::with_defaults();
|
||||
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Cached,
|
||||
});
|
||||
let (tools, _) = build_specs(&tools_config, None).build();
|
||||
|
||||
@@ -1482,16 +1491,15 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn web_search_cached_takes_precedence_over_web_search_request() {
|
||||
fn web_search_mode_live_sets_external_web_access_true() {
|
||||
let config = test_config();
|
||||
let model_info = ModelsManager::construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::WebSearchCached);
|
||||
features.enable(Feature::WebSearchRequest);
|
||||
let features = Features::with_defaults();
|
||||
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Live,
|
||||
});
|
||||
let (tools, _) = build_specs(&tools_config, None).build();
|
||||
|
||||
@@ -1499,7 +1507,7 @@ mod tests {
|
||||
assert_eq!(
|
||||
tool.spec,
|
||||
ToolSpec::WebSearch {
|
||||
external_web_access: Some(false),
|
||||
external_web_access: Some(true),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -1509,6 +1517,7 @@ mod tests {
|
||||
assert_model_tools(
|
||||
"gpt-5-codex",
|
||||
&Features::with_defaults(),
|
||||
WebSearchMode::Cached,
|
||||
&[
|
||||
"shell_command",
|
||||
"list_mcp_resources",
|
||||
@@ -1516,6 +1525,7 @@ mod tests {
|
||||
"read_mcp_resource",
|
||||
"update_plan",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
],
|
||||
);
|
||||
@@ -1526,6 +1536,7 @@ mod tests {
|
||||
assert_model_tools(
|
||||
"gpt-5.1-codex",
|
||||
&Features::with_defaults(),
|
||||
WebSearchMode::Cached,
|
||||
&[
|
||||
"shell_command",
|
||||
"list_mcp_resources",
|
||||
@@ -1533,6 +1544,7 @@ mod tests {
|
||||
"read_mcp_resource",
|
||||
"update_plan",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
],
|
||||
);
|
||||
@@ -1542,9 +1554,8 @@ mod tests {
|
||||
fn test_build_specs_gpt5_codex_unified_exec_web_search() {
|
||||
assert_model_tools(
|
||||
"gpt-5-codex",
|
||||
Features::with_defaults()
|
||||
.enable(Feature::UnifiedExec)
|
||||
.enable(Feature::WebSearchRequest),
|
||||
Features::with_defaults().enable(Feature::UnifiedExec),
|
||||
WebSearchMode::Live,
|
||||
&[
|
||||
"exec_command",
|
||||
"write_stdin",
|
||||
@@ -1563,9 +1574,8 @@ mod tests {
|
||||
fn test_build_specs_gpt51_codex_unified_exec_web_search() {
|
||||
assert_model_tools(
|
||||
"gpt-5.1-codex",
|
||||
Features::with_defaults()
|
||||
.enable(Feature::UnifiedExec)
|
||||
.enable(Feature::WebSearchRequest),
|
||||
Features::with_defaults().enable(Feature::UnifiedExec),
|
||||
WebSearchMode::Live,
|
||||
&[
|
||||
"exec_command",
|
||||
"write_stdin",
|
||||
@@ -1585,12 +1595,14 @@ mod tests {
|
||||
assert_model_tools(
|
||||
"codex-mini-latest",
|
||||
&Features::with_defaults(),
|
||||
WebSearchMode::Cached,
|
||||
&[
|
||||
"local_shell",
|
||||
"list_mcp_resources",
|
||||
"list_mcp_resource_templates",
|
||||
"read_mcp_resource",
|
||||
"update_plan",
|
||||
"web_search",
|
||||
"view_image",
|
||||
],
|
||||
);
|
||||
@@ -1601,6 +1613,7 @@ mod tests {
|
||||
assert_model_tools(
|
||||
"gpt-5.1-codex-mini",
|
||||
&Features::with_defaults(),
|
||||
WebSearchMode::Cached,
|
||||
&[
|
||||
"shell_command",
|
||||
"list_mcp_resources",
|
||||
@@ -1608,6 +1621,7 @@ mod tests {
|
||||
"read_mcp_resource",
|
||||
"update_plan",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
],
|
||||
);
|
||||
@@ -1618,12 +1632,14 @@ mod tests {
|
||||
assert_model_tools(
|
||||
"gpt-5",
|
||||
&Features::with_defaults(),
|
||||
WebSearchMode::Cached,
|
||||
&[
|
||||
"shell",
|
||||
"list_mcp_resources",
|
||||
"list_mcp_resource_templates",
|
||||
"read_mcp_resource",
|
||||
"update_plan",
|
||||
"web_search",
|
||||
"view_image",
|
||||
],
|
||||
);
|
||||
@@ -1634,6 +1650,7 @@ mod tests {
|
||||
assert_model_tools(
|
||||
"gpt-5.1",
|
||||
&Features::with_defaults(),
|
||||
WebSearchMode::Cached,
|
||||
&[
|
||||
"shell_command",
|
||||
"list_mcp_resources",
|
||||
@@ -1641,6 +1658,7 @@ mod tests {
|
||||
"read_mcp_resource",
|
||||
"update_plan",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
],
|
||||
);
|
||||
@@ -1651,6 +1669,7 @@ mod tests {
|
||||
assert_model_tools(
|
||||
"exp-5.1",
|
||||
&Features::with_defaults(),
|
||||
WebSearchMode::Cached,
|
||||
&[
|
||||
"exec_command",
|
||||
"write_stdin",
|
||||
@@ -1659,6 +1678,7 @@ mod tests {
|
||||
"read_mcp_resource",
|
||||
"update_plan",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
],
|
||||
);
|
||||
@@ -1668,9 +1688,8 @@ mod tests {
|
||||
fn test_codex_mini_unified_exec_web_search() {
|
||||
assert_model_tools(
|
||||
"codex-mini-latest",
|
||||
Features::with_defaults()
|
||||
.enable(Feature::UnifiedExec)
|
||||
.enable(Feature::WebSearchRequest),
|
||||
Features::with_defaults().enable(Feature::UnifiedExec),
|
||||
WebSearchMode::Live,
|
||||
&[
|
||||
"exec_command",
|
||||
"write_stdin",
|
||||
@@ -1689,11 +1708,11 @@ mod tests {
|
||||
let config = test_config();
|
||||
let model_info = ModelsManager::construct_model_info_offline("o3", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::WebSearchRequest);
|
||||
features.enable(Feature::UnifiedExec);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Live,
|
||||
});
|
||||
let (tools, _) = build_specs(&tools_config, Some(HashMap::new())).build();
|
||||
|
||||
@@ -1715,6 +1734,7 @@ mod tests {
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Cached,
|
||||
});
|
||||
let (tools, _) = build_specs(&tools_config, None).build();
|
||||
|
||||
@@ -1733,6 +1753,7 @@ mod tests {
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Cached,
|
||||
});
|
||||
let (tools, _) = build_specs(&tools_config, None).build();
|
||||
|
||||
@@ -1760,10 +1781,10 @@ mod tests {
|
||||
let model_info = ModelsManager::construct_model_info_offline("o3", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
features.enable(Feature::WebSearchRequest);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Live,
|
||||
});
|
||||
let (tools, _) = build_specs(
|
||||
&tools_config,
|
||||
@@ -1858,6 +1879,7 @@ mod tests {
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Cached,
|
||||
});
|
||||
|
||||
// Intentionally construct a map with keys that would sort alphabetically.
|
||||
@@ -1931,10 +1953,10 @@ mod tests {
|
||||
let model_info = ModelsManager::construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
features.enable(Feature::WebSearchRequest);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Cached,
|
||||
});
|
||||
|
||||
let (tools, _) = build_specs(
|
||||
@@ -1988,10 +2010,10 @@ mod tests {
|
||||
let model_info = ModelsManager::construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
features.enable(Feature::WebSearchRequest);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Cached,
|
||||
});
|
||||
|
||||
let (tools, _) = build_specs(
|
||||
@@ -2041,11 +2063,11 @@ mod tests {
|
||||
let model_info = ModelsManager::construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
features.enable(Feature::WebSearchRequest);
|
||||
features.enable(Feature::ApplyPatchFreeform);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Cached,
|
||||
});
|
||||
|
||||
let (tools, _) = build_specs(
|
||||
@@ -2098,10 +2120,10 @@ mod tests {
|
||||
let model_info = ModelsManager::construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
features.enable(Feature::WebSearchRequest);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Cached,
|
||||
});
|
||||
|
||||
let (tools, _) = build_specs(
|
||||
@@ -2210,10 +2232,10 @@ Examples of valid command strings:
|
||||
let model_info = ModelsManager::construct_model_info_offline("gpt-5-codex", &config);
|
||||
let mut features = Features::with_defaults();
|
||||
features.enable(Feature::UnifiedExec);
|
||||
features.enable(Feature::WebSearchRequest);
|
||||
let tools_config = ToolsConfig::new(&ToolsConfigParams {
|
||||
model_info: &model_info,
|
||||
features: &features,
|
||||
web_search_mode: WebSearchMode::Cached,
|
||||
});
|
||||
let (tools, _) = build_specs(
|
||||
&tools_config,
|
||||
|
||||
Reference in New Issue
Block a user