diff --git a/dto/gemini.go b/dto/gemini.go index d7e598db3..fa869b6d1 100644 --- a/dto/gemini.go +++ b/dto/gemini.go @@ -142,7 +142,38 @@ type GeminiThinkingConfig struct { IncludeThoughts bool `json:"includeThoughts,omitempty"` ThinkingBudget *int `json:"thinkingBudget,omitempty"` // TODO Conflict with thinkingbudget. - // ThinkingLevel json.RawMessage `json:"thinkingLevel,omitempty"` + ThinkingLevel json.RawMessage `json:"thinkingLevel,omitempty"` +} + +// UnmarshalJSON allows GeminiThinkingConfig to accept both snake_case and camelCase fields. +func (c *GeminiThinkingConfig) UnmarshalJSON(data []byte) error { + type Alias GeminiThinkingConfig + var aux struct { + Alias + IncludeThoughtsSnake *bool `json:"include_thoughts,omitempty"` + ThinkingBudgetSnake *int `json:"thinking_budget,omitempty"` + ThinkingLevelSnake json.RawMessage `json:"thinking_level,omitempty"` + } + + if err := common.Unmarshal(data, &aux); err != nil { + return err + } + + *c = GeminiThinkingConfig(aux.Alias) + + if aux.IncludeThoughtsSnake != nil { + c.IncludeThoughts = *aux.IncludeThoughtsSnake + } + + if aux.ThinkingBudgetSnake != nil { + c.ThinkingBudget = aux.ThinkingBudgetSnake + } + + if len(aux.ThinkingLevelSnake) > 0 { + c.ThinkingLevel = aux.ThinkingLevelSnake + } + + return nil } func (c *GeminiThinkingConfig) SetThinkingBudget(budget int) {