feat: resume threads after usage limits reset - #8577

Open
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit
Open

feat: resume threads after usage limits reset#8577
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit

Conversation

@Kron00

@Kron00Kron00 commented Aug 28, 2026

Copy link
Copy Markdown

I don't expect this to get merged. It's a working idea you guys can take further if any of it is useful.

Problem

When a provider usage limit stops a long-running thread, users have to remember to reopen it after their subscription resets. Threads that were already doing useful work can sit unfinished even while T3 is still running on their computer.

Fix

  • classify native usage-limit errors from Codex, Claude, Cursor, Grok, and OpenCode
  • add a "Resume when available" action with a visible scheduled state and cancellation
  • persist the schedule so server restarts and reconnects do not lose it
  • resume the same thread with a hidden continuation prompt when the reset time arrives
  • use provider reset timestamps when available, then back off retries when the provider does not supply one
  • cancel safely on settlement, deletion, archival, or newer work, and revalidate timers before starting a provider turn

This PR is desktop/web only. Mobile is unchanged.

Verification

  • 704 focused tests across 25 files after updating from the current base branch
  • focused Grok adapter and xAI extension rate-limit tests
  • vp run --filter @t3tools/contracts typecheck
  • vp run --filter @t3tools/client-runtime typecheck
  • vp run --filter t3 typecheck
  • vp run --filter @t3tools/web typecheck
  • targeted lint for changed provider adapters
  • git diff --check
  • tested the real Codex, Claude, Cursor, Grok, and OpenCode harness error formats against controlled local rate-limit responders
  • recorded a desktop end-to-end pass where an existing Grok thread scheduled, fired, and resumed automatically
  • repeated the live Grok pass after review fixes and observed the next paced retry when Grok remained limited

Visual evidence

Limit reachedResume scheduled
Usage-limit banner with Resume when availableScheduled automatic resume with cancellation

Live retry remains limited and schedules the next attempt

Desktop end-to-end recording

Generated with GPT-5.6 Sol in T3 Code through the Codex harness.


Note

Medium Risk
Touches core orchestration, provider turn dispatch, and new durable projection fields; incorrect timer or cancel logic could retry turns at the wrong time or leave stale resume state after lifecycle changes.

Overview
Adds durable automatic resume when provider turns stop on usage limits: new orchestration commands/events (schedule, attempt, retry, cancel), projection columns (usage_limit_resume_json, session last_error_class/retry_at), and the threadUsageLimitResume server capability.

ProviderCommandReactor schedules timers from resume events, restores them on startup (with repair for in-flight attempts), retries failed dispatches with backoff, and on attempt fires a hidden Continue from where you left off. turn without a new user message. Failures re-classify usage limits, pace retries via nextUsageLimitRetryAt, and cancel when work is superseded or the thread is settled/archived/deleted.

Decider enforces invariants (usage-limit session required, future resumeAt) and emits companion cancel/interrupt events on settle, delete, archive, manual turn, and interrupt. ProviderRuntimeIngestion persists typed usage_limit/retryAt on runtime errors, reschedules or cancels in-flight resume, and avoids carrying stale error metadata on unrelated session errors.

Snapshot queries and migration 044 expose resume state to clients; tests cover reactor recovery, OpenCode trailing-error ordering, and decider/projector lifecycles. Mock ACP agent gains configurable prompt failure message.

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

Note

Add automatic thread resume after usage limits reset

  • Introduces contracts for OrchestrationRuntimeErrorClass, ThreadUsageLimitResume, and related commands/events in orchestration.ts.
  • Server orchestrator classifies usage-limit errors from providers, tracks lastErrorClass and retryAt, and schedules/cancels durable timers to automatically resume threads.
  • Web UI and client runtime track resume state and expose user actions to schedule or cancel auto-resume.
  • Risk: Database migration 044_UsageLimitResume in 044_UsageLimitResume.ts adds new columns to projection_threads and projection_thread_sessions.

Macroscope summarized b6a9d16.

@coderabbitai

coderabbitaiBot commented Aug 28, 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: 658c7c3a-f1ed-4e41-b96e-9aa91ef5b044

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

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 28, 2026

@macroscopeappmacroscopeappBot 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.

Reviewed the web UI changes (ChatView.tsx, chat/ThreadErrorBanner.tsx). The banner itself composes the shared Alert/Button primitives correctly (size="xs" + variant="outline" matches the parked-thread banner action). Three findings on the new usage-limit resume surface in ChatView.tsx.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
Comment threadpackages/contracts/src/orchestration.ts

@macroscopeappmacroscopeappBot 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.

One finding on the usage-limit banner: the dismiss affordance is rendered but cannot hide the banner for a usage-limit error with no pending resume.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated

@macroscopeappmacroscopeappBot 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.

One minor copy inconsistency in the new banner action; everything else (primitive reuse, size="xs"/variant="outline" in AlertAction, timestamp formatting via snoozeWakeDescription, thread-scoped environment routing for the new commands) matches existing patterns.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/chat/ThreadErrorBanner.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding in the reactor's startup reconciliation of pending usage-limit resumes. Details inline.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated

@macroscopeappmacroscopeappBot 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.

Reviewed the new usage-limit resume services against the Effect service conventions. One finding: the shared usage-limit dispatch retry is unbounded and does not isolate persistent failures.

Posted via Macroscope — Effect Service Conventions

@Kron00
Kron00 marked this pull request as ready for review August 28, 2026 23:01

@macroscopeappmacroscopeappBot 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.

One finding on the new usage-limit resume banner wiring in ChatView.tsx. The earlier notes on the pending label, the dismissal mask, and the timestamp format look resolved.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a default-enabled capability and a broad server/client workflow that persists usage-limit state, schedules retries across restarts, and automatically starts provider turns. Its cross-cutting orchestration, provider, persistence, and lifecycle side effects require human review.

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

Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/decider.ts

@macroscopeappmacroscopeappBot 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.

Reviewed the changed web UI (ChatView.tsx, chat/ThreadErrorBanner.tsx, chat/usageLimitResumePresentation.ts) against the shared component system and the repo's environment/capability conventions.

The banner work itself now lines up with the primitives: ThreadErrorBanner keeps Alert/AlertAction ownership, the new action uses Button size="xs" variant="outline" (same geometry as the existing icon-xs dismiss control, so the h-lh / min-h-7 sm:min-h-6 first-line alignment contract still holds), the composer status banner matches its peer ComposerBannerStackItems, and the scheduled time is formatted through snoozeWakeDescription(..., timestampFormat) rather than a raw Intl call.

One finding: the new environment-scoped resume actions are offered without a server capability gate, unlike every other server-backed thread action in this file. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadpackages/client-runtime/src/state/usageLimitResume.ts

@cursorcursorBot 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 1 potential issue.

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 df9fdff. Configure here.

@rix1337

Copy link
Copy Markdown

Not commenting on the implementation details here, but I’d consider this a high-priority feature from a product perspective.

Automatic resume after usage limits reset is becoming an expected capability in long-running coding agents. Claude Code has recently added similar behavior, and other agent/harness tools are moving in the same direction.

For unattended or long-running work, requiring the user to remember to manually resume a task hours later is a significant reliability gap.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Kron00@rix1337
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: resume threads after usage limits reset - #8577

Open
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit
Open

