1use std::path::PathBuf;
2
3#[derive(Debug, thiserror::Error)]
4pub enum SkillError {
5 #[error("io error: {0}")]
6 Io(#[from] std::io::Error),
7
8 #[error("yaml parse error: {0}")]
9 Yaml(#[from] serde_yaml::Error),
10
11 #[error("invalid skill frontmatter in {path}: {message}")]
12 InvalidFrontmatter { path: PathBuf, message: String },
13
14 #[error("missing required field `{field}` in {path}")]
15 MissingField { path: PathBuf, field: &'static str },
16
17 #[error("invalid skills root, expected directory: {0}")]
18 InvalidSkillsRoot(PathBuf),
19
20 #[error("skill validation error: {0}")]
21 Validation(String),
22
23 #[error("index error: {0}")]
24 IndexError(String),
25}
26
27pub type SkillResult<T> = Result<T, SkillError>;
28
29impl From<SkillError> for adk_core::AdkError {
30 fn from(err: SkillError) -> Self {
31 use adk_core::{ErrorCategory, ErrorComponent};
32 let (category, code) = match &err {
33 SkillError::Io(_) => (ErrorCategory::Internal, "skill.io"),
34 SkillError::Yaml(_) => (ErrorCategory::InvalidInput, "skill.yaml_parse"),
35 SkillError::InvalidFrontmatter { .. } => {
36 (ErrorCategory::InvalidInput, "skill.invalid_frontmatter")
37 }
38 SkillError::MissingField { .. } => (ErrorCategory::InvalidInput, "skill.missing_field"),
39 SkillError::InvalidSkillsRoot(_) => {
40 (ErrorCategory::NotFound, "skill.invalid_skills_root")
41 }
42 SkillError::Validation(_) => (ErrorCategory::InvalidInput, "skill.validation"),
43 SkillError::IndexError(_) => (ErrorCategory::Internal, "skill.index"),
44 };
45 adk_core::AdkError::new(ErrorComponent::Tool, category, code, err.to_string())
46 .with_source(err)
47 }
48}