feat(codex): add AiHubMix provider and enhance configuration UX
- Add new AiHubMix provider preset with dual endpoints - Fix AnyRouter base_url inconsistency (add /v1 suffix) - Add configuration wizard shortcut link for Codex custom mode - Improve accessibility with aria-label for wizard button - Remove unused isCustomMode prop from CodexConfigEditor - Add internationalization for new UI elements (zh/en)
This commit is contained in:
@@ -28,8 +28,6 @@ interface CodexConfigEditorProps {
|
||||
|
||||
configError: string; // config.toml 错误提示
|
||||
|
||||
isCustomMode?: boolean; // 是否为自定义模式
|
||||
|
||||
onWebsiteUrlChange?: (url: string) => void; // 更新网址回调
|
||||
|
||||
isTemplateModalOpen?: boolean; // 模态框状态
|
||||
|
||||
@@ -453,6 +453,12 @@ export function ProviderForm({
|
||||
presetCategoryLabels={presetCategoryLabels}
|
||||
onPresetChange={handlePresetChange}
|
||||
category={category}
|
||||
appId={appId}
|
||||
onOpenWizard={
|
||||
appId === "codex"
|
||||
? () => setIsCodexTemplateModalOpen(true)
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -523,7 +529,6 @@ export function ProviderForm({
|
||||
commonConfigError={codexCommonConfigError}
|
||||
authError={codexAuthError}
|
||||
configError={codexConfigError}
|
||||
isCustomMode={selectedPresetId === "custom"}
|
||||
onWebsiteUrlChange={(url) => form.setValue("websiteUrl", url)}
|
||||
onNameChange={(name) => form.setValue("name", name)}
|
||||
isTemplateModalOpen={isCodexTemplateModalOpen}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Zap } from "lucide-react";
|
||||
import type { ProviderPreset } from "@/config/claudeProviderPresets";
|
||||
import type { CodexProviderPreset } from "@/config/codexProviderPresets";
|
||||
import type { ProviderCategory } from "@/types";
|
||||
import type { AppId } from "@/lib/api";
|
||||
|
||||
type PresetEntry = {
|
||||
id: string;
|
||||
@@ -18,6 +19,8 @@ interface ProviderPresetSelectorProps {
|
||||
presetCategoryLabels: Record<string, string>;
|
||||
onPresetChange: (value: string) => void;
|
||||
category?: ProviderCategory; // 新增:当前选中的分类
|
||||
appId?: AppId;
|
||||
onOpenWizard?: () => void; // Codex 专用:打开配置向导
|
||||
}
|
||||
|
||||
export function ProviderPresetSelector({
|
||||
@@ -27,11 +30,13 @@ export function ProviderPresetSelector({
|
||||
presetCategoryLabels,
|
||||
onPresetChange,
|
||||
category,
|
||||
appId,
|
||||
onOpenWizard,
|
||||
}: ProviderPresetSelectorProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
// 根据分类获取提示文字
|
||||
const getCategoryHint = () => {
|
||||
const getCategoryHint = (): React.ReactNode => {
|
||||
switch (category) {
|
||||
case "official":
|
||||
return t("providerForm.officialHint", {
|
||||
@@ -50,6 +55,23 @@ export function ProviderPresetSelector({
|
||||
defaultValue: "💡 第三方供应商需要填写 API Key 和请求地址",
|
||||
});
|
||||
case "custom":
|
||||
// Codex 自定义:在此位置显示"手动配置…或者 使用配置向导"
|
||||
if (appId === "codex" && onOpenWizard) {
|
||||
return (
|
||||
<>
|
||||
{t("providerForm.manualConfig")}
|
||||
<button
|
||||
type="button"
|
||||
onClick={onOpenWizard}
|
||||
className="ml-1 text-blue-500 dark:text-blue-400 hover:text-blue-600 dark:hover:text-blue-300 underline-offset-2 hover:underline"
|
||||
aria-label={t("providerForm.openConfigWizard")}
|
||||
>
|
||||
{t("providerForm.useConfigWizard")}
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
// 其他情况沿用原提示
|
||||
return t("providerForm.customApiKeyHint", {
|
||||
defaultValue: "💡 自定义配置需手动填写所有必要字段",
|
||||
});
|
||||
|
||||
@@ -70,6 +70,21 @@ export const codexProviderPresets: CodexProviderPreset[] = [
|
||||
textColor: "#FFFFFF",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "AiHubMix",
|
||||
websiteUrl: "https://aihubmix.com",
|
||||
category: "cn_official",
|
||||
auth: generateThirdPartyAuth(""),
|
||||
config: generateThirdPartyConfig(
|
||||
"aihubmix",
|
||||
"https://aihubmix.com/v1",
|
||||
"gpt-5-codex",
|
||||
),
|
||||
endpointCandidates: [
|
||||
"https://aihubmix.com/v1",
|
||||
"https://api.aihubmix.com/v1",
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "PackyCode",
|
||||
websiteUrl: "https://www.packyapi.com",
|
||||
@@ -80,7 +95,6 @@ export const codexProviderPresets: CodexProviderPreset[] = [
|
||||
"https://www.packyapi.com/v1",
|
||||
"gpt-5-codex",
|
||||
),
|
||||
// Codex 请求地址候选(用于地址管理/测速)
|
||||
endpointCandidates: [
|
||||
"https://www.packyapi.com/v1",
|
||||
"https://api-slb.packyapi.com/v1",
|
||||
@@ -93,14 +107,13 @@ export const codexProviderPresets: CodexProviderPreset[] = [
|
||||
auth: generateThirdPartyAuth(""),
|
||||
config: generateThirdPartyConfig(
|
||||
"anyrouter",
|
||||
"https://anyrouter.top",
|
||||
"https://anyrouter.top/v1",
|
||||
"gpt-5-codex",
|
||||
),
|
||||
// Codex 请求地址候选(用于地址管理/测速)
|
||||
endpointCandidates: [
|
||||
"https://anyrouter.top",
|
||||
"https://q.quuvv.cn",
|
||||
"https://pmpjfbhq.cn-nb1.rainapp.top",
|
||||
"https://anyrouter.top/v1",
|
||||
"https://q.quuvv.cn/v1",
|
||||
"https://pmpjfbhq.cn-nb1.rainapp.top/v1",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -226,6 +226,7 @@
|
||||
"manageAndTest": "Manage & Test",
|
||||
"configContent": "Config Content",
|
||||
"useConfigWizard": "Use Configuration Wizard",
|
||||
"openConfigWizard": "Open configuration wizard",
|
||||
"manualConfig": "Manually configure provider, requires complete configuration, or",
|
||||
"officialNoApiKey": "Official login does not require API Key, save directly",
|
||||
"codexOfficialNoApiKey": "Official does not require API Key, save directly",
|
||||
|
||||
@@ -226,6 +226,7 @@
|
||||
"manageAndTest": "管理与测速",
|
||||
"configContent": "配置内容",
|
||||
"useConfigWizard": "使用配置向导",
|
||||
"openConfigWizard": "打开配置向导",
|
||||
"manualConfig": "手动配置供应商,需要填写完整的配置信息,或者",
|
||||
"officialNoApiKey": "官方登录无需填写 API Key,直接保存即可",
|
||||
"codexOfficialNoApiKey": "官方无需填写 API Key,直接保存即可",
|
||||
|
||||
Reference in New Issue
Block a user