feat(codex): expose official routing and restore the built-in provider

Let users switch between the built-in OpenAI provider and third-party Codex providers directly from the provider panel while takeover mode remains active.

Centralize the frontend capability predicate so only the fixed codex-official seed receives native-login routing support, and keep copied UUID-based official entries clearly marked as unsupported.

Add an idempotent backend command that recreates the deleted official seed, wire it into the add-provider flow, refresh localized guidance, and add mutation and provider-action regression coverage.
This commit is contained in:
Jason
2026-07-12 17:52:12 +08:00
parent f2c6d48e19
commit f15184edb0
15 changed files with 228 additions and 21 deletions
+4
View File
@@ -103,6 +103,10 @@ export const providersApi = {
return await invoke("ensure_claude_desktop_official_provider");
},
async ensureCodexOfficialProvider(): Promise<boolean> {
return await invoke("ensure_codex_official_provider");
},
async getClaudeDesktopStatus(): Promise<ClaudeDesktopStatus> {
return await invoke("get_claude_desktop_status");
},
+13
View File
@@ -10,6 +10,7 @@ import { generateUUID } from "@/utils/uuid";
import { openclawKeys } from "@/hooks/useOpenClaw";
import { invalidateHermesProviderCaches } from "@/hooks/useHermes";
import { usageKeys } from "@/lib/query/usage";
import { CODEX_OFFICIAL_PROVIDER_ID } from "@/utils/providerCapabilities";
export const useAddProviderMutation = (appId: AppId) => {
const queryClient = useQueryClient();
@@ -21,12 +22,14 @@ export const useAddProviderMutation = (appId: AppId) => {
providerKey?: string;
addToLive?: boolean;
ensureClaudeDesktopOfficialSeed?: boolean;
ensureCodexOfficialSeed?: boolean;
},
) => {
const {
providerKey: _providerKey,
addToLive,
ensureClaudeDesktopOfficialSeed,
ensureCodexOfficialSeed,
...rest
} = providerInput;
@@ -40,6 +43,16 @@ export const useAddProviderMutation = (appId: AppId) => {
return officialProvider;
}
if (appId === "codex" && ensureCodexOfficialSeed) {
await providersApi.ensureCodexOfficialProvider();
const providers = await providersApi.getAll(appId);
const officialProvider = providers[CODEX_OFFICIAL_PROVIDER_ID];
if (!officialProvider) {
throw new Error("Codex official provider was not created");
}
return officialProvider;
}
let id: string;
if (appId === "opencode" || appId === "openclaw" || appId === "hermes") {