//! Agent servers configuration structure. //! //! 此模块负责配置的查询和管理。 //! 默认配置从 `default_agent_config` 模块加载(来源于 `configs/default_agents.json`)。 use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::path::Path; use super::default_agent_config::{ default_agent_servers, default_agent_servers_for_service, default_context_servers, default_context_servers_for_service, }; use crate::types::agent_config::AgentConfig; use crate::types::error::{ConfigError, Result}; use crate::types::mcp_config::ContextServerConfig; use crate::types::system_prompt::DEFAULT_SYSTEM_PROMPT; /// Agent servers configuration /// /// 包含所有 Agent 和 Context Server 的配置集合。 /// 默认配置来自 `configs/default_agents.json`(编译时嵌入)。 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AgentServersConfig { /// Agent servers configuration pub agent_servers: HashMap, /// Context servers configuration (MCP servers) #[serde(default)] pub context_servers: HashMap, } impl AgentServersConfig { /// 获取默认配置 /// /// 返回从 `configs/default_agents.json` 加载的配置。 /// /// # 已弃用 /// /// 此方法已弃用,请使用 `load_or_default_for_service` 以支持多服务类型。 #[deprecated( since = "0.2.0", note = "请使用 load_or_default_for_service 以支持多服务类型" )] pub async fn load_or_default() -> Self { Self::default() } /// 根据服务类型加载或使用默认配置 /// /// # 参数 /// - `service_type`: 服务类型(RCoder 或 ComputerAgentRunner) /// /// # 返回 /// 对应服务类型的默认配置 pub async fn load_or_default_for_service(service_type: &shared_types::ServiceType) -> Self { Self::default_for_service(service_type) } /// 根据服务类型创建默认配置 /// /// # 参数 /// - `service_type`: 服务类型 /// /// # 返回 /// 对应服务类型的默认配置实例 pub fn default_for_service(service_type: &shared_types::ServiceType) -> Self { Self { agent_servers: default_agent_servers_for_service(service_type), context_servers: default_context_servers_for_service(service_type), } } /// 从外部文件加载配置 /// /// 用于加载用户自定义的配置文件,覆盖默认配置。 pub async fn from_file>(path: P) -> Result { let path = path.as_ref(); if !path.exists() { return Err(ConfigError::file_not_found(path.display()).into()); } let content = tokio::fs::read_to_string(path) .await .map_err(|e| ConfigError::Read(format!("{}: {}", path.display(), e)))?; Self::from_json(&content) } /// 从 JSON 字符串加载配置 /// /// 用于解析用户传入的 JSON 配置。 pub fn from_json(json: &str) -> Result { serde_json::from_str(json).map_err(|e| ConfigError::Deserialization(e.to_string()).into()) } /// Validate configuration pub fn validate(&self) -> Result<()> { // Validate agent servers for (name, config) in &self.agent_servers { if config.agent_id.is_empty() { return Err( ConfigError::missing_field(format!("agent_servers.{}.agent_id", name)).into(), ); } if config.command.is_empty() { return Err( ConfigError::missing_field(format!("agent_servers.{}.command", name)).into(), ); } } // Validate context servers for (name, config) in &self.context_servers { if config.command.is_none() { return Err(ConfigError::missing_field(format!( "context_servers.{}.command", name )) .into()); } } Ok(()) } /// Get all enabled agents pub fn get_enabled_agents(&self) -> Vec<&AgentConfig> { self.agent_servers .values() .filter(|config| config.enabled) .collect() } /// Get an agent configuration by ID pub fn get_agent(&self, agent_id: &str) -> Option<&AgentConfig> { self.agent_servers.get(agent_id) } /// 获取系统提示词(优先使用配置,否则使用默认值) /// /// # 参数 /// - `agent_id`: Agent 标识符 /// /// # 返回 /// 根据配置的 source 字段决定返回内容: /// - `source: "embedded"` -> 返回编译时嵌入的默认提示词 /// - `source: "custom"` 且 template 非空 -> 返回自定义模板内容 /// - 其他情况 -> 回退到编译时嵌入的默认提示词 /// /// 注意:此方法始终返回有效的系统提示词,不受 enabled 字段影响。 /// 如需检查是否启用,请直接调用 `SystemPromptConfig::get_prompt()`。 pub fn get_system_prompt(&self, agent_id: &str) -> String { if let Some(agent) = self.get_agent(agent_id) { // 如果有系统提示词配置,使用 get_prompt_or_default() 确保始终返回有效提示词 if let Some(ref prompt_config) = agent.system_prompt { return prompt_config.get_prompt_or_default().to_string(); } } // 回退到编译时嵌入的默认值 DEFAULT_SYSTEM_PROMPT.to_string() } /// Get all enabled context servers pub fn get_enabled_context_servers(&self) -> Vec<&ContextServerConfig> { self.context_servers .values() .filter(|config| config.enabled) .collect() } /// Get a context server configuration by name pub fn get_context_server(&self, name: &str) -> Option<&ContextServerConfig> { self.context_servers.get(name) } /// 创建默认配置 /// /// 从 `configs/default_agents.json` 加载的配置(编译时嵌入)。 /// 修改 JSON 文件后重新编译即可生效。 pub fn default() -> Self { Self { agent_servers: default_agent_servers(), context_servers: default_context_servers(), } } } #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn test_load_or_default_for_service() { // 测试 RCoder let rcoder_config = AgentServersConfig::load_or_default_for_service(&shared_types::ServiceType::RCoder) .await; assert!(!rcoder_config.agent_servers.is_empty()); // 测试 ComputerAgentRunner let car_config = AgentServersConfig::load_or_default_for_service( &shared_types::ServiceType::ComputerAgentRunner, ) .await; assert!(!car_config.agent_servers.is_empty()); } #[test] fn test_default_for_service() { // 测试 RCoder let rcoder_config = AgentServersConfig::default_for_service(&shared_types::ServiceType::RCoder); assert!(!rcoder_config.agent_servers.is_empty()); // 测试 ComputerAgentRunner let car_config = AgentServersConfig::default_for_service( &shared_types::ServiceType::ComputerAgentRunner, ); assert!(!car_config.agent_servers.is_empty()); // 验证配置不同 // ComputerAgentRunner 应该有更多或不同的 context servers assert!(car_config.context_servers.len() >= rcoder_config.context_servers.len()); } }