use crate::brain::agent::AgentService;
use crate::brain::provider::Provider;
use crate::brain::tools::ToolRegistry;
use crate::config::{Config, VoiceConfig};
use crate::services::ServiceContext;
use std::path::PathBuf;
use std::sync::{Arc, OnceLock};
use tokio::sync::Mutex;
use uuid::Uuid;
pub struct ChannelFactory {
provider: Arc<dyn Provider>,
service_context: ServiceContext,
shared_brain: String,
tool_registry: OnceLock<Arc<ToolRegistry>>,
working_directory: PathBuf,
brain_path: PathBuf,
shared_session_id: Arc<Mutex<Option<Uuid>>>,
config_rx: tokio::sync::watch::Receiver<Config>,
session_updated_tx:
OnceLock<tokio::sync::mpsc::UnboundedSender<crate::brain::agent::ChannelSessionEvent>>,
}
impl ChannelFactory {
#[allow(clippy::too_many_arguments)]
pub fn new(
provider: Arc<dyn Provider>,
service_context: ServiceContext,
shared_brain: String,
working_directory: PathBuf,
brain_path: PathBuf,
shared_session_id: Arc<Mutex<Option<Uuid>>>,
config_rx: tokio::sync::watch::Receiver<Config>,
) -> Self {
Self {
provider,
service_context,
shared_brain,
tool_registry: OnceLock::new(),
working_directory,
brain_path,
shared_session_id,
config_rx,
session_updated_tx: OnceLock::new(),
}
}
pub fn set_session_updated_tx(
&self,
tx: tokio::sync::mpsc::UnboundedSender<crate::brain::agent::ChannelSessionEvent>,
) {
let _ = self.session_updated_tx.set(tx);
}
pub fn set_tool_registry(&self, registry: Arc<ToolRegistry>) {
let _ = self.tool_registry.set(registry);
}
pub async fn create_agent_service(&self) -> Arc<AgentService> {
let config = self.config_rx.borrow().clone();
let mut builder =
AgentService::new(self.provider.clone(), self.service_context.clone(), &config)
.await
.with_system_brain(self.shared_brain.clone())
.with_working_directory(self.working_directory.clone())
.with_brain_path(self.brain_path.clone());
if let Some(registry) = self.tool_registry.get() {
builder = builder.with_tool_registry(registry.clone());
}
if let Some(tx) = self.session_updated_tx.get() {
builder = builder.with_session_updated_tx(tx.clone());
}
Arc::new(builder)
}
pub fn shared_session_id(&self) -> Arc<Mutex<Option<Uuid>>> {
self.shared_session_id.clone()
}
pub fn service_context(&self) -> ServiceContext {
self.service_context.clone()
}
pub fn config_rx(&self) -> tokio::sync::watch::Receiver<Config> {
self.config_rx.clone()
}
pub fn voice_config(&self) -> VoiceConfig {
self.config_rx.borrow().voice_config()
}
pub fn openai_tts_key(&self) -> Option<String> {
let cfg = self.config_rx.borrow();
cfg.providers
.tts
.as_ref()
.and_then(|t| t.openai.as_ref())
.and_then(|p| p.api_key.clone())
}
}