Skip to content

🧺 refactor: Move the Chat Follow-Up Queue State to Jotai - #16615

Merged
berry-13 merged 2 commits into
berry-13/chat-settings-ownersfrom
berry-13/chat-queue-owners
Oct 1, 2026
Merged

berry-13 merged 2 commits into
berry-13/chat-settings-ownersfrom
berry-13/chat-queue-owners

Conversation

@berry-13

@berry-13 berry-13 commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The follow-up queue and its run-end bookkeeping lived on the Recoil store even though only chat logic reads and writes it: the queue drain, steering, the SSE hook and the queue rail. That covers queuedMessagesByConvoId, settledQueuedTurnReceiptsByConvoId, pendingQueuedTurnEnqueueIdsByConvoId, the pane and parked run-end signals (runEndByIndex, pendingRunEndByConvoId) and the interrupt-drain flag (drainAfterAbortByIndex). The client state ownership rule in AGENTS.md makes state that a feature both writes and reads feature-owned Jotai, converted together with every reader and writer. The conversion was waiting on useResumeOnLoad.spec (#13811), which has merged.

This PR moves the group to Jotai in client/src/store/queue.ts and converts every consumer: useQueueDrain, useSteering, useSteerCancel, useSteerConvert, useChatHelpers, useResumableSSE and Queue.tsx. The run-end signals keep their nullable one-shot API as a writable derived atom over a FIFO: writing a value appends it, writing null consumes the oldest, and RESET clears the queue. Callbacks whose only state was this group became plain useCallbacks. Mixed callbacks keep their Recoil transaction and write the queue through the Jotai store in the same order as before.

Second link of the chat-owners stack, on top of #16604. Part of berry-13#186, which closes with #16604.

Type of change

  • Refactor
  • Tests / tooling / CI

Testing

Tested environments/configuration:

  • Jest (jsdom). Playwright mock harness through reviewctl verify (desktop light, desktop dark, mobile).

Automated tests:

  • npx jest --findRelatedTests <changed files> --maxWorkers=2: 494 suites, 6517 tests.
  • The specs now seed and read the queue through the Jotai store. resetQueueFamilies() isolates tests that share the default store. The useSteering context harness seeds the queue into its own provider store.
  • Added e2e/specs/mock/scenarios/queue-owners.spec.ts: interrupt and send stops the run and sends the follow-up next. The composer-queue scenarios cover queueing, draining, reordering and steer-to-queue on this branch.
  • A scenario for a follow-up queued in a chat the user left fails on canary as well, so it is not in this PR; that existing bug is [upstream #16615] A follow-up queued in a chat the user left never auto-sends on return berry-13/LibreChat#225.
  • npx tsc --noEmit -p client/tsconfig.json: clean. ESLint and Prettier: clean.
  • atoms.sh (chat C2): Jotai-defined feature-owned atoms go from 6 to 12 of the 26 in the audit list. queuedMessagesByConvoId, runEndByIndex, pendingRunEndByConvoId, drainAfterAbortByIndex, settledQueuedTurnReceiptsByConvoId and pendingQueuedTurnEnqueueIdsByConvoId now have Jotai definitions. Chat C1 is unchanged: each touched hook still imports Recoil for other atoms.

Screenshots / recordings

No user-facing change.

Risk / compatibility

The diff is 2,247 lines, but 1,277 with whitespace ignored. Removing the useRecoilCallback wrapper re-indents the callback bodies in useSteering and useQueueDrain, so review with "Hide whitespace" on.

Recoil callback snapshots were frozen at callback start, while Jotai store reads are live. Every converted callback reads before it writes in one synchronous pass, so the values it decides on are the same. Jotai's atomFamily stamps Date.now() when it creates a member, so one spec that relied on the first clock read being the submit time now pins the clock to the ACK instead. useResumableSSE.spec.ts also changes in #14731, and the two auto-merge cleanly.

Checklist

  • I reviewed my own changes
  • Relevant tests have been added or updated
  • Existing relevant tests pass
  • The change does not introduce new warnings or errors
  • User-facing or complex behavior is documented where necessary
  • Required dependency changes have been merged/published
  • Required documentation PR: N/A

The follow-up queue, its settled receipts and pending enqueue ids, the
pane and parked run-end signals, and the interrupt-drain flag are
written and read only by chat logic (queue drain, steering, the SSE
hook, the queue rail). They now live in store/queue as Jotai atoms with
every consumer converted. The run-end FIFO keeps its nullable one-shot
API as a writable derived atom.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-01T10:55:14.453012Z 784d110 PR opened
🔒 Security Review ✅ Completed 2026-10-01T10:58:34.417870Z 784d110 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@codegraph-librechat codegraph-librechat Bot added the 🗺️ Chat State Mgmt codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) label Oct 1, 2026
@berry-13
berry-13 merged commit 8093dc1 into berry-13/chat-settings-owners Oct 1, 2026
28 of 29 checks passed
@berry-13
berry-13 deleted the berry-13/chat-queue-owners branch October 1, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🗺️ Chat State Mgmt codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant