use super::{AgentConfig, MemoryConfig};
use crate::core::error::{Error, Result};
use serde::{Deserialize, Serialize};
use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MeshConfig {
pub name: String,
#[serde(default)]
pub memory: Option<MemoryConfig>,
#[serde(default)]
pub agents: Vec<AgentConfig>,
}
impl Default for MeshConfig {
fn default() -> Self {
Self {
name: "mesh".to_string(),
memory: None,
agents: Vec::new(),
}
}
}
impl MeshConfig {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
memory: None,
agents: Vec::new(),
}
}
pub fn from_toml(toml_str: &str) -> Result<Self> {
toml::from_str(toml_str)
.map_err(|e| Error::ConfigError(format!("Failed to parse TOML: {}", e)))
}
pub fn from_file(path: impl AsRef<Path>) -> Result<Self> {
let content = std::fs::read_to_string(path.as_ref()).map_err(|e| {
Error::ConfigError(format!(
"Failed to read file '{}': {}",
path.as_ref().display(),
e
))
})?;
Self::from_toml(&content)
}
pub fn add_agent(mut self, agent: AgentConfig) -> Self {
self.agents.push(agent);
self
}
pub fn get_agent(&self, name: &str) -> Option<&AgentConfig> {
self.agents.iter().find(|a| a.name == name)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_mesh_config() {
let toml = r#"
name = "test_mesh"
[[agents]]
name = "agent1"
model = "ollama::llama2"
system_prompt = "First agent"
[[agents]]
name = "agent2"
model = "openai::gpt-4"
temperature = 0.8
"#;
let config = MeshConfig::from_toml(toml).unwrap();
assert_eq!(config.name, "test_mesh");
assert_eq!(config.agents.len(), 2);
assert_eq!(config.agents[0].name, "agent1");
assert_eq!(config.agents[1].name, "agent2");
assert_eq!(config.agents[1].temperature, Some(0.8));
}
#[test]
fn test_get_agent() {
let config = MeshConfig::new("test")
.add_agent(AgentConfig::new("agent1", "ollama::llama2"))
.add_agent(AgentConfig::new("agent2", "ollama::llama2"));
assert!(config.get_agent("agent1").is_some());
assert!(config.get_agent("agent2").is_some());
assert!(config.get_agent("nonexistent").is_none());
}
#[test]
fn test_empty_agents() {
let toml = r#"
name = "empty_mesh"
"#;
let config = MeshConfig::from_toml(toml).unwrap();
assert_eq!(config.name, "empty_mesh");
assert!(config.agents.is_empty());
}
}