coding-agent-cost 0.2.0__tar.gz → 0.2.1__tar.gz
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.
- {coding_agent_cost-0.2.0/coding_agent_cost.egg-info → coding_agent_cost-0.2.1}/PKG-INFO +3 -4
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/README.md +2 -3
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/__init__.py +1 -1
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/rates.json +43 -5
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1/coding_agent_cost.egg-info}/PKG-INFO +3 -4
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/coding_agent_cost.egg-info/SOURCES.txt +1 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/pyproject.toml +1 -1
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_astra_pricing.py +2 -2
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_e0a_review3_hardening.py +3 -3
- coding_agent_cost-0.2.1/tests/test_opus_5_5_rates.py +74 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_rates.py +1 -1
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_version_consistency.py +3 -3
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/LICENSE +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/aggregate.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/cli.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/config.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/facts.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/rates.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/readers/__init__.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/readers/claude.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/readers/codex.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/agent_cost/renderers.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/coding_agent_cost.egg-info/dependency_links.txt +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/coding_agent_cost.egg-info/entry_points.txt +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/coding_agent_cost.egg-info/top_level.txt +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/setup.cfg +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_aggregate.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_cli.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_e0a_fable_5_1_and_sonnet_5_correction.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_facts.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_measure_v1_contract.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_reader_claude.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_reader_codex.py +0 -0
- {coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/tests/test_reader_dedup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coding-agent-cost
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Estimate AI coding agent (Claude Code / Codex CLI) token usage and cost from local logs
|
|
5
5
|
Author: shiki-yusuke
|
|
6
6
|
License: MIT
|
|
@@ -266,8 +266,7 @@ network, never calls `gh`, and never resolves branches or PRs.
|
|
|
266
266
|
in the report's `data_quality` block instead of being silently dropped or
|
|
267
267
|
clamped to zero.
|
|
268
268
|
- **Known catalog gaps**, tracked in `agent_cost/rates.json`'s `notes`:
|
|
269
|
-
`
|
|
270
|
-
source, so its rate period's `effective_from` is a placeholder. `gpt-5.6`
|
|
269
|
+
`gpt-5.6`
|
|
271
270
|
(Sol/Terra/Luna) credits could not be confirmed from the primary source
|
|
272
271
|
(`help.openai.com`'s Codex rate card returns HTTP 403 to automated
|
|
273
272
|
fetches); the values in the catalog come from several independent
|
|
@@ -342,7 +341,7 @@ agent-cost measure --session-id <id> [--session-id <id> ...] \
|
|
|
342
341
|
```json
|
|
343
342
|
{
|
|
344
343
|
"protocol_version": "measure/v1",
|
|
345
|
-
"producer_version": "0.2.
|
|
344
|
+
"producer_version": "0.2.1",
|
|
346
345
|
"accounting_basis": "agent-cost-raw-total/v2",
|
|
347
346
|
"generated_at": "...",
|
|
348
347
|
"window": { "since": "...", "until": null },
|
|
@@ -240,8 +240,7 @@ network, never calls `gh`, and never resolves branches or PRs.
|
|
|
240
240
|
in the report's `data_quality` block instead of being silently dropped or
|
|
241
241
|
clamped to zero.
|
|
242
242
|
- **Known catalog gaps**, tracked in `agent_cost/rates.json`'s `notes`:
|
|
243
|
-
`
|
|
244
|
-
source, so its rate period's `effective_from` is a placeholder. `gpt-5.6`
|
|
243
|
+
`gpt-5.6`
|
|
245
244
|
(Sol/Terra/Luna) credits could not be confirmed from the primary source
|
|
246
245
|
(`help.openai.com`'s Codex rate card returns HTTP 403 to automated
|
|
247
246
|
fetches); the values in the catalog come from several independent
|
|
@@ -316,7 +315,7 @@ agent-cost measure --session-id <id> [--session-id <id> ...] \
|
|
|
316
315
|
```json
|
|
317
316
|
{
|
|
318
317
|
"protocol_version": "measure/v1",
|
|
319
|
-
"producer_version": "0.2.
|
|
318
|
+
"producer_version": "0.2.1",
|
|
320
319
|
"accounting_basis": "agent-cost-raw-total/v2",
|
|
321
320
|
"generated_at": "...",
|
|
322
321
|
"window": { "since": "...", "until": null },
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": "1",
|
|
3
|
-
"catalog_version": "2026-09-
|
|
3
|
+
"catalog_version": "2026-09-23",
|
|
4
4
|
"currency": "USD",
|
|
5
5
|
"unit": "per_mtok",
|
|
6
6
|
"usd_per_credit": "0.04",
|
|
7
7
|
"notes": [
|
|
8
8
|
"All Claude rates are standard (non-batch, non-priority) API prices. Batch API is roughly 50% off, but agent-cost's logs have no signal for whether a given request went through Batch, so batch usage is priced at standard rates and will overstate cost for anyone using Batch.",
|
|
9
|
-
"claude-opus-5
|
|
9
|
+
"claude-opus-5 effective_from corrected 2026-09-23: the 2026-07-01 placeholder (rate_id claude-opus-5-launch-date-unconfirmed) is replaced by the official launch date 2026-07-24 (anthropic.com/news/claude-opus-5, dated 'Jul 24, 2026'), rate_id claude-opus-5-launch-2026-07-24 -- the period is replaced rather than edited in place, following the claude-sonnet-5-standard -> claude-sonnet-5-standard-2026-09-01 correction precedent (rate_id is not consumed by any reader or report field; reports pin catalog_version + sha256). The source gives a calendar date only, so effective_from is 00:00:00Z of that day: a transcript row carrying this model ID cannot predate the public launch, so nothing on the launch day is mispriced by the earlier-of-day boundary. The earliest claude-opus-5 row across local transcripts is 2026-07-28T18:22:52Z, so no locally observed event moves from priced to unpriced; events between 2026-07-01 and 2026-07-23 that were priced under the placeholder are now unpriced, which is the correct treatment for a model that did not exist yet.",
|
|
10
10
|
"gpt-5.6 (sol/terra/luna) credits could not be confirmed from the primary source (help.openai.com's Codex rate card returned HTTP 403 to automated fetches). The values here were cross-checked across several independent secondary sources that agreed with each other and are internally consistent (Sol's $5/$30 per-MTok API price x 25 = 125/750 credits, matching usd_per_credit=0.04); see the gpt-5.6-* sources entries below. Treat effective_from (2026-07-01) as a placeholder and re-verify against the primary rate card when it becomes reachable.",
|
|
11
11
|
"gpt-6-astra: Codex standard token-based rates only; not API pricing, legacy message metering, or actual contractual charges. Confirmed 2026-09-06 JST (2026-09-05T17:18:23Z). effective_from is this observation cutoff, NOT an official launch or price-start time; earlier events remain unpriced. No Codex long-context surcharge or cache-write charge is applied. Fast multiplier 2.5 applies to explicit priority request settings with matching owned turn/model context; explicit default uses Standard. Missing or ambiguous Astra modes remain unpriced. These settings do not confirm the backend processing tier. See docs/astra-pricing.md for compatibility limits and the separate GPT-5.6 discrepancy report.",
|
|
12
12
|
"claude-fable-5-1 added 2026-09-09: rate_id claude-fable-5-1-local-first-observed-2026-09-02. effective_from (2026-09-02T01:17:55Z) is the timestamp the raw model ID was first observed across all 54 local transcript files (none found in August), not a confirmed official launch date -- if an authoritative launch date is confirmed later, add it as a separate rate_id with effective_until on this one rather than editing this period in place. Values (cache_read $0.25/MTok = 0.025x base input) differ from claude-fable-5's cache_read ($1.00/MTok = 0.1x); this is a genuine per-model price difference confirmed against the primary source (see sources below), not an inconsistency to reconcile.",
|
|
13
|
-
"claude-sonnet-5 corrected 2026-09-09: a prior period (rate_id claude-sonnet-5-standard, effective_from 2026-09-01, values 3.0/0.30/3.75/6.0/15.0) priced a previously-announced rate increase that the pricing page's claude-sonnet-5-introductory-pricing note states did not occur (\"The previously scheduled increase to $3/$15 ... on September 1, 2026 will not occur\"). That period has been replaced by claude-sonnet-5-standard-2026-09-01, which carries the same $2/$0.20/$2.50/$4/$10 values as the preceding claude-sonnet-5-launch-promo period, since the launch price is confirmed to be the ongoing price with no change at the 2026-09-01 boundary. Any measure/v1 or report output computed against the pre-correction catalog for claude-sonnet-5 sessions occurring on or after 2026-09-01 overstated cost by 1.5x for that model. To detect this class of error going forward, cross-check each priced model's rate periods against its primary pricing page's Note text on a recurring (e.g. monthly) basis for mentions of a rate-change announcement being withdrawn or not taking effect -- a period can be internally valid (schema-wise) and still price a rate that was announced but never actually charged."
|
|
13
|
+
"claude-sonnet-5 corrected 2026-09-09: a prior period (rate_id claude-sonnet-5-standard, effective_from 2026-09-01, values 3.0/0.30/3.75/6.0/15.0) priced a previously-announced rate increase that the pricing page's claude-sonnet-5-introductory-pricing note states did not occur (\"The previously scheduled increase to $3/$15 ... on September 1, 2026 will not occur\"). That period has been replaced by claude-sonnet-5-standard-2026-09-01, which carries the same $2/$0.20/$2.50/$4/$10 values as the preceding claude-sonnet-5-launch-promo period, since the launch price is confirmed to be the ongoing price with no change at the 2026-09-01 boundary. Any measure/v1 or report output computed against the pre-correction catalog for claude-sonnet-5 sessions occurring on or after 2026-09-01 overstated cost by 1.5x for that model. To detect this class of error going forward, cross-check each priced model's rate periods against its primary pricing page's Note text on a recurring (e.g. monthly) basis for mentions of a rate-change announcement being withdrawn or not taking effect -- a period can be internally valid (schema-wise) and still price a rate that was announced but never actually charged.",
|
|
14
|
+
"claude-opus-5-5 added 2026-09-23: rate_id claude-opus-5-5-launch-2026-09-22. effective_from 2026-09-22T00:00:00Z is 00:00:00Z of the official public launch date (anthropic.com/claude-opus-5-5, 'September 22, 2026'); the launch time of day is not published, but a transcript row whose raw model ID is claude-opus-5-5 cannot predate the launch, so pricing from the start of that UTC day cannot price a pre-launch event. Values 4.0/0.20/5.0/8.0/20.0 per the pricing page: cache_read is 0.05x base input (pricing-page footnote 2), a genuine per-model difference from the standard 0.1x and from claude-fable-5-1's 0.025x. fast_multiplier 2.0 (fast mode $8/$40 per MTok on the pricing page). Claude Code's CHANGELOG entry for 2.1.280 states Opus 5.5 became the default model (see sources); rows whose raw model ID is claude-opus-5-5 would be unpriced without this entry. Claude Sonnet 5.5 and Claude Haiku 5.5 are announced to follow 'in the coming weeks' -- add them as separate entries when their model IDs and prices are published, never as aliases of the 5.x entries."
|
|
14
15
|
],
|
|
15
16
|
"sources": [
|
|
16
17
|
{
|
|
@@ -60,6 +61,26 @@
|
|
|
60
61
|
"url": "https://platform.claude.com/docs/en/build-with-claude/prompt-caching",
|
|
61
62
|
"retrieved_at": "2026-09-09",
|
|
62
63
|
"note": "cache write TTL multipliers (5m = 1.25x, 1h = 2x), cross-checked against the pricing page cache columns"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"url": "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
67
|
+
"retrieved_at": "2026-09-23",
|
|
68
|
+
"note": "used for claude-opus-5-5 (Opus 5.5 row: $4 / $5 / $8 / $0.20 / $20, footnote 2 cache_read 0.05x, fast mode $8/$40); fetched via WebFetch, no local snapshot"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"url": "https://www.anthropic.com/claude-opus-5-5",
|
|
72
|
+
"retrieved_at": "2026-09-23",
|
|
73
|
+
"note": "Opus 5.5 announcement: public launch date September 22, 2026, model ID claude-opus-5-5, Sonnet 5.5 / Haiku 5.5 to follow"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"url": "https://www.anthropic.com/news/claude-opus-5",
|
|
77
|
+
"retrieved_at": "2026-09-23",
|
|
78
|
+
"note": "Opus 5 announcement dated Jul 24, 2026; used to replace the claude-opus-5 effective_from placeholder"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"url": "https://github.com/anthropics/claude-code/blob/main/CHANGELOG.md",
|
|
82
|
+
"retrieved_at": "2026-09-23",
|
|
83
|
+
"note": "Claude Code 2.1.280 entry: Claude Opus 5.5 became the default model (1M context, $4/$20 per MTok, $0.20/MTok cache reads); the reason claude-opus-5-5 rows are expected in transcripts from that version"
|
|
63
84
|
}
|
|
64
85
|
],
|
|
65
86
|
"models": [
|
|
@@ -137,8 +158,8 @@
|
|
|
137
158
|
"fast_multiplier": "2.0",
|
|
138
159
|
"rates": [
|
|
139
160
|
{
|
|
140
|
-
"rate_id": "claude-opus-5-launch-
|
|
141
|
-
"effective_from": "2026-07-
|
|
161
|
+
"rate_id": "claude-opus-5-launch-2026-07-24",
|
|
162
|
+
"effective_from": "2026-07-24T00:00:00+00:00",
|
|
142
163
|
"effective_until": null,
|
|
143
164
|
"input_nocache": "5.0",
|
|
144
165
|
"cache_read": "0.50",
|
|
@@ -148,6 +169,23 @@
|
|
|
148
169
|
}
|
|
149
170
|
]
|
|
150
171
|
},
|
|
172
|
+
{
|
|
173
|
+
"model_key": "claude-opus-5-5",
|
|
174
|
+
"aliases": [],
|
|
175
|
+
"fast_multiplier": "2.0",
|
|
176
|
+
"rates": [
|
|
177
|
+
{
|
|
178
|
+
"rate_id": "claude-opus-5-5-launch-2026-09-22",
|
|
179
|
+
"effective_from": "2026-09-22T00:00:00+00:00",
|
|
180
|
+
"effective_until": null,
|
|
181
|
+
"input_nocache": "4.0",
|
|
182
|
+
"cache_read": "0.20",
|
|
183
|
+
"cache_write_5m": "5.0",
|
|
184
|
+
"cache_write_1h": "8.0",
|
|
185
|
+
"output": "20.0"
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
},
|
|
151
189
|
{
|
|
152
190
|
"model_key": "claude-opus-4-7",
|
|
153
191
|
"aliases": [],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coding-agent-cost
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Estimate AI coding agent (Claude Code / Codex CLI) token usage and cost from local logs
|
|
5
5
|
Author: shiki-yusuke
|
|
6
6
|
License: MIT
|
|
@@ -266,8 +266,7 @@ network, never calls `gh`, and never resolves branches or PRs.
|
|
|
266
266
|
in the report's `data_quality` block instead of being silently dropped or
|
|
267
267
|
clamped to zero.
|
|
268
268
|
- **Known catalog gaps**, tracked in `agent_cost/rates.json`'s `notes`:
|
|
269
|
-
`
|
|
270
|
-
source, so its rate period's `effective_from` is a placeholder. `gpt-5.6`
|
|
269
|
+
`gpt-5.6`
|
|
271
270
|
(Sol/Terra/Luna) credits could not be confirmed from the primary source
|
|
272
271
|
(`help.openai.com`'s Codex rate card returns HTTP 403 to automated
|
|
273
272
|
fetches); the values in the catalog come from several independent
|
|
@@ -342,7 +341,7 @@ agent-cost measure --session-id <id> [--session-id <id> ...] \
|
|
|
342
341
|
```json
|
|
343
342
|
{
|
|
344
343
|
"protocol_version": "measure/v1",
|
|
345
|
-
"producer_version": "0.2.
|
|
344
|
+
"producer_version": "0.2.1",
|
|
346
345
|
"accounting_basis": "agent-cost-raw-total/v2",
|
|
347
346
|
"generated_at": "...",
|
|
348
347
|
"window": { "since": "...", "until": null },
|
|
@@ -24,6 +24,7 @@ tests/test_e0a_fable_5_1_and_sonnet_5_correction.py
|
|
|
24
24
|
tests/test_e0a_review3_hardening.py
|
|
25
25
|
tests/test_facts.py
|
|
26
26
|
tests/test_measure_v1_contract.py
|
|
27
|
+
tests/test_opus_5_5_rates.py
|
|
27
28
|
tests/test_rates.py
|
|
28
29
|
tests/test_reader_claude.py
|
|
29
30
|
tests/test_reader_codex.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "coding-agent-cost"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "Estimate AI coding agent (Claude Code / Codex CLI) token usage and cost from local logs"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -45,7 +45,7 @@ def test_standard_fast_and_unknown_mode_prices(kind, usd, credits, mode, multipl
|
|
|
45
45
|
|
|
46
46
|
def test_catalog_observation_boundary_is_not_backdated():
|
|
47
47
|
catalog = load_rates()
|
|
48
|
-
assert catalog.catalog_version == "2026-09-
|
|
48
|
+
assert catalog.catalog_version == "2026-09-23"
|
|
49
49
|
entry = catalog.models["gpt-6-astra"]
|
|
50
50
|
assert entry.aliases == ()
|
|
51
51
|
assert entry.rates[0].effective_from == CUTOFF
|
|
@@ -149,7 +149,7 @@ def test_measure_reads_isolated_synthetic_astra_with_existing_contract(tmp_path,
|
|
|
149
149
|
assert cli.main(["measure", "--session-id", "synthetic-astra", "--agent", "codex"]) == 0
|
|
150
150
|
report = json.loads(capsys.readouterr().out)
|
|
151
151
|
assert report["protocol_version"] == "measure/v1"
|
|
152
|
-
assert report["rates"]["catalog_version"] == "2026-09-
|
|
152
|
+
assert report["rates"]["catalog_version"] == "2026-09-23"
|
|
153
153
|
assert len(report["rates"]["sha256"]) == 64
|
|
154
154
|
assert report["sessions"]["synthetic-astra"]["totals"]["estimated_cost_usd"] == 122
|
|
155
155
|
assert report["total"]["totals"]["credits"] == 3050
|
|
@@ -19,7 +19,7 @@ architect レビュー (3 巡目) と builder レビューで、既存テスト
|
|
|
19
19
|
かつ確定金額が計上されない。境界ちょうどは priced になる。
|
|
20
20
|
|
|
21
21
|
条件D (PR レビュー3点目・追加分): catalog は
|
|
22
|
-
catalog_version == "2026-09-
|
|
22
|
+
catalog_version == "2026-09-23"(rates.json の現行値)であり、sources の中に url
|
|
23
23
|
"https://platform.claude.com/docs/en/about-claude/pricing" の
|
|
24
24
|
entry があって、その note に
|
|
25
25
|
"sha256=d79ad28567196bd55dd50e2fd89341b9da9774a45c1d02fcf387078507fd15e0"
|
|
@@ -224,7 +224,7 @@ def test_condition_c_claude_fable_5_1_at_effective_from_boundary_is_priced_contr
|
|
|
224
224
|
|
|
225
225
|
|
|
226
226
|
def test_condition_d_catalog_version_and_pricing_source_sha256_note():
|
|
227
|
-
"""条件D: catalog_version == "2026-09-
|
|
227
|
+
"""条件D: catalog_version == "2026-09-23"(rates.json の現行値)であり、sources に url
|
|
228
228
|
"https://platform.claude.com/docs/en/about-claude/pricing" の entry が
|
|
229
229
|
あって、その note に指定の sha256 文字列を含むこと。
|
|
230
230
|
|
|
@@ -233,7 +233,7 @@ def test_condition_d_catalog_version_and_pricing_source_sha256_note():
|
|
|
233
233
|
ダイジェストを貼り付けてしまう。
|
|
234
234
|
"""
|
|
235
235
|
catalog = load_rates()
|
|
236
|
-
assert catalog.catalog_version == "2026-09-
|
|
236
|
+
assert catalog.catalog_version == "2026-09-23"
|
|
237
237
|
|
|
238
238
|
matches = [
|
|
239
239
|
s
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Acceptance tests for the claude-opus-5-5 rate entry and the claude-opus-5
|
|
2
|
+
effective_from correction (catalog_version 2026-09-23).
|
|
3
|
+
|
|
4
|
+
Primary sources: platform.claude.com/docs/en/about-claude/pricing (Opus 5.5
|
|
5
|
+
row + footnote 2), anthropic.com/claude-opus-5-5 (launch 2026-09-22),
|
|
6
|
+
anthropic.com/news/claude-opus-5 (launch 2026-07-24).
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
from decimal import Decimal
|
|
11
|
+
|
|
12
|
+
from agent_cost.rates import load_rates
|
|
13
|
+
|
|
14
|
+
UTC = timezone.utc
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def dt(s):
|
|
18
|
+
return datetime.fromisoformat(s).replace(tzinfo=UTC)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_claude_opus_5_5_resolves_with_pricing_page_values_on_or_after_launch():
|
|
22
|
+
catalog = load_rates()
|
|
23
|
+
for occurred_at in ("2026-09-22T00:00:00+00:00", "2026-12-01T00:00:00+00:00"):
|
|
24
|
+
resolved, period = catalog.rate_for("claude-opus-5-5", dt(occurred_at))
|
|
25
|
+
assert resolved == "claude-opus-5-5"
|
|
26
|
+
assert period is not None
|
|
27
|
+
assert period.rate_id == "claude-opus-5-5-launch-2026-09-22"
|
|
28
|
+
assert period.values["input_nocache"] == Decimal("4.0")
|
|
29
|
+
assert period.values["cache_read"] == Decimal("0.20")
|
|
30
|
+
assert period.values["cache_write_5m"] == Decimal("5.0")
|
|
31
|
+
assert period.values["cache_write_1h"] == Decimal("8.0")
|
|
32
|
+
assert period.values["output"] == Decimal("20.0")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_claude_opus_5_5_is_unpriced_before_launch_date():
|
|
36
|
+
catalog = load_rates()
|
|
37
|
+
resolved, before = catalog.rate_for("claude-opus-5-5", dt("2026-09-21T23:59:59+00:00"))
|
|
38
|
+
assert resolved == "claude-opus-5-5"
|
|
39
|
+
assert before is None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_claude_opus_5_5_cache_read_is_0_05x_base_input_not_standard_0_1x():
|
|
43
|
+
# Footnote 2 on the pricing page: Opus 5.5 cache hits are 0.05x base input.
|
|
44
|
+
catalog = load_rates()
|
|
45
|
+
_, period = catalog.rate_for("claude-opus-5-5", dt("2026-10-01T00:00:00+00:00"))
|
|
46
|
+
assert period.values["cache_read"] == period.values["input_nocache"] * Decimal("0.05")
|
|
47
|
+
assert period.values["cache_read"] != period.values["input_nocache"] * Decimal("0.1")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_claude_opus_5_5_fast_multiplier_2x():
|
|
51
|
+
catalog = load_rates()
|
|
52
|
+
assert catalog.models["claude-opus-5-5"].fast_multiplier == Decimal("2.0")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_claude_opus_5_5_is_not_an_alias_of_claude_opus_5():
|
|
56
|
+
catalog = load_rates()
|
|
57
|
+
assert "claude-opus-5-5" not in catalog.models["claude-opus-5"].aliases
|
|
58
|
+
assert catalog.models["claude-opus-5-5"].aliases == ()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_claude_opus_5_effective_from_is_the_official_launch_date():
|
|
62
|
+
catalog = load_rates()
|
|
63
|
+
resolved, before = catalog.rate_for("claude-opus-5", dt("2026-07-23T23:59:59+00:00"))
|
|
64
|
+
assert resolved == "claude-opus-5"
|
|
65
|
+
assert before is None
|
|
66
|
+
_, on_launch = catalog.rate_for("claude-opus-5", dt("2026-07-24T00:00:00+00:00"))
|
|
67
|
+
assert on_launch is not None
|
|
68
|
+
assert on_launch.rate_id == "claude-opus-5-launch-2026-07-24"
|
|
69
|
+
assert on_launch.values["input_nocache"] == Decimal("5.0")
|
|
70
|
+
assert on_launch.values["cache_read"] == Decimal("0.50")
|
|
71
|
+
assert on_launch.values["cache_write_5m"] == Decimal("6.25")
|
|
72
|
+
assert on_launch.values["cache_write_1h"] == Decimal("10.0")
|
|
73
|
+
assert on_launch.values["output"] == Decimal("25.0")
|
|
74
|
+
assert on_launch.effective_until is None
|
|
@@ -88,7 +88,7 @@ def test_claude_opus_5_is_priced_with_fast_multiplier_2x():
|
|
|
88
88
|
catalog = load_rates()
|
|
89
89
|
entry = catalog.models["claude-opus-5"]
|
|
90
90
|
assert entry.fast_multiplier == Decimal("2.0")
|
|
91
|
-
_, period = catalog.rate_for("claude-opus-5", dt("2026-
|
|
91
|
+
_, period = catalog.rate_for("claude-opus-5", dt("2026-08-01T00:00:00+00:00"))
|
|
92
92
|
assert period.values["input_nocache"] == Decimal("5.0")
|
|
93
93
|
assert period.values["output"] == Decimal("25.0")
|
|
94
94
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""Spec: pyproject.toml's [project].version and agent_cost.__version__ must
|
|
2
|
-
agree, and both must read "0.2.
|
|
2
|
+
agree, and both must read "0.2.1" for this change (the Opus 5.5 catalog release bumps the package
|
|
3
3
|
version alongside the measure/v1 data_quality additions). A broken
|
|
4
4
|
implementation would bump one file but not the other, or forget the bump
|
|
5
5
|
entirely.
|
|
@@ -29,5 +29,5 @@ def test_pyproject_version_matches_package_version():
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def test_version_is_0_2_0():
|
|
32
|
-
assert agent_cost.__version__ == "0.2.
|
|
33
|
-
assert _pyproject_version() == "0.2.
|
|
32
|
+
assert agent_cost.__version__ == "0.2.1"
|
|
33
|
+
assert _pyproject_version() == "0.2.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/coding_agent_cost.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/coding_agent_cost.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{coding_agent_cost-0.2.0 → coding_agent_cost-0.2.1}/coding_agent_cost.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|