22import datetime
33import inspect
44import json
5+ import time
56import traceback
67import typing as T
78import uuid
@@ -366,7 +367,9 @@ async def _execute_handoff(
366367
367368 # 注入公共上下文
368369 shared_context_prompt = (
369- DynamicSubAgentManager .build_shared_context_prompt (umo , agent_name )
370+ DynamicSubAgentManager .build_shared_context_prompt_v2 (
371+ umo , agent_name
372+ )
370373 )
371374 if shared_context_prompt :
372375 subagent_system_prompt += f"\n { shared_context_prompt } "
@@ -430,38 +433,75 @@ async def _execute_handoff_background(
430433 ):
431434 """Execute a handoff as a background task.
432435
433- Immediately yields a success response with a task_id, then runs
434- the subagent asynchronously. When the subagent finishes, a
435- ``CronMessageEvent`` is created so the main LLM can inform the
436- user of the result – the same pattern used by
437- ``_execute_background`` for regular background tasks.
436+ 当启用增强SubAgent时,会在 DynamicSubAgentManager 中创建 pending 任务,
437+ 并返回 task_id 给主 Agent,以便后续通过 wait_for_subagent 获取结果。
438438 """
439- task_id = uuid .uuid4 ().hex
439+ event = run_context .context .event
440+ umo = event .unified_msg_origin
441+ agent_name = getattr (tool .agent , "name" , None )
442+
443+ # 生成 subagent_task_id(用于 DynamicSubAgentManager)
444+ subagent_task_id = None
445+
446+ # 检查是否启用增强版 SubAgent
447+ try :
448+ from astrbot .core .dynamic_subagent_manager import DynamicSubAgentManager
449+
450+ if agent_name :
451+ session = DynamicSubAgentManager .get_session (umo )
452+ if session and agent_name in session .agents :
453+ # 增强版:在 DynamicSubAgentManager 中创建 pending 任务
454+ subagent_task_id = (
455+ DynamicSubAgentManager .create_pending_subagent_task (
456+ session_id = umo , agent_name = agent_name
457+ )
458+ )
459+ logger .info (
460+ f"[EnhancedSubAgent] Created pending task { subagent_task_id } for { agent_name } "
461+ )
462+ except Exception as e :
463+ logger .debug (f"[EnhancedSubAgent] Failed to create pending task: { e } " )
464+
465+ # 生成原始的 task_id(用于唤醒机制等)
466+ original_task_id = uuid .uuid4 ().hex
440467
441468 async def _run_handoff_in_background () -> None :
442469 try :
443470 await cls ._do_handoff_background (
444471 tool = tool ,
445472 run_context = run_context ,
446- task_id = task_id ,
473+ task_id = original_task_id ,
474+ subagent_task_id = subagent_task_id ,
447475 ** tool_args ,
448476 )
477+
449478 except Exception as e : # noqa: BLE001
450479 logger .error (
451- f"Background handoff { task_id } ({ tool .name } ) failed: { e !s} " ,
480+ f"Background handoff { original_task_id } ({ tool .name } ) failed: { e !s} " ,
452481 exc_info = True ,
453482 )
454483
455484 asyncio .create_task (_run_handoff_in_background ())
456485
457- text_content = mcp .types .TextContent (
458- type = "text" ,
459- text = (
460- f"Background task dedicated to subagent '{ tool .agent .name } ' submitted. task_id={ task_id } . "
461- f"The subagent '{ tool .agent .name } ' is working on the task on hehalf you. "
462- f"You will be notified when it finishes."
463- ),
464- )
486+ # 构建返回消息
487+ if subagent_task_id :
488+ text_content = mcp .types .TextContent (
489+ type = "text" ,
490+ text = (
491+ f"Background task submitted. subagent_task_id={ subagent_task_id } . "
492+ f"SubAgent '{ agent_name } ' is working on the task. "
493+ f"Use wait_for_subagent(subagent_name='{ agent_name } ', task_id='{ subagent_task_id } ') to get the result."
494+ ),
495+ )
496+ else :
497+ text_content = mcp .types .TextContent (
498+ type = "text" ,
499+ text = (
500+ f"Background task submitted. task_id={ original_task_id } . "
501+ f"SubAgent '{ agent_name } ' is working on the task. "
502+ f"You will be notified when it finishes."
503+ ),
504+ )
465505 yield mcp .types .CallToolResult (content = [text_content ])
466506
467507 @classmethod
@@ -472,13 +512,24 @@ async def _do_handoff_background(
472512 task_id : str ,
473513 ** tool_args ,
474514 ) -> None :
475- """Run the subagent handoff and, on completion, wake the main agent."""
515+ """Run the subagent handoff.
516+ 当增强版 SubAgent 启用时,结果存储到 DynamicSubAgentManager,主 Agent 可通过 wait_for_subagent 获取。
517+ 否则使用原有的 _wake_main_agent_for_background_result 流程。
518+ """
519+
520+ start_time = time .time ()
476521 result_text = ""
522+ error_text = None
477523 tool_args = dict (tool_args )
478524 tool_args ["image_urls" ] = await cls ._collect_handoff_image_urls (
479525 run_context ,
480526 tool_args .get ("image_urls" ),
481527 )
528+
529+ event = run_context .context .event
530+ umo = event .unified_msg_origin
531+ agent_name = getattr (tool .agent , "name" , None )
532+
482533 try :
483534 async for r in cls ._execute_handoff (
484535 tool ,
@@ -490,26 +541,106 @@ async def _do_handoff_background(
490541 for content in r .content :
491542 if isinstance (content , mcp .types .TextContent ):
492543 result_text += content .text + "\n "
544+
493545 except Exception as e :
546+ error_text = str (e )
494547 result_text = (
495548 f"error: Background task execution failed, internal error: { e !s} "
496549 )
497550
498- event = run_context .context .event
551+ execution_time = time .time () - start_time
552+ success = error_text is None
499553
500- await cls ._wake_main_agent_for_background_result (
501- run_context = run_context ,
502- task_id = task_id ,
503- tool_name = tool .name ,
504- result_text = result_text ,
505- tool_args = tool_args ,
506- note = (
507- event .get_extra ("background_note" )
508- or f"Background task for subagent '{ tool .agent .name } ' finished."
509- ),
510- summary_name = f"Dedicated to subagent `{ tool .agent .name } `" ,
511- extra_result_fields = {"subagent_name" : tool .agent .name },
512- )
554+ # 检查是否是增强版 SubAgent
555+ enhanced_enabled = False
556+ try :
557+ from astrbot .core .dynamic_subagent_manager import DynamicSubAgentManager
558+
559+ session = DynamicSubAgentManager .get_session (umo )
560+ if session and agent_name :
561+ # 检查是否是动态创建的 SubAgent
562+ if agent_name in session .agents :
563+ enhanced_enabled = True
564+ except Exception :
565+ pass
566+
567+ subagent_task_id = tool_args .get ("subagent_task_id" , None )
568+
569+ if enhanced_enabled and agent_name and subagent_task_id :
570+ # 增强版:存储结果到 DynamicSubAgentManager
571+ try :
572+ from astrbot .core .dynamic_subagent_manager import DynamicSubAgentManager
573+
574+ # 存储结果(使用 subagent_task_id)
575+ DynamicSubAgentManager .store_subagent_result (
576+ session_id = umo ,
577+ agent_name = agent_name ,
578+ task_id = subagent_task_id ,
579+ success = success ,
580+ result = result_text .strip () if result_text else "" ,
581+ error = error_text ,
582+ execution_time = execution_time ,
583+ )
584+
585+ # 如果启用了 shared_context,发布完成状态
586+ if session .shared_context_enabled :
587+ status_content = (
588+ f" SubAgent '{ agent_name } ' 任务完成,耗时 { execution_time :.1f} s"
589+ )
590+ if error_text :
591+ status_content = (
592+ f" SubAgent '{ agent_name } ' 任务失败: { error_text } "
593+ )
594+
595+ DynamicSubAgentManager .add_shared_context (
596+ session_id = umo ,
597+ sender = agent_name ,
598+ context_type = "status" ,
599+ content = status_content ,
600+ target = "all" ,
601+ )
602+
603+ logger .info (
604+ f"[EnhancedSubAgent] Stored result for { agent_name } task { subagent_task_id } : "
605+ f"success={ success } , time={ execution_time :.1f} s"
606+ )
607+
608+ except Exception as e :
609+ logger .error (
610+ f"[EnhancedSubAgent] Failed to store result for { agent_name } : { e } "
611+ )
612+ # 存储失败时,回退到原有的唤醒机制
613+ await cls ._wake_main_agent_for_background_result (
614+ run_context = run_context ,
615+ task_id = task_id ,
616+ tool_name = tool .name ,
617+ result_text = result_text ,
618+ tool_args = tool_args ,
619+ note = (
620+ event .get_extra ("background_note" )
621+ or f"Background task for subagent '{ agent_name } ' finished."
622+ ),
623+ summary_name = f"Dedicated to subagent `{ agent_name } `" ,
624+ extra_result_fields = {
625+ "subagent_name" : agent_name ,
626+ "subagent_task_id" : subagent_task_id ,
627+ },
628+ )
629+ else :
630+ # 非增强版:使用原有的唤醒机制
631+ await cls ._wake_main_agent_for_background_result (
632+ run_context = run_context ,
633+ task_id = task_id ,
634+ tool_name = tool .name ,
635+ result_text = result_text ,
636+ tool_args = tool_args ,
637+ note = (
638+ event .get_extra ("background_note" )
639+ or f"Background task for subagent '{ agent_name } ' finished."
640+ ),
641+ summary_name = f"Dedicated to subagent `{ agent_name } `" ,
642+ extra_result_fields = {"subagent_name" : agent_name },
643+ )
513644
514645 @classmethod
515646 async def _execute_background (
0 commit comments