fix: price OpenAI requests by actual service tier

Remove the model allowlist and instead derive the Fast tier premium
from matching catalogue entries, falling back to the documented
multiplier when metadata is missing or inconsistent. Endpoint and
cost-override guards, tests, and docs are preserved.

Signed-off-by: David Gageot <david.gageot@docker.com>
This commit is contained in:
David Gageot committed 2026-10-17 13:09:15 +02:00
1 parent a494ef49bb
commit 5b38f1d517
9 files changed
+171 -48

No files matched your search

+3 -3
View File
@@ -74,12 +74,12 @@ OpenAI also accepts `priority` for Fast mode. It provides faster processing at p
The value is forwarded unchanged to Chat Completions (including reranking) and Responses requests, over either SSE or WebSocket. OpenAI-compatible providers using these APIs also receive the option when set; the endpoint must support it. Other tiers, such as `auto`, `default`, and `flex`, can also be requested; availability and valid values depend on the API and model. When omitted or empty, no `service_tier` is sent, leaving the API's default behavior unchanged. Non-string values are ignored.
For GPT-6 Astra, request [Ultrafast mode](https://developers.openai.com/api/docs/guides/ultrafast-mode) with `service_tier: ultrafast`.
For models that support it, such as GPT-6 Astra and GPT-6.1 Sol, request [Ultrafast mode](https://developers.openai.com/api/docs/guides/ultrafast-mode) with `service_tier: ultrafast`.
Cost estimates use the **actual response tier**, not the requested tier. For models served by the official OpenAI endpoint (including an explicitly configured `base_url: https://api.openai.com/v1`), Fast (`fast` or `priority`) applies 2× catalogue rates to `gpt-5.6` (the Sol alias), `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-6-astra`, `gpt-6-sol`, `gpt-6-luna`, and `gpt-6.1-sol`. Ultrafast applies 6× rates to `gpt-6-astra` only. These adjustments cover input, cached input, cache writes, and output, including the applicable long-context band. A response reporting `default` retains standard pricing, even if Fast was requested.
Cost estimates use the **actual response tier**, not the requested tier. For models served by the official OpenAI endpoint (including an explicitly configured `base_url: https://api.openai.com/v1`), an actual Fast tier (`fast` or `priority`) uses a catalogue-derived premium when matching Vercel Standard/Fast entries have the same base rates and a uniform premium across token types. Otherwise it is estimated at 2× catalogue rates. `ultrafast` is estimated at 6× rates. The response selects the tier; Docker Agent does not maintain a model allowlist. These adjustments cover input, cached input, cache writes, and output, including the applicable long-context band. A response reporting `default` retains standard pricing, even if Fast was requested.
> [!WARNING]
> Missing response tiers, unlisted models or tiers, custom endpoints (including `OPENAI_BASE_URL`), rule-based routers, and other providers retain catalogue pricing. Gateway model IDs already priced as `-fast` are not multiplied again. Estimates do not include endpoint surcharges or negotiated discounts. Use a model's [`cost` override](../../configuration/models/index.md#custom-token-pricing) when automatic pricing does not apply; overrides replace the entire price table and are never multiplied by the service tier.
> Missing or unrecognized response tiers, custom endpoints (including `OPENAI_BASE_URL`), rule-based routers, and other providers retain catalogue pricing. Gateway model IDs already priced as `-fast` are not multiplied again. The response reports the tier, not a price. Catalogue-derived premiums cover differing Fast rates such as GPT-4o and GPT-5.5; missing or inconsistent tier metadata falls back to the estimate. Estimates do not include endpoint surcharges or negotiated discounts. Use a model's [`cost` override](../../configuration/models/index.md#custom-token-pricing) when a model's published tier rates differ or automatic pricing does not apply. Overrides replace the entire price table, including context bands, and are never adjusted for the service tier—even after a downgrade.
See [`examples/openai-service-tier.yaml`](https://github.com/docker/docker-agent/blob/main/examples/openai-service-tier.yaml) for a complete example.
+7 -2
View File
@@ -1,10 +1,10 @@
# Cost estimates use the actual response tier for supported OpenAI models.
# Cost estimates use the actual response tier, not the requested tier or model name.
# https://developers.openai.com/api/docs/guides/fast-mode
# https://developers.openai.com/api/docs/guides/ultrafast-mode
agents:
root:
model: fast-gpt # Switch to ultrafast-astra to use Ultrafast mode.
model: fast-gpt # Switch to ultrafast-astra or ultrafast-sol for Ultrafast mode.
description: An assistant using OpenAI Fast mode.
instruction: You are a helpful assistant.
@@ -19,3 +19,8 @@ models:
model: gpt-6-astra
provider_opts:
service_tier: ultrafast
ultrafast-sol:
provider: openai
model: gpt-6.1-sol
provider_opts:
service_tier: ultrafast
@@ -159,6 +159,9 @@ func TestServiceTierUsageTransports(t *testing.T) {
{requested: "ultrafast", actual: "ultrafast"},
{requested: "fast", actual: "default"},
{requested: "ultrafast", actual: "default"},
{requested: "ultrafast", actual: "fast"},
{requested: "fast", actual: "ultrafast"},
{actual: "ultrafast"},
{actual: "fast"},
{requested: "fast"},
} {
+73 -22
View File
@@ -1,41 +1,29 @@
package modelsdev
import (
"math"
"slices"
"time"
)
// ForServiceTier adjusts catalogue rates for the actual response tier without mutating c.
// Unlisted models, providers and tiers retain their catalogue pricing.
// ForServiceTier estimates tier pricing from the actual response tier without mutating c.
// Other providers and unrecognized tiers retain their catalogue pricing.
func (c *Cost) ForServiceTier(id ID, tier string) *Cost {
if c == nil || id.Provider != "openai" {
return c
}
model := id.Model
if len(model) > len("-2006-01-02") {
cut := len(model) - len("2006-01-02")
if model[cut-1] == '-' {
if _, err := time.Parse(time.DateOnly, model[cut:]); err == nil {
model = model[:cut-1]
}
}
}
// https://developers.openai.com/api/docs/pricing; don't extrapolate to future models.
factor := 1.0
// Current tier premiums; models with different rates need a cost override.
// https://developers.openai.com/api/docs/pricing
var factor float64
switch tier {
case "fast", "priority":
switch model {
case "gpt-5.6", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna",
"gpt-6-astra", "gpt-6-sol", "gpt-6-luna", "gpt-6.1-sol":
factor = c.fastMultiplier
if factor == 0 {
factor = 2
}
case "ultrafast":
if model == "gpt-6-astra" {
factor = 6
}
}
if factor == 1 {
factor = 6
default:
return c
}
@@ -53,3 +41,66 @@ func (c *Cost) ForServiceTier(id ID, tier string) *Cost {
}
return &out
}
// withFastPricing derives a uniform premium only when gateway and vendor base rates agree.
func (c *Cost) withFastPricing(db *Database, id ID) *Cost {
if c == nil || id.Provider != "openai" {
return c
}
models := db.Providers["vercel"].Models
model := id.Model
for {
standard := models["openai/"+model].Cost
fast := models["openai/"+model+"-fast"].Cost
if standard != nil && fast != nil && standard.RatesFor(0) == c.RatesFor(0) {
if factor := uniformPremium(standard, fast); factor > 0 {
out := *c
out.fastMultiplier = factor
return &out
}
}
// Dated models may share the alias's pricing, but never assume its base rates match.
if len(model) <= len("-2006-01-02") {
return c
}
cut := len(model) - len("2006-01-02")
if model[cut-1] != '-' {
return c
}
if _, err := time.Parse(time.DateOnly, model[cut:]); err != nil {
return c
}
model = model[:cut-1]
}
}
func uniformPremium(standard, fast *Cost) float64 {
factor := fast.Input / standard.Input
if factor < 1 || math.IsNaN(factor) || math.IsInf(factor, 0) {
return 0
}
matches := func(base, premium Rates) bool {
return closeRate(base.Input*factor, premium.Input) &&
closeRate(base.Output*factor, premium.Output) &&
closeRate(base.CacheRead*factor, premium.CacheRead) &&
closeRate(base.CacheWrite*factor, premium.CacheWrite)
}
if !matches(standard.RatesFor(0), fast.RatesFor(0)) {
return 0
}
for _, tier := range fast.Tiers {
if tier.Tier.Size < 0 || tier.Tier.Size == math.MaxInt64 || (tier.Tier.Type != "" && tier.Tier.Type != "context") {
return 0
}
// Gateway thresholds may name the first long-context token, rather than the last short one.
if !matches(standard.RatesFor(tier.Tier.Size+1), tier.Rates) {
return 0
}
}
return factor
}
func closeRate(a, b float64) bool {
return !math.IsNaN(a) && !math.IsNaN(b) && !math.IsInf(a, 0) && !math.IsInf(b, 0) &&
math.Abs(a-b) <= 1e-9*math.Max(1, math.Max(math.Abs(a), math.Abs(b)))
}
+53 -13
View File
@@ -35,17 +35,18 @@ func TestCostForServiceTier(t *testing.T) {
}
}
func TestCostForServiceTierModels(t *testing.T) {
func TestCostForServiceTierIndependentOfModel(t *testing.T) {
t.Parallel()
cost := &Cost{Input: 1}
for _, model := range []string{"gpt-5.6", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-6-astra", "gpt-6-sol", "gpt-6-luna", "gpt-6.1-sol"} {
for _, tier := range []string{"fast", "priority"} {
assert.InDelta(t, 2.0, cost.ForServiceTier(NewID("openai", model), tier).Input, 1e-9, "%s/%s", model, tier)
assert.InDelta(t, 2.0, cost.ForServiceTier(NewID("openai", model+"-2026-09-04"), tier).Input, 1e-9, "dated %s/%s", model, tier)
for _, model := range []string{"gpt-6.1-sol", "gpt-6-astra-2026-09-04", "future-model", "future-model-fast"} {
for _, tc := range []struct {
tier string
factor float64
}{{"fast", 2}, {"priority", 2}, {"ultrafast", 6}} {
assert.InDelta(t, tc.factor, cost.ForServiceTier(NewID("openai", model), tc.tier).Input, 1e-9, "%s/%s", model, tc.tier)
}
}
assert.InDelta(t, 6.0, cost.ForServiceTier(NewID("openai", "gpt-6-astra-2026-09-04"), "ultrafast").Input, 1e-9)
}
func TestCostForServiceTierUnchanged(t *testing.T) {
@@ -61,13 +62,6 @@ func TestCostForServiceTierUnchanged(t *testing.T) {
{"openai", "gpt-6-astra", "flex"},
{"openai", "gpt-6-astra", "scale"},
{"openai", "gpt-6-astra", "future-tier"},
{"openai", "gpt-5.6-luna", "ultrafast"},
{"openai", "gpt-6.1-sol", "ultrafast"},
{"openai", "gpt-5.5", "fast"},
{"openai", "gpt-7-astra", "fast"},
{"openai", "gpt-6-astra-fast", "fast"},
{"openai", "gpt-6-astra-extra", "fast"},
{"openai", "gpt-6-astra-2026-02-30", "fast"},
{"vercel", "openai/gpt-6-astra-fast", "fast"},
{"azure", "gpt-6-astra", "fast"},
{"chatgpt", "gpt-6-astra", "ultrafast"},
@@ -78,3 +72,49 @@ func TestCostForServiceTierUnchanged(t *testing.T) {
var missing *Cost
assert.Nil(t, missing.ForServiceTier(NewID("openai", "gpt-6-astra"), "ultrafast"))
}
func TestCatalogFastPremium(t *testing.T) {
t.Parallel()
base := &Cost{
Input: 2, Output: 10, CacheRead: 0.2, CacheWrite: 2.5,
Tiers: []CostTier{{Rates: Rates{Input: 4, Output: 15, CacheRead: 0.4, CacheWrite: 5}, Tier: TierSpec{Type: "context", Size: 272_000}}},
}
for _, tc := range []struct {
name string
standard *Cost
fast *Cost
factor float64
}{
{name: "uniform premium", standard: base, fast: &Cost{Input: 5, Output: 25, CacheRead: 0.5, CacheWrite: 6.25}, factor: 2.5},
{name: "missing fast", standard: base, factor: 2},
{name: "missing standard", fast: &Cost{Input: 5, Output: 25, CacheRead: 0.5, CacheWrite: 6.25}, factor: 2},
{name: "different gateway base rates", standard: &Cost{Input: 1}, fast: &Cost{Input: 3}, factor: 2},
{name: "different token premiums", standard: base, fast: &Cost{Input: 5, Output: 20, CacheRead: 0.5, CacheWrite: 6.25}, factor: 2},
{name: "inconsistent context premium", standard: base, fast: &Cost{
Input: 5, Output: 25, CacheRead: 0.5, CacheWrite: 6.25,
Tiers: []CostTier{{Rates: Rates{Input: 8, Output: 30, CacheRead: 0.8, CacheWrite: 10}, Tier: TierSpec{Type: "context", Size: 272_001}}},
}, factor: 2},
} {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
store := NewDatabaseStore(&Database{Providers: map[string]Provider{
"openai": {Models: map[string]Model{"future-model": {Cost: base}, "future-model-2026-10-17": {Cost: base}}},
"vercel": {Models: map[string]Model{"openai/future-model": {Cost: tc.standard}, "openai/future-model-fast": {Cost: tc.fast}}},
}})
for _, name := range []string{"future-model", "future-model-2026-10-17"} {
id := NewID("openai", name)
model, err := store.GetModel(t.Context(), id)
require.NoError(t, err)
for _, tier := range []string{"fast", "priority"} {
priced := model.Cost.ForServiceTier(id, tier)
assert.InDelta(t, 2*tc.factor, priced.RatesFor(100).Input, 1e-9)
assert.InDelta(t, 4*tc.factor, priced.RatesFor(300_000).Input, 1e-9)
}
assert.InDelta(t, 12, model.Cost.ForServiceTier(id, "ultrafast").Input, 1e-9)
assert.Same(t, model.Cost, model.Cost.ForServiceTier(id, "default"))
assert.Zero(t, base.fastMultiplier, "catalogue metadata must not be mutated")
}
})
}
}
+1
View File
@@ -297,6 +297,7 @@ func (s *Store) GetModel(ctx context.Context, id ID) (*Model, error) {
provider, exists := db.Providers[id.Provider]
if model, ok := lookupModel(provider, id); ok {
model.Cost = model.Cost.withFastPricing(db, id)
return &model, nil
}
+3
View File
@@ -45,6 +45,9 @@ type Cost struct {
CacheWrite float64 `json:"cache_write,omitempty"`
Tiers []CostTier `json:"tiers,omitempty"`
// fastMultiplier is derived at lookup from matching catalogue price tables.
fastMultiplier float64
}
// Rates is a single price band, in USD per 1M tokens.
+14 -2
View File
@@ -152,6 +152,10 @@ func TestApplyModelCostServiceTier(t *testing.T) {
cfg latest.ModelConfig
short, long float64
}{
{name: "GPT-4o fast", provider: "openai", model: "gpt-4o", tier: "fast", short: 0.34, long: 2.2525},
{name: "dated GPT-4o priority", provider: "openai", model: "gpt-4o-2024-08-06", tier: "priority", short: 0.34, long: 2.2525},
{name: "GPT-5.5 fast", provider: "openai", model: "gpt-5.5", tier: "fast", short: 1.025, long: 13.1125},
{name: "GPT-5.5 downgrade", provider: "openai", model: "gpt-5.5", tier: "default", cfg: latest.ModelConfig{ProviderOpts: map[string]any{"service_tier": "fast"}}, short: 0.41, long: 5.245},
{name: "Luna fast", provider: "openai", model: "gpt-5.6-luna", tier: "fast", short: 0.0478, long: 0.4496},
{name: "Luna priority alias", provider: "openai", model: "gpt-5.6-luna", tier: "priority", short: 0.0478, long: 0.4496},
{name: "Astra fast", provider: "openai", model: "gpt-6-astra", tier: "fast", short: 2.29, long: 22.33},
@@ -160,7 +164,12 @@ func TestApplyModelCostServiceTier(t *testing.T) {
{name: "actual fast without requested tier", provider: "openai", model: "gpt-6-astra", tier: "fast", short: 2.29, long: 22.33},
{name: "missing actual tier", provider: "openai", model: "gpt-6-astra", cfg: latest.ModelConfig{ProviderOpts: map[string]any{"service_tier": "ultrafast"}}, short: 1.145, long: 11.165},
{name: "unknown tier", provider: "openai", model: "gpt-6-astra", tier: "future-tier", short: 1.145, long: 11.165},
{name: "unsupported Luna ultrafast", provider: "openai", model: "gpt-5.6-luna", tier: "ultrafast", short: 0.0239, long: 0.2248},
{name: "Luna reported ultrafast", provider: "openai", model: "gpt-5.6-luna", tier: "ultrafast", short: 0.1434, long: 1.3488},
{name: "Sol 6.1 fast", provider: "openai", model: "gpt-6.1-sol", tier: "fast", short: 0.454, long: 4.458},
{name: "Sol 6.1 ultrafast", provider: "openai", model: "gpt-6.1-sol", tier: "ultrafast", short: 1.362, long: 13.374},
{name: "Sol 6.1 downgraded to fast", provider: "openai", model: "gpt-6.1-sol", tier: "fast", cfg: latest.ModelConfig{ProviderOpts: map[string]any{"service_tier": "ultrafast"}}, short: 0.454, long: 4.458},
{name: "Sol 6.1 downgraded to default", provider: "openai", model: "gpt-6.1-sol", tier: "default", cfg: latest.ModelConfig{ProviderOpts: map[string]any{"service_tier": "ultrafast"}}, short: 0.227, long: 2.229},
{name: "Sol 6.1 missing actual tier", provider: "openai", model: "gpt-6.1-sol", cfg: latest.ModelConfig{ProviderOpts: map[string]any{"service_tier": "ultrafast"}}, short: 0.227, long: 2.229},
{name: "gateway fast already priced", provider: "vercel", model: "openai/gpt-6-astra-fast", tier: "fast", short: 2.29, long: 22.33},
{name: "Azure unchanged", provider: "azure", model: "gpt-6-astra", tier: "fast", short: 1.145, long: 11.165},
{name: "custom OpenAI endpoint unchanged", provider: "openai", model: "gpt-6-astra", tier: "ultrafast", cfg: latest.ModelConfig{BaseURL: "https://example.com/v1"}, short: 1.145, long: 11.165},
@@ -233,7 +242,7 @@ func TestApplyModelCostEndpointEligibility(t *testing.T) {
}
}
func TestLunaAstraPublishedCostBoundary(t *testing.T) {
func TestPublishedCostBoundary(t *testing.T) {
t.Parallel()
store := modelsdev.NewDatabaseStore(modelsdev.EmbeddedSnapshot())
@@ -249,6 +258,9 @@ func TestLunaAstraPublishedCostBoundary(t *testing.T) {
{"Astra fast", "openai", "gpt-6-astra", "fast", modelsdev.Rates{Input: 20, CacheRead: 2, CacheWrite: 25, Output: 100}, modelsdev.Rates{Input: 40, CacheRead: 4, CacheWrite: 50, Output: 150}},
{"Astra priority", "openai", "gpt-6-astra", "priority", modelsdev.Rates{Input: 20, CacheRead: 2, CacheWrite: 25, Output: 100}, modelsdev.Rates{Input: 40, CacheRead: 4, CacheWrite: 50, Output: 150}},
{"Astra ultrafast", "openai", "gpt-6-astra", "ultrafast", modelsdev.Rates{Input: 60, CacheRead: 6, CacheWrite: 75, Output: 300}, modelsdev.Rates{Input: 120, CacheRead: 12, CacheWrite: 150, Output: 450}},
{"Sol 6.1 standard", "openai", "gpt-6.1-sol", "default", modelsdev.Rates{Input: 2, CacheRead: 0.1, CacheWrite: 2.5, Output: 10}, modelsdev.Rates{Input: 4, CacheRead: 0.2, CacheWrite: 5, Output: 15}},
{"Sol 6.1 fast", "openai", "gpt-6.1-sol", "fast", modelsdev.Rates{Input: 4, CacheRead: 0.2, CacheWrite: 5, Output: 20}, modelsdev.Rates{Input: 8, CacheRead: 0.4, CacheWrite: 10, Output: 30}},
{"Sol 6.1 ultrafast", "openai", "gpt-6.1-sol", "ultrafast", modelsdev.Rates{Input: 12, CacheRead: 0.6, CacheWrite: 15, Output: 60}, modelsdev.Rates{Input: 24, CacheRead: 1.2, CacheWrite: 30, Output: 90}},
{"gateway Astra", "vercel", "openai/gpt-6-astra", "default", modelsdev.Rates{Input: 10, CacheRead: 1, CacheWrite: 12.5, Output: 50}, modelsdev.Rates{Input: 20, CacheRead: 2, CacheWrite: 25, Output: 75}},
{"gateway Astra fast", "vercel", "openai/gpt-6-astra-fast", "fast", modelsdev.Rates{Input: 20, CacheRead: 2, CacheWrite: 25, Output: 100}, modelsdev.Rates{Input: 40, CacheRead: 4, CacheWrite: 50, Output: 150}},
} {
+14 -6
View File
@@ -31,6 +31,9 @@ func TestRunStreamServiceTierCost(t *testing.T) {
{name: "Luna priority", model: "gpt-5.6-luna", tier: "priority", want: 0.0478},
{name: "Astra fast", model: "gpt-6-astra", tier: "fast", want: 2.29},
{name: "Astra ultrafast", model: "gpt-6-astra", tier: "ultrafast", want: 6.87},
{name: "Sol 6.1 fast", model: "gpt-6.1-sol", tier: "fast", want: 0.454},
{name: "Sol 6.1 ultrafast", model: "gpt-6.1-sol", tier: "ultrafast", want: 1.362},
{name: "Sol 6.1 fallback ultrafast", model: "gpt-6.1-sol", tier: "ultrafast", fallback: true, want: 1.362},
{name: "standard downgrade", model: "gpt-6-astra", tier: "default", want: 1.145},
{name: "fallback ultrafast", model: "gpt-6-astra", tier: "ultrafast", fallback: true, want: 6.87},
{name: "fallback override", model: "gpt-6-astra", tier: "ultrafast", fallback: true, cost: &latest.CostConfig{Input: 1, Output: 2, CacheRead: 0.1, CacheWrite: 1.25}, want: 0.0995},
@@ -108,7 +111,7 @@ func TestRunStreamServiceTierCost(t *testing.T) {
func TestServiceTierMixedTurnsPersistCost(t *testing.T) {
t.Parallel()
for _, modelID := range []string{"gpt-5.6-luna", "gpt-6-astra"} {
for _, modelID := range []string{"gpt-5.6-luna", "gpt-6-astra", "gpt-6.1-sol"} {
t.Run(modelID, func(t *testing.T) {
t.Parallel()
model := &configuredProvider{cfg: latest.ModelConfig{Provider: "openai", Model: modelID, BaseURL: "https://api.openai.com/v1", ProviderOpts: map[string]any{"service_tier": "fast"}}}
@@ -128,10 +131,12 @@ func TestServiceTierMixedTurnsPersistCost(t *testing.T) {
input int64
luna float64
astra float64
sol float64
}{
{"fast", 50_000, 0.0478, 2.29},
{"default", 500_000, 0.2248, 11.165},
{"priority", 500_000, 0.4496, 22.33},
{"fast", 50_000, 0.0478, 2.29, 0.454},
{"default", 500_000, 0.2248, 11.165, 2.229},
{"priority", 500_000, 0.4496, 22.33, 4.458},
{"ultrafast", 500_000, 1.3488, 66.99, 13.374},
} {
stream := newStreamBuilder().AddContent("ok").AddStopWithUsage(0, 0).Build()
stream.responses[len(stream.responses)-1].Usage = &chat.Usage{InputTokens: turn.input, CachedInputTokens: 20_000, CacheWriteTokens: 30_000, OutputTokens: 5_000, ReasoningTokens: 3_000, ServiceTier: turn.tier}
@@ -142,8 +147,11 @@ func TestServiceTierMixedTurnsPersistCost(t *testing.T) {
}
}
want := turn.luna
if modelID == "gpt-6-astra" {
switch modelID {
case "gpt-6-astra":
want = turn.astra
case "gpt-6.1-sol":
want = turn.sol
}
wantTotal += want
assert.InDelta(t, wantTotal, sess.TotalCost(), 1e-9)
@@ -162,7 +170,7 @@ func TestServiceTierMixedTurnsPersistCost(t *testing.T) {
tiers = append(tiers, message.Message.Usage.ServiceTier)
}
}
assert.Equal(t, []string{"fast", "default", "priority"}, tiers)
assert.Equal(t, []string{"fast", "default", "priority", "ultrafast"}, tiers)
summaries, err := reopened.GetSessionSummaries(t.Context())
require.NoError(t, err)
require.Len(t, summaries, 1)