1use thiserror::Error;
7
8pub type SageResult<T> = Result<T, SageError>;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16pub enum ErrorKind {
17 Llm,
19 Agent,
21 Runtime,
23}
24
25impl std::fmt::Display for ErrorKind {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 match self {
28 ErrorKind::Llm => write!(f, "Llm"),
29 ErrorKind::Agent => write!(f, "Agent"),
30 ErrorKind::Runtime => write!(f, "Runtime"),
31 }
32 }
33}
34
35#[derive(Debug, Error)]
40pub enum SageError {
41 #[error("LLM error: {0}")]
43 Llm(String),
44
45 #[error("Agent error: {0}")]
47 Agent(String),
48
49 #[error("Type error: expected {expected}, got {got}")]
51 Type { expected: String, got: String },
52
53 #[error("HTTP error: {0}")]
55 Http(#[from] reqwest::Error),
56
57 #[error("JSON error: {0}")]
59 Json(#[from] serde_json::Error),
60
61 #[error("Agent task failed: {0}")]
63 JoinError(String),
64}
65
66impl SageError {
67 #[must_use]
71 pub fn message(&self) -> String {
72 self.to_string()
73 }
74
75 #[must_use]
79 pub fn kind(&self) -> ErrorKind {
80 match self {
81 SageError::Llm(_) | SageError::Http(_) | SageError::Json(_) => ErrorKind::Llm,
82 SageError::Agent(_) | SageError::JoinError(_) => ErrorKind::Agent,
83 SageError::Type { .. } => ErrorKind::Runtime,
84 }
85 }
86
87 #[must_use]
89 pub fn llm(msg: impl Into<String>) -> Self {
90 SageError::Llm(msg.into())
91 }
92
93 #[must_use]
95 pub fn agent(msg: impl Into<String>) -> Self {
96 SageError::Agent(msg.into())
97 }
98
99 #[must_use]
101 pub fn type_error(expected: impl Into<String>, got: impl Into<String>) -> Self {
102 SageError::Type {
103 expected: expected.into(),
104 got: got.into(),
105 }
106 }
107}
108
109impl From<tokio::task::JoinError> for SageError {
110 fn from(e: tokio::task::JoinError) -> Self {
111 SageError::JoinError(e.to_string())
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn error_kind_classification() {
121 assert_eq!(SageError::llm("test").kind(), ErrorKind::Llm);
122 assert_eq!(SageError::agent("test").kind(), ErrorKind::Agent);
123 assert_eq!(
124 SageError::type_error("Int", "String").kind(),
125 ErrorKind::Runtime
126 );
127 }
128
129 #[test]
130 fn error_message() {
131 let err = SageError::llm("inference failed");
132 assert_eq!(err.message(), "LLM error: inference failed");
133 }
134
135 #[test]
136 fn error_kind_display() {
137 assert_eq!(format!("{}", ErrorKind::Llm), "Llm");
138 assert_eq!(format!("{}", ErrorKind::Agent), "Agent");
139 assert_eq!(format!("{}", ErrorKind::Runtime), "Runtime");
140 }
141}