Vendored
+58
-3
@@ -14,7 +14,7 @@ const CATALOG = [
|
||||
mmproj: 'MMPROJ_QWEN3_5_0_8B_MULTIMODAL_Q8_0',
|
||||
minRamGb: 4,
|
||||
approxDownloadGb: 0.7,
|
||||
ctxSize: 8192,
|
||||
ctxSize: 16384,
|
||||
},
|
||||
{
|
||||
id: 'qwen3.5-2b',
|
||||
@@ -26,7 +26,7 @@ const CATALOG = [
|
||||
mmproj: 'MMPROJ_QWEN3_5_2B_MULTIMODAL_Q8_0',
|
||||
minRamGb: 6,
|
||||
approxDownloadGb: 1.6,
|
||||
ctxSize: 8192,
|
||||
ctxSize: 16384,
|
||||
},
|
||||
{
|
||||
id: 'qwen3.5-4b',
|
||||
@@ -155,7 +155,7 @@ const CATALOG = [
|
||||
vision: false,
|
||||
minRamGb: 8,
|
||||
approxDownloadGb: 1.2,
|
||||
ctxSize: 8192,
|
||||
ctxSize: 16384,
|
||||
},
|
||||
{
|
||||
id: 'qwen3-4b',
|
||||
@@ -315,6 +315,9 @@ const COMPACT_TOOL_ALLOW = [
|
||||
'memory_search',
|
||||
'memory_get',
|
||||
'memory_write',
|
||||
'todo_write',
|
||||
'task',
|
||||
'update_goal',
|
||||
'capability_status',
|
||||
'qvac_runtime_state',
|
||||
'qvac_system_resources',
|
||||
@@ -332,6 +335,54 @@ function filterToolsForModel(defs, idOrConstant) {
|
||||
return filtered.length ? filtered : list;
|
||||
}
|
||||
|
||||
function catalogId(idOrConstant) {
|
||||
const e = findCatalogEntry(idOrConstant);
|
||||
return String((e && e.id) || idOrConstant || '').toLowerCase();
|
||||
}
|
||||
|
||||
function isQwenReasoningModel(idOrConstant) {
|
||||
const id = catalogId(idOrConstant);
|
||||
return /qwen3(?:\.\d+)?/.test(id) || /qwen3[._-]/.test(String(idOrConstant || '').toLowerCase());
|
||||
}
|
||||
|
||||
// Qwen3.5's chat template leaves thinking off unless the reasoning channel is
|
||||
// enabled. Cap it so HUD thinking still streams, then the addon force-closes
|
||||
// <think> and the model can emit the tool XML / spoken reply.
|
||||
function reasoningBudgetForModel(idOrConstant) {
|
||||
if (!isQwenReasoningModel(idOrConstant)) return null;
|
||||
const id = catalogId(idOrConstant);
|
||||
if (/0\.8b|0\.6b|600m/.test(id)) return 128;
|
||||
if (/1\.7b|(?:^|-)2b/.test(id)) return 192;
|
||||
if (/(?:^|-)4b/.test(id)) return 320;
|
||||
if (/(?:^|-)[89]b/.test(id)) return 448;
|
||||
return 320;
|
||||
}
|
||||
|
||||
// Slightly below Qwen thinking's 0.6 so compact models still follow the
|
||||
// tool XML, but high enough to avoid the greedy repeat loops of temp 0.3.
|
||||
function compactGenerationParams(idOrConstant) {
|
||||
if (!isCompactToolModel(idOrConstant)) return {};
|
||||
return { temp: 0.55 };
|
||||
}
|
||||
|
||||
function generationParamsForModel(idOrConstant, extra) {
|
||||
const base = Object.assign(
|
||||
{
|
||||
repeat_penalty: 1.15,
|
||||
frequency_penalty: 0.15,
|
||||
},
|
||||
compactGenerationParams(idOrConstant)
|
||||
);
|
||||
const budget = reasoningBudgetForModel(idOrConstant);
|
||||
if (budget != null) {
|
||||
base.reasoning_budget = budget;
|
||||
base.predict = Math.min(768, Math.max(384, budget + 288));
|
||||
} else {
|
||||
base.predict = isCompactToolModel(idOrConstant) ? 384 : 640;
|
||||
}
|
||||
return Object.assign({}, base, extra || {});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
CATALOG,
|
||||
FALLBACK_LLM_IDS,
|
||||
@@ -346,5 +397,9 @@ module.exports = {
|
||||
isCompactToolModel,
|
||||
compactToolAllowlist,
|
||||
filterToolsForModel,
|
||||
isQwenReasoningModel,
|
||||
reasoningBudgetForModel,
|
||||
compactGenerationParams,
|
||||
generationParamsForModel,
|
||||
catalogLabel,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user