lean_ctx/core/config/
proxy.rs1use serde::{Deserialize, Serialize};
4
5#[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}