mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Merge pull request #550 from RooVetGit/fix_switch_mode_command
Do a more complete mode switch from switch_mode command
This commit is contained in:
5
.changeset/stupid-parrots-grin.md
Normal file
5
.changeset/stupid-parrots-grin.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"roo-cline": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix bug where the saved API provider for a mode wasn't being selected after a mode switch command
|
||||||
@@ -2065,11 +2065,10 @@ export class Cline {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch the mode
|
// Switch the mode using shared handler
|
||||||
const provider = this.providerRef.deref()
|
const provider = this.providerRef.deref()
|
||||||
if (provider) {
|
if (provider) {
|
||||||
await provider.updateGlobalState("mode", mode_slug)
|
await provider.handleModeSwitch(mode_slug)
|
||||||
await provider.postStateToWebview()
|
|
||||||
}
|
}
|
||||||
pushToolResult(
|
pushToolResult(
|
||||||
`Successfully switched from ${getModeBySlug(currentMode)?.name ?? currentMode} mode to ${
|
`Successfully switched from ${getModeBySlug(currentMode)?.name ?? currentMode} mode to ${
|
||||||
|
|||||||
@@ -781,38 +781,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||||||
await this.postStateToWebview()
|
await this.postStateToWebview()
|
||||||
break
|
break
|
||||||
case "mode":
|
case "mode":
|
||||||
const newMode = message.text as Mode
|
await this.handleModeSwitch(message.text as Mode)
|
||||||
await this.updateGlobalState("mode", newMode)
|
|
||||||
|
|
||||||
// Load the saved API config for the new mode if it exists
|
|
||||||
const savedConfigId = await this.configManager.getModeConfigId(newMode)
|
|
||||||
const listApiConfig = await this.configManager.listConfig()
|
|
||||||
|
|
||||||
// Update listApiConfigMeta first to ensure UI has latest data
|
|
||||||
await this.updateGlobalState("listApiConfigMeta", listApiConfig)
|
|
||||||
|
|
||||||
// If this mode has a saved config, use it
|
|
||||||
if (savedConfigId) {
|
|
||||||
const config = listApiConfig?.find((c) => c.id === savedConfigId)
|
|
||||||
if (config?.name) {
|
|
||||||
const apiConfig = await this.configManager.loadConfig(config.name)
|
|
||||||
await Promise.all([
|
|
||||||
this.updateGlobalState("currentApiConfigName", config.name),
|
|
||||||
this.updateApiConfiguration(apiConfig),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If no saved config for this mode, save current config as default
|
|
||||||
const currentApiConfigName = await this.getGlobalState("currentApiConfigName")
|
|
||||||
if (currentApiConfigName) {
|
|
||||||
const config = listApiConfig?.find((c) => c.name === currentApiConfigName)
|
|
||||||
if (config?.id) {
|
|
||||||
await this.configManager.setModeConfig(newMode, config.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.postStateToWebview()
|
|
||||||
break
|
break
|
||||||
case "updateSupportPrompt":
|
case "updateSupportPrompt":
|
||||||
try {
|
try {
|
||||||
@@ -1241,6 +1210,44 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle switching to a new mode, including updating the associated API configuration
|
||||||
|
* @param newMode The mode to switch to
|
||||||
|
*/
|
||||||
|
public async handleModeSwitch(newMode: Mode) {
|
||||||
|
await this.updateGlobalState("mode", newMode)
|
||||||
|
|
||||||
|
// Load the saved API config for the new mode if it exists
|
||||||
|
const savedConfigId = await this.configManager.getModeConfigId(newMode)
|
||||||
|
const listApiConfig = await this.configManager.listConfig()
|
||||||
|
|
||||||
|
// Update listApiConfigMeta first to ensure UI has latest data
|
||||||
|
await this.updateGlobalState("listApiConfigMeta", listApiConfig)
|
||||||
|
|
||||||
|
// If this mode has a saved config, use it
|
||||||
|
if (savedConfigId) {
|
||||||
|
const config = listApiConfig?.find((c) => c.id === savedConfigId)
|
||||||
|
if (config?.name) {
|
||||||
|
const apiConfig = await this.configManager.loadConfig(config.name)
|
||||||
|
await Promise.all([
|
||||||
|
this.updateGlobalState("currentApiConfigName", config.name),
|
||||||
|
this.updateApiConfiguration(apiConfig),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If no saved config for this mode, save current config as default
|
||||||
|
const currentApiConfigName = await this.getGlobalState("currentApiConfigName")
|
||||||
|
if (currentApiConfigName) {
|
||||||
|
const config = listApiConfig?.find((c) => c.name === currentApiConfigName)
|
||||||
|
if (config?.id) {
|
||||||
|
await this.configManager.setModeConfig(newMode, config.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.postStateToWebview()
|
||||||
|
}
|
||||||
|
|
||||||
private async updateApiConfiguration(apiConfiguration: ApiConfiguration) {
|
private async updateApiConfiguration(apiConfiguration: ApiConfiguration) {
|
||||||
// Update mode's default config
|
// Update mode's default config
|
||||||
const { mode } = await this.getState()
|
const { mode } = await this.getState()
|
||||||
|
|||||||
@@ -1100,6 +1100,68 @@ describe("ClineProvider", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("handleModeSwitch", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Set up webview for each test
|
||||||
|
provider.resolveWebviewView(mockWebviewView)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("loads saved API config when switching modes", async () => {
|
||||||
|
// Mock ConfigManager methods
|
||||||
|
provider.configManager = {
|
||||||
|
getModeConfigId: jest.fn().mockResolvedValue("saved-config-id"),
|
||||||
|
listConfig: jest
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValue([{ name: "saved-config", id: "saved-config-id", apiProvider: "anthropic" }]),
|
||||||
|
loadConfig: jest.fn().mockResolvedValue({ apiProvider: "anthropic" }),
|
||||||
|
setModeConfig: jest.fn(),
|
||||||
|
} as any
|
||||||
|
|
||||||
|
// Switch to architect mode
|
||||||
|
await provider.handleModeSwitch("architect")
|
||||||
|
|
||||||
|
// Verify mode was updated
|
||||||
|
expect(mockContext.globalState.update).toHaveBeenCalledWith("mode", "architect")
|
||||||
|
|
||||||
|
// Verify saved config was loaded
|
||||||
|
expect(provider.configManager.getModeConfigId).toHaveBeenCalledWith("architect")
|
||||||
|
expect(provider.configManager.loadConfig).toHaveBeenCalledWith("saved-config")
|
||||||
|
expect(mockContext.globalState.update).toHaveBeenCalledWith("currentApiConfigName", "saved-config")
|
||||||
|
|
||||||
|
// Verify state was posted to webview
|
||||||
|
expect(mockPostMessage).toHaveBeenCalledWith(expect.objectContaining({ type: "state" }))
|
||||||
|
})
|
||||||
|
|
||||||
|
test("saves current config when switching to mode without config", async () => {
|
||||||
|
// Mock ConfigManager methods
|
||||||
|
provider.configManager = {
|
||||||
|
getModeConfigId: jest.fn().mockResolvedValue(undefined),
|
||||||
|
listConfig: jest
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValue([{ name: "current-config", id: "current-id", apiProvider: "anthropic" }]),
|
||||||
|
setModeConfig: jest.fn(),
|
||||||
|
} as any
|
||||||
|
|
||||||
|
// Mock current config name
|
||||||
|
mockContext.globalState.get = jest.fn((key: string) => {
|
||||||
|
if (key === "currentApiConfigName") return "current-config"
|
||||||
|
return undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
// Switch to architect mode
|
||||||
|
await provider.handleModeSwitch("architect")
|
||||||
|
|
||||||
|
// Verify mode was updated
|
||||||
|
expect(mockContext.globalState.update).toHaveBeenCalledWith("mode", "architect")
|
||||||
|
|
||||||
|
// Verify current config was saved as default for new mode
|
||||||
|
expect(provider.configManager.setModeConfig).toHaveBeenCalledWith("architect", "current-id")
|
||||||
|
|
||||||
|
// Verify state was posted to webview
|
||||||
|
expect(mockPostMessage).toHaveBeenCalledWith(expect.objectContaining({ type: "state" }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("updateCustomMode", () => {
|
describe("updateCustomMode", () => {
|
||||||
test("updates both file and state when updating custom mode", async () => {
|
test("updates both file and state when updating custom mode", async () => {
|
||||||
provider.resolveWebviewView(mockWebviewView)
|
provider.resolveWebviewView(mockWebviewView)
|
||||||
|
|||||||
Reference in New Issue
Block a user