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		openrouterKimiK2(),
 23		openrouterGrokCodeFast1(),
 24		openrouterClaudeSonnet4(),
 25		openrouterGrok4FastFree(),
 26		openrouterGemini25Flash(),
 27		openrouterGemini20Flash(),
 28		openrouterDeepseekV31Free(),
 29		openrouterGpt5(),
 30	}
 31
 32	for _, model := range models {
 33		// add one entry for multi provider tests
 34		pairs = append(
 35			pairs,
 36			builderPair{
 37				model.name,
 38				model.builderFunc,
 39				nil,
 40			})
 41		for _, provider := range model.providers {
 42			pairs = append(
 43				pairs,
 44				builderPair{
 45					model.name + "_" + provider,
 46					model.builderFunc,
 47					ai.ProviderOptions{
 48						openrouter.Name: &openrouter.ProviderOptions{
 49							Provider: &openrouter.Provider{
 50								Only: []string{provider},
 51							},
 52						},
 53					},
 54				})
 55		}
 56	}
 57
 58	testCommon(t, pairs)
 59}
 60
 61func openrouterKimiK2() openrouterModel {
 62	return openrouterModel{
 63		name: "kimi-k2",
 64		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
 65			provider := openrouter.New(
 66				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
 67				openrouter.WithHTTPClient(&http.Client{Transport: r}),
 68			)
 69			return provider.LanguageModel("moonshotai/kimi-k2-0905")
 70		},
 71		providers: []string{
 72			"deepinfra",
 73			"siliconflow",
 74			"fireworks",
 75			"moonshotai",
 76			"novita",
 77			"baseten",
 78			"together",
 79			"groq",
 80			"moonshotai/turbo",
 81			"wandb",
 82		},
 83	}
 84}
 85
 86func openrouterGrokCodeFast1() openrouterModel {
 87	return openrouterModel{
 88		name: "grok-code-fast-1",
 89		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
 90			provider := openrouter.New(
 91				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
 92				openrouter.WithHTTPClient(&http.Client{Transport: r}),
 93			)
 94			return provider.LanguageModel("x-ai/grok-code-fast-1")
 95		},
 96		providers: []string{
 97			"xai",
 98		},
 99	}
100}
101
102func openrouterGrok4FastFree() openrouterModel {
103	return openrouterModel{
104		name: "grok-4-fast-free",
105		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
106			provider := openrouter.New(
107				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
108				openrouter.WithHTTPClient(&http.Client{Transport: r}),
109			)
110			return provider.LanguageModel("x-ai/grok-4-fast:free")
111		},
112		providers: []string{
113			"xai",
114		},
115	}
116}
117
118func openrouterGemini25Flash() openrouterModel {
119	return openrouterModel{
120		name: "gemini-2.5-flash",
121		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
122			provider := openrouter.New(
123				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
124				openrouter.WithHTTPClient(&http.Client{Transport: r}),
125			)
126			return provider.LanguageModel("google/gemini-2.5-flash")
127		},
128		providers: []string{
129			"google-vertex/global",
130			"google-ai-studio",
131			"google-vertex",
132		},
133	}
134}
135
136func openrouterGemini20Flash() openrouterModel {
137	return openrouterModel{
138		name: "gemini-2.0-flash",
139		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
140			provider := openrouter.New(
141				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
142				openrouter.WithHTTPClient(&http.Client{Transport: r}),
143			)
144			return provider.LanguageModel("google/gemini-2.0-flash-001")
145		},
146		providers: []string{
147			"google-ai-studio",
148			"google-vertex",
149		},
150	}
151}
152
153func openrouterDeepseekV31Free() openrouterModel {
154	return openrouterModel{
155		name: "deepseek-chat-v3.1-free",
156		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
157			provider := openrouter.New(
158				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
159				openrouter.WithHTTPClient(&http.Client{Transport: r}),
160			)
161			return provider.LanguageModel("deepseek/deepseek-chat-v3.1:free")
162		},
163		providers: []string{
164			"deepinfra",
165		},
166	}
167}
168
169func openrouterClaudeSonnet4() openrouterModel {
170	return openrouterModel{
171		name: "claude-sonnet-4",
172		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
173			provider := openrouter.New(
174				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
175				openrouter.WithHTTPClient(&http.Client{Transport: r}),
176			)
177			return provider.LanguageModel("anthropic/claude-sonnet-4")
178		},
179		providers: []string{
180			"google-vertex",
181			"google-vertex/global",
182			"anthropic",
183			"google-vertex/europe",
184			"amazon-bedrock",
185		},
186	}
187}
188
189func openrouterGpt5() openrouterModel {
190	return openrouterModel{
191		name: "gpt-5",
192		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
193			provider := openrouter.New(
194				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
195				openrouter.WithHTTPClient(&http.Client{Transport: r}),
196			)
197			return provider.LanguageModel("openai/gpt-5")
198		},
199		providers: []string{
200			"openai",
201			"azure",
202		},
203	}
204}