cctally 1.57.1 → 1.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,26 @@ based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [1.58.0] - 2026-06-30
9
+
10
+ ### Added
11
+ - Embedded pricing for Claude Sonnet 5 (`claude-sonnet-5`) so its sessions are costed correctly instead of falling back to $0 as an unknown model. The rate is the standard $3/$15 per-MTok price (flat across the full 1M-token context window, identical to Claude Sonnet 4.6) — the durable rate that takes effect after Anthropic's introductory $2/$10 pricing ends 2026-08-31 — and the pricing snapshot date is bumped to 2026-07-01. LiteLLM has no Sonnet 5 entry yet, so the table is simply ahead of it (not flagged as drift by `pricing-check`).
12
+
13
+ ### Changed
14
+ - Dashboard at-a-glance redesign: the weekly Used % now dominates as a full-width hero strip — replacing the five header stats and the Current Week grid card — flanked by four spelled-out metrics (cost / 1%, Forecast, 5-hour, vs last week) and a freshness chip, and opening the rich Current Week modal on click. The panel grid is now two-tier: uniform-height summary tiles (Forecast, Weekly, Monthly, Blocks, Alerts) pack into a responsive auto-fit row above full-width data cards (Sessions, Trend, Projects, Daily, Cache Report), with within-tier drag-and-keyboard reorder that cannot cross tiers, eliminating the old forced two-column grid's dead space and roughly halving the page height. Weekly/Monthly/Blocks compact to their three most-recent rows (full history stays one tap away in each panel's modal), Forecast becomes a calm verdict tile, the empty Recent Alerts state collapses to a single line, and on mobile the hero stacks with a 2×2 metric grid while the sticky top bar collapses to one ≤64px row that reveals a condensed Used%/reset readout once you scroll past the hero (#248).
15
+ - Dashboard styling is now built entirely on the shared design tokens: every `border-radius`, `box-shadow`, and accent colour across the dashboard chrome (rgba *and* hex) resolves to the radius/shadow/accent token scale instead of a raw literal, with a small documented allowlist for intentional data-viz and bespoke values. A new global lint keeps it that way — it fails the build if any orphan literal creeps back into the dashboard CSS (the conversation viewer, which owns its own token story, is excluded). There is no visible change; this is the maintainability follow-through on the #247 token foundation (#255).
16
+ - Dashboard cards now wear a calm, neutral chrome: borders, hover elevation, header dividers, the keyboard focus ring, and every panel header title read in one consistent neutral treatment instead of eleven competing accent colours, and accent colour is reserved for genuine state — Cache Report's healthy/anomaly header and the Forecast verdict keep their meaningful hues while healthy cards stay quiet; the look is built on a new radius/shadow/type-scale design-token foundation, and Recent Sessions now caps its height and scrolls internally with its column headers pinned (#247).
17
+ - Dashboard cards read truer at a glance: when every visible Recent Session uses the same model (the common single-model case) the redundant per-row model pills collapse to a single "all · model" caption and the reclaimed width goes to the Project column so names render in full instead of truncating; the Weekly, Monthly, and Blocks model-split bars gain a compact inline legend (model dot + short name + %, with a "+N" overflow) so the breakdown is legible at a glance and on touch instead of hiding in a hover tooltip; the panel drag-to-reorder grip is now visible at rest on desktop and brightens on hover (it previously appeared only on touch) so reordering is discoverable without hovering; the footer keyboard-hint strip is hidden on touch devices where it carries no meaning; and the Current Week modal's early-week progress gauge no longer crowds its per-percent milestone ticks into a sliver below 15% used (#249).
18
+
19
+ ### Fixed
20
+ - Dashboard Projects panel on mobile no longer clips a four-figure project cost — the cost column is now content-sized so a value like $1,234.56 renders at full precision (the project name ellipsizes first instead). The Forecast panel's verdict chip now shows the glyph that matches its state — ✓ when healthy, ⚠ on warn, ⛔ when over — instead of always painting a warning triangle even on a perfectly healthy forecast (#248).
21
+ - Conversation viewer: navigating away from (or closing) a conversation while a jump-to-message is still settling no longer leaves the reader running layout-measurement animation frames against the now-unmounted view — the quiesce wait loop now stops the instant the jump is cancelled. This was invisible in normal use but surfaced as cross-test flakiness in the dashboard test suite, where a leaked frame ran after the test environment was torn down and intermittently failed the full parallel run (#256).
22
+ - Dashboard on mobile: form controls (the Recent Sessions filter/search, the Settings inputs and dropdowns, and the Cache Report threshold popover) no longer trigger iOS Safari's auto-zoom on focus, and the smallest primary data text in Sessions, Projects, and Trend is raised to a legible 14px floor (#247).
23
+ - Dashboard Current Week card no longer shows the snapshot freshness twice — the duplicate "Last snapshot" footer is gone and a single header freshness chip is now the one source of truth, rendered in a calm neutral tone when fresh and a loud amber ⚠ only when the data is genuinely stale (#247).
24
+
25
+ ### Documentation
26
+ - README rewritten as a feature-led landing page: a per-capability tour (live dashboard, conversation viewer, cost-per-1% trend, forecast & budget, threshold alerts, 5-hour analytics, live TUI, shareable reports, Codex parity, diagnostics) replaces the prior single bullet list, with a dedicated conversation-viewer showcase and two new screenshots (desktop reader + mobile phone). All marketing screenshots were regenerated against the current model lineup (Opus 4.8 and Fable 5), and the stale "nine-panel" dashboard description is corrected to the actual eleven panels.
27
+
8
28
  ## [1.57.1] - 2026-06-28
9
29
 
10
30
  ### Fixed
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  </p>
7
7
 
8
8
  <p align="center">
9
- <strong>Claude Code usage tracker and local dashboard for Pro/Max subscription limits - weekly cost-per-percent trend, quota forecasts, threshold alerts. ccusage-compatible.</strong>
9
+ <strong>Local-first usage tracker for Claude Code on Pro/Max - live dashboard, conversation viewer, weekly cost-per-percent trend, quota forecast, and threshold alerts. ccusage-compatible.</strong>
10
10
  </p>
11
11
 
12
12
  <p align="center">
@@ -16,59 +16,46 @@
16
16
  <a href="https://github.com/omrikais/cctally/stargazers"><img src="https://img.shields.io/github/stars/omrikais/cctally.svg" alt="GitHub stars"></a>
17
17
  </p>
18
18
 
19
- If you're using `ccusage` to watch Claude Code spend, `cctally` covers the same ground and adds the parts you reach for next: a live web dashboard, a forecast that tells you whether you're going to cap this week, threshold alerts when you cross a percent, and a persistent week-over-week trend of cost per percent of quota. All local, no account, no telemetry.
19
+ Claude Code's Pro/Max plans meter you on a weekly quota, but the only signal you get is a percentage that creeps up until you cap. `cctally` turns that percentage into something you can act on: it reads your local session logs, computes cost in-process, and shows you **how much each percent of quota is actually costing you, whether you're on track to cap this week, and exactly where the spend is going** - across a live web dashboard, a read-only conversation viewer, and a full set of CLI reports. Everything runs locally against your own `~/.claude` data. No account, no API key, no telemetry, nothing leaves your machine.
20
20
 
21
21
  <p align="center">
22
22
  <img src="docs/img/dashboard-desktop.png" alt="cctally dashboard, desktop view" width="900">
23
23
  </p>
24
24
 
25
- ## Installation
25
+ ## Quick start
26
26
 
27
27
  **Requirements:** Python 3.11+, macOS or Linux, Claude Code installed and run at least once.
28
28
 
29
- ### Homebrew (macOS / Linux)
30
-
31
- ```bash
32
- brew install omrikais/cctally/cctally
33
- cctally setup
34
- ```
35
-
36
- ### npm
37
-
38
29
  ```bash
39
- npm install -g cctally
40
- cctally setup
41
- ```
42
-
43
- Needs Python 3. If `cctally setup` fails with "python3 not found", install it with `brew install python` (macOS) and try again.
30
+ # Homebrew (macOS / Linux)
31
+ brew install omrikais/cctally/cctally && cctally setup
44
32
 
45
- ### From source
33
+ # …or npm
34
+ npm install -g cctally && cctally setup
46
35
 
47
- ```bash
48
- git clone https://github.com/omrikais/cctally
49
- cd cctally
50
- ./bin/cctally setup
36
+ # …or from source
37
+ git clone https://github.com/omrikais/cctally && cd cctally && ./bin/cctally setup
51
38
  ```
52
39
 
53
- `cctally setup` (any channel) symlinks the binaries into `~/.local/bin/`, adds three additive hooks to `~/.claude/settings.json` (never overwrites existing entries), and bootstraps the local SQLite cache. If `~/.local/bin/` isn't on your PATH, the script prints the line to add.
40
+ `cctally setup` symlinks the binaries into `~/.local/bin/`, adds three additive hooks to `~/.claude/settings.json` (it never overwrites existing entries), and bootstraps the local SQLite cache. If `~/.local/bin/` isn't on your `PATH`, the script prints the line to add. The npm install needs Python 3 on `PATH` - if setup reports "python3 not found", install it (`brew install python` on macOS) and re-run.
54
41
 
55
42
  ```bash
56
43
  cctally setup --status # verify hooks + symlinks
57
- cctally daily # cost-by-day, your first table
44
+ cctally daily # cost-by-day - your first table
58
45
  cctally dashboard # opens http://127.0.0.1:8789
59
46
  ```
60
47
 
61
- For status-line integration, alerts, and configuration, see [docs/installation.md](docs/installation.md) and [docs/configuration.md](docs/configuration.md).
48
+ For status-line integration and tuning, see [docs/installation.md](docs/installation.md) and [docs/configuration.md](docs/configuration.md).
62
49
 
63
- ## What it looks like
50
+ ## The live dashboard
64
51
 
65
- ### Dashboard
52
+ `cctally dashboard` serves a web app at `localhost:8789` that updates live as you work - no refresh, no polling. Eleven panels cover the whole picture: **current week**, **forecast**, **$/1% trend**, **recent sessions**, **weekly**, **monthly**, **5-hour blocks**, **daily heatmap**, **projects**, **cache report**, and **recent alerts**. Any panel expands into a focused view, sessions are filterable and searchable, and a settings drawer tunes alerts and display options on the fly. It runs only on your own machine by default; one flag opens it to the other devices on your network when you want that.
66
53
 
67
54
  <table>
68
55
  <tr>
69
56
  <td>
70
57
  <img src="docs/img/dashboard-modal.png" alt="Dashboard with trend modal open">
71
- <br><em>Any panel expands into a focused view. The trend modal shows twelve weeks of cost per percent.</em>
58
+ <br><em>Any panel expands into a focused view - here, twelve weeks of cost per percent.</em>
72
59
  </td>
73
60
  <td>
74
61
  <img src="docs/img/dashboard-warn.png" alt="Dashboard in warn state">
@@ -78,12 +65,34 @@ For status-line integration, alerts, and configuration, see [docs/installation.m
78
65
  <tr>
79
66
  <td colspan="2" align="center">
80
67
  <img src="docs/img/dashboard-mobile.png" alt="Dashboard on phone" width="350">
81
- <br><em>The same dashboard on your phone.</em>
68
+ <br><em>The same dashboard, reflowed for your phone.</em>
82
69
  </td>
83
70
  </tr>
84
71
  </table>
85
72
 
86
- ### CLI tables
73
+ See [docs/commands/dashboard.md](docs/commands/dashboard.md).
74
+
75
+ ## Conversation viewer ⭐
76
+
77
+ The dashboard's **Conversations** tab is a read-only reader for your Claude Code transcripts - your local session history, rendered the way you'd actually want to review it. A searchable rail lists every conversation with its project, branch, model chips, and cost; the reader shows the full turn-by-turn flow with thinking blocks, tool calls (with diffs and command output), and a per-turn cost-and-token breakdown. Parallel **subagent threads** render as their own nested threads, an outline pane jumps you to any turn, and an in-conversation find bar plus a faceted full-text search (prompts, assistant text, tools, thinking) make a month of sessions navigable. The open conversation **live-tails** as you work, updating within a second.
78
+
79
+ It only reads your transcripts - it never changes them - and everything stays on your own machine. Nothing is uploaded, and the viewer is reachable only from your computer unless you choose to share the dashboard with your network.
80
+
81
+ <p align="center">
82
+ <img src="docs/img/conversation-reader.png" alt="Conversation viewer: rail, threaded reader, and outline" width="900">
83
+ <br>
84
+ <em>Rail, threaded reader with tool cards and a subagent thread, and the jump-to outline.</em>
85
+ </p>
86
+
87
+ <p align="center">
88
+ <img src="docs/img/conversation-mobile.png" alt="Conversation viewer on a phone" width="300">
89
+ <br>
90
+ <em>The same reader on your phone.</em>
91
+ </p>
92
+
93
+ ## Cost per 1% of quota
94
+
95
+ The signature view. `cctally report` reframes each subscription week's spend as **dollars per percent of quota used**, so you can see your spending efficiency trend week over week - and whether this week is pulling above or below the line - instead of staring at a raw percentage. Persisted to SQLite, so the comparison survives across runs.
87
96
 
88
97
  <p align="center">
89
98
  <img src="docs/img/cli-report.svg" alt="cctally report: $ per 1% weekly trend">
@@ -91,19 +100,39 @@ For status-line integration, alerts, and configuration, see [docs/installation.m
91
100
  <em>Weekly cost as dollars per percent of quota, with the delta against the prior week.</em>
92
101
  </p>
93
102
 
103
+ See [docs/commands/report.md](docs/commands/report.md).
104
+
105
+ ## Forecast & budget
106
+
107
+ `cctally forecast` projects where your weekly percentage lands at the next reset - using both a week-average and a recent-24h rate - and tells you the daily $/% budget you'd need to stay under the 100% and 90% ceilings. When the data is thin it says so (`LOW CONF`) rather than guessing.
108
+
94
109
  <p align="center">
95
110
  <img src="docs/img/cli-forecast.svg" alt="cctally forecast: will I cap this week?">
96
111
  <br>
97
112
  <em>Projected percent at the weekly reset, plus the daily budget to stay under the cap.</em>
98
113
  </p>
99
114
 
115
+ For dollar budgets, `cctally budget` tracks an equivalent-vs-actual spend target over a configurable calendar period - per vendor, for both Claude and Codex - with a pace projection and an `ok`/`warn`/`over` verdict. See [docs/commands/forecast.md](docs/commands/forecast.md) and [docs/commands/budget.md](docs/commands/budget.md).
116
+
117
+ ## Threshold alerts
118
+
119
+ Get a native desktop notification the moment you cross a percent milestone, so a runaway week can't sneak up on you. Alerts fire on weekly percent, 5-hour blocks, and budget thresholds, with three severity levels (info / warn / critical) and native popups on macOS and Linux - or run a command of your own. `cctally alerts test` confirms it's wired up. See [docs/commands/alerts.md](docs/commands/alerts.md).
120
+
121
+ ## 5-hour analytics
122
+
123
+ Claude Code's quota also runs on rolling 5-hour windows. `cctally blocks` and `cctally five-hour-blocks` break usage down per window - anchored to the real API resets, not a re-sizable guess - with model and project rollups and cross-reset flags, and `cctally five-hour-breakdown` drills into the per-percent milestones inside a single block.
124
+
100
125
  <p align="center">
101
126
  <img src="docs/img/cli-five-hour-blocks.svg" alt="cctally five-hour-blocks: 5h analytics with model breakdown">
102
127
  <br>
103
- <em>Each 5-hour window, broken down by model.</em>
128
+ <em>Each 5-hour window, with rollup totals and 7-day drift.</em>
104
129
  </p>
105
130
 
106
- ### Live terminal
131
+ See [docs/commands/blocks.md](docs/commands/blocks.md) and [docs/commands/five-hour-blocks.md](docs/commands/five-hour-blocks.md).
132
+
133
+ ## Live terminal UI
134
+
135
+ Prefer to stay in the terminal, or working over SSH? `cctally tui` shows the same live data as a refreshing terminal dashboard. It's the one feature that needs the optional `rich` library; every other command runs on a plain Python install with nothing else to set up.
107
136
 
108
137
  <p align="center">
109
138
  <img src="docs/img/cli-tui.svg" alt="cctally tui: live terminal dashboard">
@@ -111,29 +140,32 @@ For status-line integration, alerts, and configuration, see [docs/installation.m
111
140
  <em>The same data in the terminal, refreshed live.</em>
112
141
  </p>
113
142
 
114
- ## What cctally adds
143
+ See [docs/commands/tui.md](docs/commands/tui.md).
144
+
145
+ ## Shareable reports
146
+
147
+ All eight reporting commands (`report`, `daily`, `monthly`, `weekly`, `forecast`, `project`, `five-hour-blocks`, `session`) can render to shareable Markdown, HTML, or SVG with `--format`, a light/dark `--theme`, and `--output` / `--copy` / `--open`. Project names anonymize by default (`--reveal-projects` opts in), so you can post a snapshot without leaking where you work. See [docs/commands/share.md](docs/commands/share.md).
148
+
149
+ ## Codex parity
150
+
151
+ If you also use OpenAI's Codex CLI, `cctally codex daily / monthly / session` are drop-ins for `ccusage codex daily / monthly / session`, reading from `~/.codex/sessions/`. The flat `codex-*` forms (drop-ins for the standalone `ccusage-codex` binary) stay as aliases, and `cctally codex weekly` adds a subscription-week rollup that upstream doesn't have. See [docs/commands/codex.md](docs/commands/codex.md).
152
+
153
+ ## Diagnostics & upkeep
154
+
155
+ `cctally doctor` gives you a read-only health check - install, hooks, sign-in, database, data freshness, pricing, and safety - and the same status shows up in the dashboard. `cctally pricing-check` warns you when the built-in model pricing is getting stale, `cctally db` manages the local database, and `cctally update` keeps your install current. The local cache is always safe to delete or rebuild.
115
156
 
116
- `cctally` started as a local-first replacement for [`ccusage`](https://github.com/ryoppippi/ccusage), and it stays compatible at the level of common CLI flows (`daily`, `monthly`, `weekly`, `session`, `blocks`). Paste from ccusage verbatim: `cctally claude <cmd>` is a drop-in for `ccusage claude <cmd>` (and `cctally codex <cmd>` for `ccusage codex <cmd>`), with the flat forms (`cctally daily`, `cctally codex-daily`, …) kept as aliases. Beyond that, it adds:
157
+ ## A faster, local-first ccusage
117
158
 
118
- - **Live web dashboard.** Nine-panel SSE-driven view at `localhost:8789` (current week, forecast, trend, sessions, weekly, monthly, blocks, daily, recent alerts), with per-panel modals, a mobile layout, threshold alerts, and a settings drawer.
119
- - **TUI live mode.** The same data inside your terminal (`cctally tui`; requires the optional `rich` package).
120
- - **$-per-1% weekly trend.** The `report` table reframes weekly cost as cost-per-percent-of-quota, so spending efficiency is visible week over week.
121
- - **Forecast.** Projects current-week percent and daily $/% budgets against the 100% and 90% ceilings (`cctally forecast`).
122
- - **Threshold alerts.** Configurable percent crossings with native macOS popups (`cctally alerts`).
123
- - **5-hour block analytics.** Per-block usage with model and project breakdowns (`cctally five-hour-blocks --breakdown=model`).
124
- - **Time-window diff.** Compare two windows with model and project decomposition (`cctally diff`).
125
- - **Project rollup.** Usage by Git project (`cctally project`).
126
- - **Codex parity.** `cctally codex daily / monthly / session` are drop-ins for `ccusage codex daily / monthly / session`; the flat `codex-*` forms (drop-ins for the standalone `ccusage-codex` binary) remain as aliases, plus an added `cctally codex weekly` / `cctally codex-weekly` rollup (upstream has no `codex weekly`).
127
- - **Persistent SQLite.** Week-over-week comparisons survive across runs.
159
+ `cctally` started as a local replacement for [`ccusage`](https://github.com/ryoppippi/ccusage) and stays compatible at the level of common flows: `cctally claude <cmd>` is a drop-in for `ccusage claude <cmd>` (and `cctally codex <cmd>` for `ccusage codex <cmd>`), with the flat forms (`cctally daily`, `cctally codex-daily`, …) kept as aliases. Paste your ccusage commands verbatim - then reach for the dashboard, forecast, trend, conversation viewer, and alerts that ccusage doesn't have.
128
160
 
129
- **On speed.** Pricing is embedded and computed at query time from a delta-tail SQLite cache (`~/.local/share/cctally/cache.db`), with no shell-outs. First-table latency on 30 days of session data: **~2.6s (cctally) vs ~31s (ccusage)**, about 12× faster. Measured by `bench/cctally-vs-ccusage.sh` on macOS arm64, 2026-05-05; your numbers will vary.[^bench]
161
+ It's also fast. Pricing is built in and computed in-process from a local SQLite cache, with no external tools to spawn. First table on 30 days of session data: **~2.6s (cctally) vs ~31s (ccusage)**, about 12× faster. Measured by `bench/cctally-vs-ccusage.sh` on macOS arm64, 2026-05-05; your numbers will vary.[^bench]
130
162
 
131
163
  <!--
132
164
  Footnote target uses an absolute URL because GitHub's relative-link
133
165
  rewriter doesn't traverse into GFM footnote `<li>` content; on the
134
166
  repo home page (`/omrikais/cctally`, no trailing slash) the browser
135
167
  would resolve `bench/README.md` against the page URL and produce
136
- `/omrikais/bench/README.md` a broken path. Regular paragraph links
168
+ `/omrikais/bench/README.md` - a broken path. Regular paragraph links
137
169
  are unaffected.
138
170
  -->
139
171
  [^bench]: Methodology and reproduction: [`bench/README.md`](https://github.com/omrikais/cctally/blob/main/bench/README.md).
@@ -53,7 +53,7 @@ def _chip_for_model(name: str) -> str:
53
53
  # Date the embedded pricing snapshots below were last verified against
54
54
  # vendor sources. Bump whenever CLAUDE_MODEL_PRICING / CODEX_MODEL_PRICING
55
55
  # is synced. Read by `pricing-check` + the release pre-flight staleness nudge.
56
- PRICING_SNAPSHOT_DATE = "2026-06-10"
56
+ PRICING_SNAPSHOT_DATE = "2026-07-01"
57
57
  PRICING_STALENESS_DAYS = 60 # release pre-flight WARNs past this age
58
58
 
59
59
  # Canonical machine-readable pricing source (Claude values + Codex values).
@@ -71,11 +71,17 @@ PRICING_DRIFT_ALLOWLIST: list[dict] = []
71
71
 
72
72
  # Anthropic API pricing snapshot:
73
73
  # - Source: https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json
74
- # - Captured: 2026-06-10 (see PRICING_SNAPSHOT_DATE)
74
+ # - Captured: 2026-07-01 (see PRICING_SNAPSHOT_DATE)
75
75
  # - Verified by maintainer against docs.claude.com/en/docs/about-claude/pricing;
76
76
  # update in PRs touching this table.
77
77
  # 2026-06-10: added claude-fable-5 ($10/$50 per MTok; 1M context, no
78
78
  # long-context premium) — issue #172.
79
+ # 2026-07-01: added claude-sonnet-5 ($3/$15 per MTok; 1M context, flat-rate
80
+ # across the full window — no long-context premium, same shape as
81
+ # claude-sonnet-4-6). Embedded the STANDARD rate, not the $2/$10 introductory
82
+ # rate in effect through 2026-08-31, to match what LiteLLM will publish and
83
+ # the durable post-cutover price. LiteLLM has no sonnet-5 entry yet, so the
84
+ # table is ahead_of_litellm (not a drift finding).
79
85
  CLAUDE_MODEL_PRICING: dict[str, dict[str, Any]] = {
80
86
  "claude-3-5-haiku-20241022": {
81
87
  "input_cost_per_token": 8e-07,
@@ -267,6 +273,12 @@ CLAUDE_MODEL_PRICING: dict[str, dict[str, Any]] = {
267
273
  "cache_creation_input_token_cost": 3.75e-06,
268
274
  "cache_read_input_token_cost": 3e-07,
269
275
  },
276
+ "claude-sonnet-5": {
277
+ "input_cost_per_token": 3e-06,
278
+ "output_cost_per_token": 1.5e-05,
279
+ "cache_creation_input_token_cost": 3.75e-06,
280
+ "cache_read_input_token_cost": 3e-07,
281
+ },
270
282
  }
271
283
 
272
284
  _unknown_model_warnings: set[str] = set()