F5: web search/fetch on the Kimi services (kimi-cli parity)

web_search now speaks the Kimi search service (kimi-cli tools/web/search.py,
wire-verified against api.kimi.com):
- POST {coding_base}/search with {text_query, limit 1-20 (default 5),
  enable_page_crawling, timeout_seconds: 30}, OAuth bearer +
  X-Msh-Tool-Call-Id; results render in kimi-cli's Title/Date/URL/Summary
  schema with result URLs as citations.
- The old implementation called the xAI Responses API with a search model;
  that client is fully replaced and the entire model-based config surface
  is excised root-and-branch: web_search_model config keys/env/CLI plumbing,
  resolve_web_search_sampling_config, toolset web_search SamplerConfig,
  RemoteSettings.web_search_model, default_web_search_model.
- Enablement is now purely structural: the service exists only on the Kimi
  Code subscription channel, so OAuth sessions get Enabled and API-key-only
  sessions get Disabled (tool absent) — per PRD F5.

web_fetch gains the Kimi fetch service as its primary path (kimi-cli
tools/web/fetch.py): POST {coding_base}/fetch with {url}, Accept:
text/markdown, OAuth bearer + X-Msh-Tool-Call-Id; the 200 body is the
extracted markdown (still overflow-budgeted). Any service failure falls
back to the existing local pipeline (SSRF guards, cache, extraction).
The tool gate defaults ON now (kimi-cli always offers FetchURL) and the
egress User-Agent no longer claims grok-agent/x.ai.

