Skip to main content

af_agent_runtime/
error.rs

1use af_llm::{FinishReason, LlmError};
2
3/// Failure while running a Turn.
4#[derive(Debug, thiserror::Error)]
5pub enum RuntimeError {
6    /// Invalid input.
7    #[error("invalid input: {0}")]
8    InvalidInput(String),
9    /// Session already has an active run.
10    #[error("session already has an active run")]
11    SessionBusy,
12    /// Session invariant failed.
13    #[error("session invariant failed: {0}")]
14    Invariant(String),
15    /// Model failed.
16    #[error("model failed: {0}")]
17    Model(String),
18    /// Run cancelled.
19    #[error("run cancelled")]
20    Cancelled,
21    /// Model attempt interrupted by steering input.
22    #[error("model attempt interrupted by steering input")]
23    Steered,
24    /// Model returned no choice.
25    #[error("model returned no choice")]
26    EmptyModelResponse,
27    /// Model stopped with finish reason.
28    #[error("model stopped with finish reason: {0}")]
29    FinishReason(FinishReason),
30    /// Invalid arguments for tool.
31    #[error("invalid arguments for tool {0}: {1}")]
32    InvalidToolArguments(String, String),
33    /// Tool denied.
34    #[error("tool {0} denied: {1}")]
35    ToolDenied(String, String),
36    /// An extension hook failed.
37    #[error("plugin hook failed: {0}")]
38    Hook(String),
39    /// Extension deadline exceeded.
40    #[error("extension deadline exceeded: {0}")]
41    ExtensionDeadline(String),
42    /// Context contribution failed.
43    #[error("context contribution failed: {0}")]
44    Context(String),
45    /// Conversation changed while compaction was running.
46    #[error("conversation changed while compaction was running")]
47    CompactionConflict,
48    /// Event append failed.
49    #[error("event append failed: {0}")]
50    Event(String),
51}
52
53impl RuntimeError {
54    /// Stable machine-readable code persisted as `error_code`.
55    pub fn code(&self) -> &'static str {
56        match self {
57            Self::InvalidInput(_) => "invalid_input",
58            Self::SessionBusy => "session_busy",
59            Self::CompactionConflict => "compaction_conflict",
60            Self::Cancelled => "cancelled",
61            Self::Steered => "steered",
62            Self::ToolDenied(_, _) => "tool_denied",
63            _ => "agent_run_failed",
64        }
65    }
66}
67
68impl From<LlmError> for RuntimeError {
69    fn from(error: LlmError) -> Self {
70        Self::Model(error.to_string())
71    }
72}