1use crate::config::ModelCapability;
4use thiserror::Error;
5
6#[derive(Debug, Error)]
8pub enum RoutingError {
9 #[error("Policy evaluation failed: {reason}")]
10 PolicyEvaluationFailed { reason: String },
11
12 #[error("No suitable model found for task: {task_type:?}")]
13 NoSuitableModel { task_type: TaskType },
14
15 #[error("Model execution failed: {model_id} - {reason}")]
16 ModelExecutionFailed { model_id: String, reason: String },
17
18 #[error("LLM fallback failed: {provider} - {reason}")]
19 LLMFallbackFailed { provider: String, reason: String },
20
21 #[error("Routing denied by policy: {policy} - {reason}")]
22 RoutingDenied { policy: String, reason: String },
23
24 #[error("Task classification failed: {reason}")]
25 ClassificationFailed { reason: String },
26
27 #[error("Configuration error: {key} - {reason}")]
28 ConfigurationError { key: String, reason: String },
29
30 #[error("Resource constraint violation: {constraint}")]
31 ResourceConstraintViolation { constraint: String },
32
33 #[error("Confidence evaluation failed: {reason}")]
34 ConfidenceEvaluationFailed { reason: String },
35
36 #[error("Invalid routing context: {reason}")]
37 InvalidContext { reason: String },
38
39 #[error("Model catalog error: {reason}")]
40 ModelCatalogError { reason: String },
41
42 #[error("Timeout during routing: {operation}")]
43 Timeout { operation: String },
44
45 #[error("Invalid model selection: {model_id} - {reason}")]
46 InvalidModelSelection { model_id: String, reason: String },
47
48 #[error("Policy rule parsing failed: {rule} - {reason}")]
49 PolicyRuleParsingFailed { rule: String, reason: String },
50
51 #[error("Confidence threshold not met: current={current}, required={required}")]
52 ConfidenceThresholdNotMet { current: f64, required: f64 },
53
54 #[error("Routing context validation failed: {field} - {reason}")]
55 ContextValidationFailed { field: String, reason: String },
56
57 #[error("Model capability mismatch: required={required:?}, available={available:?}")]
58 CapabilityMismatch {
59 required: Vec<crate::config::ModelCapability>,
60 available: Vec<crate::config::ModelCapability>,
61 },
62
63 #[error("External provider error: {provider} - {error}")]
64 ExternalProviderError { provider: String, error: String },
65
66 #[error("Concurrent access error: {resource}")]
67 ConcurrentAccessError { resource: String },
68
69 #[error("Resource exhaustion: {resource} - {details}")]
70 ResourceExhaustion { resource: String, details: String },
71
72 #[error("Serialization error: {context} - {source}")]
73 SerializationError {
74 context: String,
75 #[source]
76 source: serde_json::Error,
77 },
78}
79
80pub type RoutingResult<T> = Result<T, RoutingError>;
82
83impl RoutingError {
84 pub fn is_retryable(&self) -> bool {
86 matches!(
87 self,
88 RoutingError::Timeout { .. }
89 | RoutingError::ExternalProviderError { .. }
90 | RoutingError::ConcurrentAccessError { .. }
91 | RoutingError::ResourceExhaustion { .. }
92 | RoutingError::ModelExecutionFailed { .. }
93 )
94 }
95
96 pub fn severity(&self) -> ErrorSeverity {
98 match self {
99 RoutingError::PolicyEvaluationFailed { .. } => ErrorSeverity::High,
100 RoutingError::NoSuitableModel { .. } => ErrorSeverity::High,
101 RoutingError::LLMFallbackFailed { .. } => ErrorSeverity::Critical,
102 RoutingError::RoutingDenied { .. } => ErrorSeverity::Medium,
103 RoutingError::ConfigurationError { .. } => ErrorSeverity::High,
104 RoutingError::InvalidContext { .. } => ErrorSeverity::Medium,
105 RoutingError::CapabilityMismatch { .. } => ErrorSeverity::Medium,
106 RoutingError::ExternalProviderError { .. } => ErrorSeverity::Medium,
107 RoutingError::ResourceExhaustion { .. } => ErrorSeverity::High,
108 _ => ErrorSeverity::Low,
109 }
110 }
111}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq)]
115pub enum ErrorSeverity {
116 Low,
117 Medium,
118 High,
119 Critical,
120}
121
122#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
124pub enum TaskType {
125 Intent,
126 Extract,
127 Template,
128 BoilerplateCode,
129 CodeGeneration,
130 Reasoning,
131 Analysis,
132 Summarization,
133 Translation,
134 QA,
135 Custom(String),
136}
137
138impl TaskType {
139 pub fn to_capabilities(&self) -> Vec<ModelCapability> {
141 match self {
142 TaskType::CodeGeneration | TaskType::BoilerplateCode => {
143 vec![
144 ModelCapability::CodeGeneration,
145 ModelCapability::TextGeneration,
146 ]
147 }
148 TaskType::Reasoning | TaskType::Analysis => {
149 vec![ModelCapability::Reasoning, ModelCapability::TextGeneration]
150 }
151 TaskType::Intent | TaskType::Extract | TaskType::Template => {
152 vec![ModelCapability::TextGeneration]
153 }
154 TaskType::Summarization | TaskType::Translation | TaskType::QA => {
155 vec![ModelCapability::TextGeneration]
156 }
157 TaskType::Custom(_) => {
158 vec![ModelCapability::TextGeneration]
159 }
160 }
161 }
162
163 pub fn complexity_level(&self) -> u8 {
165 match self {
166 TaskType::Intent | TaskType::Extract | TaskType::Template => 1,
167 TaskType::BoilerplateCode | TaskType::Summarization | TaskType::Translation => 2,
168 TaskType::QA | TaskType::CodeGeneration => 3,
169 TaskType::Reasoning | TaskType::Analysis => 4,
170 TaskType::Custom(_) => 2, }
172 }
173}
174
175impl std::fmt::Display for TaskType {
176 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
177 match self {
178 TaskType::Intent => write!(f, "Intent"),
179 TaskType::Extract => write!(f, "Extract"),
180 TaskType::Template => write!(f, "Template"),
181 TaskType::BoilerplateCode => write!(f, "BoilerplateCode"),
182 TaskType::CodeGeneration => write!(f, "CodeGeneration"),
183 TaskType::Reasoning => write!(f, "Reasoning"),
184 TaskType::Analysis => write!(f, "Analysis"),
185 TaskType::Summarization => write!(f, "Summarization"),
186 TaskType::Translation => write!(f, "Translation"),
187 TaskType::QA => write!(f, "QA"),
188 TaskType::Custom(name) => write!(f, "Custom({})", name),
189 }
190 }
191}
192
193impl From<crate::models::ModelCatalogError> for RoutingError {
194 fn from(err: crate::models::ModelCatalogError) -> Self {
195 RoutingError::ModelCatalogError {
196 reason: err.to_string(),
197 }
198 }
199}
200
201impl From<super::confidence::ConfidenceError> for RoutingError {
202 fn from(err: super::confidence::ConfidenceError) -> Self {
203 RoutingError::ConfidenceEvaluationFailed {
204 reason: err.to_string(),
205 }
206 }
207}