From 62486534e42cb41d5b944c2eae152f8ff0f0ec27 Mon Sep 17 00:00:00 2001 From: Supra4E8C Date: Sat, 13 Dec 2025 02:20:08 +0800 Subject: [PATCH] feat: add excluded models support for Codex/Claude providers and fix header alignment - Add excludedModels field to ProviderKeyConfig type for Codex and Claude providers - Add excluded models textarea input in Codex/Claude edit modal - Display excluded models badges in Codex and Claude provider cards - Fix header connection status badge vertical alignment with IP address - Update dark theme to use pure black color scheme --- src/pages/AiProvidersPage.tsx | 57 ++++++++++++++++++++++++++++++++--- src/styles/components.scss | 6 ++++ src/styles/layout.scss | 1 + src/styles/themes.scss | 18 +++++------ src/types/provider.ts | 1 + 5 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/pages/AiProvidersPage.tsx b/src/pages/AiProvidersPage.tsx index ef51f48..19477f5 100644 --- a/src/pages/AiProvidersPage.tsx +++ b/src/pages/AiProvidersPage.tsx @@ -132,13 +132,15 @@ export function AiProvidersPage() { excludedModels: [], excludedText: '' }); - const [providerForm, setProviderForm] = useState({ + const [providerForm, setProviderForm] = useState({ apiKey: '', baseUrl: '', proxyUrl: '', headers: {}, models: [], - modelEntries: [{ name: '', alias: '' }] + excludedModels: [], + modelEntries: [{ name: '', alias: '' }], + excludedText: '' }); const [openaiForm, setOpenaiForm] = useState({ name: '', @@ -231,7 +233,9 @@ export function AiProvidersPage() { proxyUrl: '', headers: {}, models: [], - modelEntries: [{ name: '', alias: '' }] + excludedModels: [], + modelEntries: [{ name: '', alias: '' }], + excludedText: '' }); setOpenaiForm({ name: '', @@ -269,7 +273,8 @@ export function AiProvidersPage() { const entry = source[index]; setProviderForm({ ...entry, - modelEntries: modelsToEntries(entry?.models) + modelEntries: modelsToEntries(entry?.models), + excludedText: excludedModelsToText(entry?.excludedModels) }); } setModal({ type, index }); @@ -558,7 +563,8 @@ export function AiProvidersPage() { baseUrl, proxyUrl: providerForm.proxyUrl?.trim() || undefined, headers: buildHeaderObject(headersToEntries(providerForm.headers as any)), - models: entriesToModels(providerForm.modelEntries) + models: entriesToModels(providerForm.modelEntries), + excludedModels: parseExcludedModels(providerForm.excludedText) }; const source = type === 'codex' ? codexConfigs : claudeConfigs; @@ -888,6 +894,21 @@ export function AiProvidersPage() { ))} )} + {/* 排除模型徽章 */} + {item.excludedModels?.length ? ( +
+
+ {t('ai_providers.excluded_models_count', { count: item.excludedModels.length })} +
+
+ {item.excludedModels.map((model) => ( + + {model} + + ))} +
+
+ ) : null} {/* 成功/失败统计 */}
@@ -970,6 +991,21 @@ export function AiProvidersPage() { ))}
) : null} + {/* 排除模型徽章 */} + {item.excludedModels?.length ? ( +
+
+ {t('ai_providers.excluded_models_count', { count: item.excludedModels.length })} +
+
+ {item.excludedModels.map((model) => ( + + {model} + + ))} +
+
+ ) : null} {/* 成功/失败统计 */}
@@ -1213,6 +1249,17 @@ export function AiProvidersPage() { disabled={saving} />
+
+ +