This commit is contained in:
roomote-v0[bot] 2026-05-13 01:42:03 -04:00 committed by GitHub
commit 1927e4a903
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 5 deletions

View file

@ -55,8 +55,9 @@ export class SwitchModeTool extends BaseTool<"switch_mode"> {
return
}
// Switch the mode using shared handler
await task.providerRef.deref()?.handleModeSwitch(mode_slug)
// Switch the mode using shared handler, preserving the current API config
// so the user's selected model doesn't change during AI-initiated switches.
await task.providerRef.deref()?.handleModeSwitch(mode_slug, { preserveApiConfig: true })
pushToolResult(
`Successfully switched from ${getModeBySlug(currentMode)?.name ?? currentMode} mode to ${

View file

@ -1252,7 +1252,7 @@ export class ClineProvider
* Handle switching to a new mode, including updating the associated API configuration
* @param newMode The mode to switch to
*/
public async handleModeSwitch(newMode: Mode) {
public async handleModeSwitch(newMode: Mode, options?: { preserveApiConfig?: boolean }) {
const task = this.getCurrentTask()
if (task) {
@ -1285,9 +1285,11 @@ export class ClineProvider
this.emit(RooCodeEventName.ModeChanged, newMode)
// If workspace lock is on, keep the current API config — don't load mode-specific config
// If workspace lock is on, or the caller explicitly requested preserving the current
// API config (e.g. AI-initiated mode switches via the switch_mode tool), keep the
// current API config — don't load mode-specific config.
const lockApiConfigAcrossModes = this.context.workspaceState.get("lockApiConfigAcrossModes", false)
if (lockApiConfigAcrossModes) {
if (lockApiConfigAcrossModes || options?.preserveApiConfig) {
await this.postStateToWebview()
return
}

View file

@ -310,6 +310,28 @@ describe("ClineProvider - Lock API Config Across Modes", () => {
expect(activateProviderProfileSpy).not.toHaveBeenCalled()
})
it("skips mode-specific config lookup/load when preserveApiConfig option is true", async () => {
await mockContext.workspaceState.update("lockApiConfigAcrossModes", false)
const getModeConfigIdSpy = vi
.spyOn(provider.providerSettingsManager, "getModeConfigId")
.mockResolvedValue("architect-profile-id")
const listConfigSpy = vi
.spyOn(provider.providerSettingsManager, "listConfig")
.mockResolvedValue([
{ name: "architect-profile", id: "architect-profile-id", apiProvider: "anthropic" },
])
const activateProviderProfileSpy = vi
.spyOn(provider, "activateProviderProfile")
.mockResolvedValue(undefined)
await provider.handleModeSwitch("architect", { preserveApiConfig: true })
expect(getModeConfigIdSpy).not.toHaveBeenCalled()
expect(listConfigSpy).not.toHaveBeenCalled()
expect(activateProviderProfileSpy).not.toHaveBeenCalled()
})
it("keeps normal mode-specific lookup/load behavior when lockApiConfigAcrossModes is false", async () => {
await mockContext.workspaceState.update("lockApiConfigAcrossModes", false)