feat: Revalidate pricing with ETag conditional GET every cycle
Replace the unconditional 24h-TTL download with a conditional GET that runs every refresh cycle (~5 min), so a newly-released model's pricing is picked up within one cycle instead of within ~24h. The fetch now sends If-None-Match with the last ETag (raw.githubusercontent.com returns a weak validator for the gzipped body and honors it with a 0-byte 304). On 304 we re-stamp a verifiedAt timestamp and stop; on 200 we validate, overwrite the JSON, and record the new ETag. A 60s floor guards against manual-refresh storms. ETag + verifiedAt live in a sidecar (litellm-pricing-fresh.meta.json) kept separate from the JSON: a 304 re-stamp must not change the JSON's mtime, since that mtime is the content-changed signal reloadIfFreshChanged() hot-reloads on. loadFresh()'s bundle-vs-fresh trust gate now keys off verifiedAt (30-day window, re-stamped on every 200/304) instead of the JSON mtime, falling back to mtime for pre-sidecar installs. Harden the 200 path: require a usable LiteLLM pricing table (>= 10 Claude rows via the shared claudeModels() helper), not just syntactic JSON, before replacing the cache — a wrong-schema 200 must not zero out prices. Verified end-to-end on device: launch with no sidecar -> load fresh via mtime fallback (correct cost) -> first conditionalRefresh 200 captures the ETag and 44 rows -> next cycle sends If-None-Match and gets 304 with zero re-download and no spurious reload.
X
XueshiQiao committed
4335ef2103ff8fffaba89bef3328114a3b8f384d
Parent: f78fd8b