use std::error::Error as StdError;
use std::time::Duration;
use reqwest::Client;
use crate::cm_types::llm_config::LlmHttpRetryConfig;
pub fn format_reqwest_transport_err(e: &reqwest::Error) -> String {
let mut msg = e.to_string();
if e.is_timeout() {
msg.push_str(
" [提示:连接或整请求超时,可调大配置 [agent] api_timeout_secs,或检查网络/代理]",
);
} else if e.is_connect() {
msg.push_str(" [提示:无法建立 TLS/TCP 连接,常见于 DNS 失败、防火墙、需代理(HTTPS_PROXY)、或对端不可达;可用 curl -v 测同一 URL]");
}
if let Some(src) = e.source() {
msg.push_str(" | ");
msg.push_str(&src.to_string());
}
msg
}
pub fn map_reqwest_transport_err(e: reqwest::Error) -> Box<dyn std::error::Error + Send + Sync> {
std::io::Error::other(format_reqwest_transport_err(&e)).into()
}
fn connect_timeout_for(retry: &LlmHttpRetryConfig) -> Duration {
let secs = retry.api_timeout_secs.clamp(5, 45);
Duration::from_secs(secs)
}
pub fn build_shared_api_client(retry: &LlmHttpRetryConfig) -> Result<Client, reqwest::Error> {
Client::builder()
.timeout(Duration::from_secs(retry.api_timeout_secs))
.connect_timeout(connect_timeout_for(retry))
.pool_max_idle_per_host(8)
.pool_idle_timeout(Duration::from_secs(120))
.tcp_keepalive(Duration::from_secs(60))
.user_agent(concat!("crabmate/", env!("CARGO_PKG_VERSION")))
.build()
}