char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Aleksander Grygierui: Improve Chat Form Actions UI/UX (models selector, add panel) (#27746)cae63579b

char/aliceai-t5-moe
9.4 KiB307 linesraw
1import { ModelsService } from '$lib/services/models.service';
2import { describe, expect, it } from 'vitest';
3
4const { parseModelId } = ModelsService;
5
6describe('parseModelId', () => {
7	it('handles unknown patterns correctly', () => {
8		expect(parseModelId('model-name-1')).toStrictEqual({
9			activatedParams: null,
10			modelName: 'model-name-1',
11			orgName: null,
12			params: null,
13			quantization: null,
14			raw: 'model-name-1',
15			tags: []
16		});
17
18		expect(parseModelId('org/model-name-2')).toStrictEqual({
19			activatedParams: null,
20			modelName: 'model-name-2',
21			orgName: 'org',
22			params: null,
23			quantization: null,
24			raw: 'org/model-name-2',
25			tags: []
26		});
27	});
28
29	it('extracts model parameters correctly', () => {
30		expect(parseModelId('model-100B-BF16')).toMatchObject({ params: '100B' });
31		expect(parseModelId('model-100B:Q4_K_M')).toMatchObject({ params: '100B' });
32	});
33
34	it('extracts model parameters correctly in lowercase', () => {
35		expect(parseModelId('model-100b-bf16')).toMatchObject({ params: '100B' });
36		expect(parseModelId('model-100b:q4_k_m')).toMatchObject({ params: '100B' });
37	});
38
39	it('extracts effective parameters correctly', () => {
40		expect(parseModelId('model-E4B-BF16')).toMatchObject({ params: 'E4B' });
41		expect(parseModelId('model-e2b:q4_k_m')).toMatchObject({ params: 'E2B' });
42	});
43
44	it('extracts activated parameters correctly', () => {
45		expect(parseModelId('model-100B-A10B-BF16')).toMatchObject({ activatedParams: 'A10B' });
46		expect(parseModelId('model-100B-A10B:Q4_K_M')).toMatchObject({ activatedParams: 'A10B' });
47	});
48
49	it('extracts activated parameters correctly in lowercase', () => {
50		expect(parseModelId('model-100b-a10b-bf16')).toMatchObject({ activatedParams: 'A10B' });
51		expect(parseModelId('model-100b-a10b:q4_k_m')).toMatchObject({ activatedParams: 'A10B' });
52	});
53
54	it('extracts quantization correctly', () => {
55		// Dash-separated quantization
56		expect(parseModelId('model-100B-UD-IQ1_S')).toMatchObject({ quantization: 'UD-IQ1_S' });
57		expect(parseModelId('model-100B-IQ4_XS')).toMatchObject({ quantization: 'IQ4_XS' });
58		expect(parseModelId('model-100B-Q4_K_M')).toMatchObject({ quantization: 'Q4_K_M' });
59		expect(parseModelId('model-100B-Q8_0')).toMatchObject({ quantization: 'Q8_0' });
60		expect(parseModelId('model-100B-UD-Q8_K_XL')).toMatchObject({ quantization: 'UD-Q8_K_XL' });
61		expect(parseModelId('model-100B-F16')).toMatchObject({ quantization: 'F16' });
62		expect(parseModelId('model-100B-BF16')).toMatchObject({ quantization: 'BF16' });
63		expect(parseModelId('model-100B-MXFP4')).toMatchObject({ quantization: 'MXFP4' });
64
65		// Colon-separated quantization
66		expect(parseModelId('model-100B:UD-IQ1_S')).toMatchObject({ quantization: 'UD-IQ1_S' });
67		expect(parseModelId('model-100B:IQ4_XS')).toMatchObject({ quantization: 'IQ4_XS' });
68		expect(parseModelId('model-100B:Q4_K_M')).toMatchObject({ quantization: 'Q4_K_M' });
69		expect(parseModelId('model-100B:Q8_0')).toMatchObject({ quantization: 'Q8_0' });
70		expect(parseModelId('model-100B:UD-Q8_K_XL')).toMatchObject({ quantization: 'UD-Q8_K_XL' });
71		expect(parseModelId('model-100B:F16')).toMatchObject({ quantization: 'F16' });
72		expect(parseModelId('model-100B:BF16')).toMatchObject({ quantization: 'BF16' });
73		expect(parseModelId('model-100B:MXFP4')).toMatchObject({ quantization: 'MXFP4' });
74
75		// Dot-separated quantization
76		expect(parseModelId('nomic-embed-text-v2-moe.Q4_K_M')).toMatchObject({
77			quantization: 'Q4_K_M'
78		});
79	});
80
81	it('extracts additional tags correctly', () => {
82		expect(parseModelId('model-100B-foobar-Q4_K_M')).toMatchObject({ tags: ['foobar'] });
83		expect(parseModelId('model-100B-A10B-foobar-1M-BF16')).toMatchObject({
84			tags: ['foobar', '1M']
85		});
86		expect(parseModelId('model-100B-1M-foobar:UD-Q8_K_XL')).toMatchObject({
87			tags: ['1M', 'foobar']
88		});
89	});
90
91	it('filters out container format segments from tags', () => {
92		expect(parseModelId('model-100B-GGUF-Instruct-BF16')).toMatchObject({
93			tags: ['Instruct']
94		});
95		expect(parseModelId('model-100B-GGML-Instruct:Q4_K_M')).toMatchObject({
96			tags: ['Instruct']
97		});
98	});
99
100	it('strips trailing container format segments from model names', () => {
101		expect(parseModelId('unsloth/DeepSeek-V4-Flash-0731-GGUF:Q2_K_XL')).toStrictEqual({
102			activatedParams: null,
103			modelName: 'DeepSeek-V4-Flash-0731',
104			orgName: 'unsloth',
105			params: null,
106			quantization: 'Q2_K_XL',
107			raw: 'unsloth/DeepSeek-V4-Flash-0731-GGUF:Q2_K_XL',
108			tags: []
109		});
110
111		expect(parseModelId('unsloth/Laguna-S-2.1-GGUF:Q4_K_XL')).toStrictEqual({
112			activatedParams: null,
113			modelName: 'Laguna-S-2.1',
114			orgName: 'unsloth',
115			params: null,
116			quantization: 'Q4_K_XL',
117			raw: 'unsloth/Laguna-S-2.1-GGUF:Q4_K_XL',
118			tags: []
119		});
120
121		expect(parseModelId('org/Model-Name-GGUF')).toStrictEqual({
122			activatedParams: null,
123			modelName: 'Model-Name',
124			orgName: 'org',
125			params: null,
126			quantization: null,
127			raw: 'org/Model-Name-GGUF',
128			tags: []
129		});
130	});
131
132	it('handles real-world examples correctly', () => {
133		expect(parseModelId('meta-llama/Llama-3.1-8B')).toStrictEqual({
134			activatedParams: null,
135			modelName: 'Llama-3.1',
136			orgName: 'meta-llama',
137			params: '8B',
138			quantization: null,
139			raw: 'meta-llama/Llama-3.1-8B',
140			tags: []
141		});
142
143		expect(parseModelId('openai/gpt-oss-120b-MXFP4')).toStrictEqual({
144			activatedParams: null,
145			modelName: 'gpt-oss',
146			orgName: 'openai',
147			params: '120B',
148			quantization: 'MXFP4',
149			raw: 'openai/gpt-oss-120b-MXFP4',
150			tags: []
151		});
152
153		expect(parseModelId('openai/gpt-oss-20b:Q4_K_M')).toStrictEqual({
154			activatedParams: null,
155			modelName: 'gpt-oss',
156			orgName: 'openai',
157			params: '20B',
158			quantization: 'Q4_K_M',
159			raw: 'openai/gpt-oss-20b:Q4_K_M',
160			tags: []
161		});
162
163		expect(parseModelId('Qwen/Qwen3-Coder-30B-A3B-Instruct-1M-BF16')).toStrictEqual({
164			activatedParams: 'A3B',
165			modelName: 'Qwen3-Coder',
166			orgName: 'Qwen',
167			params: '30B',
168			quantization: 'BF16',
169			raw: 'Qwen/Qwen3-Coder-30B-A3B-Instruct-1M-BF16',
170			tags: ['Instruct', '1M']
171		});
172	});
173
174	it('handles real-world examples with quantization in segments', () => {
175		expect(parseModelId('meta-llama/Llama-4-Scout-17B-16E-Instruct-Q4_K_M')).toStrictEqual({
176			activatedParams: null,
177			modelName: 'Llama-4-Scout',
178			orgName: 'meta-llama',
179			params: '17B',
180			quantization: 'Q4_K_M',
181			raw: 'meta-llama/Llama-4-Scout-17B-16E-Instruct-Q4_K_M',
182			tags: ['16E', 'Instruct']
183		});
184
185		expect(parseModelId('MiniMaxAI/MiniMax-M2-IQ4_XS')).toStrictEqual({
186			activatedParams: null,
187			modelName: 'MiniMax-M2',
188			orgName: 'MiniMaxAI',
189			params: null,
190			quantization: 'IQ4_XS',
191			raw: 'MiniMaxAI/MiniMax-M2-IQ4_XS',
192			tags: []
193		});
194
195		expect(parseModelId('MiniMaxAI/MiniMax-M2-UD-Q3_K_XL')).toStrictEqual({
196			activatedParams: null,
197			modelName: 'MiniMax-M2',
198			orgName: 'MiniMaxAI',
199			params: null,
200			quantization: 'UD-Q3_K_XL',
201			raw: 'MiniMaxAI/MiniMax-M2-UD-Q3_K_XL',
202			tags: []
203		});
204
205		expect(parseModelId('mistralai/Devstral-2-123B-Instruct-2512-Q4_K_M')).toStrictEqual({
206			activatedParams: null,
207			modelName: 'Devstral-2',
208			orgName: 'mistralai',
209			params: '123B',
210			quantization: 'Q4_K_M',
211			raw: 'mistralai/Devstral-2-123B-Instruct-2512-Q4_K_M',
212			tags: ['Instruct', '2512']
213		});
214
215		expect(parseModelId('mistralai/Devstral-Small-2-24B-Instruct-2512-Q8_0')).toStrictEqual({
216			activatedParams: null,
217			modelName: 'Devstral-Small-2',
218			orgName: 'mistralai',
219			params: '24B',
220			quantization: 'Q8_0',
221			raw: 'mistralai/Devstral-Small-2-24B-Instruct-2512-Q8_0',
222			tags: ['Instruct', '2512']
223		});
224
225		expect(parseModelId('noctrex/GLM-4.7-Flash-MXFP4_MOE')).toStrictEqual({
226			activatedParams: null,
227			modelName: 'GLM-4.7-Flash',
228			orgName: 'noctrex',
229			params: null,
230			quantization: 'MXFP4_MOE',
231			raw: 'noctrex/GLM-4.7-Flash-MXFP4_MOE',
232			tags: []
233		});
234
235		expect(parseModelId('Qwen/Qwen3-Coder-Next-Q4_K_M')).toStrictEqual({
236			activatedParams: null,
237			modelName: 'Qwen3-Coder-Next',
238			orgName: 'Qwen',
239			params: null,
240			quantization: 'Q4_K_M',
241			raw: 'Qwen/Qwen3-Coder-Next-Q4_K_M',
242			tags: []
243		});
244
245		expect(parseModelId('openai/gpt-oss-120b-Q4_K_M')).toStrictEqual({
246			activatedParams: null,
247			modelName: 'gpt-oss',
248			orgName: 'openai',
249			params: '120B',
250			quantization: 'Q4_K_M',
251			raw: 'openai/gpt-oss-120b-Q4_K_M',
252			tags: []
253		});
254
255		expect(parseModelId('openai/gpt-oss-20b-F16')).toStrictEqual({
256			activatedParams: null,
257			modelName: 'gpt-oss',
258			orgName: 'openai',
259			params: '20B',
260			quantization: 'F16',
261			raw: 'openai/gpt-oss-20b-F16',
262			tags: []
263		});
264
265		expect(parseModelId('nomic-embed-text-v2-moe.Q4_K_M')).toStrictEqual({
266			activatedParams: null,
267			modelName: 'nomic-embed-text-v2-moe',
268			orgName: null,
269			params: null,
270			quantization: 'Q4_K_M',
271			raw: 'nomic-embed-text-v2-moe.Q4_K_M',
272			tags: []
273		});
274	});
275
276	it('handles ambiguous model names', () => {
277		// Qwen3.5 Instruct vs Thinking — tags should distinguish them
278		expect(parseModelId('Qwen/Qwen3.5-30B-A3B-Instruct')).toMatchObject({
279			activatedParams: 'A3B',
280			modelName: 'Qwen3.5',
281			params: '30B',
282			tags: ['Instruct']
283		});
284
285		expect(parseModelId('Qwen/Qwen3.5-30B-A3B-Thinking')).toMatchObject({
286			activatedParams: 'A3B',
287			modelName: 'Qwen3.5',
288			params: '30B',
289			tags: ['Thinking']
290		});
291
292		// Dot-separated quantization with variant suffixes
293		expect(parseModelId('gemma-3-27b-it-heretic-v2.Q8_0')).toMatchObject({
294			modelName: 'gemma-3',
295			params: '27B',
296			quantization: 'Q8_0',
297			tags: ['it', 'heretic', 'v2']
298		});
299
300		expect(parseModelId('gemma-3-27b-it.Q8_0')).toMatchObject({
301			modelName: 'gemma-3',
302			params: '27B',
303			quantization: 'Q8_0',
304			tags: ['it']
305		});
306	});
307});