From 7c79292dc680f9d5d434b6b55cf3b8963bc117e2 Mon Sep 17 00:00:00 2001 From: sigoden Date: Wed, 24 Jul 2024 20:33:52 +0800 Subject: [PATCH] feat: move agent config to separate file (#741) --- config.example.yaml | 6 ------ src/config/agent.rs | 29 ++++++++++++++--------------- src/config/mod.rs | 38 ++++++++++++++++++-------------------- 3 files changed, 32 insertions(+), 41 deletions(-) diff --git a/config.example.yaml b/config.example.yaml index 89407a6..9e51c13 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -31,12 +31,6 @@ function_calling: true # Enables or disables function calling (Globall mapping_tools: # Alias for a tool or toolset # fs: 'fs_cat,fs_ls,fs_mkdir,fs_rm,fs_write' use_tools: null # Which tools to use by default -# Per-Agent configuration -agents: - - name: todo-sh - model: null - temperature: null - top_p: null # ---- RAG ---- rag_embedding_model: null # Specifies the embedding model to use diff --git a/src/config/agent.rs b/src/config/agent.rs index 139b02d..5416586 100644 --- a/src/config/agent.rs +++ b/src/config/agent.rs @@ -37,7 +37,12 @@ impl Agent { let functions_file_path = functions_dir.join("functions.json"); let variables_path = Config::agent_variables_file(name)?; let rag_path = Config::agent_rag_file(name)?; - + let config_path = Config::agent_config_file(name)?; + let agent_config = if config_path.exists() { + AgentConfig::load(&config_path)? + } else { + AgentConfig::default() + }; let mut definition = AgentDefinition::load(&definition_file_path)?; init_variables(&variables_path, &mut definition.variables) .context("Failed to init variables")?; @@ -48,13 +53,7 @@ impl Agent { Functions::default() }; definition.replace_tools_placeholder(&functions); - let agent_config = config - .read() - .agents - .iter() - .find(|v| v.name == name) - .cloned() - .unwrap_or_else(|| AgentConfig::new(name)); + let model = { let config = config.read(); match agent_config.model_id.as_ref() { @@ -201,7 +200,6 @@ impl RoleLike for Agent { #[derive(Debug, Clone, Default, Deserialize, Serialize)] pub struct AgentConfig { - pub name: String, #[serde(rename(serialize = "model", deserialize = "model"))] pub model_id: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -213,11 +211,12 @@ pub struct AgentConfig { } impl AgentConfig { - pub fn new(name: &str) -> Self { - Self { - name: name.to_string(), - ..Default::default() - } + pub fn load(path: &Path) -> Result { + let contents = read_to_string(path) + .with_context(|| format!("Failed to read agent config file at '{}'", path.display()))?; + let config: Self = serde_yaml::from_str(&contents) + .with_context(|| format!("Failed to load agent config at '{}'", path.display()))?; + Ok(config) } } @@ -242,7 +241,7 @@ impl AgentDefinition { let contents = read_to_string(path) .with_context(|| format!("Failed to read agent index file at '{}'", path.display()))?; let definition: Self = serde_yaml::from_str(&contents) - .with_context(|| format!("Failed to load agent at '{}'", path.display()))?; + .with_context(|| format!("Failed to load agent index at '{}'", path.display()))?; Ok(definition) } diff --git a/src/config/mod.rs b/src/config/mod.rs index 7b22496..3715888 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -3,7 +3,7 @@ mod input; mod role; mod session; -pub use self::agent::{list_agents, Agent, AgentConfig}; +pub use self::agent::{list_agents, Agent}; pub use self::input::Input; pub use self::role::{Role, RoleLike, CODE_ROLE, EXPLAIN_SHELL_ROLE, SHELL_ROLE}; use self::session::Session; @@ -107,7 +107,6 @@ pub struct Config { pub function_calling: bool, pub mapping_tools: IndexMap, pub use_tools: Option, - pub agents: Vec, pub rag_embedding_model: Option, pub rag_reranker_model: Option, @@ -169,7 +168,6 @@ impl Default for Config { function_calling: true, mapping_tools: Default::default(), use_tools: None, - agents: vec![], rag_embedding_model: None, rag_reranker_model: None, @@ -337,14 +335,18 @@ impl Config { } pub fn agents_config_dir() -> Result { - match env::var(get_env_name("agents_config_dir")) { + Self::local_path(AGENTS_DIR_NAME) + } + + pub fn agent_config_dir(name: &str) -> Result { + match env::var(format!("{}_CONFIG_DIR", convert_env_prefix(name))) { Ok(value) => Ok(PathBuf::from(value)), - Err(_) => Self::local_path(AGENTS_DIR_NAME), + Err(_) => Ok(Self::agents_config_dir()?.join(name)), } } - pub fn agent_config_dir(name: &str) -> Result { - Ok(Self::agents_config_dir()?.join(name)) + pub fn agent_config_file(name: &str) -> Result { + Ok(Self::agent_config_dir(name)?.join(CONFIG_FILE_NAME)) } pub fn agent_rag_file(name: &str) -> Result { @@ -356,14 +358,14 @@ impl Config { } pub fn agents_functions_dir() -> Result { - match env::var(get_env_name("agents_functions_dir")) { - Ok(value) => Ok(PathBuf::from(value)), - Err(_) => Ok(Self::functions_dir()?.join(AGENTS_DIR_NAME)), - } + Ok(Self::functions_dir()?.join(AGENTS_DIR_NAME)) } pub fn agent_functions_dir(name: &str) -> Result { - Ok(Self::agents_functions_dir()?.join(name)) + match env::var(format!("{}_FUNCTIONS_DIR", convert_env_prefix(name))) { + Ok(value) => Ok(PathBuf::from(value)), + Err(_) => Ok(Self::agents_functions_dir()?.join(name)), + } } pub fn state(&self) -> StateFlags { @@ -528,14 +530,6 @@ impl Config { ("roles_file", display_path(&Self::roles_file()?)), ("env_file", display_path(&Self::env_file()?)), ("functions_dir", display_path(&Self::functions_dir()?)), - ( - "agents_functions_dir", - display_path(&Self::agents_functions_dir()?), - ), - ( - "agents_config_dir", - display_path(&Self::agents_config_dir()?), - ), ("rags_dir", display_path(&Self::rags_dir()?)), ("sessions_dir", display_path(&self.sessions_dir()?)), ("messages_file", display_path(&self.messages_file()?)), @@ -1798,3 +1792,7 @@ fn complete_option_bool(value: Option) -> Vec { None => vec!["true".to_string(), "false".to_string()], } } + +fn convert_env_prefix(value: &str) -> String { + value.replace('-', "_").to_ascii_uppercase() +}