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:
host committed 2026-10-30 02:45:51 +08:00
1 parent 276d433da6
commit 92b7f8e8ff
4 files changed
+71 -6

No files matched your search

+12
View File
@@ -39,6 +39,16 @@ MAX_STDOUT_CHARS = 2000
# 状态 / usage / 标记块仍从完整 stdout 解析,不受此截断影响。
MAX_RESULT_CHARS = 20000
_RESULT_TRUNCATED_MARKER = "\n\n[结果已截断:原文超 20000 字,仅显示前 20000 字]"
# 完整结果存库上限:20000 字摘要之外,完整版另存
# result_text_full,上限 200000 字只防无界增长,不作正常截断。
MAX_FULL_STDOUT_CHARS = 200000
def _full_stdout(text):
if text is None:
return ""
text = str(text)
return text[:MAX_FULL_STDOUT_CHARS] if len(text) > MAX_FULL_STDOUT_CHARS else text
# 启动前分段日志(2026-10-29 任务 A):docker run 是阻塞调用,
# 容器输出要等返回才回传,中途卡死时 worker 侧没有任何标记;
@@ -435,6 +445,7 @@ class LocalExecutor(Executor):
"task_id": task_id,
"status": status,
"stdout": stdout,
"stdout_full": _full_stdout(stdout_full),
"returncode": returncode,
"host_status": host_status,
# host.py 的 RuntimeError(如“任务已存在”)走 traceback 到
@@ -1835,6 +1846,7 @@ def _parse_host_result(task_id, fake):
"task_id": task_id,
"status": status,
"stdout": stdout,
"stdout_full": _full_stdout(stdout_full),
"returncode": returncode,
"host_status": host_status,
"stderr": _truncate_stdout(getattr(fake, "stderr", "")),