Skip to main content

crabtalk_daemon/config/
mod.rs

1//! Daemon configuration loaded from TOML.
2
3pub use ::model::{ProviderDef, ProviderRegistry, validate_providers};
4use anyhow::Result;
5pub use loader::{DEFAULT_CONFIG, scaffold_config_dir};
6pub use runtime::{McpHandler, SystemConfig, mcp::McpServerConfig};
7use serde::{Deserialize, Serialize};
8use std::collections::BTreeMap;
9#[cfg(unix)]
10pub use wcore::paths::SOCKET_PATH;
11pub use wcore::{
12    AgentConfig, ManifestConfig, ResolvedManifest, load_agents_dir, load_agents_dirs,
13    paths::{AGENTS_DIR, CONFIG_DIR, CONFIG_FILE, SKILLS_DIR},
14    resolve_manifests,
15};
16
17mod loader;
18
19/// Top-level daemon configuration (`config.toml`).
20///
21/// System-only: providers, system settings, and env vars for MCP processes.
22/// MCPs and agent configs live in manifests (`local/CrabTalk.toml` and
23/// `packages/*/*.toml`), loaded via [`resolve_manifests`].
24#[derive(Debug, Clone, Serialize, Deserialize, Default)]
25pub struct DaemonConfig {
26    /// Provider definitions (`[provider.<name>]`).
27    #[serde(default)]
28    pub provider: BTreeMap<String, ProviderDef>,
29    /// **Deprecated**: MCP configs migrated to `local/CrabTalk.toml`.
30    /// Kept for backwards compatibility during migration.
31    #[serde(default)]
32    pub mcps: BTreeMap<String, McpServerConfig>,
33    /// System configuration (tasks + memory).
34    #[serde(default)]
35    pub system: SystemConfig,
36    /// **Deprecated**: Agent configs migrated to `local/CrabTalk.toml`.
37    /// Kept for backwards compatibility during migration.
38    #[serde(default)]
39    pub agents: BTreeMap<String, AgentConfig>,
40    /// Environment variables passed to all MCP server processes at spawn time.
41    #[serde(default)]
42    pub env: BTreeMap<String, String>,
43}
44
45impl DaemonConfig {
46    /// Parse a TOML string into a `DaemonConfig`.
47    pub fn from_toml(toml_str: &str) -> Result<Self> {
48        let mut config: Self = toml::from_str(toml_str)?;
49        config.mcps.iter_mut().for_each(|(name, server)| {
50            if server.name.is_empty() {
51                server.name = name.clone();
52            }
53        });
54        if !config.mcps.is_empty() {
55            tracing::warn!("[mcps] in config.toml is deprecated — move to local/CrabTalk.toml");
56        }
57        if !config.agents.is_empty() {
58            tracing::warn!("[agents] in config.toml is deprecated — move to local/CrabTalk.toml");
59        }
60        validate_providers(&config.provider)?;
61        Ok(config)
62    }
63
64    /// Load configuration from a file path.
65    pub fn load(path: &std::path::Path) -> Result<Self> {
66        let content = std::fs::read_to_string(path)?;
67        Self::from_toml(&content)
68    }
69}