diff --git a/codex-rs/core/src/config/mod.rs b/codex-rs/core/src/config/mod.rs index 2778c03a7..4e49efabd 100644 --- a/codex-rs/core/src/config/mod.rs +++ b/codex-rs/core/src/config/mod.rs @@ -1203,11 +1203,13 @@ pub fn resolve_oss_provider( } } -/// Resolve the web search mode from explicit config and feature flags. +/// Resolve the web search mode from explicit config, feature flags, and sandbox policy. +/// Live search is auto-enabled when sandbox policy is `DangerFullAccess` fn resolve_web_search_mode( config_toml: &ConfigToml, config_profile: &ConfigProfile, features: &Features, + sandbox_policy: &SandboxPolicy, ) -> WebSearchMode { if let Some(mode) = config_profile.web_search.or(config_toml.web_search) { return mode; @@ -1218,6 +1220,9 @@ fn resolve_web_search_mode( if features.enabled(Feature::WebSearchRequest) { return WebSearchMode::Live; } + if matches!(sandbox_policy, SandboxPolicy::DangerFullAccess) { + return WebSearchMode::Live; + } WebSearchMode::Cached } @@ -1287,7 +1292,6 @@ impl Config { }; let features = Features::from_config(&cfg, &config_profile, feature_overrides); - let web_search_mode = resolve_web_search_mode(&cfg, &config_profile, &features); let resolved_cwd = { use std::env; @@ -1343,6 +1347,8 @@ impl Config { AskForApproval::default() } }); + let web_search_mode = + resolve_web_search_mode(&cfg, &config_profile, &features, &sandbox_policy); // TODO(dylan): We should be able to leverage ConfigLayerStack so that // we can reliably check this at every config level. let did_user_set_custom_approval_policy_or_sandbox_mode = approval_policy_override @@ -2271,7 +2277,7 @@ trust_level = "trusted" let features = Features::with_defaults(); assert_eq!( - resolve_web_search_mode(&cfg, &profile, &features), + resolve_web_search_mode(&cfg, &profile, &features, &SandboxPolicy::ReadOnly), WebSearchMode::Cached ); } @@ -2287,7 +2293,7 @@ trust_level = "trusted" features.enable(Feature::WebSearchCached); assert_eq!( - resolve_web_search_mode(&cfg, &profile, &features), + resolve_web_search_mode(&cfg, &profile, &features, &SandboxPolicy::ReadOnly), WebSearchMode::Live ); } @@ -2303,11 +2309,50 @@ trust_level = "trusted" features.enable(Feature::WebSearchRequest); assert_eq!( - resolve_web_search_mode(&cfg, &profile, &features), + resolve_web_search_mode(&cfg, &profile, &features, &SandboxPolicy::ReadOnly), WebSearchMode::Disabled ); } + #[test] + fn danger_full_access_defaults_web_search_live_when_unset() -> std::io::Result<()> { + let codex_home = TempDir::new()?; + let cfg = ConfigToml { + sandbox_mode: Some(SandboxMode::DangerFullAccess), + ..Default::default() + }; + + let config = Config::load_from_base_config_with_overrides( + cfg, + ConfigOverrides::default(), + codex_home.path().to_path_buf(), + )?; + + assert_eq!(config.web_search_mode, WebSearchMode::Live); + + Ok(()) + } + + #[test] + fn explicit_web_search_mode_wins_in_danger_full_access() -> std::io::Result<()> { + let codex_home = TempDir::new()?; + let cfg = ConfigToml { + sandbox_mode: Some(SandboxMode::DangerFullAccess), + web_search: Some(WebSearchMode::Cached), + ..Default::default() + }; + + let config = Config::load_from_base_config_with_overrides( + cfg, + ConfigOverrides::default(), + codex_home.path().to_path_buf(), + )?; + + assert_eq!(config.web_search_mode, WebSearchMode::Cached); + + Ok(()) + } + #[test] fn profile_legacy_toggles_override_base() -> std::io::Result<()> { let codex_home = TempDir::new()?;