feat(tasks): 完整结果另存 result_text_full,详情不再只剩 2000 字
旧链路三层截断:sandbox stdout 截 2000 字、worker 写回截
4000 字,长答案尾部在详情里永远查不到(只把上限调大是
把截断点后移,不是修掉)。修法:截断版保持不变(列表/
摘要用),完整版另存:
- sandbox _result_from_runner/_parse_host_result(local 与
docker dispatch 路)回包新增 stdout_full(上限 200000 字,
只防无界增长);goal 路结论在尾部、tail 已保结论,不动。
- worker _write_execution_result 新增 result_text_full 列
(_ensure_result_columns + server migrate_tasks_table 幂等
补列),终局与取消分支均透传 stdout_full。
- server:任务 dict 加 result_full_available(不直接塞全文
进列表负载),新增 GET /tasks/{id}/result-full(read 权限
同款校验,无完整版时 404,不回摘要冒充完整)。
单测:test_queue_sandbox 45 项(含新增 stdout_full 1 项)、
test_marker_tools 30 项。
This commit is contained in:
1 parent
276d433da6
commit
92b7f8e8ff
4 files changed
+71
-6
No files matched your search
@@ -1104,6 +1104,7 @@ def migrate_tasks_table(conn):
|
||||
"PRAGMA table_info(tasks)").fetchall()}
|
||||
new_cols = {
|
||||
"result_text": "TEXT",
|
||||
"result_text_full": "TEXT",
|
||||
"error_text": "TEXT",
|
||||
"actual_model": "TEXT",
|
||||
"started_at": "REAL",
|
||||
@@ -1748,6 +1749,7 @@ def _task_to_dict(row, attachments=None, total_tokens=None):
|
||||
"updated_at": row["updated_at"],
|
||||
"last_heartbeat": row["last_heartbeat"],
|
||||
"result_text": _row_get(row, "result_text"),
|
||||
"result_full_available": bool(_row_get(row, "result_text_full")),
|
||||
"error_text": _row_get(row, "error_text"),
|
||||
"actual_model": _row_get(row, "actual_model"),
|
||||
"started_at": _row_get(row, "started_at"),
|
||||
@@ -2277,6 +2279,9 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
user_id, rest[: -len("/trace/stream")])
|
||||
elif rest.endswith("/trace") and method == "GET":
|
||||
self._task_trace(user_id, rest[: -len("/trace")])
|
||||
elif rest.endswith("/result-full") and method == "GET":
|
||||
self._task_result_full(user_id,
|
||||
rest[: -len("/result-full")])
|
||||
elif rest.endswith("/agents") and method == "GET":
|
||||
self._task_agents(user_id, rest[: -len("/agents")])
|
||||
elif rest.endswith("/cancel") and method == "POST":
|
||||
@@ -4626,6 +4631,28 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
|
||||
for d in _trace_dirs_for_task(self.server, task)]
|
||||
return _read_trace_entries_multi(paths), ""
|
||||
|
||||
def _task_result_full(self, user_id, task_id):
|
||||
"""完整结果端点:result_text 仍是 4000 字摘要,完整版
|
||||
在 result_text_full 里;无完整版时 404(老任务、goal
|
||||
任务、或本轮没拿到 stdout_full 的任务),不回摘要
|
||||
冒充完整。权限与 _get_task 同款 read 校验。"""
|
||||
row = self._fetch_task(task_id)
|
||||
if row is None:
|
||||
self._send_json(404, {"error": "task not found"})
|
||||
return
|
||||
task = _task_to_dict(row)
|
||||
with _auth_store(self.server.db_path) as store:
|
||||
if not store.check_permission(user_id, task["project_id"], "read"):
|
||||
self._send_json(403, {"error": "forbidden"})
|
||||
return
|
||||
full = _row_get(row, "result_text_full")
|
||||
if not full:
|
||||
self._send_json(404, {"error": "result full not available"})
|
||||
return
|
||||
self._send_json(200, {"task_id": task_id,
|
||||
"status": task["status"],
|
||||
"result_text_full": full})
|
||||
|
||||
def _task_trace(self, user_id, task_id):
|
||||
row = self._fetch_task(task_id)
|
||||
if row is None:
|
||||
|
||||
Reference in new issue
Block a user