openrouter_test.go

  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		gpt5(),
 30	}
 31
 32	for _, model := range models {
 33		for _, provider := range model.providers {
 34			pairs = append(
 35				pairs,
 36				builderPair{
 37					model.name + "_" + provider,
 38					model.builderFunc,
 39					ai.ProviderOptions{
 40						openrouter.Name: &openrouter.ProviderOptions{
 41							Provider: &openrouter.Provider{
 42								Only: []string{provider},
 43							},
 44						},
 45					},
 46				})
 47		}
 48	}
 49
 50	testCommon(t, pairs)
 51}
 52
 53func kimiK2() openrouterModel {
 54	return openrouterModel{
 55		name: "kimi-k2",
 56		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
 57			provider := openrouter.New(
 58				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
 59				openrouter.WithHTTPClient(&http.Client{Transport: r}),
 60			)
 61			return provider.LanguageModel("moonshotai/kimi-k2-0905")
 62		},
 63		providers: []string{
 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}
180
181func gpt5() openrouterModel {
182	return openrouterModel{
183		name: "gpt-5",
184		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
185			provider := openrouter.New(
186				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
187				openrouter.WithHTTPClient(&http.Client{Transport: r}),
188			)
189			return provider.LanguageModel("openai/gpt-5")
190		},
191		providers: []string{
192			"openai",
193			"azure",
194		},
195	}
196}