use std::sync::Arc;
use anyhow::{Context, Result};
use crate::llm::LlmProvider;
use crate::tools::ToolRegistry;
use super::{SubagentConfig, SubagentTool};
pub struct SubagentFactory<P>
where
P: LlmProvider + 'static,
{
provider: Arc<P>,
read_only_registry: Option<Arc<ToolRegistry<()>>>,
full_registry: Option<Arc<ToolRegistry<()>>>,
}
impl<P> SubagentFactory<P>
where
P: LlmProvider + 'static,
{
#[must_use]
pub const fn new(provider: Arc<P>) -> Self {
Self {
provider,
read_only_registry: None,
full_registry: None,
}
}
#[must_use]
pub fn with_read_only_registry(mut self, registry: ToolRegistry<()>) -> Self {
self.read_only_registry = Some(Arc::new(registry));
self
}
#[must_use]
pub fn with_full_registry(mut self, registry: ToolRegistry<()>) -> Self {
self.full_registry = Some(Arc::new(registry));
self
}
pub fn create_read_only(&self, config: SubagentConfig) -> Result<SubagentTool<P>> {
let registry = self
.read_only_registry
.as_ref()
.context("read-only registry not set; call with_read_only_registry first")?;
Ok(SubagentTool::new(
config,
Arc::clone(&self.provider),
Arc::clone(registry),
))
}
pub fn create_full_access(&self, config: SubagentConfig) -> Result<SubagentTool<P>> {
let registry = self
.full_registry
.as_ref()
.context("full registry not set; call with_full_registry first")?;
Ok(SubagentTool::new(
config,
Arc::clone(&self.provider),
Arc::clone(registry),
))
}
#[must_use]
pub fn create_with_registry(
&self,
config: SubagentConfig,
registry: Arc<ToolRegistry<()>>,
) -> SubagentTool<P> {
SubagentTool::new(config, Arc::clone(&self.provider), registry)
}
#[must_use]
pub fn provider(&self) -> Arc<P> {
Arc::clone(&self.provider)
}
}
impl<P> Clone for SubagentFactory<P>
where
P: LlmProvider + 'static,
{
fn clone(&self) -> Self {
Self {
provider: Arc::clone(&self.provider),
read_only_registry: self.read_only_registry.clone(),
full_registry: self.full_registry.clone(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_subagent_config_builder() {
let config = SubagentConfig::new("test")
.with_system_prompt("You are a test agent")
.with_max_turns(5)
.with_timeout_ms(30000);
assert_eq!(config.name, "test");
assert_eq!(config.system_prompt, "You are a test agent");
assert_eq!(config.max_turns, Some(5));
assert_eq!(config.timeout_ms, Some(30000));
}
}