diff --git a/crates/goose/src/agents/agent.rs b/crates/goose/src/agents/agent.rs index 7d30228efef1..6715929ba12e 100644 --- a/crates/goose/src/agents/agent.rs +++ b/crates/goose/src/agents/agent.rs @@ -640,6 +640,28 @@ impl Agent { Ok(()) } + pub async fn subagents_enabled(&self) -> bool { + let config = crate::config::Config::global(); + let is_autonomous = config.get_goose_mode().unwrap_or(GooseMode::Auto) == GooseMode::Auto; + if !is_autonomous { + return false; + } + if self + .provider() + .await + .map(|provider| provider.get_active_model_name().starts_with("gemini")) + .unwrap_or(false) + { + return false; + } + !self + .extension_manager + .list_extensions() + .await + .map(|ext| ext.is_empty()) + .unwrap_or(true) + } + pub async fn list_tools(&self, extension_name: Option) -> Vec { let mut prefixed_tools = self .extension_manager @@ -647,8 +669,9 @@ impl Agent { .await .unwrap_or_default(); + let subagents_enabled = self.subagents_enabled().await; if extension_name.is_none() || extension_name.as_deref() == Some("platform") { - prefixed_tools.extend([platform_tools::manage_schedule_tool()]); + prefixed_tools.push(platform_tools::manage_schedule_tool()); } if extension_name.is_none() { @@ -656,10 +679,11 @@ impl Agent { prefixed_tools.push(final_output_tool.tool()); } - // Add the unified subagent tool - let sub_recipes = self.sub_recipes.lock().await; - let sub_recipes_vec: Vec<_> = sub_recipes.values().cloned().collect(); - prefixed_tools.push(create_subagent_tool(&sub_recipes_vec)); + if subagents_enabled { + let sub_recipes = self.sub_recipes.lock().await; + let sub_recipes_vec: Vec<_> = sub_recipes.values().cloned().collect(); + prefixed_tools.push(create_subagent_tool(&sub_recipes_vec)); + } } prefixed_tools @@ -1374,7 +1398,7 @@ impl Agent { let prompt_manager = self.prompt_manager.lock().await; let system_prompt = prompt_manager - .builder(model_name) + .builder() .with_extensions(extensions_info.into_iter()) .with_frontend_instructions(self.frontend_instructions.lock().await.clone()) .with_extension_and_tool_counts(extension_count, tool_count) @@ -1594,7 +1618,7 @@ mod tests { ); let prompt_manager = agent.prompt_manager.lock().await; - let system_prompt = prompt_manager.builder("gpt-4o").build(); + let system_prompt = prompt_manager.builder().build(); let final_output_tool_ref = agent.final_output_tool.lock().await; let final_output_tool_system_prompt = diff --git a/crates/goose/src/agents/prompt_manager.rs b/crates/goose/src/agents/prompt_manager.rs index 90151bfd35d0..cce4a852538f 100644 --- a/crates/goose/src/agents/prompt_manager.rs +++ b/crates/goose/src/agents/prompt_manager.rs @@ -7,7 +7,6 @@ use std::collections::HashMap; use crate::agents::extension::ExtensionInfo; use crate::agents::router_tools::llm_search_tool_prompt; -use crate::agents::subagent_tool::should_enable_subagents; use crate::hints::load_hints::{load_hint_files, AGENTS_MD_FILENAME, GOOSE_HINTS_FILENAME}; use crate::{ config::{Config, GooseMode}, @@ -47,13 +46,13 @@ struct SystemPromptContext { } pub struct SystemPromptBuilder<'a, M> { - model_name: String, manager: &'a M, extensions_info: Vec, frontend_instructions: Option, extension_tool_count: Option<(usize, usize)>, router_enabled: bool, + subagents_enabled: bool, hints: Option, } @@ -116,6 +115,11 @@ impl<'a> SystemPromptBuilder<'a, PromptManager> { self } + pub fn with_enable_subagents(mut self, subagents_enabled: bool) -> Self { + self.subagents_enabled = subagents_enabled; + self + } + pub fn build(self) -> String { let mut extensions_info = self.extensions_info; @@ -152,7 +156,7 @@ impl<'a> SystemPromptBuilder<'a, PromptManager> { extension_tool_limits, goose_mode, is_autonomous: goose_mode == GooseMode::Auto, - enable_subagents: should_enable_subagents(self.model_name.as_str()), + enable_subagents: self.subagents_enabled, max_extensions: MAX_EXTENSIONS, max_tools: MAX_TOOLS, }; @@ -228,15 +232,15 @@ impl PromptManager { self.system_prompt_override = Some(template); } - pub fn builder<'a>(&'a self, model_name: &str) -> SystemPromptBuilder<'a, Self> { + pub fn builder<'a>(&'a self) -> SystemPromptBuilder<'a, Self> { SystemPromptBuilder { - model_name: model_name.to_string(), manager: self, extensions_info: vec![], frontend_instructions: None, extension_tool_count: None, router_enabled: false, + subagents_enabled: false, hints: None, } } @@ -260,7 +264,7 @@ mod tests { let malicious_override = "System prompt\u{E0041}\u{E0042}\u{E0043}with hidden text"; manager.set_system_prompt_override(malicious_override.to_string()); - let result = manager.builder("gpt-4o").build(); + let result = manager.builder().build(); assert!(!result.contains('\u{E0041}')); assert!(!result.contains('\u{E0042}')); @@ -275,7 +279,7 @@ mod tests { let malicious_extra = "Extra instruction\u{E0041}\u{E0042}\u{E0043}hidden"; manager.add_system_prompt_extra(malicious_extra.to_string()); - let result = manager.builder("gpt-4o").build(); + let result = manager.builder().build(); assert!(!result.contains('\u{E0041}')); assert!(!result.contains('\u{E0042}')); @@ -291,7 +295,7 @@ mod tests { manager.add_system_prompt_extra("Second\u{E0042}instruction".to_string()); manager.add_system_prompt_extra("Third\u{E0043}instruction".to_string()); - let result = manager.builder("gpt-4o").build(); + let result = manager.builder().build(); assert!(!result.contains('\u{E0041}')); assert!(!result.contains('\u{E0042}')); @@ -307,7 +311,7 @@ mod tests { let legitimate_unicode = "Instruction with δΈ–η•Œ and 🌍 emojis"; manager.add_system_prompt_extra(legitimate_unicode.to_string()); - let result = manager.builder("gpt-4o").build(); + let result = manager.builder().build(); assert!(result.contains("δΈ–η•Œ")); assert!(result.contains("🌍")); @@ -325,7 +329,7 @@ mod tests { ); let result = manager - .builder("gpt-4o") + .builder() .with_extension(malicious_extension_info) .build(); @@ -340,7 +344,7 @@ mod tests { fn test_basic() { let manager = PromptManager::with_timestamp(DateTime::::from_timestamp(0, 0).unwrap()); - let system_prompt = manager.builder("gpt-4o").build(); + let system_prompt = manager.builder().build(); assert_snapshot!(system_prompt) } @@ -350,7 +354,7 @@ mod tests { let manager = PromptManager::with_timestamp(DateTime::::from_timestamp(0, 0).unwrap()); let system_prompt = manager - .builder("gpt-4o") + .builder() .with_extension(ExtensionInfo::new( "test", "how to use this extension", @@ -367,7 +371,7 @@ mod tests { let manager = PromptManager::with_timestamp(DateTime::::from_timestamp(0, 0).unwrap()); let system_prompt = manager - .builder("gpt-4o") + .builder() .with_extension(ExtensionInfo::new( "extension_A", "", diff --git a/crates/goose/src/agents/reply_parts.rs b/crates/goose/src/agents/reply_parts.rs index 0c907e082f94..2fb26da650d2 100644 --- a/crates/goose/src/agents/reply_parts.rs +++ b/crates/goose/src/agents/reply_parts.rs @@ -16,7 +16,6 @@ use crate::providers::toolshim::{ modify_system_prompt_for_tool_json, OllamaInterpreter, }; -use crate::agents::subagent_tool::should_enable_subagents; use crate::session::SessionManager; #[cfg(test)] use crate::session::SessionType; @@ -122,12 +121,6 @@ impl Agent { // If router is disabled and no tools were returned, fall back to regular tools if !router_enabled && tools.is_empty() { tools = self.list_tools(None).await; - let provider = self.provider().await?; - let model_name = provider.get_model_config().model_name; - - if !should_enable_subagents(&model_name) { - tools.retain(|tool| tool.name != crate::agents::subagent_tool::SUBAGENT_TOOL_NAME); - } } // Add frontend tools @@ -149,16 +142,16 @@ impl Agent { // Get model name from provider let provider = self.provider().await?; let model_config = provider.get_model_config(); - let model_name = &model_config.model_name; let prompt_manager = self.prompt_manager.lock().await; let mut system_prompt = prompt_manager - .builder(model_name) + .builder() .with_extensions(extensions_info.into_iter()) .with_frontend_instructions(self.frontend_instructions.lock().await.clone()) .with_extension_and_tool_counts(extension_count, tool_count) .with_router_enabled(router_enabled) .with_hints(working_dir) + .with_enable_subagents(self.subagents_enabled().await) .build(); // Handle toolshim if enabled diff --git a/crates/goose/src/agents/subagent_tool.rs b/crates/goose/src/agents/subagent_tool.rs index c775c070bc15..704c7b04af73 100644 --- a/crates/goose/src/agents/subagent_tool.rs +++ b/crates/goose/src/agents/subagent_tool.rs @@ -12,7 +12,6 @@ use tokio_util::sync::CancellationToken; use crate::agents::subagent_handler::run_complete_subagent_task; use crate::agents::subagent_task_config::TaskConfig; use crate::agents::tool_execution::ToolCallResult; -use crate::config::GooseMode; use crate::providers; use crate::recipe::build_recipe::build_recipe_from_template; use crate::recipe::local_recipes::load_local_recipe_file; @@ -440,18 +439,6 @@ async fn apply_settings_overrides( Ok(task_config) } -pub fn should_enable_subagents(model_name: &str) -> bool { - let config = crate::config::Config::global(); - let is_autonomous = config.get_goose_mode().unwrap_or(GooseMode::Auto) == GooseMode::Auto; - if !is_autonomous { - return false; - } - if model_name.starts_with("gemini") { - return false; - } - true -} - #[cfg(test)] mod tests { use super::*; diff --git a/scripts/test_compaction.sh b/scripts/test_compaction.sh index 5e51f57d9537..dc60d5ead363 100755 --- a/scripts/test_compaction.sh +++ b/scripts/test_compaction.sh @@ -151,7 +151,7 @@ echo "" # TEST 2: Auto Compaction # ================================================== echo "---------------------------------------------------" -echo "TEST 2: Auto Compaction via threshold (0.01)" +echo "TEST 2: Auto Compaction via threshold (0.005)" echo "---------------------------------------------------" TESTDIR=$(mktemp -d) @@ -159,8 +159,8 @@ echo "test content" > "$TESTDIR/test.txt" echo "Test directory: $TESTDIR" echo "" -# Set auto-compact threshold very low (1%) to trigger it quickly -export GOOSE_AUTO_COMPACT_THRESHOLD=0.01 +# Set auto-compact threshold very low (.5%) to trigger it quickly +export GOOSE_AUTO_COMPACT_THRESHOLD=0.005 OUTPUT=$(mktemp) @@ -197,7 +197,7 @@ else fi else echo "βœ— FAILED: Auto compaction was not triggered" - echo " Expected to see auto-compact messages with threshold of 0.01" + echo " Expected to see auto-compact messages with threshold of 0.005" RESULTS+=("βœ— Auto Compaction") fi fi