fix: bound web search network reads

This commit is contained in:
2026-05-29 18:21:17 +09:00
parent 2be3a5bd36
commit 82dcc57475
4 changed files with 83 additions and 6 deletions
+19
View File
@@ -332,6 +332,7 @@ impl crate::WebSearchConfig {
enabled: upper.enabled.or(self.enabled),
provider: upper.provider.or(self.provider),
api_key_env: upper.api_key_env.or(self.api_key_env),
timeout_secs: upper.timeout_secs.or(self.timeout_secs),
base_url: upper.base_url.or(self.base_url),
country: upper.country.or(self.country),
search_lang: upper.search_lang.or(self.search_lang),
@@ -1085,6 +1086,14 @@ mod tests {
prune_protected_tokens: Some(5_000),
..Default::default()
}),
web: Some(WebConfig {
search: Some(crate::WebSearchConfig {
api_key_env: Some("LOWER_BRAVE_KEY".into()),
timeout_secs: Some(12),
..Default::default()
}),
..Default::default()
}),
..Default::default()
};
let upper = PodManifestConfig {
@@ -1092,6 +1101,13 @@ mod tests {
threshold: Some(80_000),
..Default::default()
}),
web: Some(WebConfig {
search: Some(crate::WebSearchConfig {
timeout_secs: Some(3),
..Default::default()
}),
..Default::default()
}),
..Default::default()
};
let merged = lower.merge(upper);
@@ -1099,6 +1115,9 @@ mod tests {
assert_eq!(c.threshold, Some(80_000));
// field from lower retained when upper has None
assert_eq!(c.prune_protected_tokens, Some(5_000));
let search = merged.web.unwrap().search.unwrap();
assert_eq!(search.timeout_secs, Some(3));
assert_eq!(search.api_key_env.as_deref(), Some("LOWER_BRAVE_KEY"));
}
#[test]
+8 -2
View File
@@ -120,6 +120,10 @@ pub struct WebSearchConfig {
/// not belong in manifest files.
#[serde(default)]
pub api_key_env: Option<String>,
/// Request timeout in seconds. Tool implementation applies a safe default
/// when this is omitted.
#[serde(default)]
pub timeout_secs: Option<u64>,
/// Optional provider endpoint override for tests/proxies. Defaults to the
/// Brave web search endpoint for the Brave provider.
#[serde(default)]
@@ -640,13 +644,15 @@ permission = "write"
#[test]
fn parse_web_config() {
let toml = format!(
"{}\n[web]\nenabled = true\n\n[web.search]\nprovider = \"brave\"\napi_key_env = \"BRAVE_SEARCH_API_KEY\"\n\n[web.fetch]\ntimeout_secs = 7\nredirect_limit = 3\nmax_response_bytes = 12345\nmax_output_bytes = 2048\n",
"{}\n[web]\nenabled = true\n\n[web.search]\nprovider = \"brave\"\napi_key_env = \"BRAVE_SEARCH_API_KEY\"\ntimeout_secs = 12\n\n[web.fetch]\ntimeout_secs = 7\nredirect_limit = 3\nmax_response_bytes = 12345\nmax_output_bytes = 2048\n",
MINIMAL_REQUIRED
);
let manifest = PodManifest::from_toml(&toml).unwrap();
let web = manifest.web.unwrap();
assert_eq!(web.enabled, Some(true));
assert_eq!(web.search.unwrap().provider, Some(WebSearchProvider::Brave));
let search = web.search.unwrap();
assert_eq!(search.provider, Some(WebSearchProvider::Brave));
assert_eq!(search.timeout_secs, Some(12));
let fetch = web.fetch.unwrap();
assert_eq!(fetch.timeout_secs, Some(7));
assert_eq!(fetch.redirect_limit, Some(3));