Files
ccs/tests/unit/cliproxy/model-catalog-compat.test.ts
T
Tam Nhu Tran 7bbf32ae9a feat(cliproxy): source model pickers from upstream catalogs
- fetch live provider model definitions through /api/cliproxy/catalog

- overlay CCS preset metadata without keeping UI dropdowns as the source of truth

- wire /cliproxy and quick setup to the upstream-backed catalog path
2026-04-08 17:23:35 -04:00

62 lines
2.5 KiB
TypeScript

import { describe, it, expect } from 'bun:test';
import { findModel, supportsThinking } from '../../../src/cliproxy/model-catalog';
import {
PROVIDER_TO_CHANNEL,
SYNCABLE_PROVIDERS,
mergeCatalog,
} from '../../../src/cliproxy/catalog-cache';
describe('model-catalog compatibility lookups', () => {
it('finds agy Claude models using dotted major.minor IDs', () => {
const dottedThinking = findModel('agy', 'claude-opus-4.6-thinking');
const dottedNonThinking = findModel('agy', 'claude-sonnet-4.6');
expect(dottedThinking?.id).toBe('claude-opus-4-6-thinking');
expect(dottedNonThinking?.id).toBe('claude-sonnet-4-6');
});
it('maps legacy agy 4.5 IDs to canonical 4.6 catalog models', () => {
const legacyOpusThinking = findModel('agy', 'claude-opus-4.5-thinking');
const legacySonnetThinking = findModel('agy', 'claude-sonnet-4.5-thinking');
const legacySonnet = findModel('agy', 'claude-sonnet-4.5');
expect(legacyOpusThinking?.id).toBe('claude-opus-4-6-thinking');
expect(legacySonnetThinking?.id).toBe('claude-sonnet-4-6');
expect(legacySonnet?.id).toBe('claude-sonnet-4-6');
});
it('supports thinking checks for dotted agy model IDs', () => {
expect(supportsThinking('agy', 'claude-opus-4.6-thinking')).toBe(true);
expect(supportsThinking('agy', 'claude-sonnet-4.6')).toBe(true);
expect(supportsThinking('agy', 'claude-opus-4.5-thinking')).toBe(true);
expect(supportsThinking('agy', 'claude-sonnet-4.5')).toBe(true);
});
it('maps legacy sonnet 4.6 thinking aliases to canonical agy model', () => {
const dottedLegacy = findModel('agy', 'claude-sonnet-4.6-thinking');
const hyphenLegacy = findModel('agy', 'claude-sonnet-4-6-thinking');
expect(dottedLegacy?.id).toBe('claude-sonnet-4-6');
expect(hyphenLegacy?.id).toBe('claude-sonnet-4-6');
});
it('maps all dashboard providers to upstream catalog channels', () => {
expect(SYNCABLE_PROVIDERS).toContain('qwen');
expect(SYNCABLE_PROVIDERS).toContain('iflow');
expect(SYNCABLE_PROVIDERS).toContain('kiro');
expect(SYNCABLE_PROVIDERS).toContain('ghcp');
expect(PROVIDER_TO_CHANNEL.ghcp).toBe('github-copilot');
});
it('does not re-add stale static-only models when live catalog data is present', () => {
const catalog = mergeCatalog('gemini', [
{
id: 'gemini-2.5-pro',
display_name: 'Gemini 2.5 Pro',
},
]);
expect(catalog?.models.map((model) => model.id)).toEqual(['gemini-2.5-pro']);
});
});