Skip to content

Commit 1a727b5

Browse files
committed
fix: preserve OpenRouter experimental settings when switching API profiles
- Modified activateProviderProfile to preserve openRouterImageGenerationSettings - Added tests to verify the fix works correctly - Ensures experimental image generation settings are not lost during profile switches
1 parent aee531a commit 1a727b5

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

src/core/webview/ClineProvider.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,8 +1243,17 @@ export class ClineProvider
12431243
}
12441244

12451245
async activateProviderProfile(args: { name: string } | { id: string }) {
1246+
// Get current settings to preserve experimental settings
1247+
const currentSettings = this.contextProxy.getProviderSettings()
1248+
12461249
const { name, id, ...providerSettings } = await this.providerSettingsManager.activateProfile(args)
12471250

1251+
// Preserve openRouterImageGenerationSettings if it exists in current settings
1252+
// This ensures experimental settings like the image generation API key are not lost
1253+
if (currentSettings.openRouterImageGenerationSettings) {
1254+
providerSettings.openRouterImageGenerationSettings = currentSettings.openRouterImageGenerationSettings
1255+
}
1256+
12481257
// See `upsertProviderProfile` for a description of what this is doing.
12491258
await Promise.all([
12501259
this.contextProxy.setValue("listApiConfigMeta", await this.providerSettingsManager.listConfig()),

src/core/webview/__tests__/ClineProvider.spec.ts

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,136 @@ describe("ClineProvider", () => {
16581658
// Verify state was posted to webview
16591659
expect(mockPostMessage).toHaveBeenCalledWith(expect.objectContaining({ type: "state" }))
16601660
})
1661+
1662+
test("preserves openRouterImageGenerationSettings when switching profiles", async () => {
1663+
// Set up webview
1664+
await provider.resolveWebviewView(mockWebviewView)
1665+
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
1666+
1667+
// Mock the context proxy to have experimental settings
1668+
const contextProxy = (provider as any).contextProxy
1669+
const getProviderSettingsSpy = vi.spyOn(contextProxy, "getProviderSettings")
1670+
getProviderSettingsSpy.mockReturnValue({
1671+
apiProvider: "openrouter",
1672+
openRouterImageGenerationSettings: {
1673+
openRouterApiKey: "test-experimental-key",
1674+
selectedModel: "dall-e-3",
1675+
},
1676+
})
1677+
1678+
// Mock provider settings manager - activateProfile returns the full provider settings
1679+
const profileSettings = {
1680+
apiProvider: "anthropic" as const,
1681+
apiKey: "new-key",
1682+
}
1683+
1684+
;(provider as any).providerSettingsManager = {
1685+
activateProfile: vi.fn().mockResolvedValue({
1686+
name: "new-profile",
1687+
id: "new-profile-id",
1688+
...profileSettings,
1689+
}),
1690+
listConfig: vi.fn().mockResolvedValue([
1691+
{
1692+
name: "new-profile",
1693+
id: "new-profile-id",
1694+
apiProvider: "anthropic",
1695+
},
1696+
]),
1697+
setModeConfig: vi.fn().mockResolvedValue(undefined),
1698+
} as any
1699+
1700+
// Spy on setProviderSettings to verify the merged settings
1701+
const setProviderSettingsSpy = vi.spyOn(contextProxy, "setProviderSettings")
1702+
1703+
// Spy on activateProviderProfile method
1704+
const activateProviderProfileSpy = vi.spyOn(provider, "activateProviderProfile")
1705+
1706+
// Spy on postStateToWebview
1707+
const postStateToWebviewSpy = vi.spyOn(provider, "postStateToWebview").mockResolvedValue(undefined)
1708+
1709+
// Trigger profile activation via webview message
1710+
await messageHandler({
1711+
type: "loadApiConfiguration",
1712+
text: "new-profile",
1713+
})
1714+
1715+
// Verify that activateProviderProfile was called
1716+
expect(activateProviderProfileSpy).toHaveBeenCalledWith({ name: "new-profile" })
1717+
1718+
// Verify that activateProfile was called
1719+
expect(provider.providerSettingsManager.activateProfile).toHaveBeenCalledWith({ name: "new-profile" })
1720+
1721+
// Verify that setProviderSettings was called with merged settings including experimental settings
1722+
expect(setProviderSettingsSpy).toHaveBeenCalledWith({
1723+
apiProvider: "anthropic",
1724+
apiKey: "new-key",
1725+
openRouterImageGenerationSettings: {
1726+
openRouterApiKey: "test-experimental-key",
1727+
selectedModel: "dall-e-3",
1728+
},
1729+
})
1730+
1731+
// Verify state was posted to webview
1732+
expect(postStateToWebviewSpy).toHaveBeenCalled()
1733+
})
1734+
1735+
test("handles missing openRouterImageGenerationSettings when switching profiles", async () => {
1736+
// Set up webview
1737+
await provider.resolveWebviewView(mockWebviewView)
1738+
const messageHandler = (mockWebviewView.webview.onDidReceiveMessage as any).mock.calls[0][0]
1739+
1740+
// Mock the context proxy without experimental settings
1741+
const contextProxy = (provider as any).contextProxy
1742+
const getProviderSettingsSpy = vi.spyOn(contextProxy, "getProviderSettings")
1743+
getProviderSettingsSpy.mockReturnValue({
1744+
apiProvider: "openrouter",
1745+
// No openRouterImageGenerationSettings
1746+
})
1747+
1748+
// Mock provider settings manager - activateProfile returns the full provider settings
1749+
const profileSettings = {
1750+
apiProvider: "anthropic" as const,
1751+
apiKey: "new-key",
1752+
}
1753+
1754+
;(provider as any).providerSettingsManager = {
1755+
activateProfile: vi.fn().mockResolvedValue({
1756+
name: "new-profile",
1757+
id: "new-profile-id",
1758+
...profileSettings,
1759+
}),
1760+
listConfig: vi.fn().mockResolvedValue([
1761+
{
1762+
name: "new-profile",
1763+
id: "new-profile-id",
1764+
apiProvider: "anthropic",
1765+
},
1766+
]),
1767+
} as any
1768+
1769+
// Spy on setProviderSettings
1770+
const setProviderSettingsSpy = vi.spyOn(contextProxy, "setProviderSettings")
1771+
1772+
// Spy on activateProviderProfile method
1773+
const activateProviderProfileSpy = vi.spyOn(provider, "activateProviderProfile")
1774+
1775+
// Trigger profile activation via webview message
1776+
await messageHandler({
1777+
type: "loadApiConfiguration",
1778+
text: "new-profile",
1779+
})
1780+
1781+
// Verify that activateProviderProfile was called
1782+
expect(activateProviderProfileSpy).toHaveBeenCalledWith({ name: "new-profile" })
1783+
1784+
// Verify that setProviderSettings was called without experimental settings
1785+
expect(setProviderSettingsSpy).toHaveBeenCalledWith({
1786+
apiProvider: "anthropic",
1787+
apiKey: "new-key",
1788+
// No openRouterImageGenerationSettings
1789+
})
1790+
})
16611791
})
16621792

16631793
describe("createTaskWithHistoryItem mode validation", () => {

0 commit comments

Comments
 (0)