#12180: fix: merge multi-block assistant texts into single reply
agents
stale
When a model (e.g. Claude with interleaved thinking blocks) produces multiple text content blocks in a single assistant message, each block was being delivered as a separate outbound message (e.g. multiple iMessage bubbles). This merges them into a single coherent reply when block streaming is off.
## Problem
Claude API can return multiple `text` content blocks in a single assistant turn. The `buildEmbeddedRunPayloads` function creates a separate reply payload for each text block, resulting in multiple outbound messages (e.g. 2-3 iMessage bubbles for what should be a single response).
## Fix
Before iterating over `answerTexts`, merge adjacent text blocks into a single string joined by `\n\n`. This ensures the model's multi-block response is delivered as one coherent message.
## Testing
- All 4904 existing tests pass
- `payloads.test.ts` (12 tests) all pass
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This change updates `buildEmbeddedRunPayloads` to collapse multiple assistant `text` content blocks into a single outbound reply (joined with `\n\n`) to avoid sending multiple message “bubbles” when block streaming is disabled.
The logic sits in the embedded runner’s payload builder, which is responsible for turning assistant output (plus optional tool meta, reasoning text, and error messages) into a list of user-facing reply payloads. The new merge happens right before iterating and parsing reply directives for each outgoing message.
<h3>Confidence Score: 3/5</h3>
- This PR is moderately safe to merge, but it can change behavior for replies that rely on per-block directives/media parsing.
- The merge accomplishes the stated goal, but it changes the unit of parsing for `parseReplyDirectives` by combining multiple blocks into one, which can break cases where directives or media tags are intended to apply to a specific block. If directives are present in any merged block, the resulting payload fields may be incorrect or lost.
- src/agents/pi-embedded-runner/run/payloads.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#5080: fix(reply): fix duplicate block replies by unblocking coalesced pay...
by yassine20011 · 2026-01-31
79.6%
#14946: fix(webchat): accumulate text across blocks in streaming buffer
by mcaxtr · 2026-02-12
78.0%
#10612: fix: trim leading blank lines on first emitted chunk only (#5530)
by 1kuna · 2026-02-06
77.7%
#14274: feat: add collapseReplyPayloads to collapse multi-message replies
by Henry-Roff-AI · 2026-02-11
77.3%
#17953: fix(telegram): prevent silent message loss and duplicate messages i...
by zuyan9 · 2026-02-16
76.8%
#8205: fix: flush followup messages incrementally
by hanxiao · 2026-02-03
76.4%
#14216: fix(messaging): check both pipeline and direct keys for reply deduping
by F1xTrack · 2026-02-11
76.0%
#23462: fix: extract thinking blocks as fallback in extractTextFromChatContent
by nszhsl · 2026-02-22
74.6%
#4495: Fix: emit final assistant event when reply tags hide stream
by ukeate · 2026-01-30
74.4%
#16733: fix(ui): avoid injected newlines when tool output is hidden
by jp117 · 2026-02-15
74.3%