Verified end-to-end against the scripted mock service: a headless session
drove web_search (limit/crawling/call-id observed on the wire) then
web_fetch (Accept + call-id observed) to completion.
This commit is contained in:
2026-07-17 19:33:19 -04:00
parent 78cd94a751
commit 74b210535e
34 changed files with 659 additions and 1209 deletions
+1 -30
View File
@@ -531,10 +531,9 @@ impl ManagedMcpsConfig {
}
}
/// Auxiliary model overrides under `[models]`.
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize)]
#[serde(default)]
pub struct ModelOverrideConfig {
pub web_search: String,
/// `None` = current model.
pub session_summary: Option<String>,
/// Compiled default (`kigi_models::default_model()`) when unset locally, remotely, and via env.
@@ -544,16 +543,6 @@ pub struct ModelOverrideConfig {
#[serde(skip)]
pub prompt_suggestion: PromptSuggestModelPin,
}
impl Default for ModelOverrideConfig {
fn default() -> Self {
Self {
web_search: crate::models::default_web_search_model().to_owned(),
session_summary: None,
image_description: None,
prompt_suggestion: PromptSuggestModelPin::Unpinned,
}
}
}
/// Resolved model pin for the next-prompt suggestion call (tab-autocomplete
/// ghost text), `env > config.toml > remote` — see
/// [`ModelOverrideConfig::resolve`].
@@ -600,7 +589,6 @@ impl ModelOverrideConfig {
/// a model string (no CLI flag; the default and the catalog guard live at
/// the consumer, `handle_suggest_prompt`).
pub fn resolve(
cli_web_search_model: Option<&str>,
cli_session_summary_model: Option<&str>,
config: &toml::Value,
remote: Option<&crate::util::config::RemoteSettings>,
@@ -610,16 +598,12 @@ impl ModelOverrideConfig {
.and_then(|v| v.clone().try_into().ok())
.unwrap_or_default();
let mut result = Self {
web_search: parsed_models
.web_search
.unwrap_or_else(|| crate::models::default_web_search_model().to_owned()),
session_summary: non_empty_model_override(parsed_models.session_summary.as_deref()),
image_description: non_empty_model_override(parsed_models.image_description.as_deref()),
prompt_suggestion: non_empty_model_override(parsed_models.prompt_suggestion.as_deref())
.map(PromptSuggestModelPin::Pinned)
.unwrap_or_default(),
};
let has_local_ws = models_table.and_then(|m| m.get("web_search")).is_some();
let has_local_ss = models_table
.and_then(|m| m.get("session_summary"))
.is_some();
@@ -627,9 +611,6 @@ impl ModelOverrideConfig {
.and_then(|m| m.get("image_description"))
.is_some();
if let Some(remote) = remote {
if !has_local_ws && let Some(ref v) = remote.web_search_model {
result.web_search = v.clone();
}
if !has_local_ss {
result.session_summary =
non_empty_model_override(remote.session_summary_model.as_deref());
@@ -644,12 +625,6 @@ impl ModelOverrideConfig {
result.prompt_suggestion = PromptSuggestModelPin::Pinned(v);
}
}
if let Ok(v) = std::env::var("KIGI_WEB_SEARCH_MODEL") {
let v = v.trim();
if !v.is_empty() {
result.web_search = v.to_owned();
}
}
if let Ok(v) = std::env::var("KIGI_SESSION_SUMMARY_MODEL") {
result.session_summary = non_empty_model_override(Some(v.as_str()));
}
@@ -661,9 +636,6 @@ impl ModelOverrideConfig {
{
result.prompt_suggestion = PromptSuggestModelPin::Env(v);
}
if let Some(v) = cli_web_search_model {
result.web_search = v.to_owned();
}
if let Some(v) = cli_session_summary_model {
result.session_summary = non_empty_model_override(Some(v));
}
@@ -1085,7 +1057,6 @@ fn apply_requirements_inner(
};
}
enforce_str!("models", "default", config.models.default);
enforce_str!("models", "web_search", config.models.web_search);
enforce_str!("cli", "channel", config.cli.channel);
enforce_str!("cli", "minimum_version", config.cli.minimum_version);
if let Some(val) = req_str(req, "endpoints", "xai_api_base_url")
+28 -111
View File
@@ -1350,7 +1350,6 @@ fn managed_mcp_gateway_tools_enabled_with_managed_master() {
);
}
fn with_model_overrides_env_full<T>(
ws: Option<&str>,
ss: Option<&str>,
id: Option<&str>,
ps: Option<&str>,
@@ -1359,95 +1358,35 @@ fn with_model_overrides_env_full<T>(
static LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
let _guard = LOCK.lock().unwrap_or_else(|e| e.into_inner());
with_env_var_opt(
"KIGI_WEB_SEARCH_MODEL",
ws,
"KIGI_SESSION_SUMMARY_MODEL",
ss,
|| with_env_var_opt(
"KIGI_SESSION_SUMMARY_MODEL",
ss,
|| with_env_var_opt(
"KIGI_IMAGE_DESCRIPTION_MODEL",
id,
|| with_env_var_opt("KIGI_PROMPT_SUGGESTIONS_MODEL", ps, f),
),
"KIGI_IMAGE_DESCRIPTION_MODEL",
id,
|| with_env_var_opt("KIGI_PROMPT_SUGGESTIONS_MODEL", ps, f),
),
)
}
fn with_model_overrides_env<T>(
ws: Option<&str>,
ss: Option<&str>,
id: Option<&str>,
f: impl FnOnce() -> T,
) -> T {
with_model_overrides_env_full(ws, ss, id, None, f)
}
#[test]
fn model_overrides_remote_settings_blocked_by_local_config() {
with_model_overrides_env(
None,
None,
None,
|| {
let config: toml::Value = toml::from_str(
r#"
[models]
web_search = "local-ws"
"#,
)
.unwrap();
let remote = crate::util::config::RemoteSettings {
web_search_model: Some("remote-ws".to_owned()),
session_summary_model: Some("remote-ss".to_owned()),
image_description_model: Some("remote-id".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &config, Some(&remote));
assert_eq!(cfg.web_search, "local-ws");
assert_eq!(cfg.session_summary, Some("remote-ss".to_owned()));
assert_eq!(cfg.image_description, Some("remote-id".to_owned()));
},
);
}
#[test]
fn model_overrides_cli_overrides_everything() {
with_model_overrides_env(
Some("env-ws"),
Some("env-ss"),
None,
|| {
let config: toml::Value = toml::from_str(
r#"
[models]
web_search = "local-ws"
"#,
)
.unwrap();
let cfg = ModelOverrideConfig::resolve(
Some("cli-ws"),
Some("cli-ss"),
&config,
None,
);
assert_eq!(cfg.web_search, "cli-ws");
assert_eq!(cfg.session_summary, Some("cli-ss".to_owned()));
},
);
with_model_overrides_env_full(ss, id, None, f)
}
#[test]
fn model_overrides_remote_settings_applies_without_local_config() {
with_model_overrides_env(
None,
None,
None,
|| {
let empty = toml::Value::Table(toml::map::Map::new());
let remote = crate::util::config::RemoteSettings {
web_search_model: Some("remote-ws".to_owned()),
session_summary_model: Some("remote-ss".to_owned()),
image_description_model: Some("remote-id".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &empty, Some(&remote));
assert_eq!(cfg.web_search, "remote-ws");
let cfg = ModelOverrideConfig::resolve(None, &empty, Some(&remote));
assert_eq!(cfg.session_summary, Some("remote-ss".to_owned()));
assert_eq!(cfg.image_description, Some("remote-id".to_owned()));
},
@@ -1456,7 +1395,6 @@ fn model_overrides_remote_settings_applies_without_local_config() {
#[test]
fn model_overrides_local_image_description_wins_over_remote() {
with_model_overrides_env(
None,
None,
None,
|| {
@@ -1471,7 +1409,7 @@ fn model_overrides_local_image_description_wins_over_remote() {
image_description_model: Some("remote-id".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &config, Some(&remote));
let cfg = ModelOverrideConfig::resolve(None, &config, Some(&remote));
assert_eq!(cfg.image_description, Some("local-id".to_owned()));
},
);
@@ -1479,12 +1417,11 @@ fn model_overrides_local_image_description_wins_over_remote() {
#[test]
fn model_overrides_default_image_description_is_grok_build() {
with_model_overrides_env(
None,
None,
None,
|| {
let empty = toml::Value::Table(toml::map::Map::new());
let cfg = ModelOverrideConfig::resolve(None, None, &empty, None);
let cfg = ModelOverrideConfig::resolve(None, &empty, None);
assert_eq!(
cfg.image_description, Some(crate
::models::default_image_description_model().to_owned())
@@ -1495,12 +1432,11 @@ fn model_overrides_default_image_description_is_grok_build() {
#[test]
fn model_overrides_default_session_summary_is_grok_build() {
with_model_overrides_env(
None,
None,
None,
|| {
let empty = toml::Value::Table(toml::map::Map::new());
let cfg = ModelOverrideConfig::resolve(None, None, &empty, None);
let cfg = ModelOverrideConfig::resolve(None, &empty, None);
assert_eq!(
cfg.session_summary, Some(crate ::models::default_session_summary_model()
.to_owned())
@@ -1511,7 +1447,6 @@ fn model_overrides_default_session_summary_is_grok_build() {
#[test]
fn model_overrides_local_session_summary_wins_over_remote() {
with_model_overrides_env(
None,
None,
None,
|| {
@@ -1526,7 +1461,7 @@ fn model_overrides_local_session_summary_wins_over_remote() {
session_summary_model: Some("remote-ss".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &config, Some(&remote));
let cfg = ModelOverrideConfig::resolve(None, &config, Some(&remote));
assert_eq!(cfg.session_summary, Some("local-ss".to_owned()));
},
);
@@ -1534,7 +1469,6 @@ fn model_overrides_local_session_summary_wins_over_remote() {
#[test]
fn model_overrides_env_session_summary_overrides_remote() {
with_model_overrides_env(
None,
Some("env-ss"),
None,
|| {
@@ -1543,7 +1477,7 @@ fn model_overrides_env_session_summary_overrides_remote() {
session_summary_model: Some("remote-ss".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &empty, Some(&remote));
let cfg = ModelOverrideConfig::resolve(None, &empty, Some(&remote));
assert_eq!(cfg.session_summary, Some("env-ss".to_owned()));
},
);
@@ -1551,7 +1485,6 @@ fn model_overrides_env_session_summary_overrides_remote() {
#[test]
fn model_overrides_env_session_summary_overrides_local() {
with_model_overrides_env(
None,
Some("env-ss"),
None,
|| {
@@ -1562,7 +1495,7 @@ fn model_overrides_env_session_summary_overrides_local() {
"#,
)
.unwrap();
let cfg = ModelOverrideConfig::resolve(None, None, &config, None);
let cfg = ModelOverrideConfig::resolve(None, &config, None);
assert_eq!(cfg.session_summary, Some("env-ss".to_owned()));
},
);
@@ -1570,7 +1503,6 @@ fn model_overrides_env_session_summary_overrides_local() {
#[test]
fn model_overrides_empty_session_summary_toml_uses_default() {
with_model_overrides_env(
None,
None,
None,
|| {
@@ -1581,7 +1513,7 @@ fn model_overrides_empty_session_summary_toml_uses_default() {
"#,
)
.unwrap();
let cfg = ModelOverrideConfig::resolve(None, None, &config, None);
let cfg = ModelOverrideConfig::resolve(None, &config, None);
assert_eq!(
cfg.session_summary, Some(crate ::models::default_session_summary_model()
.to_owned())
@@ -1592,7 +1524,6 @@ fn model_overrides_empty_session_summary_toml_uses_default() {
#[test]
fn model_overrides_empty_session_summary_remote_uses_default() {
with_model_overrides_env(
None,
None,
None,
|| {
@@ -1601,7 +1532,7 @@ fn model_overrides_empty_session_summary_remote_uses_default() {
session_summary_model: Some(" ".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &empty, Some(&remote));
let cfg = ModelOverrideConfig::resolve(None, &empty, Some(&remote));
assert_eq!(
cfg.session_summary, Some(crate ::models::default_session_summary_model()
.to_owned())
@@ -1612,7 +1543,6 @@ fn model_overrides_empty_session_summary_remote_uses_default() {
#[test]
fn model_overrides_cli_session_summary_overrides_everything() {
with_model_overrides_env(
None,
Some("env-ss"),
None,
|| {
@@ -1628,7 +1558,6 @@ fn model_overrides_cli_session_summary_overrides_everything() {
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(
None,
Some("cli-ss"),
&config,
Some(&remote),
@@ -1640,12 +1569,11 @@ fn model_overrides_cli_session_summary_overrides_everything() {
#[test]
fn model_overrides_empty_cli_session_summary_uses_default() {
with_model_overrides_env(
None,
None,
None,
|| {
let empty = toml::Value::Table(toml::map::Map::new());
let cfg = ModelOverrideConfig::resolve(None, Some(""), &empty, None);
let cfg = ModelOverrideConfig::resolve(Some(""), &empty, None);
assert_eq!(
cfg.session_summary, Some(crate ::models::default_session_summary_model()
.to_owned())
@@ -1656,7 +1584,6 @@ fn model_overrides_empty_cli_session_summary_uses_default() {
#[test]
fn model_overrides_env_image_description_overrides_remote() {
with_model_overrides_env(
None,
None,
Some("env-id"),
|| {
@@ -1665,7 +1592,7 @@ fn model_overrides_env_image_description_overrides_remote() {
image_description_model: Some("remote-id".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &empty, Some(&remote));
let cfg = ModelOverrideConfig::resolve(None, &empty, Some(&remote));
assert_eq!(cfg.image_description, Some("env-id".to_owned()));
},
);
@@ -1673,7 +1600,6 @@ fn model_overrides_env_image_description_overrides_remote() {
#[test]
fn model_overrides_env_image_description_overrides_local() {
with_model_overrides_env(
None,
None,
Some("env-id"),
|| {
@@ -1684,7 +1610,7 @@ fn model_overrides_env_image_description_overrides_local() {
"#,
)
.unwrap();
let cfg = ModelOverrideConfig::resolve(None, None, &config, None);
let cfg = ModelOverrideConfig::resolve(None, &config, None);
assert_eq!(cfg.image_description, Some("env-id".to_owned()));
},
);
@@ -1692,7 +1618,6 @@ fn model_overrides_env_image_description_overrides_local() {
#[test]
fn model_overrides_empty_image_description_toml_uses_default() {
with_model_overrides_env(
None,
None,
None,
|| {
@@ -1703,7 +1628,7 @@ fn model_overrides_empty_image_description_toml_uses_default() {
"#,
)
.unwrap();
let cfg = ModelOverrideConfig::resolve(None, None, &config, None);
let cfg = ModelOverrideConfig::resolve(None, &config, None);
assert_eq!(
cfg.image_description, Some(crate
::models::default_image_description_model().to_owned())
@@ -1714,7 +1639,6 @@ fn model_overrides_empty_image_description_toml_uses_default() {
#[test]
fn model_overrides_empty_image_description_remote_uses_default() {
with_model_overrides_env(
None,
None,
None,
|| {
@@ -1723,7 +1647,7 @@ fn model_overrides_empty_image_description_remote_uses_default() {
image_description_model: Some(" ".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &empty, Some(&remote));
let cfg = ModelOverrideConfig::resolve(None, &empty, Some(&remote));
assert_eq!(
cfg.image_description, Some(crate
::models::default_image_description_model().to_owned())
@@ -1734,12 +1658,11 @@ fn model_overrides_empty_image_description_remote_uses_default() {
#[test]
fn model_overrides_prompt_suggestion_unpinned_by_default() {
with_model_overrides_env(
None,
None,
None,
|| {
let empty = toml::Value::Table(toml::map::Map::new());
let cfg = ModelOverrideConfig::resolve(None, None, &empty, None);
let cfg = ModelOverrideConfig::resolve(None, &empty, None);
assert_eq!(cfg.prompt_suggestion, PromptSuggestModelPin::Unpinned);
},
);
@@ -1747,7 +1670,6 @@ fn model_overrides_prompt_suggestion_unpinned_by_default() {
#[test]
fn model_overrides_prompt_suggestion_local_wins_over_remote() {
with_model_overrides_env(
None,
None,
None,
|| {
@@ -1762,7 +1684,7 @@ fn model_overrides_prompt_suggestion_local_wins_over_remote() {
prompt_suggestion_model: Some("remote-ps".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &config, Some(&remote));
let cfg = ModelOverrideConfig::resolve(None, &config, Some(&remote));
assert_eq!(
cfg.prompt_suggestion, PromptSuggestModelPin::Pinned("local-ps"
.to_owned())
@@ -1773,7 +1695,6 @@ fn model_overrides_prompt_suggestion_local_wins_over_remote() {
#[test]
fn model_overrides_prompt_suggestion_remote_applies_without_local() {
with_model_overrides_env(
None,
None,
None,
|| {
@@ -1782,7 +1703,7 @@ fn model_overrides_prompt_suggestion_remote_applies_without_local() {
prompt_suggestion_model: Some("remote-ps".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &empty, Some(&remote));
let cfg = ModelOverrideConfig::resolve(None, &empty, Some(&remote));
assert_eq!(
cfg.prompt_suggestion, PromptSuggestModelPin::Pinned("remote-ps"
.to_owned())
@@ -1793,7 +1714,6 @@ fn model_overrides_prompt_suggestion_remote_applies_without_local() {
#[test]
fn model_overrides_prompt_suggestion_env_wins_over_local_and_remote() {
with_model_overrides_env_full(
None,
None,
None,
Some("env-ps"),
@@ -1809,7 +1729,7 @@ fn model_overrides_prompt_suggestion_env_wins_over_local_and_remote() {
prompt_suggestion_model: Some("remote-ps".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &config, Some(&remote));
let cfg = ModelOverrideConfig::resolve(None, &config, Some(&remote));
assert_eq!(
cfg.prompt_suggestion, PromptSuggestModelPin::Env("env-ps".to_owned())
);
@@ -1819,7 +1739,6 @@ fn model_overrides_prompt_suggestion_env_wins_over_local_and_remote() {
#[test]
fn model_overrides_prompt_suggestion_blank_values_are_unset() {
with_model_overrides_env_full(
None,
None,
None,
Some(" "),
@@ -1831,7 +1750,7 @@ fn model_overrides_prompt_suggestion_blank_values_are_unset() {
"#,
)
.unwrap();
let cfg = ModelOverrideConfig::resolve(None, None, &config, None);
let cfg = ModelOverrideConfig::resolve(None, &config, None);
assert_eq!(
cfg.prompt_suggestion, PromptSuggestModelPin::Pinned("local-ps"
.to_owned())
@@ -1839,7 +1758,6 @@ fn model_overrides_prompt_suggestion_blank_values_are_unset() {
},
);
with_model_overrides_env(
None,
None,
None,
|| {
@@ -1854,7 +1772,7 @@ fn model_overrides_prompt_suggestion_blank_values_are_unset() {
prompt_suggestion_model: Some(" ".to_owned()),
..Default::default()
};
let cfg = ModelOverrideConfig::resolve(None, None, &config, Some(&remote));
let cfg = ModelOverrideConfig::resolve(None, &config, Some(&remote));
assert_eq!(cfg.prompt_suggestion, PromptSuggestModelPin::Unpinned);
},
);
@@ -2668,13 +2586,13 @@ fn config_layers_system_managed_lowest_priority() {
#[test]
fn apply_requirements_value_overrides_user_settings() {
let raw_config: toml::Value = toml::from_str(
"[cli]\nauto_update = true\nchannel = \"beta\"\n\n[features]\nfeedback = true\nlsp_tools = true\nweb_fetch = true\nwrite_file = true\n\n[ui]\nyolo = true\n\n[models]\ndefault = \"user-model\"\nweb_search = \"user-ws-model\"\n\n[endpoints]\ncoding_api_base_url = \"https://user-proxy.example/v1\"\nxai_api_base_url = \"https://user-api.example/v1\"\nmodels_base_url = \"https://user-models.example/v1\"\nmodels_list_url = \"https://user-models.example/v1/models\"\n",
"[cli]\nauto_update = true\nchannel = \"beta\"\n\n[features]\nfeedback = true\nlsp_tools = true\nweb_fetch = true\nwrite_file = true\n\n[ui]\nyolo = true\n\n[models]\ndefault = \"user-model\"\n\n[endpoints]\ncoding_api_base_url = \"https://user-proxy.example/v1\"\nxai_api_base_url = \"https://user-api.example/v1\"\nmodels_base_url = \"https://user-models.example/v1\"\nmodels_list_url = \"https://user-models.example/v1/models\"\n",
)
.unwrap();
let mut cfg = crate::agent::config::Config::new_from_toml_cfg(&raw_config).unwrap();
cfg.default_yolo_mode = true;
let requirements: toml::Value = toml::from_str(
"[cli]\nauto_update = false\nchannel = \"stable\"\n\n[features]\nfeedback = false\nlsp_tools = false\nweb_fetch = false\nwrite_file = false\nremote_fetch = false\n\n[ui]\nyolo = false\n\n[models]\ndefault = \"managed-model\"\nweb_search = \"managed-ws-model\"\n\n[endpoints]\ncoding_api_base_url = \"https://managed-proxy.example/v1\"\nxai_api_base_url = \"https://managed-api.example/v1\"\nmodels_base_url = \"https://managed-models.example/v1\"\nmodels_list_url = \"https://managed-models.example/v1/models\"\ndeployment_key = \"enterprise-deploy-key-should-not-log\"\n",
"[cli]\nauto_update = false\nchannel = \"stable\"\n\n[features]\nfeedback = false\nlsp_tools = false\nweb_fetch = false\nwrite_file = false\nremote_fetch = false\n\n[ui]\nyolo = false\n\n[models]\ndefault = \"managed-model\"\n\n[endpoints]\ncoding_api_base_url = \"https://managed-proxy.example/v1\"\nxai_api_base_url = \"https://managed-api.example/v1\"\nmodels_base_url = \"https://managed-models.example/v1\"\nmodels_list_url = \"https://managed-models.example/v1/models\"\ndeployment_key = \"enterprise-deploy-key-should-not-log\"\n",
)
.unwrap();
let source = RequirementSource::Requirements {
@@ -2694,7 +2612,6 @@ fn apply_requirements_value_overrides_user_settings() {
assert!(! cfg.ui.yolo);
assert!(! cfg.default_yolo_mode);
assert_eq!(Some("managed-model"), cfg.models.default.as_deref());
assert_eq!(Some("managed-ws-model"), cfg.models.web_search.as_deref());
assert_eq!(Some("stable"), cfg.cli.channel.as_deref());
assert_eq!(
Some("https://managed-proxy.example/v1"), cfg.endpoints.coding_api_base_url