fix: omit Anthropic sampling params for Claude Opus 4.7

## CHANGES

- Add Opus 4.7 sampling parameter guard
- Omit temperature and top_p for incompatible models
- Preserve existing TopP and temperature selection behavior
- Cover Opus 4.7 omission with unit test
This commit is contained in:
Kayvan Sylvan 2026-05-04 14:48:35 -07:00
parent 8a3058e2b8
commit d2995ee02e
2 changed files with 33 additions and 3 deletions

View file

@ -24,6 +24,12 @@ const webSearchToolName = "web_search"
const webSearchToolType = "web_search_20250305"
const sourcesHeader = "## Sources"
func modelDisallowsSamplingParams(model string) bool {
// Anthropic's Opus 4.7 models reject non-default sampling parameters.
// Omit these params entirely for safest compatibility.
return strings.HasPrefix(model, "claude-opus-4-7")
}
func NewClient() (ret *Client) {
vendorName := "Anthropic"
ret = &Client{}
@ -222,9 +228,10 @@ func (an *Client) buildMessageParams(msgs []anthropic.MessageParam, opts *domain
Messages: msgs,
}
// Only set one of Temperature or TopP as some models don't allow both
// Always set temperature to ensure consistent behavior (Anthropic default is 1.0, Fabric default is 0.7)
if opts.TopP != domain.DefaultTopP {
// Claude Opus 4.7 disallows sampling params; omit both temperature and top_p.
if modelDisallowsSamplingParams(opts.Model) {
// Intentionally omit both fields.
} else if opts.TopP != domain.DefaultTopP {
// User explicitly set TopP, so use that instead of temperature
params.TopP = anthropic.Opt(opts.TopP)
} else {

View file

@ -170,6 +170,29 @@ func TestBuildMessageParams_WithSearchAndLocation(t *testing.T) {
}
}
func TestBuildMessageParams_Opus47OmitsSamplingParams(t *testing.T) {
client := NewClient()
opts := &domain.ChatOptions{
Model: string(anthropic.ModelClaudeOpus4_7),
Temperature: 0.8,
TopP: 0.8,
Search: false,
}
messages := []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock("Hello")),
}
params := client.buildMessageParams(messages, opts)
if params.Temperature.Value != 0 {
t.Errorf("expected temperature to be omitted for %s, got %f", opts.Model, params.Temperature.Value)
}
if params.TopP.Value != 0 {
t.Errorf("expected top_p to be omitted for %s, got %f", opts.Model, params.TopP.Value)
}
}
func TestModelBetasConfiguration(t *testing.T) {
client := NewClient()
model := string(anthropic.ModelClaudeSonnet4_20250514)