Add Chat Completions routing for Codex providers

- Add a Codex API format selector and routing badge for Chat Completions providers.
- Convert Codex Responses requests to upstream Chat Completions when routing is required.
- Convert Chat Completions JSON and SSE responses back to Responses format.
- Keep generated Codex wire_api values on Responses for Codex compatibility.
- Add i18n labels, provider metadata handling, and focused conversion tests.
This commit is contained in:
Jason
2026-05-19 10:23:48 +08:00
parent 61e68d754c
commit 1c82b8a3fa
19 changed files with 2230 additions and 35 deletions
+18
View File
@@ -19,6 +19,10 @@ import {
} from "@/lib/query";
import { extractErrorMessage } from "@/utils/errorUtils";
import { openclawKeys } from "@/hooks/useOpenClaw";
import {
extractCodexWireApi,
isCodexChatWireApi,
} from "@/utils/providerConfigUtils";
/**
* Hook for managing provider actions (add, update, delete, switch)
@@ -149,6 +153,16 @@ export function useProviderActions(
const isCopilotProvider =
activeApp === "claude" &&
provider.meta?.providerType === "github_copilot";
const isCodexChatFormat =
activeApp === "codex" &&
(provider.meta?.apiFormat === "openai_chat" ||
(typeof (provider.settingsConfig as Record<string, any>)?.config ===
"string" &&
isCodexChatWireApi(
extractCodexWireApi(
(provider.settingsConfig as Record<string, any>).config,
),
)));
// Determine why this provider requires the proxy
let proxyRequiredReason: string | null = null;
@@ -171,6 +185,10 @@ export function useProviderActions(
proxyRequiredReason = t("notifications.proxyReasonOpenAIResponses", {
defaultValue: "使用 OpenAI Responses 接口格式",
});
} else if (isCodexChatFormat) {
proxyRequiredReason = t("notifications.proxyReasonOpenAIChat", {
defaultValue: "使用 OpenAI Chat 接口格式",
});
} else if (
activeApp === "claude-desktop" &&
provider.meta?.claudeDesktopMode === "proxy"