1package providertests
2
3import (
4 "net/http"
5 "os"
6 "testing"
7
8 "charm.land/fantasy"
9 "charm.land/fantasy/openai"
10 "github.com/stretchr/testify/require"
11 "gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
12)
13
14func TestOpenAIResponsesCommon(t *testing.T) {
15 var pairs []builderPair
16 for _, m := range openaiTestModels {
17 pairs = append(pairs, builderPair{m.name, openAIReasoningBuilder(m.model), nil})
18 }
19 testCommon(t, pairs)
20}
21
22func openAIReasoningBuilder(model string) builderFunc {
23 return func(r *recorder.Recorder) (fantasy.LanguageModel, error) {
24 provider := openai.New(
25 openai.WithAPIKey(os.Getenv("FANTASY_OPENAI_API_KEY")),
26 openai.WithHTTPClient(&http.Client{Transport: r}),
27 openai.WithUseResponsesAPI(),
28 )
29 return provider.LanguageModel(model)
30 }
31}
32
33func TestOpenAIResponsesWithSummaryThinking(t *testing.T) {
34 opts := fantasy.ProviderOptions{
35 openai.Name: &openai.ResponsesProviderOptions{
36 Include: []openai.IncludeType{
37 openai.IncludeReasoningEncryptedContent,
38 },
39 ReasoningEffort: openai.ReasoningEffortOption(openai.ReasoningEffortHigh),
40 ReasoningSummary: fantasy.Opt("auto"),
41 },
42 }
43 var pairs []builderPair
44 for _, m := range openaiTestModels {
45 if !m.reasoning {
46 continue
47 }
48 pairs = append(pairs, builderPair{m.name, openAIReasoningBuilder(m.model), opts})
49 }
50 testThinking(t, pairs, testOpenAIResponsesThinkingWithSummaryThinking)
51}
52
53func testOpenAIResponsesThinkingWithSummaryThinking(t *testing.T, result *fantasy.AgentResult) {
54 reasoningContentCount := 0
55 encryptedData := 0
56 // Test if we got the signature
57 for _, step := range result.Steps {
58 for _, msg := range step.Messages {
59 for _, content := range msg.Content {
60 if content.GetType() == fantasy.ContentTypeReasoning {
61 reasoningContentCount += 1
62 reasoningContent, ok := fantasy.AsContentType[fantasy.ReasoningPart](content)
63 if !ok {
64 continue
65 }
66 if len(reasoningContent.ProviderOptions) == 0 {
67 continue
68 }
69
70 openaiReasoningMetadata, ok := reasoningContent.ProviderOptions[openai.Name]
71 if !ok {
72 continue
73 }
74 if typed, ok := openaiReasoningMetadata.(*openai.ResponsesReasoningMetadata); ok {
75 require.NotEmpty(t, typed.EncryptedContent)
76 encryptedData += 1
77 }
78 }
79 }
80 }
81 }
82 require.Greater(t, reasoningContentCount, 0)
83 require.Greater(t, encryptedData, 0)
84 require.Equal(t, reasoningContentCount, encryptedData)
85}