openclaw - 💡(How to fix) Fix Feature Request: Add /watchdog command and suppress duplicate watchdog warnings per run [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#69978Fetched 2026-04-23 07:30:46
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Author
Participants
Timeline (top)
subscribed ×1

The TUI streaming watchdog serves an important purpose (detecting silently-dropped runs), but the current UX has two pain points:

  1. Duplicate warnings for the same run — After the watchdog fires and prints the system message, if the backend continues emitting deltas for the same runId (which can happen when the run is merely slow, not dead), the watchdog is re-armed and may fire again, producing the same streaming watchdog: no stream updates for 30s; resetting status... message repeatedly in the chat log.

  2. No runtime control over the watchdog — The threshold is hardcoded to 30 s (DEFAULT_STREAMING_WATCHDOG_MS) and can only be changed by modifying source code. There is no way for a user to disable it or tune it from the TUI.

Root Cause

  • Long-reasoning models: Models like DeepSeek-R1 or kimi-k2.5 can legitimately spend 30–120 s thinking before emitting the first delta. Users working with these models need an easy way to raise the threshold without editing source code (see also #68596).
  • Noisy chat logs: Repeated identical system messages clutter the conversation history and make it harder to read actual assistant output.
  • Debugging: Being able to quickly disable the watchdog (/watchdog off) helps distinguish between "the backend actually hung" and "the watchdog threshold is just too aggressive for this model."

Code Example

const DEFAULT_STREAMING_WATCHDOG_MS = 30_000;

// ...

chatLog.addSystem(
  `streaming watchdog: no stream updates for ${Math.round(
    streamingWatchdogMs / 1000,
  )}s; resetting status. The backend may have dropped this run silently — send a new message to resync.`,
);

---

/watchdog off          # Disable the streaming watchdog entirely
/watchdog 30s          # Set timeout to 30 seconds (default)
/watchdog 60s          # Set timeout to 60 seconds
/watchdog 120s         # Set timeout to 120 seconds
/watchdog              # Show current watchdog setting
RAW_BUFFERClick to expand / collapse

Summary

The TUI streaming watchdog serves an important purpose (detecting silently-dropped runs), but the current UX has two pain points:

  1. Duplicate warnings for the same run — After the watchdog fires and prints the system message, if the backend continues emitting deltas for the same runId (which can happen when the run is merely slow, not dead), the watchdog is re-armed and may fire again, producing the same streaming watchdog: no stream updates for 30s; resetting status... message repeatedly in the chat log.

  2. No runtime control over the watchdog — The threshold is hardcoded to 30 s (DEFAULT_STREAMING_WATCHDOG_MS) and can only be changed by modifying source code. There is no way for a user to disable it or tune it from the TUI.

Current behavior

In src/tui/tui-event-handlers.ts:

const DEFAULT_STREAMING_WATCHDOG_MS = 30_000;

// ...

chatLog.addSystem(
  `streaming watchdog: no stream updates for ${Math.round(
    streamingWatchdogMs / 1000,
  )}s; resetting status. The backend may have dropped this run silently — send a new message to resync.`,
);
  • streamingWatchdogMs can be passed via EventHandlerContext, but there is no user-facing setting or command to configure it.
  • Each time the timer expires for the same active run, a new system message is appended. There is no deduplication.

Desired behavior

1. Suppress duplicate watchdog warnings per run

Once the watchdog has fired for a given runId, do not print the warning again for that same runId, even if the run somehow stays active and the timer fires a second time. A simple Set<string> warnedRunIds (or similar) cleared on finalizeRun / terminateRun / syncSessionKey would suffice.

2. Add a /watchdog slash command

Introduce a new TUI command /watchdog with the following interface:

/watchdog off          # Disable the streaming watchdog entirely
/watchdog 30s          # Set timeout to 30 seconds (default)
/watchdog 60s          # Set timeout to 60 seconds
/watchdog 120s         # Set timeout to 120 seconds
/watchdog              # Show current watchdog setting

Suggested argument validation:

  • Parse the argument as a duration; support s/m suffixes (e.g. 30s, 2m).
  • Minimum non-zero value: maybe 5s to avoid accidental flooding.
  • off or 0 disables the watchdog (sets streamingWatchdogMs = 0, which is already supported in the timer logic).
  • Persist the preference locally (e.g. in ~/.openclaw/tui-settings.json or similar) so it survives restarts.

Why this matters

  • Long-reasoning models: Models like DeepSeek-R1 or kimi-k2.5 can legitimately spend 30–120 s thinking before emitting the first delta. Users working with these models need an easy way to raise the threshold without editing source code (see also #68596).
  • Noisy chat logs: Repeated identical system messages clutter the conversation history and make it harder to read actual assistant output.
  • Debugging: Being able to quickly disable the watchdog (/watchdog off) helps distinguish between "the backend actually hung" and "the watchdog threshold is just too aggressive for this model."

Related issues

  • #68596 — Configurable streaming watchdog timeout threshold (overlapping concern; a /watchdog command would be one concrete way to expose this configuration)
  • #69081 — TUI streaming status desyncs from actual run state (the watchdog is part of that ecosystem)

Version

2026.4.20

extent analysis

TL;DR

Implement a Set to track warned run IDs and introduce a /watchdog slash command to control the streaming watchdog.

Guidance

  • To suppress duplicate warnings, create a Set<string> to store warned run IDs and clear it on finalizeRun, terminateRun, or syncSessionKey events.
  • Introduce a /watchdog command with argument parsing to support duration settings (e.g., 30s, 2m) and disable the watchdog with off or 0.
  • Validate the argument to ensure a minimum non-zero value (e.g., 5s) and persist the preference locally.
  • Update the chatLog.addSystem call to check the warned run IDs Set before printing the warning message.

Example

const warnedRunIds = new Set<string>();

// ...

if (!warnedRunIds.has(runId)) {
  warnedRunIds.add(runId);
  chatLog.addSystem(`streaming watchdog: no stream updates for ${Math.round(streamingWatchdogMs / 1000)}s; resetting status.`);
}

Notes

The proposed solution assumes that the runId is available in the scope of the chatLog.addSystem call. If not, additional modifications may be necessary to access the runId.

Recommendation

Apply the workaround by introducing the /watchdog command and implementing the warned run IDs Set to suppress duplicate warnings, as this provides a more flexible and user-friendly solution.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Feature Request: Add /watchdog command and suppress duplicate watchdog warnings per run [1 participants]