feat: resume threads after usage limits reset#8577
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit

Conversation

@Kron00

@Kron00Kron00 commented Aug 28, 2026

Copy link
Copy Markdown

I don't expect this to get merged. It's a working idea you guys can take further if any of it is useful.

Problem

When a provider usage limit stops a long-running thread, users have to remember to reopen it after their subscription resets. Threads that were already doing useful work can sit unfinished even while T3 is still running on their computer.

Fix

  • classify native usage-limit errors from Codex, Claude, Cursor, Grok, and OpenCode
  • add a "Resume when available" action with a visible scheduled state and cancellation
  • persist the schedule so server restarts and reconnects do not lose it
  • resume the same thread with a hidden continuation prompt when the reset time arrives
  • use provider reset timestamps when available, then back off retries when the provider does not supply one
  • cancel safely on settlement, deletion, archival, or newer work, and revalidate timers before starting a provider turn

This PR is desktop/web only. Mobile is unchanged.

Verification

  • 704 focused tests across 25 files after updating from the current base branch
  • focused Grok adapter and xAI extension rate-limit tests
  • vp run --filter @t3tools/contracts typecheck
  • vp run --filter @t3tools/client-runtime typecheck
  • vp run --filter t3 typecheck
  • vp run --filter @t3tools/web typecheck
  • targeted lint for changed provider adapters
  • git diff --check
  • tested the real Codex, Claude, Cursor, Grok, and OpenCode harness error formats against controlled local rate-limit responders
  • recorded a desktop end-to-end pass where an existing Grok thread scheduled, fired, and resumed automatically
  • repeated the live Grok pass after review fixes and observed the next paced retry when Grok remained limited

Visual evidence

Limit reachedResume scheduled
Usage-limit banner with Resume when availableScheduled automatic resume with cancellation

Live retry remains limited and schedules the next attempt

Desktop end-to-end recording

Generated with GPT-5.6 Sol in T3 Code through the Codex harness.


Note

Medium Risk
Touches core orchestration, provider turn dispatch, and new durable projection fields; incorrect timer or cancel logic could retry turns at the wrong time or leave stale resume state after lifecycle changes.

Overview
Adds durable automatic resume when provider turns stop on usage limits: new orchestration commands/events (schedule, attempt, retry, cancel), projection columns (usage_limit_resume_json, session last_error_class/retry_at), and the threadUsageLimitResume server capability.

ProviderCommandReactor schedules timers from resume events, restores them on startup (with repair for in-flight attempts), retries failed dispatches with backoff, and on attempt fires a hidden Continue from where you left off. turn without a new user message. Failures re-classify usage limits, pace retries via nextUsageLimitRetryAt, and cancel when work is superseded or the thread is settled/archived/deleted.

Decider enforces invariants (usage-limit session required, future resumeAt) and emits companion cancel/interrupt events on settle, delete, archive, manual turn, and interrupt. ProviderRuntimeIngestion persists typed usage_limit/retryAt on runtime errors, reschedules or cancels in-flight resume, and avoids carrying stale error metadata on unrelated session errors.

Snapshot queries and migration 044 expose resume state to clients; tests cover reactor recovery, OpenCode trailing-error ordering, and decider/projector lifecycles. Mock ACP agent gains configurable prompt failure message.

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

Note

Add automatic thread resume after usage limits reset

  • Introduces contracts for OrchestrationRuntimeErrorClass, ThreadUsageLimitResume, and related commands/events in orchestration.ts.
  • Server orchestrator classifies usage-limit errors from providers, tracks lastErrorClass and retryAt, and schedules/cancels durable timers to automatically resume threads.
  • Web UI and client runtime track resume state and expose user actions to schedule or cancel auto-resume.
  • Risk: Database migration 044_UsageLimitResume in 044_UsageLimitResume.ts adds new columns to projection_threads and projection_thread_sessions.

Macroscope summarized b6a9d16.

@coderabbitai

coderabbitaiBot commented Aug 28, 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: 658c7c3a-f1ed-4e41-b96e-9aa91ef5b044

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

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 28, 2026

@macroscopeappmacroscopeappBot 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.

Reviewed the web UI changes (ChatView.tsx, chat/ThreadErrorBanner.tsx). The banner itself composes the shared Alert/Button primitives correctly (size="xs" + variant="outline" matches the parked-thread banner action). Three findings on the new usage-limit resume surface in ChatView.tsx.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
Comment threadpackages/contracts/src/orchestration.ts

@macroscopeappmacroscopeappBot 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.

One finding on the usage-limit banner: the dismiss affordance is rendered but cannot hide the banner for a usage-limit error with no pending resume.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated

@macroscopeappmacroscopeappBot 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.

One minor copy inconsistency in the new banner action; everything else (primitive reuse, size="xs"/variant="outline" in AlertAction, timestamp formatting via snoozeWakeDescription, thread-scoped environment routing for the new commands) matches existing patterns.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/chat/ThreadErrorBanner.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding in the reactor's startup reconciliation of pending usage-limit resumes. Details inline.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated

@macroscopeappmacroscopeappBot 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.

Reviewed the new usage-limit resume services against the Effect service conventions. One finding: the shared usage-limit dispatch retry is unbounded and does not isolate persistent failures.

Posted via Macroscope — Effect Service Conventions

@Kron00
Kron00 marked this pull request as ready for review August 28, 2026 23:01

@macroscopeappmacroscopeappBot 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.

One finding on the new usage-limit resume banner wiring in ChatView.tsx. The earlier notes on the pending label, the dismissal mask, and the timestamp format look resolved.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a default-enabled capability and a broad server/client workflow that persists usage-limit state, schedules retries across restarts, and automatically starts provider turns. Its cross-cutting orchestration, provider, persistence, and lifecycle side effects require human review.

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

Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/decider.ts

@macroscopeappmacroscopeappBot 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.

Reviewed the changed web UI (ChatView.tsx, chat/ThreadErrorBanner.tsx, chat/usageLimitResumePresentation.ts) against the shared component system and the repo's environment/capability conventions.

The banner work itself now lines up with the primitives: ThreadErrorBanner keeps Alert/AlertAction ownership, the new action uses Button size="xs" variant="outline" (same geometry as the existing icon-xs dismiss control, so the h-lh / min-h-7 sm:min-h-6 first-line alignment contract still holds), the composer status banner matches its peer ComposerBannerStackItems, and the scheduled time is formatted through snoozeWakeDescription(..., timestampFormat) rather than a raw Intl call.

One finding: the new environment-scoped resume actions are offered without a server capability gate, unlike every other server-backed thread action in this file. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadpackages/client-runtime/src/state/usageLimitResume.ts

@cursorcursorBot 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 1 potential issue.

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 df9fdff. Configure here.

@rix1337

Copy link
Copy Markdown

Not commenting on the implementation details here, but I’d consider this a high-priority feature from a product perspective.

Automatic resume after usage limits reset is becoming an expected capability in long-running coding agents. Claude Code has recently added similar behavior, and other agent/harness tools are moving in the same direction.

For unattended or long-running work, requiring the user to remember to manually resume a task hours later is a significant reliability gap.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Kron00@rix1337
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: resume threads after usage limits reset - #8577

Open
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit
Open

feat: resume threads after usage limits reset#8577
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit

Conversation

@Kron00

