mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 04:18:05 +00:00
fix(cliproxy): normalize deprecated antigravity Claude aliases
This commit is contained in:
@@ -31,8 +31,9 @@ export const CCS_CONTROL_PANEL_SECRET = 'ccs';
|
||||
* v7: Added fork:true for Claude model aliases (keep both upstream and alias names)
|
||||
* v8: Added Gemini 3.1 preview aliases for provider routing compatibility
|
||||
* v9: Added resilient alias compatibility expansion and cache-assisted alias enrichment
|
||||
* v10: Migrated deprecated gemini-claude-* aliases to upstream claude-* aliases
|
||||
*/
|
||||
export const CLIPROXY_CONFIG_VERSION = 9;
|
||||
export const CLIPROXY_CONFIG_VERSION = 10;
|
||||
|
||||
interface OAuthModelAliasEntry {
|
||||
name: string;
|
||||
@@ -41,6 +42,8 @@ interface OAuthModelAliasEntry {
|
||||
}
|
||||
|
||||
const GEMINI_MINOR_COMPAT_RANGE = [1, 2, 3, 4, 5, 6, 7, 8, 9] as const;
|
||||
const DEPRECATED_ANTIGRAVITY_ALIAS_PREFIX = 'gemini-claude-';
|
||||
const UPSTREAM_CLAUDE_ALIAS_PREFIX = 'claude-';
|
||||
|
||||
/**
|
||||
* Default Antigravity oauth-model-alias entries.
|
||||
@@ -54,12 +57,12 @@ const DEFAULT_ANTIGRAVITY_ALIASES: OAuthModelAliasEntry[] = [
|
||||
{ name: 'gemini-3-pro-high', alias: 'gemini-3.1-pro-preview' },
|
||||
{ name: 'gemini-3-pro-high', alias: 'gemini-3.1-pro-preview-customtools' },
|
||||
{ name: 'gemini-3-flash', alias: 'gemini-3-flash-preview' },
|
||||
{ name: 'claude-sonnet-4-6', alias: 'gemini-claude-sonnet-4-6', fork: true },
|
||||
{ name: 'claude-sonnet-4-6-thinking', alias: 'gemini-claude-sonnet-4-6-thinking', fork: true },
|
||||
{ name: 'claude-sonnet-4-5', alias: 'gemini-claude-sonnet-4-5', fork: true },
|
||||
{ name: 'claude-sonnet-4-5-thinking', alias: 'gemini-claude-sonnet-4-5-thinking', fork: true },
|
||||
{ name: 'claude-opus-4-5-thinking', alias: 'gemini-claude-opus-4-5-thinking', fork: true },
|
||||
{ name: 'claude-opus-4-6-thinking', alias: 'gemini-claude-opus-4-6-thinking', fork: true },
|
||||
{ name: 'claude-sonnet-4-6', alias: 'claude-sonnet-4-6', fork: true },
|
||||
{ name: 'claude-sonnet-4-6-thinking', alias: 'claude-sonnet-4-6-thinking', fork: true },
|
||||
{ name: 'claude-sonnet-4-5', alias: 'claude-sonnet-4-5', fork: true },
|
||||
{ name: 'claude-sonnet-4-5-thinking', alias: 'claude-sonnet-4-5-thinking', fork: true },
|
||||
{ name: 'claude-opus-4-5-thinking', alias: 'claude-opus-4-5-thinking', fork: true },
|
||||
{ name: 'claude-opus-4-6-thinking', alias: 'claude-opus-4-6-thinking', fork: true },
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -101,6 +104,16 @@ function sanitizeYamlScalar(rawValue: string): string {
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
function normalizeAntigravityAlias(rawAlias: string): string {
|
||||
const normalized = sanitizeYamlScalar(rawAlias);
|
||||
if (normalized.toLowerCase().startsWith(DEPRECATED_ANTIGRAVITY_ALIAS_PREFIX)) {
|
||||
return (
|
||||
UPSTREAM_CLAUDE_ALIAS_PREFIX + normalized.slice(DEPRECATED_ANTIGRAVITY_ALIAS_PREFIX.length)
|
||||
);
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function addAliasEntry(
|
||||
entries: OAuthModelAliasEntry[],
|
||||
indexByKey: Map<string, number>,
|
||||
@@ -108,7 +121,7 @@ function addAliasEntry(
|
||||
): void {
|
||||
const normalized: OAuthModelAliasEntry = {
|
||||
name: sanitizeYamlScalar(entry.name),
|
||||
alias: sanitizeYamlScalar(entry.alias),
|
||||
alias: normalizeAntigravityAlias(entry.alias),
|
||||
fork: entry.fork || undefined,
|
||||
};
|
||||
if (!normalized.name || !normalized.alias) return;
|
||||
|
||||
@@ -587,11 +587,15 @@ auth-dir: "${cliproxyDir.replace(/\\/g, '/')}/auth"
|
||||
assert(config.includes('claude-sonnet-4-5'), 'Should include Claude sonnet model');
|
||||
assert(config.includes('claude-sonnet-4-6'), 'Should include Claude Sonnet 4.6 model');
|
||||
assert(config.includes('fork: true'), 'Should include fork: true for Claude aliases');
|
||||
assert(
|
||||
!config.includes('alias: gemini-claude-'),
|
||||
'Should not emit deprecated gemini-claude aliases'
|
||||
);
|
||||
|
||||
// Verify fork: true appears after each Claude alias entry
|
||||
const lines = config.split('\n');
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].includes('alias: gemini-claude-')) {
|
||||
if (lines[i].includes('alias: claude-')) {
|
||||
assert(
|
||||
lines[i + 1] && lines[i + 1].trim() === 'fork: true',
|
||||
`fork: true should follow Claude alias at line ${i}: ${lines[i]}`
|
||||
@@ -766,5 +770,35 @@ oauth-model-alias:
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('normalizes deprecated gemini-claude aliases during regeneration', () => {
|
||||
const cliproxyDir = path.join(testDir, '.ccs', 'cliproxy');
|
||||
fs.mkdirSync(cliproxyDir, { recursive: true });
|
||||
|
||||
const initialConfig = `# CLIProxyAPI config generated by CCS v9
|
||||
port: 8317
|
||||
api-keys:
|
||||
- "ccs-internal-managed"
|
||||
auth-dir: "${cliproxyDir.replace(/\\/g, '/')}/auth"
|
||||
oauth-model-alias:
|
||||
antigravity:
|
||||
- name: claude-sonnet-4-6-thinking
|
||||
alias: gemini-claude-sonnet-4-6-thinking
|
||||
fork: true
|
||||
`;
|
||||
fs.writeFileSync(path.join(cliproxyDir, 'config.yaml'), initialConfig);
|
||||
|
||||
regenerateConfig();
|
||||
|
||||
const newConfig = fs.readFileSync(path.join(cliproxyDir, 'config.yaml'), 'utf-8');
|
||||
assert(
|
||||
newConfig.includes('alias: claude-sonnet-4-6-thinking'),
|
||||
'Should include normalized upstream Claude alias'
|
||||
);
|
||||
assert(
|
||||
!newConfig.includes('alias: gemini-claude-sonnet-4-6-thinking'),
|
||||
'Should remove deprecated gemini-claude alias after regeneration'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user