OpenCode 对话中断监控器——盯住你的 AI 编程会话,意外中断时立刻提醒,不让你干等。
当你让 OpenCode 跑长任务时,AI 对话经常因为网络抖动、服务商异常或流式响应被掐断而悄悄停掉。你切去别的窗口干活,半小时后回来才发现它早卡死了。Watchdog 就是你的第二双眼睛——后台静默运行,一旦会话出问题,立刻响铃、弹通知、网页高亮。
- 三种中断都能抓
- 🔴 静默中断:请求发出去了,但 AI 什么都没返回
- 🔴 输出截断:AI 说到一半被中途掐断(有输出但不完整)
- 🔴 上游报错:连接断开、JSON 解析失败、服务商异常、限流
- 精准判别:基于
finish=unknown信号,不误报正常结束、工具调用中间步骤或用户主动中止 - 持续提醒:异常中断每 30 秒重复报警,直到你确认处理
- 正常完成也提醒:长会话(>60秒)正常结束时绿色高亮,方便你回来验收
- 单条/全部确认:每条事件可单独确认,也可一键全确认
- 零外部依赖:直接读 OpenCode 的 SQLite 数据库,不修改任何数据,全程只读
# 双击启动
D:\tools\opencode-watchdog\gui\start.bat自动安装依赖 + 启动本地服务 + 打开浏览器 http://localhost:3456。
# PowerShell profile 里已注册 watchdog 函数,直接用
watchdog
# 或手动启动
node D:\tools\opencode-watchdog\terminal\watchdog.js┌─────────────────────────────────────────────────────────┐
│ 🐕 OpenCode Watchdog [⏸ 暂停] [✓ 全部确认]│
├─────────────────────────────────────────────────────────┤
│ 异常中断 (2) 正常停止 (1) 已确认 (5) │
├─────────────────────────────────────────────────────────┤
│ 🔴 输出截断 · P2-T1 Field 块精简方案实施 │
│ 输出到 694 tokens 时中断 · 10 分钟前 [确认] │
│ │
│ 🟢 已完成 · CLI内部窗口外部监控与操作 │
│ 跑了 12 分钟 · 刚刚 [确认] │
├─────────────────────────────────────────────────────────┤
│ 监控运行中 · 最近 1 小时 2 个会话活跃 │
└─────────────────────────────────────────────────────────┘
| 方式 | 异常中断 | 正常停止 |
|---|---|---|
| 网页高亮闪动 | ✅ 红 + 每30秒重提醒 | ✅ 绿,只闪一次 |
| 系统 Toast 通知 | ✅ | ✅ |
| 声音 | ✅ 两声短促 | ✅ 一声柔和 |
| Favicon 变色 | 🔴 红 | 🟢 绿 |
| 标题栏未确认数 | ✅ (N 异常) |
✅ (N 完成) |
opencode-watchdog/
├── core/ # 共享核心模块(终端版 + GUI 版复用)
│ ├── db.js # 数据库连接 + 判别查询
│ └── classify.js # 错误分类逻辑
├── terminal/
│ └── watchdog.js # 终端版(引用 core)
├── gui/
│ ├── server.js # GUI 后端(引用 core)
│ ├── package.json
│ ├── start.bat # Windows 启动脚本
│ └── public/
│ ├── index.html # 界面
│ ├── app.js # 前端逻辑
│ └── style.css # 样式
└── README.md
架构设计:判别逻辑(finish=unknown 判据、错误分类)统一在 core/ 里,终端版和 GUI 版各自只负责展示和交互。修改判别规则只需改 core/ 一处,两个版本自动同步。
OpenCode TUI ──写入──► opencode.db (SQLite)
│
Watchdog 轮询读取(只读)
│
▼
core/ 判别 + 分类
│
┌──────────┴──────────┐
│ │
终端版输出 GUI 版 SSE 推送
响铃 + 心跳 网页 + Toast + 声音
判别核心:OpenCode 在每条 assistant 消息的 JSON 里记录 finish 字段:
stop→ AI 正常说完 → 算正常完成(长会话才提醒)tool-calls→ 中间步骤 → 忽略unknown→ 流式响应被掐断 → 报警
finish=unknown 下再按 output 和 error 细分类型(静默中断 / 输出截断 / 上游报错)。
所有配置通过环境变量,都有合理默认值:
| 变量 | 默认 | 作用 |
|---|---|---|
WATCHDOG_POLL_MS |
4000 |
轮询数据库间隔(毫秒) |
WATCHDOG_REPEAT_MS |
30000 |
异常中断重提醒间隔(GUI 版) |
WATCHDOG_ALERT_MS |
30000 |
异常中断重提醒间隔(终端版) |
WATCHDOG_LONG_SESSION_MS |
60000 |
"长会话"阈值,短于此不提醒正常停止 |
WATCHDOG_BELL |
1 |
终端响铃,设 0 关闭 |
WATCHDOG_TOAST |
1 |
Windows Toast 通知,设 0 关闭 |
WATCHDOG_PORT |
3456 |
GUI 版服务端口 |
OPENCODE_DB |
自动 | 手动指定数据库路径 |
- Node.js 22+(使用原生
node:sqlite模块,零原生依赖) - Express(仅 GUI 版后端)
- 原生 HTML + Tailwind CDN(前端,零打包)
- SSE(Server-Sent Events,实时推送)
- Web Audio API(合成提示音,无需音频文件)
- Windows 10/11
- Node.js 22+
- OpenCode(已运行过,数据库存在于默认位置)
个人使用,随意修改。