oh-my-pi v15.12.4 发布 —— 同时开三个 omp session 会 crash?SQLite 并发修复来了
SQLite 并发崩溃、Gemini 静默停摆、模型切换卡住 UI 好几秒、session 恢复等十秒、Ollama 上传 WebP 图片返回 400、Mermaid 中文标签画歪、Mnemopi graph voice 永远返回空……
每个问题单独看都不致命,可合起来就是「这个 agent 怎么又不动了」的累积挫败感。

痛点:oomp——开了多个 session,然后全崩了
cmux 用户有个习惯:开多个 pane,每个 pane 跑一个 omp --session。一个 debug,一个 review PR,一个写文档。这很自然——omp 的 session 管理强就强在能同时维持多条独立对话线。
但问题是:当你电脑意外关机、重启后 cmux 自动恢复所有 pane,这几个 omp --session 会同时启动。它们都去打开 SQLite 数据库,争着做 WAL recovery,然后——SQLITE_BUSY_RECOVERY 一路 crash 过去。每次启动都撞到同一个锁,谁也抢不到。
这个 bug 藏了多久?从同时支持多个 session 的那天就存在了。不是 omp 的问题,是 SQLite 本身的 WAL recovery 机制——第一次写操作发生时必须加锁,多个进程同时复苏就会互锁。
v15.12.4 的修法很务实:在所有 SQLite 打开路径之前先执行 PRAGMA busy_timeout = 5000,然后 retry SQLITE_BUSY、SQLITE_BUSY_RECOVERY、SQLITE_BUSY_SNAPSHOT、SQLITE_BUSY_TIMEOUT 四种 busy 状态,带指数退避。修复覆盖了 auth credential store、AgentStorage、history、memories、github cache、auto-QA、catalog model cache、stats 全部 SQLite 路径(#2421)。
这是个挺隐蔽但用久了大概率会碰到的问题。如果你的经验里从来没遇到过,可能是还没经历过异常关机后恢复 session 的场景——遇到了就回不去了。
Gemini agent 悄悄不说话的问题
如果你用 Gemini 模型跑 omp,可能遇到过这种场景:agent 突然不回复了,没有错误提示,没有网络超时,session 安静得像什么都没发生。
原因是 Gemini 有时返回 finishReason: STOP 但附带一个空文本(只有空格或空字符串),也没有 tool call。omp 之前把这种情况当作"正常结束"——agent 收到空回复,无事可做,停止。这就是那个著名的"Gemini 静默"bug。
这个版本修了所有 Google 后端(public Generative Language、Vertex、Cloud Code Assist)的空响应处理。现在统一的 hasMeaningfulGoogleContent 检查把空文本视为"无效回复",自动重试到 MAX_EMPTY_STREAM_RETRIES 次后才报错。Cloud Code Assist 路径之前虽然有一个空流重试,但它用 hasContent 判断——空字符串也算"有内容"——所以从来没真正触发过重试。
类似的问题还有 Gemini/Antigravity 返回纯思考块(reasoning/thinking only)没有最后文本或 tool call 的 STOMP 响应:现在也自动重试了,不会静默停摆。
session 恢复等十秒、模型切换卡半分钟
这两个问题同根。无论是 pi -c 恢复 session 还是 Ctrl+P 切换模型,底层都会调用 modelRegistry.getApiKey(model)。可 getApiKey 做的事远不止"取 key"——它会同步执行命令式 key 程序(apiKey: "!cmd",execSync 带 10 秒超时),还会在 token 过期时去刷新 OAuth token。一个模型切换触发一次网络请求+子进程执行,偶尔卡几秒也就算了——但 restoreSessionModel 对每个候选模型都做一次,session 恢复就能卡十秒。
修法:switching 和 restore 改用同步的 hasConfiguredAuth 探测,不做任何有副作用的操作。真正的 key 解析延迟到第一次请求时才执行。改动很小,效果很明显——model switch 从 "fine for a few switches, then a multi-second stall" 变成瞬间切换。
Provider 流式全方位的补丁
v15.12.4 对 OpenAI-compatible 流式做了系统性加固:
- SSE 直接解析:不再依赖 OpenAI SDK,改用内部的
postOpenAIStreamJSON/SSE transport,自己解析 wire-level JSON frames 和[DONE]终结符 - HTTP 408/429/5xx 自动重试:这些在 Provider 层面不是致命错误,之前却直接抛给了用户。现在带 Retry-After/quota-hint aware backoff
- OpenRouter finish_reason: error 映射:OpenRouter 报告上游失败(如 Gemini
MALFORMED_FUNCTION_CALL)时返回finish_reason: "error"。omp 之前把它当作不可重试的错误,session 卡死。现在映射为Provider returned error finish_reason,被 session retry classifier 识别为瞬态错误,自动重试 - 客户端中断释放上游连接:用户打断 stream 时,之前只停了本地 reader,上游 request body 还在继续跑。现在 abortable stream 包装会真正 cancel 上游请求
- MiniMax M3 推理去重:同一个 chunk 携带
<think>…</think>和结构化reasoning_content时,structured reasoning 优先,累计的 MiniMax 推理快照 collapse 为 delta
这些修的不算"用户可见的功能",但如果你在用任何 OpenAI-compatible 后端(OpenRouter、Together、Fireworks 等等),session 卡死、流断掉、超频错误的场景会大幅减少。
Fireworks 新模型自动出现,不用等 catalog 更新
Fireworks 的用户之前有个隐藏痛点:他们在 model picker 里看不到 kimi-k2.7-code、deepseek-v4-flash 这些新模型——不是因为 omp 不支持,而是因为 omp 的 bundled catalog 还没更新。Fireworks 每周发新模型,而 bundled catalog 的更新滞后几天到一周。
修复:Fireworks 模型发现从 inference API(/v1/models,返回 account-specific 稀疏子集)切换到 control-plane List Models API。control-plane 枚举所有 serverless 模型,附带 capability metadata(supportsServerless、supportsTools、supportsImageInput、contextLength、displayName)。新发布的 serverless 模型现在自动出现在 picker 里,不需要等 catalog 编辑。
此外 contextWindow 和 maxTokens 用 null 代替了之前硬编码的 222222/8888 哨兵值。模型列表里未知限制显示为 - 而不是伪造的 222K/8.9K。
其他值得关注的修复
Mnemopi graph voice 终于能用了:sleep/sleepAllSessions 背后的 consolidateToEpisodic 之前"运行了但什么都没写"——gists 和 graph_edges 表永远是 0 行,Polyphonic Recall 的 graph voice 永远返回空。现在 consolidation 会实际 ingest episodic memory 进入 EpisodicGraph(#2435)。用了 3 个月 rerank voice 的人可以试试切回 graph 了。
Mermaid 中文标签不再画歪:ASCII 渲染时 CJK/emoji 标签的边框宽度用 UTF-16 code units 计算,但终端渲染东亚字符是 2 列宽。一个 patchedDependencies 入口把 beautiful-mermaid 的渲染器改成 grapheme-cluster aware wcwidth-style 测量(#2442)。这个 bug 影响所有在 agent 对话中用中文编写 Mermaid 流程图的人。
Mnemopi bank 不再被 .git 位置意外改变:之前 per-project/per-project-tagged bank 的 ID 从 git.repo.resolveSync(cwd)?.repoRoot || path.resolve(cwd) 哈希生成。如果你在 /home/x/projects/repo 下工作,然后在上层目录加了一个 .git,bank 的哈希值变了——所有之前的记忆都"消失"了(实际还在旧 bank 里,但找不到了)。现在直接哈希 path.resolve(cwd),启动时还会扫描兄弟 bank 找回那些"丢失"的记忆(#2412)。
Windows 粘贴修复:Ctrl+V 在 PowerShell 下走原生 clipboard reader;之前 reader 报 "no image" 后不会 fall back 到 PowerShell clipboard bridge。现在是 fallback 路径了(#2429)。
升级
# 已安装用户
omp update
# macOS/Linux 一键安装
curl -fsSL https://omp.sh/install | sh
# Homebrew
brew install can1357/tap/omp
# Bun(推荐)
bun install -g @oh-my-pi/pi-coding-agent
# Windows (PowerShell)
irm https://omp.sh/install.ps1 | iex
完整更新日志:GitHub Release
📢 关注我,获取最新开源更新日志和开发者工具动态。
#oh-my-pi #SQLite #AI-agent #bugfix