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	}
 29
 30	for _, model := range models {
 31		for _, provider := range model.providers {
 32			pairs = append(
 33				pairs,
 34				builderPair{
 35					model.name + "_" + provider,
 36					model.builderFunc,
 37					ai.ProviderOptions{
 38						openrouter.Name: &openrouter.ProviderOptions{
 39							Provider: &openrouter.Provider{
 40								Only: []string{provider},
 41							},
 42						},
 43					},
 44				})
 45		}
 46	}
 47
 48	testCommon(t, pairs)
 49}
 50
 51func kimiK2() openrouterModel {
 52	return openrouterModel{
 53		name: "kimi-k2",
 54		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
 55			provider := openrouter.New(
 56				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
 57				openrouter.WithHTTPClient(&http.Client{Transport: r}),
 58			)
 59			return provider.LanguageModel("moonshotai/kimi-k2-0905")
 60		},
 61		providers: []string{
 62			"chutes",
 63			"deepinfra",
 64			"siliconflow",
 65			"fireworks",
 66			"moonshotai",
 67			"novita",
 68			"baseten",
 69			"together",
 70			"groq",
 71			"moonshotai/turbo",
 72			"wandb",
 73		},
 74	}
 75}
 76
 77func grokCodeFast1() openrouterModel {
 78	return openrouterModel{
 79		name: "grok-code-fast-1",
 80		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
 81			provider := openrouter.New(
 82				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
 83				openrouter.WithHTTPClient(&http.Client{Transport: r}),
 84			)
 85			return provider.LanguageModel("x-ai/grok-code-fast-1")
 86		},
 87		providers: []string{
 88			"xai",
 89		},
 90	}
 91}
 92
 93func grok4FastFree() openrouterModel {
 94	return openrouterModel{
 95		name: "grok-4-fast-free",
 96		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
 97			provider := openrouter.New(
 98				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
 99				openrouter.WithHTTPClient(&http.Client{Transport: r}),
100			)
101			return provider.LanguageModel("x-ai/grok-4-fast:free")
102		},
103		providers: []string{
104			"xai",
105		},
106	}
107}
108
109func gemini25Flash() openrouterModel {
110	return openrouterModel{
111		name: "gemini-2.5-flash",
112		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
113			provider := openrouter.New(
114				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
115				openrouter.WithHTTPClient(&http.Client{Transport: r}),
116			)
117			return provider.LanguageModel("google/gemini-2.5-flash")
118		},
119		providers: []string{
120			"google-vertex/global",
121			"google-ai-studio",
122			"google-vertex",
123		},
124	}
125}
126
127func gemini20Flash() openrouterModel {
128	return openrouterModel{
129		name: "gemini-2.0-flash",
130		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
131			provider := openrouter.New(
132				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
133				openrouter.WithHTTPClient(&http.Client{Transport: r}),
134			)
135			return provider.LanguageModel("google/gemini-2.0-flash-001")
136		},
137		providers: []string{
138			"google-ai-studio",
139			"google-vertex",
140		},
141	}
142}
143
144func claudeSonnet4() openrouterModel {
145	return openrouterModel{
146		name: "claude-sonnet-4",
147		builderFunc: func(r *recorder.Recorder) (ai.LanguageModel, error) {
148			provider := openrouter.New(
149				openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY")),
150				openrouter.WithHTTPClient(&http.Client{Transport: r}),
151			)
152			return provider.LanguageModel("anthropic/claude-sonnet-4")
153		},
154		providers: []string{
155			"google-vertex",
156			"google-vertex/global",
157			"anthropic",
158			"google-vertex/europe",
159			"amazon-bedrock",
160		},
161	}
162}