@staticeng/opencode-litellm 0.2.4 → 0.2.5
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 +0 -0
- package/README.md +3 -3
- package/dist/helpers.d.ts +0 -0
- package/dist/helpers.js +0 -0
- package/dist/index.d.ts +0 -0
- package/dist/index.js +0 -0
- package/dist/litellm.d.ts +0 -0
- package/dist/litellm.js +0 -0
- package/dist/mapping.d.ts +0 -0
- package/dist/mapping.js +19 -11
- package/dist/merge.d.ts +0 -0
- package/dist/merge.js +0 -0
- package/dist/model-contracts.d.ts +0 -0
- package/dist/model-contracts.js +3 -3
- package/dist/options.d.ts +0 -0
- package/dist/options.js +0 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +0 -0
- package/package.json +1 -1
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -61,7 +61,7 @@ When `includeBackends` is present, models are candidates when `model_info.backen
|
|
|
61
61
|
|
|
62
62
|
LiteLLM metadata does not expose every OpenCode model field. The plugin includes exact built-in contracts for the currently approved GPT-5.4, GPT-5.5, GPT-5.6, DeepSeek V4 Flash, and Qwen3.8 aliases. Use `overrides` to customize those defaults or to add metadata for unknown models.
|
|
63
63
|
|
|
64
|
-
When LiteLLM publishes `model_info.supported_reasoning_efforts`, the plugin maps that list to OpenCode variants automatically
|
|
64
|
+
When LiteLLM publishes `model_info.supported_reasoning_efforts`, the plugin maps that list to OpenCode variants automatically. Known contracts contribute their approved defaults; discovered extra efforts remain available unless that exact contract explicitly closes discovery. Currently only `qwen3.8-flash-next` closes discovery so unverified efforts cannot become active. No substring, suffix, provider namespace, or base-model inference is used.
|
|
65
65
|
|
|
66
66
|
```json
|
|
67
67
|
{
|
|
@@ -102,9 +102,9 @@ The built-in mode matrix is:
|
|
|
102
102
|
| GPT-5.6 Luna / Sol / Terra | `none`, `low`, `medium`, `high`, `xhigh`, `max` | `medium` |
|
|
103
103
|
| DeepSeek V4 Flash | `off`, `low`, `high`, `max` | `max` |
|
|
104
104
|
| Qwen3.8 27B refusal dial | `off`, `low`, `medium`, `xhigh` | `xhigh` |
|
|
105
|
-
| Qwen3.8 Flash Next | `off`, `low` | `
|
|
105
|
+
| Qwen3.8 Flash Next | `off`, `low`, `medium`, `xhigh` | `xhigh` |
|
|
106
106
|
|
|
107
|
-
DeepSeek `off` sends canonical `none`. Qwen `off` sends only `chat_template_kwargs.enable_thinking=false`, with no reasoning effort. `ultra` is not generated by a built-in contract. For requests without an explicit named variant, the plugin supplies the row's contract default through model options; an explicit variant is merged afterward and wins. Qwen's explicit `off` cleanup removes the model's default effort before serialization. The `variantDefault` compatibility marker is UI-only and is stripped before requests for exact built-in aliases.
|
|
107
|
+
DeepSeek `off` sends canonical `none`. Qwen `off` sends only `chat_template_kwargs.enable_thinking=false`, with no reasoning effort. `ultra` is not generated by a built-in contract. Flash Next activates exactly `off`, `low`, `medium`, and `xhigh`: discovered extras such as `ultra` are suppressed, V2 omits `minimal`, `high`, and `max`, and the legacy OpenCode surface disables unsupported generic choices. For requests without an explicit named variant, the plugin supplies the row's contract default through model options; an explicit variant is merged afterward and wins. Qwen's explicit `off` cleanup removes the model's default effort before serialization. The `variantDefault` compatibility marker is UI-only and is stripped before requests for exact built-in aliases.
|
|
108
108
|
|
|
109
109
|
The exact dynamically discovered alias `qwen3.8-flash-next` also receives verified static metadata that overrides incomplete or conflicting LiteLLM group metadata: text and image input, text output, attachment, reasoning, tool calling, and a 262144-token context. Its output limit remains unknown and is represented by the package's `0` sentinel; pricing and other modalities are not supplied. The contract is still discovery-gated and never creates the alias when LiteLLM omits it.
|
|
110
110
|
|
package/dist/helpers.d.ts
CHANGED
|
File without changes
|
package/dist/helpers.js
CHANGED
|
File without changes
|
package/dist/index.d.ts
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/litellm.d.ts
CHANGED
|
File without changes
|
package/dist/litellm.js
CHANGED
|
File without changes
|
package/dist/mapping.d.ts
CHANGED
|
File without changes
|
package/dist/mapping.js
CHANGED
|
@@ -327,6 +327,8 @@ function generatedModel(model, tombstones = false) {
|
|
|
327
327
|
if (!name)
|
|
328
328
|
return undefined;
|
|
329
329
|
const mappedModalities = modalities(model);
|
|
330
|
+
const discoveredVariants = supportsReasoning(model) ? reasoningVariants(model) : undefined;
|
|
331
|
+
const suppressDiscoveredVariants = modelContract(name)?.suppressDiscoveredVariants === true;
|
|
330
332
|
const generated = {
|
|
331
333
|
id: name,
|
|
332
334
|
name,
|
|
@@ -336,7 +338,7 @@ function generatedModel(model, tombstones = false) {
|
|
|
336
338
|
modalities: mappedModalities,
|
|
337
339
|
...(mappedModalities.input.includes("image") || mappedModalities.input.includes("pdf") ? { attachment: true } : {}),
|
|
338
340
|
...(supportsReasoning(model) ? { reasoning: true } : {}),
|
|
339
|
-
...(
|
|
341
|
+
...(discoveredVariants && !suppressDiscoveredVariants ? { variants: discoveredVariants } : {}),
|
|
340
342
|
...(model.model_info?.supports_function_calling || model.model_info?.supports_tool_choice ? { tool_call: true } : {}),
|
|
341
343
|
};
|
|
342
344
|
const defaults = contractDefaults(name, tombstones);
|
|
@@ -368,20 +370,26 @@ function v2Variants(model) {
|
|
|
368
370
|
return undefined;
|
|
369
371
|
return Object.entries(variants).map(([id, value]) => ({ id, body: v2VariantBody(value) }));
|
|
370
372
|
}
|
|
371
|
-
function contractV2Variants(name, override) {
|
|
373
|
+
function contractV2Variants(name, model, override) {
|
|
372
374
|
const entry = modelContract(name);
|
|
373
375
|
if (!entry)
|
|
374
376
|
return undefined;
|
|
375
377
|
const variants = entry.modes.map((mode) => ({ id: mode.id, body: { ...mode.v2Body } }));
|
|
376
|
-
if (!isRecord(override?.variants))
|
|
377
|
-
return variants;
|
|
378
378
|
const byID = new Map(variants.map((variant) => [variant.id, variant]));
|
|
379
|
-
|
|
380
|
-
const
|
|
381
|
-
|
|
382
|
-
id,
|
|
383
|
-
|
|
384
|
-
|
|
379
|
+
if (isRecord(override?.variants)) {
|
|
380
|
+
for (const [id, value] of Object.entries(override.variants)) {
|
|
381
|
+
const current = byID.get(id);
|
|
382
|
+
byID.set(id, {
|
|
383
|
+
id,
|
|
384
|
+
body: deepMerge(current?.body ?? {}, v2VariantBody(value)),
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (!entry.suppressDiscoveredVariants && isRecord(model.variants)) {
|
|
389
|
+
for (const [id, value] of Object.entries(model.variants)) {
|
|
390
|
+
if (!byID.has(id))
|
|
391
|
+
byID.set(id, { id, body: v2VariantBody(value) });
|
|
392
|
+
}
|
|
385
393
|
}
|
|
386
394
|
return Array.from(byID.values());
|
|
387
395
|
}
|
|
@@ -449,7 +457,7 @@ export function mapModelsV2(models, options = {}) {
|
|
|
449
457
|
const legacy = mapModels(models, options);
|
|
450
458
|
return Object.fromEntries(Object.entries(legacy).map(([name, model]) => {
|
|
451
459
|
const mapped = v2Model(model, options.baseURL);
|
|
452
|
-
const variants = contractV2Variants(name, options.overrides?.[name]);
|
|
460
|
+
const variants = contractV2Variants(name, model, options.overrides?.[name]);
|
|
453
461
|
return [name, variants ? { ...mapped, variants } : mapped];
|
|
454
462
|
}));
|
|
455
463
|
}
|
package/dist/merge.d.ts
CHANGED
|
File without changes
|
package/dist/merge.js
CHANGED
|
File without changes
|
|
File without changes
|
package/dist/model-contracts.js
CHANGED
|
@@ -12,7 +12,7 @@ function effortModes(ids) {
|
|
|
12
12
|
v2Body: freezeJson({ reasoning_effort: id }),
|
|
13
13
|
})));
|
|
14
14
|
}
|
|
15
|
-
function contract(family, aliases, modes, defaultMode, metadata) {
|
|
15
|
+
function contract(family, aliases, modes, defaultMode, metadata, suppressDiscoveredVariants = false) {
|
|
16
16
|
if (!modes.some((mode) => mode.id === defaultMode))
|
|
17
17
|
throw new Error(`Model contract ${family} has an invalid default`);
|
|
18
18
|
return Object.freeze({
|
|
@@ -22,6 +22,7 @@ function contract(family, aliases, modes, defaultMode, metadata) {
|
|
|
22
22
|
defaultMode,
|
|
23
23
|
reasoning: true,
|
|
24
24
|
variantDefault: false,
|
|
25
|
+
...(suppressDiscoveredVariants ? { suppressDiscoveredVariants: true } : {}),
|
|
25
26
|
...(metadata ? { metadata } : {}),
|
|
26
27
|
});
|
|
27
28
|
}
|
|
@@ -44,7 +45,6 @@ const QWEN_MODES = Object.freeze([
|
|
|
44
45
|
Object.freeze({ id: "medium", legacy: freezeJson({ reasoningEffort: "medium" }), v2Body: freezeJson({ reasoning_effort: "medium" }) }),
|
|
45
46
|
Object.freeze({ id: "xhigh", legacy: freezeJson({ reasoningEffort: "xhigh" }), v2Body: freezeJson({ reasoning_effort: "xhigh" }) }),
|
|
46
47
|
]);
|
|
47
|
-
const QWEN_FLASH_NEXT_MODES = Object.freeze(QWEN_MODES.slice(0, 2));
|
|
48
48
|
const QWEN_FLASH_NEXT_METADATA = Object.freeze({
|
|
49
49
|
modalities: Object.freeze({
|
|
50
50
|
input: Object.freeze(["text", "image"]),
|
|
@@ -69,7 +69,7 @@ export const MODEL_CONTRACTS = Object.freeze([
|
|
|
69
69
|
contract("GPT-5.6 Terra", chatGptAliases("gpt-5.6-terra"), GPT_MAX_MODES, "medium"),
|
|
70
70
|
contract("DeepSeek V4 Flash", ["deepseek-v4-flash-fp8-mtp", "deepseek-v4-flash-fp8-mtp-norefusal"], DEEPSEEK_MODES, "max"),
|
|
71
71
|
contract("Qwen3.8", ["qwen3.8-27b-refusal-dial"], QWEN_MODES, "xhigh"),
|
|
72
|
-
contract("Qwen3.8", ["qwen3.8-flash-next"],
|
|
72
|
+
contract("Qwen3.8", ["qwen3.8-flash-next"], QWEN_MODES, "xhigh", QWEN_FLASH_NEXT_METADATA, true),
|
|
73
73
|
]);
|
|
74
74
|
export const RETIRED_MODEL_ALIASES = Object.freeze([
|
|
75
75
|
...chatGptAliases("gpt-5.3-codex"),
|
package/dist/options.d.ts
CHANGED
|
File without changes
|
package/dist/options.js
CHANGED
|
File without changes
|
package/dist/types.d.ts
CHANGED
package/dist/types.js
CHANGED
|
File without changes
|