Skip to content

Commit 9aed64e

Browse files
authored
Merge pull request #2142 from dgageot/reject-unknown-budgets
Reject unknown thinking_budget effort levels at parse time
2 parents a5e4548 + 4f6b1ab commit 9aed64e

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

pkg/config/latest/types.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,20 @@ type ThinkingBudget struct {
683683
Tokens int `json:"tokens,omitempty"`
684684
}
685685

686+
// validThinkingEfforts lists all accepted string values for thinking_budget.
687+
const validThinkingEfforts = "none, minimal, low, medium, high, max, adaptive"
688+
689+
// isValidThinkingEffort reports whether s (case-insensitive, trimmed) is a
690+
// recognised thinking_budget effort level.
691+
func isValidThinkingEffort(s string) bool {
692+
switch strings.ToLower(strings.TrimSpace(s)) {
693+
case "none", "minimal", "low", "medium", "high", "max", "adaptive":
694+
return true
695+
default:
696+
return false
697+
}
698+
}
699+
686700
func (t *ThinkingBudget) UnmarshalYAML(unmarshal func(any) error) error {
687701
// Try integer tokens first
688702
var n int
@@ -694,6 +708,9 @@ func (t *ThinkingBudget) UnmarshalYAML(unmarshal func(any) error) error {
694708
// Try string level
695709
var s string
696710
if err := unmarshal(&s); err == nil {
711+
if !isValidThinkingEffort(s) {
712+
return fmt.Errorf("invalid thinking_budget effort %q: must be one of %s", s, validThinkingEfforts)
713+
}
697714
*t = ThinkingBudget{Effort: s}
698715
return nil
699716
}
@@ -793,6 +810,9 @@ func (t *ThinkingBudget) UnmarshalJSON(data []byte) error {
793810
// Try string level
794811
var s string
795812
if err := json.Unmarshal(data, &s); err == nil {
813+
if !isValidThinkingEffort(s) {
814+
return fmt.Errorf("invalid thinking_budget effort %q: must be one of %s", s, validThinkingEfforts)
815+
}
796816
*t = ThinkingBudget{Effort: s}
797817
return nil
798818
}

pkg/config/latest/types_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package latest
22

33
import (
4+
"encoding/json"
45
"testing"
56

67
"github.com/goccy/go-yaml"
@@ -144,6 +145,32 @@ func TestThinkingBudget_IsDisabled(t *testing.T) {
144145
}
145146
}
146147

148+
func TestThinkingBudget_UnmarshalYAML_InvalidEffort(t *testing.T) {
149+
t.Parallel()
150+
151+
input := []byte(`thinking_budget: adaptative`)
152+
var config struct {
153+
ThinkingBudget *ThinkingBudget `yaml:"thinking_budget"`
154+
}
155+
156+
err := yaml.Unmarshal(input, &config)
157+
require.Error(t, err)
158+
require.Contains(t, err.Error(), `invalid thinking_budget effort "adaptative"`)
159+
}
160+
161+
func TestThinkingBudget_UnmarshalJSON_InvalidEffort(t *testing.T) {
162+
t.Parallel()
163+
164+
data := []byte(`{"thinking_budget": "adaptative"}`)
165+
var config struct {
166+
ThinkingBudget *ThinkingBudget `json:"thinking_budget"`
167+
}
168+
169+
err := json.Unmarshal(data, &config)
170+
require.Error(t, err)
171+
require.Contains(t, err.Error(), `invalid thinking_budget effort "adaptative"`)
172+
}
173+
147174
func TestThinkingBudget_IsAdaptive(t *testing.T) {
148175
t.Parallel()
149176

0 commit comments

Comments
 (0)