fix(openai): 移除已下线 Codex 模型并修复归一化兜底副作用
- backend: 删除 gpt-5 / 5.1 / 5.1-codex / 5.1-codex-max / 5.1-codex-mini / 5.2-codex / 5.4-nano 的内置映射与 DefaultModels 条目 - backend: normalizeCodexModel 默认兜底由 gpt-5.1 改为 gpt-5.4,gpt-5.3-codex-spark 独立保留映射 - backend: 修复 isOpenAIGPT54Model 与 shouldAutoInjectPromptCacheKeyForCompat 对 claude / gpt-4o 的误判(之前依赖 gpt-5.1 作为非 GPT 族的隐式 sentinel,改后需要显式前缀守卫) - backend: 清理 billing_service 中已不可达的 fallback 价格与 switch 分支 - frontend: 从白名单、OpenCode 配置、预设映射中移除已下线模型 - 同步更新所有相关单测 Refs: #1758, parallels upstream #1759 but adds downstream guard fixes
This commit is contained in:
@@ -17,16 +17,9 @@ type Model struct {
|
|||||||
var DefaultModels = []Model{
|
var DefaultModels = []Model{
|
||||||
{ID: "gpt-5.4", Object: "model", Created: 1738368000, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.4"},
|
{ID: "gpt-5.4", Object: "model", Created: 1738368000, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.4"},
|
||||||
{ID: "gpt-5.4-mini", Object: "model", Created: 1738368000, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.4 Mini"},
|
{ID: "gpt-5.4-mini", Object: "model", Created: 1738368000, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.4 Mini"},
|
||||||
{ID: "gpt-5.4-nano", Object: "model", Created: 1738368000, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.4 Nano"},
|
|
||||||
{ID: "gpt-5.3-codex", Object: "model", Created: 1735689600, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.3 Codex"},
|
{ID: "gpt-5.3-codex", Object: "model", Created: 1735689600, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.3 Codex"},
|
||||||
{ID: "gpt-5.3-codex-spark", Object: "model", Created: 1735689600, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.3 Codex Spark"},
|
{ID: "gpt-5.3-codex-spark", Object: "model", Created: 1735689600, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.3 Codex Spark"},
|
||||||
{ID: "gpt-5.2", Object: "model", Created: 1733875200, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.2"},
|
{ID: "gpt-5.2", Object: "model", Created: 1733875200, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.2"},
|
||||||
{ID: "gpt-5.2-codex", Object: "model", Created: 1733011200, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.2 Codex"},
|
|
||||||
{ID: "gpt-5.1-codex-max", Object: "model", Created: 1730419200, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.1 Codex Max"},
|
|
||||||
{ID: "gpt-5.1-codex", Object: "model", Created: 1730419200, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.1 Codex"},
|
|
||||||
{ID: "gpt-5.1", Object: "model", Created: 1731456000, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.1"},
|
|
||||||
{ID: "gpt-5.1-codex-mini", Object: "model", Created: 1730419200, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5.1 Codex Mini"},
|
|
||||||
{ID: "gpt-5", Object: "model", Created: 1722988800, OwnedBy: "openai", Type: "model", DisplayName: "GPT-5"},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultModelIDs returns the default model ID list
|
// DefaultModelIDs returns the default model ID list
|
||||||
@@ -39,7 +32,7 @@ func DefaultModelIDs() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DefaultTestModel default model for testing OpenAI accounts
|
// DefaultTestModel default model for testing OpenAI accounts
|
||||||
const DefaultTestModel = "gpt-5.1-codex"
|
const DefaultTestModel = "gpt-5.4"
|
||||||
|
|
||||||
// DefaultInstructions default instructions for non-Codex CLI requests
|
// DefaultInstructions default instructions for non-Codex CLI requests
|
||||||
// Content loaded from instructions.txt at compile time
|
// Content loaded from instructions.txt at compile time
|
||||||
|
|||||||
@@ -203,17 +203,6 @@ func (s *BillingService) initFallbackPricing() {
|
|||||||
SupportsCacheBreakdown: false,
|
SupportsCacheBreakdown: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenAI GPT-5.1(本地兜底,防止动态定价不可用时拒绝计费)
|
|
||||||
s.fallbackPrices["gpt-5.1"] = &ModelPricing{
|
|
||||||
InputPricePerToken: 1.25e-6, // $1.25 per MTok
|
|
||||||
InputPricePerTokenPriority: 2.5e-6, // $2.5 per MTok
|
|
||||||
OutputPricePerToken: 10e-6, // $10 per MTok
|
|
||||||
OutputPricePerTokenPriority: 20e-6, // $20 per MTok
|
|
||||||
CacheCreationPricePerToken: 1.25e-6, // $1.25 per MTok
|
|
||||||
CacheReadPricePerToken: 0.125e-6,
|
|
||||||
CacheReadPricePerTokenPriority: 0.25e-6,
|
|
||||||
SupportsCacheBreakdown: false,
|
|
||||||
}
|
|
||||||
// OpenAI GPT-5.4(业务指定价格)
|
// OpenAI GPT-5.4(业务指定价格)
|
||||||
s.fallbackPrices["gpt-5.4"] = &ModelPricing{
|
s.fallbackPrices["gpt-5.4"] = &ModelPricing{
|
||||||
InputPricePerToken: 2.5e-6, // $2.5 per MTok
|
InputPricePerToken: 2.5e-6, // $2.5 per MTok
|
||||||
@@ -234,12 +223,6 @@ func (s *BillingService) initFallbackPricing() {
|
|||||||
CacheReadPricePerToken: 7.5e-8,
|
CacheReadPricePerToken: 7.5e-8,
|
||||||
SupportsCacheBreakdown: false,
|
SupportsCacheBreakdown: false,
|
||||||
}
|
}
|
||||||
s.fallbackPrices["gpt-5.4-nano"] = &ModelPricing{
|
|
||||||
InputPricePerToken: 2e-7,
|
|
||||||
OutputPricePerToken: 1.25e-6,
|
|
||||||
CacheReadPricePerToken: 2e-8,
|
|
||||||
SupportsCacheBreakdown: false,
|
|
||||||
}
|
|
||||||
// OpenAI GPT-5.2(本地兜底)
|
// OpenAI GPT-5.2(本地兜底)
|
||||||
s.fallbackPrices["gpt-5.2"] = &ModelPricing{
|
s.fallbackPrices["gpt-5.2"] = &ModelPricing{
|
||||||
InputPricePerToken: 1.75e-6,
|
InputPricePerToken: 1.75e-6,
|
||||||
@@ -251,8 +234,8 @@ func (s *BillingService) initFallbackPricing() {
|
|||||||
CacheReadPricePerTokenPriority: 0.35e-6,
|
CacheReadPricePerTokenPriority: 0.35e-6,
|
||||||
SupportsCacheBreakdown: false,
|
SupportsCacheBreakdown: false,
|
||||||
}
|
}
|
||||||
// Codex 族兜底统一按 GPT-5.1 Codex 价格计费
|
// Codex 族兜底统一按 GPT-5.3 Codex 价格计费
|
||||||
s.fallbackPrices["gpt-5.1-codex"] = &ModelPricing{
|
s.fallbackPrices["gpt-5.3-codex"] = &ModelPricing{
|
||||||
InputPricePerToken: 1.5e-6, // $1.5 per MTok
|
InputPricePerToken: 1.5e-6, // $1.5 per MTok
|
||||||
InputPricePerTokenPriority: 3e-6, // $3 per MTok
|
InputPricePerTokenPriority: 3e-6, // $3 per MTok
|
||||||
OutputPricePerToken: 12e-6, // $12 per MTok
|
OutputPricePerToken: 12e-6, // $12 per MTok
|
||||||
@@ -262,17 +245,6 @@ func (s *BillingService) initFallbackPricing() {
|
|||||||
CacheReadPricePerTokenPriority: 0.3e-6,
|
CacheReadPricePerTokenPriority: 0.3e-6,
|
||||||
SupportsCacheBreakdown: false,
|
SupportsCacheBreakdown: false,
|
||||||
}
|
}
|
||||||
s.fallbackPrices["gpt-5.2-codex"] = &ModelPricing{
|
|
||||||
InputPricePerToken: 1.75e-6,
|
|
||||||
InputPricePerTokenPriority: 3.5e-6,
|
|
||||||
OutputPricePerToken: 14e-6,
|
|
||||||
OutputPricePerTokenPriority: 28e-6,
|
|
||||||
CacheCreationPricePerToken: 1.75e-6,
|
|
||||||
CacheReadPricePerToken: 0.175e-6,
|
|
||||||
CacheReadPricePerTokenPriority: 0.35e-6,
|
|
||||||
SupportsCacheBreakdown: false,
|
|
||||||
}
|
|
||||||
s.fallbackPrices["gpt-5.3-codex"] = s.fallbackPrices["gpt-5.1-codex"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getFallbackPricing 根据模型系列获取回退价格
|
// getFallbackPricing 根据模型系列获取回退价格
|
||||||
@@ -318,20 +290,12 @@ func (s *BillingService) getFallbackPricing(model string) *ModelPricing {
|
|||||||
switch normalized {
|
switch normalized {
|
||||||
case "gpt-5.4-mini":
|
case "gpt-5.4-mini":
|
||||||
return s.fallbackPrices["gpt-5.4-mini"]
|
return s.fallbackPrices["gpt-5.4-mini"]
|
||||||
case "gpt-5.4-nano":
|
|
||||||
return s.fallbackPrices["gpt-5.4-nano"]
|
|
||||||
case "gpt-5.4":
|
case "gpt-5.4":
|
||||||
return s.fallbackPrices["gpt-5.4"]
|
return s.fallbackPrices["gpt-5.4"]
|
||||||
case "gpt-5.2":
|
case "gpt-5.2":
|
||||||
return s.fallbackPrices["gpt-5.2"]
|
return s.fallbackPrices["gpt-5.2"]
|
||||||
case "gpt-5.2-codex":
|
case "gpt-5.3-codex", "gpt-5.3-codex-spark":
|
||||||
return s.fallbackPrices["gpt-5.2-codex"]
|
|
||||||
case "gpt-5.3-codex":
|
|
||||||
return s.fallbackPrices["gpt-5.3-codex"]
|
return s.fallbackPrices["gpt-5.3-codex"]
|
||||||
case "gpt-5.1-codex", "gpt-5.1-codex-max", "gpt-5.1-codex-mini", "codex-mini-latest":
|
|
||||||
return s.fallbackPrices["gpt-5.1-codex"]
|
|
||||||
case "gpt-5.1":
|
|
||||||
return s.fallbackPrices["gpt-5.1"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -667,8 +631,13 @@ func (s *BillingService) shouldApplySessionLongContextPricing(tokens UsageTokens
|
|||||||
}
|
}
|
||||||
|
|
||||||
func isOpenAIGPT54Model(model string) bool {
|
func isOpenAIGPT54Model(model string) bool {
|
||||||
normalized := normalizeCodexModel(strings.TrimSpace(strings.ToLower(model)))
|
trimmed := strings.TrimSpace(strings.ToLower(model))
|
||||||
return normalized == "gpt-5.4"
|
// 仅当模型字符串实际属于 GPT-5/Codex 族时才做归一判定,避免 normalizeCodexModel
|
||||||
|
// 的默认兜底把非 OpenAI 模型(claude-*、gemini-*、gpt-4o)误识别为 gpt-5.4。
|
||||||
|
if !strings.Contains(trimmed, "gpt-5") && !strings.Contains(trimmed, "codex") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return normalizeCodexModel(trimmed) == "gpt-5.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalculateCostWithConfig 使用配置中的默认倍率计算费用
|
// CalculateCostWithConfig 使用配置中的默认倍率计算费用
|
||||||
|
|||||||
@@ -123,15 +123,6 @@ func TestGetModelPricing_UnknownOpenAIModelReturnsError(t *testing.T) {
|
|||||||
require.Contains(t, err.Error(), "pricing not found")
|
require.Contains(t, err.Error(), "pricing not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetModelPricing_OpenAIGPT51Fallback(t *testing.T) {
|
|
||||||
svc := newTestBillingService()
|
|
||||||
|
|
||||||
pricing, err := svc.GetModelPricing("gpt-5.1")
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotNil(t, pricing)
|
|
||||||
require.InDelta(t, 1.25e-6, pricing.InputPricePerToken, 1e-12)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetModelPricing_OpenAIGPT54Fallback(t *testing.T) {
|
func TestGetModelPricing_OpenAIGPT54Fallback(t *testing.T) {
|
||||||
svc := newTestBillingService()
|
svc := newTestBillingService()
|
||||||
|
|
||||||
@@ -158,18 +149,6 @@ func TestGetModelPricing_OpenAIGPT54MiniFallback(t *testing.T) {
|
|||||||
require.Zero(t, pricing.LongContextInputThreshold)
|
require.Zero(t, pricing.LongContextInputThreshold)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetModelPricing_OpenAIGPT54NanoFallback(t *testing.T) {
|
|
||||||
svc := newTestBillingService()
|
|
||||||
|
|
||||||
pricing, err := svc.GetModelPricing("gpt-5.4-nano")
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotNil(t, pricing)
|
|
||||||
require.InDelta(t, 2e-7, pricing.InputPricePerToken, 1e-12)
|
|
||||||
require.InDelta(t, 1.25e-6, pricing.OutputPricePerToken, 1e-12)
|
|
||||||
require.InDelta(t, 2e-8, pricing.CacheReadPricePerToken, 1e-12)
|
|
||||||
require.Zero(t, pricing.LongContextInputThreshold)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCalculateCost_OpenAIGPT54LongContextAppliesWholeSessionMultipliers(t *testing.T) {
|
func TestCalculateCost_OpenAIGPT54LongContextAppliesWholeSessionMultipliers(t *testing.T) {
|
||||||
svc := newTestBillingService()
|
svc := newTestBillingService()
|
||||||
|
|
||||||
@@ -204,13 +183,13 @@ func TestGetFallbackPricing_FamilyMatching(t *testing.T) {
|
|||||||
{name: "claude generic model fallback sonnet", model: "claude-foo-bar", expectedInput: 3e-6},
|
{name: "claude generic model fallback sonnet", model: "claude-foo-bar", expectedInput: 3e-6},
|
||||||
{name: "gemini explicit fallback", model: "gemini-3-1-pro", expectedInput: 2e-6},
|
{name: "gemini explicit fallback", model: "gemini-3-1-pro", expectedInput: 2e-6},
|
||||||
{name: "gemini unknown no fallback", model: "gemini-2.0-pro", expectNilPricing: true},
|
{name: "gemini unknown no fallback", model: "gemini-2.0-pro", expectNilPricing: true},
|
||||||
{name: "openai gpt5.1", model: "gpt-5.1", expectedInput: 1.25e-6},
|
|
||||||
{name: "openai gpt5.4", model: "gpt-5.4", expectedInput: 2.5e-6},
|
{name: "openai gpt5.4", model: "gpt-5.4", expectedInput: 2.5e-6},
|
||||||
{name: "openai gpt5.4 mini", model: "gpt-5.4-mini", expectedInput: 7.5e-7},
|
{name: "openai gpt5.4 mini", model: "gpt-5.4-mini", expectedInput: 7.5e-7},
|
||||||
{name: "openai gpt5.4 nano", model: "gpt-5.4-nano", expectedInput: 2e-7},
|
|
||||||
{name: "openai gpt5.3 codex", model: "gpt-5.3-codex", expectedInput: 1.5e-6},
|
{name: "openai gpt5.3 codex", model: "gpt-5.3-codex", expectedInput: 1.5e-6},
|
||||||
{name: "openai gpt5.1 codex max alias", model: "gpt-5.1-codex-max", expectedInput: 1.5e-6},
|
{name: "openai gpt5.3 codex spark", model: "gpt-5.3-codex-spark", expectedInput: 1.5e-6},
|
||||||
{name: "openai codex mini latest alias", model: "codex-mini-latest", expectedInput: 1.5e-6},
|
{name: "openai legacy gpt5.1 falls back to gpt5.4", model: "gpt-5.1", expectedInput: 2.5e-6},
|
||||||
|
{name: "openai legacy gpt5.1 codex falls back to gpt5.3 codex", model: "gpt-5.1-codex", expectedInput: 1.5e-6},
|
||||||
|
{name: "openai legacy codex mini latest falls back to gpt5.3 codex", model: "codex-mini-latest", expectedInput: 1.5e-6},
|
||||||
{name: "openai unknown no fallback", model: "gpt-unknown-model", expectNilPricing: true},
|
{name: "openai unknown no fallback", model: "gpt-unknown-model", expectNilPricing: true},
|
||||||
{name: "non supported family", model: "qwen-max", expectNilPricing: true},
|
{name: "non supported family", model: "qwen-max", expectNilPricing: true},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
var codexModelMap = map[string]string{
|
var codexModelMap = map[string]string{
|
||||||
"gpt-5.4": "gpt-5.4",
|
"gpt-5.4": "gpt-5.4",
|
||||||
"gpt-5.4-mini": "gpt-5.4-mini",
|
"gpt-5.4-mini": "gpt-5.4-mini",
|
||||||
"gpt-5.4-nano": "gpt-5.4-nano",
|
|
||||||
"gpt-5.4-none": "gpt-5.4",
|
"gpt-5.4-none": "gpt-5.4",
|
||||||
"gpt-5.4-low": "gpt-5.4",
|
"gpt-5.4-low": "gpt-5.4",
|
||||||
"gpt-5.4-medium": "gpt-5.4",
|
"gpt-5.4-medium": "gpt-5.4",
|
||||||
@@ -22,52 +21,21 @@ var codexModelMap = map[string]string{
|
|||||||
"gpt-5.3-high": "gpt-5.3-codex",
|
"gpt-5.3-high": "gpt-5.3-codex",
|
||||||
"gpt-5.3-xhigh": "gpt-5.3-codex",
|
"gpt-5.3-xhigh": "gpt-5.3-codex",
|
||||||
"gpt-5.3-codex": "gpt-5.3-codex",
|
"gpt-5.3-codex": "gpt-5.3-codex",
|
||||||
"gpt-5.3-codex-spark": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark": "gpt-5.3-codex-spark",
|
||||||
"gpt-5.3-codex-spark-low": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark-low": "gpt-5.3-codex-spark",
|
||||||
"gpt-5.3-codex-spark-medium": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark-medium": "gpt-5.3-codex-spark",
|
||||||
"gpt-5.3-codex-spark-high": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark-high": "gpt-5.3-codex-spark",
|
||||||
"gpt-5.3-codex-spark-xhigh": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark-xhigh": "gpt-5.3-codex-spark",
|
||||||
"gpt-5.3-codex-low": "gpt-5.3-codex",
|
"gpt-5.3-codex-low": "gpt-5.3-codex",
|
||||||
"gpt-5.3-codex-medium": "gpt-5.3-codex",
|
"gpt-5.3-codex-medium": "gpt-5.3-codex",
|
||||||
"gpt-5.3-codex-high": "gpt-5.3-codex",
|
"gpt-5.3-codex-high": "gpt-5.3-codex",
|
||||||
"gpt-5.3-codex-xhigh": "gpt-5.3-codex",
|
"gpt-5.3-codex-xhigh": "gpt-5.3-codex",
|
||||||
"gpt-5.1-codex": "gpt-5.1-codex",
|
|
||||||
"gpt-5.1-codex-low": "gpt-5.1-codex",
|
|
||||||
"gpt-5.1-codex-medium": "gpt-5.1-codex",
|
|
||||||
"gpt-5.1-codex-high": "gpt-5.1-codex",
|
|
||||||
"gpt-5.1-codex-max": "gpt-5.1-codex-max",
|
|
||||||
"gpt-5.1-codex-max-low": "gpt-5.1-codex-max",
|
|
||||||
"gpt-5.1-codex-max-medium": "gpt-5.1-codex-max",
|
|
||||||
"gpt-5.1-codex-max-high": "gpt-5.1-codex-max",
|
|
||||||
"gpt-5.1-codex-max-xhigh": "gpt-5.1-codex-max",
|
|
||||||
"gpt-5.2": "gpt-5.2",
|
"gpt-5.2": "gpt-5.2",
|
||||||
"gpt-5.2-none": "gpt-5.2",
|
"gpt-5.2-none": "gpt-5.2",
|
||||||
"gpt-5.2-low": "gpt-5.2",
|
"gpt-5.2-low": "gpt-5.2",
|
||||||
"gpt-5.2-medium": "gpt-5.2",
|
"gpt-5.2-medium": "gpt-5.2",
|
||||||
"gpt-5.2-high": "gpt-5.2",
|
"gpt-5.2-high": "gpt-5.2",
|
||||||
"gpt-5.2-xhigh": "gpt-5.2",
|
"gpt-5.2-xhigh": "gpt-5.2",
|
||||||
"gpt-5.2-codex": "gpt-5.2-codex",
|
|
||||||
"gpt-5.2-codex-low": "gpt-5.2-codex",
|
|
||||||
"gpt-5.2-codex-medium": "gpt-5.2-codex",
|
|
||||||
"gpt-5.2-codex-high": "gpt-5.2-codex",
|
|
||||||
"gpt-5.2-codex-xhigh": "gpt-5.2-codex",
|
|
||||||
"gpt-5.1-codex-mini": "gpt-5.1-codex-mini",
|
|
||||||
"gpt-5.1-codex-mini-medium": "gpt-5.1-codex-mini",
|
|
||||||
"gpt-5.1-codex-mini-high": "gpt-5.1-codex-mini",
|
|
||||||
"gpt-5.1": "gpt-5.1",
|
|
||||||
"gpt-5.1-none": "gpt-5.1",
|
|
||||||
"gpt-5.1-low": "gpt-5.1",
|
|
||||||
"gpt-5.1-medium": "gpt-5.1",
|
|
||||||
"gpt-5.1-high": "gpt-5.1",
|
|
||||||
"gpt-5.1-chat-latest": "gpt-5.1",
|
|
||||||
"gpt-5-codex": "gpt-5.1-codex",
|
|
||||||
"codex-mini-latest": "gpt-5.1-codex-mini",
|
|
||||||
"gpt-5-codex-mini": "gpt-5.1-codex-mini",
|
|
||||||
"gpt-5-codex-mini-medium": "gpt-5.1-codex-mini",
|
|
||||||
"gpt-5-codex-mini-high": "gpt-5.1-codex-mini",
|
|
||||||
"gpt-5": "gpt-5.1",
|
|
||||||
"gpt-5-mini": "gpt-5.1",
|
|
||||||
"gpt-5-nano": "gpt-5.1",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type codexTransformResult struct {
|
type codexTransformResult struct {
|
||||||
@@ -220,7 +188,7 @@ func applyCodexOAuthTransform(reqBody map[string]any, isCodexCLI bool, isCompact
|
|||||||
|
|
||||||
func normalizeCodexModel(model string) string {
|
func normalizeCodexModel(model string) string {
|
||||||
if model == "" {
|
if model == "" {
|
||||||
return "gpt-5.1"
|
return "gpt-5.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
modelID := model
|
modelID := model
|
||||||
@@ -238,49 +206,29 @@ func normalizeCodexModel(model string) string {
|
|||||||
if strings.Contains(normalized, "gpt-5.4-mini") || strings.Contains(normalized, "gpt 5.4 mini") {
|
if strings.Contains(normalized, "gpt-5.4-mini") || strings.Contains(normalized, "gpt 5.4 mini") {
|
||||||
return "gpt-5.4-mini"
|
return "gpt-5.4-mini"
|
||||||
}
|
}
|
||||||
if strings.Contains(normalized, "gpt-5.4-nano") || strings.Contains(normalized, "gpt 5.4 nano") {
|
|
||||||
return "gpt-5.4-nano"
|
|
||||||
}
|
|
||||||
if strings.Contains(normalized, "gpt-5.4") || strings.Contains(normalized, "gpt 5.4") {
|
if strings.Contains(normalized, "gpt-5.4") || strings.Contains(normalized, "gpt 5.4") {
|
||||||
return "gpt-5.4"
|
return "gpt-5.4"
|
||||||
}
|
}
|
||||||
if strings.Contains(normalized, "gpt-5.2-codex") || strings.Contains(normalized, "gpt 5.2 codex") {
|
|
||||||
return "gpt-5.2-codex"
|
|
||||||
}
|
|
||||||
if strings.Contains(normalized, "gpt-5.2") || strings.Contains(normalized, "gpt 5.2") {
|
if strings.Contains(normalized, "gpt-5.2") || strings.Contains(normalized, "gpt 5.2") {
|
||||||
return "gpt-5.2"
|
return "gpt-5.2"
|
||||||
}
|
}
|
||||||
|
if strings.Contains(normalized, "gpt-5.3-codex-spark") || strings.Contains(normalized, "gpt 5.3 codex spark") {
|
||||||
|
return "gpt-5.3-codex-spark"
|
||||||
|
}
|
||||||
if strings.Contains(normalized, "gpt-5.3-codex") || strings.Contains(normalized, "gpt 5.3 codex") {
|
if strings.Contains(normalized, "gpt-5.3-codex") || strings.Contains(normalized, "gpt 5.3 codex") {
|
||||||
return "gpt-5.3-codex"
|
return "gpt-5.3-codex"
|
||||||
}
|
}
|
||||||
if strings.Contains(normalized, "gpt-5.3") || strings.Contains(normalized, "gpt 5.3") {
|
if strings.Contains(normalized, "gpt-5.3") || strings.Contains(normalized, "gpt 5.3") {
|
||||||
return "gpt-5.3-codex"
|
return "gpt-5.3-codex"
|
||||||
}
|
}
|
||||||
if strings.Contains(normalized, "gpt-5.1-codex-max") || strings.Contains(normalized, "gpt 5.1 codex max") {
|
|
||||||
return "gpt-5.1-codex-max"
|
|
||||||
}
|
|
||||||
if strings.Contains(normalized, "gpt-5.1-codex-mini") || strings.Contains(normalized, "gpt 5.1 codex mini") {
|
|
||||||
return "gpt-5.1-codex-mini"
|
|
||||||
}
|
|
||||||
if strings.Contains(normalized, "codex-mini-latest") ||
|
|
||||||
strings.Contains(normalized, "gpt-5-codex-mini") ||
|
|
||||||
strings.Contains(normalized, "gpt 5 codex mini") {
|
|
||||||
return "codex-mini-latest"
|
|
||||||
}
|
|
||||||
if strings.Contains(normalized, "gpt-5.1-codex") || strings.Contains(normalized, "gpt 5.1 codex") {
|
|
||||||
return "gpt-5.1-codex"
|
|
||||||
}
|
|
||||||
if strings.Contains(normalized, "gpt-5.1") || strings.Contains(normalized, "gpt 5.1") {
|
|
||||||
return "gpt-5.1"
|
|
||||||
}
|
|
||||||
if strings.Contains(normalized, "codex") {
|
if strings.Contains(normalized, "codex") {
|
||||||
return "gpt-5.1-codex"
|
return "gpt-5.3-codex"
|
||||||
}
|
}
|
||||||
if strings.Contains(normalized, "gpt-5") || strings.Contains(normalized, "gpt 5") {
|
if strings.Contains(normalized, "gpt-5") || strings.Contains(normalized, "gpt 5") {
|
||||||
return "gpt-5.1"
|
return "gpt-5.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
return "gpt-5.1"
|
return "gpt-5.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
func normalizeOpenAIModelForUpstream(account *Account, model string) string {
|
func normalizeOpenAIModelForUpstream(account *Account, model string) string {
|
||||||
|
|||||||
@@ -240,15 +240,13 @@ func TestNormalizeCodexModel_Gpt53(t *testing.T) {
|
|||||||
"gpt 5.4": "gpt-5.4",
|
"gpt 5.4": "gpt-5.4",
|
||||||
"gpt-5.4-mini": "gpt-5.4-mini",
|
"gpt-5.4-mini": "gpt-5.4-mini",
|
||||||
"gpt 5.4 mini": "gpt-5.4-mini",
|
"gpt 5.4 mini": "gpt-5.4-mini",
|
||||||
"gpt-5.4-nano": "gpt-5.4-nano",
|
|
||||||
"gpt 5.4 nano": "gpt-5.4-nano",
|
|
||||||
"gpt-5.3": "gpt-5.3-codex",
|
"gpt-5.3": "gpt-5.3-codex",
|
||||||
"gpt-5.3-codex": "gpt-5.3-codex",
|
"gpt-5.3-codex": "gpt-5.3-codex",
|
||||||
"gpt-5.3-codex-xhigh": "gpt-5.3-codex",
|
"gpt-5.3-codex-xhigh": "gpt-5.3-codex",
|
||||||
"gpt-5.3-codex-spark": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark": "gpt-5.3-codex-spark",
|
||||||
"gpt 5.3 codex spark": "gpt-5.3-codex",
|
"gpt 5.3 codex spark": "gpt-5.3-codex-spark",
|
||||||
"gpt-5.3-codex-spark-high": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark-high": "gpt-5.3-codex-spark",
|
||||||
"gpt-5.3-codex-spark-xhigh": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark-xhigh": "gpt-5.3-codex-spark",
|
||||||
"gpt 5.3 codex": "gpt-5.3-codex",
|
"gpt 5.3 codex": "gpt-5.3-codex",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,6 +255,26 @@ func TestNormalizeCodexModel_Gpt53(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNormalizeCodexModel_RemovedModelsFallbackToSupportedTargets(t *testing.T) {
|
||||||
|
cases := map[string]string{
|
||||||
|
"": "gpt-5.4",
|
||||||
|
"gpt-5": "gpt-5.4",
|
||||||
|
"gpt-5-mini": "gpt-5.4",
|
||||||
|
"gpt-5-nano": "gpt-5.4",
|
||||||
|
"gpt-5.1": "gpt-5.4",
|
||||||
|
"gpt-5.1-codex": "gpt-5.3-codex",
|
||||||
|
"gpt-5.1-codex-max": "gpt-5.3-codex",
|
||||||
|
"gpt-5.1-codex-mini": "gpt-5.3-codex",
|
||||||
|
"gpt-5.2-codex": "gpt-5.2",
|
||||||
|
"codex-mini-latest": "gpt-5.3-codex",
|
||||||
|
"gpt-5-codex": "gpt-5.3-codex",
|
||||||
|
}
|
||||||
|
|
||||||
|
for input, expected := range cases {
|
||||||
|
require.Equal(t, expected, normalizeCodexModel(input))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestApplyCodexOAuthTransform_PreservesBareSparkModel(t *testing.T) {
|
func TestApplyCodexOAuthTransform_PreservesBareSparkModel(t *testing.T) {
|
||||||
reqBody := map[string]any{
|
reqBody := map[string]any{
|
||||||
"model": "gpt-5.3-codex-spark",
|
"model": "gpt-5.3-codex-spark",
|
||||||
|
|||||||
@@ -10,8 +10,14 @@ import (
|
|||||||
const compatPromptCacheKeyPrefix = "compat_cc_"
|
const compatPromptCacheKeyPrefix = "compat_cc_"
|
||||||
|
|
||||||
func shouldAutoInjectPromptCacheKeyForCompat(model string) bool {
|
func shouldAutoInjectPromptCacheKeyForCompat(model string) bool {
|
||||||
switch normalizeCodexModel(strings.TrimSpace(model)) {
|
trimmed := strings.TrimSpace(strings.ToLower(model))
|
||||||
case "gpt-5.4", "gpt-5.3-codex":
|
// 仅对 Codex OAuth 路径支持的 GPT-5 族开启自动注入,避免 normalizeCodexModel
|
||||||
|
// 的默认兜底把任意模型(如 gpt-4o、claude-*)误判为 gpt-5.4。
|
||||||
|
if !strings.Contains(trimmed, "gpt-5") && !strings.Contains(trimmed, "codex") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
switch normalizeCodexModel(trimmed) {
|
||||||
|
case "gpt-5.4", "gpt-5.3-codex", "gpt-5.3-codex-spark":
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -69,14 +69,14 @@ func TestResolveOpenAIForwardModel(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResolveOpenAIForwardModel_PreventsClaudeModelFromFallingBackToGpt51(t *testing.T) {
|
func TestResolveOpenAIForwardModel_PreventsClaudeModelFromFallingBackToGpt54(t *testing.T) {
|
||||||
account := &Account{
|
account := &Account{
|
||||||
Credentials: map[string]any{},
|
Credentials: map[string]any{},
|
||||||
}
|
}
|
||||||
|
|
||||||
withoutDefault := normalizeCodexModel(resolveOpenAIForwardModel(account, "claude-opus-4-6", ""))
|
withoutDefault := normalizeCodexModel(resolveOpenAIForwardModel(account, "claude-opus-4-6", ""))
|
||||||
if withoutDefault != "gpt-5.1" {
|
if withoutDefault != "gpt-5.4" {
|
||||||
t.Fatalf("normalizeCodexModel(...) = %q, want %q", withoutDefault, "gpt-5.1")
|
t.Fatalf("normalizeCodexModel(...) = %q, want %q", withoutDefault, "gpt-5.4")
|
||||||
}
|
}
|
||||||
|
|
||||||
withDefault := normalizeCodexModel(resolveOpenAIForwardModel(account, "claude-opus-4-6", "gpt-5.4"))
|
withDefault := normalizeCodexModel(resolveOpenAIForwardModel(account, "claude-opus-4-6", "gpt-5.4"))
|
||||||
@@ -87,9 +87,9 @@ func TestResolveOpenAIForwardModel_PreventsClaudeModelFromFallingBackToGpt51(t *
|
|||||||
|
|
||||||
func TestNormalizeCodexModel(t *testing.T) {
|
func TestNormalizeCodexModel(t *testing.T) {
|
||||||
cases := map[string]string{
|
cases := map[string]string{
|
||||||
"gpt-5.3-codex-spark": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark": "gpt-5.3-codex-spark",
|
||||||
"gpt-5.3-codex-spark-high": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark-high": "gpt-5.3-codex-spark",
|
||||||
"gpt-5.3-codex-spark-xhigh": "gpt-5.3-codex",
|
"gpt-5.3-codex-spark-xhigh": "gpt-5.3-codex-spark",
|
||||||
"gpt-5.3": "gpt-5.3-codex",
|
"gpt-5.3": "gpt-5.3-codex",
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ func TestNormalizeOpenAIModelForUpstream(t *testing.T) {
|
|||||||
name: "oauth keeps codex normalization behavior",
|
name: "oauth keeps codex normalization behavior",
|
||||||
account: &Account{Type: AccountTypeOAuth},
|
account: &Account{Type: AccountTypeOAuth},
|
||||||
model: "gemini-3-flash-preview",
|
model: "gemini-3-flash-preview",
|
||||||
want: "gpt-5.1",
|
want: "gpt-5.4",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "apikey preserves custom compatible model",
|
name: "apikey preserves custom compatible model",
|
||||||
|
|||||||
@@ -617,66 +617,6 @@ function generateOpenCodeConfig(platform: string, baseUrl: string, apiKey: strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const openaiModels = {
|
const openaiModels = {
|
||||||
'gpt-5-codex': {
|
|
||||||
name: 'GPT-5 Codex',
|
|
||||||
limit: {
|
|
||||||
context: 400000,
|
|
||||||
output: 128000
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
store: false
|
|
||||||
},
|
|
||||||
variants: {
|
|
||||||
low: {},
|
|
||||||
medium: {},
|
|
||||||
high: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'gpt-5.1-codex': {
|
|
||||||
name: 'GPT-5.1 Codex',
|
|
||||||
limit: {
|
|
||||||
context: 400000,
|
|
||||||
output: 128000
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
store: false
|
|
||||||
},
|
|
||||||
variants: {
|
|
||||||
low: {},
|
|
||||||
medium: {},
|
|
||||||
high: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'gpt-5.1-codex-max': {
|
|
||||||
name: 'GPT-5.1 Codex Max',
|
|
||||||
limit: {
|
|
||||||
context: 400000,
|
|
||||||
output: 128000
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
store: false
|
|
||||||
},
|
|
||||||
variants: {
|
|
||||||
low: {},
|
|
||||||
medium: {},
|
|
||||||
high: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'gpt-5.1-codex-mini': {
|
|
||||||
name: 'GPT-5.1 Codex Mini',
|
|
||||||
limit: {
|
|
||||||
context: 400000,
|
|
||||||
output: 128000
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
store: false
|
|
||||||
},
|
|
||||||
variants: {
|
|
||||||
low: {},
|
|
||||||
medium: {},
|
|
||||||
high: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'gpt-5.2': {
|
'gpt-5.2': {
|
||||||
name: 'GPT-5.2',
|
name: 'GPT-5.2',
|
||||||
limit: {
|
limit: {
|
||||||
@@ -725,22 +665,6 @@ function generateOpenCodeConfig(platform: string, baseUrl: string, apiKey: strin
|
|||||||
xhigh: {}
|
xhigh: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'gpt-5.4-nano': {
|
|
||||||
name: 'GPT-5.4 Nano',
|
|
||||||
limit: {
|
|
||||||
context: 400000,
|
|
||||||
output: 128000
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
store: false
|
|
||||||
},
|
|
||||||
variants: {
|
|
||||||
low: {},
|
|
||||||
medium: {},
|
|
||||||
high: {},
|
|
||||||
xhigh: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'gpt-5.3-codex-spark': {
|
'gpt-5.3-codex-spark': {
|
||||||
name: 'GPT-5.3 Codex Spark',
|
name: 'GPT-5.3 Codex Spark',
|
||||||
limit: {
|
limit: {
|
||||||
@@ -773,22 +697,6 @@ function generateOpenCodeConfig(platform: string, baseUrl: string, apiKey: strin
|
|||||||
xhigh: {}
|
xhigh: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'gpt-5.2-codex': {
|
|
||||||
name: 'GPT-5.2 Codex',
|
|
||||||
limit: {
|
|
||||||
context: 400000,
|
|
||||||
output: 128000
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
store: false
|
|
||||||
},
|
|
||||||
variants: {
|
|
||||||
low: {},
|
|
||||||
medium: {},
|
|
||||||
high: {},
|
|
||||||
xhigh: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'codex-mini-latest': {
|
'codex-mini-latest': {
|
||||||
name: 'Codex Mini',
|
name: 'Codex Mini',
|
||||||
limit: {
|
limit: {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ vi.mock('@/composables/useClipboard', () => ({
|
|||||||
import UseKeyModal from '../UseKeyModal.vue'
|
import UseKeyModal from '../UseKeyModal.vue'
|
||||||
|
|
||||||
describe('UseKeyModal', () => {
|
describe('UseKeyModal', () => {
|
||||||
it('renders updated GPT-5.4 mini/nano names in OpenCode config', async () => {
|
it('renders GPT-5.4 mini entry in OpenCode config', async () => {
|
||||||
const wrapper = mount(UseKeyModal, {
|
const wrapper = mount(UseKeyModal, {
|
||||||
props: {
|
props: {
|
||||||
show: true,
|
show: true,
|
||||||
@@ -48,6 +48,6 @@ describe('UseKeyModal', () => {
|
|||||||
const codeBlock = wrapper.find('pre code')
|
const codeBlock = wrapper.find('pre code')
|
||||||
expect(codeBlock.exists()).toBe(true)
|
expect(codeBlock.exists()).toBe(true)
|
||||||
expect(codeBlock.text()).toContain('"name": "GPT-5.4 Mini"')
|
expect(codeBlock.text()).toContain('"name": "GPT-5.4 Mini"')
|
||||||
expect(codeBlock.text()).toContain('"name": "GPT-5.4 Nano"')
|
expect(codeBlock.text()).not.toContain('"name": "GPT-5.4 Nano"')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -12,10 +12,20 @@ describe('useModelWhitelist', () => {
|
|||||||
|
|
||||||
expect(models).toContain('gpt-5.4')
|
expect(models).toContain('gpt-5.4')
|
||||||
expect(models).toContain('gpt-5.4-mini')
|
expect(models).toContain('gpt-5.4-mini')
|
||||||
expect(models).toContain('gpt-5.4-nano')
|
|
||||||
expect(models).toContain('gpt-5.4-2026-03-05')
|
expect(models).toContain('gpt-5.4-2026-03-05')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('openai 模型列表不再暴露已下线的 ChatGPT 登录 Codex 模型', () => {
|
||||||
|
const models = getModelsByPlatform('openai')
|
||||||
|
|
||||||
|
expect(models).not.toContain('gpt-5')
|
||||||
|
expect(models).not.toContain('gpt-5.1')
|
||||||
|
expect(models).not.toContain('gpt-5.1-codex')
|
||||||
|
expect(models).not.toContain('gpt-5.1-codex-max')
|
||||||
|
expect(models).not.toContain('gpt-5.1-codex-mini')
|
||||||
|
expect(models).not.toContain('gpt-5.2-codex')
|
||||||
|
})
|
||||||
|
|
||||||
it('antigravity 模型列表包含图片模型兼容项', () => {
|
it('antigravity 模型列表包含图片模型兼容项', () => {
|
||||||
const models = getModelsByPlatform('antigravity')
|
const models = getModelsByPlatform('antigravity')
|
||||||
|
|
||||||
@@ -55,12 +65,11 @@ describe('useModelWhitelist', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('whitelist keeps GPT-5.4 mini and nano exact mappings', () => {
|
it('whitelist keeps GPT-5.4 mini exact mappings', () => {
|
||||||
const mapping = buildModelMappingObject('whitelist', ['gpt-5.4-mini', 'gpt-5.4-nano'], [])
|
const mapping = buildModelMappingObject('whitelist', ['gpt-5.4-mini'], [])
|
||||||
|
|
||||||
expect(mapping).toEqual({
|
expect(mapping).toEqual({
|
||||||
'gpt-5.4-mini': 'gpt-5.4-mini',
|
'gpt-5.4-mini': 'gpt-5.4-mini'
|
||||||
'gpt-5.4-nano': 'gpt-5.4-nano'
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,19 +13,11 @@ const openaiModels = [
|
|||||||
'o1', 'o1-preview', 'o1-mini', 'o1-pro',
|
'o1', 'o1-preview', 'o1-mini', 'o1-pro',
|
||||||
'o3', 'o3-mini', 'o3-pro',
|
'o3', 'o3-mini', 'o3-pro',
|
||||||
'o4-mini',
|
'o4-mini',
|
||||||
// GPT-5 系列(同步后端定价文件)
|
|
||||||
'gpt-5', 'gpt-5-2025-08-07', 'gpt-5-chat', 'gpt-5-chat-latest',
|
|
||||||
'gpt-5-codex', 'gpt-5.3-codex-spark', 'gpt-5-pro', 'gpt-5-pro-2025-10-06',
|
|
||||||
'gpt-5-mini', 'gpt-5-mini-2025-08-07',
|
|
||||||
'gpt-5-nano', 'gpt-5-nano-2025-08-07',
|
|
||||||
// GPT-5.1 系列
|
|
||||||
'gpt-5.1', 'gpt-5.1-2025-11-13', 'gpt-5.1-chat-latest',
|
|
||||||
'gpt-5.1-codex', 'gpt-5.1-codex-max', 'gpt-5.1-codex-mini',
|
|
||||||
// GPT-5.2 系列
|
// GPT-5.2 系列
|
||||||
'gpt-5.2', 'gpt-5.2-2025-12-11', 'gpt-5.2-chat-latest',
|
'gpt-5.2', 'gpt-5.2-2025-12-11', 'gpt-5.2-chat-latest',
|
||||||
'gpt-5.2-codex', 'gpt-5.2-pro', 'gpt-5.2-pro-2025-12-11',
|
'gpt-5.2-pro', 'gpt-5.2-pro-2025-12-11',
|
||||||
// GPT-5.4 系列
|
// GPT-5.4 系列
|
||||||
'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.4-nano', 'gpt-5.4-2026-03-05',
|
'gpt-5.4', 'gpt-5.4-mini', 'gpt-5.4-2026-03-05',
|
||||||
// GPT-5.3 系列
|
// GPT-5.3 系列
|
||||||
'gpt-5.3-codex', 'gpt-5.3-codex-spark',
|
'gpt-5.3-codex', 'gpt-5.3-codex-spark',
|
||||||
'chatgpt-4o-latest',
|
'chatgpt-4o-latest',
|
||||||
@@ -264,12 +256,9 @@ const openaiPresetMappings = [
|
|||||||
{ label: 'GPT-4.1', from: 'gpt-4.1', to: 'gpt-4.1', color: 'bg-indigo-100 text-indigo-700 hover:bg-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-400' },
|
{ label: 'GPT-4.1', from: 'gpt-4.1', to: 'gpt-4.1', color: 'bg-indigo-100 text-indigo-700 hover:bg-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-400' },
|
||||||
{ label: 'o1', from: 'o1', to: 'o1', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
{ label: 'o1', from: 'o1', to: 'o1', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
||||||
{ label: 'o3', from: 'o3', to: 'o3', color: 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400' },
|
{ label: 'o3', from: 'o3', to: 'o3', color: 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400' },
|
||||||
{ label: 'GPT-5', from: 'gpt-5', to: 'gpt-5', color: 'bg-amber-100 text-amber-700 hover:bg-amber-200 dark:bg-amber-900/30 dark:text-amber-400' },
|
|
||||||
{ label: 'GPT-5.3 Codex Spark', from: 'gpt-5.3-codex-spark', to: 'gpt-5.3-codex-spark', color: 'bg-teal-100 text-teal-700 hover:bg-teal-200 dark:bg-teal-900/30 dark:text-teal-400' },
|
{ label: 'GPT-5.3 Codex Spark', from: 'gpt-5.3-codex-spark', to: 'gpt-5.3-codex-spark', color: 'bg-teal-100 text-teal-700 hover:bg-teal-200 dark:bg-teal-900/30 dark:text-teal-400' },
|
||||||
{ label: 'GPT-5.1', from: 'gpt-5.1', to: 'gpt-5.1', color: 'bg-orange-100 text-orange-700 hover:bg-orange-200 dark:bg-orange-900/30 dark:text-orange-400' },
|
|
||||||
{ label: 'GPT-5.2', from: 'gpt-5.2', to: 'gpt-5.2', color: 'bg-red-100 text-red-700 hover:bg-red-200 dark:bg-red-900/30 dark:text-red-400' },
|
{ label: 'GPT-5.2', from: 'gpt-5.2', to: 'gpt-5.2', color: 'bg-red-100 text-red-700 hover:bg-red-200 dark:bg-red-900/30 dark:text-red-400' },
|
||||||
{ label: 'GPT-5.4', from: 'gpt-5.4', to: 'gpt-5.4', color: 'bg-rose-100 text-rose-700 hover:bg-rose-200 dark:bg-rose-900/30 dark:text-rose-400' },
|
{ label: 'GPT-5.4', from: 'gpt-5.4', to: 'gpt-5.4', color: 'bg-rose-100 text-rose-700 hover:bg-rose-200 dark:bg-rose-900/30 dark:text-rose-400' },
|
||||||
{ label: 'GPT-5.1 Codex', from: 'gpt-5.1-codex', to: 'gpt-5.1-codex', color: 'bg-cyan-100 text-cyan-700 hover:bg-cyan-200 dark:bg-cyan-900/30 dark:text-cyan-400' },
|
|
||||||
{ label: 'Haiku→5.4', from: 'claude-haiku-4-5-20251001', to: 'gpt-5.4', color: 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400' },
|
{ label: 'Haiku→5.4', from: 'claude-haiku-4-5-20251001', to: 'gpt-5.4', color: 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-400' },
|
||||||
{ label: 'Opus→5.4', from: 'claude-opus-4-6', to: 'gpt-5.4', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
{ label: 'Opus→5.4', from: 'claude-opus-4-6', to: 'gpt-5.4', color: 'bg-purple-100 text-purple-700 hover:bg-purple-200 dark:bg-purple-900/30 dark:text-purple-400' },
|
||||||
{ label: 'Sonnet→5.4', from: 'claude-sonnet-4-6', to: 'gpt-5.4', color: 'bg-blue-100 text-blue-700 hover:bg-blue-200 dark:bg-blue-900/30 dark:text-blue-400' }
|
{ label: 'Sonnet→5.4', from: 'claude-sonnet-4-6', to: 'gpt-5.4', color: 'bg-blue-100 text-blue-700 hover:bg-blue-200 dark:bg-blue-900/30 dark:text-blue-400' }
|
||||||
|
|||||||
Reference in New Issue
Block a user