mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 10:16:49 +00:00
fix(agy): normalize sonnet 4.6 model ids and migrate legacy thinking alias
This commit is contained in:
@@ -60,7 +60,11 @@ function stripCodexEffortSuffix(modelId: string): string {
|
|||||||
*
|
*
|
||||||
* Returns true if migration was performed and file was updated.
|
* Returns true if migration was performed and file was updated.
|
||||||
*/
|
*/
|
||||||
function migrateDeprecatedModelNames(settingsPath: string, settings: ProviderSettings): boolean {
|
function migrateDeprecatedModelNames(
|
||||||
|
settingsPath: string,
|
||||||
|
provider: CLIProxyProvider,
|
||||||
|
settings: ProviderSettings
|
||||||
|
): boolean {
|
||||||
if (!settings.env || typeof settings.env !== 'object') return false;
|
if (!settings.env || typeof settings.env !== 'object') return false;
|
||||||
|
|
||||||
let migrated = false;
|
let migrated = false;
|
||||||
@@ -68,13 +72,36 @@ function migrateDeprecatedModelNames(settingsPath: string, settings: ProviderSet
|
|||||||
const value = settings.env[key];
|
const value = settings.env[key];
|
||||||
if (typeof value !== 'string') continue;
|
if (typeof value !== 'string') continue;
|
||||||
|
|
||||||
// Check if the base model name (before any suffixes) uses the deprecated prefix
|
let canonical = value;
|
||||||
if (value.toLowerCase().startsWith(DEPRECATED_MODEL_PREFIX)) {
|
// Check if the base model name (before any suffixes) uses the deprecated prefix.
|
||||||
settings.env[key] = UPSTREAM_MODEL_PREFIX + value.slice(DEPRECATED_MODEL_PREFIX.length);
|
if (canonical.toLowerCase().startsWith(DEPRECATED_MODEL_PREFIX)) {
|
||||||
|
canonical = UPSTREAM_MODEL_PREFIX + canonical.slice(DEPRECATED_MODEL_PREFIX.length);
|
||||||
|
}
|
||||||
|
canonical = normalizeModelIdForProvider(canonical, provider);
|
||||||
|
|
||||||
|
if (canonical !== value) {
|
||||||
|
settings.env[key] = canonical;
|
||||||
migrated = true;
|
migrated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (provider === 'agy' && Array.isArray(settings.presets)) {
|
||||||
|
for (const preset of settings.presets) {
|
||||||
|
if (!preset || typeof preset !== 'object') continue;
|
||||||
|
const presetRecord = preset as Record<string, unknown>;
|
||||||
|
|
||||||
|
for (const key of PRESET_MODEL_KEYS) {
|
||||||
|
const value = presetRecord[key];
|
||||||
|
if (typeof value !== 'string') continue;
|
||||||
|
const canonical = normalizeModelIdForProvider(value, provider);
|
||||||
|
if (canonical !== value) {
|
||||||
|
presetRecord[key] = canonical;
|
||||||
|
migrated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (migrated) {
|
if (migrated) {
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', { mode: 0o600 });
|
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', { mode: 0o600 });
|
||||||
@@ -409,7 +436,7 @@ export function getEffectiveEnvVars(
|
|||||||
|
|
||||||
if (settings.env && typeof settings.env === 'object') {
|
if (settings.env && typeof settings.env === 'object') {
|
||||||
// Migrate deprecated gemini-claude-* model names if present
|
// Migrate deprecated gemini-claude-* model names if present
|
||||||
migrateDeprecatedModelNames(expandedPath, settings);
|
migrateDeprecatedModelNames(expandedPath, provider, settings);
|
||||||
// Migrate codex effort suffixes to canonical IDs if present
|
// Migrate codex effort suffixes to canonical IDs if present
|
||||||
migrateCodexEffortSuffixes(expandedPath, provider, settings);
|
migrateCodexEffortSuffixes(expandedPath, provider, settings);
|
||||||
// Migrate legacy iFlow placeholders to supported model IDs
|
// Migrate legacy iFlow placeholders to supported model IDs
|
||||||
@@ -444,7 +471,7 @@ export function getEffectiveEnvVars(
|
|||||||
|
|
||||||
if (settings.env && typeof settings.env === 'object') {
|
if (settings.env && typeof settings.env === 'object') {
|
||||||
// Migrate deprecated gemini-claude-* model names if present
|
// Migrate deprecated gemini-claude-* model names if present
|
||||||
migrateDeprecatedModelNames(settingsPath, settings);
|
migrateDeprecatedModelNames(settingsPath, provider, settings);
|
||||||
// Migrate codex effort suffixes to canonical IDs if present
|
// Migrate codex effort suffixes to canonical IDs if present
|
||||||
migrateCodexEffortSuffixes(settingsPath, provider, settings);
|
migrateCodexEffortSuffixes(settingsPath, provider, settings);
|
||||||
// Migrate legacy iFlow placeholders to supported model IDs
|
// Migrate legacy iFlow placeholders to supported model IDs
|
||||||
@@ -584,7 +611,7 @@ export function getRemoteEnvVars(
|
|||||||
const content = fs.readFileSync(expandedPath, 'utf-8');
|
const content = fs.readFileSync(expandedPath, 'utf-8');
|
||||||
const settings: ProviderSettings = JSON.parse(content);
|
const settings: ProviderSettings = JSON.parse(content);
|
||||||
if (settings.env && typeof settings.env === 'object') {
|
if (settings.env && typeof settings.env === 'object') {
|
||||||
migrateDeprecatedModelNames(expandedPath, settings);
|
migrateDeprecatedModelNames(expandedPath, provider, settings);
|
||||||
migrateCodexEffortSuffixes(expandedPath, provider, settings);
|
migrateCodexEffortSuffixes(expandedPath, provider, settings);
|
||||||
migrateIFlowPlaceholderModel(expandedPath, provider, settings);
|
migrateIFlowPlaceholderModel(expandedPath, provider, settings);
|
||||||
userEnvVars = settings.env as Record<string, string>;
|
userEnvVars = settings.env as Record<string, string>;
|
||||||
@@ -604,7 +631,7 @@ export function getRemoteEnvVars(
|
|||||||
const content = fs.readFileSync(settingsPath, 'utf-8');
|
const content = fs.readFileSync(settingsPath, 'utf-8');
|
||||||
const settings: ProviderSettings = JSON.parse(content);
|
const settings: ProviderSettings = JSON.parse(content);
|
||||||
if (settings.env && typeof settings.env === 'object') {
|
if (settings.env && typeof settings.env === 'object') {
|
||||||
migrateDeprecatedModelNames(settingsPath, settings);
|
migrateDeprecatedModelNames(settingsPath, provider, settings);
|
||||||
migrateCodexEffortSuffixes(settingsPath, provider, settings);
|
migrateCodexEffortSuffixes(settingsPath, provider, settings);
|
||||||
migrateIFlowPlaceholderModel(settingsPath, provider, settings);
|
migrateIFlowPlaceholderModel(settingsPath, provider, settings);
|
||||||
userEnvVars = settings.env as Record<string, string>;
|
userEnvVars = settings.env as Record<string, string>;
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ export const CCS_CONTROL_PANEL_SECRET = 'ccs';
|
|||||||
* v8: Added Gemini 3.1 preview aliases for provider routing compatibility
|
* v8: Added Gemini 3.1 preview aliases for provider routing compatibility
|
||||||
* v9: Added resilient alias compatibility expansion and cache-assisted alias enrichment
|
* v9: Added resilient alias compatibility expansion and cache-assisted alias enrichment
|
||||||
* v10: Migrated deprecated gemini-claude-* aliases to upstream claude-* aliases
|
* v10: Migrated deprecated gemini-claude-* aliases to upstream claude-* aliases
|
||||||
|
* v11: Migrated deprecated claude-sonnet-4-6-thinking aliases to claude-sonnet-4-6
|
||||||
*/
|
*/
|
||||||
export const CLIPROXY_CONFIG_VERSION = 10;
|
export const CLIPROXY_CONFIG_VERSION = 11;
|
||||||
|
|
||||||
interface OAuthModelAliasEntry {
|
interface OAuthModelAliasEntry {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -44,6 +45,8 @@ interface OAuthModelAliasEntry {
|
|||||||
const GEMINI_MINOR_COMPAT_RANGE = [1, 2, 3, 4, 5, 6, 7, 8, 9] as const;
|
const GEMINI_MINOR_COMPAT_RANGE = [1, 2, 3, 4, 5, 6, 7, 8, 9] as const;
|
||||||
const DEPRECATED_ANTIGRAVITY_ALIAS_PREFIX = 'gemini-claude-';
|
const DEPRECATED_ANTIGRAVITY_ALIAS_PREFIX = 'gemini-claude-';
|
||||||
const UPSTREAM_CLAUDE_ALIAS_PREFIX = 'claude-';
|
const UPSTREAM_CLAUDE_ALIAS_PREFIX = 'claude-';
|
||||||
|
const DEPRECATED_ANTIGRAVITY_SONNET_46_THINKING_ALIAS = 'claude-sonnet-4-6-thinking';
|
||||||
|
const CANONICAL_ANTIGRAVITY_SONNET_46_ALIAS = 'claude-sonnet-4-6';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Antigravity oauth-model-alias entries.
|
* Default Antigravity oauth-model-alias entries.
|
||||||
@@ -58,7 +61,8 @@ const DEFAULT_ANTIGRAVITY_ALIASES: OAuthModelAliasEntry[] = [
|
|||||||
{ name: 'gemini-3-pro-high', alias: 'gemini-3.1-pro-preview-customtools' },
|
{ name: 'gemini-3-pro-high', alias: 'gemini-3.1-pro-preview-customtools' },
|
||||||
{ name: 'gemini-3-flash', alias: 'gemini-3-flash-preview' },
|
{ name: 'gemini-3-flash', alias: 'gemini-3-flash-preview' },
|
||||||
{ name: 'claude-sonnet-4-6', alias: 'claude-sonnet-4-6', 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 },
|
// Backward compatibility: legacy sonnet thinking alias now routes to canonical model ID.
|
||||||
|
{ name: 'claude-sonnet-4-6-thinking', alias: 'claude-sonnet-4-6', fork: true },
|
||||||
{ name: 'claude-sonnet-4-5', alias: 'claude-sonnet-4-5', 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-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-5-thinking', alias: 'claude-opus-4-5-thinking', fork: true },
|
||||||
@@ -107,10 +111,15 @@ function sanitizeYamlScalar(rawValue: string): string {
|
|||||||
function normalizeAntigravityAlias(rawAlias: string): string {
|
function normalizeAntigravityAlias(rawAlias: string): string {
|
||||||
const normalized = sanitizeYamlScalar(rawAlias);
|
const normalized = sanitizeYamlScalar(rawAlias);
|
||||||
if (normalized.toLowerCase().startsWith(DEPRECATED_ANTIGRAVITY_ALIAS_PREFIX)) {
|
if (normalized.toLowerCase().startsWith(DEPRECATED_ANTIGRAVITY_ALIAS_PREFIX)) {
|
||||||
return (
|
const migratedPrefix =
|
||||||
UPSTREAM_CLAUDE_ALIAS_PREFIX + normalized.slice(DEPRECATED_ANTIGRAVITY_ALIAS_PREFIX.length)
|
UPSTREAM_CLAUDE_ALIAS_PREFIX + normalized.slice(DEPRECATED_ANTIGRAVITY_ALIAS_PREFIX.length);
|
||||||
);
|
return normalizeAntigravityAlias(migratedPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (normalized.toLowerCase() === DEPRECATED_ANTIGRAVITY_SONNET_46_THINKING_ALIAS) {
|
||||||
|
return CANONICAL_ANTIGRAVITY_SONNET_46_ALIAS;
|
||||||
|
}
|
||||||
|
|
||||||
return normalized;
|
return normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,23 +104,17 @@ export const MODEL_CATALOG: Partial<Record<CLIProxyProvider, ProviderCatalog>> =
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'claude-sonnet-4-6-thinking',
|
id: 'claude-sonnet-4-6',
|
||||||
name: 'Claude Sonnet 4.6 Thinking',
|
name: 'Claude Sonnet 4.6',
|
||||||
description: 'Latest Sonnet with extended thinking',
|
description: 'Latest Sonnet with thinking budget support',
|
||||||
thinking: {
|
thinking: {
|
||||||
type: 'budget',
|
type: 'budget',
|
||||||
min: 1024,
|
min: 1024,
|
||||||
max: 128000,
|
max: 64000,
|
||||||
zeroAllowed: true,
|
zeroAllowed: true,
|
||||||
dynamicAllowed: true,
|
dynamicAllowed: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'claude-sonnet-4-6',
|
|
||||||
name: 'Claude Sonnet 4.6',
|
|
||||||
description: 'Latest Sonnet baseline',
|
|
||||||
thinking: { type: 'none' },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'claude-sonnet-4-5-thinking',
|
id: 'claude-sonnet-4-5-thinking',
|
||||||
name: 'Claude Sonnet 4.5 Thinking',
|
name: 'Claude Sonnet 4.5 Thinking',
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ type ProviderLike = CLIProxyProvider | string | null | undefined;
|
|||||||
const CLAUDE_DOTTED_VERSION_REGEX = /claude-(sonnet|opus|haiku)-(\d+)\.(\d+)(?=(?:$|-|\[|\(|\/))/gi;
|
const CLAUDE_DOTTED_VERSION_REGEX = /claude-(sonnet|opus|haiku)-(\d+)\.(\d+)(?=(?:$|-|\[|\(|\/))/gi;
|
||||||
const CLAUDE_DOTTED_THINKING_REGEX =
|
const CLAUDE_DOTTED_THINKING_REGEX =
|
||||||
/claude-(sonnet|opus|haiku)-(\d+)\.(\d+)-thinking(?=(?:$|-|\[|\(|\/))/gi;
|
/claude-(sonnet|opus|haiku)-(\d+)\.(\d+)-thinking(?=(?:$|-|\[|\(|\/))/gi;
|
||||||
|
const DEPRECATED_ANTIGRAVITY_SONNET_46_THINKING_REGEX =
|
||||||
|
/claude-sonnet-4(?:[.-])6-thinking(?=(?:$|-|\[|\(|\/))/gi;
|
||||||
|
const CANONICAL_ANTIGRAVITY_SONNET_46_MODEL = 'claude-sonnet-4-6';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract provider segment from `/api/provider/{provider}` request paths.
|
* Extract provider segment from `/api/provider/{provider}` request paths.
|
||||||
@@ -62,6 +65,17 @@ export function normalizeClaudeDottedThinkingMajorMinor(model: string): string {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Antigravity no longer exposes `claude-sonnet-4-6-thinking`.
|
||||||
|
* Canonicalize legacy aliases to `claude-sonnet-4-6` while preserving suffixes.
|
||||||
|
*/
|
||||||
|
export function normalizeDeprecatedAntigravityModelAliases(model: string): string {
|
||||||
|
return model.replace(
|
||||||
|
DEPRECATED_ANTIGRAVITY_SONNET_46_THINKING_REGEX,
|
||||||
|
CANONICAL_ANTIGRAVITY_SONNET_46_MODEL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize model ID for a specific provider.
|
* Normalize model ID for a specific provider.
|
||||||
* Antigravity requires hyphenated Claude major.minor model IDs.
|
* Antigravity requires hyphenated Claude major.minor model IDs.
|
||||||
@@ -76,7 +90,8 @@ export function normalizeClaudeDottedThinkingMajorMinor(model: string): string {
|
|||||||
*/
|
*/
|
||||||
export function normalizeModelIdForProvider(model: string, provider: ProviderLike): string {
|
export function normalizeModelIdForProvider(model: string, provider: ProviderLike): string {
|
||||||
if (!isAntigravityProvider(provider)) return model;
|
if (!isAntigravityProvider(provider)) return model;
|
||||||
return normalizeClaudeDottedMajorMinor(model);
|
const normalizedDottedVersion = normalizeClaudeDottedMajorMinor(model);
|
||||||
|
return normalizeDeprecatedAntigravityModelAliases(normalizedDottedVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,7 +102,7 @@ export function normalizeModelIdForProvider(model: string, provider: ProviderLik
|
|||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* normalizeModelIdForRouting('claude-sonnet-4.6-thinking', null)
|
* normalizeModelIdForRouting('claude-sonnet-4.6-thinking', null)
|
||||||
* // => 'claude-sonnet-4-6-thinking'
|
* // => 'claude-sonnet-4-6'
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* normalizeModelIdForRouting('claude-sonnet-4.6', null)
|
* normalizeModelIdForRouting('claude-sonnet-4.6', null)
|
||||||
@@ -95,9 +110,10 @@ export function normalizeModelIdForProvider(model: string, provider: ProviderLik
|
|||||||
*/
|
*/
|
||||||
export function normalizeModelIdForRouting(model: string, provider: ProviderLike): string {
|
export function normalizeModelIdForRouting(model: string, provider: ProviderLike): string {
|
||||||
if (isAntigravityProvider(provider)) {
|
if (isAntigravityProvider(provider)) {
|
||||||
return normalizeClaudeDottedMajorMinor(model);
|
return normalizeModelIdForProvider(model, provider);
|
||||||
}
|
}
|
||||||
return normalizeClaudeDottedThinkingMajorMinor(model);
|
const normalizedThinking = normalizeClaudeDottedThinkingMajorMinor(model);
|
||||||
|
return normalizeDeprecatedAntigravityModelAliases(normalizedThinking);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -109,7 +125,7 @@ export function normalizeModelIdForRouting(model: string, provider: ProviderLike
|
|||||||
* { ANTHROPIC_MODEL: 'claude-sonnet-4.6-thinking' },
|
* { ANTHROPIC_MODEL: 'claude-sonnet-4.6-thinking' },
|
||||||
* 'agy'
|
* 'agy'
|
||||||
* )
|
* )
|
||||||
* // => { ANTHROPIC_MODEL: 'claude-sonnet-4-6-thinking' }
|
* // => { ANTHROPIC_MODEL: 'claude-sonnet-4-6' }
|
||||||
*/
|
*/
|
||||||
export function normalizeModelEnvVarsForProvider(
|
export function normalizeModelEnvVarsForProvider(
|
||||||
envVars: NodeJS.ProcessEnv,
|
envVars: NodeJS.ProcessEnv,
|
||||||
|
|||||||
@@ -792,8 +792,8 @@ oauth-model-alias:
|
|||||||
|
|
||||||
const newConfig = fs.readFileSync(path.join(cliproxyDir, 'config.yaml'), 'utf-8');
|
const newConfig = fs.readFileSync(path.join(cliproxyDir, 'config.yaml'), 'utf-8');
|
||||||
assert(
|
assert(
|
||||||
newConfig.includes('alias: claude-sonnet-4-6-thinking'),
|
newConfig.includes('alias: claude-sonnet-4-6'),
|
||||||
'Should include normalized upstream Claude alias'
|
'Should migrate deprecated sonnet thinking alias to canonical model ID'
|
||||||
);
|
);
|
||||||
assert(
|
assert(
|
||||||
!newConfig.includes('alias: gemini-claude-sonnet-4-6-thinking'),
|
!newConfig.includes('alias: gemini-claude-sonnet-4-6-thinking'),
|
||||||
|
|||||||
@@ -105,10 +105,17 @@ describe('getEffectiveEnvVars local provider URL normalization', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const env = getEffectiveEnvVars('agy', 8317, settingsPath);
|
const env = getEffectiveEnvVars('agy', 8317, settingsPath);
|
||||||
expect(env.ANTHROPIC_MODEL).toBe('claude-sonnet-4-6-thinking');
|
expect(env.ANTHROPIC_MODEL).toBe('claude-sonnet-4-6');
|
||||||
expect(env.ANTHROPIC_DEFAULT_OPUS_MODEL).toBe('claude-opus-4-6-thinking');
|
expect(env.ANTHROPIC_DEFAULT_OPUS_MODEL).toBe('claude-opus-4-6-thinking');
|
||||||
expect(env.ANTHROPIC_DEFAULT_SONNET_MODEL).toBe('claude-sonnet-4-6-thinking');
|
expect(env.ANTHROPIC_DEFAULT_SONNET_MODEL).toBe('claude-sonnet-4-6');
|
||||||
expect(env.ANTHROPIC_DEFAULT_HAIKU_MODEL).toBe('claude-haiku-4-5');
|
expect(env.ANTHROPIC_DEFAULT_HAIKU_MODEL).toBe('claude-haiku-4-5');
|
||||||
|
|
||||||
|
const persisted = JSON.parse(fs.readFileSync(settingsPath, 'utf-8')) as {
|
||||||
|
env: Record<string, string>;
|
||||||
|
};
|
||||||
|
expect(persisted.env.ANTHROPIC_MODEL).toBe('claude-sonnet-4-6');
|
||||||
|
expect(persisted.env.ANTHROPIC_DEFAULT_OPUS_MODEL).toBe('claude-opus-4-6-thinking');
|
||||||
|
expect(persisted.env.ANTHROPIC_DEFAULT_SONNET_MODEL).toBe('claude-sonnet-4-6');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('migrates codex preset model mappings to canonical IDs', () => {
|
it('migrates codex preset model mappings to canonical IDs', () => {
|
||||||
|
|||||||
@@ -85,15 +85,6 @@ describe('Model Catalog', () => {
|
|||||||
assert.strictEqual(sonnetThinking.name, 'Claude Sonnet 4.5 Thinking');
|
assert.strictEqual(sonnetThinking.name, 'Claude Sonnet 4.5 Thinking');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('includes Claude Sonnet 4.6 Thinking', () => {
|
|
||||||
const { MODEL_CATALOG } = modelCatalog;
|
|
||||||
const sonnetThinking = MODEL_CATALOG.agy.models.find(
|
|
||||||
(m) => m.id === 'claude-sonnet-4-6-thinking'
|
|
||||||
);
|
|
||||||
assert(sonnetThinking, 'Should include Claude Sonnet 4.6 Thinking');
|
|
||||||
assert.strictEqual(sonnetThinking.name, 'Claude Sonnet 4.6 Thinking');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('includes Claude Sonnet 4.6', () => {
|
it('includes Claude Sonnet 4.6', () => {
|
||||||
const { MODEL_CATALOG } = modelCatalog;
|
const { MODEL_CATALOG } = modelCatalog;
|
||||||
const sonnet = MODEL_CATALOG.agy.models.find((m) => m.id === 'claude-sonnet-4-6');
|
const sonnet = MODEL_CATALOG.agy.models.find((m) => m.id === 'claude-sonnet-4-6');
|
||||||
@@ -117,9 +108,9 @@ describe('Model Catalog', () => {
|
|||||||
assert.strictEqual(gem3.tier, undefined, 'AGY models should not have paid tier');
|
assert.strictEqual(gem3.tier, undefined, 'AGY models should not have paid tier');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has 7 models total', () => {
|
it('has 6 models total', () => {
|
||||||
const { MODEL_CATALOG } = modelCatalog;
|
const { MODEL_CATALOG } = modelCatalog;
|
||||||
assert.strictEqual(MODEL_CATALOG.agy.models.length, 7);
|
assert.strictEqual(MODEL_CATALOG.agy.models.length, 6);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -44,13 +44,16 @@ describe('model-id-normalizer', () => {
|
|||||||
|
|
||||||
it('applies provider-aware routing normalization', () => {
|
it('applies provider-aware routing normalization', () => {
|
||||||
expect(normalizeModelIdForRouting('claude-sonnet-4.6-thinking', null)).toBe(
|
expect(normalizeModelIdForRouting('claude-sonnet-4.6-thinking', null)).toBe(
|
||||||
'claude-sonnet-4-6-thinking'
|
'claude-sonnet-4-6'
|
||||||
);
|
);
|
||||||
expect(normalizeModelIdForRouting('claude-sonnet-4.6', null)).toBe('claude-sonnet-4.6');
|
expect(normalizeModelIdForRouting('claude-sonnet-4.6', null)).toBe('claude-sonnet-4.6');
|
||||||
expect(normalizeModelIdForRouting('claude-sonnet-4.6', 'agy')).toBe('claude-sonnet-4-6');
|
expect(normalizeModelIdForRouting('claude-sonnet-4.6', 'agy')).toBe('claude-sonnet-4-6');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('applies provider-only normalization for antigravity', () => {
|
it('applies provider-only normalization for antigravity', () => {
|
||||||
|
expect(normalizeModelIdForProvider('claude-sonnet-4.6-thinking', 'agy')).toBe(
|
||||||
|
'claude-sonnet-4-6'
|
||||||
|
);
|
||||||
expect(normalizeModelIdForProvider('claude-opus-4.6-thinking', 'agy')).toBe(
|
expect(normalizeModelIdForProvider('claude-opus-4.6-thinking', 'agy')).toBe(
|
||||||
'claude-opus-4-6-thinking'
|
'claude-opus-4-6-thinking'
|
||||||
);
|
);
|
||||||
@@ -71,7 +74,7 @@ describe('model-id-normalizer', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const normalized = normalizeModelEnvVarsForProvider(input, 'agy');
|
const normalized = normalizeModelEnvVarsForProvider(input, 'agy');
|
||||||
expect(normalized.ANTHROPIC_MODEL).toBe('claude-sonnet-4-6-thinking');
|
expect(normalized.ANTHROPIC_MODEL).toBe('claude-sonnet-4-6');
|
||||||
expect(normalized.ANTHROPIC_DEFAULT_OPUS_MODEL).toBe('claude-opus-4-6-thinking');
|
expect(normalized.ANTHROPIC_DEFAULT_OPUS_MODEL).toBe('claude-opus-4-6-thinking');
|
||||||
expect(normalized.ANTHROPIC_DEFAULT_SONNET_MODEL).toBe('claude-sonnet-4-6');
|
expect(normalized.ANTHROPIC_DEFAULT_SONNET_MODEL).toBe('claude-sonnet-4-6');
|
||||||
expect(normalized.ANTHROPIC_DEFAULT_HAIKU_MODEL).toBe('claude-haiku-4-5');
|
expect(normalized.ANTHROPIC_DEFAULT_HAIKU_MODEL).toBe('claude-haiku-4-5');
|
||||||
|
|||||||
@@ -201,9 +201,7 @@ describe('ToolSanitizationProxy Integration', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(lastRequest).not.toBeNull();
|
expect(lastRequest).not.toBeNull();
|
||||||
expect((lastRequest!.body as Record<string, unknown>).model).toBe(
|
expect((lastRequest!.body as Record<string, unknown>).model).toBe('claude-sonnet-4-6');
|
||||||
'claude-sonnet-4-6-thinking'
|
|
||||||
);
|
|
||||||
} finally {
|
} finally {
|
||||||
proxy.stop();
|
proxy.stop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export const MODEL_CATALOGS: Record<string, ProviderCatalog> = {
|
|||||||
presetMapping: {
|
presetMapping: {
|
||||||
default: 'claude-opus-4-6-thinking',
|
default: 'claude-opus-4-6-thinking',
|
||||||
opus: 'claude-opus-4-6-thinking',
|
opus: 'claude-opus-4-6-thinking',
|
||||||
sonnet: 'claude-sonnet-4-6-thinking',
|
sonnet: 'claude-sonnet-4-6',
|
||||||
haiku: 'claude-sonnet-4-6',
|
haiku: 'claude-sonnet-4-6',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -33,25 +33,14 @@ export const MODEL_CATALOGS: Record<string, ProviderCatalog> = {
|
|||||||
presetMapping: {
|
presetMapping: {
|
||||||
default: 'claude-opus-4-5-thinking',
|
default: 'claude-opus-4-5-thinking',
|
||||||
opus: 'claude-opus-4-5-thinking',
|
opus: 'claude-opus-4-5-thinking',
|
||||||
sonnet: 'claude-sonnet-4-6-thinking',
|
sonnet: 'claude-sonnet-4-6',
|
||||||
haiku: 'claude-sonnet-4-6',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'claude-sonnet-4-6-thinking',
|
|
||||||
name: 'Claude Sonnet 4.6 Thinking',
|
|
||||||
description: 'Latest Sonnet with extended thinking',
|
|
||||||
presetMapping: {
|
|
||||||
default: 'claude-sonnet-4-6-thinking',
|
|
||||||
opus: 'claude-opus-4-6-thinking',
|
|
||||||
sonnet: 'claude-sonnet-4-6-thinking',
|
|
||||||
haiku: 'claude-sonnet-4-6',
|
haiku: 'claude-sonnet-4-6',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'claude-sonnet-4-6',
|
id: 'claude-sonnet-4-6',
|
||||||
name: 'Claude Sonnet 4.6',
|
name: 'Claude Sonnet 4.6',
|
||||||
description: 'Latest Sonnet baseline',
|
description: 'Latest Sonnet with thinking budget support',
|
||||||
presetMapping: {
|
presetMapping: {
|
||||||
default: 'claude-sonnet-4-6',
|
default: 'claude-sonnet-4-6',
|
||||||
opus: 'claude-opus-4-6-thinking',
|
opus: 'claude-opus-4-6-thinking',
|
||||||
|
|||||||
Reference in New Issue
Block a user