anthropic_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/anthropic"
10	"github.com/stretchr/testify/require"
11	"gopkg.in/dnaeon/go-vcr.v4/pkg/recorder"
12)
13
14func TestAnthropicCommon(t *testing.T) {
15	testCommon(t, []builderPair{
16		{"claude-sonnet-4", builderAnthropicClaudeSonnet4, nil},
17	})
18
19	opts := ai.ProviderOptions{
20		anthropic.Name: &anthropic.ProviderOptions{
21			Thinking: &anthropic.ThinkingProviderOption{
22				BudgetTokens: 4000,
23			},
24		},
25	}
26	testThinking(t, []builderPair{
27		{"claude-sonnet-4", builderAnthropicClaudeSonnet4, opts},
28	}, testGoogleThinking)
29}
30
31func testAnthropicThinking(t *testing.T, result *ai.AgentResult) {
32	reasoningContentCount := 0
33	signaturesCount := 0
34	// Test if we got the signature
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					reasoningContent, ok := ai.AsContentType[ai.ReasoningPart](content)
41					if !ok {
42						continue
43					}
44					if len(reasoningContent.ProviderOptions) == 0 {
45						continue
46					}
47
48					anthropicReasoningMetadata, ok := reasoningContent.ProviderOptions[anthropic.Name]
49					if !ok {
50						continue
51					}
52					if reasoningContent.Text != "" {
53						if typed, ok := anthropicReasoningMetadata.(*anthropic.ReasoningOptionMetadata); ok {
54							require.NotEmpty(t, typed.Signature)
55							signaturesCount += 1
56						}
57					}
58				}
59			}
60		}
61	}
62	require.Greater(t, reasoningContentCount, 0)
63	require.Greater(t, signaturesCount, 0)
64	require.Equal(t, reasoningContentCount, signaturesCount)
65}
66
67func builderAnthropicClaudeSonnet4(r *recorder.Recorder) (ai.LanguageModel, error) {
68	provider := anthropic.New(
69		anthropic.WithAPIKey(os.Getenv("ANTHROPIC_API_KEY")),
70		anthropic.WithHTTPClient(&http.Client{Transport: r}),
71	)
72	return provider.LanguageModel("claude-sonnet-4-20250514")
73}