mirror of
https://github.com/coder/coder.git
synced 2026-11-04 23:29:17 +08:00
> **PR Stack** > > 1. #23351 ← `#23282` > 2. **#23282** ← `#23275` *(you are here)* > 3. #23275 ← `#23349` > 4. #23349 ← `main` --- ## Summary Replaces raw error strings and infinite "Thinking..." spinners in the agents chat UI with a structured live-status model that drives startup, retry, and failure UI from one source of truth. This branch also folds in the frontend follow-up fixes that fell out of that refactor: malformed `retrying_at` timestamps no longer render `Retrying in NaNs`, stale persisted generic errors no longer outlive a recovered chat status, and partial streamed output stays visible when a response fails after blocks have already rendered. Consumes the structured error metadata added in #23275. Retry-After header handling remains in #23351. <img width="853" height="493" alt="image" src="https://github.com/user-attachments/assets/5a4a1690-5e22-4ece-965c-a000fd669244" /> <img width="812" height="517" alt="image" src="https://github.com/user-attachments/assets/e78d28ce-1566-48ca-a991-62c6e1838079" /> <img width="847" height="523" alt="image" src="https://github.com/user-attachments/assets/e5fd7b60-4a3c-4573-ba4c-4e5f6dbfbdc3" /> ## Problem The previous AgentDetail chat UI derived startup, retry, and failure behavior from several loosely connected bits of state spread across `ChatContext`, `AgentDetailContent`, `ConversationTimeline`, and ad hoc props. That made the UI inconsistent: some failures were just raw strings, retry state could only partially describe what was happening, startup could sit on an infinite spinner, and rendering decisions depended on local booleans instead of one authoritative model. Those splits also made edge cases brittle. Invalid retry timestamps could produce broken countdown text, persisted generic errors could linger after recovery, and streamed partial output could disappear if the turn later failed. ## Fix Introduce a structured live-status pipeline for AgentDetail. `ChatContext` now normalizes stream errors and retry metadata into richer state, `liveStatusModel` centralizes precedence and phase derivation, and `ChatStatusCallout` renders startup, retry, and terminal failure states with shared copy, provider attribution, status links, attempt metadata, and guarded countdown handling. `AgentDetailContent` and `ConversationTimeline` now consume that single model instead of juggling separate error and stream booleans, while usage-limit messaging stays on its explicit path. The result is a timeline that shows consistent state transitions, preserves accumulated assistant output across failures, suppresses stale generic errors once live state recovers, and has focused model, store, and story coverage around those behaviors.