Allow custom providers to opt into standalone web search (#34846)

## What changed

- Add the `supports_standalone_web_search` model-provider setting, defaulting to `false`, and preserve it in remote thread configuration.
- Enable the standalone `web.run` tool for opted-in custom Responses providers when web search is enabled and the runtime provider supports it.
- Send standalone search requests through the custom provider's endpoint and authentication.

## Testing

- Cover opt-in, default-off, disabled-search, and unsupported-provider behavior.
- Verify custom-provider search request routing and authorization through the app server.

GitOrigin-RevId: 7c5f96b0ce924ad2b9715c45bfc635e89fc39cff
This commit is contained in:
sayan-oai authored and copyberry committed 2026-07-23 00:02:15 +00:00
1 parent 0da13c6c99
commit 0f9fb40fa9
20 files changed
+280 -21

No files matched your search

+6
View File
@@ -138,6 +138,9 @@ pub struct ModelProviderInfo {
/// Whether this provider supports the Responses API WebSocket transport.
#[serde(default)]
pub supports_websockets: bool,
/// Whether this provider supports the standalone web-search endpoint.
#[serde(default)]
pub supports_standalone_web_search: bool,
}
/// AWS SigV4 auth configuration for a model provider.
@@ -360,6 +363,7 @@ impl ModelProviderInfo {
websocket_connect_timeout_ms: None,
requires_openai_auth: true,
supports_websockets: true,
supports_standalone_web_search: true,
}
}
@@ -393,6 +397,7 @@ impl ModelProviderInfo {
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
supports_standalone_web_search: false,
}
}
@@ -540,6 +545,7 @@ pub fn create_oss_provider_with_base_url(base_url: &str, wire_api: WireApi) -> M
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
supports_standalone_web_search: false,
}
}
@@ -29,6 +29,7 @@ base_url = "http://localhost:11434/v1"
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
supports_standalone_web_search: false,
};
let provider: ModelProviderInfo = toml::from_str(azure_provider_toml).unwrap();
@@ -63,6 +64,7 @@ query_params = { api-version = "2025-04-01-preview" }
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
supports_standalone_web_search: false,
};
let provider: ModelProviderInfo = toml::from_str(azure_provider_toml).unwrap();
@@ -77,6 +79,7 @@ base_url = "https://example.com"
env_key = "API_KEY"
http_headers = { "X-Example-Header" = "example-value" }
env_http_headers = { "X-Example-Env-Header" = "EXAMPLE_ENV_VAR" }
supports_standalone_web_search = true
"#;
let expected_provider = ModelProviderInfo {
name: "Example".into(),
@@ -100,6 +103,7 @@ env_http_headers = { "X-Example-Env-Header" = "EXAMPLE_ENV_VAR" }
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
supports_standalone_web_search: true,
};
let provider: ModelProviderInfo = toml::from_str(azure_provider_toml).unwrap();
@@ -177,6 +181,7 @@ fn test_supports_remote_compaction_for_azure_name() {
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
supports_standalone_web_search: false,
};
assert!(provider.supports_remote_compaction());
@@ -202,6 +207,7 @@ fn test_supports_remote_compaction_for_non_openai_non_azure_provider() {
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
supports_standalone_web_search: false,
};
assert!(!provider.supports_remote_compaction());
@@ -310,6 +316,7 @@ fn test_create_amazon_bedrock_provider() {
websocket_connect_timeout_ms: None,
requires_openai_auth: false,
supports_websockets: false,
supports_standalone_web_search: false,
}
);
}