1use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::fmt;
9use uuid::Uuid;
10
11#[derive(Debug, thiserror::Error)]
13pub enum IntentError {
14 #[error("Classification failed: {0}")]
15 ClassificationFailed(String),
16
17 #[error("Invalid parameter '{parameter}': {message}")]
18 InvalidParameter { parameter: String, message: String },
19
20 #[error("Training failed: {0}")]
21 TrainingFailed(String),
22
23 #[error("Serialization error: {0}")]
24 SerializationError(#[from] serde_json::Error),
25
26 #[error("Invalid confidence value: {0}")]
27 InvalidConfidence(String),
28}
29
30pub type Result<T> = std::result::Result<T, IntentError>;
32
33#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
35pub struct IntentId(pub String);
36
37impl fmt::Display for IntentId {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "{}", self.0)
40 }
41}
42
43impl From<String> for IntentId {
44 fn from(s: String) -> Self {
45 IntentId(s)
46 }
47}
48
49impl From<&str> for IntentId {
50 fn from(s: &str) -> Self {
51 IntentId(s.to_string())
52 }
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
57pub struct Confidence(f64);
58
59impl Confidence {
60 pub fn new(value: f64) -> Result<Self> {
62 if (0.0..=1.0).contains(&value) {
63 Ok(Confidence(value))
64 } else {
65 Err(IntentError::InvalidParameter {
66 parameter: "confidence".to_string(),
67 message: format!("Confidence must be between 0.0 and 1.0, got {}", value),
68 })
69 }
70 }
71
72 pub fn value(&self) -> f64 {
74 self.0
75 }
76
77 pub fn is_high(&self) -> bool {
79 self.0 >= 0.8
80 }
81
82 pub fn is_medium(&self) -> bool {
84 self.0 >= 0.5 && self.0 < 0.8
85 }
86
87 pub fn is_low(&self) -> bool {
89 self.0 < 0.5
90 }
91}
92
93impl Default for Confidence {
94 fn default() -> Self {
95 Confidence(1.0)
96 }
97}
98
99impl From<Confidence> for f64 {
100 fn from(confidence: Confidence) -> Self {
101 confidence.0
102 }
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct IntentPrediction {
108 pub intent: IntentId,
110
111 pub confidence: Confidence,
113
114 pub alternative_intents: Vec<(IntentId, Confidence)>,
116
117 pub reasoning: String,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct TrainingExample {
124 pub text: String,
126
127 pub intent: IntentId,
129
130 pub confidence: f64,
132
133 pub source: TrainingSource,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
139pub enum TrainingSource {
140 Bootstrap,
142
143 UserFeedback,
145
146 Programmatic,
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct FeatureVector {
153 pub text_features: Vec<f64>,
155
156 pub context_features: Vec<f64>,
158
159 pub metadata: HashMap<String, f64>,
161}
162
163#[derive(Debug, Clone, Serialize, Deserialize)]
165pub struct ClassifierConfig {
166 pub feature_dimensions: usize,
168
169 pub max_vocabulary_size: usize,
171
172 pub min_confidence_threshold: f64,
174
175 pub retraining_threshold: usize,
177
178 pub debug_mode: bool,
180}
181
182impl Default for ClassifierConfig {
183 fn default() -> Self {
184 Self {
185 feature_dimensions: 1000,
186 max_vocabulary_size: 10000,
187 min_confidence_threshold: 0.3,
188 retraining_threshold: 10,
189 debug_mode: false,
190 }
191 }
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct ClassifierStats {
197 pub training_examples: usize,
199
200 pub vocabulary_size: usize,
202
203 pub intent_count: usize,
205
206 pub feedback_examples: usize,
208
209 pub last_updated: Option<DateTime<Utc>>,
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct IntentFeedback {
216 pub text: String,
218
219 pub predicted_intent: IntentId,
221
222 pub actual_intent: IntentId,
224
225 pub satisfaction_score: f64,
227
228 pub notes: Option<String>,
230
231 pub timestamp: DateTime<Utc>,
233}
234
235#[derive(Debug, Clone, Serialize, Deserialize)]
237pub struct ClassificationRequest {
238 pub text: String,
240
241 pub context: Option<HashMap<String, String>>,
243
244 pub include_alternatives: bool,
246
247 pub include_reasoning: bool,
249}
250
251#[derive(Debug, Clone, Serialize, Deserialize)]
253pub struct ClassificationResponse {
254 pub prediction: IntentPrediction,
256
257 pub processing_time_ms: f64,
259
260 pub request_id: Uuid,
262}