71 lines
4.7 KiB
JavaScript
71 lines
4.7 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { catalogue, preflight } from '../model-provider/cliproxy/index.mjs';
|
|
|
|
const ZAI = 'https://api.z.ai/api/anthropic';
|
|
const deps = () => ({
|
|
listAccounts: async () => ({ files: [
|
|
{ id: 'credential-1', name: 'credential-1', provider: 'claude', status: 'active' },
|
|
{ id: 'credential-2', name: 'credential-2', provider: 'codex', status: 'disabled' },
|
|
] }),
|
|
listModels: async name => ({ models: name === 'credential-1' ? [{ id: 'fixture-chat', display_name: 'Fixture', owned_by: 'anthropic', type: 'claude' }] : [] }),
|
|
listGroups: async () => [{ 'base-url': ZAI, keys: [{ auth_index: 'fixture-key' }], models: [{ name: 'fixture-model', alias: 'fixture-alias' }] }],
|
|
now: () => '2026-11-06T00:00:00.000Z',
|
|
});
|
|
|
|
test('catalogue attributes configured accounts, uses aliases, and enforces harness pairs', async () => {
|
|
const result = await catalogue(deps());
|
|
assert.equal(result.status, 'ready');
|
|
const zai = result.models.find(x => x.upstream === 'zai');
|
|
assert.deepEqual([zai.key, zai.model, zai.available, zai.harnesses], ['zai-fixture-alias', 'fixture-alias', true, ['pi']]);
|
|
const claude = result.models.find(x => x.upstream === 'claude');
|
|
assert.deepEqual(claude.harnesses, ['claude-code', 'pi']);
|
|
assert.deepEqual(preflight({ selection: zai, harness: 'claude-code', catalogue: result }), { allow: false, code: 'model-harness-incompatible' });
|
|
assert.deepEqual(preflight({ selection: zai, harness: 'pi', catalogue: result }), { allow: true });
|
|
assert.ok(!JSON.stringify(result).includes('credential-1'));
|
|
});
|
|
|
|
test('an empty group offers no models; unknown groups offer pi only and are unverified', async () => {
|
|
const d = deps();
|
|
d.listAccounts = async () => ({ files: [] });
|
|
d.listGroups = async () => [
|
|
{ 'base-url': ZAI, keys: [{ auth_index: 'a' }] },
|
|
{ 'base-url': 'https://fixture.invalid', keys: [{ auth_index: 'b' }], models: [{ name: 'fixture-other' }] },
|
|
];
|
|
const c = await catalogue(d);
|
|
assert.equal(c.models.length, 1);
|
|
assert.deepEqual([c.models[0].upstream, c.models[0].harnesses, c.models[0].reason], ['other', ['pi'], 'unverified']);
|
|
assert.ok(c.notices.includes('z.ai account has no models configured. Add them on Model proxy.'));
|
|
});
|
|
|
|
test('a failed catalogue never authorizes a saved route', async () => {
|
|
const d = deps(); d.listGroups = async () => { throw new Error('fixture private error'); };
|
|
const c = await catalogue(d);
|
|
assert.equal(c.status, 'unavailable');
|
|
assert.deepEqual(preflight({ selection: { upstream: 'zai', model: 'fixture-alias' }, harness: 'pi', catalogue: c }), { allow: false, code: 'model-catalogue-unavailable' });
|
|
});
|
|
|
|
test('module declares only supported transports and legacy routes without widening compatibility', async () => {
|
|
const { route } = await import('../model-provider/cliproxy/index.mjs');
|
|
assert.deepEqual(route({ selection: { upstream: 'codex', model: 'fixture-codex' }, harness: 'pi' }), {
|
|
provider: 'codex', model: 'fixture-codex', upstream: 'codex', routeId: 'codex', endpoint: 'v1', api: 'openai-responses', piProvider: 'mosaic-proxy-codex', compat: null,
|
|
});
|
|
assert.equal(route({ selection: { upstream: 'zai', model: 'fixture-zai' }, harness: 'claude-code' }).code, 'model-harness-incompatible');
|
|
assert.equal(route({ selection: { provider: 'proxy', route: 'unknown', model: 'fixture' }, harness: 'pi' }).code, 'proxy-route-unknown');
|
|
assert.equal(route({ selection: { provider: 'proxy', model: 'fixture' }, harness: 'pi' }).code, 'proxy-route-missing');
|
|
});
|
|
test('different model IDs that collapse to one readable slug refuse by name', async () => {
|
|
const d=deps();d.listAccounts=async()=>({files:[]});d.listGroups=async()=>[{'base-url':ZAI,keys:[{}],models:[{name:'fixture.a'},{name:'fixture-a'}]}];
|
|
const result=await catalogue(d);assert.equal(result.status,'unavailable');assert.equal(result.reason,'model-key-collision');
|
|
});
|
|
|
|
test('a second fixture module resolves independently and ambiguous legacy mappings refuse', async () => {
|
|
const {selectModelProvider}=await import('../src/model-provider-selection.mjs');
|
|
const first={name:'first-fixture',module:{route:({selection})=>selection.provider==='fixture-one'?{provider:selection.provider,model:selection.model,upstream:'one'}:{code:'unsupported'}}};
|
|
const second={name:'second-fixture',module:{route:({selection})=>selection.provider==='fixture-two'?{provider:selection.provider,model:selection.model,upstream:'two'}:{code:'unsupported'}}};
|
|
const entry={provider:'fixture-two',model:'fixture-model'};
|
|
assert.equal(selectModelProvider([first,second],entry)?.name,'second-fixture');
|
|
assert.equal(selectModelProvider([first,second],{...entry,module:'first-fixture'}),null);
|
|
assert.equal(selectModelProvider([first,second,{...second,name:'third-fixture'}],entry),null);
|
|
});
|