Skip to main content

costhelm

A self-hosted cost-governance gateway for LLM APIs. Your agents talk to one local HTTP endpoint; costhelm owns the provider keys and answers every call with the numbers that actually matter: what it cost, who spent it, and how much budget is left.

Most gateways treat cost as a report you read after the money is gone. costhelm treats it as a precondition: every call is projected at worst-case cost and admitted against a hard budget before any provider is contacted. A refusal is an HTTP 402 with the arithmetic in the body — limit, spend, projection, shortfall — and it costs $0, because nothing was sent.

call 4: ollama/phi4:latest — $0.017000 (total $0.047000) — 'Running budget checks before...'
call 5: REFUSED — session:budget-agent-demo would exceed its lifetime budget:
        spent $0.047000 of $0.050000, this call projects $0.016000

Features

Hard budgets Per-principal ceilings (tenant/project/user/agent/session, glob-able) with minute/hour/day/month/lifetime periods. Pre-call admission on a worst-case projection; spend is always re-derived from the ledger, never a parallel counter. Runtime overrides via POST /v1/budget — clamp a runaway session without a deploy.
Priced ledger One SQLite row per call, priced from a per-model pricing.yaml (glob patterns, cache-read/write and batch multipliers) and attributed to all five principal dimensions. CI fails if a configured default model would price at $0.
Tier routing + cascade A small router LLM classifies each prompt (TINY/LARGE/HUGE); the caller's declared role clamps the tier with floors and ceilings; candidates are ordered by cost, quality, or a tradeoff dial. Low-confidence answers escalate one tier — confidence is scored from structural signals, never a judge LLM.
Provider failover Eight providers behind one API (OpenAI, Gemini with a numbered key pool, OpenRouter, Ollama, Groq, Cerebras, NVIDIA, GitHub Models). RPM/RPD/TPM pacing, capability-aware picking (tools/vision/reasoning/structured), failure-class cooldowns — all configurable in routing.yaml.
Semantic cache Embed → cosine match → skip the provider entirely. A hit bills $0 and records the tokens as saved; truncated and empty completions are refused into the cache. Off by default, one line to enable.
Observability OTel spans with gen_ai.* attributes plus cost; two zero-build HTML dashboards; /v1/refusals captures the 402s that by design leave no span and no ledger row. Prompt/completion capture is off by default.
Optional auth One env var (COSTHELM_API_KEYS) guards /v1/* with bearer or X-API-Key. Off by default for localhost.

Quickstart

uvx costhelm serve

(or from a clone: uv sync && uv run costhelm serve)

Add a provider key to .env (see .env.example) — or none at all if Ollama is running locally:

curl -s localhost:8111/v1/chat -H 'Content-Type: application/json' \
  -d '{"prompt": "hello", "max_tokens": 50}'

Every response carries cost, budget, cache, and router_decision envelopes. Open http://localhost:8111/ for the dashboard.

To see budget enforcement end-to-end, run the example agent — it arms a $0.05 ceiling, spends it, and prints the 402:

uv run python examples/budget_agent.py

How a request flows

POST /v1/chat
  │
  1. build_context      normalise, estimate tokens, resolve principal, agent pin
  2. semantic cache     hit → return stored answer, bill $0, record tokens saved
  3. select_candidates  router-LLM tier classify → role clamp → cost/quality order
  4. dispatch           ┌ cascade loop ──────────────────────────────┐
                        │  for each candidate:                       │
                        │    budget admission (worst-case, pre-call) │──402
                        │    provider call (+1 retry, backoff)       │
                        │    structured-output validate/repair       │
                        │    confidence check → maybe escalate tier ─┘
                        │    meter → priced ledger row, OTel span
                        └ return text + cost/budget/cache envelopes

Each stage is a module in costhelm/pipeline/, and each is inert unless configured: with the shipped config files, costhelm behaves like a plain failover gateway.

Configuration

Four YAML files, three-layer resolution — an env-var path override wins, then ~/.costhelm/<name>.yaml, then the packaged default. costhelm paths prints what resolved where.

File Governs
pricing.yaml $/Mtok per model, cache/batch multipliers, quality weights
budgets.yaml Spend ceilings per principal (ships empty: nothing is refused)
routing.yaml Tiers, roles, ladders, escalation, provider limits, agent pins
cache.yaml Semantic cache (ships disabled)

Secrets and switches live in .env — see .env.example. A provider registers only if its key variable is set.

Client

from costhelm.client import CosthelmClient, BudgetExceeded

async with CosthelmClient() as gw:
    await gw.set_budget("session:run-42", 0.05, period="day")
    try:
        r = await gw.chat("hello", request={"session": "run-42", "auto_route": "worker"})
        print(r["text"], r["cost"]["total_usd"])
    except BudgetExceeded as e:
        print("refused:", e.envelope["shortfall_usd"])

The wire contract is plain HTTP JSON — any language works. The client holds no provider credential; that boundary is the point.

Deployment

deploy/ has systemd/launchd/Windows-service templates, a Modal wrapper, and a docker-compose file for a local Jaeger to receive the OTel spans. Docs: https://costhelm.com

Origins

costhelm grew out of an agentic-AI course project (a gateway serving a budget-aware agent runtime) and was extracted and restructured into a standalone framework.

License

MIT

Metadata

Release files for costhelm 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for costhelm 0.1.0
File Size Uploaded Provenance
costhelm-0.1.0.tar.gz 331.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for costhelm 0.1.0
File Interpreter ABI Platform
costhelm-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 482.4 kB

Release files / costhelm-0.1.0.tar.gz

Download URL costhelm-0.1.0.tar.gz
Size 331.3 kB
Tags Source
SHA-256 checksum
How to use checksums
968feb2008f04690ea2b827dc9273855c1118538b9a5a6238e75360033fe9f84
BLAKE2b-256 checksum
How to use checksums
14fcc12d6cc05161b3acf1d540951320946caaaa108dd72899d326216ce26c6a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / costhelm-0.1.0-py3-none-any.whl

Download URL costhelm-0.1.0-py3-none-any.whl
Size 151.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9ae136d7051556cccd583063ab930e44de67751f9a31eaf0173e2bcb9c699660
BLAKE2b-256 checksum
How to use checksums
5de27fbde871af2b8faa5321eb38b8ecf8181fe0b26f50508d61e34c4ad0c9a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for costhelm 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page