mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
fix: Codex model catalog WYSIWYG and config consolidation
- Remove mergeCodexDefaultCatalogModelForSave implicit injection (P1) The model mapping table is now the single source of truth; no hidden entries are prepended on save. - Sync first catalog row model into config.toml on save Ensures Codex default request model matches the table's first entry instead of retaining a stale template value. - Remove API Format selector from CodexFormFields (P3) wire_api is always 'responses'; the selector confused users into thinking they were changing the upstream protocol. Only the 'Needs Local Routing' toggle remains. - Add restart hint to model mapping i18n text (P2) model_catalog_json is loaded at Codex startup; users are now informed that a restart is needed after changes. - Unify write_codex_live_with_catalog helper (P4) Replaces three scattered prepare+write call sites in config.rs, provider/live.rs, and proxy.rs with a single entry point. - Clean up useCodexConfigState dead state (P3 follow-up) Remove codexModelName, codexContextWindow, codexAutoCompactLimit and their handlers/effects since no component consumes them after the UI consolidation.
This commit is contained in:
@@ -15,6 +15,7 @@ import type {
|
||||
ProviderTestConfig,
|
||||
ClaudeApiFormat,
|
||||
CodexApiFormat,
|
||||
CodexCatalogModel,
|
||||
ClaudeApiKeyField,
|
||||
} from "@/types";
|
||||
import {
|
||||
@@ -55,6 +56,7 @@ import { mergeProviderMeta } from "@/utils/providerMetaUtils";
|
||||
import {
|
||||
extractCodexWireApi,
|
||||
setCodexWireApi,
|
||||
setCodexModelName as setCodexModelNameInConfig,
|
||||
} from "@/utils/providerConfigUtils";
|
||||
import { isNonNegativeDecimalString } from "@/types/usage";
|
||||
import { getCodexCustomTemplate } from "@/config/codexTemplates";
|
||||
@@ -142,6 +144,36 @@ const codexApiFormatFromWireApi = (
|
||||
}
|
||||
};
|
||||
|
||||
export const normalizeCodexCatalogModelsForSave = (
|
||||
models: CodexCatalogModel[],
|
||||
): CodexCatalogModel[] => {
|
||||
const seen = new Set<string>();
|
||||
const normalized: CodexCatalogModel[] = [];
|
||||
|
||||
for (const item of models) {
|
||||
const model = item.model.trim();
|
||||
if (!model || seen.has(model)) continue;
|
||||
seen.add(model);
|
||||
|
||||
const displayName = item.displayName?.trim();
|
||||
const rawContextWindow = String(item.contextWindow ?? "").replace(
|
||||
/[^\d]/g,
|
||||
"",
|
||||
);
|
||||
const contextWindow = rawContextWindow
|
||||
? Number.parseInt(rawContextWindow, 10)
|
||||
: undefined;
|
||||
|
||||
normalized.push({
|
||||
model,
|
||||
...(displayName ? { displayName } : {}),
|
||||
...(contextWindow && contextWindow > 0 ? { contextWindow } : {}),
|
||||
});
|
||||
}
|
||||
|
||||
return normalized;
|
||||
};
|
||||
|
||||
export interface ProviderFormProps {
|
||||
appId: AppId;
|
||||
providerId?: string;
|
||||
@@ -440,13 +472,13 @@ function ProviderFormFull({
|
||||
codexConfig,
|
||||
codexApiKey,
|
||||
codexBaseUrl,
|
||||
codexModelName,
|
||||
codexCatalogModels,
|
||||
codexAuthError,
|
||||
setCodexAuth,
|
||||
setCodexConfig,
|
||||
setCodexCatalogModels,
|
||||
handleCodexApiKeyChange,
|
||||
handleCodexBaseUrlChange,
|
||||
handleCodexModelNameChange,
|
||||
handleCodexConfigChange: originalHandleCodexConfigChange,
|
||||
resetCodexConfig,
|
||||
} = useCodexConfigState({ initialData });
|
||||
@@ -476,10 +508,6 @@ function ProviderFormFull({
|
||||
const handleCodexConfigChange = useCallback(
|
||||
(value: string) => {
|
||||
originalHandleCodexConfigChange(value);
|
||||
const nextFormat = codexApiFormatFromWireApi(extractCodexWireApi(value));
|
||||
if (nextFormat) {
|
||||
setLocalCodexApiFormat(nextFormat);
|
||||
}
|
||||
debouncedValidate(value);
|
||||
},
|
||||
[originalHandleCodexConfigChange, debouncedValidate],
|
||||
@@ -488,6 +516,7 @@ function ProviderFormFull({
|
||||
const handleCodexApiFormatChange = useCallback(
|
||||
(format: CodexApiFormat) => {
|
||||
setLocalCodexApiFormat(format);
|
||||
// wire_api is always "responses" for Codex; format controls proxy-layer conversion
|
||||
setCodexConfig((prev) => {
|
||||
const updated = setCodexWireApi(prev, "responses");
|
||||
debouncedValidate(updated);
|
||||
@@ -1109,14 +1138,32 @@ function ProviderFormFull({
|
||||
if (appId === "codex") {
|
||||
try {
|
||||
const authJson = JSON.parse(codexAuth);
|
||||
const normalizedCodexConfig =
|
||||
let normalizedCodexConfig =
|
||||
category !== "official" && (codexConfig ?? "").trim()
|
||||
? setCodexWireApi(codexConfig ?? "", "responses")
|
||||
: (codexConfig ?? "");
|
||||
const normalizedCatalogModels =
|
||||
category !== "official" && localCodexApiFormat === "openai_chat"
|
||||
? normalizeCodexCatalogModelsForSave(codexCatalogModels)
|
||||
: [];
|
||||
// Sync first catalog row's model into config.toml so Codex uses it as default
|
||||
if (normalizedCatalogModels.length > 0) {
|
||||
normalizedCodexConfig = setCodexModelNameInConfig(
|
||||
normalizedCodexConfig,
|
||||
normalizedCatalogModels[0].model,
|
||||
);
|
||||
}
|
||||
const configObj = {
|
||||
auth: authJson,
|
||||
config: normalizedCodexConfig,
|
||||
} as {
|
||||
auth: unknown;
|
||||
config: string;
|
||||
modelCatalog?: { models: CodexCatalogModel[] };
|
||||
};
|
||||
if (normalizedCatalogModels.length > 0) {
|
||||
configObj.modelCatalog = { models: normalizedCatalogModels };
|
||||
}
|
||||
settingsConfig = JSON.stringify(configObj);
|
||||
} catch (err) {
|
||||
settingsConfig = values.settingsConfig.trim();
|
||||
@@ -1937,9 +1984,8 @@ function ProviderFormFull({
|
||||
onAutoSelectChange={setEndpointAutoSelect}
|
||||
apiFormat={localCodexApiFormat}
|
||||
onApiFormatChange={handleCodexApiFormatChange}
|
||||
shouldShowModelField={category !== "official"}
|
||||
modelName={codexModelName}
|
||||
onModelNameChange={handleCodexModelNameChange}
|
||||
catalogModels={codexCatalogModels}
|
||||
onCatalogModelsChange={setCodexCatalogModels}
|
||||
speedTestEndpoints={speedTestEndpoints}
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user