|
|
@@ -1,8 +1,8 @@
|
|
|
"""
|
|
|
-Trace 控制 API — 新建 / 运行 / 停止 / 反思
|
|
|
+Trace 控制 API:新建、续跑、回溯、停止与反思。
|
|
|
|
|
|
-提供 POST 端点触发 Agent 执行和控制。需要通过 set_runner() 注入 AgentRunner 实例。
|
|
|
-执行在后台异步进行,客户端通过 WebSocket (/api/traces/{trace_id}/watch) 监听实时更新。
|
|
|
+路由将请求转为 RunConfig 并在后台驱动 AgentRunner,客户端通过 WebSocket 读取事件。
|
|
|
+Recursive 的根完成标准和子树停止也在这一 API 边界传递给实际 Runner。
|
|
|
|
|
|
端点:
|
|
|
POST /api/traces — 新建 Trace 并执行
|
|
|
@@ -164,6 +164,8 @@ class CommitResponse(BaseModel):
|
|
|
# ===== 后台执行 =====
|
|
|
|
|
|
_running_tasks: Dict[str, asyncio.Task] = {}
|
|
|
+# 记住每个运行中 Trace 真正使用的 Runner,避免 Example 专属 Runner 的续跑/停止误落到全局 Runner。
|
|
|
+# 映射只覆盖当前进程活跃任务,由两个后台执行入口按对象身份清理。
|
|
|
_running_runners: Dict[str, Any] = {}
|
|
|
|
|
|
|
|
|
@@ -182,7 +184,9 @@ async def _cancel_and_wait_for_running_task(trace_id: str) -> None:
|
|
|
|
|
|
|
|
|
async def _run_in_background(trace_id: str, messages: List[Dict], config, runner_instance=None):
|
|
|
- """后台执行 agent,消费 run() 的所有 yield"""
|
|
|
+ """后台执行已知 Trace ID 的 Agent,消费 run() 的所有 yield。
|
|
|
+
|
|
|
+ run_trace() 续跑/回溯时调用,并登记实际 Runner 供 stop_trace() 命中 Recursive 子树。"""
|
|
|
runner = runner_instance or _get_runner()
|
|
|
current_task = asyncio.current_task()
|
|
|
if current_task:
|
|
|
@@ -203,7 +207,9 @@ async def _run_in_background(trace_id: str, messages: List[Dict], config, runner
|
|
|
async def _run_with_trace_signal(
|
|
|
messages: List[Dict], config, trace_id_future: asyncio.Future, runner_instance=None
|
|
|
):
|
|
|
- """后台执行 agent,通过 Future 将 trace_id 传回给等待的 endpoint"""
|
|
|
+ """后台新建 Agent,通过 Future 将首个 Trace 对象的 ID 传回 API。
|
|
|
+
|
|
|
+ create_and_run() 调用它,同时登记实际 Runner,使后续停止不会丢失 Example 专属运行环境。"""
|
|
|
from cyber_agent.trace.models import Trace
|
|
|
|
|
|
runner = runner_instance or _get_runner()
|
|
|
@@ -235,10 +241,9 @@ async def _run_with_trace_signal(
|
|
|
@router.post("", response_model=RunResponse)
|
|
|
async def create_and_run(req: CreateRequest):
|
|
|
"""
|
|
|
- 新建 Trace 并开始执行
|
|
|
+ 新建 Trace 并开始执行,将 HTTP 参数和 Example 默认值合并为 RunConfig。
|
|
|
|
|
|
- 立即返回 trace_id,后台异步执行。
|
|
|
- 通过 WebSocket /api/traces/{trace_id}/watch 监听实时更新。
|
|
|
+ Recursive 的 root_completion_criteria 从此传入 Runner 完成门禁;获取 trace_id 后立即返回,执行继续留在后台。
|
|
|
"""
|
|
|
import importlib
|
|
|
from cyber_agent.core.runner import RunConfig
|
|
|
@@ -411,7 +416,9 @@ def _parse_sequence_from_message_id(message_id: str) -> int:
|
|
|
@router.post("/{trace_id}/run", response_model=RunResponse)
|
|
|
async def run_trace(trace_id: str, req: TraceRunRequest):
|
|
|
"""
|
|
|
- 运行已有 Trace(统一续跑 + 回溯)
|
|
|
+ 运行已有 Trace,统一处理续跑与回溯。
|
|
|
+
|
|
|
+ 它优先取活跃 Trace 实际 Runner,再由 AgentRunner 恢复持久化的 Legacy/Recursive 模式和协议状态。
|
|
|
|
|
|
- after_message_id 为 null(或省略):从末尾续跑
|
|
|
- after_message_id 为 message_id 字符串:从该消息后运行(Runner 自动判断续跑/回溯)
|
|
|
@@ -512,10 +519,9 @@ async def run_trace(trace_id: str, req: TraceRunRequest):
|
|
|
@router.post("/{trace_id}/stop", response_model=StopResponse)
|
|
|
async def stop_trace(trace_id: str):
|
|
|
"""
|
|
|
- 停止运行中的 Trace
|
|
|
+ 向运行中 Trace 的实际 Runner 发送协作式停止信号。
|
|
|
|
|
|
- 设置取消信号,agent loop 在下一个 LLM 调用前检查并退出。
|
|
|
- Trace 状态置为 "stopped"。
|
|
|
+ Legacy 只停当前 Trace;Recursive 由 AgentRunner.stop() 向当前进程的活跃子孙传播。
|
|
|
"""
|
|
|
runner = _running_runners.get(trace_id) or _get_runner()
|
|
|
|