Skip to main content

vtcode_llm/
http_client.rs

1//! Centralized HTTP client factory for LLM providers.
2//!
3//! Provides consistent timeout configuration and client creation
4//! across all providers based on the application's TimeoutsConfig.
5
6use reqwest::Client;
7use std::time::Duration;
8
9use vtcode_config::TimeoutsConfig;
10
11/// Factory for creating pre-configured HTTP clients.
12pub struct HttpClientFactory;
13
14impl HttpClientFactory {
15    /// Create an HTTP client for standard LLM API requests.
16    ///
17    /// Uses the `default_ceiling_seconds` from TimeoutsConfig for the request timeout.
18    /// Includes a 30-second connect timeout.
19    pub fn for_llm(config: &TimeoutsConfig) -> Client {
20        let timeout_secs = if config.default_ceiling_seconds > 0 {
21            config.default_ceiling_seconds
22        } else {
23            180 // Fallback if disabled
24        };
25
26        vtcode_commons::http::create_client_with_timeouts(Duration::from_secs(30), Duration::from_secs(timeout_secs))
27    }
28
29    /// Create an HTTP client optimized for streaming requests.
30    ///
31    /// Uses the `streaming_ceiling_seconds` from TimeoutsConfig.
32    /// Streaming requests typically take longer as they wait for incremental output.
33    pub fn for_streaming(config: &TimeoutsConfig) -> Client {
34        let timeout_secs = if config.streaming_ceiling_seconds > 0 {
35            config.streaming_ceiling_seconds
36        } else {
37            600 // 10 minutes fallback for streaming
38        };
39
40        Client::builder()
41            .timeout(Duration::from_secs(timeout_secs))
42            .connect_timeout(Duration::from_secs(30))
43            .pool_idle_timeout(Some(Duration::from_secs(90)))
44            .pool_max_idle_per_host(1)
45            .build()
46            .unwrap_or_else(|_| Client::new())
47    }
48
49    /// Create an HTTP client with explicit timeout values.
50    ///
51    /// Use this when providers need custom timeout handling.
52    pub(crate) fn with_timeouts(request_timeout: Duration, connect_timeout: Duration) -> Client {
53        vtcode_commons::http::create_client_with_timeouts(connect_timeout, request_timeout)
54    }
55
56    /// Create a default HTTP client with reasonable defaults.
57    ///
58    /// Uses 180s request timeout and 30s connect timeout.
59    pub fn default_client() -> Client {
60        vtcode_commons::http::create_client_with_timeouts(Duration::from_secs(30), Duration::from_secs(180))
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn default_client_is_created() {
70        let client = HttpClientFactory::default_client();
71        // Just verify it doesn't panic
72        drop(client);
73    }
74
75    #[test]
76    fn for_llm_uses_config_timeout() {
77        let config = TimeoutsConfig::default();
78        let client = HttpClientFactory::for_llm(&config);
79        drop(client);
80    }
81
82    #[test]
83    fn for_streaming_uses_longer_timeout() {
84        let config = TimeoutsConfig::default();
85        let client = HttpClientFactory::for_streaming(&config);
86        drop(client);
87    }
88}