fix(model-aliases): avoid collisions with existing model names

This commit is contained in:
lzt404 committed 2026-08-03 23:17:28 +08:00
1 parent 83286da7d9
commit eb7fe25dd2
2 files changed
+37 -3

No files matched your search

+26 -3
View File
@@ -120,6 +120,28 @@ export const defaultModelAlias = (
return `${normalizedModel}${normalizedEffort ? `-${normalizedEffort}` : ''}${fast ? '-fast' : ''}`;
};
export const uniqueModelAlias = (
alias: string,
existingModelNames: string[],
) => {
const normalizedAlias = alias.trim();
if (!normalizedAlias) return '';
const existingNames = new Set(
existingModelNames
.map((name) => name.trim().toLowerCase())
.filter(Boolean),
);
if (!existingNames.has(normalizedAlias.toLowerCase())) return normalizedAlias;
let suffix = 2;
let candidate = `${normalizedAlias}-${suffix}`;
while (existingNames.has(candidate.toLowerCase())) {
suffix += 1;
candidate = `${normalizedAlias}-${suffix}`;
}
return candidate;
};
export const thinkingAliasSourceKindLabel = (kind: string) => {
if (kind === 'codex-oauth') return 'Codex OAuth';
if (kind === 'codex-api') return 'Codex API';
@@ -295,6 +317,7 @@ export function ThinkingAliasesPage() {
const normalizedEffort = effort.trim().toLowerCase();
const defaultAlias = defaultModelAlias(selectedSource?.model, normalizedEffort, fastEnabled);
const uniqueDefaultAlias = uniqueModelAlias(defaultAlias, sources.map((source) => source.model));
const customEffortSelected = Boolean(
normalizedEffort
&& !effortOptions.some((option) => option.value === normalizedEffort),
@@ -305,10 +328,10 @@ export function ThinkingAliasesPage() {
const currentValue = current.trim();
const canReplace = !currentValue || currentValue === generatedAliasRef.current;
if (!canReplace) return current;
generatedAliasRef.current = defaultAlias;
return defaultAlias;
generatedAliasRef.current = uniqueDefaultAlias;
return uniqueDefaultAlias;
});
}, [defaultAlias]);
}, [uniqueDefaultAlias]);
const createAlias = async () => {
if (!selectedSource) {
+11
View File
@@ -4,6 +4,7 @@ import {
combineModelAliasSources,
defaultModelAlias,
thinkingAliasSourceKindLabel,
uniqueModelAlias,
} from '../src/pages/ThinkingAliasesPage';
describe('模型别名默认名称', () => {
@@ -13,6 +14,16 @@ describe('模型别名默认名称', () => {
expect(defaultModelAlias('gpt-5.6-sol', 'xhigh', true)).toBe('gpt-5.6-sol-xhigh-fast');
expect(defaultModelAlias('gpt-5.6-sol', '', false)).toBe('');
});
test('默认别名与现有模型重名时递增数字后缀', () => {
expect(uniqueModelAlias('gpt-5.6-sol-fast', ['gpt-5.6-sol-fast'])).toBe('gpt-5.6-sol-fast-2');
expect(uniqueModelAlias('gpt-5.6-sol-fast', [
'gpt-5.6-sol-fast',
'gpt-5.6-sol-fast-2',
])).toBe('gpt-5.6-sol-fast-3');
expect(uniqueModelAlias('gpt-5.6-sol-fast', ['GPT-5.6-SOL-FAST'])).toBe('gpt-5.6-sol-fast-2');
expect(uniqueModelAlias('gpt-5.6-sol-fast', ['gpt-5.6-sol'])).toBe('gpt-5.6-sol-fast');
});
});
describe('思考别名', () => {