98ad9a2557
Root cause: when SSE delivered any chunk, maxAttempts was set to 1 with no delay. That single immediate poll hit the server before it finished writing to the DB, received status='generating' with empty content, then overwrote the SSE-streamed text with the stale empty row and exited. isStreaming went false and the UI was stuck showing '...'. Two fixes: 1. Always poll up to 20 times regardless of SSE success. SSE closing does not mean the server has committed the final row to the DB. 2. When SSE delivered content, only replace state with polled data if the polled assistant message is complete or has content — this prevents clobbering streamed text with a stale empty DB row while the server is still writing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>