mirror of
https://github.com/openai/codex.git
synced 2026-04-30 11:21:34 +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:
@@ -1,5 +1,6 @@
|
||||
#![allow(clippy::unwrap_used)]
|
||||
|
||||
use codex_protocol::config_types::WebSearchMode;
|
||||
use core_test_support::load_sse_fixture_with_id;
|
||||
use core_test_support::responses;
|
||||
use core_test_support::responses::start_mock_server;
|
||||
@@ -32,7 +33,10 @@ async fn collect_tool_identifiers_for_model(model: &str) -> Vec<String> {
|
||||
let sse = sse_completed(model);
|
||||
let resp_mock = responses::mount_sse_once(&server, sse).await;
|
||||
|
||||
let mut builder = test_codex().with_model(model);
|
||||
let mut builder = test_codex()
|
||||
.with_model(model)
|
||||
// Keep tool expectations stable when the default web_search mode changes.
|
||||
.with_config(|config| config.web_search_mode = WebSearchMode::Cached);
|
||||
let test = builder
|
||||
.build(&server)
|
||||
.await
|
||||
@@ -58,6 +62,7 @@ async fn model_selects_expected_tools() {
|
||||
"list_mcp_resource_templates".to_string(),
|
||||
"read_mcp_resource".to_string(),
|
||||
"update_plan".to_string(),
|
||||
"web_search".to_string(),
|
||||
"view_image".to_string()
|
||||
],
|
||||
"codex-mini-latest should expose the local shell tool",
|
||||
@@ -73,6 +78,7 @@ async fn model_selects_expected_tools() {
|
||||
"read_mcp_resource".to_string(),
|
||||
"update_plan".to_string(),
|
||||
"apply_patch".to_string(),
|
||||
"web_search".to_string(),
|
||||
"view_image".to_string()
|
||||
],
|
||||
"gpt-5-codex should expose the apply_patch tool",
|
||||
@@ -88,6 +94,7 @@ async fn model_selects_expected_tools() {
|
||||
"read_mcp_resource".to_string(),
|
||||
"update_plan".to_string(),
|
||||
"apply_patch".to_string(),
|
||||
"web_search".to_string(),
|
||||
"view_image".to_string()
|
||||
],
|
||||
"gpt-5.1-codex should expose the apply_patch tool",
|
||||
@@ -102,6 +109,7 @@ async fn model_selects_expected_tools() {
|
||||
"list_mcp_resource_templates".to_string(),
|
||||
"read_mcp_resource".to_string(),
|
||||
"update_plan".to_string(),
|
||||
"web_search".to_string(),
|
||||
"view_image".to_string()
|
||||
],
|
||||
"gpt-5 should expose the apply_patch tool",
|
||||
@@ -117,6 +125,7 @@ async fn model_selects_expected_tools() {
|
||||
"read_mcp_resource".to_string(),
|
||||
"update_plan".to_string(),
|
||||
"apply_patch".to_string(),
|
||||
"web_search".to_string(),
|
||||
"view_image".to_string()
|
||||
],
|
||||
"gpt-5.1 should expose the apply_patch tool",
|
||||
@@ -132,6 +141,7 @@ async fn model_selects_expected_tools() {
|
||||
"read_mcp_resource".to_string(),
|
||||
"update_plan".to_string(),
|
||||
"apply_patch".to_string(),
|
||||
"web_search".to_string(),
|
||||
"view_image".to_string()
|
||||
],
|
||||
"exp-5.1 should expose the apply_patch tool",
|
||||
|
||||
@@ -11,6 +11,7 @@ use codex_core::protocol::SandboxPolicy;
|
||||
use codex_core::protocol_config_types::ReasoningSummary;
|
||||
use codex_core::shell::Shell;
|
||||
use codex_core::shell::default_user_shell;
|
||||
use codex_protocol::config_types::WebSearchMode;
|
||||
use codex_protocol::openai_models::ReasoningEffort;
|
||||
use codex_protocol::user_input::UserInput;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
@@ -52,7 +53,13 @@ fn assert_tool_names(body: &serde_json::Value, expected_names: &[&str]) {
|
||||
.as_array()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|t| t["name"].as_str().unwrap().to_string())
|
||||
.map(|t| {
|
||||
t.get("name")
|
||||
.and_then(|value| value.as_str())
|
||||
.or_else(|| t.get("type").and_then(|value| value.as_str()))
|
||||
.unwrap()
|
||||
.to_string()
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
expected_names
|
||||
);
|
||||
@@ -80,6 +87,8 @@ async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> {
|
||||
.with_config(|config| {
|
||||
config.user_instructions = Some("be consistent and helpful".to_string());
|
||||
config.model = Some("gpt-5.1-codex-max".to_string());
|
||||
// Keep tool expectations stable when the default web_search mode changes.
|
||||
config.web_search_mode = WebSearchMode::Cached;
|
||||
})
|
||||
.build(&server)
|
||||
.await?;
|
||||
@@ -122,6 +131,7 @@ async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> {
|
||||
"read_mcp_resource",
|
||||
"update_plan",
|
||||
"apply_patch",
|
||||
"web_search",
|
||||
"view_image",
|
||||
];
|
||||
let body0 = req1.single_request().body_json();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#![allow(clippy::unwrap_used)]
|
||||
|
||||
use codex_core::features::Feature;
|
||||
use codex_protocol::config_types::WebSearchMode;
|
||||
use core_test_support::load_sse_fixture_with_id;
|
||||
use core_test_support::responses;
|
||||
use core_test_support::responses::start_mock_server;
|
||||
@@ -24,7 +25,7 @@ fn find_web_search_tool(body: &Value) -> &Value {
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn web_search_cached_sets_external_web_access_false_in_request_body() {
|
||||
async fn web_search_mode_cached_sets_external_web_access_false_in_request_body() {
|
||||
skip_if_no_network!();
|
||||
|
||||
let server = start_mock_server().await;
|
||||
@@ -34,7 +35,7 @@ async fn web_search_cached_sets_external_web_access_false_in_request_body() {
|
||||
let mut builder = test_codex()
|
||||
.with_model("gpt-5-codex")
|
||||
.with_config(|config| {
|
||||
config.features.enable(Feature::WebSearchCached);
|
||||
config.web_search_mode = WebSearchMode::Cached;
|
||||
});
|
||||
let test = builder
|
||||
.build(&server)
|
||||
@@ -50,12 +51,12 @@ async fn web_search_cached_sets_external_web_access_false_in_request_body() {
|
||||
assert_eq!(
|
||||
tool.get("external_web_access").and_then(Value::as_bool),
|
||||
Some(false),
|
||||
"web_search_cached should force external_web_access=false"
|
||||
"web_search cached mode should force external_web_access=false"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn web_search_cached_takes_precedence_over_web_search_request_in_request_body() {
|
||||
async fn web_search_mode_takes_precedence_over_legacy_flags_in_request_body() {
|
||||
skip_if_no_network!();
|
||||
|
||||
let server = start_mock_server().await;
|
||||
@@ -66,7 +67,7 @@ async fn web_search_cached_takes_precedence_over_web_search_request_in_request_b
|
||||
.with_model("gpt-5-codex")
|
||||
.with_config(|config| {
|
||||
config.features.enable(Feature::WebSearchRequest);
|
||||
config.features.enable(Feature::WebSearchCached);
|
||||
config.web_search_mode = WebSearchMode::Cached;
|
||||
});
|
||||
let test = builder
|
||||
.build(&server)
|
||||
@@ -82,6 +83,6 @@ async fn web_search_cached_takes_precedence_over_web_search_request_in_request_b
|
||||
assert_eq!(
|
||||
tool.get("external_web_access").and_then(Value::as_bool),
|
||||
Some(false),
|
||||
"web_search_cached should win over web_search_request"
|
||||
"web_search mode should win over legacy web_search_request"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user