@Kron00Kron00 commented Aug 28, 2026

Copy link
Copy Markdown

I don't expect this to get merged. It's a working idea you guys can take further if any of it is useful.

Problem

When a provider usage limit stops a long-running thread, users have to remember to reopen it after their subscription resets. Threads that were already doing useful work can sit unfinished even while T3 is still running on their computer.

Fix

  • classify native usage-limit errors from Codex, Claude, Cursor, Grok, and OpenCode
  • add a "Resume when available" action with a visible scheduled state and cancellation
  • persist the schedule so server restarts and reconnects do not lose it
  • resume the same thread with a hidden continuation prompt when the reset time arrives
  • use provider reset timestamps when available, then back off retries when the provider does not supply one
  • cancel safely on settlement, deletion, archival, or newer work, and revalidate timers before starting a provider turn

This PR is desktop/web only. Mobile is unchanged.

Verification

  • 704 focused tests across 25 files after updating from the current base branch
  • focused Grok adapter and xAI extension rate-limit tests
  • vp run --filter @t3tools/contracts typecheck
  • vp run --filter @t3tools/client-runtime typecheck
  • vp run --filter t3 typecheck
  • vp run --filter @t3tools/web typecheck
  • targeted lint for changed provider adapters
  • git diff --check
  • tested the real Codex, Claude, Cursor, Grok, and OpenCode harness error formats against controlled local rate-limit responders
  • recorded a desktop end-to-end pass where an existing Grok thread scheduled, fired, and resumed automatically
  • repeated the live Grok pass after review fixes and observed the next paced retry when Grok remained limited

Visual evidence

Limit reachedResume scheduled
Usage-limit banner with Resume when availableScheduled automatic resume with cancellation

Live retry remains limited and schedules the next attempt

Desktop end-to-end recording

Generated with GPT-5.6 Sol in T3 Code through the Codex harness.


Note

Medium Risk
Touches core orchestration, provider turn dispatch, and new durable projection fields; incorrect timer or cancel logic could retry turns at the wrong time or leave stale resume state after lifecycle changes.

Overview
Adds durable automatic resume when provider turns stop on usage limits: new orchestration commands/events (schedule, attempt, retry, cancel), projection columns (usage_limit_resume_json, session last_error_class/retry_at), and the threadUsageLimitResume server capability.

ProviderCommandReactor schedules timers from resume events, restores them on startup (with repair for in-flight attempts), retries failed dispatches with backoff, and on attempt fires a hidden Continue from where you left off. turn without a new user message. Failures re-classify usage limits, pace retries via nextUsageLimitRetryAt, and cancel when work is superseded or the thread is settled/archived/deleted.

Decider enforces invariants (usage-limit session required, future resumeAt) and emits companion cancel/interrupt events on settle, delete, archive, manual turn, and interrupt. ProviderRuntimeIngestion persists typed usage_limit/retryAt on runtime errors, reschedules or cancels in-flight resume, and avoids carrying stale error metadata on unrelated session errors.

Snapshot queries and migration 044 expose resume state to clients; tests cover reactor recovery, OpenCode trailing-error ordering, and decider/projector lifecycles. Mock ACP agent gains configurable prompt failure message.

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

Note

Add automatic thread resume after usage limits reset

  • Introduces contracts for OrchestrationRuntimeErrorClass, ThreadUsageLimitResume, and related commands/events in orchestration.ts.
  • Server orchestrator classifies usage-limit errors from providers, tracks lastErrorClass and retryAt, and schedules/cancels durable timers to automatically resume threads.
  • Web UI and client runtime track resume state and expose user actions to schedule or cancel auto-resume.
  • Risk: Database migration 044_UsageLimitResume in 044_UsageLimitResume.ts adds new columns to projection_threads and projection_thread_sessions.

Macroscope summarized b6a9d16.

@coderabbitai

coderabbitaiBot commented Aug 28, 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: 658c7c3a-f1ed-4e41-b96e-9aa91ef5b044

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

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 28, 2026

@macroscopeappmacroscopeappBot 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.

Reviewed the web UI changes (ChatView.tsx, chat/ThreadErrorBanner.tsx). The banner itself composes the shared Alert/Button primitives correctly (size="xs" + variant="outline" matches the parked-thread banner action). Three findings on the new usage-limit resume surface in ChatView.tsx.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
Comment threadpackages/contracts/src/orchestration.ts

@macroscopeappmacroscopeappBot 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.

One finding on the usage-limit banner: the dismiss affordance is rendered but cannot hide the banner for a usage-limit error with no pending resume.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated

@macroscopeappmacroscopeappBot 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.

One minor copy inconsistency in the new banner action; everything else (primitive reuse, size="xs"/variant="outline" in AlertAction, timestamp formatting via snoozeWakeDescription, thread-scoped environment routing for the new commands) matches existing patterns.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/chat/ThreadErrorBanner.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding in the reactor's startup reconciliation of pending usage-limit resumes. Details inline.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated

@macroscopeappmacroscopeappBot 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.

Reviewed the new usage-limit resume services against the Effect service conventions. One finding: the shared usage-limit dispatch retry is unbounded and does not isolate persistent failures.

Posted via Macroscope — Effect Service Conventions

@Kron00
Kron00 marked this pull request as ready for review August 28, 2026 23:01

@macroscopeappmacroscopeappBot 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.

One finding on the new usage-limit resume banner wiring in ChatView.tsx. The earlier notes on the pending label, the dismissal mask, and the timestamp format look resolved.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a default-enabled capability and a broad server/client workflow that persists usage-limit state, schedules retries across restarts, and automatically starts provider turns. Its cross-cutting orchestration, provider, persistence, and lifecycle side effects require human review.

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

Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/decider.ts

@macroscopeappmacroscopeappBot 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.

Reviewed the changed web UI (ChatView.tsx, chat/ThreadErrorBanner.tsx, chat/usageLimitResumePresentation.ts) against the shared component system and the repo's environment/capability conventions.

The banner work itself now lines up with the primitives: ThreadErrorBanner keeps Alert/AlertAction ownership, the new action uses Button size="xs" variant="outline" (same geometry as the existing icon-xs dismiss control, so the h-lh / min-h-7 sm:min-h-6 first-line alignment contract still holds), the composer status banner matches its peer ComposerBannerStackItems, and the scheduled time is formatted through snoozeWakeDescription(..., timestampFormat) rather than a raw Intl call.

One finding: the new environment-scoped resume actions are offered without a server capability gate, unlike every other server-backed thread action in this file. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadpackages/client-runtime/src/state/usageLimitResume.ts

@cursorcursorBot 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 1 potential issue.

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 df9fdff. Configure here.

@rix1337

Copy link
Copy Markdown

Not commenting on the implementation details here, but I’d consider this a high-priority feature from a product perspective.

Automatic resume after usage limits reset is becoming an expected capability in long-running coding agents. Claude Code has recently added similar behavior, and other agent/harness tools are moving in the same direction.

For unattended or long-running work, requiring the user to remember to manually resume a task hours later is a significant reliability gap.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Kron00@rix1337
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: resume threads after usage limits reset - #8577

Open
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit
Open

feat: resume threads after usage limits reset#8577
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit

Conversation

@Kron00

@Kron00Kron00 commented Aug 28, 2026

