在 Linux/WSL2 上,Terminal.run_command() 无限循环 — 命令结束标记从 splitlines/tuple-unpack 中从未返回
页:1
`metagpt.tools.libs.terminal.terminal.terminal.run command ()'在Linux/WSL2上无限期地挂起,只要永久外壳的stdout以命令末端标记为最后一行(即在正常条件下总是).
在QQread and process output中读取的回路使用QQ行,tmp = 输出.splitlines(True)",但当缓冲器中完全包含一个QQn"已终止行后,tuple-unpacking idom会将最后一行移动到"tmp"而不会产生它——所以标记检查永远不会起火,循环等待下一个字节永远不会到来.
由于每个“工程师2. think()”的电话都从“等待自定义.terminal.run command("pwd")”开始,这个错误在任何LLM的电话发出之前使整个工程师/DataAnalyst/LocationZero代理商沉默地陷入僵局。 用户看到"什么都没有发生",最终是Ctrl-C的——没有出错的消息.
- 复制步骤
任意 Linux 或 WSL2 主机, 当前“ 主要 ” :
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? 管道安装 -e. 赞美,赞美,赞美 导入 Ayncio 从 metagpt.tools.libs.terminal 导入终端
async def 主线( ): t = 终端 () 出 = 等待 ayncio.wait for(t.run command ("pwd"),超时=10 打印 (“ 获得 ” ), repr( 出)
ayncio.run(主要()) PY 时
预期:在秒下打印工作空间路径。
实际:悬挂10s,"Ayncio". 超时 Error.
主持“创造问候世界的CLI”活动,在小组组长派到Alex(工程师)的代表看到“Alex(工程师)观察:[......]”之后,就显示出同样的绞刑。
根原因
`metagpt/tools/libs/terminal.py: read and process output',当前主要:
[Python]
tmp = b" (中文(简体) ).
此时为 True :
输出 = tmp + 等待自. process.stdout. read(1)
如果不是输出 :
继续
*行,tmp = 输出.splitlines (True) # -- BUG
用于行中的行 :
... 请检查end MARKER VALUE
最小Python 解包演示:
\\ b"\ x18\ x19\ x1b\ x18\n". splitlines( True).
[b'\x18\x19\x1b\x18\n] (中文(简体) ).
* *行,tmp= [b'\x18\x19\x1b\x18\n']
线条
[
时间
b'\x18\x19\x1b\x18\n'
在一个``\n'终止的缓冲中,splitlines(True)'返回一个 1 元素列表。 拆开后将元素放入"tmp"并留下"行"空出,因此标记线从未被检查. 下一个读取(1) ' 的屏障永远存在,因为一击就释放出一切并等待着被打倒。
实际触发它的确切字节序列: 工作空间路径 + \n" + \x18\x19\x1b\x18\n" ("END MARKER VALUE"). 字节累积通常产生工作空间线(在XX18`将其推出'tmp'之后),但最后的标记线是溪流中的最后一点,在结束的QQn上仍被"tmp"所困.
建议改正
将后端- 新线缓冲器视为完整, 而不是将其藏回“ tmp” :
拆分 = 输出. splitlines( True)
如果拆分和拆分 [-1]. ends with (((b"\n", b"\r")):
线条 = 拆分
tmp = b" (中文(简体) ).
其他情况:
*行,tmp=拆分
本地补丁此并证实“ 创建一个 Python CLI ” . . . . . . .
内容来源: FoundationAgents/MetaGPT