Files
hermes-skills/skills/legal/contract-pass-workflow/references/notification-ws-failure-pattern-20260709.md

2.7 KiB

交付通知丢失:企微WS凌晨断连 + fire-and-forget架构

事件:2026-07-09 职业卫生+舜珙血压计两份合同交付无通知

时间线

  • 01:23:06 — 最后一条成功发送(gateway → doro)
  • 01:25~01:27 — WS断连(原因未知,WeCom服务端)
  • 01:27:23 — 首次846609 "aibot websocket not subscribed"
  • 01:28:01 — 职业卫生监督thread=end,final_review尝试通知→失败
  • 01:30:44 — WS reconnected
  • 02:04:16 — 成功发送(QiuTing),说明短暂恢复
  • 02:12:29 — 舜珙thread=end,通知可能在02:05-02:12期间尝试
  • 02:15:50 — WS再次断开
  • 持续不稳定直到 06:36

根因链

  1. WeCom WS凌晨不稳定(每30-60min断一次,服务端维护/长连接超时)
  2. Gateway自动重连成功但846609持续("not subscribed"是服务端状态滞后)
  3. workflow 24/7运行,final_review完成时间不可控
  4. final_review通知是fire-and-forget:_send_wecom(extra, 'doro', msg) 调一次,失败即丢弃

通知机制分析

final_review procedure step 3:
  cd ~/.hermes/hermes-agent && source venv/bin/activate && python -c "
  from tools.send_message_tool import _send_wecom
  ...asyncio.run(_send_wecom(extra, 'doro', msg))..."

_send_wecom实现:

  • 创建新的 WeComAdapter实例
  • connect() → send() → disconnect()
  • 独立WS连接,不依赖gateway的WS
  • 但用的是同一个WeCom API,846609是服务端状态,新连接一样受影响
  • 失败返回 {"error": "..."} 给LLM,LLM可能仍标记notification_sent=true

7月8日也有相同模式

  • 01:13 Timeout → 03:07 reconnect失败 → 06:04 gateway重启才恢复
  • 约5小时不可用窗口

解决方案(待实施)

推荐方案B:watchdog补发

  • watchdog cron(每20min)增加逻辑:
    1. 扫描tracker中 status=delivered + delivered_at > 30min前 + notification_sent != true
    2. wecom_dm.py --to doro 补发通知(独立WS连接)
    3. 成功后写 notification_sent=true + notification_at=timestamp
    4. 失败则 notification_attempts += 1,下次tick继续重试
    5. attempts > 6(即2小时)仍失败→日志告警不再重试

tracker字段扩展

{
  "notification_sent": false,
  "notification_at": null,
  "notification_attempts": 0
}

wecom_dm.py优势

  • 独立WS连接,不受gateway状态影响
  • 有明确的返回值(success/fail)
  • 凌晨WS虽然不稳定但有恢复窗口(如02:04成功发送)
  • 20min tick间隔 × 多次重试,大概率能命中一个可用窗口

临时止血

当发现合同delivered但Doro没收到通知时:

python3 ~/.hermes/scripts/wecom_dm.py --to doro --text "合同审查完成通知(补发): ..."