Copy link
Copy Markdown

I don't expect this to get merged. It's a working idea you guys can take further if any of it is useful.

Problem

When a provider usage limit stops a long-running thread, users have to remember to reopen it after their subscription resets. Threads that were already doing useful work can sit unfinished even while T3 is still running on their computer.

Fix

  • classify native usage-limit errors from Codex, Claude, Cursor, Grok, and OpenCode
  • add a "Resume when available" action with a visible scheduled state and cancellation
  • persist the schedule so server restarts and reconnects do not lose it
  • resume the same thread with a hidden continuation prompt when the reset time arrives
  • use provider reset timestamps when available, then back off retries when the provider does not supply one
  • cancel safely on settlement, deletion, archival, or newer work, and revalidate timers before starting a provider turn

This PR is desktop/web only. Mobile is unchanged.

Verification

  • 704 focused tests across 25 files after updating from the current base branch
  • focused Grok adapter and xAI extension rate-limit tests
  • vp run --filter @t3tools/contracts typecheck
  • vp run --filter @t3tools/client-runtime typecheck
  • vp run --filter t3 typecheck
  • vp run --filter @t3tools/web typecheck
  • targeted lint for changed provider adapters
  • git diff --check
  • tested the real Codex, Claude, Cursor, Grok, and OpenCode harness error formats against controlled local rate-limit responders
  • recorded a desktop end-to-end pass where an existing Grok thread scheduled, fired, and resumed automatically
  • repeated the live Grok pass after review fixes and observed the next paced retry when Grok remained limited

Visual evidence

Limit reachedResume scheduled
Usage-limit banner with Resume when availableScheduled automatic resume with cancellation

Live retry remains limited and schedules the next attempt

Desktop end-to-end recording

Generated with GPT-5.6 Sol in T3 Code through the Codex harness.


Note

Medium Risk
Touches core orchestration, provider turn dispatch, and new durable projection fields; incorrect timer or cancel logic could retry turns at the wrong time or leave stale resume state after lifecycle changes.

Overview
Adds durable automatic resume when provider turns stop on usage limits: new orchestration commands/events (schedule, attempt, retry, cancel), projection columns (usage_limit_resume_json, session last_error_class/retry_at), and the threadUsageLimitResume server capability.

ProviderCommandReactor schedules timers from resume events, restores them on startup (with repair for in-flight attempts), retries failed dispatches with backoff, and on attempt fires a hidden Continue from where you left off. turn without a new user message. Failures re-classify usage limits, pace retries via nextUsageLimitRetryAt, and cancel when work is superseded or the thread is settled/archived/deleted.

Decider enforces invariants (usage-limit session required, future resumeAt) and emits companion cancel/interrupt events on settle, delete, archive, manual turn, and interrupt. ProviderRuntimeIngestion persists typed usage_limit/retryAt on runtime errors, reschedules or cancels in-flight resume, and avoids carrying stale error metadata on unrelated session errors.

Snapshot queries and migration 044 expose resume state to clients; tests cover reactor recovery, OpenCode trailing-error ordering, and decider/projector lifecycles. Mock ACP agent gains configurable prompt failure message.

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

Note

Add automatic thread resume after usage limits reset

  • Introduces contracts for OrchestrationRuntimeErrorClass, ThreadUsageLimitResume, and related commands/events in orchestration.ts.
  • Server orchestrator classifies usage-limit errors from providers, tracks lastErrorClass and retryAt, and schedules/cancels durable timers to automatically resume threads.
  • Web UI and client runtime track resume state and expose user actions to schedule or cancel auto-resume.
  • Risk: Database migration 044_UsageLimitResume in 044_UsageLimitResume.ts adds new columns to projection_threads and projection_thread_sessions.

Macroscope summarized b6a9d16.

@coderabbitai

coderabbitaiBot commented Aug 28, 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: 658c7c3a-f1ed-4e41-b96e-9aa91ef5b044

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

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 28, 2026

@macroscopeappmacroscopeappBot 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.

Reviewed the web UI changes (ChatView.tsx, chat/ThreadErrorBanner.tsx). The banner itself composes the shared Alert/Button primitives correctly (size="xs" + variant="outline" matches the parked-thread banner action). Three findings on the new usage-limit resume surface in ChatView.tsx.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
Comment threadpackages/contracts/src/orchestration.ts

@macroscopeappmacroscopeappBot 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.

One finding on the usage-limit banner: the dismiss affordance is rendered but cannot hide the banner for a usage-limit error with no pending resume.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated

@macroscopeappmacroscopeappBot 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.

One minor copy inconsistency in the new banner action; everything else (primitive reuse, size="xs"/variant="outline" in AlertAction, timestamp formatting via snoozeWakeDescription, thread-scoped environment routing for the new commands) matches existing patterns.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/chat/ThreadErrorBanner.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding in the reactor's startup reconciliation of pending usage-limit resumes. Details inline.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated

@macroscopeappmacroscopeappBot 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.

Reviewed the new usage-limit resume services against the Effect service conventions. One finding: the shared usage-limit dispatch retry is unbounded and does not isolate persistent failures.

Posted via Macroscope — Effect Service Conventions

@Kron00
Kron00 marked this pull request as ready for review August 28, 2026 23:01

@macroscopeappmacroscopeappBot 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.

One finding on the new usage-limit resume banner wiring in ChatView.tsx. The earlier notes on the pending label, the dismissal mask, and the timestamp format look resolved.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a default-enabled capability and a broad server/client workflow that persists usage-limit state, schedules retries across restarts, and automatically starts provider turns. Its cross-cutting orchestration, provider, persistence, and lifecycle side effects require human review.

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

Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/decider.ts

@macroscopeappmacroscopeappBot 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.

Reviewed the changed web UI (ChatView.tsx, chat/ThreadErrorBanner.tsx, chat/usageLimitResumePresentation.ts) against the shared component system and the repo's environment/capability conventions.

The banner work itself now lines up with the primitives: ThreadErrorBanner keeps Alert/AlertAction ownership, the new action uses Button size="xs" variant="outline" (same geometry as the existing icon-xs dismiss control, so the h-lh / min-h-7 sm:min-h-6 first-line alignment contract still holds), the composer status banner matches its peer ComposerBannerStackItems, and the scheduled time is formatted through snoozeWakeDescription(..., timestampFormat) rather than a raw Intl call.

One finding: the new environment-scoped resume actions are offered without a server capability gate, unlike every other server-backed thread action in this file. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadpackages/client-runtime/src/state/usageLimitResume.ts

@cursorcursorBot 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 1 potential issue.

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 df9fdff. Configure here.

@rix1337

Copy link
Copy Markdown

Not commenting on the implementation details here, but I’d consider this a high-priority feature from a product perspective.

Automatic resume after usage limits reset is becoming an expected capability in long-running coding agents. Claude Code has recently added similar behavior, and other agent/harness tools are moving in the same direction.

For unattended or long-running work, requiring the user to remember to manually resume a task hours later is a significant reliability gap.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Kron00@rix1337
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: resume threads after usage limits reset - #8577

Open
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit
Open

feat: resume threads after usage limits reset#8577
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit

Conversation

@Kron00

@Kron00Kron00 commented Aug 28, 2026

Copy link
Copy Markdown

I don't expect this to get merged. It's a working idea you guys can take further if any of it is useful.

