Download codex-rs/codex-api/src/provider.rs from SaylorTwift/codex: direct link, hf CLI and curl.
- Browser
- Download file 4.77 kB
-
https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/codex-api/src/provider.rs
- Command line
-
hf download hf://SaylorTwift/codex/codex-rs/codex-api/src/provider.rs
-
curl -L -o provider.rs https://huggingface.co/SaylorTwift/codex/resolve/main/codex-rs/codex-api/src/provider.rs
4.77 kB
| use codex_client::Request; | |
| use codex_client::RequestCompression; | |
| use codex_client::RetryOn; | |
| use codex_client::RetryPolicy; | |
| use http::Method; | |
| use http::header::HeaderMap; | |
| use std::collections::HashMap; | |
| use std::time::Duration; | |
| use url::Url; | |
| /// High-level retry configuration for a provider. | |
| /// | |
| /// This is converted into a `RetryPolicy` used by `codex-client` to drive | |
| /// transport-level retries for both unary and streaming calls. | |
| pub struct RetryConfig { | |
| pub max_attempts: u64, | |
| pub base_delay: Duration, | |
| pub retry_429: bool, | |
| pub retry_5xx: bool, | |
| pub retry_transport: bool, | |
| } | |
| impl RetryConfig { | |
| pub fn to_policy(&self) -> RetryPolicy { | |
| RetryPolicy { | |
| max_attempts: self.max_attempts, | |
| base_delay: self.base_delay, | |
| retry_on: RetryOn { | |
| retry_429: self.retry_429, | |
| retry_5xx: self.retry_5xx, | |
| retry_transport: self.retry_transport, | |
| }, | |
| } | |
| } | |
| } | |
| /// HTTP endpoint configuration used to talk to a concrete API deployment. | |
| /// | |
| /// Encapsulates base URL, default headers, query params, retry policy, and | |
| /// stream idle timeout, plus helper methods for building requests. | |
| pub struct Provider { | |
| pub name: String, | |
| pub base_url: String, | |
| pub query_params: Option<HashMap<String, String>>, | |
| pub headers: HeaderMap, | |
| pub retry: RetryConfig, | |
| pub stream_idle_timeout: Duration, | |
| } | |
| impl Provider { | |
| pub fn url_for_path(&self, path: &str) -> String { | |
| let base = self.base_url.trim_end_matches('/'); | |
| let path = path.trim_start_matches('/'); | |
| let mut url = if path.is_empty() { | |
| base.to_string() | |
| } else { | |
| format!("{base}/{path}") | |
| }; | |
| if let Some(params) = &self.query_params | |
| && !params.is_empty() | |
| { | |
| let qs = params | |
| .iter() | |
| .map(|(k, v)| format!("{k}={v}")) | |
| .collect::<Vec<_>>() | |
| .join("&"); | |
| url.push('?'); | |
| url.push_str(&qs); | |
| } | |
| url | |
| } | |
| pub fn build_request(&self, method: Method, path: &str) -> Request { | |
| Request { | |
| method, | |
| url: self.url_for_path(path), | |
| headers: self.headers.clone(), | |
| body: None, | |
| compression: RequestCompression::None, | |
| timeout: None, | |
| response_body_limit_bytes: None, | |
| } | |
| } | |
| pub fn websocket_url_for_path(&self, path: &str) -> Result<Url, url::ParseError> { | |
| let mut url = Url::parse(&self.url_for_path(path))?; | |
| let scheme = match url.scheme() { | |
| "http" => "ws", | |
| "https" => "wss", | |
| "ws" | "wss" => return Ok(url), | |
| _ => return Ok(url), | |
| }; | |
| let _ = url.set_scheme(scheme); | |
| Ok(url) | |
| } | |
| } | |
| pub fn is_azure_responses_provider(name: &str, base_url: Option<&str>) -> bool { | |
| if name.eq_ignore_ascii_case("azure") { | |
| true | |
| } else if let Some(base_url) = base_url { | |
| matches_azure_responses_base_url(base_url) | |
| } else { | |
| false | |
| } | |
| } | |
| fn matches_azure_responses_base_url(base_url: &str) -> bool { | |
| let base_url = base_url.to_ascii_lowercase(); | |
| const AZURE_MARKERS: [&str; 6] = [ | |
| "openai.azure.", | |
| "cognitiveservices.azure.", | |
| "aoai.azure.", | |
| "azure-api.", | |
| "azurefd.", | |
| "windows.net/openai", | |
| ]; | |
| AZURE_MARKERS.iter().any(|marker| base_url.contains(marker)) | |
| } | |
| mod tests { | |
| use super::*; | |
| fn detects_azure_responses_base_urls() { | |
| let positive_cases = [ | |
| "https://foo.openai.azure.com/openai", | |
| "https://foo.openai.azure.us/openai/deployments/bar", | |
| "https://foo.cognitiveservices.azure.cn/openai", | |
| "https://foo.aoai.azure.com/openai", | |
| "https://foo.openai.azure-api.net/openai", | |
| "https://foo.z01.azurefd.net/", | |
| ]; | |
| for base_url in positive_cases { | |
| assert!( | |
| is_azure_responses_provider("test", Some(base_url)), | |
| "expected {base_url} to be detected as Azure" | |
| ); | |
| } | |
| assert!(is_azure_responses_provider( | |
| "Azure", | |
| Some("https://example.com") | |
| )); | |
| let negative_cases = [ | |
| "https://api.openai.com/v1", | |
| "https://example.com/openai", | |
| "https://myproxy.azurewebsites.net/openai", | |
| ]; | |
| for base_url in negative_cases { | |
| assert!( | |
| !is_azure_responses_provider("test", Some(base_url)), | |
| "expected {base_url} not to be detected as Azure" | |
| ); | |
| } | |
| } | |
| } | |