use std::borrow::Cow;
use thiserror::Error;
use crate::CommandError;
use super::ChatCompletionStream;
#[derive(Error, Debug)]
pub enum ToolError {
#[error("arguments for tool failed to parse: {0:#}")]
WrongArguments(#[from] serde_json::Error),
#[error("arguments missing for tool {0:#}")]
MissingArguments(Cow<'static, str>),
#[error("tool execution failed: {0:#}")]
ExecutionFailed(#[from] CommandError),
#[error(transparent)]
Unknown(#[from] anyhow::Error),
}
impl ToolError {
pub fn wrong_arguments(e: impl Into<serde_json::Error>) -> Self {
ToolError::WrongArguments(e.into())
}
pub fn missing_arguments(tool_name: impl Into<Cow<'static, str>>) -> Self {
ToolError::MissingArguments(tool_name.into())
}
pub fn execution_failed(e: impl Into<CommandError>) -> Self {
ToolError::ExecutionFailed(e.into())
}
pub fn unknown(e: impl Into<anyhow::Error>) -> Self {
ToolError::Unknown(e.into())
}
}
type BoxedError = Box<dyn std::error::Error + Send + Sync>;
#[derive(Error, Debug)]
pub enum LanguageModelError {
#[error("Context length exceeded: {0:#}")]
ContextLengthExceeded(BoxedError),
#[error("Permanent error: {0:#}")]
PermanentError(BoxedError),
#[error("Transient error: {0:#}")]
TransientError(BoxedError),
}
impl LanguageModelError {
pub fn permanent(e: impl Into<BoxedError>) -> Self {
LanguageModelError::PermanentError(e.into())
}
pub fn transient(e: impl Into<BoxedError>) -> Self {
LanguageModelError::TransientError(e.into())
}
pub fn context_length_exceeded(e: impl Into<BoxedError>) -> Self {
LanguageModelError::ContextLengthExceeded(e.into())
}
}
impl From<BoxedError> for LanguageModelError {
fn from(e: BoxedError) -> Self {
LanguageModelError::PermanentError(e)
}
}
impl From<anyhow::Error> for LanguageModelError {
fn from(e: anyhow::Error) -> Self {
LanguageModelError::PermanentError(e.into())
}
}
impl From<LanguageModelError> for ChatCompletionStream {
fn from(val: LanguageModelError) -> Self {
Box::pin(futures_util::stream::once(async move { Err(val) }))
}
}