Skip to content

Cost schema cannot express time-based pricing (peak/off-peak), so estimates diverge from actual billing #5913

Description

@greedyivan

DeepSeek V4 bills peak/off-peak (peak 01:00–04:00 and 06:00–10:00 UTC, Mon–Fri; off-peak exactly half). #4891 works around this by storing the peak rate in [cost] and documenting the windows in a comment — reasonable given the current schema, but any flat rate is 2× off in one of the windows. Billing-level example: a session I reconciled against the provider's invoice was billed at exactly the peak rates during the peak window; the same session run off-peak would be estimated 2× above its bill with #4891's data.

CostTier already has a discriminated tier.type (z.literal("context"), packages/core/src/schema.ts), and consumers already select tiers at calculation time (opencode does this for context tiers in packages/opencode/src/session/session.ts, which carries a TODO: "update models.dev to have better pricing model"). A time tier would follow the same pattern:

[cost]
# base rates = off-peak (or peak — naming decision)
input = 0.66
output = 1.98
cache_read = 0.022

[[cost.tiers]]
input = 1.32
output = 3.96
cache_read = 0.044
[cost.tiers.tier]
type = "time"
windows = [
  { days = ["mon","tue","wed","thu","fri"], from = "01:00", to = "04:00" },
  { days = ["mon","tue","wed","thu","fri"], from = "06:00", to = "10:00" },
]
timezone = "UTC"

Design questions before any code:

  1. Explicit per-window rates vs multiplier (DeepSeek is exactly ½ off-peak; a multiplier = 0.5 on the tier is compact, explicit rates generalize better).
  2. Base-rate semantics: is [cost] the list price (peak) with tiers as discounts, or the floor (off-peak) with tiers as surcharges? fix(deepseek): update V4 pricing for peak/off-peak billing #4891 argues list price; consumers that ignore tiers would then overestimate rather than underestimate — is overestimation the preferred failure mode? (I'd say yes.)
  3. Compatibility: Cost/CostTier are .strict(), so old SDK builds reject a time tier outright — data using it can't ship until consumers that validate are updated. How has the project handled adding discriminator values before — engine support first, data later?
  4. Scope: timezone-aware windows only (provider schedules are published in UTC; DST/holiday calendars feel out of scope).

Context: opencode's pricing-correctness threads stalled (anomalyco/opencode#7387 auto-closed, RFC #12377 closed, PR #7763 closed unmerged), so this issue is also a place to decide the consumer-side rollout. I can prepare the schema PR plus the opencode engine change (timestamp-based tier selection) once the shape is agreed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions