From 32a79be962663eb22e5e6fce0fc474d536880d98 Mon Sep 17 00:00:00 2001 From: gaoren002 Date: Tue, 12 May 2026 08:19:00 +0000 Subject: [PATCH] fix(openai): add codex auto review model pricing --- .../service/openai_codex_transform.go | 1 + .../service/openai_codex_transform_test.go | 1 + .../service/openai_model_mapping_test.go | 20 +++++++++++ .../internal/service/pricing_service_test.go | 18 ++++++++++ .../model_prices_and_context_window.json | 33 +++++++++++++++++++ 5 files changed, 73 insertions(+) diff --git a/backend/internal/service/openai_codex_transform.go b/backend/internal/service/openai_codex_transform.go index a3b69dee..2c582893 100644 --- a/backend/internal/service/openai_codex_transform.go +++ b/backend/internal/service/openai_codex_transform.go @@ -8,6 +8,7 @@ import ( var codexModelMap = map[string]string{ "gpt-5.5": "gpt-5.5", + "codex-auto-review": "codex-auto-review", "gpt-5.4": "gpt-5.4", "gpt-5.4-mini": "gpt-5.4-mini", "gpt-5.4-none": "gpt-5.4", diff --git a/backend/internal/service/openai_codex_transform_test.go b/backend/internal/service/openai_codex_transform_test.go index 9c72760a..62c67d3f 100644 --- a/backend/internal/service/openai_codex_transform_test.go +++ b/backend/internal/service/openai_codex_transform_test.go @@ -839,6 +839,7 @@ func TestNormalizeCodexModel_Gpt53(t *testing.T) { "gpt-5.4": "gpt-5.4", "gpt5.5": "gpt-5.5", "openai/gpt5.5": "gpt-5.5", + "codex-auto-review": "codex-auto-review", "gpt5.4": "gpt-5.4", "gpt-5.4-high": "gpt-5.4", "gpt-5.4-chat-latest": "gpt-5.4", diff --git a/backend/internal/service/openai_model_mapping_test.go b/backend/internal/service/openai_model_mapping_test.go index f087ac32..020e8875 100644 --- a/backend/internal/service/openai_model_mapping_test.go +++ b/backend/internal/service/openai_model_mapping_test.go @@ -261,6 +261,12 @@ func TestNormalizeOpenAIModelForUpstream(t *testing.T) { model: "gpt-5.4-high", want: "gpt-5.4", }, + { + name: "oauth preserves codex auto review model", + account: &Account{Type: AccountTypeOAuth}, + model: "codex-auto-review", + want: "codex-auto-review", + }, { name: "apikey preserves custom compatible model", account: &Account{Type: AccountTypeAPIKey}, @@ -283,3 +289,17 @@ func TestNormalizeOpenAIModelForUpstream(t *testing.T) { }) } } + +func TestUsageBillingModelCandidatesPreserveCodexAutoReviewModel(t *testing.T) { + candidates := usageBillingModelCandidates("codex-auto-review") + + expected := []string{"codex-auto-review"} + if len(candidates) != len(expected) { + t.Fatalf("usageBillingModelCandidates(codex-auto-review) = %#v, want %#v", candidates, expected) + } + for i := range expected { + if candidates[i] != expected[i] { + t.Fatalf("usageBillingModelCandidates(codex-auto-review) = %#v, want %#v", candidates, expected) + } + } +} diff --git a/backend/internal/service/pricing_service_test.go b/backend/internal/service/pricing_service_test.go index 3c3e2c5b..d0b46886 100644 --- a/backend/internal/service/pricing_service_test.go +++ b/backend/internal/service/pricing_service_test.go @@ -2,6 +2,8 @@ package service import ( "encoding/json" + "os" + "path/filepath" "testing" "github.com/stretchr/testify/require" @@ -111,6 +113,22 @@ func TestGetModelPricing_OpenAICompactAliasUsesStaticFallback(t *testing.T) { require.InDelta(t, 1.5e-5, got.OutputCostPerToken, 1e-12) } +func TestDefaultPricingIncludesCodexAutoReview(t *testing.T) { + data, err := os.ReadFile(filepath.Join("..", "..", "resources", "model-pricing", "model_prices_and_context_window.json")) + require.NoError(t, err) + + svc := &PricingService{} + pricingData, err := svc.parsePricingData(data) + require.NoError(t, err) + svc.pricingData = pricingData + + got := svc.GetModelPricing("codex-auto-review") + require.NotNil(t, got) + require.InDelta(t, 2.5e-6, got.InputCostPerToken, 1e-12) + require.InDelta(t, 1.5e-5, got.OutputCostPerToken, 1e-12) + require.InDelta(t, 2.5e-7, got.CacheReadInputTokenCost, 1e-12) +} + func TestGetModelPricing_Gpt54MiniUsesDedicatedStaticFallbackWhenRemoteMissing(t *testing.T) { svc := &PricingService{ pricingData: map[string]*LiteLLMModelPricing{ diff --git a/backend/resources/model-pricing/model_prices_and_context_window.json b/backend/resources/model-pricing/model_prices_and_context_window.json index 0a096257..3cae8c8b 100644 --- a/backend/resources/model-pricing/model_prices_and_context_window.json +++ b/backend/resources/model-pricing/model_prices_and_context_window.json @@ -5173,6 +5173,39 @@ "supports_tool_choice": true, "supports_vision": true }, + "codex-auto-review": { + "cache_read_input_token_cost": 2.5e-07, + "input_cost_per_token": 2.5e-06, + "litellm_provider": "openai", + "max_input_tokens": 1050000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "output_cost_per_token": 1.5e-05, + "supported_endpoints": [ + "/v1/chat/completions", + "/v1/responses" + ], + "supported_modalities": [ + "text", + "image" + ], + "supported_output_modalities": [ + "text", + "image" + ], + "supports_function_calling": true, + "supports_native_streaming": true, + "supports_parallel_function_calling": true, + "supports_pdf_input": true, + "supports_prompt_caching": true, + "supports_reasoning": true, + "supports_response_schema": true, + "supports_service_tier": true, + "supports_system_messages": true, + "supports_tool_choice": true, + "supports_vision": true + }, "gpt-5.4-mini": { "cache_read_input_token_cost": 7.5e-08, "input_cost_per_token": 7.5e-07,