use std::fmt;
use thiserror::Error;
pub type AgentResult<T> = Result<T, AgentError>;
#[derive(Debug, Error)]
pub enum AgentError {
#[error("Agent not found: {0}")]
NotFound(String),
#[error("Agent initialization failed: {0}")]
InitializationFailed(String),
#[error("Agent validation failed: {0}")]
ValidationFailed(String),
#[error("Agent execution failed: {0}")]
ExecutionFailed(String),
#[error("Tool execution failed: {tool_name}: {message}")]
ToolExecutionFailed { tool_name: String, message: String },
#[error("Tool not found: {0}")]
ToolNotFound(String),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Shutdown Failed: {0}")]
ShutdownFailed(String),
#[error("Invalid input: {0}")]
InvalidInput(String),
#[error("Invalid output: {0}")]
InvalidOutput(String),
#[error("Invalid state transition: from {from:?} to {to:?}")]
InvalidStateTransition { from: String, to: String },
#[error("Operation timed out after {duration_ms}ms")]
Timeout { duration_ms: u64 },
#[error("Operation was interrupted")]
Interrupted,
#[error("Resource unavailable: {0}")]
ResourceUnavailable(String),
#[error("Capability mismatch: required {required}, available {available}")]
CapabilityMismatch { required: String, available: String },
#[error("Agent factory not found: {0}")]
FactoryNotFound(String),
#[error("Registration failed: {0}")]
RegistrationFailed(String),
#[error("Memory error: {0}")]
MemoryError(String),
#[error("Reasoning error: {0}")]
ReasoningError(String),
#[error("Coordination error: {0}")]
CoordinationError(String),
#[error("Serialization error: {0}")]
SerializationError(String),
#[error("IO error: {0}")]
IoError(String),
#[error("Internal error: {0}")]
Internal(String),
#[error("{0}")]
Other(String),
}
impl AgentError {
pub fn tool_execution_failed(tool_name: impl Into<String>, message: impl Into<String>) -> Self {
Self::ToolExecutionFailed {
tool_name: tool_name.into(),
message: message.into(),
}
}
pub fn invalid_state_transition(from: impl fmt::Debug, to: impl fmt::Debug) -> Self {
Self::InvalidStateTransition {
from: format!("{:?}", from),
to: format!("{:?}", to),
}
}
pub fn timeout(duration_ms: u64) -> Self {
Self::Timeout { duration_ms }
}
pub fn capability_mismatch(required: impl Into<String>, available: impl Into<String>) -> Self {
Self::CapabilityMismatch {
required: required.into(),
available: available.into(),
}
}
}
impl From<std::io::Error> for AgentError {
fn from(err: std::io::Error) -> Self {
AgentError::IoError(err.to_string())
}
}
impl From<serde_json::Error> for AgentError {
fn from(err: serde_json::Error) -> Self {
AgentError::SerializationError(err.to_string())
}
}
impl From<anyhow::Error> for AgentError {
fn from(err: anyhow::Error) -> Self {
AgentError::Internal(err.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = AgentError::NotFound("test-agent".to_string());
assert_eq!(err.to_string(), "Agent not found: test-agent");
}
#[test]
fn test_tool_execution_failed() {
let err = AgentError::tool_execution_failed("calculator", "division by zero");
assert!(err.to_string().contains("calculator"));
assert!(err.to_string().contains("division by zero"));
}
}