From 8708abfabf047cb06d8d9d501791b31fb7a2448e Mon Sep 17 00:00:00 2001 From: daniel-lxs Date: Wed, 29 Oct 2025 15:17:36 -0500 Subject: [PATCH] fix: Gate auth-driven Roo model refresh to active provider only Prevents unnecessary router model fetches when auth state changes and Roo is not the active provider. This reduces memory pressure by avoiding large model payload fetches and cache reconciliation when using non-Roo providers. - Gate requestRooModels by current provider === 'roo' - Add test coverage for auth gating behavior --- .../src/context/ExtensionStateContext.tsx | 7 +- ...tensionStateContext.roo-auth-gate.spec.tsx | 75 +++++++++++++++++++ 2 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 webview-ui/src/context/__tests__/ExtensionStateContext.roo-auth-gate.spec.tsx diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 7c68795040b..6443ccad93d 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -440,12 +440,13 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode // Watch for authentication state changes and refresh Roo models useEffect(() => { const currentAuth = state.cloudIsAuthenticated ?? false - if (!prevCloudIsAuthenticated && currentAuth) { - // User just authenticated - refresh Roo models with the new auth token + const currentProvider = state.apiConfiguration?.apiProvider + if (!prevCloudIsAuthenticated && currentAuth && currentProvider === "roo") { + // User just authenticated and Roo is the active provider - refresh Roo models vscode.postMessage({ type: "requestRooModels" }) } setPrevCloudIsAuthenticated(currentAuth) - }, [state.cloudIsAuthenticated, prevCloudIsAuthenticated]) + }, [state.cloudIsAuthenticated, prevCloudIsAuthenticated, state.apiConfiguration?.apiProvider]) const contextValue: ExtensionStateContextType = { ...state, diff --git a/webview-ui/src/context/__tests__/ExtensionStateContext.roo-auth-gate.spec.tsx b/webview-ui/src/context/__tests__/ExtensionStateContext.roo-auth-gate.spec.tsx new file mode 100644 index 00000000000..d62adf26e93 --- /dev/null +++ b/webview-ui/src/context/__tests__/ExtensionStateContext.roo-auth-gate.spec.tsx @@ -0,0 +1,75 @@ +import { render, waitFor } from "@/utils/test-utils" +import React from "react" + +vi.mock("@src/utils/vscode", () => ({ + vscode: { + postMessage: vi.fn(), + }, +})) + +import { ExtensionStateContextProvider } from "@src/context/ExtensionStateContext" +import { vscode } from "@src/utils/vscode" + +describe("ExtensionStateContext Roo auth gate", () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + function postStateMessage(state: any) { + window.dispatchEvent( + new MessageEvent("message", { + data: { + type: "state", + state, + }, + }), + ) + } + + it("does not post requestRooModels when auth flips and provider !== 'roo'", async () => { + render( + +
+ , + ) + + // Flip auth to true with a non-roo provider (anthropic) + postStateMessage({ + cloudIsAuthenticated: true, + apiConfiguration: { apiProvider: "anthropic" }, + }) + + // Should NOT fire auth-driven Roo refresh + await waitFor(() => { + const calls = (vscode.postMessage as any).mock.calls as any[][] + const hasRequest = calls.some((c) => c[0]?.type === "requestRooModels") + expect(hasRequest).toBe(false) + }) + }) + + it("posts requestRooModels when auth flips and provider === 'roo'", async () => { + render( + +
+ , + ) + + // Ensure prev false (explicit) + postStateMessage({ + cloudIsAuthenticated: false, + apiConfiguration: { apiProvider: "roo" }, + }) + + vi.clearAllMocks() + + // Flip to true with provider roo - should trigger + postStateMessage({ + cloudIsAuthenticated: true, + apiConfiguration: { apiProvider: "roo" }, + }) + + await waitFor(() => { + expect(vscode.postMessage).toHaveBeenCalledWith({ type: "requestRooModels" }) + }) + }) +})