From e344831b0580ab718bda788b04fb9fe8b70173cc Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 22 Aug 2026 19:13:04 +0000 Subject: [PATCH] feat(cost_model): add provider field on Price + register qwen3.8-27b (local) --- pilot/cost_model.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pilot/cost_model.py b/pilot/cost_model.py index 06a8341..4893b7e 100644 --- a/pilot/cost_model.py +++ b/pilot/cost_model.py @@ -55,13 +55,20 @@ CHARS_PER_TOKEN = 4 # English prose/code rule of thumb; ±15% is normal @dataclass(frozen=True) class Price: """Per-MTok prices. `cache_write` and `cache_read` are absolute rates, not - multipliers, so providers with different cache economics stay comparable.""" + multipliers, so providers with different cache economics stay comparable. + + `provider` is the opencode provider name (`headroom`, `local`, ...). It + doubles as the dispatch key for `.pr-review.json:model` overrides — when + a per-repo override is set, `_resolve_display_model` returns + `f"{provider}/{key}"` so the opencode subprocess routes correctly. + Default `headroom` preserved for the existing roster.""" name: str input: float output: float cache_write: float cache_read: float + provider: str = "headroom" @property def batch_input(self) -> float: @@ -91,6 +98,12 @@ PRICES: dict[str, Price] = { # xAI Grok — cache_write = input "grok-4.5": Price("Grok 4.5", 2.00, 6.00, 2.00, 0.30), "grok-4.3": Price("Grok 4.3", 1.25, 2.50, 1.25, 0.20), + # Self-hosted — local AI workstation, no per-token charge. provider="local" + # so the opencode subprocess routes via the `local` provider block in + # opencode.json (baseURL=http://192.168.1.79:18020/v1). Equivalent-cost + # column will read $0 — the cost-comparison signal is that the same work + # would bill $X on a paid model. + "qwen3.8-27b": Price("Qwen 3.8 27B (local)", 0.0, 0.0, 0.0, 0.0, provider="local"), }