Repository navigation
Description
Problem (one or two sentences)
When the model reads 2 or more files in a row, the chat groups them into one "Zoo wants to read multiple files" card. After that card, the next turn's "API Request" row and its Thinking (reasoning) block are never shown. The chat looks frozen while the model reasons, sometimes for 30–50 seconds. The reasoning block stays hidden even after the turn finishes.
With no batched reads before it, the same reasoning block shows normally.
Steps to reproduce:
- Use a model that streams reasoning (OpenAI Compatible provider with
reasoning_content). - Ask something that makes the model call read_file 2 or more times in one turn.
- Approve the reads (auto-approve or manual).
- Watch the chat while the next request runs.
Expected: a new API Request row and the streaming Thinking block appear after the batched card.
Actual: nothing appears after the card until the model outputs visible text or another tool. That turn's Thinking block and API Request row are never shown.
Context (who is affected and when)
Environment: Zoo Code 3.88.0, VS Code on macOS, provider OpenAI Compatible with streaming reasoning_content.
Root cause: webview-ui/src/utils/batchNearby.ts. While collecting a batch, every ignorable message (api_req_started and reasoning, per isIgnorableBetweenTargets in chatBatchingPredicates.ts) goes into pendingIgnorable. When the batch has more than one item, all of pendingIgnorable is discarded ("pending ignorable items are metadata consumed by the batch"). That includes the ignorable messages after the last target, which belong to the next turn, so its api_req_started and reasoning rows are dropped.
Suggested fix: only drop ignorable messages between two targets and keep the trailing ones:
} else if (isTarget(items[j])) {
batch.push(items[j])
pendingIgnorable.length = 0 // between targets: consumed by the batch
j++
}
...
if (batch.length > 1) {
result.push(synthesize(batch))
result.push(...pendingIgnorable) // trailing items belong to the next turn
} else {
result.push(batch[0], ...pendingIgnorable)
}
The same issue affects list_files and file-edit batches, since they use the same batchNearby logic.
Reproduction steps
- Configure a provider that streams reasoning, e.g. OpenAI Compatible with
reasoning_contentin the stream deltas. - Start a task that makes the model call read_file 2 or more times in a single turn (e.g. "Compare file A and file B").
- Approve the reads, manually or with auto-approve. The chat shows one "Zoo wants to read multiple files" card.
- Watch the chat while the next API request runs (the model is reasoning).
- When the turn finishes, scroll up and check the area after the card.
Expected result
After the "Zoo wants to read multiple files" card, a new API Request row appears with the Thinking block, and the reasoning streams in real time while the model works. Both rows stay visible in the chat after the turn finishes.
Actual result
Nothing appears after the "Zoo wants to read multiple files" card while the next request runs, and the chat looks frozen. The response appears only when the model outputs visible text or another tool call. That turn's API Request row and Thinking block are never shown, not even after it finishes.
Variations tried (optional)
No response
App Version
v3.88.0
API Provider (optional)
OpenAI Compatible
Model Used (optional)
Haiku 5.5, Sonnet 5.5
Zoo Code Task Links (optional)
No response
Activity
PierrunoYT commentedon Oct 20, 2026
Working on this!
fix(chat): keep API request and reasoning rows after a batched group (Z…