use anyhow::Result;
use async_trait::async_trait;
use serde_json::Value;
use crate::llm::ToolSchema;
#[derive(Clone, Default, Debug)]
pub struct ToolContext {
pub conversation_id: String,
pub request_id: String,
}
pub struct ToolResult {
pub success: bool,
pub result_for_llm: String,
pub ui: Option<Value>,
}
impl ToolResult {
pub fn ok(result_for_llm: impl Into<String>) -> Self {
Self { success: true, result_for_llm: result_for_llm.into(), ui: None }
}
pub fn error(msg: impl Into<String>) -> Self {
Self { success: false, result_for_llm: msg.into(), ui: None }
}
pub fn with_ui(mut self, ui: Value) -> Self {
self.ui = Some(ui);
self
}
}
#[async_trait]
pub trait Tool: Send + Sync {
fn name(&self) -> &str;
fn description(&self) -> &str;
fn args_schema(&self) -> Value;
fn access_groups(&self) -> Vec<String> {
Vec::new()
}
async fn execute(&self, ctx: &ToolContext, args: Value) -> Result<ToolResult>;
fn schema(&self) -> ToolSchema {
ToolSchema {
name: self.name().to_string(),
description: self.description().to_string(),
parameters: self.args_schema(),
}
}
}