mod types;
use std::sync::Arc;
use serde_json::Value;
pub use types::*;
impl ToolSchema {
pub fn new(name: impl Into<String>, description: impl Into<String>, parameters: Value) -> Self {
Self {
name: name.into(),
description: description.into(),
parameters,
}
}
}
impl ToolCall {
pub fn new(id: impl Into<String>, name: impl Into<String>, arguments: Value) -> Self {
Self {
id: id.into(),
name: name.into(),
arguments,
}
}
}
impl ToolResult {
pub fn text(
call_id: impl Into<String>,
name: impl Into<String>,
content: impl Into<String>,
) -> Self {
Self {
call_id: call_id.into(),
name: name.into(),
content: content.into(),
raw: None,
error: None,
elapsed_ms: 0,
}
}
pub fn error(
call_id: impl Into<String>,
name: impl Into<String>,
message: impl Into<String>,
) -> Self {
let message = message.into();
Self {
call_id: call_id.into(),
name: name.into(),
content: message.clone(),
raw: None,
error: Some(message),
elapsed_ms: 0,
}
}
pub fn is_error(&self) -> bool {
self.error.is_some()
}
}
impl<State> ToolRegistry<State> {
pub fn new() -> Self {
Self {
tools: std::collections::HashMap::new(),
}
}
pub fn register(&mut self, tool: Arc<dyn Tool<State>>) -> &mut Self {
self.tools.insert(tool.name().to_owned(), tool);
self
}
pub fn get(&self, name: &str) -> Option<Arc<dyn Tool<State>>> {
self.tools.get(name).cloned()
}
pub fn names(&self) -> Vec<String> {
let mut names: Vec<String> = self.tools.keys().cloned().collect();
names.sort();
names
}
pub fn schemas(&self) -> Vec<ToolSchema> {
let mut schemas: Vec<ToolSchema> = self.tools.values().map(|t| t.schema()).collect();
schemas.sort_by(|a, b| a.name.cmp(&b.name));
schemas
}
}
impl<State> Default for ToolRegistry<State> {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod test;