openclaw - 💡(How to fix) Fix Feature: heartbeat should skip/defer when agent is actively processing [1 comments, 2 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#58656Fetched 2026-04-08 01:59:42
View on GitHub
Comments
1
Participants
2
Timeline
1
Reactions
1
Timeline (top)
commented ×1

Code Example

// cronScheduler.ts
function check() {
  if (isLoading()) return  // Skip if agent is busy
  // ... fire scheduled tasks
}

---

heartbeat interval fires
  → is agent session currently processing? (mid-turn, tool calls active)
    → yes: skip this heartbeat, wait for next interval
    → no: inject heartbeat message as usual
RAW_BUFFERClick to expand / collapse

Problem

When the heartbeat fires while the agent is mid-turn (e.g., reading files, running tools, writing output), it interrupts the current work by injecting a new message into the queue. The agent must process the heartbeat turn before resuming, causing:

  1. Context switch overhead — agent reads HEARTBEAT.md, evaluates "am I busy?", responds, then resumes prior work
  2. Wasted turn — the heartbeat result is effectively HEARTBEAT_OK since there is active work
  3. Token cost — each interrupted turn consumes tokens for context restoration

Current behavior

Heartbeat fires on a fixed interval (e.g., every 30m) regardless of whether the agent session is actively processing a message. The heartbeat message enters the same queue as user messages.

Expected behavior

Heartbeat should skip or defer when the agent is actively processing:

  • If the agent is mid-turn (tool calls in progress, generating response), defer the heartbeat to after the current turn completes
  • Or skip the heartbeat entirely and wait for the next interval

Prior art

Claude Code's proactive mode has a similar mechanism: the CronScheduler checks isLoading() before firing scheduled tasks. From their source:

// cronScheduler.ts
function check() {
  if (isLoading()) return  // Skip if agent is busy
  // ... fire scheduled tasks
}

This ensures scheduled prompts only fire when the REPL is idle between turns.

Proposed solution

Add an isProcessing check before injecting the heartbeat message:

heartbeat interval fires
  → is agent session currently processing? (mid-turn, tool calls active)
    → yes: skip this heartbeat, wait for next interval
    → no: inject heartbeat message as usual

This could be a gateway-level check (session has pending tool calls or is generating) rather than agent-level.

My setup

  • Single agent, heartbeat every 30 minutes
  • Agent frequently does multi-step work (source code research, file writing) that spans several minutes
  • Heartbeat interruptions are most noticeable during long tool-call chains

extent analysis

TL;DR

Implement an isProcessing check before injecting the heartbeat message to skip or defer heartbeats when the agent is actively processing a message.

Guidance

  • Introduce a check for isProcessing or a similar indicator to determine if the agent is mid-turn or has active tool calls, and skip the heartbeat if true.
  • Consider implementing this check at the gateway level to account for pending tool calls or response generation.
  • Review the CronScheduler from Claude Code's proactive mode as a reference for implementing the isProcessing check.
  • Evaluate the impact of skipped heartbeats on the overall system behavior and adjust the heartbeat interval if necessary.

Example

// example heartbeat scheduler
function scheduleHeartbeat() {
  if (isProcessing()) return; // Skip if agent is busy
  // inject heartbeat message into the queue
}

Notes

The proposed solution assumes that the isProcessing check can accurately determine the agent's state. Additional considerations may be needed to handle edge cases, such as prolonged tool calls or failed heartbeats.

Recommendation

Apply the proposed workaround by implementing the isProcessing check to skip or defer heartbeats when the agent is actively processing a message, as it addresses the context switch overhead, wasted turns, and token cost issues.

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…

FAQ

Expected behavior

Heartbeat should skip or defer when the agent is actively processing:

  • If the agent is mid-turn (tool calls in progress, generating response), defer the heartbeat to after the current turn completes
  • Or skip the heartbeat entirely and wait for the next interval

Still need to ship something?

×6

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

Back to top recommendations

TRENDING