fix model select and display issue - #998
Conversation
📝 WalkthroughWalkthroughModel selection now propagates application session IDs through provider resume flows, normalizes Claude transcript models, prioritizes persisted overrides, supports requested command models, filters SDK environment variables, and cleans overrides during deletion. ChangesModel selection flow
Sequence Diagram(s)sequenceDiagram
participant ChatUI
participant ChatWebSocket
participant ProviderModelsService
participant ProviderRuntime
ChatUI->>ChatWebSocket: select model and send message
ChatWebSocket->>ProviderRuntime: pass appSessionId and model
ProviderRuntime->>ProviderModelsService: resolve resumed or overridden model
ProviderModelsService-->>ProviderRuntime: return catalog-compatible model
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
847c9b7 to
966afc3
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@server/claude-sdk.js`:
- Around line 484-488: Update the appSessionId fallback in the
resolveResumeModel call to treat empty or whitespace-only values as missing by
trimming before selection, while preserving valid appSessionId values and the
sessionId fallback.
- Around line 167-177: Update the environment sanitization near sdkOptions.env
to also remove CLAUDE_CODE_SUBAGENT_MODEL from sdkEnv, alongside the existing
model-selection variables, so explicit sdkOptions.model remains authoritative
for subagents.
In `@server/modules/projects/services/project-delete.service.ts`:
- Around line 72-80: Wrap the cleanup sequence around
deleteProviderSessionActiveModelChanges in try/catch so failures are handled as
best effort and do not prevent the project row from being deleted. Preserve
deletion of session JSONL files and session rows, then continue the permanent
project deletion even when provider-model cleanup throws, following the existing
persistCache pattern in provider-models.service.ts.
In `@server/modules/providers/services/sessions.service.ts`:
- Around line 270-273: Wrap the post-deletion call to
deleteProviderSessionActiveModelChanges in a try/catch so cache cleanup failures
do not propagate after sessionsDb.deleteSessionById has succeeded. Log cleanup
failures with console.warn, matching the existing persistCache pattern, while
preserving the successful session deletion result.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 75dc7d30-4420-411d-9a00-fcd5c606e8ce
📒 Files selected for processing (14)
server/claude-sdk.jsserver/cursor-cli.jsserver/modules/projects/services/project-delete.service.tsserver/modules/providers/list/claude/claude-models.provider.tsserver/modules/providers/services/provider-models.service.tsserver/modules/providers/services/sessions.service.tsserver/modules/providers/tests/provider-models.service.test.tsserver/modules/websocket/services/chat-websocket.service.tsserver/openai-codex.jsserver/opencode-cli.jsserver/routes/commands.jsserver/routes/tests/commands.test.jsserver/shared/utils.tssrc/components/chat/hooks/useChatProviderState.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- server/opencode-cli.js
- server/openai-codex.js
- server/cursor-cli.js
- server/routes/tests/commands.test.js
- server/modules/providers/services/provider-models.service.ts
- src/components/chat/hooks/useChatProviderState.ts
- server/modules/providers/list/claude/claude-models.provider.ts
- server/routes/commands.js
- server/modules/websocket/services/chat-websocket.service.ts
Problem
Picking a Claude model from the chat
/modelspicker had two independent bugs:default/sonnetwhile the session was actually running
opus) and never reflected a just-made pick./active-model, keyed by theapp session id) was never applied on resume, because runtimes looked it up with
the provider-native session id.
Plus: a host
ANTHROPIC_MODELenv var could silently override the explicit choice,and the override cache accumulated orphaned entries.
Root causes & fixes
Fixes #981
Display — the picker reflects the real model
getCurrentActiveModelnow matches transcript events byprovider_session_id(jsonl records the provider id, the frontend passes the app id → every event was
rejected → fell back to
default).claude-models.provider.tsclaude-opus-4-8);resolveClaudeActiveOptionValuemaps it back to the catalog alias (
opus) for highlighting. Families are derivedfrom the catalog, so a newly released model needs no code change here.
claude-models.provider.ts"model":"<synthetic>") no longer mask the real model.claude-models.provider.tsprovider-models.service.tsresolveCommandModelvalidates the value against the catalog and falls back to thecomposer's requested model; wired into
/models,/cost,/status.commands.jsRuntime — the model change takes effect
chat-websocket.service.ts,claude-sdk.js,cursor-cli.js,opencode-cli.js,openai-codex.jsEnv precedence
ANTHROPIC_MODEL/ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU}_MODELfrom the SDKsubprocess env so the explicit selection wins (notably for
default).claude-sdk.jsOverride-cache hygiene
deleteProviderSessionActiveModelChanges(sessionIds), called on permanentsession delete and permanent project delete (archive is reversible → left untouched).
utils.ts,sessions.service.ts,project-delete.service.tsFrontend
the latest choice.
useChatProviderState.tsTests
override cleanup removes only the targeted sessions across providers.
tsc, 16 provider-model + command tests, eslint.Known limitations (display-only, by design)
defaultandsonnetshare the same underlying model, so without an override adefault session shows
sonnetin the picker — self-corrects once the user picks.changed:true) — that's the per-sessionmodel memory; they are cleared only when the session/project is permanently deleted.
Summary by CodeRabbit
New Features
Bug Fixes
Another PR: #996 is for same purpose.
⚠️ ⚠️ This PR includes all the changes from PR #996, along with some additional fixes. Please review and merge only one of the two PRs.
Summary by CodeRabbit
New Features
Bug Fixes