49 lines
2.0 KiB
Python
49 lines
2.0 KiB
Python
"""工具输出处理原语(从 tools/base.py 析出,2026-07-23——base 只留 Tool 基类与路径边界)。"""
|
|
from __future__ import annotations
|
|
|
|
|
|
def compact_tool_output(
|
|
text: str,
|
|
*,
|
|
max_chars: int = 8_000,
|
|
head_chars: int = 4_000,
|
|
tail_chars: int = 2_000,
|
|
) -> str:
|
|
"""压缩长工具输出,保留头尾和截断说明。"""
|
|
if len(text) <= max_chars:
|
|
return text
|
|
head_chars = max(0, min(head_chars, max_chars))
|
|
tail_chars = max(0, min(tail_chars, max_chars - head_chars))
|
|
removed = len(text) - head_chars - tail_chars
|
|
return (
|
|
text[:head_chars]
|
|
+ f"\n[... truncated, {removed} chars omitted ...]\n"
|
|
+ (text[-tail_chars:] if tail_chars else "")
|
|
)
|
|
|
|
|
|
_TIMEOUT_HINT = (
|
|
"若是批量循环(检索 / PDF 抽取 / 下载等):① 据上面已完成的部分**续跑剩下的**,别整批重跑;"
|
|
"② 每完成一项就落盘 / 打印进度,超时也不丢;③ 大批量 / 大下载改用 background=true 后台跑,"
|
|
"再用 check_process 取结果;④ 单次别塞太多项。"
|
|
)
|
|
|
|
|
|
def format_timeout_result(stdout: str, stderr: str, timeout_s: int) -> str:
|
|
"""run_python / shell 超时结果:带上超时前已捕获的部分输出 + 续跑提示。
|
|
|
|
进程被 kill 前跑出的 stdout/stderr 本已捕获(subprocess 标准行为:TimeoutExpired
|
|
带 .stdout/.stderr、docker 路径 kill 后 communicate() 续读),旧实现直接丢弃只回一句
|
|
超时 → 模型看不到「跑到哪了」、整批重来(工具失败面板 #8:批量检索 / PDF 抽取 / 下载
|
|
超时反复重跑,累计最多)。这里把部分输出一并返回,让模型据此续跑未完成的。"""
|
|
parts = []
|
|
if stdout and stdout.strip():
|
|
parts.append(f"[stdout]\n{stdout.rstrip()}")
|
|
if stderr and stderr.strip():
|
|
parts.append(f"[stderr]\n{stderr.rstrip()}")
|
|
parts.append(
|
|
f"[Error] command timed out after {timeout_s}s(进程已被杀,上方为超时前的部分输出)。"
|
|
)
|
|
parts.append(_TIMEOUT_HINT)
|
|
return "\n".join(parts)
|