1package provider
2
3import (
4 "context"
5 "net/http"
6 "net/http/httptest"
7 "testing"
8)
9
10// TestDiscoverOpenRouterPrefersServedContextLength verifies the
11// discovery fix: OpenRouter reports an inflated model-level
12// context_length (the model's theoretical max) alongside the serving
13// provider's real top_provider.context_length. When the served limit is
14// smaller, discovery must use it, because that's the limit OpenRouter
15// actually enforces. Using the inflated value made every context-window
16// check useless and let max_tokens exceed the real ceiling.
17func TestDiscoverOpenRouterPrefersServedContextLength(t *testing.T) {
18 const body = `{"data":[
19 {"id":"infl","name":"Inflated","context_length":1000000,
20 "top_provider":{"context_length":262144}},
21 {"id":"served-bigger","name":"ServedBigger","context_length":131072,
22 "top_provider":{"context_length":262144}},
23 {"id":"no-top","name":"NoTop","context_length":128000,
24 "top_provider":{"context_length":0}}
25 ]}`
26 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
27 w.Header().Set("Content-Type", "application/json")
28 _, _ = w.Write([]byte(body))
29 }))
30 defer srv.Close()
31
32 models, err := DiscoverOpenRouter(context.Background(), srv.URL)
33 if err != nil {
34 t.Fatal(err)
35 }
36 byID := map[string]Model{}
37 for _, m := range models {
38 byID[m.ID] = m
39 }
40
41 // Inflated model-level window: use the smaller served limit.
42 if got := byID["infl"].ContextWindow; got != 262144 {
43 t.Errorf("inflated model ContextWindow = %d; want 262144 (served limit)", got)
44 }
45 // Served limit larger than model-level: keep the smaller model value.
46 if got := byID["served-bigger"].ContextWindow; got != 131072 {
47 t.Errorf("served-bigger ContextWindow = %d; want 131072 (model value, the smaller one)", got)
48 }
49 // No served limit: fall back to the model-level value.
50 if got := byID["no-top"].ContextWindow; got != 128000 {
51 t.Errorf("no-top ContextWindow = %d; want 128000 (model value, no top_provider)", got)
52 }
53}
54
55func TestDiscoverOpenRouterPresets(t *testing.T) {
56 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
57 if r.URL.Path != "/presets" {
58 http.NotFound(w, r)
59 return
60 }
61 if got := r.Header.Get("Authorization"); got != "Bearer test-key" {
62 t.Errorf("Authorization = %q; want Bearer test-key", got)
63 }
64 w.Header().Set("Content-Type", "application/json")
65 _, _ = w.Write([]byte(`{"data":[
66 {"name":"Flash","slug":"flash","status":"active"},
67 {"name":"Old","slug":"old","status":"archived"},
68 {"name":"Off","slug":"off","status":"disabled"},
69 {"name":"NoSlug","slug":"","status":"active"}
70 ],"total_count":4}`))
71 }))
72 defer srv.Close()
73
74 models, err := DiscoverOpenRouterPresets(context.Background(), "test-key", srv.URL)
75 if err != nil {
76 t.Fatal(err)
77 }
78 if len(models) != 1 {
79 t.Fatalf("got %d presets; want 1 active", len(models))
80 }
81 m := models[0]
82 if m.Provider != "openrouter" || m.ID != "@preset/flash" {
83 t.Errorf("preset = %+v; want openrouter @preset/flash", m)
84 }
85 if m.DisplayName != "Flash (preset)" {
86 t.Errorf("DisplayName = %q", m.DisplayName)
87 }
88 if m.ContextWindow != 0 || m.MaxOutput != 0 || m.Reasoning {
89 t.Errorf("preset has invented capabilities: %+v", m)
90 }
91}