From f3996756074067c7a3a25e701dcfd8aad13a60a8 Mon Sep 17 00:00:00 2001 From: merefield Date: Tue, 27 Oct 2026 11:22:33 +0000 Subject: [PATCH 1/2] FEAT: add GPT-6.1 Terra pricing and refresh published-rate audit --- README.md | 44 ++++++++++++++++++++-------- internal/codex/benchmark.go | 3 +- internal/codex/benchmark_test.go | 12 ++++---- internal/codex/service_tier.go | 9 +++--- internal/codex/service_tier_test.go | 37 +++++++++++++++++++++++ internal/ui/english_snapshot_test.go | 4 +-- 6 files changed, 84 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 96107e1..07f9d21 100644 --- a/README.md +++ b/README.md @@ -868,7 +868,7 @@ hidden from Sessions; hiding presentation does not exclude their aggregate subscription impact from Quota views. The embedded rates come from the [official OpenAI API pricing page](https://developers.openai.com/api/docs/pricing) -and were last reviewed on **2026-10-12**. +and were last reviewed on **2026-10-27**. Every Quota presentation repeats that retrieval date and a terminal hyperlink to the source in its footer when the terminal is wide enough, matching the Benchmark view and making stale compiled pricing conspicuous wherever a priced @@ -2525,24 +2525,44 @@ release was built. Codexometer does not inherit or guess such a price. Pricing can change after a binary is released; consult the [official OpenAI API pricing page](https://developers.openai.com/api/docs/pricing) for current values. The compiled table was last updated from -that page on **2026-09-30**; every pricing-bearing Quota or Benchmark footer +that page on **2026-10-27**; every pricing-bearing Quota or Benchmark footer displays both the retrieval date and a terminal hyperlink to the source when space permits, so stale embedded pricing is visible while interpreting results. -The maintained price table covers GPT-6.1 Sol, GPT-6 Astra, GPT-6 Sol, GPT-6 Luna, GPT-5.6 Sol, GPT-5.6 Terra, -GPT-5.6 Luna, GPT-5.5, GPT-5.4, GPT-5.4 Mini, and GPT-5.3 Codex. +The maintained table uses these standard USD rates per million tokens. All +entries were checked against the official pricing page on the date above. -The September additions use these standard USD rates per million tokens: - -| Model | Input | Cached input | Cache writes | Output | +| Model | Input | Cached input | Cache writes (30 minutes) | Output | | --- | ---: | ---: | ---: | ---: | +| GPT-6 Astra | $10.00 | $1.00 | $12.50 | $50.00 | | [GPT-6.1 Sol](https://developers.openai.com/api/docs/models/gpt-6.1-sol) | $2.00 | $0.10 | $2.50 | $10.00 | +| [GPT-6.1 Terra](https://developers.openai.com/api/docs/models/gpt-6.1-terra) | $1.00 | $0.05 | $1.25 | $5.00 | | [GPT-6 Sol](https://developers.openai.com/api/docs/models/gpt-6-sol) | $2.00 | $0.20 | $2.50 | $10.00 | | [GPT-6 Luna](https://developers.openai.com/api/docs/models/gpt-6-luna) | $0.10 | $0.01 | $0.125 | $0.50 | - -Above 272,000 input tokens per response, input and cache rates double and -output rates multiply by 1.5 for the entire response. Requested Fast/priority -pricing doubles the applicable rates in live estimates; benchmark API EQ -continues to use standard pricing. Existing model prices are retained. +| GPT-5.6 Sol | $4.00 | $0.40 | $5.00 | $20.00 | +| GPT-5.6 Terra | $2.00 | $0.20 | $2.50 | $12.00 | +| GPT-5.6 Luna | $0.20 | $0.02 | $0.25 | $1.20 | +| GPT-5.5 | $5.00 | $0.50 | Not published | $30.00 | +| GPT-5.4 | $2.50 | $0.25 | Not published | $15.00 | +| GPT-5.4 Mini | $0.75 | $0.075 | Not published | $4.50 | +| GPT-5.3 Codex | $1.75 | $0.175 | Not published | $14.00 | +| GPT-5.2 | $1.75 | $0.175 | Not published | $14.00 | + +For GPT-6, GPT-6.1, GPT-5.6, GPT-5.5 and GPT-5.4 (not Mini), above 272,000 +input tokens per response, input and cache rates double and output rates +multiply by 1.5 for the entire response. Models without maintained long-context +rates remain unpriced above that threshold. Requested Fast/priority pricing +doubles the applicable rates in live estimates, except GPT-5.5's 2.5× rate; +long-context Fast pricing for GPT-5.4 and GPT-5.5 remains unpriced. Published +Flex rates are half Standard; Ultrafast is 6× Standard for GPT-6 Astra and +GPT-6.1 Sol only. GPT-6.1 Terra has no maintained Ultrafast price, and the +unpublished ID `gpt-6-terra` is not treated as an alias. Benchmark API EQ +continues to use standard pricing. + +Cache-write estimates use the published 30-minute rates. The observed token +breakdown does not identify retention duration; 12-hour cache writes cost more +and are not separately accounted for. Existing model prices are unchanged by +this update; GPT-5.6 Sol's promotional pricing is currently advertised through +at least 21 November 2026. The figures are useful for comparing these particular observed trials, but they have important limitations: diff --git a/internal/codex/benchmark.go b/internal/codex/benchmark.go index f658769..4fb51d7 100644 --- a/internal/codex/benchmark.go +++ b/internal/codex/benchmark.go @@ -33,7 +33,7 @@ const ( // the published rates compiled into this release. Keep both in sync whenever // standardAPIPrices changes. StandardAPIPricingSourceURL = "https://developers.openai.com/api/docs/pricing" - StandardAPIPricingRetrievedOn = "2026-10-12" + StandardAPIPricingRetrievedOn = "2026-10-27" ) // BenchmarkUsage is the app-server token breakdown for one isolated turn. @@ -1652,6 +1652,7 @@ type apiPrice struct { var standardAPIPrices = map[string]apiPrice{ "gpt-5.2": {input: 1.75, cached: 0.175, output: 14.00}, "gpt-6.1-sol": {input: 2.00, cached: 0.10, cacheWrite: 2.50, cacheWriteKnown: true, output: 10.00, longInput: 4.00, longCached: 0.20, longCacheWrite: 5.00, longOutput: 15.00, longKnown: true}, + "gpt-6.1-terra": {input: 1.00, cached: 0.05, cacheWrite: 1.25, cacheWriteKnown: true, output: 5.00, longInput: 2.00, longCached: 0.10, longCacheWrite: 2.50, longOutput: 7.50, longKnown: true}, "gpt-6-sol": {input: 2.00, cached: 0.20, cacheWrite: 2.50, cacheWriteKnown: true, output: 10.00, longInput: 4.00, longCached: 0.40, longCacheWrite: 5.00, longOutput: 15.00, longKnown: true}, "gpt-6-luna": {input: 0.10, cached: 0.01, cacheWrite: 0.125, cacheWriteKnown: true, output: 0.50, longInput: 0.20, longCached: 0.02, longCacheWrite: 0.25, longOutput: 0.75, longKnown: true}, "gpt-6-astra": {input: 10.00, cached: 1.00, cacheWrite: 12.50, cacheWriteKnown: true, output: 50.00, longInput: 20.00, longCached: 2.00, longCacheWrite: 25.00, longOutput: 75.00, longKnown: true}, diff --git a/internal/codex/benchmark_test.go b/internal/codex/benchmark_test.go index 3d480b0..bf64399 100644 --- a/internal/codex/benchmark_test.go +++ b/internal/codex/benchmark_test.go @@ -1210,6 +1210,7 @@ func TestStandardAPIPricesMatchPublishedRates(t *testing.T) { want := map[string]apiPrice{ "gpt-5.2": {input: 1.75, cached: 0.175, output: 14.00}, "gpt-6.1-sol": {input: 2.00, cached: 0.10, cacheWrite: 2.50, cacheWriteKnown: true, output: 10.00, longInput: 4.00, longCached: 0.20, longCacheWrite: 5.00, longOutput: 15.00, longKnown: true}, + "gpt-6.1-terra": {input: 1.00, cached: 0.05, cacheWrite: 1.25, cacheWriteKnown: true, output: 5.00, longInput: 2.00, longCached: 0.10, longCacheWrite: 2.50, longOutput: 7.50, longKnown: true}, "gpt-6-sol": {input: 2.00, cached: 0.20, cacheWrite: 2.50, cacheWriteKnown: true, output: 10.00, longInput: 4.00, longCached: 0.40, longCacheWrite: 5.00, longOutput: 15.00, longKnown: true}, "gpt-6-luna": {input: 0.10, cached: 0.01, cacheWrite: 0.125, cacheWriteKnown: true, output: 0.50, longInput: 0.20, longCached: 0.02, longCacheWrite: 0.25, longOutput: 0.75, longKnown: true}, "gpt-6-astra": {input: 10.00, cached: 1.00, cacheWrite: 12.50, cacheWriteKnown: true, output: 50.00, longInput: 20.00, longCached: 2.00, longCacheWrite: 25.00, longOutput: 75.00, longKnown: true}, @@ -1237,13 +1238,14 @@ func TestStandardAPIPricesMatchPublishedRates(t *testing.T) { } } -func TestGPT6SolLunaPricingBoundaries(t *testing.T) { +func TestGPT6PricingBoundaries(t *testing.T) { for _, tc := range []struct { model string input, cached, write, output float64 }{ {"gpt-6-sol", 2, 0.2, 2.5, 10}, {"gpt-6.1-sol", 2, 0.1, 2.5, 10}, + {"gpt-6.1-terra", 1, 0.05, 1.25, 5}, {"gpt-6-luna", 0.1, 0.01, 0.125, 0.5}, } { for _, input := range []int64{272000, 272001} { @@ -1258,18 +1260,18 @@ func TestGPT6SolLunaPricingBoundaries(t *testing.T) { if !known || issue != "" || math.Abs(got-want) > 1e-12 { t.Fatalf("%s input %d: %g, %v, %s; want %g", model, input, got, known, issue, want) } - for _, tier := range []string{"fast", "priority"} { + for tier, factor := range map[string]float64{"default": 1, "fast": 2, "priority": 2, "flex": 0.5} { r := &LiveUsageReader{} call := LiveModelCall{Model: model, RequestedServiceTier: tier} r.finalizeCallPricing(&call, usage) - if !call.APIEqKnown || math.Abs(call.APIEqUSD+call.APIEqTierPremiumUSD-2*want) > 1e-12 { - t.Fatalf("%s %s input %d: incorrect Fast cost: %+v", model, tier, input, call) + if !call.APIEqKnown || math.Abs(call.APIEqUSD+call.APIEqTierPremiumUSD-factor*want) > 1e-12 { + t.Fatalf("%s %s input %d: incorrect tier cost: %+v", model, tier, input, call) } } } } } - for _, model := range []string{"gpt-6-terra", "gpt-6-sol-preview", "gpt-6-luna-preview", "gpt-6.1-sol-preview", "gpt-6.1-astra", "gpt-6.1-luna"} { + for _, model := range []string{"gpt-6-terra", "gpt-6.1-terra-preview", "gpt-6.1-terra-2026-99-99", "gpt-6-sol-preview", "gpt-6-luna-preview", "gpt-6.1-sol-preview", "gpt-6.1-astra", "gpt-6.1-luna"} { if _, known := priceForModel(model); known { t.Fatalf("unpublished model %s was priced", model) } diff --git a/internal/codex/service_tier.go b/internal/codex/service_tier.go index d46486e..91c4e90 100644 --- a/internal/codex/service_tier.go +++ b/internal/codex/service_tier.go @@ -8,9 +8,8 @@ import ( ) // FastAPIPricingRetrievedOn is separate from the standard-price review date. -// Sources: https://developers.openai.com/api/docs/pricing and -// https://learn.chatgpt.com/docs/agent-configuration/speed (GPT-5.6 API rates). -const FastAPIPricingRetrievedOn = "2026-10-12" +// Source: https://developers.openai.com/api/docs/pricing (Fast, Flex and Ultrafast). +const FastAPIPricingRetrievedOn = "2026-10-27" // requestedTierPremium prices a single response's requested tier. It does not // claim that the backend delivered/billed that tier. Empty means unavailable, @@ -29,7 +28,7 @@ func requestedTierMultiplier(model, tier string) (float64, bool) { return 1, true case "fast", "priority": switch name { - case "gpt-6-astra", "gpt-6.1-sol", "gpt-6-sol", "gpt-6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.2", "gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex": + case "gpt-6-astra", "gpt-6.1-sol", "gpt-6.1-terra", "gpt-6-sol", "gpt-6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.2", "gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex": return 2, true case "gpt-5.5": return 2.5, true @@ -40,7 +39,7 @@ func requestedTierMultiplier(model, tier string) (float64, bool) { } case "flex": switch name { - case "gpt-6-astra", "gpt-6.1-sol", "gpt-6-sol", "gpt-6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.2", "gpt-5.5": + case "gpt-6-astra", "gpt-6.1-sol", "gpt-6.1-terra", "gpt-6-sol", "gpt-6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.2", "gpt-5.5": return 0.5, true } } diff --git a/internal/codex/service_tier_test.go b/internal/codex/service_tier_test.go index 85daf3d..40fc636 100644 --- a/internal/codex/service_tier_test.go +++ b/internal/codex/service_tier_test.go @@ -18,6 +18,12 @@ func TestRequestedTierPremium(t *testing.T) { {"gpt-6-astra", "fast", 3, true}, {"gpt-6-sol", "fast", 3, true}, {"gpt-6.1-sol", "fast", 3, true}, + {"gpt-6.1-terra", "fast", 3, true}, + {" GPT-6.1-TERRA-2026-10-27 ", " PRIORITY ", 3, true}, + {"gpt-6.1-terra", "flex", -1.5, true}, + {"gpt-6.1-terra", "ultrafast", 0, false}, + {"gpt-6.1-terra-preview", "fast", 0, false}, + {"gpt-6-terra", "fast", 0, false}, {" GPT-6.1-SOL-2026-09-30 ", " PRIORITY ", 3, true}, {"gpt-6.1-sol-preview", "fast", 0, false}, {"gpt-6-luna", "priority", 3, true}, @@ -43,6 +49,37 @@ func TestRequestedTierPremium(t *testing.T) { } } +func TestMaintainedTierMultipliersMatchPublishedRates(t *testing.T) { + // Reviewed against the Standard, Fast, Flex and Ultrafast tables on + // https://developers.openai.com/api/docs/pricing, 2026-10-27. + for _, test := range []struct { + model string + fast, flex, ultrafast float64 + }{ + {"gpt-6-astra", 2, 0.5, 6}, + {"gpt-6.1-sol", 2, 0.5, 6}, + {"gpt-6.1-terra", 2, 0.5, 0}, + {"gpt-6-sol", 2, 0.5, 0}, + {"gpt-6-luna", 2, 0.5, 0}, + {"gpt-5.6-sol", 2, 0.5, 0}, + {"gpt-5.6-terra", 2, 0.5, 0}, + {"gpt-5.6-luna", 2, 0.5, 0}, + {"gpt-5.5", 2.5, 0.5, 0}, + {"gpt-5.4", 2, 0, 0}, + {"gpt-5.4-mini", 2, 0, 0}, + {"gpt-5.3-codex", 2, 0, 0}, + {"gpt-5.2", 2, 0.5, 0}, + } { + for tier, want := range map[string]float64{"standard": 1, "fast": test.fast, "priority": test.fast, "flex": test.flex, "ultrafast": test.ultrafast} { + got, known := requestedTierMultiplier(test.model, tier) + // Zero denotes a deliberately unmaintained combination, not free usage. + if known != (want > 0) || known && got != want { + t.Errorf("%s %s = %g, known %v; want %g", test.model, tier, got, known, want) + } + } + } +} + func TestFastPricingPreservesTokenClassesAndLongContext(t *testing.T) { for _, input := range []int64{272000, 272001} { r := &LiveUsageReader{} diff --git a/internal/ui/english_snapshot_test.go b/internal/ui/english_snapshot_test.go index 6a35a92..007ddd5 100644 --- a/internal/ui/english_snapshot_test.go +++ b/internal/ui/english_snapshot_test.go @@ -39,8 +39,8 @@ func TestEnglishPresentationSnapshot(t *testing.T) { // Baseline includes Pace graph controls, explicit panel/border // backgrounds, Sessions Zero/Close All, the ACTIVE category and responsive // summary filters; every theme, view and size - // remains covered. The displayed pricing review date is now 2026-10-12. - const want = "51ffe11ef44315386abd14364c7c64e2dd3c56ada230d21be539e2e29db88f48" + // remains covered. The displayed pricing review date is now 2026-10-27. + const want = "20af39ed4d2355a8cc183775b36d8d0ed4dc51a1284858a98c0011587a84a0ca" if got != want { t.Fatalf("English presentation changed: got %s, want %s", got, want) } From c41290fcdc506a2fa716aff9e4dc8cafe93b52d0 Mon Sep 17 00:00:00 2001 From: merefield Date: Tue, 27 Oct 2026 11:29:50 +0000 Subject: [PATCH 2/2] DOC: align quota tier guidance with Terra pricing audit --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 07f9d21..5be4236 100644 --- a/README.md +++ b/README.md @@ -744,16 +744,17 @@ or applies today's `/fast` setting retroactively. combination is unpriced and interrupts clean learning rather than silently applying an invented multiplier. Benchmark comparisons continue to use Standard rates. -Tier pricing was reviewed on **12 October 2026**: **GPT-6.1 Sol, GPT-6 (Astra, Sol, Luna) and GPT-5.6 +Tier pricing was reviewed on **27 October 2026**: **GPT-6.1 (Sol, Terra), GPT-6 (Astra, Sol, Luna) and GPT-5.6 (Sol, Terra, Luna)** use **2× applicable standard API prices** for `fast` / the -legacy `priority` alias. Astra and GPT-6.1 Sol **Ultrafast** use **6×** applicable standard API prices. -**Flex** uses **½×** on the maintained GPT-6/GPT-5.6 models, GPT-5.2 and GPT-5.5. +legacy `priority` alias. Astra and GPT-6.1 Sol **Ultrafast** use **6×** applicable standard API prices; +GPT-6.1 Terra has no maintained Ultrafast rate. +**Flex** uses **½×** on the maintained GPT-6.1/GPT-6/GPT-5.6 models, GPT-5.2 and GPT-5.5. GPT-5.2 fallback pricing and published short-context Fast rates for GPT-5.2, GPT-5.3 Codex, GPT-5.4/Mini and GPT-5.5 are also maintained; GPT-5.5 Fast is 2.5×. Other explicit model/tier combinations and unpublished long-context Fast rates remain unavailable. Adjustments follow per-response long-context and cache calculations; reasoning output is not counted twice. See the official -[Astra pricing](https://developers.openai.com/api/docs/models/gpt-6-astra), +[API pricing table](https://developers.openai.com/api/docs/pricing), [Codex speed guidance](https://learn.chatgpt.com/docs/agent-configuration/speed), and [API Fast-mode guide](https://developers.openai.com/api/docs/guides/fast-mode). The footer's standard-price retrieval date remains separate from this tier review.