1use thiserror::Error;
6
7#[derive(Debug, Error)]
9pub enum Error {
10 #[error("Provider error: {0}")]
11 Provider(#[from] ProviderError),
12
13 #[error("Database error: {0}")]
14 Database(#[from] DatabaseError),
15
16 #[error("Memory error: {0}")]
17 Memory(#[from] MemoryError),
18
19 #[error("Security error: {0}")]
20 Security(#[from] SecurityError),
21
22 #[error("Scheduler error: {0}")]
23 Scheduler(#[from] SchedulerError),
24
25 #[error("MCP error: {0}")]
26 Mcp(#[from] McpError),
27
28 #[error("Tool error: {0}")]
29 Tool(#[from] ToolError),
30
31 #[error("Gateway error: {0}")]
32 Gateway(#[from] GatewayError),
33
34 #[error("Channel error: {0}")]
35 Channel(#[from] ChannelError),
36
37 #[error("Voice error: {0}")]
38 Voice(#[from] VoiceError),
39
40 #[error("Distributed error: {0}")]
41 Distributed(#[from] DistributedError),
42
43 #[error("Configuration error: {0}")]
44 Config(String),
45
46 #[error("Sidecar error: {0}")]
47 Sidecar(String),
48
49 #[error("Internal error: {0}")]
50 Internal(String),
51}
52
53#[derive(Debug, Error)]
55pub enum ProviderError {
56 #[error("rate limit from {provider} (retry after {retry_after_secs:?}s)")]
57 RateLimited {
58 provider: String,
59 retry_after_secs: Option<u64>,
60 },
61
62 #[error("Authentication failed for {provider}: {message}")]
63 AuthFailed { provider: String, message: String },
64
65 #[error("Model {model} not found on {provider}")]
66 ModelNotFound { provider: String, model: String },
67
68 #[error("Context length exceeded: {used} tokens used, {max} max")]
69 ContextLengthExceeded { used: usize, max: usize },
70
71 #[error("Provider {provider} unavailable: {message}")]
72 Unavailable { provider: String, message: String },
73
74 #[error("Invalid tool call from {provider}: {message}")]
75 InvalidToolCall { provider: String, message: String },
76
77 #[error("Streaming error from {provider}: {message}")]
78 StreamError { provider: String, message: String },
79
80 #[error("Batch error from {provider}: {message}")]
81 BatchError { provider: String, message: String },
82
83 #[error("All providers in fallback chain exhausted")]
84 AllProvidersExhausted,
85
86 #[error("Provider request error: {0}")]
87 Request(String),
88
89 #[error("Provider response parse error: {0}")]
90 Parse(String),
91}
92
93#[derive(Debug, Error)]
95pub enum DatabaseError {
96 #[error("Connection error: {0}")]
97 Connection(String),
98
99 #[error("Migration error: {0}")]
100 Migration(String),
101
102 #[error("Query error: {0}")]
103 Query(String),
104
105 #[error("Record not found: {entity} with id {id}")]
106 NotFound { entity: String, id: String },
107
108 #[error("Constraint violation: {0}")]
109 Constraint(String),
110}
111
112#[derive(Debug, Error)]
114pub enum MemoryError {
115 #[error("Embedding error: {0}")]
116 Embedding(String),
117
118 #[error("Search error: {0}")]
119 Search(String),
120
121 #[error("Core memory budget exceeded: {used} tokens, max {max}")]
122 CoreMemoryBudgetExceeded { used: usize, max: usize },
123
124 #[error("Deduplication: entry already exists with id {existing_id}")]
125 Duplicate { existing_id: String },
126
127 #[error("Memory store error: {0}")]
128 Store(String),
129}
130
131#[derive(Debug, Error)]
133pub enum SecurityError {
134 #[error("Authentication required")]
135 AuthRequired,
136
137 #[error("Invalid origin: {origin}")]
138 InvalidOrigin { origin: String },
139
140 #[error("Token expired")]
141 TokenExpired,
142
143 #[error("Token invalid: {0}")]
144 TokenInvalid(String),
145
146 #[error("Skill verification failed: {0}")]
147 SkillVerificationFailed(String),
148
149 #[error("Prompt injection detected: {0}")]
150 PromptInjectionDetected(String),
151
152 #[error("Permission denied: {0}")]
153 PermissionDenied(String),
154
155 #[error("Session isolation violation: {0}")]
156 IsolationViolation(String),
157}
158
159#[derive(Debug, Error)]
161pub enum SchedulerError {
162 #[error("Job not found: {0}")]
163 JobNotFound(String),
164
165 #[error("Lease acquisition failed for job {job_id}")]
166 LeaseAcquisitionFailed { job_id: String },
167
168 #[error("Idempotency conflict: job {job_id} already completed with key {key}")]
169 IdempotencyConflict { job_id: String, key: String },
170
171 #[error("Max retries exceeded for job {job_id} (attempts: {attempts})")]
172 MaxRetriesExceeded { job_id: String, attempts: u32 },
173
174 #[error("Workflow execution failed: {0}")]
175 WorkflowFailed(String),
176
177 #[error("Invalid trigger config: {0}")]
178 InvalidTrigger(String),
179
180 #[error("Heartbeat task not found: {0}")]
181 HeartbeatTaskNotFound(String),
182
183 #[error("Invalid cron expression: {0}")]
184 InvalidCronExpression(String),
185
186 #[error("Missing heartbeat condition")]
187 MissingHeartbeatCondition,
188
189 #[error("Missing heartbeat action")]
190 MissingHeartbeatAction,
191
192 #[error("Heartbeat cooldown active for task {0}")]
193 HeartbeatCooldown(String),
194
195 #[error("File watch error: {0}")]
196 FileWatchError(String),
197
198 #[error("Heartbeat action failed: {0}")]
199 HeartbeatActionFailed(String),
200}
201
202#[derive(Debug, Error)]
204pub enum McpError {
205 #[error("MCP connection error: {0}")]
206 Connection(String),
207
208 #[error("MCP tool not found: {server}/{tool}")]
209 ToolNotFound { server: String, tool: String },
210
211 #[error("MCP tool execution error: {0}")]
212 ToolExecution(String),
213
214 #[error("MCP schema translation error: {0}")]
215 SchemaTranslation(String),
216
217 #[error("MCP transport error: {0}")]
218 Transport(String),
219}
220
221#[derive(Debug, Error)]
223pub enum ToolError {
224 #[error("Tool not found: {0}")]
225 NotFound(String),
226
227 #[error("Tool execution failed: {tool}: {message}")]
228 ExecutionFailed { tool: String, message: String },
229
230 #[error("Tool input validation error: {tool}: {message}")]
231 InputValidation { tool: String, message: String },
232
233 #[error("Tool capability not granted: {tool} requires {capability}")]
234 CapabilityDenied { tool: String, capability: String },
235
236 #[error("Tool sandbox violation: {0}")]
237 SandboxViolation(String),
238
239 #[error("Tool timeout: {tool} exceeded {timeout_ms}ms")]
240 Timeout { tool: String, timeout_ms: u64 },
241}
242
243#[derive(Debug, Error)]
245pub enum GatewayError {
246 #[error("WebSocket error: {0}")]
247 WebSocket(String),
248
249 #[error("Session not found: {0}")]
250 SessionNotFound(String),
251
252 #[error("Rate limit exceeded for session {session_id}")]
253 RateLimitExceeded { session_id: String },
254
255 #[error("Connection closed: {0}")]
256 ConnectionClosed(String),
257}
258
259#[derive(Debug, Error)]
261pub enum DistributedError {
262 #[error("Cluster error: {0}")]
263 Cluster(String),
264
265 #[error("Node error: {0}")]
266 Node(String),
267
268 #[error("Consensus error: {0}")]
269 Consensus(String),
270
271 #[error("Discovery error: {0}")]
272 Discovery(String),
273
274 #[error("Messaging error: {0}")]
275 Messaging(String),
276
277 #[error("Session error: {0}")]
278 Session(String),
279
280 #[error("Memory error: {0}")]
281 Memory(String),
282
283 #[error("Lock error: {lock_name}: {message}")]
284 Lock { lock_name: String, message: String },
285
286 #[error("Task error: {0}")]
287 Task(String),
288
289 #[error("Leader not available")]
290 LeaderNotAvailable,
291
292 #[error("Not leader: current leader is {0:?}")]
293 NotLeader(Option<String>),
294
295 #[error("Node not found: {0}")]
296 NodeNotFound(String),
297
298 #[error("Session not found: {0}")]
299 SessionNotFound(String),
300
301 #[error("Task not found: {0}")]
302 TaskNotFound(String),
303
304 #[error("Split brain detected: conflicting leader {0}")]
305 SplitBrain(String),
306
307 #[error("Quorum not reached: {0} of {1} nodes available")]
308 QuorumNotReached(usize, usize),
309
310 #[error("Timeout: {0}")]
311 Timeout(String),
312
313 #[error("Serialization error: {0}")]
314 Serialization(String),
315
316 #[error("Invalid state transition from {from} to {to}")]
317 InvalidStateTransition { from: String, to: String },
318}
319
320#[derive(Debug, Error)]
322pub enum ChannelError {
323 #[error("{platform} authentication failed: {message}")]
324 AuthFailed { platform: String, message: String },
325
326 #[error("{platform} rate limited (retry after {retry_after_secs:?}s)")]
327 RateLimited {
328 platform: String,
329 retry_after_secs: Option<u64>,
330 },
331
332 #[error("{platform} connection error: {message}")]
333 Connection { platform: String, message: String },
334
335 #[error("{platform} message send failed: {message}")]
336 SendFailed { platform: String, message: String },
337
338 #[error("{platform} invalid message format: {message}")]
339 InvalidFormat { platform: String, message: String },
340
341 #[error("{platform} configuration error: {message}")]
342 Config { platform: String, message: String },
343
344 #[error("{platform} not connected")]
345 NotConnected { platform: String },
346
347 #[error("{platform} Pub/Sub error: {message}")]
348 PubSubError { platform: String, message: String },
349
350 #[error("{platform} permission denied: {message}")]
351 PermissionDenied { platform: String, message: String },
352}
353
354#[derive(Debug, Error)]
356pub enum VoiceError {
357 #[error("Wake word error: {0}")]
358 Wake(String),
359
360 #[error("Speech-to-text error: {0}")]
361 Stt(String),
362
363 #[error("Text-to-speech error: {0}")]
364 Tts(String),
365
366 #[error("Audio error: {0}")]
367 Audio(String),
368
369 #[error("Audio device not found: {0}")]
370 DeviceNotFound(String),
371
372 #[error("Model error: {0}")]
373 Model(String),
374
375 #[error("Voice configuration error: {0}")]
376 VoiceConfig(String),
377
378 #[error("Component not initialized: {0}")]
379 NotInitialized(String),
380
381 #[error("Talk mode error: {0}")]
382 TalkMode(String),
383
384 #[error("Voice API error: {0}")]
385 VoiceApi(String),
386
387 #[error("Invalid audio format: {0}")]
388 InvalidFormat(String),
389
390 #[error("Voice timeout: {0}")]
391 VoiceTimeout(String),
392}
393
394pub type Result<T> = std::result::Result<T, Error>;