← Back to PRs

#12974: fix: intermittent (no output) reported by users

by vincentkoc open 2026-02-10 00:46 View on GitHub →
agents stale size: S
This addresses intermittent "(no output)" reports by preserving assistant-visible text in finalization paths. The goal is to avoid empty chat finals when providers emit non-text block shapes or error-only assistant completions. Issue 1 is a run-finalization gap between the agent pipeline and the gateway chat stream: once a run is marked as agent-started, `chat.send` no longer uses its local final-text fallback, and the gateway emits `chat.state="final"` from the streamed assistant buffer only. If that buffer is empty (for example when the assistant ends with an error-only message, tool-only behavior, or no emitted assistant delta), the final chat event has no `message`, and the TUI resolves that to `(no output)`. This explains the intermittent “works sometimes” pattern and why restarting can appear to help without fixing root behavior. Issue 2 is content-shape mismatch in text extraction: several extraction paths only read blocks with `type: "text"` and ignore other valid text-like formats such as `output_text`. When a provider/model returns content in those alternate shapes, the system can treat a real answer as empty, which again feeds into the same “no output” symptom. This aligns with reports that it happens across specific providers/models and can look inconsistent across channels. - Fixes #5030 <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This change set attempts to eliminate intermittent “(no output)” finals in the TUI by (1) preserving assistant-visible text through agent run finalization paths, and (2) expanding text extraction to handle alternate provider content shapes (e.g., `output_text`) so the gateway/TUI final message buffer isn’t empty. The updates span the embedded PI agent pipeline (message handling + final-output suppression filtering), shared embedded utilities (text extraction), heartbeat runner (finalization behavior), and TUI formatters + tests (rendering/formatting when the final message is missing or non-text). Overall, the intent is to ensure that when providers emit tool-only/error-only/non-`text` blocks, user-facing final events still contain assistant-readable content or a safe fallback rather than resolving to `(no output)`. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk. - Changes are narrowly focused on text extraction/finalization edge-cases and are backed by targeted tests across the agent embedded utilities and TUI formatting paths; I did not find any new logic that would break normal streaming or introduce security concerns. - No files require special attention <!-- greptile_other_comments_section --> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs