Skip to content

fix(server): preserve queued messages after usage limits - #13877

Merged
Yash-Singh1 merged 12 commits into
t3code/codex-turn-mappingfrom
t3code/89147132
Sep 27, 2026
Merged

Yash-Singh1 merged 12 commits into
t3code/codex-turn-mappingfrom
t3code/89147132

Conversation

@Yash-Singh1

@Yash-Singh1 Yash-Singh1 commented Sep 26, 2026 •

Copy link
Copy Markdown
Collaborator

A provider usage limit could send queued messages into the same exhausted allowance, while the queue hid the failed turn. After a stop, an empty composer also offered no direct way to continue the interrupted work.

Hold queued runs until the stopped turn continues. Keep the failed run visible in thread summaries, preserve restart-held queues, and offer scheduled recovery at the provider's reset time. On web and desktop, an empty composer now shows a play button for interrupted or limited turns. A manual click starts a guarded continuation ahead of queued messages, and a stale click cannot start a second one. The same button releases a queue held after a server restart.

A Stop from the client also holds the queue, as does a provider failure when the next queued message targets the same provider. Validation failures and messages queued for another provider still start automatically.

Checks: Focused server, composer, and queue tests passed. Server, web, client runtime, contracts, and shared typechecks passed. Targeted lint passed.

Resume play button in the empty composer with a queued message

Queue held after the user stops a run

Queue held after a provider error

Model: GPT-6
Harness: Codex

🤖 Generated with Claude Code

@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 26, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This is a cross-layer runtime behavior change that alters automatic queue dispatch and Stop semantics, persists queue-hold state, and introduces a new manual continuation action across the server, client, and web UI. Because it adds a user-facing workflow and gates provider work based on usage and failure state, it warrants human review.

You can add or adjust custom eligibility rules. Learn more.

Comment thread apps/server/src/orchestration-v2/Orchestrator.ts
@github-actions

github-actions Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ No successful main baseline artifact is available yet. This run establishes the initial measurement.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire — 4.9 KiB — 6.8 KiB ✅
Codex Thread snapshot wire — 3.7 KiB — 4.9 KiB ✅
Codex Live turn WebSocket wire — 1.1 KiB — 2.0 KiB ✅
Codex Live turn WebSocket decoded — 20.4 KiB — 29.3 KiB ✅
Codex Live turn messages — 1 — 8 ✅
Claude Total thread wire — 4.9 KiB — 6.8 KiB ✅
Claude Thread snapshot wire — 3.7 KiB — 4.9 KiB ✅
Claude Live turn WebSocket wire — 1.2 KiB — 2.0 KiB ✅
Claude Live turn WebSocket decoded — 20.8 KiB — 29.3 KiB ✅
Claude Live turn messages — 2 — 8 ✅

Baseline: unavailable · PR result: 258f994 · 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: 106.1 KiB
  • Claude decoded thread snapshot: 106.4 KiB

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

Comment thread packages/shared/src/orchestrationV2ThreadError.ts Outdated
Comment thread apps/web/src/components/ChatView.tsx
Comment thread apps/web/src/components/ChatView.tsx
Yash-Singh1 and others added 5 commits September 26, 2026 18:58
A provider that just failed will likely fail the next queued message too,
so hold the queue for the same provider until the user resumes it.
Validation failures and messages queued for another provider still start.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Sep 27, 2026
Comment thread apps/server/src/orchestration-v2/Orchestrator.ts
Comment thread apps/server/src/orchestration-v2/Orchestrator.ts
Yash-Singh1 and others added 2 commits September 26, 2026 23:42
A usage limit only blocks queued messages for the limited provider.
Queuing a message for a different provider is how users recover, so
it now starts automatically and queue.resume accepts it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread apps/server/src/orchestration-v2/Orchestrator.ts Outdated
…usage limit"

A queued message is meant to run after the current task finishes. A
usage limit stops that task, so every queued message waits for the user,
whichever provider it targets.

This reverts commit 2740d98.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Yash-Singh1
Yash-Singh1 merged commit 4018a6c into t3code/codex-turn-mapping Sep 27, 2026
25 checks passed
@Yash-Singh1
Yash-Singh1 deleted the t3code/89147132 branch September 27, 2026 05:45
@Yash-Singh1
Yash-Singh1 restored the t3code/89147132 branch September 27, 2026 05:45
dillonc-dev added a commit to exarch-run/t3code that referenced this pull request Sep 27, 2026
The usage-limit recovery sweep passed its auto-resume and snooze switches
to SQLite as JS booleans. Node 24.20, which Exarch bundles, refuses them
("Provided value cannot be bound to SQLite parameter 3"), so the sweep
failed every 5 seconds and logged "Scheduler source failed". Node 24.21 and
later accept booleans, which is why upstream's tests never saw it.

Both switches now go through the booleanInt helper the file already uses,
character for character as upstream e32db91 (PR pingdotgg#13877) does, so the
refresh that brings that commit merges cleanly.

The new test runs the real query on in-memory node:sqlite with a guard that
refuses boolean binds on any Node, across all four switch combinations.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 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.

1 participant