Skip to content

feat: conditional bootstrap file loading for heartbeat vs DM sessions#13524

Closed
tarun131313 wants to merge 1 commit into
openclaw:mainfrom
tarun131313:feat/conditional-bootstrap-loading
Closed

feat: conditional bootstrap file loading for heartbeat vs DM sessions#13524
tarun131313 wants to merge 1 commit into
openclaw:mainfrom
tarun131313:feat/conditional-bootstrap-loading

Conversation

@tarun131313

@tarun131313 tarun131313 commented Feb 10, 2026

Copy link
Copy Markdown

Problem

Workspace bootstrap files (AGENTS.md, SOUL.md, TOOLS.md, IDENTITY.md, USER.md, HEARTBEAT.md, MEMORY.md) are injected into every agent run regardless of session type. This wastes tokens:

  • DM sessions load HEARTBEAT.md (~300-1,500 tokens) which contains heartbeat poller instructions not needed during interactive conversations
  • Heartbeat runs load SOUL.md, TOOLS.md, USER.md, MEMORY.md which are not needed for a periodic check

For users with multiple agents and detailed HEARTBEAT.md files, this adds up to 1,400+ wasted tokens per DM message.

Solution

Extend filterBootstrapFilesForSession() to support session-type-aware filtering:

  • Subagent sessions: AGENTS.md + TOOLS.md (unchanged, existing behavior)
  • Heartbeat sessions: HEARTBEAT.md + AGENTS.md + IDENTITY.md (new)
  • Normal DM sessions: All files except HEARTBEAT.md (new)

The isHeartbeat flag is threaded from the auto-reply layer through the embedded runner to the bootstrap file resolver.

Changes

  • workspace.ts: Added HEARTBEAT_BOOTSTRAP_ALLOWLIST, DM_BOOTSTRAP_EXCLUDELIST, and FilterBootstrapOptions type. Extended filterBootstrapFilesForSession() with optional opts parameter.
  • bootstrap-files.ts: Thread isHeartbeat through resolveBootstrapFilesForRun and resolveBootstrapContextForRun.
  • run/types.ts + run/params.ts: Added isHeartbeat? to embedded run params.
  • run/attempt.ts + run.ts: Pass isHeartbeat to bootstrap context resolver.
  • followup-runner.ts + agent-runner-execution.ts: Pass isHeartbeat to embedded runner.

Testing

  • All existing tests pass (workspace.test.ts: 4/4, bootstrap-files.test.ts: 2/2)
  • Backward compatible: the opts parameter is optional, existing behavior unchanged when not provided

Related Issues

Greptile Overview

Greptile Summary

This PR adds session-type-aware bootstrap file filtering to reduce token waste: subagent runs continue to load a minimal allowlist, heartbeat runs load only HEARTBEAT.md + core identity/agent files, and normal DM sessions load everything except HEARTBEAT.md. The new isHeartbeat flag is threaded from the auto-reply layer through the embedded runner into the bootstrap resolver, which then calls the updated filterBootstrapFilesForSession().

Main issue to address before merge: followup runs don’t register isHeartbeat in the agent run context, which can break downstream behavior that relies on getAgentRunContext(runId)?.isHeartbeat (notably webchat broadcast suppression for heartbeats).

Confidence Score: 3/5

  • Not safe to merge until followup heartbeat runs are correctly classified.
  • The bootstrap filtering and isHeartbeat threading are mostly consistent, but followup runs omit isHeartbeat when registering AgentRunContext, which breaks downstream heartbeat-specific behavior (e.g., suppressing heartbeat broadcasts).
  • src/auto-reply/reply/followup-runner.ts

(2/5) Greptile learns from your feedback when you react with thumbs up/down!

Add session-type-aware filtering to filterBootstrapFilesForSession():

- Heartbeat runs: load only HEARTBEAT.md, AGENTS.md, IDENTITY.md
- Normal DM sessions: load all files EXCEPT HEARTBEAT.md
- Subagent sessions: unchanged (AGENTS.md + TOOLS.md)

This saves ~1,400+ tokens per DM message by excluding heartbeat
instructions that are only relevant during heartbeat polls, and saves
tokens during heartbeat runs by excluding files the heartbeat poller
doesn't need (SOUL.md, TOOLS.md, USER.md, MEMORY.md).

The isHeartbeat flag is threaded from the auto-reply layer through the
embedded runner to the bootstrap file resolver.

Related: openclaw#9157 (workspace file injection token waste)
Related: openclaw#1594 (heartbeat context overhead)
@openclaw-barnacle openclaw-barnacle Bot added the agents Agent runtime and tooling label Feb 10, 2026

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@greptile-apps

greptile-apps Bot commented Feb 10, 2026

Copy link
Copy Markdown
Contributor
Additional Comments (1)

src/auto-reply/reply/followup-runner.ts
Heartbeat runs misclassified

registerAgentRunContext() here doesn’t include isHeartbeat, so followup heartbeat runs won’t be marked as heartbeat in the run context. This breaks consumers that gate behavior on getAgentRunContext(runId)?.isHeartbeat (e.g. webchat heartbeat broadcast suppression in src/gateway/server-chat.ts:12-25). Consider passing isHeartbeat: opts?.isHeartbeat === true in this call.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/auto-reply/reply/followup-runner.ts
Line: 117:122

Comment:
**Heartbeat runs misclassified**

`registerAgentRunContext()` here doesn’t include `isHeartbeat`, so followup heartbeat runs won’t be marked as heartbeat in the run context. This breaks consumers that gate behavior on `getAgentRunContext(runId)?.isHeartbeat` (e.g. webchat heartbeat broadcast suppression in `src/gateway/server-chat.ts:12-25`). Consider passing `isHeartbeat: opts?.isHeartbeat === true` in this call.

How can I resolve this? If you propose a fix, please make it concise.

@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added stale Marked as stale due to inactivity and removed stale Marked as stale due to inactivity labels Feb 21, 2026
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Mar 10, 2026
@openclaw-barnacle

Copy link
Copy Markdown

Closing due to inactivity.
If you believe this PR should be revived, post in #pr-thunderdome-dangerzone on Discord to talk to a maintainer.
That channel is the escape hatch for high-quality PRs that get auto-closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants