[search] allow explicitly disabling web search (#9249)

moving `web_search` rollout serverside, so need a way to explicitly
disable search + signal eligibility from the client.

- Add `x‑oai‑web‑search‑eligible` header that signifies whether the
request can have web search.
- Only attach the `web_search` tool when the resolved `WebSearchMode` is
`Live` or `Cached`.
This commit is contained in:
sayan-oai
2026-01-15 11:28:57 -08:00
committed by GitHub
parent 42fa4c237f
commit 169201b1b5
11 changed files with 139 additions and 60 deletions

View File

@@ -25,7 +25,7 @@ use std::collections::HashMap;
pub(crate) struct ToolsConfig {
pub shell_type: ConfigShellToolType,
pub apply_patch_tool_type: Option<ApplyPatchToolType>,
pub web_search_mode: WebSearchMode,
pub web_search_mode: Option<WebSearchMode>,
pub collab_tools: bool,
pub experimental_supported_tools: Vec<String>,
}
@@ -33,7 +33,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,
pub(crate) web_search_mode: Option<WebSearchMode>,
}
impl ToolsConfig {
@@ -1244,17 +1244,17 @@ pub(crate) fn build_specs(
}
match config.web_search_mode {
WebSearchMode::Disabled => {}
WebSearchMode::Cached => {
Some(WebSearchMode::Cached) => {
builder.push_spec(ToolSpec::WebSearch {
external_web_access: Some(false),
});
}
WebSearchMode::Live => {
Some(WebSearchMode::Live) => {
builder.push_spec(ToolSpec::WebSearch {
external_web_access: Some(true),
});
}
Some(WebSearchMode::Disabled) | None => {}
}
builder.push_spec_with_parallel_support(create_view_image_tool(), true);
@@ -1398,7 +1398,7 @@ mod tests {
let config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Live,
web_search_mode: Some(WebSearchMode::Live),
});
let (tools, _) = build_specs(&config, None).build();
@@ -1460,7 +1460,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Cached,
web_search_mode: Some(WebSearchMode::Cached),
});
let (tools, _) = build_specs(&tools_config, None).build();
assert_contains_tool_names(
@@ -1472,7 +1472,7 @@ mod tests {
fn assert_model_tools(
model_slug: &str,
features: &Features,
web_search_mode: WebSearchMode,
web_search_mode: Option<WebSearchMode>,
expected_tools: &[&str],
) {
let config = test_config();
@@ -1496,7 +1496,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Cached,
web_search_mode: Some(WebSearchMode::Cached),
});
let (tools, _) = build_specs(&tools_config, None).build();
@@ -1518,7 +1518,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Live,
web_search_mode: Some(WebSearchMode::Live),
});
let (tools, _) = build_specs(&tools_config, None).build();
@@ -1536,7 +1536,7 @@ mod tests {
assert_model_tools(
"gpt-5-codex",
&Features::with_defaults(),
WebSearchMode::Cached,
Some(WebSearchMode::Cached),
&[
"shell_command",
"list_mcp_resources",
@@ -1555,7 +1555,7 @@ mod tests {
assert_model_tools(
"gpt-5.1-codex",
&Features::with_defaults(),
WebSearchMode::Cached,
Some(WebSearchMode::Cached),
&[
"shell_command",
"list_mcp_resources",
@@ -1574,7 +1574,7 @@ mod tests {
assert_model_tools(
"gpt-5-codex",
Features::with_defaults().enable(Feature::UnifiedExec),
WebSearchMode::Live,
Some(WebSearchMode::Live),
&[
"exec_command",
"write_stdin",
@@ -1594,7 +1594,7 @@ mod tests {
assert_model_tools(
"gpt-5.1-codex",
Features::with_defaults().enable(Feature::UnifiedExec),
WebSearchMode::Live,
Some(WebSearchMode::Live),
&[
"exec_command",
"write_stdin",
@@ -1614,7 +1614,7 @@ mod tests {
assert_model_tools(
"codex-mini-latest",
&Features::with_defaults(),
WebSearchMode::Cached,
Some(WebSearchMode::Cached),
&[
"local_shell",
"list_mcp_resources",
@@ -1632,7 +1632,7 @@ mod tests {
assert_model_tools(
"gpt-5.1-codex-mini",
&Features::with_defaults(),
WebSearchMode::Cached,
Some(WebSearchMode::Cached),
&[
"shell_command",
"list_mcp_resources",
@@ -1651,7 +1651,7 @@ mod tests {
assert_model_tools(
"gpt-5",
&Features::with_defaults(),
WebSearchMode::Cached,
Some(WebSearchMode::Cached),
&[
"shell",
"list_mcp_resources",
@@ -1669,7 +1669,7 @@ mod tests {
assert_model_tools(
"gpt-5.1",
&Features::with_defaults(),
WebSearchMode::Cached,
Some(WebSearchMode::Cached),
&[
"shell_command",
"list_mcp_resources",
@@ -1688,7 +1688,7 @@ mod tests {
assert_model_tools(
"exp-5.1",
&Features::with_defaults(),
WebSearchMode::Cached,
Some(WebSearchMode::Cached),
&[
"exec_command",
"write_stdin",
@@ -1708,7 +1708,7 @@ mod tests {
assert_model_tools(
"codex-mini-latest",
Features::with_defaults().enable(Feature::UnifiedExec),
WebSearchMode::Live,
Some(WebSearchMode::Live),
&[
"exec_command",
"write_stdin",
@@ -1731,7 +1731,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Live,
web_search_mode: Some(WebSearchMode::Live),
});
let (tools, _) = build_specs(&tools_config, Some(HashMap::new())).build();
@@ -1753,7 +1753,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Cached,
web_search_mode: Some(WebSearchMode::Cached),
});
let (tools, _) = build_specs(&tools_config, None).build();
@@ -1772,7 +1772,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Cached,
web_search_mode: Some(WebSearchMode::Cached),
});
let (tools, _) = build_specs(&tools_config, None).build();
@@ -1803,7 +1803,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Live,
web_search_mode: Some(WebSearchMode::Live),
});
let (tools, _) = build_specs(
&tools_config,
@@ -1898,7 +1898,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Cached,
web_search_mode: Some(WebSearchMode::Cached),
});
// Intentionally construct a map with keys that would sort alphabetically.
@@ -1975,7 +1975,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Cached,
web_search_mode: Some(WebSearchMode::Cached),
});
let (tools, _) = build_specs(
@@ -2032,7 +2032,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Cached,
web_search_mode: Some(WebSearchMode::Cached),
});
let (tools, _) = build_specs(
@@ -2086,7 +2086,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Cached,
web_search_mode: Some(WebSearchMode::Cached),
});
let (tools, _) = build_specs(
@@ -2142,7 +2142,7 @@ mod tests {
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Cached,
web_search_mode: Some(WebSearchMode::Cached),
});
let (tools, _) = build_specs(
@@ -2254,7 +2254,7 @@ Examples of valid command strings:
let tools_config = ToolsConfig::new(&ToolsConfigParams {
model_info: &model_info,
features: &features,
web_search_mode: WebSearchMode::Cached,
web_search_mode: Some(WebSearchMode::Cached),
});
let (tools, _) = build_specs(
&tools_config,