use super::memory::ConcurrencyLimiter;
use super::runtime::{AgentConfig, AgentRuntime};
use crate::provider::LlmProvider;
use anyhow::Result;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
pub struct AgentManager {
agents: Arc<RwLock<HashMap<Arc<str>, Arc<AgentRuntime>>>>,
limiter: ConcurrencyLimiter,
provider: Option<Arc<dyn LlmProvider>>,
}
impl AgentManager {
pub fn new(max_concurrent: u32) -> Self {
Self {
agents: Arc::new(RwLock::new(HashMap::new())),
limiter: ConcurrencyLimiter::new(max_concurrent),
provider: None,
}
}
pub fn set_provider(&mut self, provider: Arc<dyn LlmProvider>) {
self.provider = Some(provider);
}
pub fn provider(&self) -> Option<Arc<dyn LlmProvider>> {
self.provider.clone()
}
pub async fn create(&self, config: AgentConfig) -> Result<Arc<str>> {
if !self.limiter.try_acquire() {
anyhow::bail!(
"Cannot create agent: concurrency limit reached ({}/{})",
self.limiter.current(),
self.limiter.max()
);
}
let name = config.name.clone();
let agent = Arc::new(AgentRuntime::new(config));
{
let mut agents = self.agents.write().await;
agents.insert(name.clone(), agent);
}
tracing::info!("Agent '{}' created", name);
Ok(name)
}
pub async fn get(&self, name: &str) -> Option<Arc<AgentRuntime>> {
let agents = self.agents.read().await;
agents.get(name).cloned()
}
pub async fn list(&self) -> Vec<Arc<AgentRuntime>> {
let agents = self.agents.read().await;
agents.values().cloned().collect()
}
pub async fn destroy(&self, name: &str) -> Result<bool> {
let mut agents = self.agents.write().await;
if agents.remove(name).is_some() {
self.limiter.release();
tracing::info!("Agent '{}' destroyed", name);
Ok(true)
} else {
Ok(false)
}
}
pub async fn chat(&self, agent_name: &str, message: &str) -> Result<String> {
let agent = self.get(agent_name).await
.ok_or_else(|| anyhow::anyhow!("Agent '{}' not found", agent_name))?;
let provider = self.provider.clone()
.ok_or_else(|| anyhow::anyhow!("No LLM provider configured"))?;
agent.chat(message, provider).await
}
pub async fn count(&self) -> usize {
let agents = self.agents.read().await;
agents.len()
}
pub fn is_at_capacity(&self) -> bool {
self.limiter.is_at_capacity()
}
pub fn current_concurrency(&self) -> u64 {
self.limiter.current()
}
pub fn max_concurrency(&self) -> u64 {
self.limiter.max()
}
}
impl Default for AgentManager {
fn default() -> Self {
Self::new(3)
}
}