Skip to main content

kowalski_cli/
config.rs

1use crate::error::KowalskiCliError;
2use kowalski_core::config::McpConfig;
3use serde::{Deserialize, Serialize};
4use std::fs;
5use std::path::Path;
6
7/// Load only the `[mcp]` section from a TOML file. Other top-level tables (e.g. `[ollama]`) are ignored.
8#[derive(Debug, Deserialize)]
9struct McpSection {
10    #[serde(default)]
11    mcp: McpConfig,
12}
13
14/// Read `[mcp]` from `path` (e.g. workspace `config.toml`). Missing `[mcp]` yields empty `servers`.
15pub fn load_mcp_config_from_file(path: &Path) -> Result<McpConfig, KowalskiCliError> {
16    let content = fs::read_to_string(path).map_err(|e| {
17        KowalskiCliError::Config(format!("Failed to read {}: {}", path.display(), e))
18    })?;
19    let section: McpSection = toml::from_str(&content).map_err(|e| {
20        KowalskiCliError::Config(format!("Failed to parse TOML {}: {}", path.display(), e))
21    })?;
22    Ok(section.mcp)
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct AgentConfig {
27    pub name: String,
28    pub agent_type: String, // web, academic, code, data
29    pub system_prompt: Option<String>,
30    pub temperature: Option<f32>,
31    pub model: Option<String>,
32    pub tools: Option<Vec<String>>,
33    pub llm: Option<LLMConfig>,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct LLMConfig {
38    pub provider: String,
39    pub model: String,
40    pub api_key: Option<String>,
41}
42
43impl AgentConfig {
44    pub fn load_from_file(path: &Path) -> Result<Self, KowalskiCliError> {
45        let content = fs::read_to_string(path)
46            .map_err(|e| KowalskiCliError::Config(format!("Failed to read config file: {}", e)))?;
47
48        let config: AgentConfig = toml::from_str(&content)
49            .map_err(|e| KowalskiCliError::Config(format!("Failed to parse TOML config: {}", e)))?;
50
51        Ok(config)
52    }
53}