crabtalk_core/config/
daemon.rs1use crate::{ProviderDef, config::system::TasksConfig};
4use anyhow::Result;
5use serde::{Deserialize, Serialize};
6use std::collections::BTreeMap;
7
8#[derive(Debug, Clone, Serialize, Deserialize, Default)]
15pub struct DaemonConfig {
16 #[serde(default)]
18 pub provider: BTreeMap<String, ProviderDef>,
19 #[serde(default)]
21 pub tasks: TasksConfig,
22 #[serde(default)]
24 pub env: BTreeMap<String, String>,
25}
26
27impl DaemonConfig {
28 pub fn from_toml(toml_str: &str) -> Result<Self> {
30 let config: Self = toml::from_str(toml_str)?;
31 validate_providers(&config.provider)?;
32 Ok(config)
33 }
34
35 pub fn load(path: &std::path::Path) -> Result<Self> {
37 let content = std::fs::read_to_string(path)?;
38 Self::from_toml(&content)
39 }
40}
41
42pub fn validate_providers(providers: &BTreeMap<String, ProviderDef>) -> Result<()> {
44 let mut seen = std::collections::HashSet::new();
45 for (name, def) in providers {
46 def.validate(name).map_err(|e| anyhow::anyhow!(e))?;
47 for model in &def.models {
48 if !seen.insert(model.clone()) {
49 anyhow::bail!("duplicate model name '{model}' across providers");
50 }
51 }
52 }
53 Ok(())
54}