Oh My Pi v16.1.10 发布 —— JSON 解析器自研重写,流式输出丢失和 WebSocket 串帧全修了

自研 JSON 解析器:RelaxedJson 替换 partial-json
之前 pi-ai 用 partial-json 处理 LLM 返回的 JSON。问题是 LLM 输出的 JSON 几乎没有严格按照规范写过——单引号字符串、尾随逗号、Python 的 True/False/None、行内和块注释、原始控制字符、无效的 escape 序列,哪个模型都能偶尔吐一点。partial-json 处理不了就抛异常,用户除了重试别无选择。
v16.1.10 用自研的 RelaxedJson 完全替换了 partial-json。新解析器接受单引号字符串、未加引号的 object key、尾随和多余逗号、// 和 /* */ 注释、Python 布尔和 None 字面量、原始控制字符、无效 escape 和未转义的单引号——几乎覆盖了 LLM 会输出的所有 JSON 变体。最终解析仍在截断或乱码输入上正确报错,也拒绝 JS 独有的 NaN/Infinity。一句话:只要 LLM 吐的是人能看懂的东西,RelaxedJson 就能吃进去。partial-json 依赖已从项目中移除。
Tool-call ID 修复链——Anthropic 模型的工具调用 ID 规范化、Anthropic Messages 回放中工具调用 ID 的清洗、以及 transformMessages 把孤立工具结果拉到重用 ID 上的问题。三个修复贯穿了同一根根因:ID 的生成、传递和清洗链路上各有各的位置瑕疵,现在全链路对齐了。
Codex WebSocket 串帧:回连不再张冠李戴
Codex Responses WebSocket transport 藏了一个烦人的 bug:当你复用 WebSocket 连接发出新一轮请求时,服务端返回的数据帧可能被错误地分配到上一轮的输出里。终端上看到的就是"输出串了"——明明是新 prompt 的回答,显示的却是前一个问题的尾巴。
根因在于 WebSocket 连接上消息帧的归属判断逻辑不够严谨,复用连接时上下文切换标记丢失。修复后每一帧输出都能正确关联到当前轮的请求,连接复用不再是风险。
pi-coding-agent:ARIA 工具上线,write 和 find 不再隐身
编码 agent 包在这个版本拿到了两个新能力。
tab.ariaSnapshot(selector?) 按 Playwright 格式输出 ARIA 树 YAML——做浏览器自动化的场景下,你可以直接拿到页面的无障碍结构树,比翻 DOM 更直观。配合新增的 tab.ref("e5") 和 aria-ref=e5 选择器,实现了基于 ARIA 引用的快速元素定位。写自动化脚本时不用再抠 CSS 选择器,标一个 ref 就能精准命中。
还有一个重要的行为变更:write 和 find 工具现在被标记为 essential,在 tools.discoveryMode === "all" 模式下不会被过滤掉。之前有些场景下这两个工具在发现模式中凭空消失,agent 想写文件却找不到 write 工具,现在这个问题不存在了。流式工具调用预览在工具完成后卡在占位符 body 上的问题也已修复。
pi-tui:流式输出不再消失在滚动缓冲区
pi-tui 的终端输出有一个隐蔽的 bug:当内容溢出视口后,commit-unstable "barrier" 区块之下的流式输出会被原生滚动缓冲区吞掉。你看到的景象是——能往回滚动看到之前的历史内容,但最新输出的"尾巴"凭空消失了。
修复后的行为:所有流式输出都正确保留在原生滚动缓冲区中,无论视口是否溢出、无论 barrier 块的位置在哪。对于重度终端用户来说,这是一个显著改善体验的修复——终于可以在 TUI 里放心滚回去查之前的输出了。
agent-core:Label 中断不再留下残损工具调用
Labelled user interrupts(带标签的用户中断)在触发时有一个边缘情况:如果当前正在流式接收工具调用,而流尚未发送 toolcall_end 标记,中断后的回放会残留一段不完整的工具调用 ID。这些残损 ID 在重放时导致匹配失败或解析异常。
修复逻辑很直接——中断发生时清除未完成的流式工具调用段,确保进入回放状态时所有工具调用都是完整可用的。
分级与细节修复
• DashScope 429 限流分类修复:之前阿里云 DashScope 返回 429 限流错误时,被归类为凭据失败,导致客户端误认为 API Key 无效而将其标记为失效。现在 429 被正确识别为限流,不会触发 Key 失效逻辑。
• OpenCode Go 401 配额错误分类修复:OpenCode Go 返回的 401 Insufficient balance 之前被当作未知错误处理。现在归类为 usage-limit 错误,余额不足时会触发合理的重试或降级策略。
升级方式
curl -fsSL https://omp.sh/install | sh # macOS/Linux
npm install -g @oh-my-pi/pi-coding-agent # or bun install -g @oh-my-pi/pi-coding-agent
brew install can1357/tap/omp # Homebrew
📢 关注我,获取最新开源更新日志和开发者工具动态。
#OhMyPi #版本更新 #AI写代码的小任 #LLM更新报告