cdx-manager 0.20.5 → 0.20.6

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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  <br clear="left"/>
6
6
 
7
- [![License](https://img.shields.io/badge/license-MIT-4C8BF5)](LICENSE) ![Version](https://img.shields.io/badge/version-v0.20.5-4C8BF5) ![Python](https://img.shields.io/badge/python-3.9%2B-3776AB?logo=python&logoColor=white)
7
+ [![License](https://img.shields.io/badge/license-MIT-4C8BF5)](LICENSE) ![Version](https://img.shields.io/badge/version-v0.20.6-4C8BF5) ![Python](https://img.shields.io/badge/python-3.9%2B-3776AB?logo=python&logoColor=white)
8
8
 
9
9
  **Stop guessing which AI account still has quota.** `cdx` tracks the rate-limit window of every Codex and Claude account you own, tells you which one is usable right now, and launches it with isolated auth — in one command.
10
10
 
@@ -725,13 +725,13 @@ Every usage record, whichever path produced it, uses one set of definitions:
725
725
 
726
726
  Cached input is counted once: it is excluded from `input_tokens` and reported in the cache fields, never in both. `null` means the provider did not report the figure, which is not the same as zero.
727
727
 
728
- `cdx stats` also shows a **`COST~`** column and ranks sessions by it. It weights each token class by what it costs relative to one uncached input token — cache read 0.1x, cache write 1.25x, output 5x — and reports the result in uncached-input-equivalent tokens. These are ratios rather than prices: across the current model lineup output is 5x input on every model and the cache multipliers do not vary by model either, so the figure needs no per-model price table and does not go stale when prices change. It is **not** a currency amount, and it is not comparable across providers whose own prices differ. The cache-write multiplier assumes the five-minute cache TTL; a one-hour TTL costs 2x and nothing in a transcript says which was used, so long-TTL writes are slightly under-weighted.
728
+ `cdx stats` also shows a **`COST~`** column and ranks sessions by it. It weights each token class by what it costs relative to one uncached input token — cache read 0.1x, cache write 1.25x, and output at the recorded model's output/input ratio — and reports the result in uncached-input-equivalent tokens. These are ratios rather than prices. It is **not** a currency amount, and it is not comparable across providers whose own prices differ. The cache-write multiplier assumes the five-minute cache TTL; a one-hour TTL costs 2x and nothing in a transcript says which was used, so long-TTL writes are slightly under-weighted.
729
729
 
730
730
  Ranking on the raw total would put a session that mostly replayed a cache above one that spent far more on generation, because cache reads are typically the overwhelming majority of tokens consumed while costing a fiftieth of an output token.
731
731
 
732
732
  The **`USD~`** column turns that into money for runs whose serving model cdx recorded. It needs one number per model — the list price per million uncached input tokens — because `COST~` has already absorbed every other rate. Prices live in configuration, not in code: set `CDX_TOKEN_PRICES` to a JSON object mapping model id to dollars per million tokens to override the built-in table, whose last review date is printed with the totals. A run whose model cdx never saw stays unpriced rather than being charged at a default tier, and the totals line says how many runs were actually priced.
733
733
 
734
- The table carries two numbers per model — uncached input and output per million tokens — and derives the cache rates from the input rate: a cache read is 0.1x it and a cache write 1.25x, a relationship that holds on both vendors. Each token class is then priced at its own rate rather than through the weighted figure, because the weighted shortcut is only correct while every model shares one output ratio, and they do not: Anthropic bills output at 5x input, OpenAI at 6x.
734
+ The table carries two numbers per model — uncached input and output per million tokens — and derives the cache rates from the input rate: a cache read is 0.1x it and a cache write 1.25x, a relationship that holds on the supported non-Pro model rows. Each token class is then priced at its own rate rather than through a weighted shortcut, because output/input ratios vary by model.
735
735
 
736
736
  Three caveats stated rather than hidden. A run is priced at the model serving its most recent record, so a run that switched models mid-way is priced at the newer one. The figure is an estimate at public list prices — not an invoice. And OpenAI's long-context tier, which roughly doubles both rates above a 272K-token request, is **not** modelled: cdx records tokens per run rather than per request, so it cannot tell which requests crossed that line, and long-context Codex work is under-costed.
737
737
 
@@ -742,7 +742,7 @@ Totals: 26 runs, ... ; no price for gpt-6-unreleased)
742
742
  CDX_TOKEN_PRICES='{"gpt-6-unreleased": {"input": 3, "output": 18}}' cdx stats
743
743
  ```
744
744
 
745
- **Prices are the only part of this that rots on its own.** A test fails once the table has gone 90 days without review, and `scripts/check_token_prices.py` compares it against published pricing — outside the test suite, since a check that needs the network fails for reasons nobody wants in CI. A row it cannot confirm is reported as unverified, never as passing. When it finds a difference, follow [`docs/token-prices-runbook.md`](docs/token-prices-runbook.md) — which also records where each vendor's numbers actually live, and which pages refuse to be read by a script.
745
+ **Prices are the only part of this that rots on its own.** A test fails once the table has gone 90 days without review, and `scripts/check_token_prices.py` compares it against published pricing — outside the test suite, since a check that needs the network fails for reasons nobody wants in CI. A row it cannot confirm is reported as unverified, never as passing. When it finds a difference, follow [`logics/runbook/run_005_maintaining_the_token_price_table.md`](logics/runbook/run_005_maintaining_the_token_price_table.md) — which also records where each vendor's numbers actually live.
746
746
 
747
747
  Runs recorded before these definitions existed carry figures that are fictitious rather than imprecise — one real session reported 206.6M cached tokens for a period in which its own conversation consumed 33,608, because the old reader picked whichever transcript had the newest modification time and re-read all of it on every launch. They cannot be recomputed: a run's true usage is the increment its transcript gained while it ran, and nothing recorded that. They are therefore excluded from every total automatically, and the totals line says how many runs that covered — so a period containing only such runs reads as absent rather than as a session that spent nothing. The records themselves are left alone, which keeps them recoverable if the marker ever proves wrong; `cdx repair` clears them from the file for anyone who would rather they were gone:
748
748
 
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.20.5
1
+ 0.20.6
@@ -0,0 +1,14 @@
1
+ # CDX Manager 0.20.6
2
+
3
+ ## Fixes
4
+
5
+ - `cdx stats` now prices current Codex/OpenAI and Claude models that were
6
+ previously unpriced or stale, including `gpt-5.5`, `gpt-5.6-terra`, and the
7
+ current Claude Sonnet/Haiku snapshot ids seen in real usage history.
8
+ - The token price review tooling now checks OpenAI's official pricing
9
+ documentation directly and points maintainers at the active Logics runbook.
10
+
11
+ ## Notes
12
+
13
+ - Pro-only or credit-based Codex models without an official token price remain
14
+ unpriced rather than receiving a guessed USD estimate.
@@ -364,6 +364,17 @@
364
364
  "x86_64-pc-windows-msvc": "7508e04ee07adb7a500b346be1d3891d93aec54dc0ff53643bd8c57e4e411118",
365
365
  "x86_64-unknown-linux-musl": "47a1c8cff60c896db659d30d74496045d8c343e74a00f826e608f3973e735532"
366
366
  }
367
+ },
368
+ "v0.20.5": {
369
+ "github_tarball_sha256": "6360b48c4e7c3e79f213174d55fa6679ea2e94b016e0de3ebe77a39cdac98856",
370
+ "github_zip_sha256": "6fed447ed9facf353205745265935fd5c7d73b877e7b933cc53b08656fb1b32a",
371
+ "tray_assets": {
372
+ "aarch64-apple-darwin": "5f2bf81fc17f49479e2880d0312e8f60bcd23a87b7d4978c7161015f75783f03",
373
+ "aarch64-unknown-linux-musl": "76a5a362f5a2c41cab23165760f7d9d3fb5bfbe5a2e9d5b9643afb30e6d65e0d",
374
+ "x86_64-apple-darwin": "ecc05376dd93c043b36dad6e9a27e129c00898227f204e0c8f050ee834138239",
375
+ "x86_64-pc-windows-msvc": "208064f2bfee19914ca72edb527966a9966154179d6d040f0dae4a647a61f9f4",
376
+ "x86_64-unknown-linux-musl": "9fa01d3b71daed98c9234ddb0cf7b6345b3d757edff910ece4e3bd9f5eb8eb6b"
377
+ }
367
378
  }
368
379
  }
369
380
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdx-manager",
3
- "version": "0.20.5",
3
+ "version": "0.20.6",
4
4
  "description": "Terminal session manager for Codex and Claude accounts.",
5
5
  "license": "MIT",
6
6
  "author": "Alexandre Agostini",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cdx-manager"
7
- version = "0.20.5"
7
+ version = "0.20.6"
8
8
  description = "Terminal session manager for Codex and Claude accounts."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
package/src/run_usage.py CHANGED
@@ -99,9 +99,8 @@ CACHE_READ_MULTIPLIER = 0.1
99
99
  CACHE_WRITE_MULTIPLIER = 1.25
100
100
 
101
101
  #: What an output token costs relative to an uncached input one, when the model
102
- #: is unknown. Anthropic bills 5x and OpenAI 6x, so an unknown model is priced
103
- #: at the lower of the two: understating a cost cdx is guessing at is the safer
104
- #: direction.
102
+ #: is unknown. Current model ratios vary, so an unknown model is priced at the
103
+ #: low known ratio: understating a cost cdx is guessing at is the safer direction.
105
104
  DEFAULT_OUTPUT_MULTIPLIER = 5.0
106
105
 
107
106
 
@@ -155,13 +154,11 @@ def weighted_usage(usage, model=None, prices=None):
155
154
  #: rather than editing code, and treat an unknown model as unpriced instead of
156
155
  #: assuming a tier. `scripts/check_token_prices.py` re-checks this table
157
156
  #: against published pricing and a staleness test fails when nobody has;
158
- #: `docs/token-prices-runbook.md` records where the numbers live and which
157
+ #: `logics/runbook/run_005_maintaining_the_token_price_table.md` records where the numbers live and which
159
158
  #: vendor pages refuse to be read.
160
159
  #:
161
- #: Anthropic figures come from the vendor's own reference. OpenAI figures were
162
- #: taken from third-party aggregators on 2026-08-14 because openai.com refuses
163
- #: automated fetches; four sources agreed on $2.50/$15 for Terra and one
164
- #: outlier said $2/$12, so these carry more doubt than the Anthropic rows.
160
+ #: Anthropic and OpenAI figures come from the vendors' own references, checked
161
+ #: on the review date below.
165
162
  #:
166
163
  #: Not modelled: OpenAI's long-context tier, which roughly doubles both rates
167
164
  #: above a 272K-token request. cdx records tokens per run, not per request, so
@@ -175,15 +172,29 @@ DEFAULT_TOKEN_PRICES = {
175
172
  "claude-opus-4-8": {"input": 5.0, "output": 25.0},
176
173
  "claude-opus-4-7": {"input": 5.0, "output": 25.0},
177
174
  "claude-opus-4-6": {"input": 5.0, "output": 25.0},
178
- "claude-sonnet-5": {"input": 3.0, "output": 15.0},
175
+ "claude-opus-4-5": {"input": 5.0, "output": 25.0},
176
+ "claude-sonnet-5": {"input": 2.0, "output": 10.0},
179
177
  "claude-sonnet-4-6": {"input": 3.0, "output": 15.0},
178
+ "claude-sonnet-4-5": {"input": 3.0, "output": 15.0},
179
+ "claude-sonnet-4-5-20250929": {"input": 3.0, "output": 15.0},
180
180
  "claude-haiku-4-5": {"input": 1.0, "output": 5.0},
181
+ "claude-haiku-4-5-20251001": {"input": 1.0, "output": 5.0},
181
182
  # OpenAI
182
- "gpt-5.6-sol": {"input": 5.0, "output": 30.0},
183
- "gpt-5.6-terra": {"input": 2.5, "output": 15.0},
184
- "gpt-5.6-luna": {"input": 1.0, "output": 6.0},
183
+ "gpt-5.6": {"input": 4.0, "output": 20.0},
184
+ "gpt-5.6-sol": {"input": 4.0, "output": 20.0},
185
+ "gpt-5.6-terra": {"input": 2.0, "output": 12.0},
186
+ "gpt-5.6-luna": {"input": 0.2, "output": 1.2},
187
+ "gpt-5.5": {"input": 5.0, "output": 30.0},
188
+ "gpt-5.5-2026-04-23": {"input": 5.0, "output": 30.0},
189
+ "gpt-5.4": {"input": 2.5, "output": 15.0},
190
+ "gpt-5.4-2026-03-05": {"input": 2.5, "output": 15.0},
191
+ "gpt-5.4-mini": {"input": 0.75, "output": 4.5},
192
+ "gpt-5.4-mini-2026-03-17": {"input": 0.75, "output": 4.5},
193
+ "gpt-5.4-nano": {"input": 0.2, "output": 1.25},
194
+ "gpt-5.4-nano-2026-03-17": {"input": 0.2, "output": 1.25},
195
+ "gpt-5.3-codex": {"input": 1.75, "output": 14.0},
185
196
  }
186
- TOKEN_PRICES_REVIEWED = "2026-08-14"
197
+ TOKEN_PRICES_REVIEWED = "2026-08-22"
187
198
  #: How long a review stays fresh before the staleness test asks for another.
188
199
  TOKEN_PRICES_MAX_AGE_DAYS = 90
189
200
  TOKEN_PRICES_ENV = "CDX_TOKEN_PRICES"
@@ -215,8 +226,7 @@ def estimate_cost(usage, model, prices=None):
215
226
 
216
227
  Each token class is priced directly rather than through the weighted
217
228
  figure. That shortcut was only correct while every model shared one
218
- output-to-input ratio, and it does not: Anthropic bills 5x, OpenAI 6x, so
219
- it under-costed Codex output by a fifth.
229
+ output-to-input ratio, and they do not.
220
230
 
221
231
  ponytail: a run is priced at one model -- the one serving its most recent
222
232
  record -- rather than split per model. A session that switches models