systemprompt_models/services/ai/
model.rs1use serde::{Deserialize, Serialize};
13
14use super::config::ResilienceSettings;
15
16const fn default_true() -> bool {
17 true
18}
19
20#[expect(
21 clippy::struct_excessive_bools,
22 reason = "model capability matrix: each bool is an independent provider feature flag, not \
23 state"
24)]
25#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, schemars::JsonSchema)]
26pub struct ModelCapabilities {
27 #[serde(default)]
28 pub vision: bool,
29
30 #[serde(default)]
31 pub audio_input: bool,
32
33 #[serde(default)]
34 pub video_input: bool,
35
36 #[serde(default)]
37 pub image_generation: bool,
38
39 #[serde(default)]
40 pub audio_generation: bool,
41
42 #[serde(default)]
43 pub streaming: bool,
44
45 #[serde(default)]
46 pub tools: bool,
47
48 #[serde(default)]
49 pub structured_output: bool,
50
51 #[serde(default)]
52 pub system_prompts: bool,
53
54 #[serde(default)]
55 pub image_resolution_config: bool,
56}
57
58#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, schemars::JsonSchema)]
59pub struct ModelLimits {
60 #[serde(default)]
61 pub context_window: u32,
62
63 #[serde(default)]
64 pub max_output_tokens: u32,
65
66 #[serde(default, skip_serializing_if = "Option::is_none")]
72 pub max_thinking_budget: Option<u32>,
73}
74
75#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, schemars::JsonSchema)]
76pub struct ModelPricing {
77 #[serde(default)]
78 pub input_per_million: f64,
79
80 #[serde(default)]
81 pub output_per_million: f64,
82
83 #[serde(default)]
88 pub cache_read_per_million: f64,
89
90 #[serde(default)]
93 pub cache_write_per_million: f64,
94
95 #[serde(default)]
96 pub per_image_cents: Option<f64>,
97}
98
99impl ModelPricing {
100 #[must_use]
104 pub fn is_billable(&self) -> bool {
105 if self.per_image_cents.is_some_and(|c| c > 0.0) {
106 return true;
107 }
108 self.input_per_million > 0.0 && self.output_per_million > 0.0
109 }
110}
111
112#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
113pub struct ModelDefinition {
114 #[serde(default)]
115 pub capabilities: ModelCapabilities,
116
117 #[serde(default)]
118 pub limits: ModelLimits,
119
120 #[serde(default)]
121 pub pricing: ModelPricing,
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct AiProviderConfig {
132 #[serde(default = "default_true")]
133 pub enabled: bool,
134
135 #[serde(default)]
137 pub default_model: String,
138
139 #[serde(default)]
140 pub default_image_model: String,
141
142 #[serde(default)]
143 pub google_search_enabled: bool,
144
145 #[serde(default)]
148 pub resilience: ResilienceSettings,
149}
150
151impl Default for AiProviderConfig {
152 fn default() -> Self {
153 Self {
154 enabled: true,
155 default_model: String::new(),
156 default_image_model: String::new(),
157 google_search_enabled: false,
158 resilience: ResilienceSettings::default(),
159 }
160 }
161}