1package provider
2
3import (
4 "slices"
5 "testing"
6)
7
8func TestOpus55CatalogAndThinking(t *testing.T) {
9 copilot := NewGithubCopilotClient("synthetic-token").(*copilotClient)
10 for _, tc := range []struct {
11 provider, id string
12 client *anthropicClient
13 }{
14 {"anthropic", "claude-opus-5-5", NewAnthropic("synthetic-key", "").(*anthropicClient)},
15 {"anthropic", "claude-opus-5-5", NewAnthropicOAuth("synthetic-token", "").(*anthropicClient)},
16 {"github-copilot", "claude-opus-5.5", copilot.router.byAPI[APIAnthropicMessages].(*anthropicClient)},
17 } {
18 t.Run(tc.provider, func(t *testing.T) {
19 m, err := FindModel(tc.provider, tc.id)
20 if err != nil {
21 t.Fatal(err)
22 }
23 if m.ContextWindow != 1000000 || m.MaxOutput != 128000 || !m.Reasoning || !m.AdaptiveThinking || m.Speculative {
24 t.Fatalf("unexpected capabilities: %+v", m)
25 }
26 if m.PriceInput != 4 || m.PriceOutput != 20 || m.PriceCacheRead != 0.2 || m.PriceCacheWrite != 5 {
27 t.Fatalf("unexpected pricing: %+v", m)
28 }
29 want := []string{"low", "medium", "high", "xhigh", "max"}
30 if got := AvailableReasoningLevels(m); !slices.Equal(got, want) {
31 t.Fatalf("levels = %q, want %q", got, want)
32 }
33 for _, level := range []string{"", "off", "minimum", "low", "medium", "high", "xhigh", "max"} {
34 effort := level
35 if level == "" || level == "off" || level == "minimum" {
36 effort = "low"
37 }
38 if got := ClampReasoningForModel(m, level); got != effort {
39 t.Errorf("clamp(%q) = %q, want %q", level, got, effort)
40 }
41 temperature := float32(0.5)
42 wire, err := tc.client.buildRequest(Request{Model: tc.id, Reasoning: level, Temperature: &temperature})
43 if err != nil {
44 t.Fatal(err)
45 }
46 if wire.Model != tc.id || wire.MaxTokens != 128000 || wire.Temperature != nil {
47 t.Fatalf("unexpected request: %+v", wire)
48 }
49 if wire.Thinking == nil || wire.Thinking.Type != "adaptive" || wire.Thinking.BudgetTokens != 0 {
50 t.Fatalf("thinking = %+v", wire.Thinking)
51 }
52 if wire.OutputConfig == nil || wire.OutputConfig.Effort != effort {
53 t.Fatalf("output config = %+v, want effort %q", wire.OutputConfig, effort)
54 }
55 }
56 })
57 }
58}
59
60func TestOpus55ReasoningOverrides(t *testing.T) {
61 m, err := FindModel("anthropic", "claude-opus-5-5")
62 if err != nil {
63 t.Fatal(err)
64 }
65 m.ReasoningLevelMap = map[string]string{"max": "xhigh"}
66 want := []string{"low", "medium", "high", "xhigh"}
67 if got := AvailableReasoningLevels(m); !slices.Equal(got, want) {
68 t.Fatalf("levels = %q, want %q", got, want)
69 }
70 if got := ClampReasoningForModel(m, "off"); got != "low" {
71 t.Fatalf("off clamped to %q, want low", got)
72 }
73}