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")]
67 pub max_thinking_budget: Option<u32>,
68}
69
70#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, schemars::JsonSchema)]
71pub struct ModelPricing {
72 #[serde(default)]
73 pub input_per_million: f64,
74
75 #[serde(default)]
76 pub output_per_million: f64,
77
78 #[serde(default)]
79 pub cache_read_per_million: f64,
80
81 #[serde(default)]
82 pub cache_write_per_million: f64,
83
84 #[serde(default)]
85 pub per_image_cents: Option<f64>,
86}
87
88impl ModelPricing {
89 #[must_use]
90 pub fn is_billable(&self) -> bool {
91 if self.per_image_cents.is_some_and(|c| c > 0.0) {
92 return true;
93 }
94 self.input_per_million > 0.0 && self.output_per_million > 0.0
95 }
96}
97
98#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
99pub struct ModelDefinition {
100 #[serde(default)]
101 pub capabilities: ModelCapabilities,
102
103 #[serde(default)]
104 pub limits: ModelLimits,
105
106 #[serde(default)]
107 pub pricing: ModelPricing,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
117pub struct AiProviderConfig {
118 #[serde(default = "default_true")]
119 pub enabled: bool,
120
121 #[serde(default)]
122 pub default_model: String,
123
124 #[serde(default)]
125 pub default_image_model: String,
126
127 #[serde(default)]
128 pub google_search_enabled: bool,
129
130 #[serde(default)]
131 pub resilience: ResilienceSettings,
132}
133
134impl Default for AiProviderConfig {
135 fn default() -> Self {
136 Self {
137 enabled: true,
138 default_model: String::new(),
139 default_image_model: String::new(),
140 google_search_enabled: false,
141 resilience: ResilienceSettings::default(),
142 }
143 }
144}