Drop @ai-sdk/react and resumable-stream in favor of a unified GraphQL SSE
subscription for all agent chat events (token streaming, message persistence,
queue updates). This makes the architecture server-driven and eliminates
the class of bugs caused by dual-state (AI SDK internal state vs Jotai atoms).
Key changes:
- Backend: publish UIMessageChunks via Redis PubSub instead of HTTP SSE +
resumable-stream. New AgentChatEventPublisherService, subscription resolver,
and unified POST /:threadId/message endpoint (server decides queue vs stream).
- Frontend: new useAgentChatSubscription hook bridges graphql-sse events into
readUIMessageStream (from ai package) for chunk accumulation. Optimistic
rendering preserves user messages during streaming. SSE client recycling
triggers automatic resubscription.
- Queue: messages sent during active streaming are placed directly in queue
atoms (no flash). Server auto-flushes next queued message after stream ends.
Made-with: Cursor