use crate::AiPermission;
use async_trait::async_trait;
use origin_domain::Result;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolDescriptor {
pub name: String,
pub title: String,
pub description: String,
pub permission: AiPermission,
pub input_schema: serde_json::Value,
}
impl ToolDescriptor {
pub fn new(
name: impl Into<String>,
title: impl Into<String>,
description: impl Into<String>,
permission: AiPermission,
) -> Self {
Self {
name: name.into(),
title: title.into(),
description: description.into(),
permission,
input_schema: serde_json::json!({
"type": "object",
"properties": {},
"additionalProperties": false
}),
}
}
pub fn with_schema(mut self, input_schema: serde_json::Value) -> Self {
self.input_schema = input_schema;
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolOutput {
pub text: String,
pub structured: Option<serde_json::Value>,
}
impl ToolOutput {
pub fn text(text: impl Into<String>) -> Self {
Self {
text: text.into(),
structured: None,
}
}
pub fn with_structured(mut self, structured: serde_json::Value) -> Self {
self.structured = Some(structured);
self
}
}
#[async_trait]
pub trait Tool: Debug + Send + Sync + 'static {
fn descriptor(&self) -> ToolDescriptor;
async fn call(&self, arguments: serde_json::Value) -> Result<ToolOutput>;
}