1package providertests
2
3import (
4 "net/http"
5 "os"
6 "testing"
7
8 "github.com/charmbracelet/fantasy/ai"
9 "github.com/charmbracelet/fantasy/openai"
10 "github.com/charmbracelet/fantasy/openaicompat"
11 "github.com/stretchr/testify/require"
12 "gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
13)
14
15func TestOpenAICompatibleCommon(t *testing.T) {
16 testCommon(t, []builderPair{
17 {"xai-grok-4-fast", builderXAIGrok4Fast, nil},
18 {"xai-grok-code-fast", builderXAIGrokCodeFast, nil},
19 {"groq-kimi-k2", builderGroq, nil},
20 {"zai-glm-4.5", builderZAIGLM45, nil},
21 })
22 opts := ai.ProviderOptions{
23 openaicompat.Name: &openaicompat.ProviderOptions{
24 ReasoningEffort: openai.ReasoningEffortOption(openai.ReasoningEffortHigh),
25 },
26 }
27 testThinking(t, []builderPair{
28 {"xai-grok-3-mini", builderXAIGrok3Mini, opts},
29 {"zai-glm-4.5", builderZAIGLM45, opts},
30 }, testOpenAICompatThinking)
31}
32
33func testOpenAICompatThinking(t *testing.T, result *ai.AgentResult) {
34 reasoningContentCount := 0
35 for _, step := range result.Steps {
36 for _, msg := range step.Messages {
37 for _, content := range msg.Content {
38 if content.GetType() == ai.ContentTypeReasoning {
39 reasoningContentCount += 1
40 }
41 }
42 }
43 }
44 require.Greater(t, reasoningContentCount, 0)
45}
46
47func builderXAIGrokCodeFast(r *recorder.Recorder) (ai.LanguageModel, error) {
48 provider := openaicompat.New(
49 "https://api.x.ai/v1",
50 openaicompat.WithAPIKey(os.Getenv("XAI_API_KEY")),
51 openaicompat.WithHTTPClient(&http.Client{Transport: r}),
52 )
53 return provider.LanguageModel("grok-code-fast-1")
54}
55
56func builderXAIGrok4Fast(r *recorder.Recorder) (ai.LanguageModel, error) {
57 provider := openaicompat.New(
58 "https://api.x.ai/v1",
59 openaicompat.WithAPIKey(os.Getenv("XAI_API_KEY")),
60 openaicompat.WithHTTPClient(&http.Client{Transport: r}),
61 )
62 return provider.LanguageModel("grok-4-fast")
63}
64
65func builderXAIGrok3Mini(r *recorder.Recorder) (ai.LanguageModel, error) {
66 provider := openaicompat.New(
67 "https://api.x.ai/v1",
68 openaicompat.WithAPIKey(os.Getenv("XAI_API_KEY")),
69 openaicompat.WithHTTPClient(&http.Client{Transport: r}),
70 )
71 return provider.LanguageModel("grok-3-mini")
72}
73
74func builderZAIGLM45(r *recorder.Recorder) (ai.LanguageModel, error) {
75 provider := openaicompat.New(
76 "https://api.z.ai/api/coding/paas/v4",
77 openaicompat.WithAPIKey(os.Getenv("ZAI_API_KEY")),
78 openaicompat.WithHTTPClient(&http.Client{Transport: r}),
79 )
80 return provider.LanguageModel("glm-4.5")
81}
82
83func builderGroq(r *recorder.Recorder) (ai.LanguageModel, error) {
84 provider := openaicompat.New(
85 "https://api.groq.com/openai/v1",
86 openaicompat.WithAPIKey(os.Getenv("GROQ_API_KEY")),
87 openaicompat.WithHTTPClient(&http.Client{Transport: r}),
88 )
89 return provider.LanguageModel("moonshotai/kimi-k2-instruct-0905")
90}