""" tools/subagent_tool.py — Sub-agent creation and synchronous execution. Only available when the parent agent has can_create_subagents=True. Creates a child agent in the DB (with parent_agent_id set) and runs it synchronously, returning the result and token counts. """ from __future__ import annotations import logging from .base import BaseTool, ToolResult logger = logging.getLogger(__name__) class SubagentTool(BaseTool): name = "subagent" description = ( "Create and run a sub-agent synchronously. " "Use this to delegate a well-defined sub-task to a focused agent. " "The sub-agent runs to completion and returns its result. " "Operation: create_and_run(name, prompt, model=None)" ) input_schema = { "type": "object", "properties": { "name": { "type": "string", "description": "Short name for the sub-agent", }, "prompt": { "type": "string", "description": "The task prompt for the sub-agent", }, "model": { "type": "string", "description": "Model override for the sub-agent (optional)", }, }, "required": ["name", "prompt"], } requires_confirmation = False allowed_in_scheduled_tasks = False def __init__(self, parent_agent_id: str, parent_model: str) -> None: self._parent_agent_id = parent_agent_id self._parent_model = parent_model async def execute( self, name: str, prompt: str, model: str = "", **kwargs, ) -> ToolResult: from ..agents import tasks as agent_store from ..agents.runner import agent_runner resolved_model = model or self._parent_model try: # Create sub-agent in DB sub = agent_store.create_agent( name=name, prompt=prompt, model=resolved_model, parent_agent_id=self._parent_agent_id, created_by=self._parent_agent_id, enabled=True, ) sub_id = sub["id"] # Run it now and wait for completion run = await agent_runner.run_agent_now(sub_id) run_id = run["id"] # Wait for the asyncio task to finish (run_agent_now creates the task) import asyncio task = agent_runner._running.get(run_id) if task: await task # Fetch final run record final = agent_store.get_run(run_id) if not final: return ToolResult(success=False, error="Sub-agent run record not found") return ToolResult( success=final["status"] == "success", data={ "run_id": run_id, "agent_id": sub_id, "status": final["status"], "result": final.get("result") or "", "input_tokens": final.get("input_tokens", 0), "output_tokens": final.get("output_tokens", 0), }, error=final.get("error") if final["status"] != "success" else None, ) except Exception as e: logger.error(f"[subagent] Error running sub-agent: {e}") return ToolResult(success=False, error=f"Sub-agent error: {e}")