Skip to main content

vtcode_core/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(
27            Duration::from_secs(30),
28            Duration::from_secs(timeout_secs),
29        )
30    }
31
32    /// Create an HTTP client optimized for streaming requests.
33    ///
34    /// Uses the `streaming_ceiling_seconds` from TimeoutsConfig.
35    /// Streaming requests typically take longer as they wait for incremental output.
36    pub fn for_streaming(config: &TimeoutsConfig) -> Client {
37        let timeout_secs = if config.streaming_ceiling_seconds > 0 {
38            config.streaming_ceiling_seconds
39        } else {
40            600 // 10 minutes fallback for streaming
41        };
42
43        Client::builder()
44            .timeout(Duration::from_secs(timeout_secs))
45            .connect_timeout(Duration::from_secs(30))
46            .pool_idle_timeout(Some(Duration::from_secs(90)))
47            .pool_max_idle_per_host(1)
48            .build()
49            .unwrap_or_else(|_| Client::new())
50    }
51
52    /// Create an HTTP client with explicit timeout values.
53    ///
54    /// Use this when providers need custom timeout handling.
55    pub fn with_timeouts(request_timeout: Duration, connect_timeout: Duration) -> Client {
56        vtcode_commons::http::create_client_with_timeouts(connect_timeout, request_timeout)
57    }
58
59    /// Create a default HTTP client with reasonable defaults.
60    ///
61    /// Uses 180s request timeout and 30s connect timeout.
62    pub fn default_client() -> Client {
63        vtcode_commons::http::create_client_with_timeouts(
64            Duration::from_secs(30),
65            Duration::from_secs(180),
66        )
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn default_client_is_created() {
76        let client = HttpClientFactory::default_client();
77        // Just verify it doesn't panic
78        drop(client);
79    }
80
81    #[test]
82    fn for_llm_uses_config_timeout() {
83        let config = TimeoutsConfig::default();
84        let client = HttpClientFactory::for_llm(&config);
85        drop(client);
86    }
87
88    #[test]
89    fn for_streaming_uses_longer_timeout() {
90        let config = TimeoutsConfig::default();
91        let client = HttpClientFactory::for_streaming(&config);
92        drop(client);
93    }
94}