Repository navigation
chore(deps): every uv package but harbor, with litellm v1.103.2 prices - #36
Merged
Merged
Conversation
…m v1.103.2 prices `uv lock --upgrade` past the 7-day cooldown, with cyclopts held at 4.25.3 for its own commit and harbor still at 0.23.0. Moves boto3 1.43.106, pytz 2026.4, commitizen 4.19.0, litellm 1.103.2, hypothesis 6.168.3, ruff 0.16.9, ty 0.0.84, duckdb 1.5.6, lefthook 2.1.15 and pyjwt 2.15.1 (Dependabot alert #1), plus their transitives. Supersedes Dependabot #33 and #35. litellm 1.103.0 changed its cost arithmetic: a cache-creation or cache-read rate the price map leaves out resolves to the input rate instead of $0, and a missing 1h write rate to the cache-creation rate (BerriAI/litellm 22b377fe2aad, 8573241c4981, 88d1eb3b35b4). That, not the data, is what turned #33 red, so the vendored table is regenerated with `scripts/update_prices.py --ref v1.103.2` and `domain/pricing.py` ports the rule; an entry carrying off_peak_pricing is declined rather than priced by wall-clock time. The codex synthetic golden is re-frozen by `ATIF_FREEZE_GOLDENS=1` because harbor prices its 900 cache-write tokens at gpt-5.1-codex's input rate under litellm 1.103.2: only `total_cost_usd` and one step's `cost_usd` move. The eight gpt-5.1-codex / gpt-5.5 frozen prices in test_pricing_policy.py are re-captured from litellm 1.103.2 for the same reason. CONVERTER_SCHEMA_VERSION 5 -> 6: total_cost_usd and metrics.cost_usd change for sessions with cache tokens on a model without cache rates, so the corpus re-converts on the next materialize. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cyclopts 5 is a major: the 5.0.0 notes list dropped fuzzy command matching, child-wins fallthrough parsing, greedy *args subcommands, user parameters shadowing --help/--version, and parse errors exiting 2 instead of 1. atif-sql has no meta app, no *args command and no help/version parameter, so only the exit code reaches it, and 2 is a wire code in EXIT_CODES (empty_session, no_embeddings): an agent would read a typo as an empty session. main() runs the app with exit_on_error=False and maps cyclopts' parse error to invalid_input (64) after cyclopts prints its panel. The new test fails with the mapping removed (3 red) and passes with it. Both floors (root and atif-cli) rise to >=5.1.1 so test_distribution's union holds. Supersedes Dependabot #34. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
laithalsaadoon
marked this pull request as ready for review
October 8, 2026 18:01
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.
Bring every uv dependency but harbor up to date, with litellm v1.103.2 prices
Branch
factory/1-uv-deps, two commits onorigin/main239e9e2:d3b2c4a chore(deps): upgrade every uv package but harbor and cyclopts, litellm v1.103.2 pricesf896ef8 chore(deps): take cyclopts 5.1.1, a usage error exits 64Supersedes Dependabot #33, #34 and #35, and closes Dependabot alert #1 (PyJWT, 2.14.0 -> 2.15.1). harbor stays at 0.23.0.
Why #33 was red: litellm's cost logic, not its data
litellm 1.103.0 changed
_get_token_base_cost: a cache-creation or cache-read rate the price map leaves out resolves to the input rate instead of $0, and a missing 1h cache-write rate resolves to the cache-creation rate (BerriAI/litellm22b377fe2aad"price cache writes without a creation rate",8573241c4981"resolve a missing 1h cache write rate after off-peak pricing",88d1eb3b35b4"bill cache-read tokens at the input rate when the map has no cache-read rate"). After regenerating the table,test_every_vendored_key_prices_identicallyand the five gpt-5.1-codex grid cells were still red, so the rule is ported intodomain/pricing.py(_base_rateskeeps cache ratesNonethrough the tier and threshold lookups, then resolves them). The port is sound to replicate: it is threeNonedefaults and one fallback, and the identity grid now passes bit for bit over every shared key, shape and tier. An entry carryingoff_peak_pricingis declined (litellm would price it by wall-clock time); no vendored entry carries one today. litellm was not held on 1.102.x.Who pays more after this: any session with cache-write tokens on a model with no
cache_creation_input_token_cost(107 of 258 bare keys, every OpenAI text model, plusanthropic.claude-instant-v1,anthropic.claude-v1,anthropic.claude-v2:1), and cache-read tokens on the 46 keys with nocache_read_input_token_cost(the*-pro, audio, gpt-3.5/gpt-4 and gpt-oss entries, and the three old Bedrock Claude ids). Every other Claude entry carries both cache rates and does not move (anthropic.claude-mythos-previewlacks them but prices input at 0, so it stays $0). Example: the codex synthetic golden goes fromtotal_cost_usd0.00198 to 0.003105 because harbor (through litellm 1.103.2) now bills its 900 cache-write tokens at gpt-5.1-codex's input rate.CONVERTER_SCHEMA_VERSION5 -> 6 (AGENTS.md rule: a litellm bump that can alter an artifact byte needs the decision by hand;total_cost_usdandmetrics.cost_usdmove), with the digest intest_converter_schema_version.pyre-pinned. The next materialize re-converts the whole corpus.Packages moved (uv.lock)
harbor 0.23.0 is unchanged.
pyproject.tomlandpackages/atif-cli/pyproject.tomlraisecyclopts>=4.10.2tocyclopts>=5.1.1.Held by cooldown (newer than the 7-day
exclude-newer, upload time on PyPI)<0.40inpyproject.tomlVendored price table: v1.102.0 -> v1.103.2
Regenerated with
uv run scripts/update_prices.py --ref v1.103.2, never by hand. 257 -> 259 entries: addedgpt-5.5-cyberandgpt-rosalind-research, none removed. 24 entries changed a rate field; the rest of the diff is metadata (sourceon 108 Bedrock entries,supports_tool_search,supports_thinking_cache_preservation,deprecation_date,max_input_tokensfor claude-sonnet-4-5 200000 -> 1000000). The converter reads no*_batcheskey, so of the rate changes only the flex rows can move a cost, and only for aflexservice tier. Every rate change, per token:gpt-3.5-turbo-0125input_cost_per_token_batchesgpt-3.5-turbo-0125output_cost_per_token_batchesgpt-3.5-turbo-1106input_cost_per_token_batchesgpt-3.5-turbo-1106output_cost_per_token_batchesgpt-4-0613input_cost_per_token_batchesgpt-4-0613output_cost_per_token_batchesgpt-4-turbo-2024-04-09input_cost_per_token_batchesgpt-4-turbo-2024-04-09output_cost_per_token_batchesgpt-5input_cost_per_token_batchesgpt-5output_cost_per_token_batchesgpt-5-2025-08-07input_cost_per_token_batchesgpt-5-2025-08-07output_cost_per_token_batchesgpt-5-miniinput_cost_per_token_batchesgpt-5-minioutput_cost_per_token_batchesgpt-5-mini-2025-08-07input_cost_per_token_batchesgpt-5-mini-2025-08-07output_cost_per_token_batchesgpt-5-nanoinput_cost_per_token_batchesgpt-5-nanooutput_cost_per_token_batchesgpt-5-nano-2025-08-07input_cost_per_token_batchesgpt-5-nano-2025-08-07output_cost_per_token_batchesgpt-5.1cache_read_input_token_cost_flexgpt-5.1input_cost_per_token_batchesgpt-5.1input_cost_per_token_flexgpt-5.1output_cost_per_token_batchesgpt-5.1output_cost_per_token_flexgpt-5.1-2025-11-13cache_read_input_token_cost_flexgpt-5.1-2025-11-13input_cost_per_token_batchesgpt-5.1-2025-11-13input_cost_per_token_flexgpt-5.1-2025-11-13output_cost_per_token_batchesgpt-5.1-2025-11-13output_cost_per_token_flexgpt-5.2cache_read_input_token_cost_flexgpt-5.2input_cost_per_token_batchesgpt-5.2input_cost_per_token_flexgpt-5.2output_cost_per_token_batchesgpt-5.2output_cost_per_token_flexgpt-5.2-2025-12-11cache_read_input_token_cost_flexgpt-5.2-2025-12-11input_cost_per_token_batchesgpt-5.2-2025-12-11input_cost_per_token_flexgpt-5.2-2025-12-11output_cost_per_token_batchesgpt-5.2-2025-12-11output_cost_per_token_flexgpt-5.2-proinput_cost_per_token_batchesgpt-5.2-prooutput_cost_per_token_batchesgpt-5.2-pro-2025-12-11input_cost_per_token_batchesgpt-5.2-pro-2025-12-11output_cost_per_token_batcheso1input_cost_per_token_batcheso1output_cost_per_token_batcheso1-2024-12-17input_cost_per_token_batcheso1-2024-12-17output_cost_per_token_batcheso3input_cost_per_token_batcheso3output_cost_per_token_batcheso3-2025-04-16input_cost_per_token_batcheso3-2025-04-16output_cost_per_token_batcheso3-miniinput_cost_per_token_batcheso3-minioutput_cost_per_token_batcheso3-mini-2025-01-31input_cost_per_token_batcheso3-mini-2025-01-31output_cost_per_token_batcheso4-minicache_read_input_token_cost_flexo4-miniinput_cost_per_token_batcheso4-minioutput_cost_per_token_batcheso4-mini-2025-04-16cache_read_input_token_cost_flexo4-mini-2025-04-16input_cost_per_token_batcheso4-mini-2025-04-16output_cost_per_token_batchescyclopts 5
Read the 5.0.0, 5.1.0 and 5.1.1 release notes (GitHub releases of BrianPugh/cyclopts, 2026-10-08). atif-sql has no meta app, no
*argssubcommand and no parameter namedhelporversion, so fuzzy-match removal, child-wins fallthrough, greedy*argsand flag shadowing do not reach it. One change does: parse errors exit 2 instead of 1, and 2 is a wire code inEXIT_CODES(empty_session,no_embeddings).main()runsapp(sys.argv[1:], exit_on_error=False)and mapscyclopts.CycloptsErrortoEXIT_CODES["invalid_input"](64) after cyclopts prints its panel.TestUsageErrorExitCodecovers--bogus,convert --bogusandsearch q -k many; with the mapping removed it fails 3 of 3.docs/reference/cli.mdanderrors.pysay so. Help pages gain cyclopts 5 metavars (--format CHOICE); no committed doc holds help output.Goldens
ATIF_FREEZE_GOLDENS=1 uv run pytest packages/atif-converter/tests/test_harbor_oracle.py -k freezerewrote onlycodex.synthetic.trajectory.json, and only$.final_metrics.total_cost_usd(0.00198 -> 0.003105) and$.steps[2].metrics.cost_usd(0.000525 -> 0.00165).claude_code.syntheticdid not change. The eight gpt-5.1-codex and gpt-5.5 rows ofFROZEN_PRICESintest_pricing_policy.pyare re-captured from litellm 1.103.2 for the same reason.Gates (2026-10-08, in a fresh clone)
mise run checkon commit 1: 2351 passed, 1 skipped in 256.77 s; ruff, ty, pyright (0 errors), import-linter, actionlint, lefthook validate, vex check all green.mise run checkon commit 2 (head): 2354 passed, 1 skipped in 242.68 s, all legs green.test_pricing_identity,test_harbor_oracle,test_parity_codex,test_codex_conversion_port) pass inside both runs.mise run lock:check:uv lock --checkresolved 137 packages, clean.mise run security:vex:check:osv-scanner.toml matches security/atif-sql.openvex.json; the ledger has no statements, so it needed no edit.mise run docs:install && mise run docs:gate: 0 errors, 0 warnings; vitest 64 passed.Risks
total_cost_usd. This follows litellm, which harbor uses, so parity holds; whether OpenAI actually bills cache writes at the input rate is litellm's claim, not ours.scripts/atif-sql-refresh.shbranches only on 0 and 78.What to look at
packages/atif-converter/src/atif_converter/domain/pricing.py_base_ratesand_tiered_ratesagainst litellm v1.103.2litellm/litellm_core_utils/llm_cost_calc/utils.py_get_token_base_cost.packages/atif-cli/src/atif_cli/app.pymain.Lead review (2026-10-08)
Re-ran on
f896ef8in a fresh worktree:mise run check2354 passed, 1 skipped (pyright 0 errors),lock:checkclean at 137 packages, and test_pricing_identity, test_harbor_oracle, test_parity_codex and test_codex_conversion_port 243 passed, 1 skipped. harbor is 0.23.0 inuv.lock. The three cited litellm commits exist and are inside v1.103.0 (compare v1.103.0...88d1eb3b35b4isbehind).🤖 Generated with Claude Code