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	}
 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}