Changeset 0.22.7 (#149)

This commit is contained in:
2026-03-04 10:44:42 +00:00
parent d8e0664fa3
commit 389e47b0f9
62 changed files with 6820 additions and 1476 deletions

View File

@@ -75,9 +75,9 @@ describe('processModelsResponse — catalog models', () => {
assert.equal(models[0].name, 'claude-3-opus');
});
it('marks catalog models as NOT presets', () => {
it('marks catalog models as NOT personas', () => {
const models = processModelsResponse(apiResponse);
assert.equal(models[0].isPreset, false);
assert.equal(models[0].isPersona, false);
});
it('preserves configId from config_id || provider_config_id', () => {
@@ -93,7 +93,7 @@ describe('processModelsResponse — catalog models', () => {
// ── Preset transform ─────────────────────────
describe('processModelsResponse — presets', () => {
describe('processModelsResponse — personas', () => {
const apiResponse = {
models: [
{
@@ -107,47 +107,47 @@ describe('processModelsResponse — presets', () => {
avatar: '/avatars/code.png',
source: 'persona',
// Frontend alias fields
is_preset: true,
preset_id: 'preset-uuid',
preset_scope: 'global',
preset_avatar: '/avatars/code.png',
preset_team_name: null,
is_persona: true,
persona_id: 'preset-uuid',
persona_scope: 'global',
persona_avatar: '/avatars/code.png',
persona_team_name: null,
config_id: 'cfg-uuid',
provider_name: 'OpenAI',
},
],
};
it('uses preset_id as ID (not composite)', () => {
it('uses persona_id as ID (not composite)', () => {
const models = processModelsResponse(apiResponse);
assert.equal(models[0].id, 'preset-uuid',
'preset ID must use preset_id, not config_id:model_id');
'persona ID must use persona_id, not config_id:model_id');
});
it('falls back to persona_id when preset_id is missing', () => {
it('falls back to persona_id when not present', () => {
const resp = {
models: [{
id: 'p-uuid', model_id: 'gpt-4o',
is_preset: true, persona_id: 'p-uuid',
is_persona: true, persona_id: 'p-uuid',
// NO preset_id — simulates broken alias
source: 'persona',
}],
};
const models = processModelsResponse(resp);
assert.equal(models[0].id, 'p-uuid',
'must fall back to persona_id when preset_id is missing');
'must fall back to persona_id');
});
it('marks as preset', () => {
it('marks as persona', () => {
const models = processModelsResponse(apiResponse);
assert.equal(models[0].isPreset, true);
assert.equal(models[0].isPersona, true);
});
it('preserves preset metadata', () => {
it('preserves persona metadata', () => {
const models = processModelsResponse(apiResponse);
assert.equal(models[0].presetScope, 'global');
assert.equal(models[0].presetAvatar, '/avatars/code.png');
assert.equal(models[0].presetId, 'preset-uuid');
assert.equal(models[0].personaScope, 'global');
assert.equal(models[0].personaAvatar, '/avatars/code.png');
assert.equal(models[0].personaId, 'preset-uuid');
});
it('baseModelId is the underlying model', () => {
@@ -215,16 +215,16 @@ describe('processModelsResponse — hidden models', () => {
assert.equal(models[1].hidden, false, 'claude-3 should NOT be hidden');
});
it('presets are never hidden via model ID', () => {
it('personas are never hidden via model ID', () => {
const resp = {
models: [
{ model_id: 'gpt-4o', is_preset: true, preset_id: 'p1', display_name: 'Preset' },
{ model_id: 'gpt-4o', is_persona: true, persona_id: 'p1', display_name: 'Persona' },
],
};
const hidden = new Set(['gpt-4o']);
const models = processModelsResponse(resp, hidden);
assert.equal(models[0].hidden, false,
'presets must NOT be hidden by base model hidden pref');
'personas must NOT be hidden by base model hidden pref');
});
});
@@ -270,44 +270,44 @@ describe('Model sorting', () => {
function sortModels(models) {
const scopeOrder = { global: 0, team: 1, personal: 2 };
return [...models].sort((a, b) => {
if (a.isPreset && !b.isPreset) return -1;
if (!a.isPreset && b.isPreset) return 1;
if (a.isPreset && b.isPreset) {
const sa = scopeOrder[a.presetScope] ?? 9;
const sb = scopeOrder[b.presetScope] ?? 9;
if (a.isPersona && !b.isPersona) return -1;
if (!a.isPersona && b.isPersona) return 1;
if (a.isPersona && b.isPersona) {
const sa = scopeOrder[a.personaScope] ?? 9;
const sb = scopeOrder[b.personaScope] ?? 9;
if (sa !== sb) return sa - sb;
}
return a.name.localeCompare(b.name);
});
}
it('presets sort before regular models', () => {
it('personas sort before regular models', () => {
const models = [
{ name: 'GPT-4o', isPreset: false },
{ name: 'Code Helper', isPreset: true, presetScope: 'global' },
{ name: 'GPT-4o', isPersona: false },
{ name: 'Code Helper', isPersona: true, personaScope: 'global' },
];
const sorted = sortModels(models);
assert.equal(sorted[0].name, 'Code Helper');
assert.equal(sorted[1].name, 'GPT-4o');
});
it('global presets sort before team presets', () => {
it('global personas sort before team personas', () => {
const models = [
{ name: 'Team Bot', isPreset: true, presetScope: 'team' },
{ name: 'Global Bot', isPreset: true, presetScope: 'global' },
{ name: 'My Bot', isPreset: true, presetScope: 'personal' },
{ name: 'Team Bot', isPersona: true, personaScope: 'team' },
{ name: 'Global Bot', isPersona: true, personaScope: 'global' },
{ name: 'My Bot', isPersona: true, personaScope: 'personal' },
];
const sorted = sortModels(models);
assert.equal(sorted[0].presetScope, 'global');
assert.equal(sorted[1].presetScope, 'team');
assert.equal(sorted[2].presetScope, 'personal');
assert.equal(sorted[0].personaScope, 'global');
assert.equal(sorted[1].personaScope, 'team');
assert.equal(sorted[2].personaScope, 'personal');
});
it('regular models sort alphabetically', () => {
const models = [
{ name: 'Zephyr', isPreset: false },
{ name: 'Claude', isPreset: false },
{ name: 'GPT-4o', isPreset: false },
{ name: 'Zephyr', isPersona: false },
{ name: 'Claude', isPersona: false },
{ name: 'GPT-4o', isPersona: false },
];
const sorted = sortModels(models);
assert.equal(sorted[0].name, 'Claude');