109 lines
2.6 KiB
Rust
109 lines
2.6 KiB
Rust
//! Tool call and result types.
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
/// A single tool invocation requested by the AI model.
|
|
#[derive(Debug, Clone)]
|
|
pub struct ToolCall {
|
|
pub id: String,
|
|
pub name: String,
|
|
pub arguments: String,
|
|
}
|
|
|
|
impl ToolCall {
|
|
pub fn arguments_json(&self) -> serde_json::Result<serde_json::Value> {
|
|
serde_json::from_str(&self.arguments)
|
|
}
|
|
|
|
pub fn parse_args<T: serde::de::DeserializeOwned>(&self) -> serde_json::Result<T> {
|
|
serde_json::from_str(&self.arguments)
|
|
}
|
|
}
|
|
|
|
/// The result of executing a tool call.
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(untagged)]
|
|
pub enum ToolResult {
|
|
/// Successful result with a JSON value.
|
|
Ok(serde_json::Value),
|
|
/// Error result with an error message.
|
|
Error(String),
|
|
}
|
|
|
|
impl ToolResult {
|
|
pub fn ok<T: Serialize>(value: T) -> Self {
|
|
Self::Ok(serde_json::to_value(value).unwrap_or(serde_json::Value::Null))
|
|
}
|
|
|
|
pub fn error(message: impl Into<String>) -> Self {
|
|
Self::Error(message.into())
|
|
}
|
|
|
|
pub fn is_error(&self) -> bool {
|
|
matches!(self, Self::Error(_))
|
|
}
|
|
}
|
|
|
|
/// Errors that can occur during tool execution.
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum ToolError {
|
|
#[error("tool not found: {0}")]
|
|
NotFound(String),
|
|
|
|
#[error("argument parse error: {0}")]
|
|
ParseError(String),
|
|
|
|
#[error("execution error: {0}")]
|
|
ExecutionError(String),
|
|
|
|
#[error("recursion limit exceeded (max depth: {max_depth})")]
|
|
RecursionLimitExceeded { max_depth: u32 },
|
|
|
|
#[error("max tool calls exceeded: {0}")]
|
|
MaxToolCallsExceeded(usize),
|
|
|
|
#[error("internal error: {0}")]
|
|
Internal(String),
|
|
}
|
|
|
|
impl ToolError {
|
|
pub fn into_result(self) -> ToolResult {
|
|
ToolResult::Error(self.to_string())
|
|
}
|
|
}
|
|
|
|
impl From<serde_json::Error> for ToolError {
|
|
fn from(e: serde_json::Error) -> Self {
|
|
Self::ParseError(e.to_string())
|
|
}
|
|
}
|
|
|
|
/// A completed tool call with its result, ready to be sent back to the AI.
|
|
#[derive(Debug, Clone)]
|
|
pub struct ToolCallResult {
|
|
/// The original tool call.
|
|
pub call: ToolCall,
|
|
/// The execution result.
|
|
pub result: ToolResult,
|
|
}
|
|
|
|
impl ToolCallResult {
|
|
pub fn ok(call: ToolCall, value: serde_json::Value) -> Self {
|
|
Self {
|
|
call,
|
|
result: ToolResult::Ok(value),
|
|
}
|
|
}
|
|
|
|
pub fn error(call: ToolCall, message: impl Into<String>) -> Self {
|
|
Self {
|
|
call,
|
|
result: ToolResult::Error(message.into()),
|
|
}
|
|
}
|
|
|
|
pub fn from_result(call: ToolCall, result: ToolResult) -> Self {
|
|
Self { call, result }
|
|
}
|
|
}
|