use std::collections::HashMap;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use serde_json::Value;
#[derive(Debug, Clone)]
pub struct ToolCallOutput {
pub summary: String,
pub full_data: Option<Value>,
}
impl ToolCallOutput {
pub fn summary_only(summary: impl Into<String>) -> Self {
Self { summary: summary.into(), full_data: None }
}
pub fn with_data(summary: impl Into<String>, data: Value) -> Self {
Self { summary: summary.into(), full_data: Some(data) }
}
}
pub type HandlerFuture = Pin<Box<dyn Future<Output = String> + Send>>;
pub type DataHandlerFuture = Pin<Box<dyn Future<Output = ToolCallOutput> + Send>>;
pub type HandlerFn = Arc<dyn Fn(String) -> HandlerFuture + Send + Sync>;
pub type DataHandlerFn = Arc<dyn Fn(String) -> DataHandlerFuture + Send + Sync>;
#[derive(Clone)]
pub enum RegistryHandler {
Simple(HandlerFn),
Data(DataHandlerFn),
}
pub struct FunctionRegistry {
handlers: HashMap<String, RegistryHandler>,
}
impl FunctionRegistry {
pub fn new() -> Self {
Self { handlers: HashMap::new() }
}
pub fn register<F, Fut>(&mut self, name: impl Into<String>, handler: F)
where
F: Fn(String) -> Fut + Send + Sync + 'static,
Fut: Future<Output = String> + Send + 'static,
{
let name = name.into();
log::debug!("FunctionRegistry: registered simple handler for '{}'", name);
self.handlers.insert(
name,
RegistryHandler::Simple(Arc::new(move |args| Box::pin(handler(args)))),
);
}
pub fn register_data<F, Fut>(&mut self, name: impl Into<String>, handler: F)
where
F: Fn(String) -> Fut + Send + Sync + 'static,
Fut: Future<Output = ToolCallOutput> + Send + 'static,
{
let name = name.into();
log::debug!("FunctionRegistry: registered data handler for '{}'", name);
self.handlers.insert(
name,
RegistryHandler::Data(Arc::new(move |args| Box::pin(handler(args)))),
);
}
pub fn get(&self, name: &str) -> Option<&RegistryHandler> {
self.handlers.get(name)
}
pub fn has(&self, name: &str) -> bool {
self.handlers.contains_key(name)
}
pub fn len(&self) -> usize {
self.handlers.len()
}
pub fn is_empty(&self) -> bool {
self.handlers.is_empty()
}
pub fn names(&self) -> impl Iterator<Item = &str> {
self.handlers.keys().map(|s| s.as_str())
}
}
impl Default for FunctionRegistry {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Debug for FunctionRegistry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FunctionRegistry")
.field("handlers", &self.handlers.keys().collect::<Vec<_>>())
.finish()
}
}