mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-08-04 19:45:34 +08:00
feat(proxy): flag managed-OAuth providers as routing-required
Managed-OAuth providers (github_copilot / codex_oauth / xai_oauth) need proxy takeover to inject credentials, but the "needs routing" badge and the switch-time warning only keyed off apiFormat — missing OAuth providers whose upstream format is native (e.g. the new Codex xAI Grok OAuth preset on openai_responses). - Add isOAuthProviderType / OAUTH_PROVIDER_TYPES as the SSOT for OAuth types - Extract providerNeedsRouting() as the authoritative predicate: managed OAuth always needs routing (the backend rejects these accounts' direct connection) regardless of apiFormat or Claude Desktop mode - ProviderCard badges (claude / codex / claude-desktop) and the switch warning consume the shared predicate instead of raw apiFormat - Gate the warning on per-app routing readiness: claude-desktop uses isProxyRunning (backend takeover status has no such field), other apps use isProxyTakeover — fixes false warnings on Desktop and missing warnings when the proxy runs but the app isn't taken over - Force proxy mode for all managed-OAuth providers in the Claude Desktop form (lock the mode toggle), not only xai_oauth - Add unit tests for providerNeedsRouting, the switch routing gate, and Desktop OAuth preset enforcement - i18n(zh/en/ja/zh-TW): add notifications.proxyReasonManagedOAuth
This commit is contained in:
@@ -21,11 +21,11 @@ import { FailoverPriorityBadge } from "@/components/providers/FailoverPriorityBa
|
||||
import {
|
||||
extractCodexBaseUrl,
|
||||
extractCodexExperimentalBearerToken,
|
||||
extractCodexWireApi,
|
||||
isCodexAnthropicWireApi,
|
||||
isCodexChatWireApi,
|
||||
} from "@/utils/providerConfigUtils";
|
||||
import { supportsOfficialProxyTakeover } from "@/utils/providerCapabilities";
|
||||
import {
|
||||
supportsOfficialProxyTakeover,
|
||||
providerNeedsRouting,
|
||||
} from "@/utils/providerCapabilities";
|
||||
import { useProviderHealth } from "@/lib/query/failover";
|
||||
import { useUsageQuery } from "@/lib/query/queries";
|
||||
import { resolveProviderIcon } from "@/utils/providerIcon";
|
||||
@@ -227,25 +227,10 @@ export function ProviderCard({
|
||||
appId === "hermes" && isHermesReadOnlyProvider(provider.settingsConfig);
|
||||
const isCodexOauth =
|
||||
provider.meta?.providerType === PROVIDER_TYPES.CODEX_OAUTH;
|
||||
const codexNeedsRouting = useMemo(() => {
|
||||
if (appId !== "codex" || provider.category === "official") return false;
|
||||
if (
|
||||
provider.meta?.apiFormat === "openai_chat" ||
|
||||
provider.meta?.apiFormat === "anthropic"
|
||||
)
|
||||
return true;
|
||||
const config = (provider.settingsConfig as Record<string, any>)?.config;
|
||||
return (
|
||||
typeof config === "string" &&
|
||||
(isCodexChatWireApi(extractCodexWireApi(config)) ||
|
||||
isCodexAnthropicWireApi(extractCodexWireApi(config)))
|
||||
);
|
||||
}, [
|
||||
appId,
|
||||
provider.category,
|
||||
provider.meta?.apiFormat,
|
||||
(provider.settingsConfig as Record<string, any>)?.config,
|
||||
]);
|
||||
// 统一权威谓词(详见 providerNeedsRouting):以 providerType 为准,不受
|
||||
// apiFormat 被改动/缺省影响。此 badge 仅在 Codex 视图渲染,故加 appId 守卫。
|
||||
const codexNeedsRouting =
|
||||
appId === "codex" && providerNeedsRouting(appId, provider);
|
||||
// 获取用量数据以判断是否有多套餐
|
||||
// 累加模式应用(OpenCode/OpenClaw/Hermes):使用 isInConfig 代替 isCurrent
|
||||
const shouldAutoQuery =
|
||||
@@ -381,8 +366,7 @@ export function ProviderCard({
|
||||
)}
|
||||
|
||||
{appId === "claude-desktop" &&
|
||||
provider.category !== "official" &&
|
||||
provider.meta?.claudeDesktopMode === "proxy" && (
|
||||
providerNeedsRouting(appId, provider) && (
|
||||
<span className="inline-flex items-center rounded-md bg-sky-100 px-1.5 py-0.5 text-[10px] font-semibold text-sky-700 dark:bg-sky-900/40 dark:text-sky-300">
|
||||
{t("claudeDesktop.modeProxy", {
|
||||
defaultValue: "需要路由",
|
||||
@@ -390,16 +374,13 @@ export function ProviderCard({
|
||||
</span>
|
||||
)}
|
||||
|
||||
{appId === "claude" &&
|
||||
provider.category !== "official" &&
|
||||
provider.meta?.apiFormat &&
|
||||
provider.meta.apiFormat !== "anthropic" && (
|
||||
<span className="inline-flex items-center rounded-md bg-sky-100 px-1.5 py-0.5 text-[10px] font-semibold text-sky-700 dark:bg-sky-900/40 dark:text-sky-300">
|
||||
{t("claudeCode.needsRouting", {
|
||||
defaultValue: "需要路由",
|
||||
})}
|
||||
</span>
|
||||
)}
|
||||
{appId === "claude" && providerNeedsRouting(appId, provider) && (
|
||||
<span className="inline-flex items-center rounded-md bg-sky-100 px-1.5 py-0.5 text-[10px] font-semibold text-sky-700 dark:bg-sky-900/40 dark:text-sky-300">
|
||||
{t("claudeCode.needsRouting", {
|
||||
defaultValue: "需要路由",
|
||||
})}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{codexNeedsRouting && (
|
||||
<span className="inline-flex items-center rounded-md bg-sky-100 px-1.5 py-0.5 text-[10px] font-semibold text-sky-700 dark:bg-sky-900/40 dark:text-sky-300">
|
||||
|
||||
Reference in New Issue
Block a user