Skip to content

fix(clients): sync thread modes across devices - #5519

Closed
Lucenx9 wants to merge 2 commits into
pingdotgg:mainfrom
Lucenx9:codex/fix-thread-mode-sync
Closed

fix(clients): sync thread modes across devices#5519
Lucenx9 wants to merge 2 commits into
pingdotgg:mainfrom
Lucenx9:codex/fix-thread-mode-sync

Conversation

@Lucenx9

@Lucenx9 Lucenx9 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Closes #5278

Problem

Runtime and interaction mode changes on an existing thread were stored as device-local composer overrides until the next message was sent. Other clients could therefore keep showing and using a different mode for the same server-backed thread. The optimistic override was also cleared by value equality, which could mis-handle rapid A → B → A changes or hide a later remote update.

Fix

  • Dispatch the existing thread mode commands immediately from web/desktop and mobile.
  • Track each optimistic change by commandId and the returned DispatchResult.sequence; clear it only after the environment shell has applied that sequence or a later one.
  • Persist pending mobile mode changes and retry transient failures with the same commandId from a root sync worker, so retries survive reconnects, navigation, and app restarts.
  • Roll back terminal failures, ignore stale callbacks, and keep legacy server-thread draft modes from overriding server state after hydration.
  • Preserve new-task settings, pending-task settings, and unsent draft content.

Impact

Mode changes persist as thread state and propagate across local, remote, and multi-device clients without requiring a prompt. Rapid local changes and remote overwrites no longer depend on matching values to acknowledge an update. Web and desktop share the web implementation; mobile uses the same server commands and a persistent retry path. Provider adapters and wire contracts are unchanged.

There are no visual changes, so before/after screenshots would be identical.

Validation

  • vp test run packages/client-runtime/src/state/threadModeSync.test.ts apps/mobile/src/state/use-composer-drafts.test.ts apps/web/src/composerDraftStore.test.ts (92 tests)
  • Typecheck: @t3tools/client-runtime, @t3tools/mobile, and @t3tools/web
  • Targeted lint and format check for all changed source files
  • React Doctor changed-lines scan (0 errors, 0 warnings)

Model: OpenAI Codex (GPT-5)
Harness: Codex desktop app


Note

Medium Risk
Touches cross-client thread state, optimistic UI, persistence hydration, and background dispatch/retry paths; server commands are existing but client coordination bugs could show wrong modes or duplicate sends.

Overview
Thread mode changes on existing server-backed threads now sync immediately instead of staying as device-local composer overrides until the next message.

A shared thread-mode-sync helper in client-runtime tracks optimistic mode updates (command id, dispatch sequence, ack/fail/retry rules). Web/desktop dispatches setRuntimeMode / setInteractionMode on change, keeps a short-lived composer override, then clears it when the environment shell sequence confirms or on terminal failure (error toast).

Mobile stores the same pending sync on composer drafts, runs a new useThreadModeSyncDrain alongside the outbox drain in BackgroundSyncWorker, and retries like the outbox. Hydration drops stale runtimeMode / interactionMode on existing-thread draft keys unless a pending sync is present (new-task and pending-task drafts unchanged). Mode toggles no-op when already active; connection errors use id-scoped pending error clearing to avoid races.

Reviewed by Cursor Bugbot for commit 03787b3. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Sync thread runtime and interaction mode changes across devices with pending state and retry

  • Adds a PendingThreadModeSync abstraction in threadModeSync.ts with helpers to begin, dispatch, acknowledge, and fail pending mode syncs based on environment snapshot sequences.
  • On mobile, useThreadComposerState records pending runtimeModeSync/interactionModeSync in composer drafts when mode changes are initiated; useThreadModeSyncDrain dispatches these in the background with exponential backoff and acknowledgment.
  • On web, ChatViewContent dispatches mode changes immediately, tracks pending sync state, acknowledges on snapshot sequence catchup, and shows a toast on terminal failure while rolling back draft overrides.
  • ComposerDraft is extended to store pending mode sync fields; existing thread drafts no longer hydrate server-owned modes directly.
  • Behavioral Change: drafts for existing threads that contain only pending mode sync metadata are now retained rather than dropped as empty.

Macroscope summarized 03787b3.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b77e542b-94e6-4bd7-b900-ed96a0ae39de

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 6, 2026
Comment thread apps/mobile/src/state/use-thread-composer-state.ts Outdated
@Lucenx9
Lucenx9 force-pushed the codex/fix-thread-mode-sync branch from 4d7d5b8 to 86fbe33 Compare August 6, 2026 13:46
@Lucenx9
Lucenx9 marked this pull request as ready for review August 6, 2026 13:46

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 86fbe3313e

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/mobile/src/state/use-composer-drafts.ts Outdated
Comment thread apps/mobile/src/state/use-thread-composer-state.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces cross-device thread mode synchronization - a new feature with significant new logic across mobile and web clients. The scope of changes (new files, new state management, retry logic) combined with unresolved review comments identifying potential bugs (mode overrides not clearing properly on draft routes) warrants human review.

You can customize Macroscope's approvability policy. Learn more.

@Lucenx9
Lucenx9 force-pushed the codex/fix-thread-mode-sync branch from 86fbe33 to c4d5af5 Compare August 6, 2026 13:59
Comment thread apps/mobile/src/state/use-thread-composer-state.ts Outdated
@Lucenx9
Lucenx9 force-pushed the codex/fix-thread-mode-sync branch from c4d5af5 to 1298ae5 Compare August 6, 2026 14:07
Comment thread apps/mobile/src/state/use-thread-composer-state.ts Outdated
Comment thread apps/web/src/components/ChatView.tsx
@Lucenx9
Lucenx9 force-pushed the codex/fix-thread-mode-sync branch from 1298ae5 to 702984a Compare August 6, 2026 14:17

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 03787b3. Configure here.

setComposerDraftInteractionMode,
setComposerDraftRuntimeMode,
updatePendingInteractionModeSync,
updatePendingRuntimeModeSync,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Draft route never clears mode overrides

Medium Severity

Mode sync still runs on draft routes once a server thread exists (serverModeThreadId), but acknowledgment only runs when routeKind === "server". Pending sync state and composer overrides on the draft target therefore never clear while the draft route stays mounted, so remote mode updates stay hidden until navigation.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 03787b3. Configure here.

if (next !== currentPending) {
input.writePending(next);
}
clearRetry(commandId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mode sync errors never clear

Low Severity

Terminal mode-sync failures call setPendingConnectionError, but a later successful dispatch only records the sequence and never clears that pending error. The prior in-composer flow cleared the error by id on success, so failed-then-succeeded mode changes can leave a stale pairing/connection error around.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 03787b3. Configure here.

@Lucenx9 Lucenx9 closed this Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Thread interaction and runtime modes do not sync between desktop clients

1 participant