Repository navigation
fix(pricing): price gpt-6.1-sol codex usage rows - #351
Merged
Merged
Conversation
Codex was writing gpt-6.1-sol rows and nothing priced them: the builtin
table stopped at gpt-5.5, and the local LiteLLM snapshot predated the
model, so 11 stored rows imported cost-unknown and stayed that way
because a scan only reprices what a catalog row now covers.
The builtin table now carries the model's published rates on both routes
a codex row can report — the client's own ("codex", ...) key and
OpenAI's — at list price: $2/1M in, $10/1M out, $0.10/1M cache read,
$2.50/1M cache write. No multiplier: the 2.5x ccusage fast-pricing
convention stays scoped to gpt-5.5, so the codex and openai routes price
identically instead of one of them silently carrying a convention.
Coverage stays per model. A sibling sol id no row carries (for example
gpt-6.1-sol-pro) remains cost-unknown rather than borrowing this row.
Verified on a copy of a live ledger with no pricing snapshot at all
(builtin table only, no network): 11/11 gpt-6.1-sol rows repriced to
cost_confidence estimated_from_tokens, cost_basis pricing_table,
pricing_source agent_sentinel_builtin, $6.528786 total — the same
dollars a fresh import produces, and the stored rows are the only thing
written. The snapshot path is unchanged: when a snapshot does carry the
model, the builtin row still answers for its exact codex key.
mikehasa
added a commit
that referenced
this pull request
Sep 30, 2026
Version bump only (pyproject.toml + CHANGELOG.md). This release carries the gpt-6.1-sol pricing fix (#351) merged just before it. DMG preflight (§3a): src/agentacct/cost.py changed since v0.12.8 and the DMG embeds the frozen Python CLI, so the payload changed even though no Swift file did. Decision: REBUILD (§3c) from this release's own squash commit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Codex is reporting gpt-6.1-sol, and nothing in agentacct priced it. The live ledger showed it plainly:
Two rows of the price stack both missed it:
gpt-5.5(gpt-5.6* was deliberately left to the snapshot, which is whycodex/gpt-5.6-solhas rows too — those stay excluded for a different reason: codex reported no input/output split for them);codex -> openaiprovider alias had nothing to resolve to.Stored rows do not heal on their own: a scan only reprices what a catalog row now covers, so the 11 rows would have stayed
cost_confidence: unknownuntil a snapshot refresh happened to pick the model up.Change
The builtin table now carries gpt-6.1-sol at its published rates, on both routes a codex row can report — the client's own
("codex", ...)key and OpenAI's("openai", ...)key:Source: LiteLLM's
model_prices_and_context_window.json(gpt-6.1-sol,litellm_provider: openai), the same upstream table the snapshot is built from.gpt-5.5, so the codex and openai routes price identically rather than one silently carrying a convention. Cost basis ispricing_table/estimated_from_tokens, never provider-billed.gpt-5.5. Exact-key lookup answers for the codex route instead of depending on the snapshot's TTL refresh to alias it onto OpenAI's row; if a snapshot does carry the model, the builtin row still answers for its exact codex key and the dollars agree.gpt-6.1-sol-pro) stays cost-unknown rather than borrowing this row's price.Tests
tests/test_pricing_catalog.py(+2): both routes resolve to the builtin row with the published rates, no multiplier, cache read/write columns priced throughestimate_model_cost_breakdown_usd; sibling/uncovered ids stay unpriced; and a snapshot that does carry the model leaves the price and provenance unchanged.tests/test_stored_usage_repricing.py(+1): the stored-row reprice path prices a codex gpt-6.1-sol row from the builtin table with no snapshot at all, and produces the exact row a fresh import does (dollars +pricing_sourceprovenance), leaving the stored row untouched while planning.pytest -q tests/test_pricing_catalog.py tests/test_stored_usage_repricing.py→ 53 passed.pytest -q→ 4894 passed, 7 failed. All 7 are intests/test_onboard_global.pyand are pre-existing and unrelated — they fail identically on unmodifiedorigin/main(an environment string drift: the test asserts the word "yourself" appears in onboarding copy this machine does not produce).Verification against a real ledger
Run on a copy of a real store, with the pricing snapshot deleted so nothing but the builtin table is in play, and auto-refresh pinned off (no network):
→ 11/11 gpt-6.1-sol rows priced,
cost_confidence: estimated_from_tokens,cost_basis: pricing_table,pricing_source: agent_sentinel_builtin, $6.528786 total. The copied store's 11 stored rows are the only thing written; the live store was never touched. Spot-checked one row by hand: 5,859 in × $2/1M + 400 out × $10/1M + 125,440 cache read × $0.10/1M = $0.028262, matching the stored value exactly.Docs / safety
CHANGELOG.mdunder Unreleased → Fixed.