Skip to content

fix(web): send queued messages in background threads - #13122

Closed
t3-code[bot] wants to merge 3 commits into
mainfrom
fix/background-thread-queues
Closed

t3-code[bot] wants to merge 3 commits into
mainfrom
fix/background-thread-queues

Conversation

@t3-code

@t3-code t3-code Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

problem

queued follow-ups were only processed by the selected ChatView. switching threads left the previous thread's queue waiting until it was selected again.

fix

add an app-level processor that subscribes only to threads with queued messages. the selected thread keeps its existing send path; other threads can send at the same tool/turn boundaries without mounting hidden chat views. this also keeps queues running while settings is open.

background sends use the original thread/environment and a snapshot of the queued model and modes. they wait for connection, hydration, approval/question, and checkpoint-rewind gates. messages stay cancellable during uploads. an atomic take claims the send before persistent settings updates, and a per-thread in-flight marker keeps Stop effective through those updates and prevents competing foreground sends. failed sends return to the queue held for manual retry, without touching the selected composer's draft.

verification

  • reproduced the original failure before implementation: finishing thread a while b was selected produced zero sends.
  • 74 focused tests passed across the queue store, background processor/sender, context records, and composer validation.
  • coverage includes navigating away, a mounted processor through the real send preparation path, text-only turn boundaries, delayed dispatch receipts, reconnection, approvals/questions, rewind, attachments/context, cancellation during upload, held failures, concurrent preparation, late shell hydration, and claiming an intent before thread mutations.
  • web typecheck passed. targeted lint passed for all new files and the queue store. existing ChatView lint warnings remain outside this change.
  • tests use controlled environment updates and mocked transport/upload boundaries. no live provider or full desktop/browser run was performed.

web and desktop share this implementation. native mobile's separate queue is unchanged.

request provenance

requested by @extoci.

implemented with gpt-6-astra using hermes agent.

Closes #13676

Co-authored-by: Exotic <118054752+extoci@users.noreply.github.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 22, 2026
Comment thread apps/web/src/lib/sendBackgroundQueuedMessage.ts
Comment thread apps/web/src/lib/sendBackgroundQueuedMessage.ts
@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.5 KiB 13.5 KiB +31 B (+0.2%) 15.1 KiB ✅
Codex Thread snapshot wire 7.1 KiB 7.1 KiB −1 B (−0.0%) 7.3 KiB ✅
Codex Live turn WebSocket wire 6.4 KiB 6.5 KiB +32 B (+0.5%) 7.8 KiB ✅
Codex Live turn WebSocket decoded 56.2 KiB 56.3 KiB +44 B (+0.1%) 66.4 KiB ✅
Codex Live turn messages 9 10 +1 (+11.1%) 21 ✅
Claude Total thread wire 13.5 KiB 13.5 KiB +20 B (+0.1%) 15.1 KiB ✅
Claude Thread snapshot wire 7.1 KiB 7.1 KiB +3 B (+0.0%) 7.3 KiB ✅
Claude Live turn WebSocket wire 6.4 KiB 6.5 KiB +17 B (+0.3%) 7.8 KiB ✅
Claude Live turn WebSocket decoded 57.0 KiB 57.0 KiB 0 B (0.0%) 66.4 KiB ✅
Claude Live turn messages 9 9 0 (0.0%) 21 ✅

Baseline: f193a68 · PR result: 77372f9 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 113.9 KiB
  • Claude decoded thread snapshot: 114.6 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@macroscopeapp

macroscopeapp Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces substantial production behavior that automatically dispatches queued messages across navigation, including attachment uploads, persistent thread-setting updates, and provider-turn creation. An unresolved Medium-severity path can also leave uploaded attachments pending for up to 24 hours after cancellation.

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

Co-authored-by: Exotic <118054752+extoci@users.noreply.github.com>
Comment thread apps/web/src/lib/sendBackgroundQueuedMessage.ts
@macroscopeapp

macroscopeapp Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

All clear

Posted via Macroscope — UI Consistency

Co-authored-by: Exotic <118054752+extoci@users.noreply.github.com>
Comment thread apps/web/src/lib/sendBackgroundQueuedMessage.ts
@t3-code

t3-code Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor Author

@macroscopeapp please refresh approvability for 77372f9. the valid findings are fixed and tested. the latest attachment-release suggestion was resolved with source evidence: Cancel/Stop restores the attachment to the composer, and transient readiness gates retain queued ownership, so releasing the pending upload at that return would break retained attachments. latest CI is green.

@juliusmarminge

Copy link
Copy Markdown
Member

Superseded by #13764, which already landed the same fix (queued messages send while their thread is not open) and closed #13676 / #13319.

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:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Queued follow-up never sends while you're on another thread; dispatch only runs in the active ChatView

1 participant