From 6707b7d5b470375c3068950894fb7b96b8fa4bf4 Mon Sep 17 00:00:00 2001 From: Tam Nhu Tran Date: Sun, 29 Mar 2026 14:13:23 -0400 Subject: [PATCH] fix(cliproxy): preserve manual high-minor alias clusters --- src/cliproxy/config/generator.ts | 14 ++++--- tests/unit/cliproxy/config-generator.test.js | 39 +++++++++++++++++++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/cliproxy/config/generator.ts b/src/cliproxy/config/generator.ts index 1dfdd46e..fc79958e 100644 --- a/src/cliproxy/config/generator.ts +++ b/src/cliproxy/config/generator.ts @@ -82,6 +82,7 @@ const BUILT_IN_GEMINI_ALIAS_NAMES = new Set( ) ); const MIN_STALE_GUESSED_GEMINI_MINOR_VERSIONS = 2; +const MIN_STALE_HIGH_ONLY_GEMINI_MINOR_VERSIONS = 3; const MIN_STALE_GUESSED_GEMINI_AVERAGE_VARIANTS_PER_MINOR = 2; const LEGACY_GEMINI_STALE_ALIAS_MIGRATION_VERSION = 16; const MAX_LEGACY_MANUAL_GEMINI_MINOR_VERSION = 2; @@ -399,7 +400,14 @@ function buildLegacyGeneratedGeminiAliasPruneSet( const totalAliasCount = sortedMinorVersions.reduce((total, minorVersion) => { return total + (aliasKeysByMinor.get(minorVersion)?.length ?? 0); }, 0); - if (sortedMinorVersions.length < MIN_STALE_GUESSED_GEMINI_MINOR_VERSIONS) { + const preservedMinorVersion = + Number(sortedMinorVersions[0]) <= MAX_LEGACY_MANUAL_GEMINI_MINOR_VERSION + ? sortedMinorVersions[0] + : null; + const minimumMinorVersionsToPrune = preservedMinorVersion + ? MIN_STALE_GUESSED_GEMINI_MINOR_VERSIONS + : MIN_STALE_HIGH_ONLY_GEMINI_MINOR_VERSIONS; + if (sortedMinorVersions.length < minimumMinorVersionsToPrune) { continue; } if ( @@ -409,10 +417,6 @@ function buildLegacyGeneratedGeminiAliasPruneSet( continue; } - const preservedMinorVersion = - Number(sortedMinorVersions[0]) <= MAX_LEGACY_MANUAL_GEMINI_MINOR_VERSION - ? sortedMinorVersions[0] - : null; for (const minorVersion of sortedMinorVersions) { if (minorVersion === preservedMinorVersion) { continue; diff --git a/tests/unit/cliproxy/config-generator.test.js b/tests/unit/cliproxy/config-generator.test.js index cbf16e2b..0e55d717 100644 --- a/tests/unit/cliproxy/config-generator.test.js +++ b/tests/unit/cliproxy/config-generator.test.js @@ -913,10 +913,10 @@ ${staleRange} } }); - it('prunes partially retained guessed ranges during legacy cleanup', () => { + it('prunes partially retained broad guessed ranges during legacy cleanup', () => { const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy'); fs.mkdirSync(cliproxyDir, { recursive: true }); - const guessedMinors = ['3', '4']; + const guessedMinors = ['3', '4', '5']; const partialRange = guessedMinors .flatMap((minor) => [ ` - name: gemini-3-pro-high`, @@ -948,6 +948,41 @@ ${partialRange} } }); + it('preserves manual high-only multi-version clusters that are not broad guessed ranges', () => { + 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.3-pro-preview + - name: gemini-3-pro-high + alias: gemini-3.3-pro-preview-customtools + - name: gemini-3-pro-high + alias: gemini-3.4-pro-preview + - name: gemini-3-pro-high + alias: gemini-3.4-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.3-pro-preview'), + 'Should preserve manual 3.3 aliases when the cluster is not broad enough to infer stale fan-out' + ); + assert( + newConfig.includes('alias: gemini-3.4-pro-preview-customtools'), + 'Should preserve manual 3.4 compatibility aliases when provenance is ambiguous' + ); + }); + 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 });