Merge pull request #2982 from loafoe/fix/bedrock-opus48-temperature

fix(bedrock): drop temperature for models that deprecate it (Opus 4.8)
This commit is contained in:
Mauro
2026-06-01 13:02:18 +02:00
committed by GitHub
2 changed files with 71 additions and 6 deletions
+25 -6
View File
@@ -143,7 +143,22 @@ type converseParams struct {
toolConfig *types.ToolConfiguration
}
func buildConverseParams(messages []Message, tools []ToolDefinition, options map[string]any) converseParams {
// modelDeprecatesTemperature reports whether the given Bedrock model rejects the
// temperature inference parameter. Newer Claude models (Opus 4.8 and later) treat
// temperature as deprecated and return a ValidationException if it is supplied:
//
// ValidationException: The model returned the following errors:
// temperature is deprecated for this model.
//
// The match is intentionally loose: Bedrock model IDs and inference-profile ARNs
// embed the model name (e.g. "us.anthropic.claude-opus-4-8-20260514-v1:0"), so a
// substring check covers both bare IDs and region-prefixed inference profiles.
func modelDeprecatesTemperature(model string) bool {
m := strings.ToLower(model)
return strings.Contains(m, "claude-opus-4-8")
}
func buildConverseParams(messages []Message, tools []ToolDefinition, model string, options map[string]any) converseParams {
bedrockMessages, systemPrompts := convertMessages(messages)
var inferenceConfig *types.InferenceConfiguration
@@ -159,10 +174,14 @@ func buildConverseParams(messages []Message, tools []ToolDefinition, options map
}
if temp, ok := common.AsFloat(options["temperature"]); ok {
if inferenceConfig == nil {
inferenceConfig = &types.InferenceConfiguration{}
if modelDeprecatesTemperature(model) {
log.Printf("bedrock: temperature dropped because model %q no longer supports it", model)
} else {
if inferenceConfig == nil {
inferenceConfig = &types.InferenceConfiguration{}
}
inferenceConfig.Temperature = aws.Float32(float32(temp))
}
inferenceConfig.Temperature = aws.Float32(float32(temp))
}
var toolConfig *types.ToolConfiguration
@@ -199,7 +218,7 @@ func (p *Provider) Chat(
defer cancel()
}
params := buildConverseParams(messages, tools, options)
params := buildConverseParams(messages, tools, model, options)
input := &bedrockruntime.ConverseInput{
ModelId: aws.String(model),
Messages: params.messages,
@@ -242,7 +261,7 @@ func (p *Provider) ChatStream(
}
}
params := buildConverseParams(messages, tools, options)
params := buildConverseParams(messages, tools, model, options)
input := &bedrockruntime.ConverseStreamInput{
ModelId: aws.String(model),
Messages: params.messages,
@@ -875,3 +875,49 @@ func TestParseStreamResponse_StopReasons(t *testing.T) {
})
}
}
func TestModelDeprecatesTemperature(t *testing.T) {
tests := []struct {
name string
model string
want bool
}{
{"opus 4.8 bare id", "claude-opus-4-8-20260514-v1:0", true},
{"opus 4.8 inference profile", "us.anthropic.claude-opus-4-8-20260514-v1:0", true},
{"opus 4.8 mixed case", "US.Anthropic.Claude-Opus-4-8", true},
{"opus 4.7 unaffected", "us.anthropic.claude-opus-4-7-20250101-v1:0", false},
{"sonnet unaffected", "us.anthropic.claude-sonnet-4-6", false},
{"empty", "", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, modelDeprecatesTemperature(tt.model))
})
}
}
func TestBuildConverseParams_DropsTemperatureForDeprecatedModel(t *testing.T) {
options := map[string]any{
"temperature": 0.7,
"max_tokens": 1024,
}
params := buildConverseParams(nil, nil, "us.anthropic.claude-opus-4-8-20260514-v1:0", options)
require.NotNil(t, params.inferenceConfig, "max_tokens should still populate inference config")
assert.Nil(t, params.inferenceConfig.Temperature, "temperature must be omitted for opus 4.8")
require.NotNil(t, params.inferenceConfig.MaxTokens)
assert.Equal(t, int32(1024), *params.inferenceConfig.MaxTokens)
}
func TestBuildConverseParams_KeepsTemperatureForSupportedModel(t *testing.T) {
options := map[string]any{
"temperature": 0.7,
}
params := buildConverseParams(nil, nil, "us.anthropic.claude-opus-4-7-20250101-v1:0", options)
require.NotNil(t, params.inferenceConfig)
require.NotNil(t, params.inferenceConfig.Temperature)
assert.InDelta(t, 0.7, float64(*params.inferenceConfig.Temperature), 0.0001)
}