Initial scaffold: GyanDoot v2.0 in Rust
Full Cargo workspace with 11 crates: - gyandoot-core: Shared types, config, error types - gyandoot-agent: Agent loop, tool execution, context compression - gyandoot-providers: LLM provider abstraction (OpenAI, Anthropic, Ollama) - gyandoot-memory: MemPalace persistent memory system - gyandoot-platform: Platform adapters (Telegram, Discord, Webhook, CLI) - gyandoot-security: Credential vault, sanitizer, threat detector - gyandoot-kanban: Task decomposition, swarm orchestration, diagnostics - gyandoot-subagents: Sub-agent spawning and orchestration - gyandoot-skills: Skills discovery, loading, preprocessing, bundles - gyandoot-profile: Multi-agent profile manager - gyandoot-gateway: Gateway sessions, routing, access control Plus: CLI entry point with clap, cross-platform installer script, KANBAN.md, .gnpl/AGENTS.md Workspace compiles clean: cargo check passes with 0 errors.
This commit is contained in:
253
crates/gyandoot-core/src/config.rs
Normal file
253
crates/gyandoot-core/src/config.rs
Normal file
@@ -0,0 +1,253 @@
|
||||
//! Configuration types for GyanDoot agents and platform.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Top-level agent configuration.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AgentConfig {
|
||||
pub name: String,
|
||||
pub model: String,
|
||||
pub max_tokens: usize,
|
||||
pub temperature: f64,
|
||||
pub system_prompt: String,
|
||||
pub provider: ProviderConfig,
|
||||
pub platform: PlatformConfig,
|
||||
pub memory: MemoryConfig,
|
||||
pub security: SecurityConfig,
|
||||
pub kanban: KanbanConfig,
|
||||
pub skills: SkillsConfig,
|
||||
}
|
||||
|
||||
impl Default for AgentConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "gyandoot".to_string(),
|
||||
model: "gpt-4o".to_string(),
|
||||
max_tokens: 4096,
|
||||
temperature: 0.7,
|
||||
system_prompt: String::new(),
|
||||
provider: ProviderConfig::default(),
|
||||
platform: PlatformConfig::default(),
|
||||
memory: MemoryConfig::default(),
|
||||
security: SecurityConfig::default(),
|
||||
kanban: KanbanConfig::default(),
|
||||
skills: SkillsConfig::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// LLM provider configuration.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ProviderConfig {
|
||||
pub default: String,
|
||||
pub openai: Option<OpenAIConfig>,
|
||||
pub anthropic: Option<AnthropicConfig>,
|
||||
pub ollama: Option<OllamaConfig>,
|
||||
}
|
||||
|
||||
impl Default for ProviderConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
default: "openai".to_string(),
|
||||
openai: Some(OpenAIConfig::default()),
|
||||
anthropic: None,
|
||||
ollama: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct OpenAIConfig {
|
||||
pub api_key: String,
|
||||
pub model: String,
|
||||
pub base_url: Option<String>,
|
||||
pub max_retries: u32,
|
||||
}
|
||||
|
||||
impl Default for OpenAIConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
api_key: String::new(),
|
||||
model: "gpt-4o".to_string(),
|
||||
base_url: None,
|
||||
max_retries: 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AnthropicConfig {
|
||||
pub api_key: String,
|
||||
pub model: String,
|
||||
pub max_retries: u32,
|
||||
}
|
||||
|
||||
impl Default for AnthropicConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
api_key: String::new(),
|
||||
model: "claude-3-5-sonnet-20241022".to_string(),
|
||||
max_retries: 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct OllamaConfig {
|
||||
pub base_url: String,
|
||||
pub model: String,
|
||||
pub max_retries: u32,
|
||||
}
|
||||
|
||||
impl Default for OllamaConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
base_url: "http://localhost:11434".to_string(),
|
||||
model: "llama3".to_string(),
|
||||
max_retries: 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Platform adapter configuration.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PlatformConfig {
|
||||
pub default: String,
|
||||
pub telegram: Option<TelegramConfig>,
|
||||
pub discord: Option<DiscordConfig>,
|
||||
pub webhook: Option<WebhookConfig>,
|
||||
}
|
||||
|
||||
impl Default for PlatformConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
default: "cli".to_string(),
|
||||
telegram: None,
|
||||
discord: None,
|
||||
webhook: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TelegramConfig {
|
||||
pub bot_token: String,
|
||||
pub allowed_users: Vec<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DiscordConfig {
|
||||
pub bot_token: String,
|
||||
pub guild_id: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct WebhookConfig {
|
||||
pub listen_host: String,
|
||||
pub listen_port: u16,
|
||||
pub secret: Option<String>,
|
||||
}
|
||||
|
||||
/// Memory system configuration.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MemoryConfig {
|
||||
pub backend: String,
|
||||
pub storage_path: Option<PathBuf>,
|
||||
pub max_entries: usize,
|
||||
pub auto_compress: bool,
|
||||
}
|
||||
|
||||
impl Default for MemoryConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
backend: "local".to_string(),
|
||||
storage_path: None,
|
||||
max_entries: 10000,
|
||||
auto_compress: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Security configuration.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SecurityConfig {
|
||||
pub vault_path: Option<PathBuf>,
|
||||
pub encryption_enabled: bool,
|
||||
pub threat_detection: bool,
|
||||
}
|
||||
|
||||
impl Default for SecurityConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
vault_path: None,
|
||||
encryption_enabled: true,
|
||||
threat_detection: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Kanban task system configuration.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct KanbanConfig {
|
||||
pub enabled: bool,
|
||||
pub max_concurrent_tasks: usize,
|
||||
pub auto_decompose: bool,
|
||||
}
|
||||
|
||||
impl Default for KanbanConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: true,
|
||||
max_concurrent_tasks: 5,
|
||||
auto_decompose: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Skills system configuration.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SkillsConfig {
|
||||
pub enabled: bool,
|
||||
pub skills_dir: Option<PathBuf>,
|
||||
pub auto_load: bool,
|
||||
}
|
||||
|
||||
impl Default for SkillsConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: true,
|
||||
skills_dir: None,
|
||||
auto_load: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Load configuration from a TOML file.
|
||||
pub fn load_config_from_file(path: &std::path::Path) -> anyhow::Result<AgentConfig> {
|
||||
let content = std::fs::read_to_string(path)
|
||||
.map_err(|e| anyhow::anyhow!("Failed to read config file {}: {}", path.display(), e))?;
|
||||
let config: AgentConfig = toml::from_str(&content)
|
||||
.map_err(|e| anyhow::anyhow!("Failed to parse config file {}: {}", path.display(), e))?;
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_default_config() {
|
||||
let config = AgentConfig::default();
|
||||
assert_eq!(config.name, "gyandoot");
|
||||
assert_eq!(config.max_tokens, 4096);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_provider_default() {
|
||||
let provider = ProviderConfig::default();
|
||||
assert_eq!(provider.default, "openai");
|
||||
assert!(provider.openai.is_some());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user