feat(chat): OpenClaw 4.5 compatibility — fix silent no-reply + add working state indicators

Problem:
- Sending a message with no response left users stuck with an empty typing
  indicator forever (no timeout, no error, no feedback)
- Users had no visibility into what OpenClaw was doing (thinking, planning,
  executing tools, running commands, waiting for approval)
- The response watchdog only reacted to chat delta/final events, ignoring
  all agent processing events

Root cause:
- Watchdog looped every 15s polling history but had no ultimate timeout
- Agent events (lifecycle, item, plan, approval, thinking, command_output)
  were not handled — only tool stream events updated the typing hint
- When OpenClaw processed silently (no delta), the UI showed nothing useful

Fix:
1. Handle ALL OpenClaw 4.5 agent event streams in handleEvent():
   - lifecycle: "AI is processing…" on phase start
   - item: structured execution steps (tool/command/search/analysis)
   - plan: "AI is planning…"
   - approval: "Waiting for approval…"
   - thinking: "AI is thinking…"
   - command_output: "Running command…"
   - compaction/error: appropriate indicators

2. Enhanced watchdog mechanism:
   - 3-minute ultimate timeout that persists across watchdog re-polls
   - Agent events reset the polling timer (OpenClaw is alive) but not
     the ultimate timeout
   - After 30s shows "Still waiting…" with elapsed time
   - At 3min shows clear error: "Check if OpenClaw is running"

3. Live elapsed timer in typing indicator:
   - Shows seconds elapsed since message was sent (after 5s)
   - Updates every 5s while waiting
   - Properly cleaned up on response/error/page exit

4. Config compatibility check: no changes needed — our code already uses
   canonical config paths, no legacy aliases affected by 4.5 removal.

Files: chat.js, chat.css, locales/modules/chat.js
This commit is contained in:
晴天
2026-04-07 13:34:21 +08:00
parent f781f2afa6
commit 35423f428b
3 changed files with 196 additions and 25 deletions

View File

@@ -42,6 +42,7 @@ export default {
sendFailed: _('发送失败: ', 'Send failed: ', '發送失敗: ', '送信失敗', '전송 실패'),
usingTool: _('正在使用工具: {name}', 'Using tool: {name}'),
streamTimeout: _('输出超时,已自动结束', 'Output timed out, auto-ended', '輸出逾時,已自動結束'),
elapsedTime: _('{seconds}秒', '{seconds}s'),
generationStopped: _('生成已停止', 'Generation stopped'),
errorPrefix: _('错误: ', 'Error: ', '錯誤: '),
connectionRejected: _('连接被 Gateway 拒绝,请点击「修复并重连」', 'Connection rejected by Gateway, click "Fix & Reconnect"', '連線被 Gateway 拒絕,請点擊「修复並重連」'),
@@ -57,6 +58,16 @@ export default {
tool: _('工具', 'Tool'),
file: _('文件', 'File', '檔案'),
compacting: _('正在整理上下文Compaction…', 'Compacting context…'),
aiProcessing: _('AI 正在处理…', 'AI is processing…', 'AI 正在處理…'),
aiThinking: _('AI 正在思考…', 'AI is thinking…', 'AI 正在思考…'),
aiPlanning: _('AI 正在规划…', 'AI is planning…', 'AI 正在規劃…'),
aiExecuting: _('正在执行: {title}', 'Executing: {title}', '正在執行: {title}'),
aiSearching: _('正在搜索…', 'Searching…', '正在搜尋…'),
aiAnalyzing: _('正在分析…', 'Analyzing…', '正在分析…'),
commandRunning: _('正在运行命令…', 'Running command…', '正在執行命令…'),
waitingApproval: _('等待操作批准…', 'Waiting for approval…', '等待操作批准…'),
responseTimeout: _('等待回复超时({seconds}秒无响应),请检查 OpenClaw 是否正常运行', 'Response timed out ({seconds}s no response). Please check if OpenClaw is running.', '等待回覆逾時({seconds}秒無回應),請檢查 OpenClaw 是否正常運行'),
stillWaiting: _('仍在等待回复…', 'Still waiting for response…', '仍在等待回覆…'),
remaining: _('剩余', 'Remaining', '剩餘'),
connectFailed: _('连接失败', 'Connection failed', '連線失敗'),
fixDoneReconnecting: _('修复完成,正在重连...', 'Fix done, reconnecting...', '修复完成,正在重連...'),