feat(claude-desktop): add 44 provider presets translated from Claude Code

- New src/config/claudeDesktopProviderPresets.ts with the Claude Code
  preset list re-shaped into Desktop's three-segment route format
  (routeId / upstreamModel / displayName); excludes OAuth providers,
  AWS Bedrock (no SigV4 support) and KAT-Coder (placeholder URL).
- Non-Claude upstream presets show upstream model id as displayName
  (e.g. deepseek-v4-pro) so the Desktop model list reflects what is
  actually being requested. OpenRouter/TheRouter/PIPELLM keep
  Sonnet/Opus/Haiku since their upstream really is Anthropic Claude.
- Wire ProviderPresetSelector into ClaudeDesktopProviderForm so
  selecting a preset back-fills baseUrl, mode, routes and apiFormat.
- Drop the hard-coded ANTHROPIC_AUTH_TOKEN write in handleSubmit so
  ANTHROPIC_API_KEY presets (LemonData / AiHubMix / Gemini Native)
  save under the correct env key, and clear the opposite key on switch.
- Hide the universal-providers tab for claude-desktop because its
  meta-driven routing has no analogue in the universal flat-env shape.
- Add apps."claude-desktop" i18n key (zh/en/ja) so the dialog tab
  label resolves instead of showing the literal key.
This commit is contained in:
Jason
2026-05-09 17:19:09 +08:00
parent 292c117509
commit 5bbd83f7ca
7 changed files with 996 additions and 14 deletions
+26 -1
View File
@@ -17,6 +17,7 @@ import { UniversalProviderPanel } from "@/components/universal";
import { providerPresets } from "@/config/claudeProviderPresets";
import { codexProviderPresets } from "@/config/codexProviderPresets";
import { geminiProviderPresets } from "@/config/geminiProviderPresets";
import { claudeDesktopProviderPresets } from "@/config/claudeDesktopProviderPresets";
import { extractCodexBaseUrl } from "@/utils/providerConfigUtils";
import type { OpenClawSuggestedDefaults } from "@/config/openclawProviderPresets";
import type { UniversalProviderPreset } from "@/config/universalProviderPresets";
@@ -42,7 +43,10 @@ export function AddProviderDialog({
const { t } = useTranslation();
// OpenCode and OpenClaw don't support universal providers
const showUniversalTab =
appId !== "opencode" && appId !== "openclaw" && appId !== "hermes";
appId !== "opencode" &&
appId !== "openclaw" &&
appId !== "hermes" &&
appId !== "claude-desktop";
const [activeTab, setActiveTab] = useState<"app-specific" | "universal">(
"app-specific",
);
@@ -171,6 +175,22 @@ export function AddProviderDialog({
preset.endpointCandidates.forEach(addUrl);
}
}
} else if (appId === "claude-desktop") {
const presets = claudeDesktopProviderPresets;
const presetIndex = parseInt(
values.presetId.replace("claude-desktop-", ""),
);
if (
!isNaN(presetIndex) &&
presetIndex >= 0 &&
presetIndex < presets.length
) {
const preset = presets[presetIndex];
if (Array.isArray(preset.endpointCandidates)) {
preset.endpointCandidates.forEach(addUrl);
}
addUrl(preset.baseUrl);
}
}
}
@@ -179,6 +199,11 @@ export function AddProviderDialog({
if (env?.ANTHROPIC_BASE_URL) {
addUrl(env.ANTHROPIC_BASE_URL);
}
} else if (appId === "claude-desktop") {
const env = parsedConfig.env as Record<string, any> | undefined;
if (env?.ANTHROPIC_BASE_URL) {
addUrl(env.ANTHROPIC_BASE_URL);
}
} else if (appId === "codex") {
const config = parsedConfig.config as string | undefined;
if (config) {