use std::collections::HashMap;
use std::path::PathBuf;
pub use agent_diva_core::config::MCPServerConfig;
#[derive(Debug, Clone)]
pub struct WebSearchConfig {
pub provider: String,
pub api_key: Option<String>,
pub max_results: u32,
}
impl Default for WebSearchConfig {
fn default() -> Self {
Self {
provider: "bocha".to_string(),
api_key: None,
max_results: 5,
}
}
}
#[derive(Debug, Clone)]
pub struct SoulConfig {
pub enabled: bool,
pub max_chars: usize,
pub bootstrap_once: bool,
pub notify_on_change: bool,
pub frequent_change_window_secs: u64,
pub frequent_change_threshold: usize,
pub boundary_confirmation_hint: bool,
}
impl Default for SoulConfig {
fn default() -> Self {
Self {
enabled: true,
max_chars: 4000,
bootstrap_once: true,
notify_on_change: true,
frequent_change_window_secs: 300,
frequent_change_threshold: 3,
boundary_confirmation_hint: true,
}
}
}
#[derive(Debug, Clone)]
pub struct NanoConfig {
pub model: String,
pub api_key: String,
pub api_base: Option<String>,
pub workspace: PathBuf,
pub max_iterations: usize,
pub exec_timeout: u64,
pub restrict_to_workspace: bool,
pub web_search: Option<WebSearchConfig>,
pub mcp_servers: HashMap<String, MCPServerConfig>,
pub soul: SoulConfig,
}
impl Default for NanoConfig {
fn default() -> Self {
Self {
model: String::new(),
api_key: String::new(),
api_base: None,
workspace: PathBuf::from("."),
max_iterations: 20,
exec_timeout: 60,
restrict_to_workspace: true,
web_search: None,
mcp_servers: HashMap::new(),
soul: SoulConfig::default(),
}
}
}
impl NanoConfig {
pub fn from_env() -> Result<Self, String> {
let model = std::env::var("NANO_MODEL")
.map_err(|_| "NANO_MODEL environment variable not set")?;
let api_key = std::env::var("NANO_API_KEY")
.map_err(|_| "NANO_API_KEY environment variable not set")?;
let api_base = std::env::var("NANO_API_BASE").ok().filter(|s| !s.is_empty());
Ok(Self {
model,
api_key,
api_base,
..Default::default()
})
}
}