feat: 文档/图片工具进任务镜像 + 结果截断从截断 JSON 改为提取 text 上限 20000 字
This commit is contained in:
1 parent
9ac0199eba
commit
c1d25d11b1
4 files changed
+93
-13
No files matched your search
+38
-5
@@ -30,6 +30,15 @@ from cloud.marker_tools import extract_wait_threads as _extract_wait_threads
|
||||
from cloud.peer_messages import extract_peer_messages as _extract_peer_messages
|
||||
|
||||
MAX_STDOUT_CHARS = 2000
|
||||
# 任务结果文本上限:2000 字截断的是 host.py 打印的整段 JSON,
|
||||
# text 超过 2000 字时 JSON 本身被截断,worker 再解析 stdout
|
||||
# 取 text 必然失败,存库的就变成截断的 JSON(2026-10-30
|
||||
# 生产审计任务 dbe0c39f… 正是这样在 "PI" 处断掉)。修法:
|
||||
# 解析出的 text(或非 JSON 的原文本)单独截到 20000 字,
|
||||
# 超限时带截断标记,绝不把截断的 JSON 当结果存库。
|
||||
# 状态 / usage / 标记块仍从完整 stdout 解析,不受此截断影响。
|
||||
MAX_RESULT_CHARS = 20000
|
||||
_RESULT_TRUNCATED_MARKER = "\n\n[结果已截断:原文超 20000 字,仅显示前 20000 字]"
|
||||
|
||||
# 启动前分段日志(2026-10-29 任务 A):docker run 是阻塞调用,
|
||||
# 容器输出要等返回才回传,中途卡死时 worker 侧没有任何标记;
|
||||
@@ -223,6 +232,21 @@ def _truncate_stdout(text):
|
||||
return str(text)[:MAX_STDOUT_CHARS]
|
||||
|
||||
|
||||
def _result_text(parsed, stdout_full):
|
||||
"""执行结果存库用的文本:优先取 host.py JSON 的 text 字段,
|
||||
取不到时用原文本;截到 MAX_RESULT_CHARS,超限带截断标记。
|
||||
调用方必须在解析出 parsed 后再调本函数,绝不能先截断
|
||||
stdout 再解析 JSON(截断的 JSON 解析失败,text 全丢)。
|
||||
"""
|
||||
if isinstance(parsed, dict) and parsed.get("text"):
|
||||
text = str(parsed["text"])
|
||||
else:
|
||||
text = str(stdout_full or "")
|
||||
if len(text) > MAX_RESULT_CHARS:
|
||||
return text[:MAX_RESULT_CHARS] + _RESULT_TRUNCATED_MARKER
|
||||
return text
|
||||
|
||||
|
||||
def _default_runner(cmd, env=None):
|
||||
"""subprocess.run 的薄封装:捕获输出、文本模式。
|
||||
|
||||
@@ -353,7 +377,6 @@ class LocalExecutor(Executor):
|
||||
"""
|
||||
returncode = getattr(result, "returncode", 1)
|
||||
stdout_full = getattr(result, "stdout", "") or ""
|
||||
stdout = _truncate_stdout(stdout_full)
|
||||
status = "failed"
|
||||
usage = None
|
||||
task_messages = []
|
||||
@@ -364,12 +387,14 @@ class LocalExecutor(Executor):
|
||||
task_retries = []
|
||||
turn_id = None
|
||||
root_turn_id = None
|
||||
parsed = None
|
||||
if returncode == 0:
|
||||
status = "completed"
|
||||
# JSON 解析必须用完整 stdout:截头后的前 2000 字在
|
||||
# text 很长时根本不是合法 JSON,旧代码会把 host 的
|
||||
# failed 误判成 completed;usage 在 JSON 末尾,截头
|
||||
# 后同样丢。存库的 stdout 仍用截头版,不变。
|
||||
# 后同样丢。存库的 stdout 是解析出的 text(见
|
||||
# _result_text),不再是截断的 JSON。
|
||||
try:
|
||||
parsed = json.loads(stdout_full)
|
||||
except (TypeError, ValueError):
|
||||
@@ -404,6 +429,7 @@ class LocalExecutor(Executor):
|
||||
host_status = None
|
||||
else:
|
||||
host_status = None
|
||||
stdout = _result_text(parsed, stdout_full)
|
||||
return {
|
||||
"executor": "local",
|
||||
"task_id": task_id,
|
||||
@@ -796,7 +822,12 @@ class LocalExecutor(Executor):
|
||||
raise ValueError("任务缺少 id")
|
||||
result = self.runner(self._command(task_id))
|
||||
returncode = getattr(result, "returncode", 1)
|
||||
stdout = _truncate_stdout(getattr(result, "stdout", ""))
|
||||
stdout_full = getattr(result, "stdout", "") or ""
|
||||
try:
|
||||
parsed = json.loads(stdout_full)
|
||||
except (TypeError, ValueError):
|
||||
parsed = None
|
||||
stdout = _result_text(parsed, stdout_full)
|
||||
return {
|
||||
"executor": "local",
|
||||
"task_id": task_id,
|
||||
@@ -1758,7 +1789,6 @@ def _parse_host_result(task_id, fake):
|
||||
"""
|
||||
returncode = getattr(fake, "returncode", 1)
|
||||
stdout_full = getattr(fake, "stdout", "") or ""
|
||||
stdout = _truncate_stdout(stdout_full)
|
||||
status = "failed"
|
||||
host_status = None
|
||||
usage = None
|
||||
@@ -1770,12 +1800,14 @@ def _parse_host_result(task_id, fake):
|
||||
task_retries = []
|
||||
turn_id = None
|
||||
root_turn_id = None
|
||||
parsed = None
|
||||
if returncode == 0:
|
||||
status = "completed"
|
||||
# 与 _result_from_runner 同理:JSON 解析用完整 stdout,
|
||||
# 否则长 text 会把 host 的 failed 误判成 completed,
|
||||
# 也会丢掉 JSON 末尾的 usage。标记块同样从完整解析
|
||||
# 出的 text 里提取。
|
||||
# 出的 text 里提取。存库的 stdout 是解析出的 text,
|
||||
# 不再是截断的 JSON(见 _result_text)。
|
||||
try:
|
||||
parsed = json.loads(stdout_full)
|
||||
except (TypeError, ValueError):
|
||||
@@ -1797,6 +1829,7 @@ def _parse_host_result(task_id, fake):
|
||||
# 时保持 None,worker 写回时不覆盖旧值。
|
||||
turn_id = parsed.get("turn_id")
|
||||
root_turn_id = parsed.get("root_turn_id")
|
||||
stdout = _result_text(parsed, stdout_full)
|
||||
return {
|
||||
"executor": "docker",
|
||||
"task_id": task_id,
|
||||
|
||||
Reference in new issue
Block a user