1package providertests
2
3import (
4 "net/http"
5 "os"
6 "testing"
7
8 "github.com/charmbracelet/fantasy/ai"
9 "github.com/charmbracelet/fantasy/openrouter"
10 "gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
11)
12
13type openrouterModel struct {
14 name string
15 builderFunc builderFunc
16 providers []string
17}
18
19func TestOpenRouterCommon(t *testing.T) {
20 var pairs []builderPair
21 models := []openrouterModel{
22 kimiK2(),
23 grokCodeFast1(),
24 claudeSonnet4(),
25 grok4FastFree(),
26 gemini25Flash(),
27 gemini20Flash(),
28 deepseekV31Free(),
29 }
30
31 for _, model := range models {
32 for _, provider := range model.providers {
33 pairs = append(
34 pairs,
35 builderPair{
36 model.name + "_" + provider,
37 model.builderFunc,
38 ai.ProviderOptions{
39 openrouter.Name: &openrouter.ProviderOptions{
40 Provider: &openrouter.Provider{
41 Only: []string{provider},
42 },
43 },
44 },
45 })
46 }
47 }
48
49 testCommon(t, pairs)
50}
51
52func kimiK2() openrouterModel {
53 return openrouterModel{
54 name: "kimi-k2",
55 builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
56 provider := openrouter.New(
57 openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
58 openrouter.WithHTTPClient(&http.Client{Transport: r}),
59 )
60 return provider.LanguageModel("moonshotai/kimi-k2-0905")
61 },
62 providers: []string{
63 "chutes",
64 "deepinfra",
65 "siliconflow",
66 "fireworks",
67 "moonshotai",
68 "novita",
69 "baseten",
70 "together",
71 "groq",
72 "moonshotai/turbo",
73 "wandb",
74 },
75 }
76}
77
78func grokCodeFast1() openrouterModel {
79 return openrouterModel{
80 name: "grok-code-fast-1",
81 builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
82 provider := openrouter.New(
83 openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
84 openrouter.WithHTTPClient(&http.Client{Transport: r}),
85 )
86 return provider.LanguageModel("x-ai/grok-code-fast-1")
87 },
88 providers: []string{
89 "xai",
90 },
91 }
92}
93
94func grok4FastFree() openrouterModel {
95 return openrouterModel{
96 name: "grok-4-fast-free",
97 builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
98 provider := openrouter.New(
99 openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
100 openrouter.WithHTTPClient(&http.Client{Transport: r}),
101 )
102 return provider.LanguageModel("x-ai/grok-4-fast:free")
103 },
104 providers: []string{
105 "xai",
106 },
107 }
108}
109
110func gemini25Flash() openrouterModel {
111 return openrouterModel{
112 name: "gemini-2.5-flash",
113 builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
114 provider := openrouter.New(
115 openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
116 openrouter.WithHTTPClient(&http.Client{Transport: r}),
117 )
118 return provider.LanguageModel("google/gemini-2.5-flash")
119 },
120 providers: []string{
121 "google-vertex/global",
122 "google-ai-studio",
123 "google-vertex",
124 },
125 }
126}
127
128func gemini20Flash() openrouterModel {
129 return openrouterModel{
130 name: "gemini-2.0-flash",
131 builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
132 provider := openrouter.New(
133 openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
134 openrouter.WithHTTPClient(&http.Client{Transport: r}),
135 )
136 return provider.LanguageModel("google/gemini-2.0-flash-001")
137 },
138 providers: []string{
139 "google-ai-studio",
140 "google-vertex",
141 },
142 }
143}
144
145func deepseekV31Free() openrouterModel {
146 return openrouterModel{
147 name: "deepseek-chat-v3.1-free",
148 builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
149 provider := openrouter.New(
150 openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
151 openrouter.WithHTTPClient(&http.Client{Transport: r}),
152 )
153 return provider.LanguageModel("deepseek/deepseek-chat-v3.1:free")
154 },
155 providers: []string{
156 "deepinfra",
157 },
158 }
159}
160
161func claudeSonnet4() openrouterModel {
162 return openrouterModel{
163 name: "claude-sonnet-4",
164 builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
165 provider := openrouter.New(
166 openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
167 openrouter.WithHTTPClient(&http.Client{Transport: r}),
168 )
169 return provider.LanguageModel("anthropic/claude-sonnet-4")
170 },
171 providers: []string{
172 "google-vertex",
173 "google-vertex/global",
174 "anthropic",
175 "google-vertex/europe",
176 "amazon-bedrock",
177 },
178 }
179}