fix(openai): align GPT-5.6 billing with official pricing

This commit is contained in:
benjamin
2026-07-10 09:42:31 +08:00
parent 4a2b10c94e
commit 383f61d0e9
8 changed files with 270 additions and 93 deletions
+54 -24
View File
@@ -282,10 +282,37 @@ func (s *BillingService) initFallbackPricing() {
s.fallbackPrices["gpt-5.5"] = s.fallbackPrices["gpt-5.4"]
s.fallbackPrices["gpt-5.5-pro"] = s.fallbackPrices["gpt-5.4"]
// GPT-5.6sol / terra / luna)暂无独立定价,回退到 GPT-5.4
s.fallbackPrices["gpt-5.6-sol"] = s.fallbackPrices["gpt-5.4"]
s.fallbackPrices["gpt-5.6-terra"] = s.fallbackPrices["gpt-5.4"]
s.fallbackPrices["gpt-5.6-luna"] = s.fallbackPrices["gpt-5.4"]
// OpenAI GPT-5.6 官方价格(USD/token)。缓存写入为输入价的 1.25 倍
s.fallbackPrices["gpt-5.6-sol"] = &ModelPricing{
InputPricePerToken: 5e-6,
InputPricePerTokenPriority: 10e-6,
OutputPricePerToken: 30e-6,
OutputPricePerTokenPriority: 60e-6,
CacheCreationPricePerToken: 6.25e-6,
CacheCreationPricePerTokenPriority: 12.5e-6,
CacheReadPricePerToken: 0.5e-6,
CacheReadPricePerTokenPriority: 1e-6,
}
s.fallbackPrices["gpt-5.6-terra"] = &ModelPricing{
InputPricePerToken: 2.5e-6,
InputPricePerTokenPriority: 5e-6,
OutputPricePerToken: 15e-6,
OutputPricePerTokenPriority: 30e-6,
CacheCreationPricePerToken: 3.125e-6,
CacheCreationPricePerTokenPriority: 6.25e-6,
CacheReadPricePerToken: 0.25e-6,
CacheReadPricePerTokenPriority: 0.5e-6,
}
s.fallbackPrices["gpt-5.6-luna"] = &ModelPricing{
InputPricePerToken: 1e-6,
InputPricePerTokenPriority: 2e-6,
OutputPricePerToken: 6e-6,
OutputPricePerTokenPriority: 12e-6,
CacheCreationPricePerToken: 1.25e-6,
CacheCreationPricePerTokenPriority: 2.5e-6,
CacheReadPricePerToken: 0.1e-6,
CacheReadPricePerTokenPriority: 0.2e-6,
}
s.fallbackPrices["gpt-5.4-mini"] = &ModelPricing{
InputPricePerToken: 7.5e-7,
@@ -1066,11 +1093,13 @@ func (s *BillingService) applyModelSpecificPricingPolicy(model string, pricing *
return nil
}
normalized := normalizeKnownOpenAICodexModel(model)
if !isOpenAIGPT54Model(model) {
isGPT56 := isOpenAIGPT56Model(normalized)
usesLegacyLongContextPricing := usesOpenAILegacyLongContextPricing(normalized)
if !isGPT56 && !usesLegacyLongContextPricing {
return pricing
}
isGPT56 := normalized == "gpt-5.6-sol" || normalized == "gpt-5.6-terra" || normalized == "gpt-5.6-luna"
needsLongContextPolicy := pricing.LongContextInputThreshold <= 0 || pricing.LongContextInputMultiplier <= 0 || pricing.LongContextOutputMultiplier <= 0
needsLongContextPolicy := usesLegacyLongContextPricing &&
(pricing.LongContextInputThreshold <= 0 || pricing.LongContextInputMultiplier <= 0 || pricing.LongContextOutputMultiplier <= 0)
needsCacheCreationPolicy := isGPT56 && (pricing.CacheCreationPricePerToken <= 0 ||
(pricing.InputPricePerTokenPriority > 0 && pricing.CacheCreationPricePerTokenPriority <= 0))
if !needsLongContextPolicy && !needsCacheCreationPolicy {
@@ -1079,20 +1108,22 @@ func (s *BillingService) applyModelSpecificPricingPolicy(model string, pricing *
cloned := *pricing
if isGPT56 {
if cloned.CacheCreationPricePerToken <= 0 {
cloned.CacheCreationPricePerToken = cloned.InputPricePerToken
cloned.CacheCreationPricePerToken = cloned.InputPricePerToken * 1.25
}
if cloned.CacheCreationPricePerTokenPriority <= 0 {
cloned.CacheCreationPricePerTokenPriority = cloned.InputPricePerTokenPriority
cloned.CacheCreationPricePerTokenPriority = cloned.InputPricePerTokenPriority * 1.25
}
}
if cloned.LongContextInputThreshold <= 0 {
cloned.LongContextInputThreshold = openAIGPT54LongContextInputThreshold
}
if cloned.LongContextInputMultiplier <= 0 {
cloned.LongContextInputMultiplier = openAIGPT54LongContextInputMultiplier
}
if cloned.LongContextOutputMultiplier <= 0 {
cloned.LongContextOutputMultiplier = openAIGPT54LongContextOutputMultiplier
if usesLegacyLongContextPricing {
if cloned.LongContextInputThreshold <= 0 {
cloned.LongContextInputThreshold = openAIGPT54LongContextInputThreshold
}
if cloned.LongContextInputMultiplier <= 0 {
cloned.LongContextInputMultiplier = openAIGPT54LongContextInputMultiplier
}
if cloned.LongContextOutputMultiplier <= 0 {
cloned.LongContextOutputMultiplier = openAIGPT54LongContextOutputMultiplier
}
}
return &cloned
}
@@ -1108,13 +1139,12 @@ func (s *BillingService) shouldApplySessionLongContextPricing(tokens UsageTokens
return totalInputTokens > pricing.LongContextInputThreshold
}
func isOpenAIGPT54Model(model string) bool {
// 仅当模型字符串实际属于已知 GPT-5/Codex 族时才做归一判定,避免
// normalizeCodexModel 的默认兜底把非 OpenAI 模型(claude-*、gemini-*、gpt-4o
// 误识别为 gpt-5.4。
normalized := normalizeKnownOpenAICodexModel(model)
return normalized == "gpt-5.4" || normalized == "gpt-5.5" || normalized == "gpt-5.5-pro" ||
normalized == "gpt-5.6-sol" || normalized == "gpt-5.6-terra" || normalized == "gpt-5.6-luna"
func isOpenAIGPT56Model(normalized string) bool {
return normalized == "gpt-5.6-sol" || normalized == "gpt-5.6-terra" || normalized == "gpt-5.6-luna"
}
func usesOpenAILegacyLongContextPricing(normalized string) bool {
return normalized == "gpt-5.4" || normalized == "gpt-5.5" || normalized == "gpt-5.5-pro"
}
// CalculateCostWithConfig 使用配置中的默认倍率计算费用
@@ -1039,7 +1039,7 @@ func TestOpenAIGatewayServiceRecordUsage_GPT56SeparatesCacheWriteForBillingAndSt
require.Equal(t, 100, usageRepo.lastLog.CacheReadTokens)
require.Equal(t, 1050, usageRepo.lastLog.TotalTokens())
require.InDelta(t, 700*5e-6, usageRepo.lastLog.InputCost, 1e-12)
require.InDelta(t, 200*5e-6, usageRepo.lastLog.CacheCreationCost, 1e-12)
require.InDelta(t, 200*6.25e-6, usageRepo.lastLog.CacheCreationCost, 1e-12)
require.InDelta(t, 100*0.5e-6, usageRepo.lastLog.CacheReadCost, 1e-12)
require.InDelta(t, 50*30e-6, usageRepo.lastLog.OutputCost, 1e-12)
require.InDelta(t, usageRepo.lastLog.TotalCost*1.1, usageRepo.lastLog.ActualCost, 1e-12)
@@ -783,14 +783,14 @@ func openAICacheReadTokensFromUsage(value gjson.Result) int {
func openAICacheCreationTokensFromUsage(value gjson.Result) int {
return firstPositiveGJSONInt(
value.Get("input_tokens_details.cache_write_tokens"),
value.Get("prompt_tokens_details.cache_write_tokens"),
value.Get("input_tokens_details.cache_creation_tokens"),
value.Get("prompt_tokens_details.cache_creation_tokens"),
value.Get("cache_write_tokens"),
value.Get("cache_creation_input_tokens"),
value.Get("cache_write_input_tokens"),
value.Get("cache_creation_tokens"),
value.Get("cache_write_tokens"),
value.Get("input_tokens_details.cache_creation_tokens"),
value.Get("input_tokens_details.cache_write_tokens"),
value.Get("prompt_tokens_details.cache_creation_tokens"),
value.Get("prompt_tokens_details.cache_write_tokens"),
)
}
@@ -2817,6 +2817,10 @@ func TestExtractOpenAIUsageFromJSONBytes_AcceptsResponseAndChatUsageShapes(t *te
usage, ok = extractOpenAIUsageFromJSONBytes([]byte(`{"usage":{"input_tokens":11,"output_tokens":2,"cache_write_input_tokens":6}}`))
require.True(t, ok)
require.Equal(t, 6, usage.CacheCreationInputTokens)
usage, ok = extractOpenAIUsageFromJSONBytes([]byte(`{"usage":{"input_tokens":20,"output_tokens":2,"cache_creation_input_tokens":19,"input_tokens_details":{"cache_write_tokens":7}}}`))
require.True(t, ok)
require.Equal(t, 7, usage.CacheCreationInputTokens, "官方嵌套字段应优先于兼容顶层别名")
}
func TestExtractCodexFinalResponse_SampleReplay(t *testing.T) {
@@ -812,14 +812,14 @@ func parseUsageIntField(value gjson.Result, required bool) (int, bool) {
func openAICacheCreationTokensFromUsage(value gjson.Result) int {
for _, field := range []string{
"input_tokens_details.cache_write_tokens",
"prompt_tokens_details.cache_write_tokens",
"input_tokens_details.cache_creation_tokens",
"prompt_tokens_details.cache_creation_tokens",
"cache_write_tokens",
"cache_creation_input_tokens",
"cache_write_input_tokens",
"cache_creation_tokens",
"cache_write_tokens",
"input_tokens_details.cache_creation_tokens",
"input_tokens_details.cache_write_tokens",
"prompt_tokens_details.cache_creation_tokens",
"prompt_tokens_details.cache_write_tokens",
} {
if tokens := int(value.Get(field).Int()); tokens > 0 {
return tokens
+55 -4
View File
@@ -35,6 +35,48 @@ var (
Mode: "chat",
SupportsPromptCaching: true,
}
openAIGPT56SolFallbackPricing = &LiteLLMModelPricing{
InputCostPerToken: 5e-06,
InputCostPerTokenPriority: 1e-05,
OutputCostPerToken: 3e-05,
OutputCostPerTokenPriority: 6e-05,
CacheCreationInputTokenCost: 6.25e-06,
CacheCreationInputTokenCostPriority: 1.25e-05,
CacheReadInputTokenCost: 5e-07,
CacheReadInputTokenCostPriority: 1e-06,
SupportsServiceTier: true,
LiteLLMProvider: "openai",
Mode: "chat",
SupportsPromptCaching: true,
}
openAIGPT56TerraFallbackPricing = &LiteLLMModelPricing{
InputCostPerToken: 2.5e-06,
InputCostPerTokenPriority: 5e-06,
OutputCostPerToken: 1.5e-05,
OutputCostPerTokenPriority: 3e-05,
CacheCreationInputTokenCost: 3.125e-06,
CacheCreationInputTokenCostPriority: 6.25e-06,
CacheReadInputTokenCost: 2.5e-07,
CacheReadInputTokenCostPriority: 5e-07,
SupportsServiceTier: true,
LiteLLMProvider: "openai",
Mode: "chat",
SupportsPromptCaching: true,
}
openAIGPT56LunaFallbackPricing = &LiteLLMModelPricing{
InputCostPerToken: 1e-06,
InputCostPerTokenPriority: 2e-06,
OutputCostPerToken: 6e-06,
OutputCostPerTokenPriority: 1.2e-05,
CacheCreationInputTokenCost: 1.25e-06,
CacheCreationInputTokenCostPriority: 2.5e-06,
CacheReadInputTokenCost: 1e-07,
CacheReadInputTokenCostPriority: 2e-07,
SupportsServiceTier: true,
LiteLLMProvider: "openai",
Mode: "chat",
SupportsPromptCaching: true,
}
openAIGPT54MiniFallbackPricing = &LiteLLMModelPricing{
InputCostPerToken: 7.5e-07,
OutputCostPerToken: 4.5e-06,
@@ -842,11 +884,20 @@ func (s *PricingService) matchOpenAIModel(model string) *LiteLLMModelPricing {
}
}
// GPT-5.6sol / terra / luna)回退到 GPT-5.4 定价
if strings.HasPrefix(model, "gpt-5.6") {
if strings.HasPrefix(model, "gpt-5.6-sol") {
logger.With(zap.String("component", "service.pricing")).
Info(fmt.Sprintf("[Pricing] OpenAI fallback matched %s -> %s", model, "gpt-5.4(static)"))
return openAIGPT54FallbackPricing
Info(fmt.Sprintf("[Pricing] OpenAI fallback matched %s -> %s", model, "gpt-5.6-sol(static)"))
return openAIGPT56SolFallbackPricing
}
if strings.HasPrefix(model, "gpt-5.6-terra") {
logger.With(zap.String("component", "service.pricing")).
Info(fmt.Sprintf("[Pricing] OpenAI fallback matched %s -> %s", model, "gpt-5.6-terra(static)"))
return openAIGPT56TerraFallbackPricing
}
if strings.HasPrefix(model, "gpt-5.6-luna") {
logger.With(zap.String("component", "service.pricing")).
Info(fmt.Sprintf("[Pricing] OpenAI fallback matched %s -> %s", model, "gpt-5.6-luna(static)"))
return openAIGPT56LunaFallbackPricing
}
// GPT-5.5 回退到 GPT-5.4 定价
+112 -23
View File
@@ -40,43 +40,57 @@ func TestParsePricingData_ParsesPriorityAndServiceTierFields(t *testing.T) {
require.True(t, pricing.SupportsServiceTier)
}
func TestBillingService_GPT56CacheWritePricingUsesInputTier(t *testing.T) {
for _, model := range []string{"gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"} {
t.Run(model, func(t *testing.T) {
func TestBillingService_GPT56CacheWritePricingUsesOfficialMultiplier(t *testing.T) {
tests := []struct {
model string
input float64
inputPriority float64
output float64
outputPriority float64
cacheRead float64
cacheReadPriority float64
}{
{model: "gpt-5.6-sol", input: 5e-6, inputPriority: 10e-6, output: 30e-6, outputPriority: 60e-6, cacheRead: 0.5e-6, cacheReadPriority: 1e-6},
{model: "gpt-5.6-terra", input: 2.5e-6, inputPriority: 5e-6, output: 15e-6, outputPriority: 30e-6, cacheRead: 0.25e-6, cacheReadPriority: 0.5e-6},
{model: "gpt-5.6-luna", input: 1e-6, inputPriority: 2e-6, output: 6e-6, outputPriority: 12e-6, cacheRead: 0.1e-6, cacheReadPriority: 0.2e-6},
}
for _, tt := range tests {
t.Run(tt.model, func(t *testing.T) {
pricingSvc := &PricingService{pricingData: map[string]*LiteLLMModelPricing{
model: {
InputCostPerToken: 5e-6,
InputCostPerTokenPriority: 10e-6,
OutputCostPerToken: 30e-6,
OutputCostPerTokenPriority: 60e-6,
CacheReadInputTokenCost: 0.5e-6,
CacheReadInputTokenCostPriority: 1e-6,
tt.model: {
InputCostPerToken: tt.input,
InputCostPerTokenPriority: tt.inputPriority,
OutputCostPerToken: tt.output,
OutputCostPerTokenPriority: tt.outputPriority,
CacheReadInputTokenCost: tt.cacheRead,
CacheReadInputTokenCostPriority: tt.cacheReadPriority,
},
}}
svc := NewBillingService(&config.Config{}, pricingSvc)
pricing, err := svc.GetModelPricing(model)
pricing, err := svc.GetModelPricing(tt.model)
require.NoError(t, err)
require.InDelta(t, 5e-6, pricing.CacheCreationPricePerToken, 1e-12)
require.InDelta(t, 10e-6, pricing.CacheCreationPricePerTokenPriority, 1e-12)
require.InDelta(t, tt.input*1.25, pricing.CacheCreationPricePerToken, 1e-12)
require.InDelta(t, tt.inputPriority*1.25, pricing.CacheCreationPricePerTokenPriority, 1e-12)
require.Zero(t, pricing.LongContextInputThreshold)
tokens := UsageTokens{InputTokens: 700, OutputTokens: 50, CacheCreationTokens: 200, CacheReadTokens: 100}
standard, err := svc.CalculateCostWithServiceTier(model, tokens, 1, "")
standard, err := svc.CalculateCostWithServiceTier(tt.model, tokens, 1, "")
require.NoError(t, err)
require.InDelta(t, 200*5e-6, standard.CacheCreationCost, 1e-12)
require.InDelta(t, 200*tt.input*1.25, standard.CacheCreationCost, 1e-12)
priority, err := svc.CalculateCostWithServiceTier(model, tokens, 1, "priority")
priority, err := svc.CalculateCostWithServiceTier(tt.model, tokens, 1, "priority")
require.NoError(t, err)
require.InDelta(t, 200*10e-6, priority.CacheCreationCost, 1e-12)
require.InDelta(t, 200*tt.inputPriority*1.25, priority.CacheCreationCost, 1e-12)
flex, err := svc.CalculateCostWithServiceTier(model, tokens, 1, "flex")
flex, err := svc.CalculateCostWithServiceTier(tt.model, tokens, 1, "flex")
require.NoError(t, err)
require.InDelta(t, 200*2.5e-6, flex.CacheCreationCost, 1e-12)
require.InDelta(t, 200*tt.input*1.25*0.5, flex.CacheCreationCost, 1e-12)
})
}
}
func TestBillingService_GPT56CacheWriteContributesToLongContextThreshold(t *testing.T) {
func TestBillingService_GPT56DoesNotUseLegacyLongContextMultiplier(t *testing.T) {
model := "gpt-5.6-sol"
pricingSvc := &PricingService{pricingData: map[string]*LiteLLMModelPricing{
model: {
@@ -90,9 +104,84 @@ func TestBillingService_GPT56CacheWriteContributesToLongContextThreshold(t *test
cost, err := svc.CalculateCost(model, tokens, 1)
require.NoError(t, err)
require.InDelta(t, 100000*10e-6, cost.InputCost, 1e-12)
require.InDelta(t, 173000*10e-6, cost.CacheCreationCost, 1e-12)
require.InDelta(t, 10*45e-6, cost.OutputCost, 1e-12)
require.InDelta(t, 100000*5e-6, cost.InputCost, 1e-12)
require.InDelta(t, 173000*6.25e-6, cost.CacheCreationCost, 1e-12)
require.InDelta(t, 10*30e-6, cost.OutputCost, 1e-12)
}
func TestDefaultPricingIncludesOfficialGPT56Rates(t *testing.T) {
data, err := os.ReadFile(filepath.Join("..", "..", "resources", "model-pricing", "model_prices_and_context_window.json"))
require.NoError(t, err)
pricingSvc := &PricingService{}
pricingData, err := pricingSvc.parsePricingData(data)
require.NoError(t, err)
pricingSvc.pricingData = pricingData
billingSvc := NewBillingService(&config.Config{}, pricingSvc)
tests := []struct {
model string
input, cached, cacheWrite, output float64
inputPriority, cachedPriority, cacheWritePriority, outputPriority float64
}{
{model: "gpt-5.6-sol", input: 5e-6, cached: 0.5e-6, cacheWrite: 6.25e-6, output: 30e-6, inputPriority: 10e-6, cachedPriority: 1e-6, cacheWritePriority: 12.5e-6, outputPriority: 60e-6},
{model: "gpt-5.6-terra", input: 2.5e-6, cached: 0.25e-6, cacheWrite: 3.125e-6, output: 15e-6, inputPriority: 5e-6, cachedPriority: 0.5e-6, cacheWritePriority: 6.25e-6, outputPriority: 30e-6},
{model: "gpt-5.6-luna", input: 1e-6, cached: 0.1e-6, cacheWrite: 1.25e-6, output: 6e-6, inputPriority: 2e-6, cachedPriority: 0.2e-6, cacheWritePriority: 2.5e-6, outputPriority: 12e-6},
}
for _, tt := range tests {
t.Run(tt.model, func(t *testing.T) {
pricing, err := billingSvc.GetModelPricing(tt.model)
require.NoError(t, err)
require.InDelta(t, tt.input, pricing.InputPricePerToken, 1e-12)
require.InDelta(t, tt.cached, pricing.CacheReadPricePerToken, 1e-12)
require.InDelta(t, tt.cacheWrite, pricing.CacheCreationPricePerToken, 1e-12)
require.InDelta(t, tt.output, pricing.OutputPricePerToken, 1e-12)
require.InDelta(t, tt.inputPriority, pricing.InputPricePerTokenPriority, 1e-12)
require.InDelta(t, tt.cachedPriority, pricing.CacheReadPricePerTokenPriority, 1e-12)
require.InDelta(t, tt.cacheWritePriority, pricing.CacheCreationPricePerTokenPriority, 1e-12)
require.InDelta(t, tt.outputPriority, pricing.OutputPricePerTokenPriority, 1e-12)
require.Zero(t, pricing.LongContextInputThreshold)
})
}
}
func TestGPT56DedicatedFallbacksUseOfficialRates(t *testing.T) {
tests := []struct {
model string
input, cached, cacheWrite, output float64
}{
{model: "gpt-5.6-sol", input: 5e-6, cached: 0.5e-6, cacheWrite: 6.25e-6, output: 30e-6},
{model: "gpt-5.6-terra", input: 2.5e-6, cached: 0.25e-6, cacheWrite: 3.125e-6, output: 15e-6},
{model: "gpt-5.6-luna", input: 1e-6, cached: 0.1e-6, cacheWrite: 1.25e-6, output: 6e-6},
}
for _, tt := range tests {
t.Run(tt.model+"/pricing_service", func(t *testing.T) {
pricingSvc := &PricingService{pricingData: map[string]*LiteLLMModelPricing{
"gpt-5.1-codex": {InputCostPerToken: 1.25e-6},
}}
svc := NewBillingService(&config.Config{}, pricingSvc)
pricing, err := svc.GetModelPricing(tt.model + "-preview")
require.NoError(t, err)
assertGPT56FallbackPricing(t, pricing, tt.input, tt.cached, tt.cacheWrite, tt.output)
})
t.Run(tt.model+"/billing_service", func(t *testing.T) {
svc := NewBillingService(&config.Config{}, nil)
pricing, err := svc.GetModelPricing(tt.model)
require.NoError(t, err)
assertGPT56FallbackPricing(t, pricing, tt.input, tt.cached, tt.cacheWrite, tt.output)
})
}
}
func assertGPT56FallbackPricing(t *testing.T, pricing *ModelPricing, input, cached, cacheWrite, output float64) {
t.Helper()
require.InDelta(t, input, pricing.InputPricePerToken, 1e-12)
require.InDelta(t, cached, pricing.CacheReadPricePerToken, 1e-12)
require.InDelta(t, cacheWrite, pricing.CacheCreationPricePerToken, 1e-12)
require.InDelta(t, output, pricing.OutputPricePerToken, 1e-12)
require.Zero(t, pricing.LongContextInputThreshold)
}
func TestParsePricingData_KeepsImageOnlyPricing(t *testing.T) {
@@ -4961,12 +4961,14 @@
"supports_xhigh_reasoning_effort": true
},
"gpt-5.6-sol": {
"cache_creation_input_token_cost": 6.25e-06,
"cache_creation_input_token_cost_batches": 3.125e-06,
"cache_creation_input_token_cost_flex": 3.125e-06,
"cache_creation_input_token_cost_priority": 1.25e-05,
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_flex": 2.5e-07,
"cache_read_input_token_cost_priority": 1e-06,
"input_cost_per_token": 5e-06,
"input_cost_per_token_above_272k_tokens": 1e-05,
"input_cost_per_token_batches": 2.5e-06,
"input_cost_per_token_flex": 2.5e-06,
"input_cost_per_token_priority": 1e-05,
@@ -4976,7 +4978,6 @@
"max_tokens": 128000,
"mode": "chat",
"output_cost_per_token": 3e-05,
"output_cost_per_token_above_272k_tokens": 4.5e-05,
"output_cost_per_token_batches": 1.5e-05,
"output_cost_per_token_flex": 1.5e-05,
"output_cost_per_token_priority": 6e-05,
@@ -5009,25 +5010,26 @@
"supports_xhigh_reasoning_effort": true
},
"gpt-5.6-terra": {
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_flex": 2.5e-07,
"cache_read_input_token_cost_priority": 1e-06,
"input_cost_per_token": 5e-06,
"input_cost_per_token_above_272k_tokens": 1e-05,
"input_cost_per_token_batches": 2.5e-06,
"input_cost_per_token_flex": 2.5e-06,
"input_cost_per_token_priority": 1e-05,
"cache_creation_input_token_cost": 3.125e-06,
"cache_creation_input_token_cost_batches": 1.5625e-06,
"cache_creation_input_token_cost_flex": 1.5625e-06,
"cache_creation_input_token_cost_priority": 6.25e-06,
"cache_read_input_token_cost": 2.5e-07,
"cache_read_input_token_cost_flex": 1.25e-07,
"cache_read_input_token_cost_priority": 5e-07,
"input_cost_per_token": 2.5e-06,
"input_cost_per_token_batches": 1.25e-06,
"input_cost_per_token_flex": 1.25e-06,
"input_cost_per_token_priority": 5e-06,
"litellm_provider": "openai",
"max_input_tokens": 1050000,
"max_output_tokens": 128000,
"max_tokens": 128000,
"mode": "chat",
"output_cost_per_token": 3e-05,
"output_cost_per_token_above_272k_tokens": 4.5e-05,
"output_cost_per_token_batches": 1.5e-05,
"output_cost_per_token_flex": 1.5e-05,
"output_cost_per_token_priority": 6e-05,
"output_cost_per_token": 1.5e-05,
"output_cost_per_token_batches": 7.5e-06,
"output_cost_per_token_flex": 7.5e-06,
"output_cost_per_token_priority": 3e-05,
"supported_endpoints": [
"/v1/chat/completions",
"/v1/batch",
@@ -5057,25 +5059,26 @@
"supports_xhigh_reasoning_effort": true
},
"gpt-5.6-luna": {
"cache_read_input_token_cost": 5e-07,
"cache_read_input_token_cost_above_272k_tokens": 1e-06,
"cache_read_input_token_cost_flex": 2.5e-07,
"cache_read_input_token_cost_priority": 1e-06,
"input_cost_per_token": 5e-06,
"input_cost_per_token_above_272k_tokens": 1e-05,
"input_cost_per_token_batches": 2.5e-06,
"input_cost_per_token_flex": 2.5e-06,
"input_cost_per_token_priority": 1e-05,
"cache_creation_input_token_cost": 1.25e-06,
"cache_creation_input_token_cost_batches": 6.25e-07,
"cache_creation_input_token_cost_flex": 6.25e-07,
"cache_creation_input_token_cost_priority": 2.5e-06,
"cache_read_input_token_cost": 1e-07,
"cache_read_input_token_cost_flex": 5e-08,
"cache_read_input_token_cost_priority": 2e-07,
"input_cost_per_token": 1e-06,
"input_cost_per_token_batches": 5e-07,
"input_cost_per_token_flex": 5e-07,
"input_cost_per_token_priority": 2e-06,
"litellm_provider": "openai",
"max_input_tokens": 1050000,
"max_output_tokens": 128000,
"max_tokens": 128000,
"mode": "chat",
"output_cost_per_token": 3e-05,
"output_cost_per_token_above_272k_tokens": 4.5e-05,
"output_cost_per_token_batches": 1.5e-05,
"output_cost_per_token_flex": 1.5e-05,
"output_cost_per_token_priority": 6e-05,
"output_cost_per_token": 6e-06,
"output_cost_per_token_batches": 3e-06,
"output_cost_per_token_flex": 3e-06,
"output_cost_per_token_priority": 1.2e-05,
"supported_endpoints": [
"/v1/chat/completions",
"/v1/batch",