chronicle_proxy/
config.rs1use std::{collections::BTreeMap, time::Duration};
2
3use serde::{Deserialize, Serialize};
4
5use crate::providers::custom::{CustomProvider, ProviderRequestFormat};
6
7#[derive(Serialize, Deserialize, Debug, Clone, Default)]
9pub struct ProxyConfig {
10 #[serde(default)]
12 pub providers: Vec<CustomProviderConfig>,
13 #[serde(default)]
15 pub aliases: Vec<AliasConfig>,
16 #[serde(default)]
18 pub api_keys: Vec<ApiKeyConfig>,
19 pub default_timeout: Option<Duration>,
21 pub log_to_database: Option<bool>,
23 pub user_agent: Option<String>,
25}
26
27#[derive(Serialize, Deserialize, Debug, Clone, sqlx::FromRow)]
29pub struct AliasConfig {
30 pub name: String,
32 #[serde(default)]
35 pub random_order: bool,
36 pub models: Vec<AliasConfigProvider>,
38}
39
40#[derive(Serialize, Deserialize, Debug, Clone, sqlx::FromRow)]
42pub struct AliasConfigProvider {
43 pub model: String,
45 pub provider: String,
47 pub api_key_name: Option<String>,
49}
50
51sqlx_transparent_json_decode::sqlx_json_decode!(AliasConfigProvider);
52
53#[derive(Serialize, Deserialize, Clone, sqlx::FromRow)]
55pub struct ApiKeyConfig {
56 pub name: String,
58 pub source: String,
61 pub value: String,
63}
64
65impl std::fmt::Debug for ApiKeyConfig {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 f.debug_struct("ApiKeyConfig")
68 .field("name", &self.name)
69 .field("source", &self.source)
70 .field(
71 "value",
72 if self.source == "env" {
73 &self.value
74 } else {
75 &"***"
76 },
77 )
78 .finish_non_exhaustive()
79 }
80}
81
82#[derive(Serialize, Deserialize, Debug, Clone)]
84pub struct CustomProviderConfig {
85 pub name: String,
87 pub label: Option<String>,
89 pub url: String,
91 pub api_key: Option<String>,
93 pub api_key_source: Option<String>,
98 #[serde(default)]
100 pub format: ProviderRequestFormat,
101 #[serde(default)]
103 pub headers: BTreeMap<String, String>,
104 pub prefix: Option<String>,
106}
107
108impl CustomProviderConfig {
109 pub fn into_provider(mut self, client: reqwest::Client) -> CustomProvider {
111 if self.api_key_source.as_deref().unwrap_or_default() == "env" {
112 if let Some(token) = self
113 .api_key
114 .as_deref()
115 .and_then(|var| std::env::var(&var).ok())
116 {
117 self.api_key = Some(token);
118 }
119 }
120
121 CustomProvider::new(self, client)
122 }
123
124 pub fn with_token_or_env(mut self, token: Option<String>, env: &str) -> Self {
127 match token {
128 Some(token) => {
129 self.api_key = Some(token);
130 self.api_key_source = None;
131 }
132 None => {
133 self.api_key = Some(env.to_string());
134 self.api_key_source = Some("env".to_string());
135 }
136 }
137
138 self
139 }
140}