- Removed internal history management from AgentLoop. - Updated process method to accept conversation history as a parameter. - Adjusted continue_with_tool_results to work with external history. - Added OutboundDispatcher for handling outbound messages from MessageBus. - Introduced InboundMessage and OutboundMessage structs for message handling. - Updated Channel trait to include message handling and publishing to MessageBus. - Refactored Session to manage chat histories instead of AgentLoop instances. - Enhanced GatewayState to start message processing loops for inbound and outbound messages.
88 lines
3.1 KiB
Rust
88 lines
3.1 KiB
Rust
use std::collections::HashMap;
|
|
use std::sync::Arc;
|
|
use tokio::sync::RwLock;
|
|
|
|
use crate::bus::{MessageBus, OutboundMessage};
|
|
use crate::channels::base::{Channel, ChannelError};
|
|
use crate::channels::feishu::FeishuChannel;
|
|
use crate::config::Config;
|
|
|
|
/// ChannelManager manages all Channel instances and the MessageBus
|
|
#[derive(Clone)]
|
|
pub struct ChannelManager {
|
|
channels: Arc<RwLock<HashMap<String, Arc<dyn Channel + Send + Sync>>>>,
|
|
bus: Arc<MessageBus>,
|
|
}
|
|
|
|
impl ChannelManager {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
channels: Arc::new(RwLock::new(HashMap::new())),
|
|
bus: MessageBus::new(100),
|
|
}
|
|
}
|
|
|
|
/// Get a reference to the MessageBus
|
|
pub fn bus(&self) -> Arc<MessageBus> {
|
|
self.bus.clone()
|
|
}
|
|
|
|
/// Initialize all Channel instances from config
|
|
pub async fn init(&self, config: &Config, _provider_config: crate::config::LLMProviderConfig) -> Result<(), ChannelError> {
|
|
// Initialize Feishu channel if enabled
|
|
if let Some(feishu_config) = config.channels.get("feishu") {
|
|
if feishu_config.enabled {
|
|
let channel = FeishuChannel::new(feishu_config.clone(), _provider_config)
|
|
.map_err(|e| ChannelError::Other(format!("Failed to create Feishu channel: {}", e)))?;
|
|
|
|
self.channels
|
|
.write()
|
|
.await
|
|
.insert("feishu".to_string(), Arc::new(channel));
|
|
tracing::info!("Feishu channel registered");
|
|
} else {
|
|
tracing::info!("Feishu channel disabled in config");
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn start_all(&self) -> Result<(), ChannelError> {
|
|
let channels = self.channels.read().await;
|
|
let bus = self.bus.clone();
|
|
for (name, channel) in channels.iter() {
|
|
tracing::info!(channel = %name, "Starting channel");
|
|
if let Err(e) = channel.start(bus.clone()).await {
|
|
tracing::error!(channel = %name, error = %e, "Failed to start channel");
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn stop_all(&self) -> Result<(), ChannelError> {
|
|
let mut channels = self.channels.write().await;
|
|
for (name, channel) in channels.iter() {
|
|
tracing::info!(channel = %name, "Stopping channel");
|
|
if let Err(e) = channel.stop().await {
|
|
tracing::error!(channel = %name, error = %e, "Error stopping channel");
|
|
}
|
|
}
|
|
channels.clear();
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn get_channel(&self, name: &str) -> Option<Arc<dyn Channel + Send + Sync>> {
|
|
self.channels.read().await.get(name).cloned()
|
|
}
|
|
|
|
/// Dispatch an outbound message to the appropriate channel
|
|
pub async fn dispatch(&self, msg: OutboundMessage) -> Result<(), ChannelError> {
|
|
let channel_name = &msg.channel;
|
|
if let Some(channel) = self.get_channel(channel_name).await {
|
|
channel.send(msg).await
|
|
} else {
|
|
Err(ChannelError::Other(format!("Channel not found: {}", channel_name)))
|
|
}
|
|
}
|
|
}
|