Skip to main content

systemprompt_models/services/ai/
model.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4use super::config::ResilienceSettings;
5
6const fn default_true() -> bool {
7    true
8}
9
10#[derive(Debug, Clone, Default, Serialize, Deserialize)]
11pub struct ToolModelSettings {
12    pub model: String,
13
14    #[serde(default)]
15    pub max_output_tokens: Option<u32>,
16}
17
18#[allow(clippy::struct_excessive_bools)]
19#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
20pub struct ModelCapabilities {
21    #[serde(default)]
22    pub vision: bool,
23
24    #[serde(default)]
25    pub audio_input: bool,
26
27    #[serde(default)]
28    pub video_input: bool,
29
30    #[serde(default)]
31    pub image_generation: bool,
32
33    #[serde(default)]
34    pub audio_generation: bool,
35
36    #[serde(default)]
37    pub streaming: bool,
38
39    #[serde(default)]
40    pub tools: bool,
41
42    #[serde(default)]
43    pub structured_output: bool,
44
45    #[serde(default)]
46    pub system_prompts: bool,
47
48    #[serde(default)]
49    pub image_resolution_config: bool,
50}
51
52#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
53pub struct ModelLimits {
54    #[serde(default)]
55    pub context_window: u32,
56
57    #[serde(default)]
58    pub max_output_tokens: u32,
59}
60
61#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, schemars::JsonSchema)]
62pub struct ModelPricing {
63    #[serde(default)]
64    pub input_per_million: f64,
65
66    #[serde(default)]
67    pub output_per_million: f64,
68
69    #[serde(default)]
70    pub per_image_cents: Option<f64>,
71}
72
73#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
74pub struct ModelDefinition {
75    #[serde(default)]
76    pub capabilities: ModelCapabilities,
77
78    #[serde(default)]
79    pub limits: ModelLimits,
80
81    #[serde(default)]
82    pub pricing: ModelPricing,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct AiProviderConfig {
87    #[serde(default = "default_true")]
88    pub enabled: bool,
89
90    #[serde(default)]
91    pub api_key: String,
92
93    #[serde(default)]
94    pub endpoint: Option<String>,
95
96    #[serde(default)]
97    pub default_model: String,
98
99    #[serde(default)]
100    pub default_image_model: String,
101
102    #[serde(default)]
103    pub default_image_resolution: String,
104
105    #[serde(default)]
106    pub google_search_enabled: bool,
107
108    #[serde(default)]
109    pub models: HashMap<String, ModelDefinition>,
110
111    /// Resilience policy applied to outbound AI provider calls (timeouts,
112    /// retry, circuit breaker, bulkhead).
113    #[serde(default)]
114    pub resilience: ResilienceSettings,
115}
116
117impl Default for AiProviderConfig {
118    fn default() -> Self {
119        Self {
120            enabled: true,
121            api_key: String::new(),
122            endpoint: None,
123            default_model: String::new(),
124            default_image_model: String::new(),
125            default_image_resolution: String::new(),
126            google_search_enabled: false,
127            models: HashMap::new(),
128            resilience: ResilienceSettings::default(),
129        }
130    }
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize)]
134pub struct ToolModelConfig {
135    pub provider: String,
136    pub model: String,
137
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub max_output_tokens: Option<u32>,
140
141    #[serde(skip_serializing_if = "Option::is_none")]
142    pub thinking_level: Option<String>,
143}