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:
commit
1cfa781925
2 changed files with 71 additions and 6 deletions
|
|
@ -143,7 +143,22 @@ type converseParams struct {
|
||||||
toolConfig *types.ToolConfiguration
|
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)
|
bedrockMessages, systemPrompts := convertMessages(messages)
|
||||||
|
|
||||||
var inferenceConfig *types.InferenceConfiguration
|
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 temp, ok := common.AsFloat(options["temperature"]); ok {
|
||||||
if inferenceConfig == nil {
|
if modelDeprecatesTemperature(model) {
|
||||||
inferenceConfig = &types.InferenceConfiguration{}
|
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
|
var toolConfig *types.ToolConfiguration
|
||||||
|
|
@ -199,7 +218,7 @@ func (p *Provider) Chat(
|
||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
params := buildConverseParams(messages, tools, options)
|
params := buildConverseParams(messages, tools, model, options)
|
||||||
input := &bedrockruntime.ConverseInput{
|
input := &bedrockruntime.ConverseInput{
|
||||||
ModelId: aws.String(model),
|
ModelId: aws.String(model),
|
||||||
Messages: params.messages,
|
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{
|
input := &bedrockruntime.ConverseStreamInput{
|
||||||
ModelId: aws.String(model),
|
ModelId: aws.String(model),
|
||||||
Messages: params.messages,
|
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)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue