Skip to main content

systemprompt_models/services/
ai.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4const fn default_true() -> bool {
5    true
6}
7
8#[derive(Debug, Clone, Default, Serialize, Deserialize)]
9pub struct AiConfig {
10    #[serde(default)]
11    pub default_provider: String,
12
13    #[serde(default)]
14    pub default_max_output_tokens: Option<u32>,
15
16    #[serde(default)]
17    pub sampling: SamplingConfig,
18
19    #[serde(default)]
20    pub providers: HashMap<String, AiProviderConfig>,
21
22    #[serde(default)]
23    pub tool_models: HashMap<String, ToolModelSettings>,
24
25    #[serde(default)]
26    pub mcp: McpConfig,
27
28    #[serde(default)]
29    pub history: HistoryConfig,
30}
31
32#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
33pub struct SamplingConfig {
34    #[serde(default)]
35    pub enable_smart_routing: bool,
36
37    #[serde(default)]
38    pub fallback_enabled: bool,
39}
40
41#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
42pub struct McpConfig {
43    #[serde(default)]
44    pub auto_discover: bool,
45
46    #[serde(default = "default_connect_timeout")]
47    pub connect_timeout_ms: u64,
48
49    #[serde(default = "default_execution_timeout")]
50    pub execution_timeout_ms: u64,
51
52    #[serde(default = "default_retry_attempts")]
53    pub retry_attempts: u32,
54}
55
56impl Default for McpConfig {
57    fn default() -> Self {
58        Self {
59            auto_discover: false,
60            connect_timeout_ms: default_connect_timeout(),
61            execution_timeout_ms: default_execution_timeout(),
62            retry_attempts: default_retry_attempts(),
63        }
64    }
65}
66
67const fn default_connect_timeout() -> u64 {
68    5000
69}
70
71const fn default_execution_timeout() -> u64 {
72    30000
73}
74
75const fn default_retry_attempts() -> u32 {
76    3
77}
78
79#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
80pub struct HistoryConfig {
81    #[serde(default = "default_retention_days")]
82    pub retention_days: u32,
83
84    #[serde(default)]
85    pub log_tool_executions: bool,
86}
87
88impl Default for HistoryConfig {
89    fn default() -> Self {
90        Self {
91            retention_days: default_retention_days(),
92            log_tool_executions: false,
93        }
94    }
95}
96
97const fn default_retention_days() -> u32 {
98    30
99}
100
101#[derive(Debug, Clone, Default, Serialize, Deserialize)]
102pub struct ToolModelSettings {
103    pub model: String,
104
105    #[serde(default)]
106    pub max_output_tokens: Option<u32>,
107}
108
109#[allow(clippy::struct_excessive_bools)]
110#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
111pub struct ModelCapabilities {
112    #[serde(default)]
113    pub vision: bool,
114
115    #[serde(default)]
116    pub audio_input: bool,
117
118    #[serde(default)]
119    pub video_input: bool,
120
121    #[serde(default)]
122    pub image_generation: bool,
123
124    #[serde(default)]
125    pub audio_generation: bool,
126
127    #[serde(default)]
128    pub streaming: bool,
129
130    #[serde(default)]
131    pub tools: bool,
132
133    #[serde(default)]
134    pub structured_output: bool,
135
136    #[serde(default)]
137    pub system_prompts: bool,
138
139    #[serde(default)]
140    pub image_resolution_config: bool,
141}
142
143#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
144pub struct ModelLimits {
145    #[serde(default)]
146    pub context_window: u32,
147
148    #[serde(default)]
149    pub max_output_tokens: u32,
150}
151
152#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
153pub struct ModelPricing {
154    #[serde(default)]
155    pub input_per_million: f64,
156
157    #[serde(default)]
158    pub output_per_million: f64,
159
160    #[serde(default)]
161    pub per_image_cents: Option<f64>,
162}
163
164#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
165pub struct ModelDefinition {
166    #[serde(default)]
167    pub capabilities: ModelCapabilities,
168
169    #[serde(default)]
170    pub limits: ModelLimits,
171
172    #[serde(default)]
173    pub pricing: ModelPricing,
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct AiProviderConfig {
178    #[serde(default = "default_true")]
179    pub enabled: bool,
180
181    #[serde(default)]
182    pub api_key: String,
183
184    #[serde(default)]
185    pub endpoint: Option<String>,
186
187    #[serde(default)]
188    pub default_model: String,
189
190    #[serde(default)]
191    pub google_search_enabled: bool,
192
193    #[serde(default)]
194    pub models: HashMap<String, ModelDefinition>,
195}
196
197impl Default for AiProviderConfig {
198    fn default() -> Self {
199        Self {
200            enabled: true,
201            api_key: String::new(),
202            endpoint: None,
203            default_model: String::new(),
204            google_search_enabled: false,
205            models: HashMap::new(),
206        }
207    }
208}
209
210#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct ToolModelConfig {
212    pub provider: String,
213    pub model: String,
214
215    #[serde(skip_serializing_if = "Option::is_none")]
216    pub max_output_tokens: Option<u32>,
217
218    #[serde(skip_serializing_if = "Option::is_none")]
219    pub thinking_level: Option<String>,
220}