genai-lite 0.8.3 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +210 -207
- package/dist/config/llm-presets.json +24 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -1
- package/dist/llm/LLMService.d.ts +30 -1
- package/dist/llm/LLMService.js +42 -4
- package/dist/llm/clients/AnthropicClientAdapter.d.ts +2 -2
- package/dist/llm/clients/AnthropicClientAdapter.js +17 -3
- package/dist/llm/clients/GeminiClientAdapter.d.ts +2 -2
- package/dist/llm/clients/GeminiClientAdapter.js +14 -3
- package/dist/llm/clients/LlamaCppClientAdapter.d.ts +4 -4
- package/dist/llm/clients/LlamaCppClientAdapter.js +118 -15
- package/dist/llm/clients/MistralClientAdapter.d.ts +2 -2
- package/dist/llm/clients/MistralClientAdapter.js +15 -4
- package/dist/llm/clients/MockClientAdapter.d.ts +2 -2
- package/dist/llm/clients/MockClientAdapter.js +36 -19
- package/dist/llm/clients/OpenAIClientAdapter.d.ts +2 -2
- package/dist/llm/clients/OpenAIClientAdapter.js +26 -3
- package/dist/llm/clients/OpenRouterClientAdapter.d.ts +2 -2
- package/dist/llm/clients/OpenRouterClientAdapter.js +81 -10
- package/dist/llm/clients/types.d.ts +18 -1
- package/dist/llm/clients/types.js +4 -0
- package/dist/llm/config.d.ts +9 -2
- package/dist/llm/config.js +695 -33
- package/dist/llm/services/ModelResolver.d.ts +6 -0
- package/dist/llm/services/ModelResolver.js +57 -17
- package/dist/llm/services/SettingsManager.d.ts +1 -1
- package/dist/llm/services/SettingsManager.js +92 -4
- package/dist/llm/types.d.ts +127 -0
- package/dist/prompting/index.d.ts +1 -1
- package/dist/prompting/index.js +2 -1
- package/dist/prompting/parser.d.ts +23 -0
- package/dist/prompting/parser.js +33 -0
- package/dist/shared/adapters/errorUtils.d.ts +15 -0
- package/dist/shared/adapters/errorUtils.js +69 -1
- package/dist/shared/adapters/logprobsUtils.d.ts +13 -0
- package/dist/shared/adapters/logprobsUtils.js +33 -0
- package/dist/shared/services/withRetry.d.ts +50 -0
- package/dist/shared/services/withRetry.js +78 -0
- package/package.json +59 -59
- package/src/config/image-presets.json +212 -212
- package/src/config/llm-presets.json +623 -599
package/dist/llm/config.js
CHANGED
|
@@ -44,7 +44,8 @@ exports.ADAPTER_CONFIGS = {
|
|
|
44
44
|
baseURL: process.env.ANTHROPIC_API_BASE_URL || undefined,
|
|
45
45
|
},
|
|
46
46
|
llamacpp: {
|
|
47
|
-
|
|
47
|
+
// 127.0.0.1 (not localhost) avoids a ~2s/request IPv6-fallback stall on Windows
|
|
48
|
+
baseURL: process.env.LLAMACPP_API_BASE_URL || 'http://127.0.0.1:8080',
|
|
48
49
|
},
|
|
49
50
|
openrouter: {
|
|
50
51
|
baseURL: process.env.OPENROUTER_API_BASE_URL || 'https://openrouter.ai/api/v1',
|
|
@@ -63,6 +64,10 @@ exports.DEFAULT_LLM_SETTINGS = {
|
|
|
63
64
|
stopSequences: [],
|
|
64
65
|
frequencyPenalty: 0.0,
|
|
65
66
|
presencePenalty: 0.0,
|
|
67
|
+
topK: undefined, // No universal default; provider support varies, filtered when undefined
|
|
68
|
+
minP: undefined, // No universal default; explicit per-model defaults for detected GGUF models
|
|
69
|
+
repeatPenalty: undefined, // No universal default; explicit per-model defaults for detected GGUF models
|
|
70
|
+
seed: undefined, // No universal default; deterministic sampling is opt-in
|
|
66
71
|
supportsSystemMessage: true,
|
|
67
72
|
systemMessageFallback: {
|
|
68
73
|
format: 'xml',
|
|
@@ -89,6 +94,9 @@ exports.DEFAULT_LLM_SETTINGS = {
|
|
|
89
94
|
},
|
|
90
95
|
openRouterProvider: undefined, // Optional, only used with OpenRouter provider
|
|
91
96
|
structuredOutput: undefined, // Optional, enables JSON schema-constrained output
|
|
97
|
+
logprobs: undefined, // Optional, per-token log probabilities (llama.cpp/OpenAI/OpenRouter)
|
|
98
|
+
topLogprobs: undefined, // Optional, number of alternatives per token
|
|
99
|
+
llamacpp: undefined, // Optional, llama.cpp-specific settings (grammar, chatTemplateKwargs)
|
|
92
100
|
};
|
|
93
101
|
/**
|
|
94
102
|
* Per-provider default setting overrides
|
|
@@ -123,19 +131,23 @@ exports.SUPPORTED_PROVIDERS = [
|
|
|
123
131
|
{
|
|
124
132
|
id: "openai",
|
|
125
133
|
name: "OpenAI",
|
|
126
|
-
unsupportedParameters: ["frequencyPenalty"],
|
|
134
|
+
unsupportedParameters: ["frequencyPenalty", "topK", "minP", "repeatPenalty"],
|
|
127
135
|
},
|
|
128
136
|
{
|
|
129
137
|
id: "anthropic",
|
|
130
138
|
name: "Anthropic",
|
|
139
|
+
unsupportedParameters: ["seed", "minP", "repeatPenalty", "logprobs", "topLogprobs"],
|
|
131
140
|
},
|
|
132
141
|
{
|
|
133
142
|
id: "gemini",
|
|
134
143
|
name: "Google Gemini",
|
|
144
|
+
// Gemini has its own logprobs mechanism with a different shape; not mapped yet
|
|
145
|
+
unsupportedParameters: ["minP", "repeatPenalty", "logprobs", "topLogprobs"],
|
|
135
146
|
},
|
|
136
147
|
{
|
|
137
148
|
id: "mistral",
|
|
138
149
|
name: "Mistral AI",
|
|
150
|
+
unsupportedParameters: ["topK", "minP", "repeatPenalty", "logprobs", "topLogprobs"],
|
|
139
151
|
},
|
|
140
152
|
{
|
|
141
153
|
id: "llamacpp",
|
|
@@ -153,16 +165,241 @@ exports.SUPPORTED_PROVIDERS = [
|
|
|
153
165
|
allowUnknownModels: true, // Test provider accepts any model
|
|
154
166
|
},
|
|
155
167
|
];
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
// Shared vendor sampling profiles and reasoning-toggle metadata for GGUF models.
|
|
170
|
+
// Sampling values follow vendor model cards; llama.cpp's own server defaults
|
|
171
|
+
// (temperature 0.8, top_k 40, min_p 0.05) match no vendor's recommendation, so
|
|
172
|
+
// detected models set them explicitly. See docs/dev/adding-models-and-providers.md.
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
const HYBRID_REASONING = {
|
|
175
|
+
supported: true,
|
|
176
|
+
enabledByDefault: false,
|
|
177
|
+
canDisable: true,
|
|
178
|
+
};
|
|
179
|
+
const ALWAYS_ON_REASONING = {
|
|
180
|
+
supported: true,
|
|
181
|
+
enabledByDefault: true,
|
|
182
|
+
canDisable: false,
|
|
183
|
+
};
|
|
184
|
+
const THINK_MARKERS = ["<think>", "</think>"];
|
|
185
|
+
/** Qwen chat templates: enable_thinking flag; template injects an empty think block when disabled */
|
|
186
|
+
const QWEN_LOCAL_REASONING = {
|
|
187
|
+
toggleKwarg: "enable_thinking",
|
|
188
|
+
nothinkPrefix: "<think>\n\n</think>\n\n",
|
|
189
|
+
markers: THINK_MARKERS,
|
|
190
|
+
};
|
|
191
|
+
/** Gemma 4 chat template: enable_thinking flag; harmony-style thought-channel markers */
|
|
192
|
+
const GEMMA4_LOCAL_REASONING = {
|
|
193
|
+
toggleKwarg: "enable_thinking",
|
|
194
|
+
nothinkPrefix: "<|channel>thought\n<channel|>",
|
|
195
|
+
markers: ["<|channel>thought", "<channel|>"],
|
|
196
|
+
};
|
|
197
|
+
// Vendor sampling profiles (temperature / topP / topK / minP / repeatPenalty)
|
|
198
|
+
const QWEN_NONTHINKING_SAMPLING = {
|
|
199
|
+
temperature: 0.7, topP: 0.8, topK: 20, minP: 0, repeatPenalty: 1.0,
|
|
200
|
+
};
|
|
201
|
+
const QWEN3_THINKING_SAMPLING = {
|
|
202
|
+
temperature: 0.6, topP: 0.95, topK: 20, minP: 0, repeatPenalty: 1.0,
|
|
203
|
+
};
|
|
204
|
+
const QWEN35_THINKING_SAMPLING = {
|
|
205
|
+
temperature: 1.0, topP: 0.95, topK: 20, minP: 0, repeatPenalty: 1.0,
|
|
206
|
+
};
|
|
207
|
+
const GEMMA_SAMPLING = {
|
|
208
|
+
temperature: 1.0, topP: 0.95, topK: 64, minP: 0, repeatPenalty: 1.0,
|
|
209
|
+
};
|
|
210
|
+
const GPT_OSS_SAMPLING = {
|
|
211
|
+
temperature: 1.0, topP: 1.0, topK: 0, minP: 0, repeatPenalty: 1.0,
|
|
212
|
+
};
|
|
213
|
+
const MINISTRAL_INSTRUCT_SAMPLING = {
|
|
214
|
+
temperature: 0.15, minP: 0, repeatPenalty: 1.0,
|
|
215
|
+
};
|
|
216
|
+
const MINISTRAL_REASONING_SAMPLING = {
|
|
217
|
+
temperature: 0.7, topP: 0.95, minP: 0, repeatPenalty: 1.0,
|
|
218
|
+
};
|
|
219
|
+
const GRANITE_SAMPLING = {
|
|
220
|
+
temperature: 0.7, topP: 0.95, topK: 0, minP: 0, repeatPenalty: 1.0,
|
|
221
|
+
};
|
|
222
|
+
const LLAMA32_SAMPLING = {
|
|
223
|
+
temperature: 0.6, topP: 0.9, topK: 0, minP: 0, repeatPenalty: 1.0,
|
|
224
|
+
};
|
|
156
225
|
/**
|
|
157
226
|
* Known GGUF model patterns for capability detection
|
|
158
227
|
*
|
|
159
228
|
* Order matters: more specific patterns should come before generic ones.
|
|
160
229
|
* First matching pattern wins.
|
|
161
230
|
*
|
|
162
|
-
*
|
|
231
|
+
* Ordering rules (see docs/dev/adding-models-and-providers.md):
|
|
232
|
+
* - Specific before generic: "qwen3-4b-instruct-2507" before "qwen3-4b"
|
|
233
|
+
* - Newer family names before older substrings they contain: "qwen3.5" contains no
|
|
234
|
+
* "qwen3-" (the dot breaks the match) but is listed first anyway for clarity
|
|
235
|
+
* - Quantization agnostic: never embed Q4_K_M/Q8_0 in patterns
|
|
163
236
|
*/
|
|
164
237
|
exports.KNOWN_GGUF_MODELS = [
|
|
165
|
-
// Qwen 3
|
|
238
|
+
// --- Qwen 3.5 (hybrid thinking; enable_thinking toggle) ---
|
|
239
|
+
{
|
|
240
|
+
pattern: "qwen3.5-2b",
|
|
241
|
+
name: "Qwen 3.5 2B",
|
|
242
|
+
description: "Qwen 3.5 2B hybrid-thinking model",
|
|
243
|
+
capabilities: {
|
|
244
|
+
maxTokens: 8192,
|
|
245
|
+
contextWindow: 131072,
|
|
246
|
+
supportsImages: false,
|
|
247
|
+
supportsPromptCache: false,
|
|
248
|
+
reasoning: { ...HYBRID_REASONING },
|
|
249
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
250
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
251
|
+
reasoningDefaultSettings: QWEN35_THINKING_SAMPLING,
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
pattern: "qwen3.5-4b",
|
|
256
|
+
name: "Qwen 3.5 4B",
|
|
257
|
+
description: "Qwen 3.5 4B hybrid-thinking model",
|
|
258
|
+
capabilities: {
|
|
259
|
+
maxTokens: 8192,
|
|
260
|
+
contextWindow: 131072,
|
|
261
|
+
supportsImages: false,
|
|
262
|
+
supportsPromptCache: false,
|
|
263
|
+
reasoning: { ...HYBRID_REASONING },
|
|
264
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
265
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
266
|
+
reasoningDefaultSettings: QWEN35_THINKING_SAMPLING,
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
pattern: "qwen3.5-9b",
|
|
271
|
+
name: "Qwen 3.5 9B",
|
|
272
|
+
description: "Qwen 3.5 9B hybrid-thinking model",
|
|
273
|
+
capabilities: {
|
|
274
|
+
maxTokens: 16384,
|
|
275
|
+
contextWindow: 131072,
|
|
276
|
+
supportsImages: false,
|
|
277
|
+
supportsPromptCache: false,
|
|
278
|
+
reasoning: { ...HYBRID_REASONING },
|
|
279
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
280
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
281
|
+
reasoningDefaultSettings: QWEN35_THINKING_SAMPLING,
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
pattern: "qwen3.5",
|
|
286
|
+
name: "Qwen 3.5",
|
|
287
|
+
description: "Qwen 3.5 hybrid-thinking model (size not recognized)",
|
|
288
|
+
capabilities: {
|
|
289
|
+
maxTokens: 8192,
|
|
290
|
+
contextWindow: 131072,
|
|
291
|
+
supportsImages: false,
|
|
292
|
+
supportsPromptCache: false,
|
|
293
|
+
reasoning: { ...HYBRID_REASONING },
|
|
294
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
295
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
296
|
+
reasoningDefaultSettings: QWEN35_THINKING_SAMPLING,
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
// --- Qwen 3.6 (hybrid thinking; same profiles as 3.5 per family reuse) ---
|
|
300
|
+
{
|
|
301
|
+
pattern: "qwen3.6-27b",
|
|
302
|
+
name: "Qwen 3.6 27B",
|
|
303
|
+
description: "Qwen 3.6 27B hybrid-thinking model",
|
|
304
|
+
capabilities: {
|
|
305
|
+
maxTokens: 16384,
|
|
306
|
+
contextWindow: 131072,
|
|
307
|
+
supportsImages: false,
|
|
308
|
+
supportsPromptCache: false,
|
|
309
|
+
reasoning: { ...HYBRID_REASONING },
|
|
310
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
311
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
312
|
+
reasoningDefaultSettings: QWEN35_THINKING_SAMPLING,
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
pattern: "qwen3.6-35b",
|
|
317
|
+
name: "Qwen 3.6 35B-A3B",
|
|
318
|
+
description: "Qwen 3.6 35B MoE (3B active) hybrid-thinking model",
|
|
319
|
+
capabilities: {
|
|
320
|
+
maxTokens: 16384,
|
|
321
|
+
contextWindow: 131072,
|
|
322
|
+
supportsImages: false,
|
|
323
|
+
supportsPromptCache: false,
|
|
324
|
+
reasoning: { ...HYBRID_REASONING },
|
|
325
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
326
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
327
|
+
reasoningDefaultSettings: QWEN35_THINKING_SAMPLING,
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
pattern: "qwen3.6",
|
|
332
|
+
name: "Qwen 3.6",
|
|
333
|
+
description: "Qwen 3.6 hybrid-thinking model (size not recognized)",
|
|
334
|
+
capabilities: {
|
|
335
|
+
maxTokens: 8192,
|
|
336
|
+
contextWindow: 131072,
|
|
337
|
+
supportsImages: false,
|
|
338
|
+
supportsPromptCache: false,
|
|
339
|
+
reasoning: { ...HYBRID_REASONING },
|
|
340
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
341
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
342
|
+
reasoningDefaultSettings: QWEN35_THINKING_SAMPLING,
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
// --- Qwen 3 2507 refreshes (must precede the base qwen3-* size patterns) ---
|
|
346
|
+
// Instruct-2507 checkpoints are non-thinking; the enable_thinking:false kwarg and
|
|
347
|
+
// nothink stripping are safe no-ops there (template has no think injection).
|
|
348
|
+
{
|
|
349
|
+
pattern: "qwen3-4b-instruct-2507",
|
|
350
|
+
name: "Qwen 3 4B Instruct 2507",
|
|
351
|
+
description: "Qwen 3 4B Instruct-2507 (non-thinking checkpoint)",
|
|
352
|
+
capabilities: {
|
|
353
|
+
maxTokens: 8192,
|
|
354
|
+
contextWindow: 131072,
|
|
355
|
+
supportsImages: false,
|
|
356
|
+
supportsPromptCache: false,
|
|
357
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
358
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
pattern: "qwen3-4b-thinking-2507",
|
|
363
|
+
name: "Qwen 3 4B Thinking 2507",
|
|
364
|
+
description: "Qwen 3 4B Thinking-2507 (thinking-only checkpoint)",
|
|
365
|
+
capabilities: {
|
|
366
|
+
maxTokens: 16384,
|
|
367
|
+
contextWindow: 131072,
|
|
368
|
+
supportsImages: false,
|
|
369
|
+
supportsPromptCache: false,
|
|
370
|
+
reasoning: { ...ALWAYS_ON_REASONING },
|
|
371
|
+
localReasoning: { markers: THINK_MARKERS },
|
|
372
|
+
defaultSettings: QWEN3_THINKING_SAMPLING,
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
pattern: "qwen3-30b-a3b-instruct-2507",
|
|
377
|
+
name: "Qwen 3 30B-A3B Instruct 2507",
|
|
378
|
+
description: "Qwen 3 30B-A3B Instruct-2507 (non-thinking checkpoint)",
|
|
379
|
+
capabilities: {
|
|
380
|
+
maxTokens: 16384,
|
|
381
|
+
contextWindow: 131072,
|
|
382
|
+
supportsImages: false,
|
|
383
|
+
supportsPromptCache: false,
|
|
384
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
385
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
pattern: "qwen3-30b-a3b-thinking-2507",
|
|
390
|
+
name: "Qwen 3 30B-A3B Thinking 2507",
|
|
391
|
+
description: "Qwen 3 30B-A3B Thinking-2507 (thinking-only checkpoint)",
|
|
392
|
+
capabilities: {
|
|
393
|
+
maxTokens: 16384,
|
|
394
|
+
contextWindow: 131072,
|
|
395
|
+
supportsImages: false,
|
|
396
|
+
supportsPromptCache: false,
|
|
397
|
+
reasoning: { ...ALWAYS_ON_REASONING },
|
|
398
|
+
localReasoning: { markers: THINK_MARKERS },
|
|
399
|
+
defaultSettings: QWEN3_THINKING_SAMPLING,
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
// --- Qwen 3 Series (original hybrid checkpoints; enable_thinking toggle) ---
|
|
166
403
|
{
|
|
167
404
|
pattern: "qwen3-30b",
|
|
168
405
|
name: "Qwen 3 30B",
|
|
@@ -173,11 +410,12 @@ exports.KNOWN_GGUF_MODELS = [
|
|
|
173
410
|
supportsImages: false,
|
|
174
411
|
supportsPromptCache: false,
|
|
175
412
|
reasoning: {
|
|
176
|
-
|
|
177
|
-
enabledByDefault: false,
|
|
178
|
-
canDisable: true,
|
|
413
|
+
...HYBRID_REASONING,
|
|
179
414
|
maxBudget: 38912,
|
|
180
415
|
},
|
|
416
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
417
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
418
|
+
reasoningDefaultSettings: QWEN3_THINKING_SAMPLING,
|
|
181
419
|
},
|
|
182
420
|
},
|
|
183
421
|
{
|
|
@@ -190,11 +428,12 @@ exports.KNOWN_GGUF_MODELS = [
|
|
|
190
428
|
supportsImages: false,
|
|
191
429
|
supportsPromptCache: false,
|
|
192
430
|
reasoning: {
|
|
193
|
-
|
|
194
|
-
enabledByDefault: false,
|
|
195
|
-
canDisable: true,
|
|
431
|
+
...HYBRID_REASONING,
|
|
196
432
|
maxBudget: 38912,
|
|
197
433
|
},
|
|
434
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
435
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
436
|
+
reasoningDefaultSettings: QWEN3_THINKING_SAMPLING,
|
|
198
437
|
},
|
|
199
438
|
},
|
|
200
439
|
{
|
|
@@ -207,11 +446,12 @@ exports.KNOWN_GGUF_MODELS = [
|
|
|
207
446
|
supportsImages: false,
|
|
208
447
|
supportsPromptCache: false,
|
|
209
448
|
reasoning: {
|
|
210
|
-
|
|
211
|
-
enabledByDefault: false,
|
|
212
|
-
canDisable: true,
|
|
449
|
+
...HYBRID_REASONING,
|
|
213
450
|
maxBudget: 38912,
|
|
214
451
|
},
|
|
452
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
453
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
454
|
+
reasoningDefaultSettings: QWEN3_THINKING_SAMPLING,
|
|
215
455
|
},
|
|
216
456
|
},
|
|
217
457
|
{
|
|
@@ -224,11 +464,12 @@ exports.KNOWN_GGUF_MODELS = [
|
|
|
224
464
|
supportsImages: false,
|
|
225
465
|
supportsPromptCache: false,
|
|
226
466
|
reasoning: {
|
|
227
|
-
|
|
228
|
-
enabledByDefault: false,
|
|
229
|
-
canDisable: true,
|
|
467
|
+
...HYBRID_REASONING,
|
|
230
468
|
maxBudget: 38912,
|
|
231
469
|
},
|
|
470
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
471
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
472
|
+
reasoningDefaultSettings: QWEN3_THINKING_SAMPLING,
|
|
232
473
|
},
|
|
233
474
|
},
|
|
234
475
|
{
|
|
@@ -241,11 +482,12 @@ exports.KNOWN_GGUF_MODELS = [
|
|
|
241
482
|
supportsImages: false,
|
|
242
483
|
supportsPromptCache: false,
|
|
243
484
|
reasoning: {
|
|
244
|
-
|
|
245
|
-
enabledByDefault: false,
|
|
246
|
-
canDisable: true,
|
|
485
|
+
...HYBRID_REASONING,
|
|
247
486
|
maxBudget: 30720,
|
|
248
487
|
},
|
|
488
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
489
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
490
|
+
reasoningDefaultSettings: QWEN3_THINKING_SAMPLING,
|
|
249
491
|
},
|
|
250
492
|
},
|
|
251
493
|
{
|
|
@@ -258,15 +500,319 @@ exports.KNOWN_GGUF_MODELS = [
|
|
|
258
500
|
supportsImages: false,
|
|
259
501
|
supportsPromptCache: false,
|
|
260
502
|
reasoning: {
|
|
261
|
-
|
|
262
|
-
enabledByDefault: false,
|
|
263
|
-
canDisable: true,
|
|
503
|
+
...HYBRID_REASONING,
|
|
264
504
|
maxBudget: 30720,
|
|
265
505
|
},
|
|
506
|
+
localReasoning: QWEN_LOCAL_REASONING,
|
|
507
|
+
defaultSettings: QWEN_NONTHINKING_SAMPLING,
|
|
508
|
+
reasoningDefaultSettings: QWEN3_THINKING_SAMPLING,
|
|
509
|
+
},
|
|
510
|
+
},
|
|
511
|
+
// --- Gemma 4 (hybrid thinking, supports system messages) ---
|
|
512
|
+
// Note: enable_thinking:true is best-effort on Gemma 4 — the chat-template flag
|
|
513
|
+
// activates the thought channel unreliably. enable_thinking:false works reliably.
|
|
514
|
+
{
|
|
515
|
+
pattern: "gemma-4-e2b",
|
|
516
|
+
name: "Gemma 4 E2B",
|
|
517
|
+
description: "Gemma 4 E2B (2.3B effective) hybrid-thinking model",
|
|
518
|
+
capabilities: {
|
|
519
|
+
maxTokens: 8192,
|
|
520
|
+
contextWindow: 131072,
|
|
521
|
+
supportsImages: false,
|
|
522
|
+
supportsPromptCache: false,
|
|
523
|
+
supportsSystemMessage: true,
|
|
524
|
+
reasoning: { ...HYBRID_REASONING },
|
|
525
|
+
localReasoning: GEMMA4_LOCAL_REASONING,
|
|
526
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
527
|
+
},
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
pattern: "gemma-4-e4b",
|
|
531
|
+
name: "Gemma 4 E4B",
|
|
532
|
+
description: "Gemma 4 E4B (4.5B effective) hybrid-thinking model",
|
|
533
|
+
capabilities: {
|
|
534
|
+
maxTokens: 8192,
|
|
535
|
+
contextWindow: 131072,
|
|
536
|
+
supportsImages: false,
|
|
537
|
+
supportsPromptCache: false,
|
|
538
|
+
supportsSystemMessage: true,
|
|
539
|
+
reasoning: { ...HYBRID_REASONING },
|
|
540
|
+
localReasoning: GEMMA4_LOCAL_REASONING,
|
|
541
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
542
|
+
},
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
pattern: "gemma-4-12b",
|
|
546
|
+
name: "Gemma 4 12B",
|
|
547
|
+
description: "Gemma 4 12B dense hybrid-thinking model (256K context)",
|
|
548
|
+
capabilities: {
|
|
549
|
+
maxTokens: 16384,
|
|
550
|
+
contextWindow: 262144,
|
|
551
|
+
supportsImages: false,
|
|
552
|
+
supportsPromptCache: false,
|
|
553
|
+
supportsSystemMessage: true,
|
|
554
|
+
reasoning: { ...HYBRID_REASONING },
|
|
555
|
+
localReasoning: GEMMA4_LOCAL_REASONING,
|
|
556
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
557
|
+
},
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
pattern: "gemma-4-26b-a4b",
|
|
561
|
+
name: "Gemma 4 26B-A4B",
|
|
562
|
+
description: "Gemma 4 26B MoE (~4B active) hybrid-thinking model (256K context)",
|
|
563
|
+
capabilities: {
|
|
564
|
+
maxTokens: 16384,
|
|
565
|
+
contextWindow: 262144,
|
|
566
|
+
supportsImages: false,
|
|
567
|
+
supportsPromptCache: false,
|
|
568
|
+
supportsSystemMessage: true,
|
|
569
|
+
reasoning: { ...HYBRID_REASONING },
|
|
570
|
+
localReasoning: GEMMA4_LOCAL_REASONING,
|
|
571
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
pattern: "gemma-4-31b",
|
|
576
|
+
name: "Gemma 4 31B",
|
|
577
|
+
description: "Gemma 4 31B dense hybrid-thinking model (256K context)",
|
|
578
|
+
capabilities: {
|
|
579
|
+
maxTokens: 16384,
|
|
580
|
+
contextWindow: 262144,
|
|
581
|
+
supportsImages: false,
|
|
582
|
+
supportsPromptCache: false,
|
|
583
|
+
supportsSystemMessage: true,
|
|
584
|
+
reasoning: { ...HYBRID_REASONING },
|
|
585
|
+
localReasoning: GEMMA4_LOCAL_REASONING,
|
|
586
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
587
|
+
},
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
pattern: "gemma-4",
|
|
591
|
+
name: "Gemma 4",
|
|
592
|
+
description: "Gemma 4 hybrid-thinking model (size not recognized)",
|
|
593
|
+
capabilities: {
|
|
594
|
+
maxTokens: 8192,
|
|
595
|
+
contextWindow: 131072,
|
|
596
|
+
supportsImages: false,
|
|
597
|
+
supportsPromptCache: false,
|
|
598
|
+
supportsSystemMessage: true,
|
|
599
|
+
reasoning: { ...HYBRID_REASONING },
|
|
600
|
+
localReasoning: GEMMA4_LOCAL_REASONING,
|
|
601
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
602
|
+
},
|
|
603
|
+
},
|
|
604
|
+
// --- Gemma 3 (no thinking, no system-message role) ---
|
|
605
|
+
{
|
|
606
|
+
pattern: "gemma-3-1b",
|
|
607
|
+
name: "Gemma 3 1B",
|
|
608
|
+
description: "Gemma 3 1B instruction-tuned model",
|
|
609
|
+
capabilities: {
|
|
610
|
+
maxTokens: 8192,
|
|
611
|
+
contextWindow: 32768,
|
|
612
|
+
supportsImages: false,
|
|
613
|
+
supportsPromptCache: false,
|
|
614
|
+
supportsSystemMessage: false,
|
|
615
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
616
|
+
},
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
pattern: "gemma-3-4b",
|
|
620
|
+
name: "Gemma 3 4B",
|
|
621
|
+
description: "Gemma 3 4B instruction-tuned model",
|
|
622
|
+
capabilities: {
|
|
623
|
+
maxTokens: 8192,
|
|
624
|
+
contextWindow: 131072,
|
|
625
|
+
supportsImages: false,
|
|
626
|
+
supportsPromptCache: false,
|
|
627
|
+
supportsSystemMessage: false,
|
|
628
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
629
|
+
},
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
pattern: "gemma-3-12b",
|
|
633
|
+
name: "Gemma 3 12B",
|
|
634
|
+
description: "Gemma 3 12B instruction-tuned model",
|
|
635
|
+
capabilities: {
|
|
636
|
+
maxTokens: 8192,
|
|
637
|
+
contextWindow: 131072,
|
|
638
|
+
supportsImages: false,
|
|
639
|
+
supportsPromptCache: false,
|
|
640
|
+
supportsSystemMessage: false,
|
|
641
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
642
|
+
},
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
pattern: "gemma-3-27b",
|
|
646
|
+
name: "Gemma 3 27B",
|
|
647
|
+
description: "Gemma 3 27B instruction-tuned model",
|
|
648
|
+
capabilities: {
|
|
649
|
+
maxTokens: 8192,
|
|
650
|
+
contextWindow: 131072,
|
|
651
|
+
supportsImages: false,
|
|
652
|
+
supportsPromptCache: false,
|
|
653
|
+
supportsSystemMessage: false,
|
|
654
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
655
|
+
},
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
pattern: "gemma-3",
|
|
659
|
+
name: "Gemma 3",
|
|
660
|
+
description: "Gemma 3 instruction-tuned model (size not recognized)",
|
|
661
|
+
capabilities: {
|
|
662
|
+
maxTokens: 8192,
|
|
663
|
+
contextWindow: 32768,
|
|
664
|
+
supportsImages: false,
|
|
665
|
+
supportsPromptCache: false,
|
|
666
|
+
supportsSystemMessage: false,
|
|
667
|
+
defaultSettings: GEMMA_SAMPLING,
|
|
668
|
+
},
|
|
669
|
+
},
|
|
670
|
+
// --- GPT-OSS (harmony format; reasoning always on, cannot be disabled) ---
|
|
671
|
+
{
|
|
672
|
+
pattern: "gpt-oss-120b",
|
|
673
|
+
name: "GPT-OSS 120B",
|
|
674
|
+
description: "OpenAI GPT-OSS 120B reasoning-native model (harmony format)",
|
|
675
|
+
capabilities: {
|
|
676
|
+
maxTokens: 16384,
|
|
677
|
+
contextWindow: 131072,
|
|
678
|
+
supportsImages: false,
|
|
679
|
+
supportsPromptCache: false,
|
|
680
|
+
reasoning: { ...ALWAYS_ON_REASONING },
|
|
681
|
+
defaultSettings: GPT_OSS_SAMPLING,
|
|
682
|
+
},
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
pattern: "gpt-oss-20b",
|
|
686
|
+
name: "GPT-OSS 20B",
|
|
687
|
+
description: "OpenAI GPT-OSS 20B reasoning-native model (harmony format)",
|
|
688
|
+
capabilities: {
|
|
689
|
+
maxTokens: 16384,
|
|
690
|
+
contextWindow: 131072,
|
|
691
|
+
supportsImages: false,
|
|
692
|
+
supportsPromptCache: false,
|
|
693
|
+
reasoning: { ...ALWAYS_ON_REASONING },
|
|
694
|
+
defaultSettings: GPT_OSS_SAMPLING,
|
|
695
|
+
},
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
pattern: "gpt-oss",
|
|
699
|
+
name: "GPT-OSS",
|
|
700
|
+
description: "OpenAI GPT-OSS reasoning-native model (size not recognized)",
|
|
701
|
+
capabilities: {
|
|
702
|
+
maxTokens: 16384,
|
|
703
|
+
contextWindow: 131072,
|
|
704
|
+
supportsImages: false,
|
|
705
|
+
supportsPromptCache: false,
|
|
706
|
+
reasoning: { ...ALWAYS_ON_REASONING },
|
|
707
|
+
defaultSettings: GPT_OSS_SAMPLING,
|
|
708
|
+
},
|
|
709
|
+
},
|
|
710
|
+
// --- Ministral 3 (Reasoning variants before Instruct; Reasoning is a separate
|
|
711
|
+
// checkpoint, not a toggle) ---
|
|
712
|
+
{
|
|
713
|
+
pattern: "ministral-3-3b-reasoning",
|
|
714
|
+
name: "Ministral 3 3B Reasoning",
|
|
715
|
+
description: "Ministral 3 3B Reasoning variant (always-on thinking)",
|
|
716
|
+
capabilities: {
|
|
717
|
+
maxTokens: 16384,
|
|
718
|
+
contextWindow: 131072,
|
|
719
|
+
supportsImages: false,
|
|
720
|
+
supportsPromptCache: false,
|
|
721
|
+
reasoning: { ...ALWAYS_ON_REASONING },
|
|
722
|
+
localReasoning: { markers: THINK_MARKERS },
|
|
723
|
+
defaultSettings: MINISTRAL_REASONING_SAMPLING,
|
|
724
|
+
},
|
|
725
|
+
},
|
|
726
|
+
{
|
|
727
|
+
pattern: "ministral-3-8b-reasoning",
|
|
728
|
+
name: "Ministral 3 8B Reasoning",
|
|
729
|
+
description: "Ministral 3 8B Reasoning variant (always-on thinking)",
|
|
730
|
+
capabilities: {
|
|
731
|
+
maxTokens: 16384,
|
|
732
|
+
contextWindow: 131072,
|
|
733
|
+
supportsImages: false,
|
|
734
|
+
supportsPromptCache: false,
|
|
735
|
+
reasoning: { ...ALWAYS_ON_REASONING },
|
|
736
|
+
localReasoning: { markers: THINK_MARKERS },
|
|
737
|
+
defaultSettings: MINISTRAL_REASONING_SAMPLING,
|
|
738
|
+
},
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
pattern: "ministral-3-14b-reasoning",
|
|
742
|
+
name: "Ministral 3 14B Reasoning",
|
|
743
|
+
description: "Ministral 3 14B Reasoning variant (always-on thinking)",
|
|
744
|
+
capabilities: {
|
|
745
|
+
maxTokens: 16384,
|
|
746
|
+
contextWindow: 131072,
|
|
747
|
+
supportsImages: false,
|
|
748
|
+
supportsPromptCache: false,
|
|
749
|
+
reasoning: { ...ALWAYS_ON_REASONING },
|
|
750
|
+
localReasoning: { markers: THINK_MARKERS },
|
|
751
|
+
defaultSettings: MINISTRAL_REASONING_SAMPLING,
|
|
752
|
+
},
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
pattern: "ministral-3",
|
|
756
|
+
name: "Ministral 3",
|
|
757
|
+
description: "Ministral 3 Instruct model (thinking disabled via template flag)",
|
|
758
|
+
capabilities: {
|
|
759
|
+
maxTokens: 8192,
|
|
760
|
+
contextWindow: 131072,
|
|
761
|
+
supportsImages: false,
|
|
762
|
+
supportsPromptCache: false,
|
|
763
|
+
// Template supports a thinking flag but the Instruct variant is not a
|
|
764
|
+
// reasoning model; the adapter keeps enable_thinking:false.
|
|
765
|
+
localReasoning: {
|
|
766
|
+
toggleKwarg: "enable_thinking",
|
|
767
|
+
markers: THINK_MARKERS,
|
|
768
|
+
},
|
|
769
|
+
defaultSettings: MINISTRAL_INSTRUCT_SAMPLING,
|
|
770
|
+
},
|
|
771
|
+
},
|
|
772
|
+
// --- Granite 4.1 (no thinking) ---
|
|
773
|
+
{
|
|
774
|
+
pattern: "granite-4.1",
|
|
775
|
+
name: "Granite 4.1",
|
|
776
|
+
description: "IBM Granite 4.1 instruction-tuned model",
|
|
777
|
+
capabilities: {
|
|
778
|
+
maxTokens: 8192,
|
|
779
|
+
contextWindow: 131072,
|
|
780
|
+
supportsImages: false,
|
|
781
|
+
supportsPromptCache: false,
|
|
782
|
+
defaultSettings: GRANITE_SAMPLING,
|
|
783
|
+
},
|
|
784
|
+
},
|
|
785
|
+
// --- DeepSeek R1 (reasoning always on) ---
|
|
786
|
+
{
|
|
787
|
+
pattern: "deepseek-r1",
|
|
788
|
+
name: "DeepSeek R1",
|
|
789
|
+
description: "DeepSeek R1 reasoning model (always-on thinking)",
|
|
790
|
+
capabilities: {
|
|
791
|
+
maxTokens: 16384,
|
|
792
|
+
contextWindow: 131072,
|
|
793
|
+
supportsImages: false,
|
|
794
|
+
supportsPromptCache: false,
|
|
795
|
+
reasoning: { ...ALWAYS_ON_REASONING },
|
|
796
|
+
localReasoning: { markers: THINK_MARKERS },
|
|
797
|
+
defaultSettings: {
|
|
798
|
+
temperature: 0.6, topP: 0.95, minP: 0, repeatPenalty: 1.0,
|
|
799
|
+
},
|
|
800
|
+
},
|
|
801
|
+
},
|
|
802
|
+
// --- Llama 3.2 (no thinking) ---
|
|
803
|
+
{
|
|
804
|
+
pattern: "llama-3.2",
|
|
805
|
+
name: "Llama 3.2",
|
|
806
|
+
description: "Meta Llama 3.2 instruction-tuned model",
|
|
807
|
+
capabilities: {
|
|
808
|
+
maxTokens: 8192,
|
|
809
|
+
contextWindow: 131072,
|
|
810
|
+
supportsImages: false,
|
|
811
|
+
supportsPromptCache: false,
|
|
812
|
+
defaultSettings: LLAMA32_SAMPLING,
|
|
266
813
|
},
|
|
267
814
|
},
|
|
268
815
|
// Add more model patterns here as needed
|
|
269
|
-
// DeepSeek, Llama, etc.
|
|
270
816
|
];
|
|
271
817
|
/**
|
|
272
818
|
* Detects model capabilities from GGUF filename
|
|
@@ -635,6 +1181,44 @@ exports.SUPPORTED_MODELS = [
|
|
|
635
1181
|
notes: "Gemma models do not support JSON mode via Google's API",
|
|
636
1182
|
},
|
|
637
1183
|
},
|
|
1184
|
+
// Google Gemma 4 Models (Open weights, free via Gemini API)
|
|
1185
|
+
// Note: Unlike Gemma 3, Gemma 4 supports a native system role
|
|
1186
|
+
// Note: Reasoning left unsupported on the cloud entries — the Gemini API exposes
|
|
1187
|
+
// no thinking toggle for Gemma (the <|think|> system-token mechanism is not modeled)
|
|
1188
|
+
{
|
|
1189
|
+
id: "gemma-4-26b-a4b-it",
|
|
1190
|
+
name: "Gemma 4 26B-A4B",
|
|
1191
|
+
providerId: "gemini",
|
|
1192
|
+
contextWindow: 262144,
|
|
1193
|
+
inputPrice: 0.0,
|
|
1194
|
+
outputPrice: 0.0,
|
|
1195
|
+
description: "Google's Gemma 4 26B MoE (~4B active) open model with 256K context (free via Gemini API)",
|
|
1196
|
+
maxTokens: 8192,
|
|
1197
|
+
supportsImages: false,
|
|
1198
|
+
supportsPromptCache: false,
|
|
1199
|
+
supportsSystemMessage: true,
|
|
1200
|
+
structuredOutput: {
|
|
1201
|
+
supported: false,
|
|
1202
|
+
notes: "Gemma models do not support JSON mode via Google's API",
|
|
1203
|
+
},
|
|
1204
|
+
},
|
|
1205
|
+
{
|
|
1206
|
+
id: "gemma-4-31b-it",
|
|
1207
|
+
name: "Gemma 4 31B",
|
|
1208
|
+
providerId: "gemini",
|
|
1209
|
+
contextWindow: 262144,
|
|
1210
|
+
inputPrice: 0.0,
|
|
1211
|
+
outputPrice: 0.0,
|
|
1212
|
+
description: "Google's Gemma 4 31B dense open model with 256K context (free via Gemini API)",
|
|
1213
|
+
maxTokens: 8192,
|
|
1214
|
+
supportsImages: false,
|
|
1215
|
+
supportsPromptCache: false,
|
|
1216
|
+
supportsSystemMessage: true,
|
|
1217
|
+
structuredOutput: {
|
|
1218
|
+
supported: false,
|
|
1219
|
+
notes: "Gemma models do not support JSON mode via Google's API",
|
|
1220
|
+
},
|
|
1221
|
+
},
|
|
638
1222
|
// OpenAI Models - GPT-5 Series
|
|
639
1223
|
// Note: GPT-5 models do not support temperature or topP parameters
|
|
640
1224
|
{
|
|
@@ -649,7 +1233,7 @@ exports.SUPPORTED_MODELS = [
|
|
|
649
1233
|
supportsImages: true,
|
|
650
1234
|
supportsPromptCache: true,
|
|
651
1235
|
cacheReadsPrice: 0.4375,
|
|
652
|
-
unsupportedParameters: ["temperature", "topP"],
|
|
1236
|
+
unsupportedParameters: ["temperature", "topP", "seed"],
|
|
653
1237
|
reasoning: {
|
|
654
1238
|
supported: true,
|
|
655
1239
|
enabledByDefault: false,
|
|
@@ -673,7 +1257,7 @@ exports.SUPPORTED_MODELS = [
|
|
|
673
1257
|
supportsImages: true,
|
|
674
1258
|
supportsPromptCache: true,
|
|
675
1259
|
cacheReadsPrice: 0.3125,
|
|
676
|
-
unsupportedParameters: ["temperature", "topP"],
|
|
1260
|
+
unsupportedParameters: ["temperature", "topP", "seed"],
|
|
677
1261
|
reasoning: {
|
|
678
1262
|
supported: true,
|
|
679
1263
|
enabledByDefault: false,
|
|
@@ -697,7 +1281,7 @@ exports.SUPPORTED_MODELS = [
|
|
|
697
1281
|
supportsImages: true,
|
|
698
1282
|
supportsPromptCache: true,
|
|
699
1283
|
cacheReadsPrice: 0.0625,
|
|
700
|
-
unsupportedParameters: ["temperature", "topP"],
|
|
1284
|
+
unsupportedParameters: ["temperature", "topP", "seed"],
|
|
701
1285
|
reasoning: {
|
|
702
1286
|
supported: true,
|
|
703
1287
|
enabledByDefault: false,
|
|
@@ -721,7 +1305,7 @@ exports.SUPPORTED_MODELS = [
|
|
|
721
1305
|
supportsImages: true,
|
|
722
1306
|
supportsPromptCache: true,
|
|
723
1307
|
cacheReadsPrice: 0.0125,
|
|
724
|
-
unsupportedParameters: ["temperature", "topP"],
|
|
1308
|
+
unsupportedParameters: ["temperature", "topP", "seed"],
|
|
725
1309
|
reasoning: {
|
|
726
1310
|
supported: true,
|
|
727
1311
|
enabledByDefault: false,
|
|
@@ -746,7 +1330,7 @@ exports.SUPPORTED_MODELS = [
|
|
|
746
1330
|
supportsImages: true,
|
|
747
1331
|
supportsPromptCache: true,
|
|
748
1332
|
cacheReadsPrice: 0.275,
|
|
749
|
-
unsupportedParameters: ["topP"],
|
|
1333
|
+
unsupportedParameters: ["topP", "seed"],
|
|
750
1334
|
reasoning: {
|
|
751
1335
|
supported: true,
|
|
752
1336
|
enabledByDefault: true,
|
|
@@ -882,6 +1466,14 @@ exports.SUPPORTED_MODELS = [
|
|
|
882
1466
|
maxTokens: 4096,
|
|
883
1467
|
supportsImages: false,
|
|
884
1468
|
supportsPromptCache: false,
|
|
1469
|
+
// Optimistic: the server decides which model is loaded, so reasoning requests on
|
|
1470
|
+
// the generic id are not rejected. When the loaded GGUF is recognized, detection
|
|
1471
|
+
// overlays the real capabilities; otherwise extraction degrades gracefully.
|
|
1472
|
+
reasoning: {
|
|
1473
|
+
supported: true,
|
|
1474
|
+
enabledByDefault: false,
|
|
1475
|
+
canDisable: true,
|
|
1476
|
+
},
|
|
885
1477
|
structuredOutput: {
|
|
886
1478
|
supported: true,
|
|
887
1479
|
strictMode: true,
|
|
@@ -1018,22 +1610,32 @@ function createFallbackModelInfo(modelId, providerId, capabilities) {
|
|
|
1018
1610
|
*
|
|
1019
1611
|
* @param modelId - The model ID
|
|
1020
1612
|
* @param providerId - The provider ID
|
|
1613
|
+
* @param resolvedModelInfo - Optional already-resolved ModelInfo (e.g. a detected GGUF
|
|
1614
|
+
* model's fallback info). When provided it is used instead of a registry lookup, so
|
|
1615
|
+
* capabilities and defaultSettings of dynamically-detected models flow into settings.
|
|
1021
1616
|
* @returns Merged default settings with model-specific overrides applied
|
|
1022
1617
|
*/
|
|
1023
|
-
function getDefaultSettingsForModel(modelId, providerId) {
|
|
1618
|
+
function getDefaultSettingsForModel(modelId, providerId, resolvedModelInfo) {
|
|
1024
1619
|
// Base settings: global defaults, then provider-specific, then model-specific overrides
|
|
1025
1620
|
const baseDefaults = { ...exports.DEFAULT_LLM_SETTINGS };
|
|
1026
1621
|
const providerDefaults = exports.PROVIDER_DEFAULT_SETTINGS[providerId] || {};
|
|
1027
1622
|
const modelDefaults = exports.MODEL_DEFAULT_SETTINGS[modelId] || {};
|
|
1028
|
-
//
|
|
1623
|
+
// Prefer the caller's resolved ModelInfo (covers detected GGUF/unknown models);
|
|
1624
|
+
// fall back to the static registry.
|
|
1625
|
+
const modelInfo = resolvedModelInfo ?? getModelById(modelId, providerId);
|
|
1626
|
+
// Merge settings in order of precedence (model-declared defaults sit above the
|
|
1627
|
+
// static per-model-ID table, below request settings)
|
|
1029
1628
|
const mergedSettings = {
|
|
1030
1629
|
...baseDefaults,
|
|
1031
1630
|
...providerDefaults,
|
|
1032
1631
|
...modelDefaults,
|
|
1632
|
+
...(modelInfo?.defaultSettings || {}),
|
|
1033
1633
|
};
|
|
1034
|
-
// Override maxTokens from ModelInfo if available
|
|
1035
|
-
|
|
1036
|
-
if (modelInfo &&
|
|
1634
|
+
// Override maxTokens from ModelInfo if available (unless the model's own
|
|
1635
|
+
// defaultSettings already chose one)
|
|
1636
|
+
if (modelInfo &&
|
|
1637
|
+
modelInfo.maxTokens !== undefined &&
|
|
1638
|
+
modelInfo.defaultSettings?.maxTokens === undefined) {
|
|
1037
1639
|
mergedSettings.maxTokens = modelInfo.maxTokens;
|
|
1038
1640
|
}
|
|
1039
1641
|
// Handle reasoning settings based on model capabilities
|
|
@@ -1128,6 +1730,66 @@ function validateLLMSettings(settings) {
|
|
|
1128
1730
|
errors.push("stopSequences must contain only non-empty strings");
|
|
1129
1731
|
}
|
|
1130
1732
|
}
|
|
1733
|
+
if (settings.topK !== undefined) {
|
|
1734
|
+
if (!Number.isInteger(settings.topK) || settings.topK < 0) {
|
|
1735
|
+
errors.push("topK must be a non-negative integer");
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
if (settings.minP !== undefined) {
|
|
1739
|
+
if (typeof settings.minP !== "number" ||
|
|
1740
|
+
settings.minP < 0 ||
|
|
1741
|
+
settings.minP > 1) {
|
|
1742
|
+
errors.push("minP must be a number between 0 and 1");
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
if (settings.repeatPenalty !== undefined) {
|
|
1746
|
+
if (typeof settings.repeatPenalty !== "number" ||
|
|
1747
|
+
settings.repeatPenalty <= 0) {
|
|
1748
|
+
errors.push("repeatPenalty must be a positive number");
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
if (settings.seed !== undefined) {
|
|
1752
|
+
if (!Number.isInteger(settings.seed)) {
|
|
1753
|
+
errors.push("seed must be an integer");
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
if (settings.logprobs !== undefined && typeof settings.logprobs !== "boolean") {
|
|
1757
|
+
errors.push("logprobs must be a boolean");
|
|
1758
|
+
}
|
|
1759
|
+
if (settings.topLogprobs !== undefined) {
|
|
1760
|
+
if (!Number.isInteger(settings.topLogprobs) ||
|
|
1761
|
+
settings.topLogprobs < 0 ||
|
|
1762
|
+
settings.topLogprobs > 20) {
|
|
1763
|
+
errors.push("topLogprobs must be an integer between 0 and 20");
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
if (settings.llamacpp !== undefined) {
|
|
1767
|
+
if (typeof settings.llamacpp !== "object" || settings.llamacpp === null) {
|
|
1768
|
+
errors.push("llamacpp must be an object");
|
|
1769
|
+
}
|
|
1770
|
+
else {
|
|
1771
|
+
if (settings.llamacpp.grammar !== undefined &&
|
|
1772
|
+
typeof settings.llamacpp.grammar !== "string") {
|
|
1773
|
+
errors.push("llamacpp.grammar must be a string (GBNF grammar)");
|
|
1774
|
+
}
|
|
1775
|
+
if (settings.llamacpp.chatTemplateKwargs !== undefined) {
|
|
1776
|
+
const kwargs = settings.llamacpp.chatTemplateKwargs;
|
|
1777
|
+
if (typeof kwargs !== "object" || kwargs === null || Array.isArray(kwargs)) {
|
|
1778
|
+
errors.push("llamacpp.chatTemplateKwargs must be an object");
|
|
1779
|
+
}
|
|
1780
|
+
else if (Object.values(kwargs).some((v) => !["string", "number", "boolean"].includes(typeof v))) {
|
|
1781
|
+
errors.push("llamacpp.chatTemplateKwargs values must be strings, numbers, or booleans");
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
// llama-server rejects requests carrying both a raw grammar and a JSON schema:
|
|
1785
|
+
// "Either 'json_schema' or 'grammar' can be specified, but not both"
|
|
1786
|
+
if (settings.llamacpp.grammar &&
|
|
1787
|
+
settings.structuredOutput?.schema &&
|
|
1788
|
+
settings.structuredOutput.enabled !== false) {
|
|
1789
|
+
errors.push("llamacpp.grammar and structuredOutput are mutually exclusive (llama-server rejects both together)");
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1131
1793
|
if (settings.user !== undefined && typeof settings.user !== "string") {
|
|
1132
1794
|
errors.push("user must be a string");
|
|
1133
1795
|
}
|