Problem

When a provider usage limit stops a long-running thread, users have to remember to reopen it after their subscription resets. Threads that were already doing useful work can sit unfinished even while T3 is still running on their computer.

Fix

  • classify native usage-limit errors from Codex, Claude, Cursor, Grok, and OpenCode
  • add a "Resume when available" action with a visible scheduled state and cancellation
  • persist the schedule so server restarts and reconnects do not lose it
  • resume the same thread with a hidden continuation prompt when the reset time arrives
  • use provider reset timestamps when available, then back off retries when the provider does not supply one
  • cancel safely on settlement, deletion, archival, or newer work, and revalidate timers before starting a provider turn

This PR is desktop/web only. Mobile is unchanged.

Verification

  • 704 focused tests across 25 files after updating from the current base branch
  • focused Grok adapter and xAI extension rate-limit tests
  • vp run --filter @t3tools/contracts typecheck
  • vp run --filter @t3tools/client-runtime typecheck
  • vp run --filter t3 typecheck
  • vp run --filter @t3tools/web typecheck
  • targeted lint for changed provider adapters
  • git diff --check
  • tested the real Codex, Claude, Cursor, Grok, and OpenCode harness error formats against controlled local rate-limit responders
  • recorded a desktop end-to-end pass where an existing Grok thread scheduled, fired, and resumed automatically
  • repeated the live Grok pass after review fixes and observed the next paced retry when Grok remained limited

Visual evidence

Limit reachedResume scheduled
Usage-limit banner with Resume when availableScheduled automatic resume with cancellation

Live retry remains limited and schedules the next attempt

Desktop end-to-end recording

Generated with GPT-5.6 Sol in T3 Code through the Codex harness.


Note

Medium Risk
Touches core orchestration, provider turn dispatch, and new durable projection fields; incorrect timer or cancel logic could retry turns at the wrong time or leave stale resume state after lifecycle changes.

Overview
Adds durable automatic resume when provider turns stop on usage limits: new orchestration commands/events (schedule, attempt, retry, cancel), projection columns (usage_limit_resume_json, session last_error_class/retry_at), and the threadUsageLimitResume server capability.

ProviderCommandReactor schedules timers from resume events, restores them on startup (with repair for in-flight attempts), retries failed dispatches with backoff, and on attempt fires a hidden Continue from where you left off. turn without a new user message. Failures re-classify usage limits, pace retries via nextUsageLimitRetryAt, and cancel when work is superseded or the thread is settled/archived/deleted.

Decider enforces invariants (usage-limit session required, future resumeAt) and emits companion cancel/interrupt events on settle, delete, archive, manual turn, and interrupt. ProviderRuntimeIngestion persists typed usage_limit/retryAt on runtime errors, reschedules or cancels in-flight resume, and avoids carrying stale error metadata on unrelated session errors.

Snapshot queries and migration 044 expose resume state to clients; tests cover reactor recovery, OpenCode trailing-error ordering, and decider/projector lifecycles. Mock ACP agent gains configurable prompt failure message.

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

Note

Add automatic thread resume after usage limits reset

  • Introduces contracts for OrchestrationRuntimeErrorClass, ThreadUsageLimitResume, and related commands/events in orchestration.ts.
  • Server orchestrator classifies usage-limit errors from providers, tracks lastErrorClass and retryAt, and schedules/cancels durable timers to automatically resume threads.
  • Web UI and client runtime track resume state and expose user actions to schedule or cancel auto-resume.
  • Risk: Database migration 044_UsageLimitResume in 044_UsageLimitResume.ts adds new columns to projection_threads and projection_thread_sessions.

Macroscope summarized b6a9d16.

@coderabbitai

coderabbitaiBot commented Aug 28, 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: 658c7c3a-f1ed-4e41-b96e-9aa91ef5b044

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

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 28, 2026

@macroscopeappmacroscopeappBot 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.

Reviewed the web UI changes (ChatView.tsx, chat/ThreadErrorBanner.tsx). The banner itself composes the shared Alert/Button primitives correctly (size="xs" + variant="outline" matches the parked-thread banner action). Three findings on the new usage-limit resume surface in ChatView.tsx.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
Comment threadpackages/contracts/src/orchestration.ts

@macroscopeappmacroscopeappBot 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.

One finding on the usage-limit banner: the dismiss affordance is rendered but cannot hide the banner for a usage-limit error with no pending resume.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated

@macroscopeappmacroscopeappBot 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.

One minor copy inconsistency in the new banner action; everything else (primitive reuse, size="xs"/variant="outline" in AlertAction, timestamp formatting via snoozeWakeDescription, thread-scoped environment routing for the new commands) matches existing patterns.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/chat/ThreadErrorBanner.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding in the reactor's startup reconciliation of pending usage-limit resumes. Details inline.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated

@macroscopeappmacroscopeappBot 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.

Reviewed the new usage-limit resume services against the Effect service conventions. One finding: the shared usage-limit dispatch retry is unbounded and does not isolate persistent failures.

Posted via Macroscope — Effect Service Conventions

@Kron00
Kron00 marked this pull request as ready for review August 28, 2026 23:01

@macroscopeappmacroscopeappBot 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.

One finding on the new usage-limit resume banner wiring in ChatView.tsx. The earlier notes on the pending label, the dismissal mask, and the timestamp format look resolved.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a default-enabled capability and a broad server/client workflow that persists usage-limit state, schedules retries across restarts, and automatically starts provider turns. Its cross-cutting orchestration, provider, persistence, and lifecycle side effects require human review.

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

Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/decider.ts

@macroscopeappmacroscopeappBot 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.

Reviewed the changed web UI (ChatView.tsx, chat/ThreadErrorBanner.tsx, chat/usageLimitResumePresentation.ts) against the shared component system and the repo's environment/capability conventions.

The banner work itself now lines up with the primitives: ThreadErrorBanner keeps Alert/AlertAction ownership, the new action uses Button size="xs" variant="outline" (same geometry as the existing icon-xs dismiss control, so the h-lh / min-h-7 sm:min-h-6 first-line alignment contract still holds), the composer status banner matches its peer ComposerBannerStackItems, and the scheduled time is formatted through snoozeWakeDescription(..., timestampFormat) rather than a raw Intl call.

One finding: the new environment-scoped resume actions are offered without a server capability gate, unlike every other server-backed thread action in this file. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadpackages/client-runtime/src/state/usageLimitResume.ts

@cursorcursorBot 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 1 potential issue.

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 df9fdff. Configure here.

@rix1337

Copy link
Copy Markdown

Not commenting on the implementation details here, but I’d consider this a high-priority feature from a product perspective.

Automatic resume after usage limits reset is becoming an expected capability in long-running coding agents. Claude Code has recently added similar behavior, and other agent/harness tools are moving in the same direction.

For unattended or long-running work, requiring the user to remember to manually resume a task hours later is a significant reliability gap.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Kron00@rix1337
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: resume threads after usage limits reset - #8577

Open
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit
Open

feat: resume threads after usage limits reset#8577
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit

Conversation

@Kron00

@Kron00Kron00 commented Aug 28, 2026

Copy link
Copy Markdown

I don't expect this to get merged. It's a working idea you guys can take further if any of it is useful.

Problem

