1use std::time::Duration;
4
5#[derive(Debug, thiserror::Error)]
7pub enum ProviderError {
8 #[error("network error: {0}")]
11 Network(#[source] Box<dyn std::error::Error + Send + Sync>),
12 #[error("rate limited, retry after {retry_after:?}")]
14 RateLimit {
15 retry_after: Option<Duration>,
17 },
18 #[error("model loading: {0}")]
20 ModelLoading(String),
21 #[error("timeout after {0:?}")]
23 Timeout(Duration),
24 #[error("service unavailable: {0}")]
26 ServiceUnavailable(String),
27
28 #[error("authentication failed: {0}")]
31 Authentication(String),
32 #[error("invalid request: {0}")]
34 InvalidRequest(String),
35 #[error("model not found: {0}")]
37 ModelNotFound(String),
38 #[error("insufficient resources: {0}")]
40 InsufficientResources(String),
41
42 #[error("stream error: {0}")]
45 StreamError(String),
46 #[error(transparent)]
48 Other(Box<dyn std::error::Error + Send + Sync>),
49}
50
51impl ProviderError {
52 #[must_use]
54 pub fn is_retryable(&self) -> bool {
55 matches!(
56 self,
57 Self::Network(_)
58 | Self::RateLimit { .. }
59 | Self::ModelLoading(_)
60 | Self::Timeout(_)
61 | Self::ServiceUnavailable(_)
62 )
63 }
64}
65
66#[derive(Debug, thiserror::Error)]
68pub enum ToolError {
69 #[error("tool not found: {0}")]
71 NotFound(String),
72 #[error("invalid input: {0}")]
74 InvalidInput(String),
75 #[error("execution failed: {0}")]
77 ExecutionFailed(#[source] Box<dyn std::error::Error + Send + Sync>),
78 #[error("permission denied: {0}")]
80 PermissionDenied(String),
81 #[error("cancelled")]
83 Cancelled,
84}
85
86#[derive(Debug, thiserror::Error)]
88pub enum ContextError {
89 #[error("compaction failed: {0}")]
91 CompactionFailed(String),
92 #[error("provider error during summarization: {0}")]
94 Provider(#[from] ProviderError),
95}
96
97#[derive(Debug, thiserror::Error)]
99pub enum LoopError {
100 #[error("provider error: {0}")]
102 Provider(#[from] ProviderError),
103 #[error("tool error: {0}")]
105 Tool(#[from] ToolError),
106 #[error("context error: {0}")]
108 Context(#[from] ContextError),
109 #[error("max turns reached ({0})")]
111 MaxTurns(usize),
112 #[error("terminated by hook: {0}")]
114 HookTerminated(String),
115}
116
117#[derive(Debug, thiserror::Error)]
119pub enum DurableError {
120 #[error("activity failed: {0}")]
122 ActivityFailed(String),
123 #[error("workflow cancelled")]
125 Cancelled,
126 #[error("signal timeout")]
128 SignalTimeout,
129 #[error("continue as new: {0}")]
131 ContinueAsNew(String),
132 #[error(transparent)]
134 Other(Box<dyn std::error::Error + Send + Sync>),
135}
136
137#[derive(Debug, thiserror::Error)]
139pub enum McpError {
140 #[error("connection failed: {0}")]
142 Connection(String),
143 #[error("initialization failed: {0}")]
145 Initialization(String),
146 #[error("tool call failed: {0}")]
148 ToolCall(String),
149 #[error("transport error: {0}")]
151 Transport(String),
152 #[error(transparent)]
154 Other(Box<dyn std::error::Error + Send + Sync>),
155}
156
157#[derive(Debug, thiserror::Error)]
159pub enum HookError {
160 #[error("hook failed: {0}")]
162 Failed(String),
163 #[error(transparent)]
165 Other(Box<dyn std::error::Error + Send + Sync>),
166}
167
168#[derive(Debug, thiserror::Error)]
170pub enum StorageError {
171 #[error("not found: {0}")]
173 NotFound(String),
174 #[error("serialization error: {0}")]
176 Serialization(String),
177 #[error("io error: {0}")]
179 Io(#[from] std::io::Error),
180 #[error(transparent)]
182 Other(Box<dyn std::error::Error + Send + Sync>),
183}
184
185#[derive(Debug, thiserror::Error)]
187pub enum SubAgentError {
188 #[error("sub-agent not found: {0}")]
190 NotFound(String),
191 #[error("max depth exceeded: {0}")]
193 MaxDepthExceeded(usize),
194 #[error("loop error: {0}")]
196 Loop(#[from] LoopError),
197}
198
199#[derive(Debug, thiserror::Error)]
201pub enum SandboxError {
202 #[error("execution failed: {0}")]
204 ExecutionFailed(String),
205 #[error("sandbox error: {0}")]
207 SetupFailed(String),
208 #[error(transparent)]
210 Other(Box<dyn std::error::Error + Send + Sync>),
211}