From 8d38f0ee4f003e51d30f5345bc6c446bb6c17734 Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 5 Apr 2026 09:39:51 +0800 Subject: [PATCH] fix: allow provider switch without proxy, show warning instead of blocking Remove the hard block that prevented switching to providers requiring proxy (OpenAI format, Copilot, full URL mode) when the proxy is not running. Now the switch proceeds with a warning toast. Also deduplicate the proxy hint info toast so it doesn't appear alongside the warning. --- src/hooks/useProviderActions.ts | 4 ++-- tests/hooks/useProviderActions.test.tsx | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hooks/useProviderActions.ts b/src/hooks/useProviderActions.ts index a694e9484..346de6e5b 100644 --- a/src/hooks/useProviderActions.ts +++ b/src/hooks/useProviderActions.ts @@ -183,7 +183,6 @@ export function useProviderActions(activeApp: AppId, isProxyRunning?: boolean) { "此供应商{{reason}},需要代理服务才能正常使用,请先启动代理", }), ); - return; } try { @@ -203,13 +202,14 @@ export function useProviderActions(activeApp: AppId, isProxyRunning?: boolean) { // 根据供应商类型显示不同的成功提示 if ( + !proxyRequiredReason && activeApp === "claude" && provider.category !== "official" && (isCopilotProvider || provider.meta?.apiFormat === "openai_chat" || provider.meta?.apiFormat === "openai_responses") ) { - // OpenAI format provider: show proxy hint + // OpenAI format provider: show proxy hint (skip if warning already shown) toast.info( isCopilotProvider ? t("notifications.copilotProxyHint") diff --git a/tests/hooks/useProviderActions.test.tsx b/tests/hooks/useProviderActions.test.tsx index 8a7a2e8b4..2387b76a2 100644 --- a/tests/hooks/useProviderActions.test.tsx +++ b/tests/hooks/useProviderActions.test.tsx @@ -194,7 +194,8 @@ describe("useProviderActions", () => { expect(settingsApiApplyMock).not.toHaveBeenCalled(); }); - it("blocks switching providers that require proxy when proxy is not running", async () => { + it("warns but still switches providers that require proxy when proxy is not running", async () => { + switchProviderMutateAsync.mockResolvedValueOnce(undefined); const { wrapper } = createWrapper(); const provider = createProvider({ category: "custom", @@ -211,12 +212,12 @@ describe("useProviderActions", () => { await result.current.switchProvider(provider); }); - expect(switchProviderMutateAsync).not.toHaveBeenCalled(); expect(toastWarningMock).toHaveBeenCalledTimes(1); - expect(settingsApiGetMock).not.toHaveBeenCalled(); + expect(switchProviderMutateAsync).toHaveBeenCalledWith(provider.id); }); - it("blocks switching Codex full URL providers when proxy is not running", async () => { + it("warns but still switches Codex full URL providers when proxy is not running", async () => { + switchProviderMutateAsync.mockResolvedValueOnce(undefined); const { wrapper } = createWrapper(); const provider = createProvider({ category: "custom", @@ -233,9 +234,8 @@ describe("useProviderActions", () => { await result.current.switchProvider(provider); }); - expect(switchProviderMutateAsync).not.toHaveBeenCalled(); expect(toastWarningMock).toHaveBeenCalledTimes(1); - expect(settingsApiGetMock).not.toHaveBeenCalled(); + expect(switchProviderMutateAsync).toHaveBeenCalledWith(provider.id); }); it("should sync plugin config when switching Claude provider with integration enabled", async () => {