From 3e9b3d00319af151558a54a7ee5334013ab37640 Mon Sep 17 00:00:00 2001 From: YoVinchen Date: Wed, 11 Feb 2026 17:48:41 +0800 Subject: [PATCH] feat(omo): add preset model variants for thinking level support Add OPENCODE_PRESET_MODEL_VARIANTS constant with variant definitions for Google, OpenAI, and Anthropic models. The omoModelVariantsMap builder now falls back to presets when config-defined variants are absent, enabling the variant selector for supported models. --- .../providers/forms/OmoFormFields.tsx | 4 +- .../providers/forms/ProviderForm.tsx | 20 ++ src/config/opencodeProviderPresets.ts | 252 ++++++++++++++++++ 3 files changed, 275 insertions(+), 1 deletion(-) diff --git a/src/components/providers/forms/OmoFormFields.tsx b/src/components/providers/forms/OmoFormFields.tsx index 7bf7c8a34..3c5cb8214 100644 --- a/src/components/providers/forms/OmoFormFields.tsx +++ b/src/components/providers/forms/OmoFormFields.tsx @@ -273,6 +273,8 @@ export function OmoFormFields({ currentVariant, ); const hasModel = Boolean(currentModel); + const hasVariants = + hasModel && (modelVariantsMap[currentModel] || []).length > 0; const firstIsUnavailable = Boolean(currentVariant) && !(modelVariantsMap[currentModel] || []).includes(currentVariant); @@ -283,7 +285,7 @@ export function OmoFormFields({ onValueChange={(value) => onChange(value === EMPTY_VARIANT_VALUE ? "" : value) } - disabled={!hasModel} + disabled={!hasModel || !hasVariants} > p.id === modelId); + if (preset?.variants) { + const presetKeys = Object.keys(preset.variants).filter(Boolean); + if (presetKeys.length > 0) { + variantsMap[fullKey] = presetKeys; + } + } + } + } } return variantsMap; diff --git a/src/config/opencodeProviderPresets.ts b/src/config/opencodeProviderPresets.ts index 26e71a2ad..095f9668a 100644 --- a/src/config/opencodeProviderPresets.ts +++ b/src/config/opencodeProviderPresets.ts @@ -24,6 +24,258 @@ export const opencodeNpmPackages = [ { value: "@ai-sdk/google", label: "Google (Gemini)" }, ] as const; +export interface PresetModelVariant { + id: string; + variants?: Record>; +} + +export const OPENCODE_PRESET_MODEL_VARIANTS: Record< + string, + PresetModelVariant[] +> = { + "@ai-sdk/google": [ + { + id: "gemini-2.5-flash-lite", + variants: { + auto: { thinkingConfig: { includeThoughts: true, thinkingBudget: -1 } }, + "no-thinking": { thinkingConfig: { thinkingBudget: 0 } }, + }, + }, + { + id: "gemini-3-flash-preview", + variants: { + high: { + thinkingConfig: { includeThoughts: true, thinkingLevel: "high" }, + }, + low: { + thinkingConfig: { includeThoughts: true, thinkingLevel: "low" }, + }, + medium: { + thinkingConfig: { includeThoughts: true, thinkingLevel: "medium" }, + }, + }, + }, + { + id: "gemini-3-pro-preview", + variants: { + high: { + thinkingConfig: { includeThoughts: true, thinkingLevel: "high" }, + }, + low: { + thinkingConfig: { includeThoughts: true, thinkingLevel: "low" }, + }, + }, + }, + ], + "@ai-sdk/openai": [ + { + id: "gpt-5", + variants: { + high: { + reasoningEffort: "high", + reasoningSummary: "auto", + textVerbosity: "high", + }, + low: { + reasoningEffort: "low", + reasoningSummary: "auto", + textVerbosity: "low", + }, + medium: { + reasoningEffort: "medium", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + }, + }, + { + id: "gpt-5.1", + variants: { + high: { + reasoningEffort: "high", + reasoningSummary: "auto", + textVerbosity: "high", + }, + low: { + reasoningEffort: "low", + reasoningSummary: "auto", + textVerbosity: "low", + }, + medium: { + reasoningEffort: "medium", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + }, + }, + { + id: "gpt-5.1-codex", + variants: { + high: { + reasoningEffort: "high", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + low: { + reasoningEffort: "low", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + medium: { + reasoningEffort: "medium", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + }, + }, + { + id: "gpt-5.1-codex-max", + variants: { + high: { + reasoningEffort: "high", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + low: { + reasoningEffort: "low", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + medium: { + reasoningEffort: "medium", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + xhigh: { + reasoningEffort: "xhigh", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + }, + }, + { + id: "gpt-5.2", + variants: { + high: { + reasoningEffort: "high", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + low: { + reasoningEffort: "low", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + medium: { + reasoningEffort: "medium", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + xhigh: { + reasoningEffort: "xhigh", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + }, + }, + { + id: "gpt-5.2-codex", + variants: { + high: { + reasoningEffort: "high", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + low: { + reasoningEffort: "low", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + medium: { + reasoningEffort: "medium", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + xhigh: { + reasoningEffort: "xhigh", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + }, + }, + { + id: "gpt-5.3-codex", + variants: { + high: { + reasoningEffort: "high", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + low: { + reasoningEffort: "low", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + medium: { + reasoningEffort: "medium", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + xhigh: { + reasoningEffort: "xhigh", + reasoningSummary: "auto", + textVerbosity: "medium", + }, + }, + }, + ], + "@ai-sdk/anthropic": [ + { + id: "claude-sonnet-4-5-20250929", + variants: { + high: { effort: "high" }, + low: { effort: "low" }, + medium: { effort: "medium" }, + }, + }, + { + id: "claude-opus-4-5-20251101", + variants: { + high: { thinking: { budgetTokens: 18000, type: "enabled" } }, + low: { thinking: { budgetTokens: 5000, type: "enabled" } }, + medium: { thinking: { budgetTokens: 13000, type: "enabled" } }, + }, + }, + { + id: "claude-opus-4-6", + variants: { + high: { thinking: { budgetTokens: 18000, type: "enabled" } }, + low: { thinking: { budgetTokens: 5000, type: "enabled" } }, + medium: { thinking: { budgetTokens: 13000, type: "enabled" } }, + }, + }, + { + id: "claude-haiku-4-5-20251001", + }, + { + id: "gemini-claude-opus-4-5-thinking", + variants: { + high: { effort: "high" }, + low: { effort: "low" }, + medium: { effort: "medium" }, + }, + }, + { + id: "gemini-claude-sonnet-4-5-thinking", + variants: { + high: { thinking: { budgetTokens: 18000, type: "enabled" } }, + low: { thinking: { budgetTokens: 5000, type: "enabled" } }, + medium: { thinking: { budgetTokens: 13000, type: "enabled" } }, + }, + }, + ], +}; + export const opencodeProviderPresets: OpenCodeProviderPreset[] = [ { name: "DeepSeek",