Bug Description
pruneContextMessages() in src/agents/pi-extensions/context-pruning/pruner.ts explicitly skips any toolResult message that contains image blocks:
if (hasImageBlocks(msg.content)) {
continue; // line ~248
}
This means tool results with images (e.g. browser screenshots, read tool reading image files) can never be pruned, even when the context window is full. The comment says "for now" but there is no fallback or tracking issue.
Meanwhile, pruneProcessedHistoryImages() in src/agents/pi-embedded-runner/run/history-image-prune.ts only processes role === "user" messages — it does not touch toolResult images either.
Both pruning mechanisms ignore tool result images, creating a gap where screenshot-heavy sessions accumulate unbounded image data with no recovery path.
Impact
This is particularly severe for browser automation workflows — one of OpenClaw's core use cases. Each browser action can produce a screenshot as a toolResult. In a typical debugging session:
- 20 browser actions → 20 screenshot tool results
- Each image ~1200+ tokens (actual base64 data far larger)
pruneContextMessages cannot reclaim any of this space
- Context window fills → session becomes unusable
Unlike user-uploaded images (#19099) or vision-model loops (#29290), this scenario has no workaround — the context pruner is supposed to be the safety net, but it refuses to touch the largest consumers of context space.
Reproduction
- Start a session with browser automation enabled
- Perform 15-20+ browser actions that produce screenshots
- Observe context usage growing monotonically
- Context pruning triggers but fails to free meaningful space (images skipped)
- Eventually: context overflow or severely degraded performance
Expected Behavior
pruneContextMessages() should be able to prune image-containing tool results, at minimum by replacing image blocks with a text placeholder like [screenshot removed during context pruning] while preserving any accompanying text content.
Suggested Fix
In softTrimToolResultMessage() and the hard-clear phase of pruneContextMessages(), instead of skipping image tool results entirely, replace image blocks with text placeholders:
// Instead of:
if (hasImageBlocks(msg.content)) {
continue;
}
// Consider:
if (hasImageBlocks(msg.content)) {
// Replace image blocks with placeholder, keep text blocks
const prunedContent = msg.content.map(block =>
block.type === 'image'
? asText('[image removed during context pruning]')
: block
);
// ... proceed with pruned content
}
This preserves the message structure and any text descriptions while reclaiming the image data.
Related Issues
Environment
- OpenClaw: latest main branch
- Affected files:
src/agents/pi-extensions/context-pruning/pruner.ts (skips image tool results)
src/agents/pi-embedded-runner/run/history-image-prune.ts (only handles user messages)
Bug Description
pruneContextMessages()insrc/agents/pi-extensions/context-pruning/pruner.tsexplicitly skips anytoolResultmessage that contains image blocks:This means tool results with images (e.g. browser screenshots,
readtool reading image files) can never be pruned, even when the context window is full. The comment says "for now" but there is no fallback or tracking issue.Meanwhile,
pruneProcessedHistoryImages()insrc/agents/pi-embedded-runner/run/history-image-prune.tsonly processesrole === "user"messages — it does not touchtoolResultimages either.Both pruning mechanisms ignore tool result images, creating a gap where screenshot-heavy sessions accumulate unbounded image data with no recovery path.
Impact
This is particularly severe for browser automation workflows — one of OpenClaw's core use cases. Each browser action can produce a screenshot as a
toolResult. In a typical debugging session:pruneContextMessagescannot reclaim any of this spaceUnlike user-uploaded images (#19099) or vision-model loops (#29290), this scenario has no workaround — the context pruner is supposed to be the safety net, but it refuses to touch the largest consumers of context space.
Reproduction
Expected Behavior
pruneContextMessages()should be able to prune image-containing tool results, at minimum by replacing image blocks with a text placeholder like[screenshot removed during context pruning]while preserving any accompanying text content.Suggested Fix
In
softTrimToolResultMessage()and the hard-clear phase ofpruneContextMessages(), instead of skipping image tool results entirely, replace image blocks with text placeholders:This preserves the message structure and any text descriptions while reclaiming the image data.
Related Issues
Environment
src/agents/pi-extensions/context-pruning/pruner.ts(skips image tool results)src/agents/pi-embedded-runner/run/history-image-prune.ts(only handles user messages)