#19932: feat(agents): suppressPreToolText config + onBlockReply buffering
agents
size: L
Cluster:
Tool Execution and Error Handling
## Summary
Adds a `suppressPreToolText` option to agent defaults that discards intermediate assistant text from tool-use turns (e.g. "Let me check that for you...") before they reach the channel. This is useful for Discord bots where pre-tool narration creates noise.
### Changes
**Commit 1: `fix(agents): batch announces + suppress pre-tool text`**
- New `agents.defaults.suppressPreToolText` config option (boolean, default: false)
- Config flows through `AgentDefaultsConfig` → `RunEmbeddedPiAgentParams` → `SubscribeEmbeddedPiSessionParams` → subscribe state
- `emitBlockChunk()` skips text emission when `suppressPreToolText` is enabled and the turn contains tool use
- `handleMessageEnd()` / `finalizeAssistantTexts()` properly handle the suppress flag
- Includes `collectMode` for subagent announce batching (related improvement)
**Commit 2: `fix(agents): buffer onBlockReply during streaming`**
- Introduces `pendingBlockReplies` buffer in the subscribe handler
- When `suppressPreToolText` is enabled, block replies are buffered during streaming
- On `message_end`, if the message contains tool use, buffered replies are discarded
- If no tool use, buffered replies are flushed normally
- Prevents partial text from leaking to Discord before we know if tools will be invoked
### Config example
```yaml
agents:
defaults:
suppressPreToolText: true
```
### Testing
- 12 tests in `pi-embedded-subscribe.suppress-pre-tool-text.test.ts`
- 4 tests in `zod-schema.agent-defaults.suppress-pre-tool-text.test.ts`
- All 16 tests pass
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR adds a `suppressPreToolText` config option that buffers `onBlockReply` payloads during assistant message streaming and discards them if the message ends with a tool call (`stopReason === "toolUse"`). This prevents intermediate narration like "Let me check that for you..." from reaching Discord/messaging channels. Final-answer turns are flushed normally.
The implementation touches the full config-to-subscribe pipeline: `AgentDefaultsConfig` -> `FollowupRun` -> `RunEmbeddedPiAgentParams` -> `SubscribeEmbeddedPiSessionParams` -> subscribe state, which is clean and consistent.
A secondary change fixes collect-mode subagent announce batching to always queue (even when the parent agent is idle), and bumps the default announce debounce from 1s to 3s.
- `suppressPreToolText` correctly buffers and discards intermediate text, with verbose-mode bypass for debugging
- `assistantTexts` splice logic removes intermediate texts from the accumulated array on tool-use turns
- `pendingBlockReplies` buffer is properly initialized, reset on message boundaries, and flushed/discarded at the end of `handleMessageEnd`
- Collect-mode early-return in `subagent-announce.ts` omits `announceId` from the queue item, which may weaken idempotency dedup (see inline comment)
- 16 new tests cover the feature comprehensively across splice logic, streaming buffering, verbose mode, and both `blockReplyBreak` modes
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge with one minor idempotency concern in the collect-mode announce path.
- The core suppressPreToolText feature is well-implemented with proper buffering, flushing, and state management. The config pipeline is complete and consistent. Tests are thorough (16 new tests). The one issue is the missing announceId in the collect-mode early-return path in subagent-announce.ts, which could allow duplicate announces in edge cases. The default debounce change from 1s to 3s is a behavior change but low-risk.
- src/agents/subagent-announce.ts — missing announceId in collect-mode queue item may weaken idempotency deduplication
<sub>Last reviewed commit: cd2462d</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#15864: feat: add deliverOnlyToolMessages config for clean messaging channe...
by gandalf-the-engineer · 2026-02-14
80.4%
#20052: fix(agents): suppress narration text when assistant message has too...
by lailoo · 2026-02-18
79.0%
#18934: fix(agents): suppress exec tool output from channel delivery
by BinHPdev · 2026-02-17
77.9%
#19235: fix(telegram): tool error warnings no longer overwrite streamed rep...
by gatewaybuddy · 2026-02-17
77.6%
#18916: fix(agents): suppress memory tool delivery to prevent reply drop
by BinHPdev · 2026-02-17
77.0%
#15996: fix(agents): messages arrive out of order — tool output beats narra...
by yinghaosang · 2026-02-14
76.9%
#14274: feat: add collapseReplyPayloads to collapse multi-message replies
by Henry-Roff-AI · 2026-02-11
76.8%
#19632: fix: suppressToolErrors now suppresses exec tool failure notifications
by Gitjay11 · 2026-02-18
76.2%
#18187: fix: tool summaries silently dropped when reasoningLevel is stream
by ayanesakura · 2026-02-16
76.2%
#13105: fix: debounce subagent lifecycle events to prevent premature announ...
by mcaxtr · 2026-02-10
76.2%