im_wower
·
2026-03-30
WATCHDOG_V2_CONDUCTOR_INTEGRATED.md
1# Watchdog V2 — Conductor 集成方案
2
3> 日期: 2026-03-30
4> 状态: 方案设计
5
6## 问题
7
8当前看门狗依赖 Claude 手动设心跳文件状态(working → waiting),Claude 经常忘记,导致续命失效。
9
10## 核心洞察
11
12Conductor 已拦截每个 AI 的 SSE final-message。收到 final-message = AI 回复结束 = 需要续命。
13
14**不需要 Claude 手动设状态,conductor 天然知道。**
15
16## 链路
17
18```
19Claude 回复结束
20 → 浏览器 SSE 流结束
21 → Firefox 插件拦截 final-message
22 → WS 发给 conductor
23 → conductor ingest 处理
24 → ingest 末尾触发续命 hook
25 → 延迟 N 秒
26 → 通过 a11y 给 Safari 对话页发续命消息
27```
28
29## 实现位置
30
31`firefox-ws.ts` 的 `handleBrowserFinalMessage` 末尾,或 `ingest.ts` 的 `ingestAssistantFinalMessage` 末尾。
32
33## 配置
34
35```typescript
36interface WatchdogConfig {
37 enabled: boolean; // 开关
38 targetTab: string; // Safari 标签页全名
39 platform: string; // 监控哪个平台,如 "claude"
40 delayMs: number; // final-message 后延迟多久(默认 5000ms)
41 renewalMessage: string; // 续命消息
42 cooldownMs: number; // 冷却期,避免连续续命(默认 30000ms)
43 conversationId?: string; // 可选:只监控特定对话
44}
45```
46
47## 逻辑
48
49```typescript
50let lastRenewalTime = 0;
51
52function onFinalMessage(platform: string, conversationId: string) {
53 if (!config.enabled) return;
54 if (platform !== config.platform) return;
55 if (config.conversationId && conversationId !== config.conversationId) return;
56 const now = Date.now();
57 if (now - lastRenewalTime < config.cooldownMs) return;
58
59 setTimeout(() => {
60 exec(`bash tools/watchdog/a11y_msg.sh "${config.targetTab}" "${config.renewalMessage}"`);
61 lastRenewalTime = Date.now();
62 }, config.delayMs);
63}
64```
65
66## 触发条件
67
681. watchdog enabled
692. final-message 来自指定平台
703. 距上次续命超过冷却期
714. 可选:匹配 conversationId
72
73## 对比
74
75| | V1(当前) | V2(本方案) |
76|---|---|---|
77| 触发 | 心跳文件 + 定时轮询 | 事件驱动 |
78| 依赖手动操作 | 是 | 否 |
79| 延迟 | 最多 60 秒 | 5 秒 |
80| 进程管理 | launchd 独立进程 | conductor 内置 |
81| 失败模式 | 忘设状态→永不续命 | SSE 链路通就续命 |
82| 复杂度 | 心跳+状态机+进度文件 | 一个 hook + setTimeout |
83
84## V1 保留为兜底
85
86V2 依赖 SSE 链路(插件→WS→conductor),链路断了 V2 不工作。V1 独立于 conductor,作为最后保险。
87
88## 实现步骤
89
901. conductor-daemon 加 watchdog 配置读取
912. ingest/firefox-ws 加 final-message hook
923. hook 调 a11y_msg.sh 或直接 osascript
934. 加开关端点:POST /v1/watchdog/enable, /disable
945. 测试验证
95
96## 风险
97
98- conductor 和 Safari 不在同一台机器时不工作(a11y 是本机操作)
99- osascript 在 node 子进程可能有 TCC 权限问题
100- final-message 漏掉(SSE 异常中断)→ V1 兜底