Walkthrough
Claude refusal fallback events now update the thread’s model selection for non-local scopes. Provider event routing and ingestion synchronize the selection when the provider instance matches. Tests cover fallback scopes, repeated selections, and reports from a different provider instance.
Changes: Fallback model synchronization
Layer / File(s) Summary Report Claude fallback model changes
packages/provider-core/src/server/ProviderAdapter.ts,apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts,apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.tsThe provider event schema adds model-selection updates. Claude emits an update for non-local refusal fallbacks. Tests cover fallback scope and later model selections. Route and synchronize thread model updates
apps/server/src/orchestration-v2/RunExecutionService.ts,apps/server/src/orchestration-v2/ProviderEventIngestor.ts,apps/server/src/orchestration-v2/ProviderEventIngestor.test.tsRun event routing accepts model-selection updates for owned threads. Ingestion synchronizes matching provider instances under the thread lock and skips duplicate or mismatched updates. Tests cover these cases. Priority: External image Normal
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix · Severity of issue fixed: Low
Possibly related issues
- pingdotgg/t3code#24115 — The issue describes a thread retaining its original model after a Claude safeguard fallback. This change updates the thread selection for non-local fallback events.
Possibly related PRs
- pingdotgg/t3code#23931 — Both changes update the thread model after Claude refusal fallbacks, using different provider event paths.
- pingdotgg/t3code#24044 — This PR handles session model changes after an automatic fallback; PR
#24044handles the refusal prompt when automatic switching is disabled. - pingdotgg/t3code#24669 — Both changes address effects of Claude safeguard refusals. This PR updates the thread model when a refusal causes a session fallback.
Suggested labels:
bugfixSuggested reviewers:
maria-rcks,juliusmarminge
Merge Risk: External image Moderate · up to 8f1e7
When a Claude session falls back to another model, the thread now follows it. If the user changes the model or options on the same provider while that run is active, the fallback can overwrite the user's choice. The thread can then resume on a model the user did not select. Fix this before merge.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title clearly identifies the main change: Claude sessions now follow the fallback model after a refusal fallback. Description check Passed The description covers the problem, implementation, scope and approval, visual evidence, focused tests, validation results, and the remaining untested scenario. It is specific and aligned with the req… Linked Issues check Passed [ #24115] asks that a Claude safeguard fallback moves the thread model selection to the fallback model. The head diff meets this. In ClaudeAdapterV2.ts, a system/model_refusal_fallback message whose sc…Out of Scope Changes check Passed Each changed hunk supports the Claude fallback objective in [ #24115]. The ClaudeAdapterV2.ts hunk handles the fallback message. The ProviderEventIngestor.ts changes extract syncThreadModelSelection fr…Full details: Description check
Explanation
The description covers the problem, implementation, scope and approval, visual evidence, focused tests, validation results, and the remaining untested scenario. It is specific and aligned with the required template.
Full details: Linked Issues check
Explanation
[
#24115] asks that a Claude safeguard fallback moves the thread model selection to the fallback model. The head diff meets this. In ClaudeAdapterV2.ts, a system/model_refusal_fallback message whose scope is not "local" (session or absent) resolves fallback_model, updates the live query selection, and emits app_thread.model_selection.updated. A local fallback emits nothing. In ProviderEventIngestor.ts, syncThreadModelSelection writes the reported selection under the thread lock. It skips the write when the selection already matches. It keeps the thread's choice when the thread now belongs to a different provider instance. This covers the composer display and resumes, because resume reads thread.modelSelection. The live selection update lets a later pick of the original model call setModel. The issue also covers switchModelsOnFlag: false, where the same SDK message is expected after the user picks the retry option. The handler does not depend on switchModelsOnFlag, but no test covers that path directly. The reported tests cover session and local scopes, a repeated event, a different provider instance, and a later model change. The subagent sync refactor keeps its previous behavior. The direction field is ignored. The PR author states that Claude Code 2.1.309 no longer emits revert or sticky. The issue does not require handling those values.
Full details: Out of Scope Changes check
Explanation
Each changed hunk supports the Claude fallback objective in [
#24115]. The ClaudeAdapterV2.ts hunk handles the fallback message. The ProviderEventIngestor.ts changes extract syncThreadModelSelection from the subagent path, add the app_thread.model_selection.updated case, and add the provider-instance guard. The RunExecutionService.ts and ProviderAdapter.ts changes add routing and the event type. The tests cover the new behavior. The PR adds no client, contract, or unrelated adapter change, and it leaves Codex model/rerouted handling out of scope, as the PR states.
Finishing Touches
🧪 Generate unit tests (beta)
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.