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")]
41 NotFound { name: String },
42 #[error("invalid args for `{name}`: {reason}")]
43 InvalidArgs { name: String, reason: String },
44 #[error("execution failed: {0}")]
45 Exec(String),
46 #[error("permission denied: {0}")]
47 Permission(String),
48}
49
50#[derive(Debug, Error)]
51pub enum GuideError {
52 #[error("guide `{id}` failed: {reason}")]
53 Failed { id: String, reason: String },
54}
55
56#[derive(Debug, Error)]
57pub enum SensorError {
58 #[error("sensor `{id}` failed: {reason}")]
59 Failed { id: String, reason: String },
60}
61
62#[derive(Debug, Error)]
63pub enum CompactError {
64 #[error("compaction stage {stage:?} failed: {reason}")]
65 Failed { stage: String, reason: String },
66}
67
68#[derive(Debug, Error)]
69pub enum SkillError {
70 #[error("io error: {0}")]
71 Io(String),
72 #[error("invalid SKILL.md at {path}: {reason}")]
73 Invalid { path: String, reason: String },
74 #[error("name regex violation: `{name}` — {reason}")]
75 NameRegex { name: String, reason: String },
76 #[error("description too long: {len} > 1024")]
77 DescriptionTooLong { len: usize },
78 #[error("compatibility too long: {len} > 500")]
79 CompatibilityTooLong { len: usize },
80 #[error("name `{name}` does not match parent directory `{dir}`")]
81 NameDirMismatch { name: String, dir: String },
82 #[error("missing required field `{field}`")]
83 MissingField { field: String },
84 #[error("skill `{name}` already registered")]
85 Duplicate { name: String },
86}
87
88pub type Result<T, E = HarnessError> = std::result::Result<T, E>;