1use anyhow::Error as AnyhowError;
2use thiserror::Error;
3
4pub type Result<T> = std::result::Result<T, Error>;
6
7#[derive(Debug, Error)]
9pub enum Error {
10 #[error("Agent configuration error: {0}")]
14 AgentConfig(String),
15
16 #[error("Agent execution error: {0}")]
18 AgentExecution(String),
19
20 #[error("Provider API error: {0}")]
23 ProviderApi(String),
24
25 #[error("Provider authentication error: {0}")]
27 ProviderAuth(String),
28
29 #[error("Provider rate limit exceeded: retry after {retry_after_secs}s")]
31 ProviderRateLimit {
32 retry_after_secs: u64,
34 },
35
36 #[error("Tool not found: {0}")]
39 ToolNotFound(String),
40
41 #[error("Tool execution error: {tool_name} - {message}")]
43 ToolExecution {
44 tool_name: String,
46 message: String,
48 },
49
50 #[error("Tool execution blocked: {tool_name} requires approval but no handler was available")]
52 ToolApprovalRequired {
53 tool_name: String,
55 },
56
57 #[error("Invalid tool arguments for {tool_name}: {message}")]
59 ToolArguments {
60 tool_name: String,
62 message: String,
64 },
65
66 #[error("Message parse error: {0}")]
69 MessageParse(String),
70
71 #[error("Message serialization error: {0}")]
73 MessageSerialize(#[from] serde_json::Error),
74
75 #[error("Stream interrupted: {0}")]
78 StreamInterrupted(String),
79
80 #[error("Stream timeout after {timeout_secs}s")]
82 StreamTimeout {
83 timeout_secs: u64,
85 },
86
87 #[error("Memory storage error: {0}")]
90 MemoryStorage(String),
91
92 #[error("Memory retrieval error: {0}")]
94 MemoryRetrieval(String),
95
96 #[error("Strategy configuration error: {0}")]
99 StrategyConfig(String),
100
101 #[error("Strategy execution error: {0}")]
103 StrategyExecution(String),
104
105 #[error("Condition evaluation error: {0}")]
107 ConditionEvaluation(String),
108
109 #[error("Risk check failed: {check_name} - {reason}")]
112 RiskCheckFailed {
113 check_name: String,
115 reason: String,
117 },
118
119 #[error("Risk limit exceeded: {limit_type} - current: {current}, max: {max}")]
121 RiskLimitExceeded {
122 limit_type: String,
124 current: String,
126 max: String,
128 },
129
130 #[error("Simulation error: {0}")]
133 Simulation(String),
134
135 #[error("Agent coordination error: {0}")]
138 AgentCoordination(String),
139
140 #[error("Agent communication error: {0}")]
142 AgentCommunication(String),
143
144 #[error("HTTP error: {0}")]
147 Http(#[from] reqwest::Error),
148
149 #[error("IO error: {0}")]
152 Io(#[from] std::io::Error),
153
154 #[error("Internal error: {0}")]
157 Internal(String),
158
159 #[error("{0}")]
161 Other(AnyhowError),
162}
163
164impl Error {
165 pub fn agent_config(msg: impl Into<String>) -> Self {
167 Self::AgentConfig(msg.into())
168 }
169
170 pub fn tool_execution(tool_name: impl Into<String>, message: impl Into<String>) -> Self {
172 Self::ToolExecution {
173 tool_name: tool_name.into(),
174 message: message.into(),
175 }
176 }
177
178 pub fn risk_check_failed(check_name: impl Into<String>, reason: impl Into<String>) -> Self {
180 Self::RiskCheckFailed {
181 check_name: check_name.into(),
182 reason: reason.into(),
183 }
184 }
185
186 pub fn is_retryable(&self) -> bool {
188 matches!(
189 self,
190 Self::ProviderRateLimit { .. }
191 | Self::StreamInterrupted(_)
192 | Self::StreamTimeout { .. }
193 | Self::Http(_)
194 )
195 }
196}