Actually vendor harness

This commit is contained in:
2026-09-11 13:41:22 -04:00
parent 1acd371668
commit 04e013b090
52 changed files with 8550 additions and 1 deletions
+290
View File
@@ -0,0 +1,290 @@
/**
* LLM catalog — Hugging Face GGUFs that already exist as @qvac/sdk constants.
* Arbitrary HF repos will not load.
*/
const CATALOG = [
{
id: 'qwen3.5-0.8b',
constant: 'QWEN3_5_0_8B_MULTIMODAL_Q4_K_M',
name: 'Qwen3.5 0.8B',
tools: true,
vision: true,
mmproj: 'MMPROJ_QWEN3_5_0_8B_MULTIMODAL_Q8_0',
minRamGb: 4,
approxDownloadGb: 0.7,
ctxSize: 8192,
},
{
id: 'qwen3.5-2b',
constant: 'QWEN3_5_2B_MULTIMODAL_Q4_K_M',
name: 'Qwen3.5 2B',
tools: true,
vision: true,
mmproj: 'MMPROJ_QWEN3_5_2B_MULTIMODAL_Q8_0',
minRamGb: 6,
approxDownloadGb: 1.6,
ctxSize: 8192,
},
{
id: 'qwen3.5-4b',
constant: 'QWEN3_5_4B_MULTIMODAL_Q4_K_M',
name: 'Qwen3.5 4B',
tools: true,
vision: true,
mmproj: 'MMPROJ_QWEN3_5_4B_MULTIMODAL_Q8_0',
minRamGb: 10,
approxDownloadGb: 2.8,
ctxSize: 16384,
},
{
id: 'qwen3.5-9b',
constant: 'QWEN3_5_9B_MULTIMODAL_Q4_K_M',
name: 'Qwen3.5 9B',
tools: true,
vision: true,
mmproj: 'MMPROJ_QWEN3_5_9B_MULTIMODAL_F16',
minRamGb: 16,
approxDownloadGb: 5.5,
ctxSize: 32768,
},
{
id: 'gemma4-2b',
constant: 'GEMMA4_2B_MULTIMODAL_Q4_K_M',
name: 'Gemma4 E2B',
tools: true,
vision: true,
mmproj: 'MMPROJ_GEMMA4_2B_MULTIMODAL_Q8_0',
minRamGb: 8,
approxDownloadGb: 3.5,
ctxSize: 16384,
},
{
id: 'gemma4-4b',
constant: 'GEMMA4_4B_MULTIMODAL_Q4_K_M',
name: 'Gemma4 E4B',
tools: true,
vision: true,
mmproj: 'MMPROJ_GEMMA4_4B_MULTIMODAL_Q8_0',
minRamGb: 16,
approxDownloadGb: 5,
ctxSize: 32768,
},
{
id: 'qwen3-8b',
constant: 'QWEN3_8B_INST_Q4_K_M',
name: 'Qwen3 8B',
tools: true,
vision: false,
minRamGb: 16,
approxDownloadGb: 5,
ctxSize: 32768,
},
{
id: 'qwen3vl-2b',
constant: 'QWEN3_VL_2B_INSTRUCT_Q4_K_M',
name: 'Qwen3 VL 2B',
tools: true,
vision: true,
mmproj: 'MMPROJ_QWEN3_VL_2B_INSTRUCT_Q8_0',
minRamGb: 6,
approxDownloadGb: 1.5,
ctxSize: 8192,
},
{
id: 'qwen3.6-27b',
constant: 'QWEN3_6_27B_MULTIMODAL_Q4_K_XL',
name: 'Qwen3.6 27B',
tools: true,
vision: true,
mmproj: 'MMPROJ_QWEN3_6_27B_MULTIMODAL_F16',
minRamGb: 40,
approxDownloadGb: 16,
ctxSize: 32768,
},
{
id: 'qwen3.6-35b-a3b',
constant: 'QWEN3_6_35B_A3B_MULTIMODAL_Q4_K_M',
name: 'Qwen3.6 35B A3B',
tools: true,
vision: true,
mmproj: 'MMPROJ_QWEN3_6_35B_A3B_MULTIMODAL_F16',
minRamGb: 48,
approxDownloadGb: 20,
ctxSize: 32768,
},
{
id: 'gpt-oss-20b',
constant: 'GPT_OSS_20B_INST_Q4_K_M',
name: 'GPT-OSS 20B',
tools: true,
vision: false,
minRamGb: 32,
approxDownloadGb: 12,
ctxSize: 32768,
},
{
id: 'gemma4-31b',
constant: 'GEMMA4_31B_MULTIMODAL_Q4_K_M',
name: 'Gemma4 31B',
tools: true,
vision: true,
mmproj: 'MMPROJ_GEMMA4_31B_MULTIMODAL_F16',
minRamGb: 48,
approxDownloadGb: 18,
ctxSize: 32768,
},
{
id: 'qwen3-0.6b',
constant: 'QWEN3_600M_INST_Q4',
name: 'Qwen3 0.6B (lite)',
tools: false,
vision: false,
minRamGb: 4,
approxDownloadGb: 0.5,
ctxSize: 4096,
},
{
id: 'qwen3-1.7b',
constant: 'QWEN3_1_7B_INST_Q4',
name: 'Qwen3 1.7B',
tools: true,
vision: false,
minRamGb: 8,
approxDownloadGb: 1.2,
ctxSize: 8192,
},
{
id: 'qwen3-4b',
constant: 'QWEN3_4B_INST_Q4_K_M',
name: 'Qwen3 4B',
tools: true,
vision: false,
minRamGb: 16,
approxDownloadGb: 2.6,
ctxSize: 8192,
},
{
id: 'llama-tool-1b',
constant: 'LLAMA_TOOL_CALLING_1B_INST_Q4_K',
name: 'Llama tool-calling 1B',
tools: true,
vision: false,
minRamGb: 6,
approxDownloadGb: 0.8,
ctxSize: 4096,
},
];
const byId = new Map(CATALOG.map((e) => [e.id, e]));
const byConstant = new Map(CATALOG.filter((e) => e.constant).map((e) => [e.constant, e]));
const FALLBACK_LLM_IDS = [
'qwen3.5-4b',
'qwen3.5-9b',
'gemma4-4b',
'qwen3-8b',
'gemma4-2b',
'qwen3vl-2b',
'qwen3.5-2b',
'qwen3.5-0.8b',
];
function sizeTag(e) {
const n = Number(e && e.approxDownloadGb);
if (!Number.isFinite(n) || n <= 0) return '';
const g = n >= 10 ? String(Math.round(n)) : String(n).replace(/\.0$/, '');
return ' · ~' + g + ' GB';
}
function catalogLabel(e) {
if (!e) return '';
return (e.name || e.id || '') + sizeTag(e);
}
function listCatalog() {
return CATALOG.map((e) => Object.assign({}, e, { label: catalogLabel(e) }));
}
function findCatalogEntry(idOrConstant) {
if (!idOrConstant) return null;
return byId.get(idOrConstant) || byConstant.get(idOrConstant) || null;
}
function resolveModelConstant(idOrConstant) {
const e = findCatalogEntry(idOrConstant);
return e ? e.constant : idOrConstant;
}
function suggestProfile(hw) {
const ramGb = Number(hw && hw.totalRamBytes) / 1e9 || 0;
const vramGb = Number(hw && hw.vramBytes) / 1e9 || 0;
const budget = Math.max(ramGb, vramGb * 1.5);
const toolModels = CATALOG.filter((e) => e.tools).sort((a, b) => a.minRamGb - b.minRamGb);
let pick = toolModels[0] || CATALOG[0];
for (const e of toolModels) {
if (e.minRamGb + 2 <= budget) pick = e;
}
return pick;
}
function isVisionModel(idOrConstant) {
const e = findCatalogEntry(idOrConstant);
if (e) return e.vision === true;
return /_MULTIMODAL_/.test(String(idOrConstant || ''));
}
const MMPROJ_QUANTS = ['Q8_0', 'F16', 'BF16'];
function mmprojConstant(idOrConstant) {
if (idOrConstant && typeof idOrConstant === 'object') {
if (idOrConstant.mmproj) return idOrConstant.mmproj;
idOrConstant = idOrConstant.id || idOrConstant.constant;
}
const e = findCatalogEntry(idOrConstant);
if (e && e.mmproj) return e.mmproj;
const constant = (e && e.constant) || String(idOrConstant || '');
if (constant.indexOf('_MULTIMODAL_') < 0) return null;
return 'MMPROJ_' + constant.replace(/_Q[0-9A-Z_]+$/, '') + '_Q8_0';
}
function mmprojFamily(name) {
return String(name || '').replace(/_(Q8_0|F16|BF16|Q4_K)$/, '');
}
function mmprojCandidates(idOrConstant) {
const preferred = mmprojConstant(idOrConstant);
if (!preferred) return [];
const family = mmprojFamily(preferred);
const out = [];
function add(n) {
if (n && out.indexOf(n) < 0) out.push(n);
}
add(preferred);
for (let i = 0; i < MMPROJ_QUANTS.length; i++) add(family + '_' + MMPROJ_QUANTS[i]);
return out;
}
function toolDialectFor(idOrConstant) {
const e = findCatalogEntry(idOrConstant);
const id = (e && e.id) || String(idOrConstant || '').toLowerCase();
if (id.includes('qwen3.5') || id.includes('qwen3.6') || id.includes('qwen35')) return 'qwen35';
if (id.includes('gemma4')) return 'gemma4';
if (id.includes('gpt-oss') || id.includes('harmony')) return 'harmony';
if (id.includes('llama')) return 'pythonic';
return 'hermes';
}
module.exports = {
CATALOG,
FALLBACK_LLM_IDS,
listCatalog,
findCatalogEntry,
resolveModelConstant,
suggestProfile,
isVisionModel,
mmprojConstant,
mmprojCandidates,
toolDialectFor,
catalogLabel,
};