llm_gateway/
config.rs

1use serde::Deserialize;
2
3#[derive(Clone, Default, Deserialize)]
4pub struct ProviderConfig {
5    pub base_url: Option<String>,
6    pub api_key: Option<String>,
7    pub models: Option<Vec<String>>,
8}
9
10#[derive(Clone, Default)]
11pub struct CallOptions {
12    pub api_key: Option<String>,
13    pub base_url: Option<String>,
14}
15
16#[derive(Clone, Default, Deserialize)]
17pub struct Config {
18    #[serde(default)]
19    pub deepseek: ProviderConfig,
20    #[serde(default)]
21    pub glm: ProviderConfig,      // Zhipu GLM
22    #[serde(default)]
23    pub qwen: ProviderConfig,     // Alibaba Qwen
24    #[serde(default)]
25    pub kimi: ProviderConfig,     // Moonshot/Kimi
26    /// 是否在线发现模型(默认关闭,离线/内网环境建议关闭)
27    #[serde(default)]
28    pub discover_models: bool,
29    /// 在线发现模型结果缓存 TTL(秒)。0 表示使用内置默认(300s)
30    #[serde(default)]
31    pub discover_models_ttl_secs: u64,
32}
33
34impl Config {
35    pub fn from_env() -> Self {
36        let get = |k: &str| std::env::var(k).ok().filter(|s| !s.is_empty());
37        Config {
38            deepseek: ProviderConfig {
39                base_url: get("DEEPSEEK_BASE_URL"),
40                api_key: get("DEEPSEEK_API_KEY"),
41                ..Default::default()
42            },
43            glm: ProviderConfig {
44                base_url: get("GLM_BASE_URL").or_else(|| get("ZHIPU_BASE_URL")),
45                api_key: get("GLM_API_KEY").or_else(|| get("ZHIPU_API_KEY")),
46                ..Default::default()
47            },
48            qwen: ProviderConfig {
49                base_url: get("QWEN_BASE_URL").or_else(|| get("ALIBABA_QWEN_BASE_URL")),
50                api_key: get("QWEN_API_KEY").or_else(|| get("ALIBABA_QWEN_API_KEY")),
51                ..Default::default()
52            },
53            kimi: ProviderConfig {
54                base_url: get("KIMI_BASE_URL").or_else(|| get("MOONSHOT_BASE_URL")),
55                api_key: get("KIMI_API_KEY").or_else(|| get("MOONSHOT_API_KEY")),
56                ..Default::default()
57            },
58            // 环境变量模式下默认不启用在线发现
59            discover_models: false,
60            // 通过配置文件控制;环境变量不再覆盖
61            discover_models_ttl_secs: 0,
62        }
63    }
64
65    // 在当前工作目录和 ~/.config/llm-gateway/config.yaml 两个路径下自动寻找
66    pub fn from_yaml_file_auto() -> Option<Self> {
67        use std::fs;
68        use std::path::PathBuf;
69
70        let candidates: [PathBuf; 2] = [
71            PathBuf::from("llm-gateway.config.yaml"),
72            std::env::var("HOME")
73                .map(|home| PathBuf::from(home).join(".config/llm-gateway/config.yaml"))
74                .unwrap_or_else(|_| PathBuf::from("/non-existent")),
75        ];
76
77        for path in candidates {
78            if path.exists() {
79                let text = fs::read_to_string(&path).ok()?;
80                if let Ok(cfg) = serde_yaml::from_str::<Config>(&text) {
81                    return Some(cfg);
82                }
83            }
84        }
85        None
86    }
87}