What would you like to be added?
Refactor the model persistence semantics to distinguish between a default model (global) and a project model (per-project override).
Proposed semantics:
~/.qwen/settings.json → model.name = default model (unchanged)
<project>/.qwen/settings.json → model.name = project model override
- If project-level
model.name is set → use it for sessions in that project
- If project-level
model.name is empty/absent → fall back to the global default
Implementation: the read path (loadSettings().merged → resolveModelConfig) already supports workspace overriding user settings. The fix is in the write path — change getPersistScopeForModelSelection to default to Workspace scope instead of following modelProviders ownership. Add a --global flag to /model for explicitly setting the global default.
Why is this needed?
Different projects have different complexity and cost requirements. A simple scripting project may only need a lightweight model, while a complex architecture project needs a stronger one. Today, /model always writes to the scope that owns modelProviders (usually ~/.qwen/settings.json), so switching models in one project affects all projects globally. The only workaround is to duplicate the entire modelProviders config at project level, which is impractical.
Additional context
Related issues:
Code analysis:
- Read path:
modelConfigResolver.ts resolves settings.model.name from merged settings — workspace already overrides user. No changes needed.
- Write path:
modelProvidersScope.ts getPersistScopeForModelSelection returns the scope that owns modelProviders, which is usually User. This is the only thing blocking per-project model support.
- Suggested change: default to
Workspace scope, add --global flag for explicit user-level writes.
What would you like to be added?
Refactor the model persistence semantics to distinguish between a default model (global) and a project model (per-project override).
Proposed semantics:
~/.qwen/settings.json→model.name= default model (unchanged)<project>/.qwen/settings.json→model.name= project model overridemodel.nameis set → use it for sessions in that projectmodel.nameis empty/absent → fall back to the global defaultImplementation: the read path (
loadSettings().merged→resolveModelConfig) already supports workspace overriding user settings. The fix is in the write path — changegetPersistScopeForModelSelectionto default toWorkspacescope instead of followingmodelProvidersownership. Add a--globalflag to/modelfor explicitly setting the global default.Why is this needed?
Different projects have different complexity and cost requirements. A simple scripting project may only need a lightweight model, while a complex architecture project needs a stronger one. Today,
/modelalways writes to the scope that ownsmodelProviders(usually~/.qwen/settings.json), so switching models in one project affects all projects globally. The only workaround is to duplicate the entiremodelProvidersconfig at project level, which is impractical.Additional context
Related issues:
/modelshould be session-only by default (complementary: session isolation and per-project persistence are orthogonal)/model <id> <prompt>one-shot override (complementary: one-shot for ad-hoc, per-project for durable)Code analysis:
modelConfigResolver.tsresolvessettings.model.namefrom merged settings — workspace already overrides user. No changes needed.modelProvidersScope.tsgetPersistScopeForModelSelectionreturns the scope that ownsmodelProviders, which is usuallyUser. This is the only thing blocking per-project model support.Workspacescope, add--globalflag for explicit user-level writes.