feat: 命令台子代理链路(主任务/模型子代理/委派子任务 + 过程调用实时同步)
host:链路条目带 thread 归属;delegate 向父链路文件写 agent-start/done 标记。服务端:GET /tasks/{id}/agents 聚合父链路 + 子链路文件成代理链(状态口径:委派以结束标记为准、无标记即进行中;模型子代理无结束信号时父任务运行中为进行中、否则未知)。命令台:新增子代理链路区,随 SSE 流防抖刷新;扁平链路也渲染 agent 标记。
This commit is contained in:
1 parent
34cd0eeba7
commit
c4d3ec9bff
6 files changed
+366
-14
No files matched your search
@@ -6,6 +6,7 @@
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
@@ -130,6 +131,48 @@ class TraceFileTestCase(unittest.TestCase):
|
||||
self.assertEqual(len(lines), 1)
|
||||
self.assertEqual(json.loads(lines[0])["id"], "c1")
|
||||
|
||||
def test_summarize_carries_thread(self):
|
||||
# 模型内子代理与主任务同文件时,服务端凭 thread 归属条目。
|
||||
entries = _summarize_trace_item(
|
||||
"item/completed",
|
||||
{"item": {"type": "commandExecution", "id": "c1",
|
||||
"command": "ls"},
|
||||
"threadId": "th-sub", "completedAtMs": 1700000000000})
|
||||
self.assertEqual(entries[0]["thread"], "th-sub")
|
||||
entries = _summarize_trace_item(
|
||||
"item/completed",
|
||||
{"item": {"type": "commandExecution", "id": "c2",
|
||||
"command": "ls"},
|
||||
"completedAtMs": 1700000000000})
|
||||
self.assertIsNone(entries[0]["thread"])
|
||||
|
||||
def test_append_trace_marker_to_parent_file(self):
|
||||
# delegate 向父链路报到:路径清洗与 set_trace_file 一致,
|
||||
# 写失败不抛(尽力而为,不影响回合)。
|
||||
from host import _append_trace_marker, _trace_file_path
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
state_path = os.path.join(d, "host-state.json")
|
||||
self.assertEqual(
|
||||
_trace_file_path(state_path, "abc/def?id=1"),
|
||||
os.path.join(d, "host-traces", "abc-def-id-1.jsonl"))
|
||||
_append_trace_marker(
|
||||
state_path, "parent task!",
|
||||
{"kind": "agent-start", "id": "agent:rev",
|
||||
"name": "rev", "prompt": "review"})
|
||||
path = os.path.join(d, "host-traces", "parent-task-.jsonl")
|
||||
with open(path, encoding="utf-8") as f:
|
||||
entry = json.loads(f.read().strip())
|
||||
self.assertEqual(entry["kind"], "agent-start")
|
||||
self.assertEqual(entry["name"], "rev")
|
||||
# 目录被文件占住时也不抛。
|
||||
blocker = os.path.join(d, "host-traces")
|
||||
shutil.rmtree(blocker)
|
||||
with open(blocker, "w", encoding="utf-8") as f:
|
||||
f.write("x")
|
||||
_append_trace_marker(state_path, "parent task!",
|
||||
{"kind": "agent-done", "id": "agent:rev:done",
|
||||
"name": "rev", "status": "completed"})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user