Files
oai-web/server/tools/subagent_tool.py
2026-04-08 12:43:24 +02:00

105 lines
3.4 KiB
Python

"""
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}")