mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 18:37:24 +00:00
Price gpt-6.1-sol (and its effort/suffix variants) at its own base and long-context rates instead of leaving it unpriced. Co-authored-by: Rongzheng Liu <tianlrz@users.noreply.github.com>
205 lines
6.4 KiB
TypeScript
205 lines
6.4 KiB
TypeScript
type CodexTokenRates = { input: number; cachedInput: number; output: number }
|
|
export type CodexModelPricing = CodexTokenRates & {
|
|
/** Long-context rates apply to the entire request, including cached input and output. */
|
|
longContext?: CodexTokenRates
|
|
}
|
|
|
|
export const LONG_CONTEXT_THRESHOLD_TOKENS = 272_000
|
|
|
|
export const MODEL_PRICING: Record<string, CodexModelPricing> = {
|
|
'gpt-5': { input: 1.25, cachedInput: 0.125, output: 10 },
|
|
'gpt-5.1': { input: 1.25, cachedInput: 0.125, output: 10 },
|
|
'gpt-5.1-codex': { input: 1.25, cachedInput: 0.125, output: 10 },
|
|
'gpt-5.1-codex-max': { input: 1.25, cachedInput: 0.125, output: 10 },
|
|
'gpt-5.2': { input: 1.75, cachedInput: 0.175, output: 14 },
|
|
'gpt-5.2-pro': { input: 21, cachedInput: 21, output: 168 },
|
|
'gpt-5.2-codex': { input: 1.75, cachedInput: 0.175, output: 14 },
|
|
'gpt-5.3': { input: 1.75, cachedInput: 0.175, output: 14 },
|
|
'gpt-5.3-codex': { input: 1.75, cachedInput: 0.175, output: 14 },
|
|
'gpt-5.3-codex-spark': { input: 1.75, cachedInput: 0.175, output: 14 },
|
|
'gpt-5.4-mini': { input: 0.75, cachedInput: 0.075, output: 4.5 },
|
|
'gpt-5.4-nano': { input: 0.2, cachedInput: 0.02, output: 1.25 },
|
|
'gpt-5.4-pro': {
|
|
input: 30,
|
|
cachedInput: 30,
|
|
output: 180,
|
|
longContext: { input: 60, cachedInput: 60, output: 270 }
|
|
},
|
|
'gpt-5.4': {
|
|
input: 2.5,
|
|
cachedInput: 0.25,
|
|
output: 15,
|
|
longContext: { input: 5, cachedInput: 0.5, output: 22.5 }
|
|
},
|
|
'gpt-5.5-pro': {
|
|
input: 30,
|
|
cachedInput: 30,
|
|
output: 180,
|
|
longContext: { input: 60, cachedInput: 60, output: 270 }
|
|
},
|
|
'gpt-5.5': {
|
|
input: 5,
|
|
cachedInput: 0.5,
|
|
output: 30,
|
|
longContext: { input: 10, cachedInput: 1, output: 45 }
|
|
},
|
|
// Promotional Sol rates are listed through at least 2026-11-21.
|
|
'gpt-5.6-sol': {
|
|
input: 4,
|
|
cachedInput: 0.4,
|
|
output: 20,
|
|
longContext: { input: 8, cachedInput: 0.8, output: 30 }
|
|
},
|
|
'gpt-5.6-terra': {
|
|
input: 2,
|
|
cachedInput: 0.2,
|
|
output: 12,
|
|
longContext: { input: 4, cachedInput: 0.4, output: 18 }
|
|
},
|
|
'gpt-5.6-luna': {
|
|
input: 0.2,
|
|
cachedInput: 0.02,
|
|
output: 1.2,
|
|
longContext: { input: 0.4, cachedInput: 0.04, output: 1.8 }
|
|
},
|
|
'gpt-6-astra': {
|
|
input: 10,
|
|
cachedInput: 1,
|
|
output: 50,
|
|
longContext: { input: 20, cachedInput: 2, output: 75 }
|
|
},
|
|
'gpt-6-sol': {
|
|
input: 2,
|
|
cachedInput: 0.2,
|
|
output: 10,
|
|
longContext: { input: 4, cachedInput: 0.4, output: 15 }
|
|
},
|
|
'gpt-6.1-sol': {
|
|
input: 2,
|
|
cachedInput: 0.1,
|
|
output: 10,
|
|
longContext: { input: 4, cachedInput: 0.2, output: 15 }
|
|
},
|
|
'gpt-6-luna': {
|
|
input: 0.1,
|
|
cachedInput: 0.01,
|
|
output: 0.5,
|
|
longContext: { input: 0.2, cachedInput: 0.02, output: 0.75 }
|
|
}
|
|
}
|
|
|
|
const REASONING_TIER_SUFFIXES = ['minimal', 'low', 'medium', 'high', 'xhigh', 'auto', 'none']
|
|
// Preserve model names ending in "-max"; only strip max/ultra inside parentheses.
|
|
const PARENTHESIZED_REASONING_TIERS = [...REASONING_TIER_SUFFIXES, 'max', 'ultra']
|
|
|
|
function stripParenthesizedReasoningTier(model: string): string | null {
|
|
const match = model.match(/^(.*)\(([^()]*)\)$/)
|
|
if (!match) {
|
|
return model
|
|
}
|
|
const tier = match[2].trim().toLowerCase()
|
|
if (!PARENTHESIZED_REASONING_TIERS.includes(tier)) {
|
|
return null
|
|
}
|
|
return match[1]
|
|
}
|
|
|
|
function stripDashReasoningTiers(model: string): string {
|
|
let current = model
|
|
for (let index = 0; index < 4; index++) {
|
|
const suffix = REASONING_TIER_SUFFIXES.find((tier) => current.endsWith(`-${tier}`))
|
|
if (!suffix) {
|
|
return current
|
|
}
|
|
current = current.slice(0, -suffix.length - 1)
|
|
}
|
|
return current
|
|
}
|
|
|
|
export function normalizeModelForPricing(model: string | null): string | null {
|
|
if (!model) {
|
|
return null
|
|
}
|
|
|
|
const lower = stripParenthesizedReasoningTier(model.toLowerCase().trim())
|
|
if (!lower) {
|
|
return null
|
|
}
|
|
|
|
const normalized = stripDashReasoningTiers(lower)
|
|
if (normalized === 'gpt-5' || normalized === 'gpt-5-codex') {
|
|
return 'gpt-5'
|
|
}
|
|
if (normalized === 'gpt-5.1-codex-max' || normalized.startsWith('gpt-5.1-codex-max-')) {
|
|
return 'gpt-5.1-codex-max'
|
|
}
|
|
if (normalized === 'gpt-5.1-codex' || normalized.startsWith('gpt-5.1-codex-')) {
|
|
return 'gpt-5.1-codex'
|
|
}
|
|
if (normalized === 'gpt-5.1' || normalized.startsWith('gpt-5.1-')) {
|
|
return 'gpt-5.1'
|
|
}
|
|
if (normalized === 'gpt-5.2-pro' || normalized.startsWith('gpt-5.2-pro-')) {
|
|
return 'gpt-5.2-pro'
|
|
}
|
|
if (normalized === 'gpt-5.2-codex' || normalized.startsWith('gpt-5.2-codex-')) {
|
|
return 'gpt-5.2-codex'
|
|
}
|
|
if (normalized === 'gpt-5.2' || normalized.startsWith('gpt-5.2-')) {
|
|
return 'gpt-5.2'
|
|
}
|
|
if (normalized === 'gpt-5.3-codex-spark' || normalized.startsWith('gpt-5.3-codex-spark-')) {
|
|
return 'gpt-5.3-codex-spark'
|
|
}
|
|
if (normalized === 'gpt-5.3-codex' || normalized.startsWith('gpt-5.3-codex-')) {
|
|
return 'gpt-5.3-codex'
|
|
}
|
|
if (normalized === 'gpt-5.3' || normalized.startsWith('gpt-5.3-')) {
|
|
return 'gpt-5.3'
|
|
}
|
|
if (normalized === 'gpt-5.4-mini' || normalized.startsWith('gpt-5.4-mini-')) {
|
|
return 'gpt-5.4-mini'
|
|
}
|
|
if (normalized === 'gpt-5.4-nano' || normalized.startsWith('gpt-5.4-nano-')) {
|
|
return 'gpt-5.4-nano'
|
|
}
|
|
if (normalized === 'gpt-5.4-pro' || normalized.startsWith('gpt-5.4-pro-')) {
|
|
return 'gpt-5.4-pro'
|
|
}
|
|
if (normalized === 'gpt-5.4' || normalized.startsWith('gpt-5.4-')) {
|
|
return 'gpt-5.4'
|
|
}
|
|
if (normalized === 'gpt-5.5-pro' || normalized.startsWith('gpt-5.5-pro-')) {
|
|
return 'gpt-5.5-pro'
|
|
}
|
|
if (normalized === 'gpt-5.5' || normalized.startsWith('gpt-5.5-')) {
|
|
return 'gpt-5.5'
|
|
}
|
|
if (normalized === 'gpt-5.6-sol' || normalized.startsWith('gpt-5.6-sol-')) {
|
|
return 'gpt-5.6-sol'
|
|
}
|
|
if (normalized === 'gpt-5.6-terra' || normalized.startsWith('gpt-5.6-terra-')) {
|
|
return 'gpt-5.6-terra'
|
|
}
|
|
if (normalized === 'gpt-5.6-luna' || normalized.startsWith('gpt-5.6-luna-')) {
|
|
return 'gpt-5.6-luna'
|
|
}
|
|
if (normalized === 'gpt-6-astra' || normalized.startsWith('gpt-6-astra-')) {
|
|
return 'gpt-6-astra'
|
|
}
|
|
if (normalized === 'gpt-6-sol' || normalized.startsWith('gpt-6-sol-')) {
|
|
return 'gpt-6-sol'
|
|
}
|
|
if (normalized === 'gpt-6.1-sol' || normalized.startsWith('gpt-6.1-sol-')) {
|
|
return 'gpt-6.1-sol'
|
|
}
|
|
if (normalized === 'gpt-6-luna' || normalized.startsWith('gpt-6-luna-')) {
|
|
return 'gpt-6-luna'
|
|
}
|
|
// Exact alias match avoids assigning Sol rates to future cheaper variants.
|
|
if (normalized === 'gpt-5.6') {
|
|
return 'gpt-5.6-sol'
|
|
}
|
|
return null
|
|
}
|