When a provider usage limit stops a long-running thread, users have to remember to reopen it after their subscription resets. Threads that were already doing useful work can sit unfinished even while T3 is still running on their computer.

Fix

  • classify native usage-limit errors from Codex, Claude, Cursor, Grok, and OpenCode
  • add a "Resume when available" action with a visible scheduled state and cancellation
  • persist the schedule so server restarts and reconnects do not lose it
  • resume the same thread with a hidden continuation prompt when the reset time arrives
  • use provider reset timestamps when available, then back off retries when the provider does not supply one
  • cancel safely on settlement, deletion, archival, or newer work, and revalidate timers before starting a provider turn

This PR is desktop/web only. Mobile is unchanged.

Verification

  • 704 focused tests across 25 files after updating from the current base branch
  • focused Grok adapter and xAI extension rate-limit tests
  • vp run --filter @t3tools/contracts typecheck
  • vp run --filter @t3tools/client-runtime typecheck
  • vp run --filter t3 typecheck
  • vp run --filter @t3tools/web typecheck
  • targeted lint for changed provider adapters
  • git diff --check
  • tested the real Codex, Claude, Cursor, Grok, and OpenCode harness error formats against controlled local rate-limit responders
  • recorded a desktop end-to-end pass where an existing Grok thread scheduled, fired, and resumed automatically
  • repeated the live Grok pass after review fixes and observed the next paced retry when Grok remained limited

Visual evidence

Limit reachedResume scheduled
Usage-limit banner with Resume when availableScheduled automatic resume with cancellation

Live retry remains limited and schedules the next attempt

Desktop end-to-end recording

Generated with GPT-5.6 Sol in T3 Code through the Codex harness.


Note

Medium Risk
Touches core orchestration, provider turn dispatch, and new durable projection fields; incorrect timer or cancel logic could retry turns at the wrong time or leave stale resume state after lifecycle changes.

Overview
Adds durable automatic resume when provider turns stop on usage limits: new orchestration commands/events (schedule, attempt, retry, cancel), projection columns (usage_limit_resume_json, session last_error_class/retry_at), and the threadUsageLimitResume server capability.

ProviderCommandReactor schedules timers from resume events, restores them on startup (with repair for in-flight attempts), retries failed dispatches with backoff, and on attempt fires a hidden Continue from where you left off. turn without a new user message. Failures re-classify usage limits, pace retries via nextUsageLimitRetryAt, and cancel when work is superseded or the thread is settled/archived/deleted.

Decider enforces invariants (usage-limit session required, future resumeAt) and emits companion cancel/interrupt events on settle, delete, archive, manual turn, and interrupt. ProviderRuntimeIngestion persists typed usage_limit/retryAt on runtime errors, reschedules or cancels in-flight resume, and avoids carrying stale error metadata on unrelated session errors.

Snapshot queries and migration 044 expose resume state to clients; tests cover reactor recovery, OpenCode trailing-error ordering, and decider/projector lifecycles. Mock ACP agent gains configurable prompt failure message.

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

Note

Add automatic thread resume after usage limits reset

  • Introduces contracts for OrchestrationRuntimeErrorClass, ThreadUsageLimitResume, and related commands/events in orchestration.ts.
  • Server orchestrator classifies usage-limit errors from providers, tracks lastErrorClass and retryAt, and schedules/cancels durable timers to automatically resume threads.
  • Web UI and client runtime track resume state and expose user actions to schedule or cancel auto-resume.
  • Risk: Database migration 044_UsageLimitResume in 044_UsageLimitResume.ts adds new columns to projection_threads and projection_thread_sessions.

Macroscope summarized b6a9d16.

@coderabbitai

coderabbitaiBot commented Aug 28, 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: 658c7c3a-f1ed-4e41-b96e-9aa91ef5b044

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

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 28, 2026

@macroscopeappmacroscopeappBot 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.

Reviewed the web UI changes (ChatView.tsx, chat/ThreadErrorBanner.tsx). The banner itself composes the shared Alert/Button primitives correctly (size="xs" + variant="outline" matches the parked-thread banner action). Three findings on the new usage-limit resume surface in ChatView.tsx.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
Comment threadpackages/contracts/src/orchestration.ts

@macroscopeappmacroscopeappBot 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.

One finding on the usage-limit banner: the dismiss affordance is rendered but cannot hide the banner for a usage-limit error with no pending resume.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated

@macroscopeappmacroscopeappBot 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.

One minor copy inconsistency in the new banner action; everything else (primitive reuse, size="xs"/variant="outline" in AlertAction, timestamp formatting via snoozeWakeDescription, thread-scoped environment routing for the new commands) matches existing patterns.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/chat/ThreadErrorBanner.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding in the reactor's startup reconciliation of pending usage-limit resumes. Details inline.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated

@macroscopeappmacroscopeappBot 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.

Reviewed the new usage-limit resume services against the Effect service conventions. One finding: the shared usage-limit dispatch retry is unbounded and does not isolate persistent failures.

Posted via Macroscope — Effect Service Conventions

@Kron00
Kron00 marked this pull request as ready for review August 28, 2026 23:01

@macroscopeappmacroscopeappBot 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.

One finding on the new usage-limit resume banner wiring in ChatView.tsx. The earlier notes on the pending label, the dismissal mask, and the timestamp format look resolved.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a default-enabled capability and a broad server/client workflow that persists usage-limit state, schedules retries across restarts, and automatically starts provider turns. Its cross-cutting orchestration, provider, persistence, and lifecycle side effects require human review.

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

Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/decider.ts

@macroscopeappmacroscopeappBot 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.

Reviewed the changed web UI (ChatView.tsx, chat/ThreadErrorBanner.tsx, chat/usageLimitResumePresentation.ts) against the shared component system and the repo's environment/capability conventions.

The banner work itself now lines up with the primitives: ThreadErrorBanner keeps Alert/AlertAction ownership, the new action uses Button size="xs" variant="outline" (same geometry as the existing icon-xs dismiss control, so the h-lh / min-h-7 sm:min-h-6 first-line alignment contract still holds), the composer status banner matches its peer ComposerBannerStackItems, and the scheduled time is formatted through snoozeWakeDescription(..., timestampFormat) rather than a raw Intl call.

One finding: the new environment-scoped resume actions are offered without a server capability gate, unlike every other server-backed thread action in this file. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadpackages/client-runtime/src/state/usageLimitResume.ts

@cursorcursorBot 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 1 potential issue.

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 df9fdff. Configure here.

@rix1337

Copy link
Copy Markdown

Not commenting on the implementation details here, but I’d consider this a high-priority feature from a product perspective.

Automatic resume after usage limits reset is becoming an expected capability in long-running coding agents. Claude Code has recently added similar behavior, and other agent/harness tools are moving in the same direction.

For unattended or long-running work, requiring the user to remember to manually resume a task hours later is a significant reliability gap.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Kron00@rix1337
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: resume threads after usage limits reset - #8577

Open
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit
Open

feat: resume threads after usage limits reset#8577
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit

Conversation

@Kron00

@Kron00Kron00 commented Aug 28, 2026

Copy link
Copy Markdown

I don't expect this to get merged. It's a working idea you guys can take further if any of it is useful.

Problem

When a provider usage limit stops a long-running thread, users have to remember to reopen it after their subscription resets. Threads that were already doing useful work can sit unfinished even while T3 is still running on their computer.

