use af_llm::{FinishReason, LlmError};
#[derive(Debug, thiserror::Error)]
pub enum RuntimeError {
#[error("invalid input: {0}")]
InvalidInput(String),
#[error("session already has an active run")]
SessionBusy,
#[error("session invariant failed: {0}")]
Invariant(String),
#[error("model failed: {0}")]
Model(String),
#[error("run cancelled")]
Cancelled,
#[error("model attempt interrupted by steering input")]
Steered,
#[error("model returned no choice")]
EmptyModelResponse,
#[error("model stopped with finish reason: {0}")]
FinishReason(FinishReason),
#[error("invalid arguments for tool {0}: {1}")]
InvalidToolArguments(String, String),
#[error("tool {0} denied: {1}")]
ToolDenied(String, String),
#[error("plugin hook failed: {0}")]
Hook(String),
#[error("extension deadline exceeded: {0}")]
ExtensionDeadline(String),
#[error("context contribution failed: {0}")]
Context(String),
#[error("conversation changed while compaction was running")]
CompactionConflict,
#[error("event append failed: {0}")]
Event(String),
}
impl RuntimeError {
pub fn code(&self) -> &'static str {
match self {
Self::InvalidInput(_) => "invalid_input",
Self::SessionBusy => "session_busy",
Self::CompactionConflict => "compaction_conflict",
Self::Cancelled => "cancelled",
Self::Steered => "steered",
Self::ToolDenied(_, _) => "tool_denied",
_ => "agent_run_failed",
}
}
}
impl From<LlmError> for RuntimeError {
fn from(error: LlmError) -> Self {
Self::Model(error.to_string())
}
}