use std::sync::Arc;
use foundation_db::traits::DocumentStore;
use foundation_nativeapis::shared::vfs::AsyncVfsFileSystem;
use crate::agentic::memory::MemoryHierarchy;
use crate::agentic::memory_store::MemoryStore;
use crate::agentic::tool_impl::{ToolCallManager, ToolImpl};
use crate::agentic::UserId;
use crate::types::routable_provider::ProviderRouter;
use crate::types::{ModelId, SessionId};
pub struct ToolPreset {
tools: Vec<Arc<dyn ToolImpl>>,
}
impl Default for ToolPreset {
fn default() -> Self {
Self { tools: Vec::new() }
}
}
impl ToolPreset {
#[must_use]
pub fn empty() -> Self {
Self::default()
}
#[must_use]
pub fn from_tools(tools: Vec<Arc<dyn ToolImpl>>) -> Self {
Self { tools }
}
pub fn register_all(&self, manager: &ToolCallManager) {
for tool in &self.tools {
manager.register(Arc::clone(tool));
}
}
#[must_use]
pub fn into_manager(self, session_id: SessionId) -> ToolCallManager {
let mgr = ToolCallManager::new(session_id);
self.register_all(&mgr);
mgr
}
#[must_use]
pub fn as_child_tools(&self) -> Vec<Arc<dyn ToolImpl>> {
self.tools.iter().map(Arc::clone).collect()
}
#[must_use]
pub fn len(&self) -> usize {
self.tools.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.tools.is_empty()
}
#[must_use]
pub fn merge(mut self, other: Self) -> Self {
self.tools.extend(other.tools);
self
}
#[must_use]
pub fn tools(&self) -> &[Arc<dyn ToolImpl>] {
&self.tools
}
#[must_use]
pub fn files<F: AsyncVfsFileSystem + 'static>(fs: Arc<F>) -> Self {
use crate::agentic::tools::files::{EditTool, ReadTool, WriteTool};
Self {
tools: vec![
Arc::new(ReadTool::new(Arc::clone(&fs) as Arc<_>)),
Arc::new(WriteTool::new(Arc::clone(&fs) as Arc<_>)),
Arc::new(EditTool::new(fs)),
],
}
}
#[must_use]
pub fn shell() -> Self {
use crate::agentic::tools::files::BashTool;
Self {
tools: vec![Arc::new(BashTool::new())],
}
}
#[must_use]
pub fn memory<M, D>(hierarchy: Arc<MemoryHierarchy<M, D>>) -> Self
where
M: MemoryStore + 'static,
D: DocumentStore + 'static,
{
use crate::agentic::tools::memory::MemoryTool;
Self {
tools: vec![Arc::new(MemoryTool::new(hierarchy))],
}
}
#[must_use]
pub fn shed(discovery: Arc<crate::agentic::tools::shed::ToolDiscovery>) -> Self {
use crate::agentic::tools::shed::ShedTool;
Self {
tools: vec![Arc::new(ShedTool::new(discovery))],
}
}
#[must_use]
pub fn agent<D, M>(
router: ProviderRouter,
depth: u32,
max_depth: u32,
default_model: ModelId,
output_base: &str,
user: UserId,
child_tools: Vec<Arc<dyn ToolImpl>>,
) -> Self
where
D: DocumentStore + Default + 'static,
M: MemoryStore + Default + 'static,
{
use crate::agentic::tools::agent::AgentTool;
Self {
tools: vec![Arc::new(AgentTool::<D, M>::new(
router,
depth,
max_depth,
default_model,
output_base.to_string(),
user,
child_tools,
))],
}
}
#[must_use]
pub fn minimal_sub_agent<F: AsyncVfsFileSystem + 'static>(fs: Arc<F>) -> Self {
Self::files(fs).merge(Self::shell())
}
#[must_use]
pub fn standard<F, M, D>(
fs: Arc<F>,
hierarchy: Arc<MemoryHierarchy<M, D>>,
discovery: Arc<crate::agentic::tools::shed::ToolDiscovery>,
) -> Self
where
F: AsyncVfsFileSystem + 'static,
M: MemoryStore + 'static,
D: DocumentStore + 'static,
{
Self::files(fs)
.merge(Self::shell())
.merge(Self::memory(hierarchy))
.merge(Self::shed(discovery))
}
}
impl std::ops::Add for ToolPreset {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
self.merge(rhs)
}
}