Releases: Rodiun/frugon
Release list
v0.2.4
frugon v0.2.4
A hardening release: sturdier log ingest, a safer capture proxy, and a tighter supply chain. No behaviour change for well-formed logs — every number renders exactly as before.
Hardened
- Compressed logs can't blow up your machine.
.gzfiles are now decompressed as a stream with a 512MB ceiling (override withFRUGON_MAX_GZIP_BYTES), and a truncated or mislabeled.gzgets a clean one-line error instead of a raw traceback. - Malformed log lines can't take down a run. A JSONL line that parses as a bare array, string, or number — valid JSON, but not a record — used to crash
analyzeoutright. It's now counted into the same "malformed records skipped" total you already see, and the run carries on. - Report writes are atomic and symlink-safe. Every report file is written to a temp file and swapped into place, so a crash mid-write can't leave a half-written report, and a symlinked output path can no longer overwrite the symlink's target.
capturetreats your log like the credential it is. The capture file is created private (0o600) on macOS/Linux, and the startup panel now carries an explicit caution on every platform: it contains your full prompts and completions.- The capture proxy fails loud, not silent. Streaming requests get a clear 400 explaining capture doesn't support them yet (instead of silently breaking the stream); requests to unsupported paths log a one-time warning naming the path and what is supported (instead of a bare 404); and a
kill/systemd stop now shuts the proxy down cleanly through its normal cleanup path. - Deterministic sampling dedup.
--measure's prompt dedup key now uses sha256 instead of Python's process-saltedhash(), so the same logs dedup identically across runs and machines.
Supply chain
- litellm is pinned below 2.0 in the
measureextra, so a future major release can't silently break--measureinstalls. - Every CI workflow now runs with least-privilege permissions, enforced by a test that checks every workflow file — including ones added later.
Install / upgrade
uvx frugon@latest # or: uv tool upgrade frugon / pipx upgrade frugon / pip install -U frugonFull Changelog: v0.2.3...v0.2.4
v0.2.3
frugon v0.2.3
A timed comparison checkpoint, an upfront disclosure for the demo's --measure try-out, and a routing fix for Mistral's newest model.
Improved
- The "Compared" checkpoint now shows its own elapsed time, and the live progress bar names the comparison stage while it runs. Ranking a couple dozen candidates against the baseline is real work — you'd see
✓ Compared 23 candidatessit there with no indication of how long it took or that anything was happening. It now reads✓ Compared 23 candidates in 0.9s, and the bar itself switches from "Pricing" to "Comparing 23 candidates…" the moment pricing finishes, so the trail never goes quiet. frugon analyze --demo --measurenow tells you upfront why it only needs an OpenAI key. The demo's recommendation is computed against the full model roster, same as a real run — but its--measuretry-out samples a single pinned model so anyone can run it with justOPENAI_API_KEY, no multi-provider key hunt. That's now disclosed at the point it happens, not just in the fine print afterward, and the--measure --helptext and README say the same thing.
Fixed
mistral-large-3(and the whole baremistral-*family) now routes correctly for--measure. LiteLLM doesn't infer a provider from a bare Mistral model name the way it does for OpenAI or Anthropic — a--measurerun againstmistral-large-3was failing with a generic "bad request" instead of actually sampling the model. It now routes throughmistral/automatically.
Install / upgrade
uvx frugon@latest # or: uv tool upgrade frugon / pipx upgrade frugon / pip install -U frugonFull Changelog: v0.2.2...v0.2.3
v0.2.2
frugon v0.2.2
A dramatically faster analysis pass, a cleaner "Candidates considered" legend, and a fixed demo image on PyPI.
Fixed
- Analysis is dramatically faster — two hot-loop costs fixed. First, pricing a large log was checking the pricing file on disk once per record — tens of thousands of redundant filesystem checks per run. It now checks once per run; this was the largest single cost, and it speeds up every analysis (single-model,
--wholesale, and--candidatesruns alike). Second, the "Candidates considered" block introduced in v0.2.1 was re-running the easy/hard call classification once per candidate — up to 23 times over the same call set — even though that classification never depends on the candidate; it now runs once and every candidate's projection is derived from it. Together, on the bundled ~56,100-call demo, the analysis pass dropped from roughly 17 seconds to about 1 second, and the pause after "Priced" is gone. The figures are unchanged to the cent. - The demo image now renders on PyPI. The README's demo GIF used a relative path that GitHub resolves but PyPI's project-page renderer does not, so the animated demo never showed up on
pypi.org/project/frugon. It now points at the raw GitHub URL, so it renders on both.
Improved
- A clearer "Candidates considered" legend on a default (no
--candidates) run. The pool size and how many rows are shown now sit right in the header — "23 in pool · top 5 shown" — instead of a trailing sentence you'd read after the table. The two paragraphs of prose below the table are now three short bullet points: what each row represents, how the recommendation is picked, and how to compare specific models or measure quality yourself. An explicit--candidatesrun is unchanged.
Install / upgrade
uvx frugon@latest # or: uv tool upgrade frugon / pipx upgrade frugon / pip install -U frugonFull Changelog: v0.2.1...v0.2.2
v0.2.1
frugon v0.2.1
A much bigger recommendation roster, better quality coverage for reasoning models, a demo that runs on the exact same roster a real analysis uses, and freshly synced data tables.
Added
- A 23-model recommendation roster across 11 vendors. The default candidate pool grew from 10 to 23 current top models spanning OpenAI, Anthropic, Google, DeepSeek, Moonshot, xAI, Mistral, Z.ai, MiniMax, Alibaba, and Meta (open-source Llama) — every one both priced and quality-rated — so recommendations on your real logs draw from a much wider, more current field. The two open-source Llama 4 checkpoints, which have no single first-party price, are priced via Groq as a labeled reference host rather than an invented number.
- See what else was considered. A default (no
--candidates) run now shows a "Candidates considered" block alongside the headline recommendation — the recommended model plus the next four cheapest candidates that also beat your current spend, each one with its own projected monthly cost, saving%, and quality tier. Previously this transparency only appeared when you passed--candidatesyourself; now it's there by default, on the demo too, with a line telling you how many models were in the full pool and how to compare specific ones with--candidates. When two or more candidates save the same amount to the decimal place shown, the recommendation goes to whichever has the higher quality tier — the Quality tier column makes that call visible, not just asserted.
Improved
- Better quality coverage for reasoning models. frugon now recognises that LMArena often rates a reasoning model under an effort-tagged or dated name (
gpt-5-high,grok-4-0709) while your logs carry the bare name (gpt-5,grok-4) — and honestly attributes the rating to the base model, since reasoning effort changes how many tokens a call spends thinking, not the per-token rate. More of the models in your logs come back rated instead of unrated. Pricing is never folded this way — a thinking variant keeps its own price. - The demo is no longer special-cased.
frugon analyze --demoused to route against a small, fixed illustrative candidate set — a stand-in that could drift from what the tool actually recommends on your own logs. It now uses the SAME default 23-model roster a real run does, so the demo shows exactly what you'd get. The one narrower exception:--demo --measurestill samples a single pinned model so the try-out path only needs anOPENAI_API_KEY— that pin never touches the recommendation itself. - The demo's recommendation moved. With the un-pinned roster and the refreshed data below, the demo's headline recommendation now routes easy calls to
deepseek-v4-flash(it previously routed to a fixed illustrative pick) — an honest side effect of no longer special-casing the demo. - Fresh pricing and quality data. The bundled pricing table and LMArena quality tiers are re-synced to their public sources as of this release, the same weekly process
frugon updateruns for you. - Honest disclosure copy. The post-recommendation note no longer claims a "fixed demo candidate set" — it says plainly that
--demoruns on bundled sample data, full stop. --measure/--judgenow recognise every vendor in the 23-model roster. DeepSeek, xAI (Grok), Moonshot (Kimi), Z.ai (GLM), MiniMax, and Alibaba (Qwen) models — plus the two reference-host Llama 4 checkpoints — now get the correct provider-key prompt and route correctly to their provider, instead of a generic "bad request" the first time you tried to measure one of them.
Install / upgrade
uvx frugon@latest # or: uv tool upgrade frugon / pipx upgrade frugon / pip install -U frugonFull Changelog: v0.2.0...v0.2.1
v0.2.0
frugon v0.2.0
Recommendations now track the models developers actually use. The routing pool is a curated set of current top models — every one priced and quality-rated — and a new frugon update command keeps your pricing and quality tables current.
Added
frugon update— refresh the pricing and quality tables from their public sources in one step (the same as runningfrugon pricing updatethenfrugon quality update). No account, and nothing about your usage is sent anywhere.- Curated recommendation roster. The default candidate pool is now a hand-picked set of current top models across providers, drawn from OpenRouter usage rankings and intersected with LiteLLM pricing and LMArena quality tiers — so recommendations reflect what teams run today rather than a stale list. Every model in the pool is both priced and quality-rated.
Improved
- A clear note on where recommendations come from. After a recommendation, frugon names the curated set, when its prices were last synced, and its sources — with a nudge to run
frugon updateif the bundled data is getting old. It never blocks output. - Broader out-of-the-box pricing — several newly-listed models added to the bundled table.
- Modernized
--demo— the built-in demo now reflects a current baseline and recommendation.
Install / upgrade
uvx frugon@latest # or: uv tool upgrade frugon / pipx upgrade frugon / pip install -U frugonWhat's Changed
- chore(pricing): weekly pricing table sync by @github-actions[bot] in #3
- chore(quality): weekly quality tier sync [auto-merge] by @github-actions[bot] in #4
Full Changelog: v0.1.3...v0.2.0
v0.1.3
frugon v0.1.3
Money is easier to read — and the savings now check out by hand. Every dollar amount displays at two decimal places, and the reported saving reconciles exactly with the figures shown.
Improved
- All dollar amounts display at 2 decimal places (e.g.
$389.88instead of$389.8849). Sub-cent amounts keep the precision they need — costs below $0.01 show 4 decimals, below $0.0001 show 6 — so a genuinely tiny cost never rounds away to$0.00. - Reported savings reconcile from the printed figures. The saving amount and the percentage are derived from the rounded numbers you see, so
Current − New = SAVINGandpercent = saving / currentcheck out by hand — on every surface (the terminal panel, the Markdown report, and both HTML report styles).
Install / upgrade
pipx upgrade frugon # or: pip install -U frugon / uvx frugon@latestFull Changelog: v0.1.2...v0.1.3
v0.1.2
frugon v0.1.2
A patch release. The headline fix: frugon --version now reports the correct version. It also broadens out-of-the-box pricing coverage.
Fixed
--version(and the requestUser-Agent) now report the actual installed version. They previously read a hardcoded string that wasn't kept in lockstep with the package version — so the 0.1.1 wheel reported0.1.0. The version is now derived from the installed package metadata, so it can never drift again.
Improved
- Broader out-of-the-box price coverage. More bare model names now resolve to a price automatically — including the DeepSeek family (
deepseek-r1,deepseek-chat) and xAI Grok (grok-2,grok-3). Frugon now matches your model name against the pricing registry's provider-prefixed entries, so you don't have to spell out the full provider path to get a cost. Where a model's price genuinely differs across hosts (as many open-weight models do), Frugon still reports no price rather than guess.
Housekeeping
- Refreshed the bundled quality tiers to the latest LMArena snapshot. You can refresh these yourself any time with
frugon quality update— this just improves the defaults you get on a fresh install. - Internal CI maintenance (GitHub Action runtime bumps; data-sync workflow fix).
Install / upgrade
pipx upgrade frugon # or: pip install -U frugon / uvx frugon@latestWhat's Changed
- chore(pricing): weekly pricing table sync by @github-actions[bot] in #2
- chore(quality): weekly quality tier sync [auto-merge] by @github-actions[bot] in #1
New Contributors
- @github-actions[bot] made their first contribution in #2
Full Changelog: v0.1.1...v0.1.2
v0.1.1
frugon v0.1.1
A documentation and report-wording accuracy pass. No behaviour, cost-math, or analysis changes — the numbers are identical to v0.1.0; only documentation and report wording differ.
What changed
- Provenance, stated precisely. The report's methodology line now reads "LMArena quality tiers, RouteLLM-style routing" — naming each source for exactly what it does: model-quality tiers come from the LMArena leaderboard; routing is a RouteLLM-style local heuristic (not a trained router); and the headline savings ranges (30–50%, up to ~85%) are anchored to RouteLLM's published research. The easy/hard split caveat is worded to match.
- Demo size stated accurately as 56,100 calls (the bundled
--demoset; was rounded to "50k" in--help). - Cross-platform timing wording — the bundled demo "prices in a few seconds" (≈2s on WSL, ≈4s on Windows).
- SECURITY.md — single security contact (
security@rodiun.io, plus GitHub private vulnerability reporting).
Install / upgrade
pipx upgrade frugon # or: pip install -U frugon / uvx frugon@latestBuilt by Rodiun. MIT licensed.
Full Changelog: v0.1.0...v0.1.1
v0.1.0
frugon v0.1.0
Your data never leaves your machine. Your keys go straight to your own providers. Nothing reaches us.
Free, local, open-source LLM cost analyzer. Point it at your real call logs and see — on your machine — how much you'd save by switching or routing models.
Install
# One-shot (no install)
uvx frugon analyze ./logs.jsonl
# Permanent install
pipx install frugon
frugon analyze --demo # bundled sample log, see it work in 5 seconds
frugon analyze ./logs.jsonl # your real logsCross-platform: macOS, Linux, Windows · Python 3.10 / 3.11 / 3.12 / 3.13.
What's in this release
frugon analyze — read OpenAI-compatible JSONL logs and produce a cost analysis. Counts tokens with tokencost, prices with LiteLLM's registry, picks a cheaper-than-baseline candidate model, and tells you the dollar saving. Cross-platform, fully local, no LLM calls, no network. Honest savings anchored to RouteLLM/LMSYS quality bands — we never inflate the number.
frugon capture — passive OpenAI-compatible logger. Point your app's base URL at http://127.0.0.1:8787 for a day; it records every call to a local JSONL file in the canonical shape and forwards the request unchanged to the real upstream. No data goes anywhere but your local file and your existing upstream.
frugon pricing update — refresh the bundled pricing table from the LiteLLM model_prices_and_context_window.json registry. Atomic write, JSON shape validation, weekly GitHub Actions sync.
frugon models [QUERY] — list the model names frugon can price (the exact names --candidates accepts), optionally filtered by a case-insensitive substring. Pure local read — no network.
frugon quality update — refresh the bundled quality-tier table from the LMArena leaderboard so the Strong / Capable tier labels stay current. Tiers are self-recalibrating percentile bands: Elite (top 10%), Strong (10–30%), Capable (30–60%), Efficient (bottom 40%).
frugon analyze --measure (optional [measure] extra) — sample real prompts through candidate models using your own API keys. Calls go straight to your providers (OpenAI / Anthropic / etc.) — never to us. Two tiers: side-by-side diffs (human judge) or LLM-as-judge win/loss/tie tallies.
frugon analyze --report file.html|file.md — shareable single-page report. Self-contained HTML with inline CSS (deep indigo + cyan + silver), or clean Markdown. The viral surface someone shows their boss.
Realistic savings
Anchored to RouteLLM / LMSYS research bands:
| Traffic mix | Typical saving |
|---|---|
| General mixed traffic | 30–50% |
| Easy / repetitive (MT-Bench) | up to ~85% |
| Hard tasks (MMLU) | ~30% |
Your actual number comes from your logs. Frugon shows what the math says for your data.
Privacy guarantees (tested as code, not promised in prose)
- Cost analysis is fully local. No LLM, no network, no telemetry.
capturenever sends data anywhere but your configured upstream. Asserted at the socket layer in tests — any future regression that introduces a side-channel HTTP client breaks CI.--measurecalls only the user's own providers with the user's own keys. Keys are never logged, never persisted, never sent anywhere but the provider. Asserted by a defense-in-depth fixture patchingsocket.socket/socket.create_connection/socket.getaddrinfo.- The CLI collects nothing. Open source — anyone can verify.
Quality
- 1,960 tests, 95% overall coverage, 97% on the cost-math triad (
cost.py/pricing.py/routing.py). - CI green on 3 OS × 4 Python (ubuntu / macos / windows × 3.10 / 3.11 / 3.12 / 3.13).
- Every change is code-reviewed before merge; cost-math changes get an extra dedicated review pass.
- ruff + mypy clean.
Keep the savings
This release is the diagnosis. Want it to keep routing automatically and hold the savings? → https://frugon.rodiun.io
Built by Rodiun. MIT licensed.