@@ -213,7 +213,7 @@ def _cleanup_single_subagent(cls, session_id: str, agent_name: str) -> None:
213213 session .agent_histories .pop (agent_name , None )
214214 SubAgentLogger .info (
215215 session_id ,
216- "DynamicSubAgentManager :auto_cleanup" ,
216+ "DynamicSubAgentrManager :auto_cleanup" ,
217217 f"Auto cleaned: { agent_name } " ,
218218 agent_name ,
219219 )
@@ -309,19 +309,25 @@ def get_subagent_tools(cls, session_id: str, agent_name: str) -> list | None:
309309 return config .tools
310310
311311 @classmethod
312- def clear_subagent_history (cls , session_id : str , agent_name : str ) -> None :
312+ def clear_subagent_history (cls , session_id : str , agent_name : str ) -> str :
313313 """Clear conversation history for a subagent"""
314314 session = cls .get_session (session_id )
315315 if not session :
316- return
316+ return f"__HISTORY_CLEARED_FAILED_: Session_id { session_id } does not exist."
317317 if agent_name in session .agent_histories :
318318 session .agent_histories .pop (agent_name )
319+
320+ if session .shared_context_enabled :
321+ cls .cleanup_shared_context_by_agent (session_id , agent_name )
319322 SubAgentLogger .debug (
320323 session_id ,
321324 "DynamicSubAgentManager:history" ,
322325 f"Cleared history for: { agent_name } " ,
323326 agent_name ,
324327 )
328+ return "__HISTORY_CLEARED__"
329+ else :
330+ return f"__HISTORY_CLEARED_FAILED_: Agent name { agent_name } not found. Available names { list (session .agents .keys ())} "
325331
326332 @classmethod
327333 def set_shared_context_enabled (cls , session_id : str , enabled : bool ) -> None :
@@ -342,7 +348,7 @@ def add_shared_context(
342348 context_type : str ,
343349 content : str ,
344350 target : str = "all" ,
345- ) -> None :
351+ ) -> str :
346352 """Add a message to the shared context
347353
348354 Args:
@@ -355,7 +361,11 @@ def add_shared_context(
355361
356362 session = cls .get_or_create_session (session_id )
357363 if not session .shared_context_enabled :
358- return
364+ return "__SHARED_CONTEXT_ADDED_FAILED__: Shared context disabled."
365+ if (sender not in list (session .agents .keys ())) and (sender != "System" ):
366+ return f"__SHARED_CONTEXT_ADDED_FAILED__: Sender name { sender } not found. Available names { list (session .agents .keys ())} "
367+ if (target not in list (session .agents .keys ())) and (target != "all" ):
368+ return f"__SHARED_CONTEXT_ADDED_FAILED__: Target name { sender } not found. Available names { list (session .agents .keys ())} and 'all' "
359369
360370 if len (session .shared_context ) >= cls ._shared_context_maxlen :
361371 # 删除最旧的消息
@@ -378,6 +388,7 @@ def add_shared_context(
378388 f"[{ context_type } ] { sender } -> { target } : { content [:50 ]} ..." ,
379389 sender ,
380390 )
391+ return "__SHARED_CONTEXT_ADDED__"
381392
382393 @classmethod
383394 def get_shared_context (cls , session_id : str , filter_by_agent : str = None ) -> list :
@@ -582,22 +593,30 @@ async def cleanup_session(cls, session_id: str) -> dict:
582593 return {"status" : "cleaned" , "cleaned_agents" : cleaned }
583594
584595 @classmethod
585- async def cleanup_subagent (cls , session_id : str , agent_name : str ) -> bool :
596+ def remove_subagent (cls , session_id : str , agent_name : str ) -> str :
586597 session = cls .get_session (session_id )
587- if not session or agent_name not in session .agents :
588- return False
589- session .agents .pop (agent_name , None )
590- session .handoff_tools .pop (agent_name , None )
591- session .agent_histories .pop (agent_name , None )
592- # 清理公共上下文中包含该Agent的内容
593- cls .cleanup_shared_context_by_agent (session_id , agent_name )
594- SubAgentLogger .info (
595- session_id ,
596- "DynamicSubAgentManager:cleanup" ,
597- f"Cleaned: { agent_name } " ,
598- agent_name ,
599- )
600- return True
598+ if agent_name == "all" :
599+ session .agents .clear ()
600+ session .handoff_tools .clear ()
601+ session .agent_histories .clear ()
602+ session .shared_context .clear ()
603+ return "__SUBAGENT_REMOVED__"
604+ else :
605+ if agent_name not in session .agents :
606+ return f"__SUBAGENT_REMOVE_FAILED__: { agent_name } not found. Available subagent names { list (session .agents .keys ())} "
607+ else :
608+ session .agents .pop (agent_name , None )
609+ session .handoff_tools .pop (agent_name , None )
610+ session .agent_histories .pop (agent_name , None )
611+ # 清理公共上下文中包含该Agent的内容
612+ cls .cleanup_shared_context_by_agent (session_id , agent_name )
613+ SubAgentLogger .info (
614+ session_id ,
615+ "DynamicSubAgentManager:cleanup" ,
616+ f"Cleaned: { agent_name } " ,
617+ agent_name ,
618+ )
619+ return "__SUBAGENT_REMOVED__"
601620
602621 @classmethod
603622 def get_handoff_tools_for_session (cls , session_id : str ) -> list :
@@ -681,17 +700,22 @@ async def call(self, context, **kwargs) -> str:
681700 if handoff_tool :
682701 return f"__DYNAMIC_TOOL_CREATED__:{ tool_name } :{ handoff_tool .name } :Created. Use { tool_name } to delegate."
683702 else :
684- return f"__FAILED_TO_CREATE_DYNAMIC_TOOL__ :{ tool_name } "
703+ return f"__DYNAMIC_TOOL_CREATE_FAILED_ :{ tool_name } "
685704
686705
687706@dataclass
688- class CleanupDynamicSubagentTool (FunctionTool ):
689- name : str = "cleanup_dynamic_subagent "
690- description : str = "Clean up dynamic subagent."
707+ class RemoveDynamicSubagentTool (FunctionTool ):
708+ name : str = "remove_dynamic_subagent "
709+ description : str = "Remove dynamic subagent by name ."
691710 parameters : dict = field (
692711 default_factory = lambda : {
693712 "type" : "object" ,
694- "properties" : {"name" : {"type" : "string" }},
713+ "properties" : {
714+ "name" : {
715+ "type" : "string" ,
716+ "description" : "Subagent name to remove. Use 'all' to remove all dynamic subagents." ,
717+ }
718+ },
695719 "required" : ["name" ],
696720 }
697721 )
@@ -701,8 +725,11 @@ async def call(self, context, **kwargs) -> str:
701725 if not name :
702726 return "Error: name required"
703727 session_id = context .context .event .unified_msg_origin
704- success = await DynamicSubAgentManager .cleanup_subagent (session_id , name )
705- return f"Cleaned { name } " if success else f"Not found: { name } "
728+ remove_status = DynamicSubAgentManager .remove_subagent (session_id , name )
729+ if remove_status == "__SUBAGENT_REMOVED__" :
730+ return f"Cleaned { name } Subagent"
731+ else :
732+ return remove_status
706733
707734
708735@dataclass
@@ -748,7 +775,7 @@ async def call(self, context, **kwargs) -> str:
748775 session_id = context .context .event .unified_msg_origin
749776 session = DynamicSubAgentManager .get_or_create_session (session_id )
750777 if name not in session .agents :
751- return f"Error: Subagent { name } not found"
778+ return f"Error: Subagent { name } not found. Available subagents: { session . agents . keys () } "
752779 DynamicSubAgentManager .protect_subagent (session_id , name )
753780 return f"Subagent { name } is now protected from auto cleanup"
754781
@@ -783,12 +810,32 @@ async def call(self, context, **kwargs) -> str:
783810 return f"Subagent { name } was not protected"
784811
785812
786- # Tool instances
787- CREATE_DYNAMIC_SUBAGENT_TOOL = CreateDynamicSubAgentTool ()
788- CLEANUP_DYNAMIC_SUBAGENT_TOOL = CleanupDynamicSubagentTool ()
789- LIST_DYNAMIC_SUBAGENTS_TOOL = ListDynamicSubagentsTool ()
790- PROTECT_SUBAGENT_TOOL = ProtectSubagentTool ()
791- UNPROTECT_SUBAGENT_TOOL = UnprotectSubagentTool ()
813+ @dataclass
814+ class ResetSubAgentTool (FunctionTool ):
815+ """Tool to reset a subagent"""
816+
817+ name : str = "reset_subagent"
818+ description : str = "Reset an existing subagent. This will clean the dialog history of the subagent."
819+ parameters : dict = field (
820+ default_factory = lambda : {
821+ "type" : "object" ,
822+ "properties" : {
823+ "name" : {"type" : "string" , "description" : "Subagent name to reset" },
824+ },
825+ "required" : ["name" ],
826+ }
827+ )
828+
829+ async def call (self , context , ** kwargs ) -> str :
830+ name = kwargs .get ("name" , "" )
831+ if not name :
832+ return "Error: name required"
833+ session_id = context .context .event .unified_msg_origin
834+ reset_status = DynamicSubAgentManager .clear_subagent_history (session_id , name )
835+ if reset_status == "__HISTORY_CLEARED__" :
836+ return f"Subagent { name } was reset"
837+ else :
838+ return reset_status
792839
793840
794841# Shared Context Tools
@@ -826,10 +873,13 @@ async def call(self, context, **kwargs) -> str:
826873 if not content :
827874 return "Error: content is required"
828875 session_id = context .context .event .unified_msg_origin
829- DynamicSubAgentManager .add_shared_context (
876+ add_status = DynamicSubAgentManager .add_shared_context (
830877 session_id , "System" , context_type , content , target
831878 )
832- return f"Shared context updated: [{ context_type } ] System -> { target } : { content [:100 ]} { '...' if len (content ) > 100 else '' } "
879+ if add_status == "__SHARED_CONTEXT_ADDED__" :
880+ return f"Shared context updated: [{ context_type } ] System -> { target } : { content [:100 ]} { '...' if len (content ) > 100 else '' } "
881+ else :
882+ return add_status
833883
834884
835885@dataclass
@@ -873,10 +923,13 @@ async def call(self, context, **kwargs) -> str:
873923 if not content :
874924 return "Error: content is required"
875925 session_id = context .context .event .unified_msg_origin
876- DynamicSubAgentManager .add_shared_context (
926+ add_status = DynamicSubAgentManager .add_shared_context (
877927 session_id , sender , context_type , content , target
878928 )
879- return f"Shared context updated: [{ context_type } ] { sender } -> { target } : { content [:100 ]} { '...' if len (content ) > 100 else '' } "
929+ if add_status == "__SHARED_CONTEXT_ADDED__" :
930+ return f"Shared context updated: [{ context_type } ] { sender } -> { target } : { content [:100 ]} { '...' if len (content ) > 100 else '' } "
931+ else :
932+ return add_status
880933
881934
882935@dataclass
@@ -914,7 +967,13 @@ async def call(self, context, **kwargs) -> str:
914967 return "\n " .join (lines )
915968
916969
917- # Shared context tool instances
970+ # Tool instances
971+ CREATE_DYNAMIC_SUBAGENT_TOOL = CreateDynamicSubAgentTool ()
972+ REMOVE_DYNAMIC_SUBAGENT_TOOL = RemoveDynamicSubagentTool ()
973+ LIST_DYNAMIC_SUBAGENTS_TOOL = ListDynamicSubagentsTool ()
974+ RESET_SUBAGENT_TOOL = ResetSubAgentTool ()
975+ PROTECT_SUBAGENT_TOOL = ProtectSubagentTool ()
976+ UNPROTECT_SUBAGENT_TOOL = UnprotectSubagentTool ()
918977SEND_SHARED_CONTEXT_TOOL = SendSharedContextTool ()
919978SEND_SHARED_CONTEXT_TOOL_FOR_MAIN_AGENT = SendSharedContextToolForMainAgent ()
920979VIEW_SHARED_CONTEXT_TOOL = ViewSharedContextTool ()
0 commit comments