Fix

  • classify native usage-limit errors from Codex, Claude, Cursor, Grok, and OpenCode
  • add a "Resume when available" action with a visible scheduled state and cancellation
  • persist the schedule so server restarts and reconnects do not lose it
  • resume the same thread with a hidden continuation prompt when the reset time arrives
  • use provider reset timestamps when available, then back off retries when the provider does not supply one
  • cancel safely on settlement, deletion, archival, or newer work, and revalidate timers before starting a provider turn

This PR is desktop/web only. Mobile is unchanged.

Verification

  • 704 focused tests across 25 files after updating from the current base branch
  • focused Grok adapter and xAI extension rate-limit tests
  • vp run --filter @t3tools/contracts typecheck
  • vp run --filter @t3tools/client-runtime typecheck
  • vp run --filter t3 typecheck
  • vp run --filter @t3tools/web typecheck
  • targeted lint for changed provider adapters
  • git diff --check
  • tested the real Codex, Claude, Cursor, Grok, and OpenCode harness error formats against controlled local rate-limit responders
  • recorded a desktop end-to-end pass where an existing Grok thread scheduled, fired, and resumed automatically
  • repeated the live Grok pass after review fixes and observed the next paced retry when Grok remained limited

Visual evidence

Limit reachedResume scheduled
Usage-limit banner with Resume when availableScheduled automatic resume with cancellation

Live retry remains limited and schedules the next attempt

Desktop end-to-end recording

Generated with GPT-5.6 Sol in T3 Code through the Codex harness.


Note

Medium Risk
Touches core orchestration, provider turn dispatch, and new durable projection fields; incorrect timer or cancel logic could retry turns at the wrong time or leave stale resume state after lifecycle changes.

Overview
Adds durable automatic resume when provider turns stop on usage limits: new orchestration commands/events (schedule, attempt, retry, cancel), projection columns (usage_limit_resume_json, session last_error_class/retry_at), and the threadUsageLimitResume server capability.

ProviderCommandReactor schedules timers from resume events, restores them on startup (with repair for in-flight attempts), retries failed dispatches with backoff, and on attempt fires a hidden Continue from where you left off. turn without a new user message. Failures re-classify usage limits, pace retries via nextUsageLimitRetryAt, and cancel when work is superseded or the thread is settled/archived/deleted.

Decider enforces invariants (usage-limit session required, future resumeAt) and emits companion cancel/interrupt events on settle, delete, archive, manual turn, and interrupt. ProviderRuntimeIngestion persists typed usage_limit/retryAt on runtime errors, reschedules or cancels in-flight resume, and avoids carrying stale error metadata on unrelated session errors.

Snapshot queries and migration 044 expose resume state to clients; tests cover reactor recovery, OpenCode trailing-error ordering, and decider/projector lifecycles. Mock ACP agent gains configurable prompt failure message.

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

Note

Add automatic thread resume after usage limits reset

  • Introduces contracts for OrchestrationRuntimeErrorClass, ThreadUsageLimitResume, and related commands/events in orchestration.ts.
  • Server orchestrator classifies usage-limit errors from providers, tracks lastErrorClass and retryAt, and schedules/cancels durable timers to automatically resume threads.
  • Web UI and client runtime track resume state and expose user actions to schedule or cancel auto-resume.
  • Risk: Database migration 044_UsageLimitResume in 044_UsageLimitResume.ts adds new columns to projection_threads and projection_thread_sessions.

Macroscope summarized b6a9d16.

@coderabbitai

coderabbitaiBot commented Aug 28, 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: 658c7c3a-f1ed-4e41-b96e-9aa91ef5b044

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

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 28, 2026

@macroscopeappmacroscopeappBot 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.

Reviewed the web UI changes (ChatView.tsx, chat/ThreadErrorBanner.tsx). The banner itself composes the shared Alert/Button primitives correctly (size="xs" + variant="outline" matches the parked-thread banner action). Three findings on the new usage-limit resume surface in ChatView.tsx.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
Comment threadpackages/contracts/src/orchestration.ts

@macroscopeappmacroscopeappBot 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.

One finding on the usage-limit banner: the dismiss affordance is rendered but cannot hide the banner for a usage-limit error with no pending resume.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated

@macroscopeappmacroscopeappBot 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.

One minor copy inconsistency in the new banner action; everything else (primitive reuse, size="xs"/variant="outline" in AlertAction, timestamp formatting via snoozeWakeDescription, thread-scoped environment routing for the new commands) matches existing patterns.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/chat/ThreadErrorBanner.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding in the reactor's startup reconciliation of pending usage-limit resumes. Details inline.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated

@macroscopeappmacroscopeappBot 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.

Reviewed the new usage-limit resume services against the Effect service conventions. One finding: the shared usage-limit dispatch retry is unbounded and does not isolate persistent failures.

Posted via Macroscope — Effect Service Conventions

@Kron00
Kron00 marked this pull request as ready for review August 28, 2026 23:01

@macroscopeappmacroscopeappBot 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.

One finding on the new usage-limit resume banner wiring in ChatView.tsx. The earlier notes on the pending label, the dismissal mask, and the timestamp format look resolved.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a default-enabled capability and a broad server/client workflow that persists usage-limit state, schedules retries across restarts, and automatically starts provider turns. Its cross-cutting orchestration, provider, persistence, and lifecycle side effects require human review.

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

Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/decider.ts

@macroscopeappmacroscopeappBot 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.

Reviewed the changed web UI (ChatView.tsx, chat/ThreadErrorBanner.tsx, chat/usageLimitResumePresentation.ts) against the shared component system and the repo's environment/capability conventions.

The banner work itself now lines up with the primitives: ThreadErrorBanner keeps Alert/AlertAction ownership, the new action uses Button size="xs" variant="outline" (same geometry as the existing icon-xs dismiss control, so the h-lh / min-h-7 sm:min-h-6 first-line alignment contract still holds), the composer status banner matches its peer ComposerBannerStackItems, and the scheduled time is formatted through snoozeWakeDescription(..., timestampFormat) rather than a raw Intl call.

One finding: the new environment-scoped resume actions are offered without a server capability gate, unlike every other server-backed thread action in this file. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadpackages/client-runtime/src/state/usageLimitResume.ts

@cursorcursorBot 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 1 potential issue.

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 df9fdff. Configure here.

@rix1337

Copy link
Copy Markdown

Not commenting on the implementation details here, but I’d consider this a high-priority feature from a product perspective.

Automatic resume after usage limits reset is becoming an expected capability in long-running coding agents. Claude Code has recently added similar behavior, and other agent/harness tools are moving in the same direction.

For unattended or long-running work, requiring the user to remember to manually resume a task hours later is a significant reliability gap.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Kron00@rix1337
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: resume threads after usage limits reset - #8577

Open
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit
Open

feat: resume threads after usage limits reset#8577
Kron00 wants to merge 32 commits into
pingdotgg:mainfrom
Kron00:feat/resume-after-usage-limit

Conversation

@Kron00

@Kron00Kron00 commented Aug 28, 2026

Copy link
Copy Markdown

I don't expect this to get merged. It's a working idea you guys can take further if any of it is useful.

Problem

