feat(agents): add chat model pricing metadata (#22959)

## Summary
- add chat model pricing metadata to the agents admin form and SDK
metadata
- split pricing into its own section and show default pricing as
placeholders
- apply default pricing when admins leave pricing fields blank
This commit is contained in:
Michael Suchacz
2026-03-12 07:37:33 +01:00
committed by GitHub
parent 3325b86903
commit fba00a6b3a
17 changed files with 958 additions and 165 deletions
+32 -1
View File
@@ -553,7 +553,8 @@ func normalizedEnumValue(value string, allowed ...string) *string {
return nil
}
// MergeMissingCallConfig fills unset call config values from defaults.
// MergeMissingCallConfig fills unset call config values from a provider or
// profile default config.
func MergeMissingCallConfig(
dst *codersdk.ChatModelCallConfig,
defaults codersdk.ChatModelCallConfig,
@@ -576,9 +577,39 @@ func MergeMissingCallConfig(
if dst.FrequencyPenalty == nil {
dst.FrequencyPenalty = defaults.FrequencyPenalty
}
MergeMissingModelCostConfig(&dst.Cost, defaults.Cost)
MergeMissingProviderOptions(&dst.ProviderOptions, defaults.ProviderOptions)
}
// MergeMissingModelCostConfig fills unset pricing metadata from defaults.
func MergeMissingModelCostConfig(
dst **codersdk.ModelCostConfig,
defaults *codersdk.ModelCostConfig,
) {
if defaults == nil {
return
}
if *dst == nil {
copied := *defaults
*dst = &copied
return
}
current := *dst
if current.InputPricePerMillionTokens == nil {
current.InputPricePerMillionTokens = defaults.InputPricePerMillionTokens
}
if current.OutputPricePerMillionTokens == nil {
current.OutputPricePerMillionTokens = defaults.OutputPricePerMillionTokens
}
if current.CacheReadPricePerMillionTokens == nil {
current.CacheReadPricePerMillionTokens = defaults.CacheReadPricePerMillionTokens
}
if current.CacheWritePricePerMillionTokens == nil {
current.CacheWritePricePerMillionTokens = defaults.CacheWritePricePerMillionTokens
}
}
// MergeMissingProviderOptions fills unset provider option fields from defaults.
func MergeMissingProviderOptions(
dst **codersdk.ChatModelProviderOptions,
+20 -2
View File
@@ -142,16 +142,25 @@ func TestMergeMissingCallConfig_FillsUnsetFields(t *testing.T) {
dst := codersdk.ChatModelCallConfig{
Temperature: float64Ptr(0.2),
Cost: &codersdk.ModelCostConfig{
OutputPricePerMillionTokens: float64Ptr(0.7),
},
ProviderOptions: &codersdk.ChatModelProviderOptions{
OpenAI: &codersdk.ChatModelOpenAIProviderOptions{
User: stringPtr("alice"),
},
},
}
defaults := codersdk.ChatModelCallConfig{
defaultCallConfig := codersdk.ChatModelCallConfig{
MaxOutputTokens: int64Ptr(512),
Temperature: float64Ptr(0.9),
TopP: float64Ptr(0.8),
Cost: &codersdk.ModelCostConfig{
InputPricePerMillionTokens: float64Ptr(0.15),
OutputPricePerMillionTokens: float64Ptr(0.9),
CacheReadPricePerMillionTokens: float64Ptr(0.03),
CacheWritePricePerMillionTokens: float64Ptr(0.3),
},
ProviderOptions: &codersdk.ChatModelProviderOptions{
OpenAI: &codersdk.ChatModelOpenAIProviderOptions{
User: stringPtr("bob"),
@@ -160,7 +169,7 @@ func TestMergeMissingCallConfig_FillsUnsetFields(t *testing.T) {
},
}
chatprovider.MergeMissingCallConfig(&dst, defaults)
chatprovider.MergeMissingCallConfig(&dst, defaultCallConfig)
require.NotNil(t, dst.MaxOutputTokens)
require.EqualValues(t, 512, *dst.MaxOutputTokens)
@@ -168,6 +177,15 @@ func TestMergeMissingCallConfig_FillsUnsetFields(t *testing.T) {
require.Equal(t, 0.2, *dst.Temperature)
require.NotNil(t, dst.TopP)
require.Equal(t, 0.8, *dst.TopP)
require.NotNil(t, dst.Cost)
require.NotNil(t, dst.Cost.InputPricePerMillionTokens)
require.Equal(t, 0.15, *dst.Cost.InputPricePerMillionTokens)
require.NotNil(t, dst.Cost.OutputPricePerMillionTokens)
require.Equal(t, 0.7, *dst.Cost.OutputPricePerMillionTokens)
require.NotNil(t, dst.Cost.CacheReadPricePerMillionTokens)
require.Equal(t, 0.03, *dst.Cost.CacheReadPricePerMillionTokens)
require.NotNil(t, dst.Cost.CacheWritePricePerMillionTokens)
require.Equal(t, 0.3, *dst.Cost.CacheWritePricePerMillionTokens)
require.NotNil(t, dst.ProviderOptions)
require.NotNil(t, dst.ProviderOptions.OpenAI)
require.Equal(t, "alice", *dst.ProviderOptions.OpenAI.User)