#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ErrorDomain {
Planning,
Reflection,
Action,
System,
}
impl ErrorDomain {
#[must_use]
pub fn is_auto_retryable(self) -> bool {
matches!(self, Self::System)
}
#[must_use]
pub fn needs_llm_correction(self) -> bool {
matches!(self, Self::Reflection | Self::Planning)
}
#[must_use]
pub fn label(self) -> &'static str {
match self {
Self::Planning => "planning",
Self::Reflection => "reflection",
Self::Action => "action",
Self::System => "system",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ToolInvocationPhase {
Setup,
ParamHandling,
Execution,
ResultInterpretation,
}
impl ToolInvocationPhase {
#[must_use]
pub fn label(self) -> &'static str {
match self {
Self::Setup => "setup",
Self::ParamHandling => "param_handling",
Self::Execution => "execution",
Self::ResultInterpretation => "result_interpretation",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize)]
pub enum ToolErrorCategory {
ToolNotFound,
InvalidParameters,
TypeMismatch,
PolicyBlocked,
ConfirmationRequired,
PermanentFailure,
Cancelled,
RateLimited,
ServerError,
NetworkError,
Timeout,
}
impl ToolErrorCategory {
#[must_use]
pub fn is_retryable(self) -> bool {
matches!(
self,
Self::RateLimited | Self::ServerError | Self::NetworkError | Self::Timeout
)
}
#[must_use]
pub fn needs_parameter_reformat(self) -> bool {
matches!(self, Self::InvalidParameters | Self::TypeMismatch)
}
#[must_use]
pub fn is_quality_failure(self) -> bool {
matches!(
self,
Self::InvalidParameters | Self::TypeMismatch | Self::ToolNotFound
)
}
#[must_use]
pub fn domain(self) -> ErrorDomain {
match self {
Self::ToolNotFound => ErrorDomain::Planning,
Self::InvalidParameters | Self::TypeMismatch => ErrorDomain::Reflection,
Self::PolicyBlocked
| Self::ConfirmationRequired
| Self::PermanentFailure
| Self::Cancelled => ErrorDomain::Action,
Self::RateLimited | Self::ServerError | Self::NetworkError | Self::Timeout => {
ErrorDomain::System
}
}
}
#[must_use]
pub fn label(self) -> &'static str {
match self {
Self::ToolNotFound => "tool_not_found",
Self::InvalidParameters => "invalid_parameters",
Self::TypeMismatch => "type_mismatch",
Self::PolicyBlocked => "policy_blocked",
Self::ConfirmationRequired => "confirmation_required",
Self::PermanentFailure => "permanent_failure",
Self::Cancelled => "cancelled",
Self::RateLimited => "rate_limited",
Self::ServerError => "server_error",
Self::NetworkError => "network_error",
Self::Timeout => "timeout",
}
}
#[must_use]
pub fn phase(self) -> ToolInvocationPhase {
match self {
Self::ToolNotFound => ToolInvocationPhase::Setup,
Self::InvalidParameters | Self::TypeMismatch => ToolInvocationPhase::ParamHandling,
Self::PolicyBlocked
| Self::ConfirmationRequired
| Self::PermanentFailure
| Self::Cancelled
| Self::RateLimited
| Self::ServerError
| Self::NetworkError
| Self::Timeout => ToolInvocationPhase::Execution,
}
}
#[must_use]
pub fn suggestion(self) -> &'static str {
match self {
Self::ToolNotFound => {
"Check the tool name. Use tool_definitions to see available tools."
}
Self::InvalidParameters => "Review the tool schema and provide correct parameters.",
Self::TypeMismatch => "Check parameter types against the tool schema.",
Self::PolicyBlocked => {
"This operation is blocked by security policy. Try an alternative approach."
}
Self::ConfirmationRequired => "This operation requires user confirmation.",
Self::PermanentFailure => {
"This resource is not available. Try an alternative approach."
}
Self::Cancelled => "Operation was cancelled by the user.",
Self::RateLimited => "Rate limit exceeded. The system will retry if possible.",
Self::ServerError => "Server error. The system will retry if possible.",
Self::NetworkError => "Network error. The system will retry if possible.",
Self::Timeout => "Operation timed out. The system will retry if possible.",
}
}
}