@@ -10,12 +10,9 @@ use uuid::Uuid;
1010
1111use crate :: agents:: extension:: { ExtensionConfig , ExtensionError , ExtensionResult , ToolInfo } ;
1212use crate :: agents:: extension_manager:: { get_parameter_names, ExtensionManager } ;
13+ use crate :: agents:: extension_manager_extension:: MANAGE_EXTENSIONS_TOOL_NAME_COMPLETE ;
1314use crate :: agents:: final_output_tool:: { FINAL_OUTPUT_CONTINUATION_MESSAGE , FINAL_OUTPUT_TOOL_NAME } ;
14- use crate :: agents:: platform_tools:: {
15- PLATFORM_LIST_RESOURCES_TOOL_NAME , PLATFORM_MANAGE_EXTENSIONS_TOOL_NAME ,
16- PLATFORM_MANAGE_SCHEDULE_TOOL_NAME , PLATFORM_READ_RESOURCE_TOOL_NAME ,
17- PLATFORM_SEARCH_AVAILABLE_EXTENSIONS_TOOL_NAME ,
18- } ;
15+ use crate :: agents:: platform_tools:: PLATFORM_MANAGE_SCHEDULE_TOOL_NAME ;
1916use crate :: agents:: prompt_manager:: PromptManager ;
2017use crate :: agents:: recipe_tools:: dynamic_task_tools:: {
2118 create_dynamic_task, create_dynamic_task_tool, DYNAMIC_TASK_TOOL_NAME_PREFIX ,
@@ -32,7 +29,7 @@ use crate::agents::tool_route_manager::ToolRouteManager;
3229use crate :: agents:: tool_router_index_manager:: ToolRouterIndexManager ;
3330use crate :: agents:: types:: SessionConfig ;
3431use crate :: agents:: types:: { FrontendTool , ToolResultReceiver } ;
35- use crate :: config:: { get_enabled_extensions, get_extension_by_name , Config } ;
32+ use crate :: config:: { get_enabled_extensions, Config } ;
3633use crate :: context_mgmt:: DEFAULT_COMPACTION_THRESHOLD ;
3734use crate :: conversation:: { debug_conversation_fix, fix_conversation, Conversation } ;
3835use crate :: mcp_utils:: ToolResult ;
@@ -88,7 +85,7 @@ pub struct ToolCategorizeResult {
8885/// The main goose Agent
8986pub struct Agent {
9087 pub ( super ) provider : Mutex < Option < Arc < dyn Provider > > > ,
91- pub extension_manager : ExtensionManager ,
88+ pub extension_manager : Arc < ExtensionManager > ,
9289 pub ( super ) sub_recipe_manager : Mutex < SubRecipeManager > ,
9390 pub ( super ) tasks_manager : TasksManager ,
9491 pub ( super ) final_output_tool : Arc < Mutex < Option < FinalOutputTool > > > ,
@@ -100,7 +97,7 @@ pub struct Agent {
10097 pub ( super ) tool_result_tx : mpsc:: Sender < ( String , ToolResult < Vec < Content > > ) > ,
10198 pub ( super ) tool_result_rx : ToolResultReceiver ,
10299
103- pub ( super ) tool_route_manager : ToolRouteManager ,
100+ pub tool_route_manager : Arc < ToolRouteManager > ,
104101 pub ( super ) scheduler_service : Mutex < Option < Arc < dyn SchedulerTrait > > > ,
105102 pub ( super ) retry_manager : RetryManager ,
106103 pub ( super ) tool_inspection_manager : ToolInspectionManager ,
@@ -163,7 +160,7 @@ impl Agent {
163160
164161 Self {
165162 provider : Mutex :: new ( None ) ,
166- extension_manager : ExtensionManager :: new ( ) ,
163+ extension_manager : Arc :: new ( ExtensionManager :: new ( ) ) ,
167164 sub_recipe_manager : Mutex :: new ( SubRecipeManager :: new ( ) ) ,
168165 tasks_manager : TasksManager :: new ( ) ,
169166 final_output_tool : Arc :: new ( Mutex :: new ( None ) ) ,
@@ -174,7 +171,7 @@ impl Agent {
174171 confirmation_rx : Mutex :: new ( confirm_rx) ,
175172 tool_result_tx : tool_tx,
176173 tool_result_rx : Arc :: new ( Mutex :: new ( tool_rx) ) ,
177- tool_route_manager : ToolRouteManager :: new ( ) ,
174+ tool_route_manager : Arc :: new ( ToolRouteManager :: new ( ) ) ,
178175 scheduler_service : Mutex :: new ( None ) ,
179176 retry_manager : RetryManager :: new ( ) ,
180177 tool_inspection_manager : Self :: create_default_tool_inspection_manager ( ) ,
@@ -404,28 +401,6 @@ impl Agent {
404401 return ( request_id, Ok ( ToolCallResult :: from ( result) ) ) ;
405402 }
406403
407- if tool_call. name == PLATFORM_MANAGE_EXTENSIONS_TOOL_NAME {
408- let extension_name = tool_call
409- . arguments
410- . as_ref ( )
411- . and_then ( |args| args. get ( "extension_name" ) )
412- . and_then ( |v| v. as_str ( ) )
413- . unwrap_or ( "" )
414- . to_string ( ) ;
415- let action = tool_call
416- . arguments
417- . as_ref ( )
418- . and_then ( |args| args. get ( "action" ) )
419- . and_then ( |v| v. as_str ( ) )
420- . unwrap_or ( "" )
421- . to_string ( ) ;
422- let ( request_id, result) = self
423- . manage_extensions ( action, extension_name, request_id)
424- . await ;
425-
426- return ( request_id, Ok ( ToolCallResult :: from ( result) ) ) ;
427- }
428-
429404 if tool_call. name == FINAL_OUTPUT_TOOL_NAME {
430405 return if let Some ( final_output_tool) = self . final_output_tool . lock ( ) . await . as_mut ( ) {
431406 let result = final_output_tool. execute_tool_call ( tool_call. clone ( ) ) . await ;
@@ -488,12 +463,12 @@ impl Agent {
488463 let parent_session_id = session. id . to_string ( ) ;
489464 let parent_working_dir = session. working_dir . clone ( ) ;
490465
491- let task_config = TaskConfig :: new (
492- provider ,
493- parent_session_id ,
494- parent_working_dir ,
495- get_enabled_extensions ( ) ,
496- ) ;
466+ // Get extensions from the agent's runtime state rather than global config
467+ // This ensures subagents inherit extensions that were dynamically enabled by the parent
468+ let extensions = self . get_extension_configs ( ) . await ;
469+
470+ let task_config =
471+ TaskConfig :: new ( provider , parent_session_id , parent_working_dir , extensions ) ;
497472
498473 let arguments = match tool_call. arguments . clone ( ) {
499474 Some ( args) => Value :: Object ( args) ,
@@ -560,31 +535,6 @@ impl Agent {
560535 . map ( Value :: Object )
561536 . unwrap_or ( Value :: Object ( serde_json:: Map :: new ( ) ) ) ;
562537 create_dynamic_task ( arguments, & self . tasks_manager , loaded_extensions) . await
563- } else if tool_call. name == PLATFORM_READ_RESOURCE_TOOL_NAME {
564- // Check if the tool is read_resource and handle it separately
565- let arguments = tool_call
566- . arguments
567- . clone ( )
568- . map ( Value :: Object )
569- . unwrap_or ( Value :: Object ( serde_json:: Map :: new ( ) ) ) ;
570- ToolCallResult :: from (
571- self . extension_manager
572- . read_resource ( arguments, cancellation_token. unwrap_or_default ( ) )
573- . await ,
574- )
575- } else if tool_call. name == PLATFORM_LIST_RESOURCES_TOOL_NAME {
576- let arguments = tool_call
577- . arguments
578- . clone ( )
579- . map ( Value :: Object )
580- . unwrap_or ( Value :: Object ( serde_json:: Map :: new ( ) ) ) ;
581- ToolCallResult :: from (
582- self . extension_manager
583- . list_resources ( arguments, cancellation_token. unwrap_or_default ( ) )
584- . await ,
585- )
586- } else if tool_call. name == PLATFORM_SEARCH_AVAILABLE_EXTENSIONS_TOOL_NAME {
587- ToolCallResult :: from ( self . extension_manager . search_available_extensions ( ) . await )
588538 } else if self . is_frontend_tool ( & tool_call. name ) . await {
589539 // For frontend tools, return an error indicating we need frontend execution
590540 ToolCallResult :: from ( Err ( ErrorData :: new (
@@ -653,109 +603,6 @@ impl Agent {
653603 Ok ( ( ) )
654604 }
655605
656- #[ allow( clippy:: too_many_lines) ]
657- pub ( super ) async fn manage_extensions (
658- & self ,
659- action : String ,
660- extension_name : String ,
661- request_id : String ,
662- ) -> ( String , Result < Vec < Content > , ErrorData > ) {
663- if self . tool_route_manager . is_router_functional ( ) . await {
664- let selector = self . tool_route_manager . get_router_tool_selector ( ) . await ;
665- if let Some ( selector) = selector {
666- let selector_action = if action == "disable" { "remove" } else { "add" } ;
667- let selector = Arc :: new ( selector) ;
668- if let Err ( e) = ToolRouterIndexManager :: update_extension_tools (
669- & selector,
670- & self . extension_manager ,
671- & extension_name,
672- selector_action,
673- )
674- . await
675- {
676- return (
677- request_id,
678- Err ( ErrorData :: new (
679- ErrorCode :: INTERNAL_ERROR ,
680- format ! ( "Failed to update LLM index: {}" , e) ,
681- None ,
682- ) ) ,
683- ) ;
684- }
685- }
686- }
687- if action == "disable" {
688- let result = self
689- . extension_manager
690- . remove_extension ( & extension_name)
691- . await
692- . map ( |_| {
693- vec ! [ Content :: text( format!(
694- "The extension '{}' has been disabled successfully" ,
695- extension_name
696- ) ) ]
697- } )
698- . map_err ( |e| ErrorData :: new ( ErrorCode :: INTERNAL_ERROR , e. to_string ( ) , None ) ) ;
699- return ( request_id, result) ;
700- }
701-
702- let config = match get_extension_by_name ( & extension_name) {
703- Some ( config) => config,
704- None => {
705- return (
706- request_id,
707- Err ( ErrorData :: new (
708- ErrorCode :: RESOURCE_NOT_FOUND ,
709- format ! (
710- "Extension '{}' not found. Please check the extension name and try again." ,
711- extension_name
712- ) ,
713- None ,
714- ) ) ,
715- )
716- }
717- } ;
718- let result = self
719- . extension_manager
720- . add_extension ( config)
721- . await
722- . map ( |_| {
723- vec ! [ Content :: text( format!(
724- "The extension '{}' has been installed successfully" ,
725- extension_name
726- ) ) ]
727- } )
728- . map_err ( |e| ErrorData :: new ( ErrorCode :: INTERNAL_ERROR , e. to_string ( ) , None ) ) ;
729-
730- // Update LLM index if operation was successful and LLM routing is functional
731- if result. is_ok ( ) && self . tool_route_manager . is_router_functional ( ) . await {
732- let selector = self . tool_route_manager . get_router_tool_selector ( ) . await ;
733- if let Some ( selector) = selector {
734- let llm_action = if action == "disable" { "remove" } else { "add" } ;
735- let selector = Arc :: new ( selector) ;
736- if let Err ( e) = ToolRouterIndexManager :: update_extension_tools (
737- & selector,
738- & self . extension_manager ,
739- & extension_name,
740- llm_action,
741- )
742- . await
743- {
744- return (
745- request_id,
746- Err ( ErrorData :: new (
747- ErrorCode :: INTERNAL_ERROR ,
748- format ! ( "Failed to update LLM index: {}" , e) ,
749- None ,
750- ) ) ,
751- ) ;
752- }
753- }
754- }
755-
756- ( request_id, result)
757- }
758-
759606 pub async fn add_extension ( & self , extension : ExtensionConfig ) -> ExtensionResult < ( ) > {
760607 match & extension {
761608 ExtensionConfig :: Frontend {
@@ -824,21 +671,10 @@ impl Agent {
824671
825672 if extension_name. is_none ( ) || extension_name. as_deref ( ) == Some ( "platform" ) {
826673 // Add platform tools
827- prefixed_tools. extend ( [
828- platform_tools:: search_available_extensions_tool ( ) ,
829- platform_tools:: manage_extensions_tool ( ) ,
830- platform_tools:: manage_schedule_tool ( ) ,
831- ] ) ;
674+ // TODO: migrate the manage schedule tool as well
675+ prefixed_tools. extend ( [ platform_tools:: manage_schedule_tool ( ) ] ) ;
832676 // Dynamic task tool
833677 prefixed_tools. push ( create_dynamic_task_tool ( ) ) ;
834-
835- // Add resource tools if supported
836- if self . extension_manager . supports_resources ( ) . await {
837- prefixed_tools. extend ( [
838- platform_tools:: read_resource_tool ( ) ,
839- platform_tools:: list_resources_tool ( ) ,
840- ] ) ;
841- }
842678 }
843679
844680 if extension_name. is_none ( ) {
@@ -1220,7 +1056,7 @@ impl Agent {
12201056 let mut enable_extension_request_ids = vec![ ] ;
12211057 for request in & remaining_requests {
12221058 if let Ok ( tool_call) = & request. tool_call {
1223- if tool_call. name == PLATFORM_MANAGE_EXTENSIONS_TOOL_NAME {
1059+ if tool_call. name == MANAGE_EXTENSIONS_TOOL_NAME_COMPLETE {
12241060 enable_extension_request_ids. push( request. id. clone( ) ) ;
12251061 }
12261062 }
0 commit comments