1use thiserror::Error;
2
3#[derive(Debug, Error)]
4#[non_exhaustive]
5pub enum HarnessError {
6 #[error("model error: {0}")]
7 Model(#[from] ModelError),
8 #[error("tool error: {0}")]
9 Tool(#[from] ToolError),
10 #[error("guide error: {0}")]
11 Guide(#[from] GuideError),
12 #[error("sensor error: {0}")]
13 Sensor(#[from] SensorError),
14 #[error("compaction error: {0}")]
15 Compact(#[from] CompactError),
16 #[error("skill error: {0}")]
17 Skill(#[from] SkillError),
18 #[error("budget exhausted after {iters} iterations")]
19 BudgetExhausted { iters: u32 },
20 #[error("policy violation: {0}")]
21 Policy(String),
22 #[error("{0}")]
23 Other(String),
24}
25
26#[derive(Debug, Error)]
27pub enum ModelError {
28 #[error("transport: {0}")]
29 Transport(String),
30 #[error("invalid response: {0}")]
31 Invalid(String),
32 #[error("rate limited (retry after {retry_after_ms}ms)")]
33 RateLimited { retry_after_ms: u64 },
34 #[error("context overflow: needed {needed} tokens, window is {window}")]
35 ContextOverflow { needed: u32, window: u32 },
36}
37
38#[derive(Debug, Error)]
39pub enum ToolError {
40 #[error("tool `{name}` not found{hint}")]
45 NotFound { name: String, hint: String },
46 #[error("invalid args for `{name}`: {reason}")]
47 InvalidArgs { name: String, reason: String },
48 #[error("execution failed: {0}")]
49 Exec(String),
50 #[error("permission denied: {0}")]
51 Permission(String),
52}
53
54#[derive(Debug, Error)]
55pub enum GuideError {
56 #[error("guide `{id}` failed: {reason}")]
57 Failed { id: String, reason: String },
58}
59
60#[derive(Debug, Error)]
61pub enum SensorError {
62 #[error("sensor `{id}` failed: {reason}")]
63 Failed { id: String, reason: String },
64}
65
66#[derive(Debug, Error)]
67pub enum CompactError {
68 #[error("compaction stage {stage:?} failed: {reason}")]
69 Failed { stage: String, reason: String },
70}
71
72#[derive(Debug, Error)]
73pub enum SkillError {
74 #[error("io error: {0}")]
75 Io(String),
76 #[error("invalid SKILL.md at {path}: {reason}")]
77 Invalid { path: String, reason: String },
78 #[error("name regex violation: `{name}` — {reason}")]
79 NameRegex { name: String, reason: String },
80 #[error("description too long: {len} > 1024")]
81 DescriptionTooLong { len: usize },
82 #[error("compatibility too long: {len} > 500")]
83 CompatibilityTooLong { len: usize },
84 #[error("name `{name}` does not match parent directory `{dir}`")]
85 NameDirMismatch { name: String, dir: String },
86 #[error("missing required field `{field}`")]
87 MissingField { field: String },
88 #[error("skill `{name}` already registered")]
89 Duplicate { name: String },
90}
91
92pub type Result<T, E = HarnessError> = std::result::Result<T, E>;