mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-10 22:41:14 +00:00
fix: preserve selected model during AI-initiated mode switches
When the AI agent uses the switch_mode tool, the user's selected model should not change. Previously, handleModeSwitch would load mode-specific API configurations even for AI-initiated switches, unexpectedly changing the model mid-task. This adds a preserveApiConfig option to handleModeSwitch and passes it from SwitchModeTool so the current API config is preserved. User-initiated mode switches from the UI continue to load per-mode configs as before. Closes #12237
This commit is contained in:
parent
ad25634905
commit
6b186b447c
3 changed files with 30 additions and 5 deletions
|
|
@ -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 ${
|
||||
|
|
|
|||
|
|
@ -1391,7 +1391,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) {
|
||||
|
|
@ -1426,9 +1426,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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,6 +342,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)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue