pub mod permission;
use crate::error::Result;
use futures::future::BoxFuture;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolResult {
pub success: bool,
pub output: String,
pub error: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub bytes: Option<Vec<u8>>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub data: Option<serde_json::Value>,
}
impl ToolResult {
pub fn success(output: impl Into<String>) -> Self {
Self {
success: true,
output: output.into(),
error: None,
bytes: None,
data: None,
}
}
pub fn success_json(data: serde_json::Value) -> Self {
let output = serde_json::to_string(&data).unwrap_or_default();
Self {
success: true,
output,
error: None,
bytes: None,
data: Some(data),
}
}
pub fn error(error: impl Into<String>) -> Self {
Self {
success: false,
output: String::new(),
error: Some(error.into()),
bytes: None,
data: None,
}
}
pub fn binary(bytes: Vec<u8>) -> Self {
Self {
success: true,
output: String::new(),
error: None,
bytes: Some(bytes),
data: None,
}
}
pub fn with_bytes(mut self, bytes: Vec<u8>) -> Self {
self.bytes = Some(bytes);
self
}
pub fn with_output(mut self, output: impl Into<String>) -> Self {
self.output = output.into();
self
}
pub fn with_error(mut self, error: impl Into<String>) -> Self {
self.success = false;
self.error = Some(error.into());
self
}
pub fn with_data(mut self, data: serde_json::Value) -> Self {
self.data = Some(data);
self
}
}
#[derive(Debug, Clone)]
pub struct ToolExecutionConfig {
pub timeout_ms: u64,
pub retry_on_fail: bool,
pub max_retries: u32,
pub retry_delay_ms: u64,
pub max_concurrency: Option<usize>,
}
impl Default for ToolExecutionConfig {
fn default() -> Self {
Self {
timeout_ms: 30_000,
retry_on_fail: false,
max_retries: 2,
retry_delay_ms: 200,
max_concurrency: None,
}
}
}
pub type ToolParameters = HashMap<String, serde_json::Value>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
pub enum ToolRiskLevel {
ReadOnly,
#[default]
Standard,
Dangerous,
}
pub trait Tool: Send + Sync {
fn name(&self) -> &str;
fn description(&self) -> &str;
fn parameters(&self) -> serde_json::Value;
fn execute(&self, parameters: ToolParameters) -> BoxFuture<'_, Result<ToolResult>>;
fn validate_parameters(&self, _params: &ToolParameters) -> BoxFuture<'_, Result<()>> {
Box::pin(async { Ok(()) })
}
fn permissions(&self) -> Vec<permission::ToolPermission> {
vec![]
}
fn risk_level(&self) -> ToolRiskLevel {
ToolRiskLevel::Standard
}
}