use std::collections::{HashMap, HashSet}; use std::sync::Arc; use crate::agent::AgentError; use crate::config::LLMProviderConfig; use crate::gateway::tool_registry_factory::ToolRegistryFactory; use crate::skills::SkillRuntime; use crate::storage::{ ConversationRepository, MemoryRepository, PromptInjectionRepository, SchedulerJobRepository, SessionStore, SkillEventRepository, }; use crate::tools::{NoopSessionMessageSender, SessionMessageSender, ToolRegistry}; use super::agent_factory::AgentFactory; use super::cli_session::CliSessionService; use super::memory_maintenance_coordinator::MemoryMaintenanceCoordinator; use super::provider_config_service::ProviderConfigService; use super::scheduled_agent_task_service::ScheduledAgentTaskService; use super::session::{SessionManager, SessionManagerServices}; use super::session_factory::SessionFactory; use super::session_lifecycle::SessionLifecycleService; use super::session_message_service::SessionMessageService; pub(crate) fn build_session_manager( agent_prompt_reinject_every: u64, show_tool_results: bool, default_timezone: String, provider_config: LLMProviderConfig, provider_configs: HashMap, skills: Arc, disabled_tools: HashSet, chat_history_ttl_hours: Option, session_ttl_hours: Option, ) -> Result { build_session_manager_with_sender( agent_prompt_reinject_every, show_tool_results, default_timezone, provider_config, provider_configs, skills, Arc::new(NoopSessionMessageSender), disabled_tools, chat_history_ttl_hours, session_ttl_hours, ) } pub(crate) fn build_session_manager_with_sender( agent_prompt_reinject_every: u64, show_tool_results: bool, default_timezone: String, provider_config: LLMProviderConfig, provider_configs: HashMap, skills: Arc, session_message_sender: Arc, disabled_tools: HashSet, chat_history_ttl_hours: Option, session_ttl_hours: Option, ) -> Result { let store = Arc::new( SessionStore::new() .map_err(|err| AgentError::Other(format!("session store init error: {}", err)))?, ); let known_agents = provider_configs.keys().cloned().collect::>(); let provider_configs = ProviderConfigService::new(provider_config.clone(), provider_configs); if let Err(err) = store.append_skill_event(None, "discovered", None, &skills.discovery_event_payload()) { tracing::warn!(error = %err, "Failed to record skill discovery event"); } let memories: Arc = store.clone(); let scheduler_jobs: Arc = store.clone(); let skill_events: Arc = store.clone(); let tools = Arc::new( ToolRegistryFactory::new( skills.clone(), memories, scheduler_jobs, skill_events.clone(), session_message_sender, known_agents, default_timezone, disabled_tools, ) .build(), ); let prompt_repository: Arc = store.clone(); let agent_factory = AgentFactory::new( tools.clone(), skills.clone(), agent_prompt_reinject_every as usize, prompt_repository.clone(), ); let conversations: Arc = store.clone(); let session_factory = SessionFactory::new( provider_config.clone(), skills.clone(), agent_factory, conversations, skill_events, chat_history_ttl_hours, ); let lifecycle = SessionLifecycleService::new(session_factory, session_ttl_hours); let cli_sessions = CliSessionService::new(store.clone()); let messages = SessionMessageService::new(lifecycle.clone(), show_tool_results); let scheduled_tasks = ScheduledAgentTaskService::new( lifecycle.clone(), provider_configs.clone(), show_tool_results, ); let memory_maintenance = MemoryMaintenanceCoordinator::new(store.clone(), provider_configs.clone()); Ok(SessionManager::from_services(SessionManagerServices { tools: tools as Arc, skills, store, show_tool_results, lifecycle, cli_sessions, messages, scheduled_tasks, memory_maintenance, })) }