mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-17 06:14:30 +00:00
fix(cliproxy): narrow legacy gemini alias cleanup
This commit is contained in:
1 parent
061cd9679f
commit
c4428e4176
2 files changed
+445
-86
No files matched your search
@@ -753,7 +753,202 @@ oauth-model-alias:
|
||||
);
|
||||
});
|
||||
|
||||
it('drops stale generated Gemini preview clusters while preserving true custom aliases', () => {
|
||||
it('drops stale multi-version Gemini preview ranges while preserving true custom aliases', () => {
|
||||
const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy');
|
||||
fs.mkdirSync(cliproxyDir, { recursive: true });
|
||||
const guessedMinors = ['3', '4', '5', '6'];
|
||||
const buildGuessedRange = (name, family) =>
|
||||
guessedMinors
|
||||
.flatMap((minor) => [
|
||||
` - name: ${name}`,
|
||||
` alias: gemini-3.${minor}-${family}-preview`,
|
||||
` - name: ${name}`,
|
||||
` alias: gemini-3.${minor}-${family}-preview-customtools`,
|
||||
` - name: ${name}`,
|
||||
` alias: gemini-3-${minor}-${family}-preview`,
|
||||
` - name: ${name}`,
|
||||
` alias: gemini-3-${minor}-${family}-preview-customtools`,
|
||||
])
|
||||
.join('\n');
|
||||
|
||||
const initialConfig = `# CLIProxyAPI config generated by CCS v12
|
||||
port: 8317
|
||||
api-keys:
|
||||
- "ccs-internal-managed"
|
||||
auth-dir: "${cliproxyDir.replace(/\\/g, '/')}/auth"
|
||||
oauth-model-alias:
|
||||
antigravity:
|
||||
${buildGuessedRange('gemini-3-pro-high', 'pro')}
|
||||
${buildGuessedRange('gemini-3-flash', 'flash')}
|
||||
- name: custom-model
|
||||
alias: keep-me
|
||||
`;
|
||||
fs.writeFileSync(path.join(cliproxyDir, 'config.yaml'), initialConfig);
|
||||
|
||||
regenerateConfig();
|
||||
|
||||
const newConfig = fs.readFileSync(path.join(cliproxyDir, 'config.yaml'), 'utf-8');
|
||||
for (const minor of guessedMinors) {
|
||||
assert(
|
||||
!newConfig.includes(`alias: gemini-3.${minor}-pro-preview`),
|
||||
`Should remove stale generated Pro aliases for 3.${minor}`
|
||||
);
|
||||
assert(
|
||||
!newConfig.includes(`alias: gemini-3-${minor}-flash-preview-customtools`),
|
||||
`Should remove stale generated Flash aliases for 3.${minor}`
|
||||
);
|
||||
}
|
||||
assert(newConfig.includes('alias: keep-me'), 'Should preserve true custom aliases');
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3-pro-preview'),
|
||||
'Should still keep current baseline Pro preview alias'
|
||||
);
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3.1-flash-preview-customtools'),
|
||||
'Should still keep current baseline Flash compatibility alias'
|
||||
);
|
||||
});
|
||||
|
||||
it('preserves sparse manual minor-version overrides when a stale guessed range is pruned', () => {
|
||||
const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy');
|
||||
fs.mkdirSync(cliproxyDir, { recursive: true });
|
||||
const guessedMinors = ['3', '4', '5', '6'];
|
||||
const staleRange = guessedMinors
|
||||
.flatMap((minor) => [
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3.${minor}-pro-preview`,
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3.${minor}-pro-preview-customtools`,
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3-${minor}-pro-preview`,
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3-${minor}-pro-preview-customtools`,
|
||||
])
|
||||
.join('\n');
|
||||
|
||||
const initialConfig = `# CLIProxyAPI config generated by CCS v12
|
||||
port: 8317
|
||||
api-keys:
|
||||
- "ccs-internal-managed"
|
||||
auth-dir: "${cliproxyDir.replace(/\\/g, '/')}/auth"
|
||||
oauth-model-alias:
|
||||
antigravity:
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3.2-pro-preview
|
||||
${staleRange}
|
||||
`;
|
||||
fs.writeFileSync(path.join(cliproxyDir, 'config.yaml'), initialConfig);
|
||||
|
||||
regenerateConfig();
|
||||
|
||||
const newConfig = fs.readFileSync(path.join(cliproxyDir, 'config.yaml'), 'utf-8');
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3.2-pro-preview'),
|
||||
'Should preserve sparse manual minor-version override'
|
||||
);
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3.2-pro-preview-customtools'),
|
||||
'Should still expand compatibility aliases for preserved sparse manual override'
|
||||
);
|
||||
for (const minor of guessedMinors) {
|
||||
assert(
|
||||
!newConfig.includes(`alias: gemini-3.${minor}-pro-preview`),
|
||||
`Should prune stale guessed aliases for 3.${minor}`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('preserves a manual 3.2 compatibility cluster while pruning higher stale guessed minors', () => {
|
||||
const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy');
|
||||
fs.mkdirSync(cliproxyDir, { recursive: true });
|
||||
const guessedMinors = ['3', '4', '5', '6'];
|
||||
const staleRange = guessedMinors
|
||||
.flatMap((minor) => [
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3.${minor}-pro-preview`,
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3.${minor}-pro-preview-customtools`,
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3-${minor}-pro-preview`,
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3-${minor}-pro-preview-customtools`,
|
||||
])
|
||||
.join('\n');
|
||||
|
||||
const initialConfig = `# CLIProxyAPI config generated by CCS v12
|
||||
port: 8317
|
||||
api-keys:
|
||||
- "ccs-internal-managed"
|
||||
auth-dir: "${cliproxyDir.replace(/\\/g, '/')}/auth"
|
||||
oauth-model-alias:
|
||||
antigravity:
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3.2-pro-preview
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3.2-pro-preview-customtools
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3-2-pro-preview
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3-2-pro-preview-customtools
|
||||
${staleRange}
|
||||
`;
|
||||
fs.writeFileSync(path.join(cliproxyDir, 'config.yaml'), initialConfig);
|
||||
|
||||
regenerateConfig();
|
||||
|
||||
const newConfig = fs.readFileSync(path.join(cliproxyDir, 'config.yaml'), 'utf-8');
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3.2-pro-preview'),
|
||||
'Should preserve the manual 3.2 compatibility cluster during legacy cleanup'
|
||||
);
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3-2-pro-preview-customtools'),
|
||||
'Should preserve hyphenated manual compatibility aliases for 3.2'
|
||||
);
|
||||
for (const minor of guessedMinors) {
|
||||
assert(
|
||||
!newConfig.includes(`alias: gemini-3.${minor}-pro-preview`),
|
||||
`Should prune higher stale guessed aliases for 3.${minor}`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('prunes partially retained guessed ranges during legacy cleanup', () => {
|
||||
const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy');
|
||||
fs.mkdirSync(cliproxyDir, { recursive: true });
|
||||
const guessedMinors = ['3', '4'];
|
||||
const partialRange = guessedMinors
|
||||
.flatMap((minor) => [
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3.${minor}-pro-preview`,
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3.${minor}-pro-preview-customtools`,
|
||||
])
|
||||
.join('\n');
|
||||
|
||||
const initialConfig = `# CLIProxyAPI config generated by CCS v12
|
||||
port: 8317
|
||||
api-keys:
|
||||
- "ccs-internal-managed"
|
||||
auth-dir: "${cliproxyDir.replace(/\\/g, '/')}/auth"
|
||||
oauth-model-alias:
|
||||
antigravity:
|
||||
${partialRange}
|
||||
`;
|
||||
fs.writeFileSync(path.join(cliproxyDir, 'config.yaml'), initialConfig);
|
||||
|
||||
regenerateConfig();
|
||||
|
||||
const newConfig = fs.readFileSync(path.join(cliproxyDir, 'config.yaml'), 'utf-8');
|
||||
for (const minor of guessedMinors) {
|
||||
assert(
|
||||
!newConfig.includes(`alias: gemini-3.${minor}-pro-preview`),
|
||||
`Should prune partially retained guessed aliases for 3.${minor}`
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it('preserves single-minor high-version aliases when they are not part of a guessed range', () => {
|
||||
const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy');
|
||||
fs.mkdirSync(cliproxyDir, { recursive: true });
|
||||
|
||||
@@ -765,23 +960,9 @@ auth-dir: "${cliproxyDir.replace(/\\/g, '/')}/auth"
|
||||
oauth-model-alias:
|
||||
antigravity:
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3.9-pro-preview
|
||||
alias: gemini-3.11-pro-preview
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3.9-pro-preview-customtools
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3-9-pro-preview
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3-9-pro-preview-customtools
|
||||
- name: gemini-3-flash
|
||||
alias: gemini-3.9-flash-preview
|
||||
- name: gemini-3-flash
|
||||
alias: gemini-3.9-flash-preview-customtools
|
||||
- name: gemini-3-flash
|
||||
alias: gemini-3-9-flash-preview
|
||||
- name: gemini-3-flash
|
||||
alias: gemini-3-9-flash-preview-customtools
|
||||
- name: custom-model
|
||||
alias: keep-me
|
||||
alias: gemini-3.11-pro-preview-customtools
|
||||
`;
|
||||
fs.writeFileSync(path.join(cliproxyDir, 'config.yaml'), initialConfig);
|
||||
|
||||
@@ -789,45 +970,47 @@ oauth-model-alias:
|
||||
|
||||
const newConfig = fs.readFileSync(path.join(cliproxyDir, 'config.yaml'), 'utf-8');
|
||||
assert(
|
||||
!newConfig.includes('alias: gemini-3.9-pro-preview'),
|
||||
'Should remove stale generated Pro preview alias noise'
|
||||
newConfig.includes('alias: gemini-3.11-pro-preview'),
|
||||
'Should preserve lone manual high-version aliases during legacy cleanup'
|
||||
);
|
||||
assert(
|
||||
!newConfig.includes('alias: gemini-3.9-pro-preview-customtools'),
|
||||
'Should remove stale generated Pro customtools alias noise'
|
||||
newConfig.includes('alias: gemini-3.11-pro-preview-customtools'),
|
||||
'Should still expand compatibility aliases for preserved high-version aliases'
|
||||
);
|
||||
});
|
||||
|
||||
it('writes a one-time backup before pruning legacy Gemini aliases during migration', () => {
|
||||
const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy');
|
||||
fs.mkdirSync(cliproxyDir, { recursive: true });
|
||||
const configPath = path.join(cliproxyDir, 'config.yaml');
|
||||
const guessedMinors = ['3', '4', '5'];
|
||||
const staleRange = guessedMinors
|
||||
.flatMap((minor) => [
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3.${minor}-pro-preview`,
|
||||
` - name: gemini-3-pro-high`,
|
||||
` alias: gemini-3.${minor}-pro-preview-customtools`,
|
||||
])
|
||||
.join('\n');
|
||||
|
||||
const initialConfig = `# CLIProxyAPI config generated by CCS v12
|
||||
port: 8317
|
||||
api-keys:
|
||||
- "ccs-internal-managed"
|
||||
auth-dir: "${cliproxyDir.replace(/\\/g, '/')}/auth"
|
||||
oauth-model-alias:
|
||||
antigravity:
|
||||
${staleRange}
|
||||
`;
|
||||
fs.writeFileSync(configPath, initialConfig);
|
||||
|
||||
regenerateConfig();
|
||||
|
||||
const backupPath = `${configPath}.pre-v16-gemini-alias-cleanup.bak`;
|
||||
assert(fs.existsSync(backupPath), 'Should keep a backup of the legacy config before pruning');
|
||||
assert(
|
||||
!newConfig.includes('alias: gemini-3-9-pro-preview'),
|
||||
'Should remove stale generated hyphenated Pro alias noise'
|
||||
);
|
||||
assert(
|
||||
!newConfig.includes('alias: gemini-3-9-pro-preview-customtools'),
|
||||
'Should remove stale generated hyphenated Pro customtools alias noise'
|
||||
);
|
||||
assert(
|
||||
!newConfig.includes('alias: gemini-3.9-flash-preview'),
|
||||
'Should remove stale generated Flash preview alias noise'
|
||||
);
|
||||
assert(
|
||||
!newConfig.includes('alias: gemini-3.9-flash-preview-customtools'),
|
||||
'Should remove stale generated Flash customtools alias noise'
|
||||
);
|
||||
assert(
|
||||
!newConfig.includes('alias: gemini-3-9-flash-preview'),
|
||||
'Should remove stale generated hyphenated Flash alias noise'
|
||||
);
|
||||
assert(
|
||||
!newConfig.includes('alias: gemini-3-9-flash-preview-customtools'),
|
||||
'Should remove stale generated Flash preview alias noise'
|
||||
);
|
||||
assert(newConfig.includes('alias: keep-me'), 'Should preserve true custom aliases');
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3-pro-preview'),
|
||||
'Should still keep current baseline Pro preview alias'
|
||||
);
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3.1-flash-preview-customtools'),
|
||||
'Should still keep current baseline Flash compatibility alias'
|
||||
fs.readFileSync(backupPath, 'utf-8').includes('gemini-3.5-pro-preview'),
|
||||
'Should preserve the pruned legacy alias in the migration backup'
|
||||
);
|
||||
});
|
||||
|
||||
@@ -882,6 +1065,86 @@ oauth-model-alias:
|
||||
}
|
||||
});
|
||||
|
||||
it('preserves manual Gemini preview compatibility clusters on built-in alias names', () => {
|
||||
const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy');
|
||||
fs.mkdirSync(cliproxyDir, { recursive: true });
|
||||
|
||||
const initialConfig = `# CLIProxyAPI config generated by CCS v12
|
||||
port: 8317
|
||||
api-keys:
|
||||
- "ccs-internal-managed"
|
||||
auth-dir: "${cliproxyDir.replace(/\\/g, '/')}/auth"
|
||||
oauth-model-alias:
|
||||
antigravity:
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3.2-pro-preview
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3.2-pro-preview-customtools
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3-2-pro-preview
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3-2-pro-preview-customtools
|
||||
`;
|
||||
fs.writeFileSync(path.join(cliproxyDir, 'config.yaml'), initialConfig);
|
||||
|
||||
regenerateConfig();
|
||||
|
||||
const newConfig = fs.readFileSync(path.join(cliproxyDir, 'config.yaml'), 'utf-8');
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3.2-pro-preview'),
|
||||
'Should preserve manual dotted Pro preview override'
|
||||
);
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3.2-pro-preview-customtools'),
|
||||
'Should preserve manual dotted Pro customtools override'
|
||||
);
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3-2-pro-preview'),
|
||||
'Should preserve manual hyphenated Pro preview override'
|
||||
);
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3-2-pro-preview-customtools'),
|
||||
'Should preserve manual hyphenated Pro customtools override'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not re-prune multi-version manual clusters once the config is already migrated', () => {
|
||||
const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy');
|
||||
fs.mkdirSync(cliproxyDir, { recursive: true });
|
||||
|
||||
const initialConfig = `# CLIProxyAPI config generated by CCS v16
|
||||
port: 8317
|
||||
api-keys:
|
||||
- "ccs-internal-managed"
|
||||
auth-dir: "${cliproxyDir.replace(/\\/g, '/')}/auth"
|
||||
oauth-model-alias:
|
||||
antigravity:
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3.2-pro-preview
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3.3-pro-preview
|
||||
- name: gemini-3-pro-high
|
||||
alias: gemini-3.4-pro-preview
|
||||
`;
|
||||
fs.writeFileSync(path.join(cliproxyDir, 'config.yaml'), initialConfig);
|
||||
|
||||
regenerateConfig();
|
||||
|
||||
const newConfig = fs.readFileSync(path.join(cliproxyDir, 'config.yaml'), 'utf-8');
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3.2-pro-preview'),
|
||||
'Should preserve manual aliases after legacy migration has already run'
|
||||
);
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3.3-pro-preview'),
|
||||
'Should not re-prune later manual version clusters on v16+ configs'
|
||||
);
|
||||
assert(
|
||||
newConfig.includes('alias: gemini-3.4-pro-preview'),
|
||||
'Should leave already-migrated multi-version manual aliases untouched'
|
||||
);
|
||||
});
|
||||
|
||||
it('preserves user-added aliases with fork during regeneration', () => {
|
||||
const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy');
|
||||
fs.mkdirSync(cliproxyDir, { recursive: true });
|
||||
|
||||
Reference in new issue
Block a user