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