@@ -7,6 +7,8 @@ import (
77
88 "charm.land/catwalk/pkg/catwalk"
99 "charm.land/fantasy"
10+ "charm.land/fantasy/providers/anthropic"
11+ "charm.land/fantasy/providers/bedrock"
1012 "github.com/charmbracelet/crush/internal/config"
1113 "github.com/stretchr/testify/assert"
1214 "github.com/stretchr/testify/require"
@@ -383,3 +385,36 @@ func TestUpdateParentSessionCost(t *testing.T) {
383385 assert.InDelta(t, 0.0, updated.Cost, 1e-9)
384386 })
385387}
388+
389+func TestGetProviderOptionsReasoningEffort(t *testing.T) {
390+ // Bedrock is Fantasy's Anthropic under a different provider name; options
391+ // must land under anthropic.Name so the Anthropic language model picks them up.
392+ tests := []struct {
393+ name string
394+ providerType catwalk.Type
395+ }{
396+ {"anthropic honors reasoning_effort", catwalk.Type(anthropic.Name)},
397+ {"bedrock honors reasoning_effort", catwalk.Type(bedrock.Name)},
398+ }
399+ for _, tc := range tests {
400+ t.Run(tc.name, func(t *testing.T) {
401+ model := Model{
402+ CatwalkCfg: catwalk.Model{ID: "claude-opus-4-7"},
403+ ModelCfg: config.SelectedModel{
404+ Provider: "test",
405+ ReasoningEffort: "max",
406+ },
407+ }
408+ providerCfg := config.ProviderConfig{ID: "test", Type: tc.providerType}
409+
410+ opts := getProviderOptions(model, providerCfg)
411+
412+ raw, ok := opts[anthropic.Name]
413+ require.True(t, ok, "options should be keyed under anthropic.Name for type %q", tc.providerType)
414+ parsed, ok := raw.(*anthropic.ProviderOptions)
415+ require.True(t, ok)
416+ require.NotNil(t, parsed.Effort)
417+ assert.Equal(t, anthropic.Effort("max"), *parsed.Effort)
418+ })
419+ }
420+}