Make Sonnet's expiring intro pricing date-aware

The table hardcoded $2/$10 with a comment noting it lapses 2026-08-31.
From Sept 1 that would have under-reported every grade by a third — both
the per-grade figure in the UI and the cost recorded against each result.
This commit is contained in:
Barely Removable 2026-08-22 13:10:08 -07:00
parent 602bce8ce3
commit 762b394c8a

View file

@ -16,6 +16,7 @@ Works on any trading card: Pokemon, sports, Magic, whatever PSA grades.
import base64
import json
import os
import time
import cardimage
@ -48,8 +49,11 @@ MODELS = {
"effort": True,
"adaptive_thinking": True,
"fallbacks": False,
# Introductory pricing runs through 2026-08-31, then 3.00 / 15.00.
# Introductory pricing, which EXPIRES — see `priced_from` below.
# Hardcoding the intro rate alone would have quietly under-reported
# every grade by a third from 2026-09-01 onward.
"in_per_mtok": 2.00, "out_per_mtok": 10.00,
"priced_from": [("2026-09-01", 3.00, 15.00)],
"approx_image_tokens": 4800,
},
"claude-opus-5": {
@ -824,13 +828,31 @@ def grade_card(images, api_key=None, model=None, effort=None, zoom_details=True)
}
def current_rates(caps, on_date=None):
"""(input, output) $/Mtok for a model, honouring any scheduled change.
A model on introductory pricing carries the dated rates that supersede
it in `priced_from`; the latest one whose date has passed wins. Without
this the table silently keeps quoting a rate that no longer exists once
the promotion ends, and every cost shown in the app is wrong by
whatever the increase was.
"""
rate_in, rate_out = caps["in_per_mtok"], caps["out_per_mtok"]
today = on_date or time.strftime("%Y-%m-%d")
for starts, new_in, new_out in sorted(caps.get("priced_from") or []):
if today >= starts:
rate_in, rate_out = new_in, new_out
return rate_in, rate_out
def estimate_cost(usage):
"""Actual USD cost of one grading call, from the reported token counts."""
if not usage:
return None
caps = MODELS.get(usage.get("model") or "", MODELS[DEFAULT_MODEL])
return ((usage.get("input_tokens") or 0) * caps["in_per_mtok"] / 1_000_000
+ (usage.get("output_tokens") or 0) * caps["out_per_mtok"] / 1_000_000)
rate_in, rate_out = current_rates(caps)
return ((usage.get("input_tokens") or 0) * rate_in / 1_000_000
+ (usage.get("output_tokens") or 0) * rate_out / 1_000_000)
def price_guide():
@ -840,10 +862,11 @@ def price_guide():
# 1 supplied photo + ~12 generated close-ups, JSON verdict out.
est_in = caps["approx_image_tokens"] * 5 + 600
est_out = 700
rate_in, rate_out = current_rates(caps)
guide[model_id] = {
"label": caps["label"],
"supports_effort": caps["effort"],
"per_grade": round(est_in * caps["in_per_mtok"] / 1_000_000
+ est_out * caps["out_per_mtok"] / 1_000_000, 4),
"per_grade": round(est_in * rate_in / 1_000_000
+ est_out * rate_out / 1_000_000, 4),
}
return guide