| 1 | package config |
| 2 | |
| 3 | import ( |
| 4 | "os" |
| 5 | "path/filepath" |
| 6 | "testing" |
| 7 | ) |
| 8 | |
| 9 | func loadSingleProvider(t *testing.T, providerBody string) *ProviderEntry { |
| 10 | t.Helper() |
| 11 | dir := t.TempDir() |
| 12 | body := "default_model = \"relay\"\n\n[[providers]]\nname = \"relay\"\nkind = \"openai\"\nmodels = [\"a\", \"b\"]\ndefault = \"a\"\n" + providerBody + "\n" |
| 13 | if err := os.WriteFile(filepath.Join(dir, "reasonix.toml"), []byte(body), 0o644); err != nil { |
| 14 | t.Fatalf("write config: %v", err) |
| 15 | } |
| 16 | c, err := LoadForRootReadOnly(dir) |
| 17 | if err != nil { |
| 18 | t.Fatalf("load config: %v", err) |
| 19 | } |
| 20 | e, ok := c.ResolveModel("relay/a") |
| 21 | if !ok { |
| 22 | t.Fatal("ResolveModel did not resolve relay/a") |
| 23 | } |
| 24 | return e |
| 25 | } |
| 26 | |
| 27 | // normalizedModelOverrides drops overrides it judges empty. Its emptiness test |
| 28 | // omitted MaxOutputTokens, so an override carrying only max_output_tokens was |
| 29 | // discarded at load and the documented key silently did nothing. |
| 30 | func TestMaxOutputTokensOnlyOverrideSurvivesLoad(t *testing.T) { |
| 31 | e := loadSingleProvider(t, `model_overrides = { "a" = { max_output_tokens = 32768 } }`) |
| 32 | if e.MaxOutputTokens != 32768 { |
| 33 | t.Fatalf("MaxOutputTokens = %d, want 32768 from the model override", e.MaxOutputTokens) |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | // A negative value is the documented way to force-omit optional wire limits, so |
| 38 | // it must survive the same pass rather than reading as an unset field. |
| 39 | func TestNegativeMaxOutputTokensOnlyOverrideSurvivesLoad(t *testing.T) { |
| 40 | e := loadSingleProvider(t, `model_overrides = { "a" = { max_output_tokens = -1 } }`) |
| 41 | if e.MaxOutputTokens != -1 { |
| 42 | t.Fatalf("MaxOutputTokens = %d, want -1 from the model override", e.MaxOutputTokens) |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | // An override with nothing set is still dropped, and an override aimed at a |
| 47 | // different model must not leak onto the resolved one. |
| 48 | func TestEmptyAndForeignModelOverridesStayInert(t *testing.T) { |
| 49 | e := loadSingleProvider(t, `model_overrides = { "a" = { }, "b" = { max_output_tokens = 4096 } }`) |
| 50 | if len(e.ModelOverrides) != 1 { |
| 51 | t.Fatalf("ModelOverrides = %+v, want only the non-empty entry for b", e.ModelOverrides) |
| 52 | } |
| 53 | if e.MaxOutputTokens == 4096 { |
| 54 | t.Fatal("an override for model b was applied to model a") |
| 55 | } |
| 56 | } |
| 57 |