Repository navigation
fix(frontend): keep a sent message when the user switches sessions - #7834
Conversation
A first send waits for the workflow before it goes out. If the user opened another session meanwhile, the workflow query that was still loading never reached the unsubscribed atom the request builder reads, so the send timed out and the failure path deleted the fresh session row. Hold the workflow subscription while the request is built, so the send goes out off screen. When a send still fails after the screen closed, keep the session and store the message as a failed task that the chat screen offers again with its retry.
📝 Summary
Merge Risk:
|
Website previewPreview URL: https://pr-7834-agenta-website-preview.mahmoud-637.workers.dev Built from |
|
@coderabbitai review |
✅ Action performed
|
There was a problem hiding this comment.
Actionable comments posted: 1

Review info
-
Run configuration-
- Source mode: Auto
- Repository: Agenta-AI/agenta
- Branch: fix/frontend-lost-message-on-session-switch
- File: .coderabbit.yaml
- Commit: 0d036f9
- Layers: Repository YAML (base), Organization UI (inherited)
- Review profile: CHILL
- Plan: Advanced
- Run ID:
28cf6897-70b9-4051-8edd-4ddc090f8d82
Files selected for processing: 8-
web/mobile/src/features/chat/LiveConversation.tsxweb/mobile/src/features/home/pendingTask.tsweb/mobile/tests/unit/liveConversationOffScreenFailure.render.test.tsxweb/mobile/tests/unit/liveConversationReadOnly.render.test.tsxweb/packages/agenta-chat/src/hooks/useAgentChatQueue.tsweb/packages/agenta-chat/src/hooks/useAgentConversation.tsweb/packages/agenta-chat/src/hooks/useServerSessionInputs.tsweb/packages/agenta-chat/tests/unit/hooks/useServerSessionInputs.offScreen.test.ts
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 4 remain after this review.
-
Context
A user types the first message in a new agent session and presses send. Starting the turn can take a while on a loaded box. If the user opens another session in the sidebar during that wait, the message is never sent. When they come back, the session and the message are gone.
The cause is in how the send builds its request. Before
/invokegoes out,useServerSessionInputs.submitwaits (up to 15 s) for the workflow's invocation URL, andbuildAgentRequestreads it withstore.get, which does not subscribe. While the chat screen is open, the screen keeps the workflow query subscribed. After a session switch, nothing holds it. A jotai atom nobody subscribes to does not take the data its query loads later, so if the workflow was still loading at the switch, every build returnednulluntil the deadline failed the send with "The agent is not ready to accept input." The failure path then calleddropUnacceptedLocalSession, which deleted the fresh session row, and tried to put the text back into a composer that no longer existed.Once
/invokehas left the browser, a switch is already safe: the fetch has no abort signal and nothing cancels the stream on unmount.Changes
submitsubscribes toworkflowMolecule.selectors.invocationUrl(entityId)while the request builds and releases the subscription right after. A workflow that finishes loading off screen now reaches the builder, and the send goes out.LiveConversationknows when it has unmounted. If a send fails while the screen is still open, nothing changes: the fresh session row is dropped and the text goes back to the composer. If it fails after the screen closed, the session row stays, and a newkeepFailedSendAtomputs the message intopendingTasksAtomas a failed task (text, file parts, and the refusal's own reason when there is one). When the user comes back, the existingPendingTaskErrorcard ("Message not sent", "Retry message") shows it. A Home task already in that slot is left tosendPendingTaskAtom, which already marks it failed.To carry the refusal reason,
onSendFailednow also receives the error that rejected the send:(message, error?) => void.Tests
useServerSessionInputs.offScreen.test.ts: a send waits on a workflow that is still loading, the screen's subscription goes away and the hook unmounts, then the workflow loads./invokeis called once. Without the fix it is never called.liveConversationOffScreenFailure.render.test.tsx: a failure after unmount keeps the session and stores a failed task with its reason, and the task shows again on remount. A Home task in the slot is left alone. A failure while mounted still drops the session row and stores no task. The first two cases fail without the fix.pnpm --filter @agenta/chat test:unit(1404 passed),pnpm --filter @agenta/mobile test:unit(675 passed),types:checkfor both,pnpm lint-fixinweb/.atomWithQuerynever takes data that lands after its last subscriber left; holding a subscription fixes it) with a scratch vitest against the repo's installed jotai and jotai-tanstack-query.What to QA