|
|
@@ -276,6 +276,48 @@ def _build_evaluate_prompt(goal_description: str, messages: Optional[Messages])
|
|
|
return "\n".join(lines)
|
|
|
|
|
|
|
|
|
+def _make_event_printer(label: str):
|
|
|
+ """
|
|
|
+ 创建子 Agent 执行过程打印函数。
|
|
|
+
|
|
|
+ 当父 runner.debug=True 时,传给 run_result(on_event=...),
|
|
|
+ 实时输出子 Agent 的工具调用和助手消息。
|
|
|
+ """
|
|
|
+ prefix = f" [{label}]"
|
|
|
+
|
|
|
+ def on_event(item):
|
|
|
+ from agent.trace.models import Trace, Message
|
|
|
+ if isinstance(item, Message):
|
|
|
+ if item.role == "assistant":
|
|
|
+ content = item.content
|
|
|
+ if isinstance(content, dict):
|
|
|
+ text = content.get("text", "")
|
|
|
+ tool_calls = content.get("tool_calls")
|
|
|
+ if text:
|
|
|
+ preview = text[:120] + "..." if len(text) > 120 else text
|
|
|
+ print(f"{prefix} {preview}")
|
|
|
+ if tool_calls:
|
|
|
+ for tc in tool_calls:
|
|
|
+ name = tc.get("function", {}).get("name", "unknown")
|
|
|
+ print(f"{prefix} 🛠️ {name}")
|
|
|
+ elif item.role == "tool":
|
|
|
+ content = item.content
|
|
|
+ if isinstance(content, dict):
|
|
|
+ name = content.get("tool_name", "unknown")
|
|
|
+ desc = item.description or ""
|
|
|
+ desc_short = (desc[:60] + "...") if len(desc) > 60 else desc
|
|
|
+ suffix = f": {desc_short}" if desc_short else ""
|
|
|
+ print(f"{prefix} ✅ {name}{suffix}")
|
|
|
+ elif isinstance(item, Trace):
|
|
|
+ if item.status == "completed":
|
|
|
+ print(f"{prefix} ✓ 完成")
|
|
|
+ elif item.status == "failed":
|
|
|
+ err = (item.error_message or "")[:80]
|
|
|
+ print(f"{prefix} ✗ 失败: {err}")
|
|
|
+
|
|
|
+ return on_event
|
|
|
+
|
|
|
+
|
|
|
# ===== 统一内部执行函数 =====
|
|
|
|
|
|
async def _run_agents(
|
|
|
@@ -283,6 +325,8 @@ async def _run_agents(
|
|
|
per_agent_msgs: List[Messages],
|
|
|
continue_from: Optional[str],
|
|
|
store, trace_id: str, goal_id: str, runner, context: dict,
|
|
|
+ agent_type: Optional[str] = None,
|
|
|
+ skills: Optional[List[str]] = None,
|
|
|
) -> Dict[str, Any]:
|
|
|
"""
|
|
|
统一 agent 执行逻辑。
|
|
|
@@ -317,7 +361,7 @@ async def _run_agents(
|
|
|
# continue_from 已经设置了 sub_trace_id
|
|
|
pass
|
|
|
else:
|
|
|
- agent_type = "delegate" if single else "explore"
|
|
|
+ resolved_agent_type = agent_type or ("delegate" if single else "explore")
|
|
|
suffix = "delegate" if single else f"explore-{i+1:03d}"
|
|
|
stid = generate_sub_trace_id(trace_id, suffix)
|
|
|
|
|
|
@@ -327,7 +371,7 @@ async def _run_agents(
|
|
|
task=task_item,
|
|
|
parent_trace_id=trace_id,
|
|
|
parent_goal_id=goal_id,
|
|
|
- agent_type=agent_type,
|
|
|
+ agent_type=resolved_agent_type,
|
|
|
uid=parent_trace.uid if parent_trace else None,
|
|
|
model=parent_trace.model if parent_trace else None,
|
|
|
status="running",
|
|
|
@@ -342,7 +386,7 @@ async def _run_agents(
|
|
|
# 广播 sub_trace_started
|
|
|
await broadcast_sub_trace_started(
|
|
|
trace_id, stid, goal_id or "",
|
|
|
- agent_type, task_item,
|
|
|
+ resolved_agent_type, task_item,
|
|
|
)
|
|
|
|
|
|
if single:
|
|
|
@@ -363,16 +407,22 @@ async def _run_agents(
|
|
|
agent_msgs = list(msgs) + [{"role": "user", "content": task_item}]
|
|
|
allowed_tools = _get_allowed_tools(single, context)
|
|
|
|
|
|
+ debug = getattr(runner, 'debug', False)
|
|
|
+ agent_label = (agent_type or ("delegate" if single else f"explore-{i+1}"))
|
|
|
+ on_event = _make_event_printer(agent_label) if debug else None
|
|
|
+
|
|
|
coro = runner.run_result(
|
|
|
messages=agent_msgs,
|
|
|
config=_make_run_config(
|
|
|
trace_id=cur_stid,
|
|
|
- agent_type="delegate" if single else "explore",
|
|
|
+ agent_type=agent_type or ("delegate" if single else "explore"),
|
|
|
model=parent_trace.model if parent_trace else "gpt-4o",
|
|
|
uid=parent_trace.uid if parent_trace else None,
|
|
|
tools=allowed_tools,
|
|
|
name=task_item[:50],
|
|
|
+ skills=skills,
|
|
|
),
|
|
|
+ on_event=on_event,
|
|
|
)
|
|
|
coros.append((i, cur_stid, collab_name, coro))
|
|
|
|
|
|
@@ -492,6 +542,8 @@ async def agent(
|
|
|
task: Union[str, List[str]],
|
|
|
messages: Optional[Union[Messages, List[Messages]]] = None,
|
|
|
continue_from: Optional[str] = None,
|
|
|
+ agent_type: Optional[str] = None,
|
|
|
+ skills: Optional[List[str]] = None,
|
|
|
context: Optional[dict] = None,
|
|
|
) -> Dict[str, Any]:
|
|
|
"""
|
|
|
@@ -504,6 +556,8 @@ async def agent(
|
|
|
task: 任务描述。字符串=单任务,列表=多任务并行
|
|
|
messages: 预置消息。1D 列表=所有 agent 共享;2D 列表=per-agent
|
|
|
continue_from: 继续已有 trace(仅单任务)
|
|
|
+ agent_type: 子 Agent 类型,决定 preset 和默认 skills(如 "deconstruct")
|
|
|
+ skills: 附加到 system prompt 的 skill 名称列表,覆盖 preset 默认值
|
|
|
context: 框架自动注入的上下文
|
|
|
"""
|
|
|
if not context:
|
|
|
@@ -545,6 +599,8 @@ async def agent(
|
|
|
return await _run_agents(
|
|
|
tasks, per_agent_msgs, continue_from,
|
|
|
store, trace_id, goal_id, runner, context,
|
|
|
+ agent_type=agent_type,
|
|
|
+ skills=skills,
|
|
|
)
|
|
|
|
|
|
|
|
|
@@ -655,6 +711,7 @@ async def evaluate(
|
|
|
tools=allowed_tools,
|
|
|
name=f"评估: {goal_id}",
|
|
|
),
|
|
|
+ on_event=_make_event_printer("evaluate") if getattr(runner, 'debug', False) else None,
|
|
|
)
|
|
|
|
|
|
await broadcast_sub_trace_completed(
|