oh-my-pi v15.11.2 发布 —— 12.5次/秒、串行、默认关闭:三个数字背后的进化
串行。这是之前 bash 工具在多步骤请求里的执行方式——同一个消息里的 5 个 bash 调用,必须等前一个跑完才轮到下一个。如果你的第一步是 sleep 5,剩下 4 个就干等着。
默认关闭。这是之前 async.enabled 的状态。异步任务不是一个选项,而是一个你需要在配置里主动打开的功能——很多人甚至不知道它的存在。
这三个数字,是 v15.11.1 和 v15.11.2 联合发布的隐藏注脚。它们不是 Release Notes 里最显眼的那几行,却最精确地描述了 oh-my-pi 在两个小版本中完成了什么样的进化。

渲染进化:从 12.5 次/秒到组件级隔离
如果你在 TUI 里跑过超过 30 分钟的会话,你应该经历过那种奇妙的卡顿——消息越来越多,终端越来越慢,但你分不清到底是模型在思考还是 UI 在拖后腿。你倾向于相信是后者。
以往的情况确实如此。TUI 的 loader tick 以 12.5 次/秒的频率触发全量 compose。每条新增消息、每个工具调用返回、甚至每帧加载动画,都会迫使整棵组件树从头 re-render 一遍。对话越长,开销越重。你不需要一个 profiler 就能感觉到——光标变得迟滞,键盘输入有微妙的延迟。[#2309] 的修复思路简单到只差一行 API:TUI.requestComponentRender。不是每次状态变化都重绘全局,而是只渲染状态变化的那个组件。受影响子树之外的所有节点,碰都不碰。
这个改动带来的效果非常直观——长对话再也不会有那种「帧率骤降」的瞬间了。渲染不再随对话长度衰减。
配合 v15.11.1 引入的 display.smoothStreaming——它让流式 tool-call 参数也能渐进式地出现在你眼前,而不是一次性刷出一大段 JSON——TUI 的实时感上升了一个台阶。模型在构建工具的输入参数时,你就能看到它是怎么一步步搭建这个参数的。
执行进化:bash 从串行到并行
这是 v15.11.2 中我相当欣赏的一个改动。它不是大幅降低了什么延迟,而是在某种意义上压缩了你对工具执行速度的「感知」。
之前,如果你在 assistant message 里提交 3 个 bash 调用,oh-my-pi 会把它们串行化——先跑第一个,等它返回,再跑第二个,再跑第三个。这在逻辑上没问题,但你在终端前看着光标转圈的时候,会下意识问:为什么不能一起跑?
现在可以了。[#2310] 的核心逻辑简单到可以用一句话概括:同一个 assistant message 里的 bash 工具调用,如果 shell 是 non-pty 且共享的,就并行执行。两个例外:
pty:true的 shell 保持独占(终端交互不能乱)- 重叠的 shell key 调用退化为隔离的一次性 shell(不会互相污染状态)
这带来了一个务实的改变:当你让模型做一组无依赖的批量操作——比如同时查看 3 个不同的文件、同时启动 2 个本地服务——你不必再被串行化的顺序阻塞。结果的到达时间线被压缩了。
AgentConcurrency 的粒度进化
如果说 bash 并行是执行层面的改进,那 AgentTool.concurrency 的升级就是声明层面的。
以前,你的工具要么独占总线(exclusive),要么共享总线(shared),一个工具定义决定了它的调度策略,没办法按单次调用的参数动态选择。
v15.11.2 让 concurrency 支持一个 per-call 的 resolver 函数——(args) => shared | exclusive。你可以在工具定义里写一段逻辑:如果这次调用的 args 里带了一个特定 flag,就共享;没有,就独占。这个改动不大,但它打开了工具调度策略的「可编程性」。未来多 agent 共享同一个工具池的场景里,这种 per-call 调度会变得不可或缺。
魔力关键词:不再悄悄替你决定
oh-my-pi 有几种隐藏魔法关键词——ultrathink、orchestrate、workflow。你在对话里提到它们,框架会触发对应的特殊行为。这对熟客来说很有用,但对新用户来说可能有点「偷偷摸摸」——你说了一句话,框架替你做了某个决定,但你不知道自己触发了什么。
v15.11.2 增加了 magicKeywords.enabled 主开关和每个关键词的独立开关。你可以在配置里选择完全不启用这个机制(magicKeywords.enabled: false),或保留整体启用但关掉某个特定关键词的提示通知。这对于不需要 workflow 模式、但想保留 ultrathink 的用户来说,是实打实的选择权。
Expert Elixir:语言服务器自动探测
Elixir 社区的用户会在 v15.11.2 里发现一个让人会心一笑的改动:expert --stdio 形式的 Expert 语言服务器会被 Mix 项目自动检测到。
这意味着你不需要手动配置 [languages.elixir] 的专家模式。如果工作目录是个 Elixir/Mix 项目,框架会自动启用 Expert Elixir LSP。对于每天在 Phoenix 或 Nx 项目里工作的人来说,少配一行配置可能省不了几秒钟,但它消除了判断「这个项目该不该配」的认知成本。
v15.11.1 的基础演进
回过头看,v15.11.1 本身也做了相当多前期工作。
最值得说的是 async.enabled 现在默认是 true([#2301])。这背后是一系列任务编排组件成熟到了不需要用户主动理解的程度——后台任务执行、异步 bash 都开箱即用。「默认开启」的意思是,团队的信心到了。
display.smoothStreaming 前面已经提过,但 statusLine.transparent 这个外观设置值得单独说一下([#2306]):状态栏现在可以继承终端的默认背景色,而不是强制画出自己的底色。这会让 oh-my-pi 的使用体验融入到你的终端配色方案里,而不是像一个悬浮的 UI 块。
缩短的背景任务指示器——齿轮图标加数字——取代了冗长的文字提示。这跟透明状态栏的审美逻辑是一致的:不在你的屏幕上多占一个像素的不必要空间。
Bugfix 主题:数据路径的完整性
两个版本的 bugfix 整理来看,有一个清晰的脉络:数据路径的完整性。
Anthropic 方面,stop_details 在 assistant 消息上的保留([#2290])、metadata.user_id 在 web search 请求中的正确传递([#2295])、以及错误 tool results 中的纯空白内容不再导致 HTTP 400 错误(v15.11.2),全部指向同一个方向:模型和工具之间的数据交换不能因为「看起来空的」内容而断裂。
OpenAI 方面,Responses/Completions 流在 120 秒超时前卡死的问题被修复([#2290])。我之前遇到过类似的情况——一个看起来已经生成完毕的流卡在 final 帧上,终端没有任何错误提示,只是沉默。这种死锁比显式报错更让人困惑。
pi-catalog 方面,NVIDIA NIM Qwen 的 enable_thinking 参数([#2299])和 Moonshot/Kimi 的请求元数据([#2289])也修好了。
还有一组修复值得注意:CDP attach 目标选择(Chromium/Edge)和本地内存整理在 Responses 类模型上的修复。这两个都是「不太常见但一旦遇到就完全抓狂」的场景——前者的症状是开浏览器 debug 时连不上正确的 target,后者的症状是记忆文件越积越多但无人回收。
其他有印象的修复
Plain-RPC 斜杠命令发现了命令源元数据;编辑工具 hashline prompt 指引被修好([#2292]);MCP OAuth 授权在目标服务器的流程跑通了;IRC 发送的 await:true 不再困住发送者——消息发出后就释放发送者的上下文,不再等接收方读完。
流式代码块避免同步语法高亮直到最终确定——之前的版本会等整块代码到达后才解析,现在提前释放了帧率。job 工具 poll 头部不再重复显示 running count。Windows 风格反斜杠路径也能被正确解析了。修复了扩展/插件加载器注入 pi 自导入导致的栈溢出。
以及我特别想提的一个 Windows 修复:Ctrl+C/退出不再破坏父 shell。emergencyTerminalRestore 现在只在追踪到 alt-screen 状态后才触发([#2311])。之前如果你在 Windows 的 cmd 里按下 Ctrl+C 退出 oh-my-pi 的 TUI,回到命令行后终端显示会处于一个半 corrupted 的状态。
两个小版本合在一起,展示的是 oh-my-pi 这个工具性格的侧面特写——从「什么都能做」到「做什么都更稳」。







