use std::sync::Arc;
use async_trait::async_trait;
use synaptic_core::{
ChatModel, ChatRequest, ChatResponse, ChatStream, SynapticError, ToolDefinition,
};
pub struct BoundToolsChatModel {
inner: Arc<dyn ChatModel>,
tools: Vec<ToolDefinition>,
}
impl BoundToolsChatModel {
pub fn new(inner: Arc<dyn ChatModel>, tools: Vec<ToolDefinition>) -> Self {
Self { inner, tools }
}
fn inject_tools(&self, mut request: ChatRequest) -> ChatRequest {
if request.tools.is_empty() {
request.tools = self.tools.clone();
} else {
for tool in &self.tools {
if !request.tools.iter().any(|t| t.name == tool.name) {
request.tools.push(tool.clone());
}
}
}
request
}
}
#[async_trait]
impl ChatModel for BoundToolsChatModel {
async fn chat(&self, request: ChatRequest) -> Result<ChatResponse, SynapticError> {
self.inner.chat(self.inject_tools(request)).await
}
fn stream_chat(&self, request: ChatRequest) -> ChatStream<'_> {
self.inner.stream_chat(self.inject_tools(request))
}
}