When a provider usage limit stops a long-running thread, users have to remember to reopen it after their subscription resets. Threads that were already doing useful work can sit unfinished even while T3 is still running on their computer.

Fix

  • classify native usage-limit errors from Codex, Claude, Cursor, Grok, and OpenCode
  • add a "Resume when available" action with a visible scheduled state and cancellation
  • persist the schedule so server restarts and reconnects do not lose it
  • resume the same thread with a hidden continuation prompt when the reset time arrives
  • use provider reset timestamps when available, then back off retries when the provider does not supply one
  • cancel safely on settlement, deletion, archival, or newer work, and revalidate timers before starting a provider turn

This PR is desktop/web only. Mobile is unchanged.

Verification

  • 704 focused tests across 25 files after updating from the current base branch
  • focused Grok adapter and xAI extension rate-limit tests
  • vp run --filter @t3tools/contracts typecheck
  • vp run --filter @t3tools/client-runtime typecheck
  • vp run --filter t3 typecheck
  • vp run --filter @t3tools/web typecheck
  • targeted lint for changed provider adapters
  • git diff --check
  • tested the real Codex, Claude, Cursor, Grok, and OpenCode harness error formats against controlled local rate-limit responders
  • recorded a desktop end-to-end pass where an existing Grok thread scheduled, fired, and resumed automatically
  • repeated the live Grok pass after review fixes and observed the next paced retry when Grok remained limited

Visual evidence

Limit reachedResume scheduled
Usage-limit banner with Resume when availableScheduled automatic resume with cancellation

Live retry remains limited and schedules the next attempt

Desktop end-to-end recording

Generated with GPT-5.6 Sol in T3 Code through the Codex harness.


Note

Medium Risk
Touches core orchestration, provider turn dispatch, and new durable projection fields; incorrect timer or cancel logic could retry turns at the wrong time or leave stale resume state after lifecycle changes.

Overview
Adds durable automatic resume when provider turns stop on usage limits: new orchestration commands/events (schedule, attempt, retry, cancel), projection columns (usage_limit_resume_json, session last_error_class/retry_at), and the threadUsageLimitResume server capability.

ProviderCommandReactor schedules timers from resume events, restores them on startup (with repair for in-flight attempts), retries failed dispatches with backoff, and on attempt fires a hidden Continue from where you left off. turn without a new user message. Failures re-classify usage limits, pace retries via nextUsageLimitRetryAt, and cancel when work is superseded or the thread is settled/archived/deleted.

Decider enforces invariants (usage-limit session required, future resumeAt) and emits companion cancel/interrupt events on settle, delete, archive, manual turn, and interrupt. ProviderRuntimeIngestion persists typed usage_limit/retryAt on runtime errors, reschedules or cancels in-flight resume, and avoids carrying stale error metadata on unrelated session errors.

Snapshot queries and migration 044 expose resume state to clients; tests cover reactor recovery, OpenCode trailing-error ordering, and decider/projector lifecycles. Mock ACP agent gains configurable prompt failure message.

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

Note

Add automatic thread resume after usage limits reset

  • Introduces contracts for OrchestrationRuntimeErrorClass, ThreadUsageLimitResume, and related commands/events in orchestration.ts.
  • Server orchestrator classifies usage-limit errors from providers, tracks lastErrorClass and retryAt, and schedules/cancels durable timers to automatically resume threads.
  • Web UI and client runtime track resume state and expose user actions to schedule or cancel auto-resume.
  • Risk: Database migration 044_UsageLimitResume in 044_UsageLimitResume.ts adds new columns to projection_threads and projection_thread_sessions.

Macroscope summarized b6a9d16.

@coderabbitai

coderabbitaiBot commented Aug 28, 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: 658c7c3a-f1ed-4e41-b96e-9aa91ef5b044

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

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

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 28, 2026

@macroscopeappmacroscopeappBot 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.

Reviewed the web UI changes (ChatView.tsx, chat/ThreadErrorBanner.tsx). The banner itself composes the shared Alert/Button primitives correctly (size="xs" + variant="outline" matches the parked-thread banner action). Three findings on the new usage-limit resume surface in ChatView.tsx.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
Comment threadpackages/contracts/src/orchestration.ts

@macroscopeappmacroscopeappBot 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.

One finding on the usage-limit banner: the dismiss affordance is rendered but cannot hide the banner for a usage-limit error with no pending resume.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts Outdated

@macroscopeappmacroscopeappBot 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.

One minor copy inconsistency in the new banner action; everything else (primitive reuse, size="xs"/variant="outline" in AlertAction, timestamp formatting via snoozeWakeDescription, thread-scoped environment routing for the new commands) matches existing patterns.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/chat/ThreadErrorBanner.tsx Outdated

@macroscopeappmacroscopeappBot 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.

One finding in the reactor's startup reconciliation of pending usage-limit resumes. Details inline.

Posted via Macroscope — Effect Service Conventions

Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated

@macroscopeappmacroscopeappBot 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.

Reviewed the new usage-limit resume services against the Effect service conventions. One finding: the shared usage-limit dispatch retry is unbounded and does not isolate persistent failures.

Posted via Macroscope — Effect Service Conventions

@Kron00
Kron00 marked this pull request as ready for review August 28, 2026 23:01

@macroscopeappmacroscopeappBot 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.

One finding on the new usage-limit resume banner wiring in ChatView.tsx. The earlier notes on the pending label, the dismissal mask, and the timestamp format look resolved.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
@macroscopeapp

macroscopeappBot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a default-enabled capability and a broad server/client workflow that persists usage-limit state, schedules retries across restarts, and automatically starts provider turns. Its cross-cutting orchestration, provider, persistence, and lifecycle side effects require human review.

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

Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/decider.ts
Comment threadapps/server/src/orchestration/Layers/ProviderCommandReactor.ts Outdated
Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/decider.ts

@macroscopeappmacroscopeappBot 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.

Reviewed the changed web UI (ChatView.tsx, chat/ThreadErrorBanner.tsx, chat/usageLimitResumePresentation.ts) against the shared component system and the repo's environment/capability conventions.

The banner work itself now lines up with the primitives: ThreadErrorBanner keeps Alert/AlertAction ownership, the new action uses Button size="xs" variant="outline" (same geometry as the existing icon-xs dismiss control, so the h-lh / min-h-7 sm:min-h-6 first-line alignment contract still holds), the composer status banner matches its peer ComposerBannerStackItems, and the scheduled time is formatted through snoozeWakeDescription(..., timestampFormat) rather than a raw Intl call.

One finding: the new environment-scoped resume actions are offered without a server capability gate, unlike every other server-backed thread action in this file. Details inline.

Posted via Macroscope — UI Consistency

Comment threadapps/web/src/components/ChatView.tsx
Comment threadapps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts Outdated
Comment threadpackages/client-runtime/src/state/usageLimitResume.ts

@cursorcursorBot 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 1 potential issue.

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 df9fdff. Configure here.

@rix1337

Copy link
Copy Markdown

Not commenting on the implementation details here, but I’d consider this a high-priority feature from a product perspective.

Automatic resume after usage limits reset is becoming an expected capability in long-running coding agents. Claude Code has recently added similar behavior, and other agent/harness tools are moving in the same direction.

For unattended or long-running work, requiring the user to remember to manually resume a task hours later is a significant reliability gap.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@Kron00@rix1337