diff --git a/src/cliproxy/model-catalog.ts b/src/cliproxy/model-catalog.ts index 3671eb6c..8a4e4564 100644 --- a/src/cliproxy/model-catalog.ts +++ b/src/cliproxy/model-catalog.ts @@ -11,24 +11,14 @@ import { migrateDeniedAntigravityModelAliases, normalizeModelIdForProvider, } from './model-id-normalizer'; +import { + AGY_GEMINI_PRO_COMPATIBILITY_IDS, + AGY_GEMINI_PRO_HIGH_ID, + AGY_GEMINI_PRO_LOW_ID, +} from '../shared/agy-gemini-pro-compatibility'; import { stripModelConfigurationSuffixes } from '../shared/extended-context-utils'; import { GEMINI_MINOR_VERSION_COMPATIBILITY_IDS } from '../shared/gemini-minor-version-compatibility'; -const AGY_GEMINI_PRO_HIGH_ID = 'gemini-3.1-pro-high'; -const AGY_GEMINI_PRO_LOW_ID = 'gemini-3.1-pro-low'; -const AGY_GEMINI_PRO_COMPATIBILITY_IDS = Object.freeze({ - 'gemini-3-pro-high': AGY_GEMINI_PRO_HIGH_ID, - 'gemini-3.1-pro-high': AGY_GEMINI_PRO_HIGH_ID, - 'gemini-3-pro-low': AGY_GEMINI_PRO_LOW_ID, - 'gemini-3.1-pro-low': AGY_GEMINI_PRO_LOW_ID, - 'gemini-3-pro-preview': AGY_GEMINI_PRO_HIGH_ID, - 'gemini-3-pro-preview-customtools': AGY_GEMINI_PRO_HIGH_ID, - 'gemini-3.1-pro-preview': AGY_GEMINI_PRO_HIGH_ID, - 'gemini-3.1-pro-preview-customtools': AGY_GEMINI_PRO_HIGH_ID, - 'gemini-3-1-pro-preview': AGY_GEMINI_PRO_HIGH_ID, - 'gemini-3-1-pro-preview-customtools': AGY_GEMINI_PRO_HIGH_ID, -} satisfies Record); - /** * Thinking support configuration for a model. * Defines how thinking/reasoning budget can be controlled. diff --git a/src/shared/agy-gemini-pro-compatibility.ts b/src/shared/agy-gemini-pro-compatibility.ts new file mode 100644 index 00000000..88b4215d --- /dev/null +++ b/src/shared/agy-gemini-pro-compatibility.ts @@ -0,0 +1,15 @@ +export const AGY_GEMINI_PRO_HIGH_ID = 'gemini-3.1-pro-high'; +export const AGY_GEMINI_PRO_LOW_ID = 'gemini-3.1-pro-low'; + +export const AGY_GEMINI_PRO_COMPATIBILITY_IDS = Object.freeze({ + 'gemini-3-pro-high': AGY_GEMINI_PRO_HIGH_ID, + 'gemini-3.1-pro-high': AGY_GEMINI_PRO_HIGH_ID, + 'gemini-3-pro-low': AGY_GEMINI_PRO_LOW_ID, + 'gemini-3.1-pro-low': AGY_GEMINI_PRO_LOW_ID, + 'gemini-3-pro-preview': AGY_GEMINI_PRO_HIGH_ID, + 'gemini-3-pro-preview-customtools': AGY_GEMINI_PRO_HIGH_ID, + 'gemini-3.1-pro-preview': AGY_GEMINI_PRO_HIGH_ID, + 'gemini-3.1-pro-preview-customtools': AGY_GEMINI_PRO_HIGH_ID, + 'gemini-3-1-pro-preview': AGY_GEMINI_PRO_HIGH_ID, + 'gemini-3-1-pro-preview-customtools': AGY_GEMINI_PRO_HIGH_ID, +} satisfies Record); diff --git a/ui/src/lib/model-catalogs.ts b/ui/src/lib/model-catalogs.ts index ad809f3c..ab6425e8 100644 --- a/ui/src/lib/model-catalogs.ts +++ b/ui/src/lib/model-catalogs.ts @@ -5,24 +5,15 @@ import type { ModelEntry, ProviderCatalog } from '@/components/cliproxy/provider-model-selector'; import { stripModelConfigurationSuffixes } from '@/lib/extended-context-utils'; +import { + AGY_GEMINI_PRO_COMPATIBILITY_IDS, + AGY_GEMINI_PRO_HIGH_ID, + AGY_GEMINI_PRO_LOW_ID, +} from '@shared/agy-gemini-pro-compatibility'; import { GEMINI_MINOR_VERSION_COMPATIBILITY_IDS } from '@shared/gemini-minor-version-compatibility'; const GEMINI_PREVIEW_MODEL_ID_PATTERN = /^gemini-(\d+(?:[.-]\d+)*)-(pro|flash)-preview(-customtools)?$/i; -const AGY_GEMINI_PRO_HIGH_ID = 'gemini-3.1-pro-high'; -const AGY_GEMINI_PRO_LOW_ID = 'gemini-3.1-pro-low'; -const AGY_GEMINI_PRO_COMPATIBILITY_IDS = new Map([ - ['gemini-3-pro-high', AGY_GEMINI_PRO_HIGH_ID], - ['gemini-3.1-pro-high', AGY_GEMINI_PRO_HIGH_ID], - ['gemini-3-pro-low', AGY_GEMINI_PRO_LOW_ID], - ['gemini-3.1-pro-low', AGY_GEMINI_PRO_LOW_ID], - ['gemini-3-pro-preview', AGY_GEMINI_PRO_HIGH_ID], - ['gemini-3-pro-preview-customtools', AGY_GEMINI_PRO_HIGH_ID], - ['gemini-3.1-pro-preview', AGY_GEMINI_PRO_HIGH_ID], - ['gemini-3.1-pro-preview-customtools', AGY_GEMINI_PRO_HIGH_ID], - ['gemini-3-1-pro-preview', AGY_GEMINI_PRO_HIGH_ID], - ['gemini-3-1-pro-preview-customtools', AGY_GEMINI_PRO_HIGH_ID], -]); const MANAGED_MODEL_PREFIXES = ['agy/', 'gcli/'] as const; export type CatalogAvailableModel = { @@ -62,7 +53,7 @@ function stripCustomtoolsSuffix(modelId: string): string { } function getAgyGeminiProCompatibilityId(modelId: string): string | undefined { - return AGY_GEMINI_PRO_COMPATIBILITY_IDS.get(normalizeModelId(modelId)); + return AGY_GEMINI_PRO_COMPATIBILITY_IDS[normalizeModelId(modelId)]; } function parseGeminiPreviewModelId(modelId: string): GeminiPreviewModelInfo | null { @@ -208,8 +199,8 @@ export const MODEL_CATALOGS: Record = { extendedContext: true, presetMapping: { default: 'gemini-3-1-flash-preview', - opus: 'gemini-3.1-pro-preview', - sonnet: 'gemini-3.1-pro-preview', + opus: AGY_GEMINI_PRO_HIGH_ID, + sonnet: AGY_GEMINI_PRO_HIGH_ID, haiku: 'gemini-3-1-flash-preview', }, }, diff --git a/ui/tests/unit/ui/lib/preset-utils.test.ts b/ui/tests/unit/ui/lib/preset-utils.test.ts index 2049860a..b527c51d 100644 --- a/ui/tests/unit/ui/lib/preset-utils.test.ts +++ b/ui/tests/unit/ui/lib/preset-utils.test.ts @@ -158,6 +158,12 @@ describe('claude preset utils', () => { expect(resolvedAgyModels.find((model) => model.name === 'Gemini Flash')?.id).toBe( 'gemini-3-1-flash-preview' ); + expect(resolvedAgyModels.find((model) => model.name === 'Gemini Flash')?.presetMapping).toEqual( + expect.objectContaining({ + opus: 'gemini-3.1-pro-high', + sonnet: 'gemini-3.1-pro-high', + }) + ); const supplementalAgyModels = getSupplementalCatalogModels( 'agy',