From 5c40a2db215b17a1f0f7d383bfb29c18f647eb2b Mon Sep 17 00:00:00 2001 From: hkfires <10558748+hkfires@users.noreply.github.com> Date: Thu, 15 Jan 2026 14:03:08 +0800 Subject: [PATCH] refactor(thinking): simplify ModeNone and budget validation logic --- internal/registry/model_definitions.go | 4 ++-- internal/thinking/validate.go | 33 +++++++++++--------------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/internal/registry/model_definitions.go b/internal/registry/model_definitions.go index b8ca8757..13fc8177 100644 --- a/internal/registry/model_definitions.go +++ b/internal/registry/model_definitions.go @@ -777,8 +777,8 @@ func GetAntigravityModelConfig() map[string]*AntigravityModelConfig { "gemini-3-pro-high": {Thinking: &ThinkingSupport{Min: 128, Max: 32768, ZeroAllowed: false, DynamicAllowed: true, Levels: []string{"low", "high"}}, Name: "models/gemini-3-pro-high"}, "gemini-3-pro-image": {Thinking: &ThinkingSupport{Min: 128, Max: 32768, ZeroAllowed: false, DynamicAllowed: true, Levels: []string{"low", "high"}}, Name: "models/gemini-3-pro-image"}, "gemini-3-flash": {Thinking: &ThinkingSupport{Min: 128, Max: 32768, ZeroAllowed: false, DynamicAllowed: true, Levels: []string{"minimal", "low", "medium", "high"}}, Name: "models/gemini-3-flash"}, - "claude-sonnet-4-5-thinking": {Thinking: &ThinkingSupport{Min: 1024, Max: 128000, ZeroAllowed: true, DynamicAllowed: false}, MaxCompletionTokens: 64000}, - "claude-opus-4-5-thinking": {Thinking: &ThinkingSupport{Min: 1024, Max: 128000, ZeroAllowed: true, DynamicAllowed: false}, MaxCompletionTokens: 64000}, + "claude-sonnet-4-5-thinking": {Thinking: &ThinkingSupport{Min: 1024, Max: 128000, ZeroAllowed: true, DynamicAllowed: true}, MaxCompletionTokens: 64000}, + "claude-opus-4-5-thinking": {Thinking: &ThinkingSupport{Min: 1024, Max: 128000, ZeroAllowed: true, DynamicAllowed: true}, MaxCompletionTokens: 64000}, } } diff --git a/internal/thinking/validate.go b/internal/thinking/validate.go index 799c8005..897a64a3 100644 --- a/internal/thinking/validate.go +++ b/internal/thinking/validate.go @@ -159,27 +159,22 @@ func ValidateConfig(config ThinkingConfig, modelInfo *registry.ModelInfo, provid normalized = convertAutoToMidRange(normalized, support, provider, model) } - // ModeNone handling varies by provider/model capability: - // - Claude can always disable thinking via thinking.type="disabled". - // - Some models/providers cannot be fully disabled; for those we force minimal thinking - // while hiding thoughts (ModeNone + Budget>0 and/or Level set). - if normalized.Mode == ModeNone { - if provider == "claude" { - normalized.Budget = 0 - normalized.Level = "" - } else if !support.ZeroAllowed { - if support.Min > 0 { - normalized.Budget = support.Min - } - if normalized.Level == "" && normalized.Budget > 0 && len(support.Levels) > 0 { - normalized.Level = ThinkingLevel(support.Levels[0]) - } + if normalized.Mode == ModeNone && provider == "claude" { + // Claude supports explicit disable via thinking.type="disabled". + // Keep Budget=0 so applier can omit budget_tokens. + normalized.Budget = 0 + normalized.Level = "" + } else { + switch normalized.Mode { + case ModeBudget, ModeAuto, ModeNone: + normalized.Budget = ClampBudget(normalized.Budget, modelInfo, provider) } - } - switch normalized.Mode { - case ModeBudget, ModeAuto: - normalized.Budget = ClampBudget(normalized.Budget, modelInfo, provider) + // ModeNone with clamped Budget > 0: set Level to lowest for Level-only/Hybrid models + // This ensures Apply layer doesn't need to access support.Levels + if normalized.Mode == ModeNone && normalized.Budget > 0 && len(support.Levels) > 0 { + normalized.Level = ThinkingLevel(support.Levels[0]) + } } return &normalized, nil