Skip to main content

lean_ctx/core/config/
proxy.rs

1//! API proxy upstream overrides (`config.toml`).
2
3use serde::{Deserialize, Serialize};
4
5/// API proxy upstream overrides. `None` = use provider default.
6#[derive(Debug, Clone, Default, Serialize, Deserialize)]
7#[serde(default)]
8pub struct ProxyConfig {
9    pub anthropic_upstream: Option<String>,
10    pub openai_upstream: Option<String>,
11    pub gemini_upstream: Option<String>,
12}
13
14impl ProxyConfig {
15    pub fn resolve_upstream(&self, provider: ProxyProvider) -> String {
16        let (env_var, config_val, default) = match provider {
17            ProxyProvider::Anthropic => (
18                "LEAN_CTX_ANTHROPIC_UPSTREAM",
19                self.anthropic_upstream.as_deref(),
20                "https://api.anthropic.com",
21            ),
22            ProxyProvider::OpenAi => (
23                "LEAN_CTX_OPENAI_UPSTREAM",
24                self.openai_upstream.as_deref(),
25                "https://api.openai.com",
26            ),
27            ProxyProvider::Gemini => (
28                "LEAN_CTX_GEMINI_UPSTREAM",
29                self.gemini_upstream.as_deref(),
30                "https://generativelanguage.googleapis.com",
31            ),
32        };
33        std::env::var(env_var)
34            .ok()
35            .and_then(|v| normalize_url_opt(&v))
36            .or_else(|| config_val.and_then(normalize_url_opt))
37            .unwrap_or_else(|| normalize_url(default))
38    }
39}
40
41#[derive(Debug, Clone, Copy)]
42pub enum ProxyProvider {
43    Anthropic,
44    OpenAi,
45    Gemini,
46}
47
48pub fn normalize_url(value: &str) -> String {
49    value.trim().trim_end_matches('/').to_string()
50}
51
52pub fn normalize_url_opt(value: &str) -> Option<String> {
53    let trimmed = normalize_url(value);
54    if trimmed.is_empty() {
55        None
56    } else {
57        Some(trimmed)
58    }
59}
60
61pub fn is_local_proxy_url(value: &str) -> bool {
62    let n = normalize_url(value);
63    n.starts_with("http://127.0.0.1:")
64        || n.starts_with("http://localhost:")
65        || n.starts_with("http://[::1]:")
66}