crabtalk_daemon/config/
mod.rs1pub 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#[derive(Debug, Clone, Serialize, Deserialize, Default)]
25pub struct DaemonConfig {
26 #[serde(default)]
28 pub provider: BTreeMap<String, ProviderDef>,
29 #[serde(default)]
32 pub mcps: BTreeMap<String, McpServerConfig>,
33 #[serde(default)]
35 pub system: SystemConfig,
36 #[serde(default)]
39 pub agents: BTreeMap<String, AgentConfig>,
40 #[serde(default)]
42 pub env: BTreeMap<String, String>,
43}
44
45impl DaemonConfig {
46 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 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}