rsclaw 0.0.1-alpha.1

rsclaw: High-performance AI agent (BETA). Optimized for M4 Max and 2GB VPS. 100% compatible with openclaw
Documentation
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::Arc;

/// Unified runtime configuration used by all modules.
/// Supports both OpenClaw JSON5 and Rsclaw TOML formats.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RuntimeConfig {
    pub meta: MetaConfig,
    pub gateway: GatewayConfig,
    pub agents: AgentsConfig,
    pub models: ModelsConfig,
    pub auth: AuthConfig,
    pub channels: ChannelsConfig,
    pub session: SessionConfig,
    pub bindings: Vec<BindingRule>,
    pub cron: CronConfig,
    pub tools: ToolsConfig,
    pub sandbox: SandboxConfig,
    pub skills: SkillsConfig,
    pub plugins: PluginsConfig,
    pub hooks: HooksConfig,
    pub memory: MemoryConfig,
}

impl Default for RuntimeConfig {
    fn default() -> Self {
        Self {
            meta: MetaConfig::default(),
            gateway: GatewayConfig::default(),
            agents: AgentsConfig::default(),
            models: ModelsConfig::default(),
            auth: AuthConfig::default(),
            channels: ChannelsConfig::default(),
            session: SessionConfig::default(),
            bindings: Vec::new(),
            cron: CronConfig::default(),
            tools: ToolsConfig::default(),
            sandbox: SandboxConfig::default(),
            skills: SkillsConfig::default(),
            plugins: PluginsConfig::default(),
            hooks: HooksConfig::default(),
            memory: MemoryConfig::default(),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetaConfig {
    pub name: Arc<str>,
    pub version: Arc<str>,
    pub description: Arc<str>,
}

impl Default for MetaConfig {
    fn default() -> Self {
        Self {
            name: Arc::from("rsclaw"),
            version: Arc::from(env!("CARGO_PKG_VERSION")),
            description: Arc::from("Rust multi-agent collaboration framework"),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GatewayConfig {
    pub host: Arc<str>,
    pub port: u16,
}

impl Default for GatewayConfig {
    fn default() -> Self {
        Self {
            host: Arc::from("127.0.0.1"),
            port: 8080,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentsConfig {
    pub list: Vec<AgentEntry>,
}

impl Default for AgentsConfig {
    fn default() -> Self {
        Self {
            list: vec![AgentEntry {
                name: Arc::from("default"),
                model: Some(Arc::from("gpt-4")),
                system_prompt: Some(Arc::from("You are a helpful assistant.")),
                tools: None,
                channels: None,
                default: true,
                max_tokens: Some(4096),
                memory_limit_mb: Some(512),
            }],
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentEntry {
    pub name: Arc<str>,
    pub model: Option<Arc<str>>,
    pub system_prompt: Option<Arc<str>>,
    pub tools: Option<Vec<Arc<str>>>,
    pub channels: Option<Vec<Arc<str>>>,
    #[serde(default)]
    pub default: bool,
    pub max_tokens: Option<u32>,
    pub memory_limit_mb: Option<u32>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelsConfig {
    pub providers: Vec<ProviderConfig>,
    pub primary_model: Option<Arc<str>>,
}

impl Default for ModelsConfig {
    fn default() -> Self {
        Self {
            providers: Vec::new(),
            primary_model: None,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProviderConfig {
    pub name: Arc<str>,
    pub provider_type: Arc<str>,
    pub api_key: Option<Arc<str>>,
    pub base_url: Option<Arc<str>>,
    pub models: Vec<ModelEntry>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelEntry {
    pub name: Arc<str>,
    pub max_tokens: Option<u32>,
    pub supports_functions: Option<bool>,
    pub supports_vision: Option<bool>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfig {
    pub api_keys: HashMap<Arc<str>, Arc<str>>,
}

impl Default for AuthConfig {
    fn default() -> Self {
        Self {
            api_keys: HashMap::new(),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChannelsConfig {
    pub telegram: Option<ChannelConfig>,
    pub discord: Option<ChannelConfig>,
    pub slack: Option<ChannelConfig>,
    pub whatsapp: Option<ChannelConfig>,
}

impl Default for ChannelsConfig {
    fn default() -> Self {
        Self {
            telegram: None,
            discord: None,
            slack: None,
            whatsapp: None,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChannelConfig {
    pub enabled: bool,
    pub token: Option<Arc<str>>,
    pub webhook_url: Option<Arc<str>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionConfig {
    pub timeout_minutes: u32,
    pub max_history: u32,
}

impl Default for SessionConfig {
    fn default() -> Self {
        Self {
            timeout_minutes: 30,
            max_history: 100,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BindingRule {
    pub channel: Option<Arc<str>>,
    pub agent: Arc<str>,
    pub peer_id: Option<Arc<str>>,
    pub group_id: Option<Arc<str>>,
    pub path: Option<Arc<str>>,
    pub priority: i32,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CronConfig {
    pub enabled: bool,
}

impl Default for CronConfig {
    fn default() -> Self {
        Self { enabled: false }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolsConfig {
    pub enabled: Vec<Arc<str>>,
    pub web_search: Option<WebSearchConfig>,
}

impl Default for ToolsConfig {
    fn default() -> Self {
        Self {
            enabled: Vec::new(),
            web_search: None,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WebSearchConfig {
    pub engine: Arc<str>,
    pub api_key: Option<Arc<str>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SandboxConfig {
    pub enabled: bool,
    pub timeout_seconds: u32,
}

impl Default for SandboxConfig {
    fn default() -> Self {
        Self {
            enabled: false,
            timeout_seconds: 30,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SkillsConfig {
    pub paths: Vec<PathBuf>,
}

impl Default for SkillsConfig {
    fn default() -> Self {
        Self { paths: Vec::new() }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginsConfig {
    pub paths: Vec<PathBuf>,
}

impl Default for PluginsConfig {
    fn default() -> Self {
        Self { paths: Vec::new() }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HooksConfig {
    pub enabled: bool,
}

impl Default for HooksConfig {
    fn default() -> Self {
        Self { enabled: false }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryConfig {
    pub max_agent_memory_mb: u32,
    pub conversation_cache_size: u32,
    pub token_threshold: u32,
    pub max_concurrent_agents: u32,
}

impl Default for MemoryConfig {
    fn default() -> Self {
        Self {
            max_agent_memory_mb: 512,
            conversation_cache_size: 100,
            token_threshold: 1500,
            max_concurrent_agents: 3,
        }
    }
}