stepcost (Python SDK)
FinOps for LLM agents — a typed, priced cost graph for every agent step. See
../../SPEC.md for the product and technical design.
Install
pip install stepcost # from PyPI (or: pip install -e . from a clone)
pip install -e ".[dev]" # + pytest, ruff
Requires Python ≥ 3.11. Runtime deps: pydantic (only).
Quickstart (no API key, $0)
python examples/quickstart.py
stepcost report ~/.stepcost/quickstart.db
examples/quickstart.py instruments a 3-step agent (plan → retrieve → execute)
with simulated usage and writes a priced cost graph to SQLite. stepcost report
renders the per-step tree, by-step / by-kind / by-customer rollups, and waste
flags — no spend, no network.
Instrument your agent
from stepcost import StepCost, agent_step, llm_call
cc = StepCost(project="my-app", sink="sqlite:///~/.stepcost/my-app.db")
with cc.trace(feature_id="chat", customer_id="acme") as trace:
with agent_step("answer"), llm_call(model="gpt-4o-mini", provider="openai") as call:
resp = openai_client.chat.completions.create(...)
call.record(resp) # invoice-safe token + $ extraction
print(trace.total_usd, trace.by_step) # also .by_kind
call.record(resp)extracts usage from OpenAI (Chat Completions, Responses API, embeddings) and Anthropic responses — cached / reasoning tokens and 5m- vs 1h-TTL cache writes split correctly, no double-count. Unrecognized usage shapes raise instead of silently recording $0.- No extractor for your provider? Use
record_usage(input_tokens=…, output_tokens=…, embedding_tokens=…). - Sinks:
sink="stdout"orsink="sqlite:///path.db". - Safe by construction: spans persist at trace exit and process exit (no manual
flush()needed), sink failures re-queue instead of dropping spans, and concurrent asyncio tasks under one trace parent their spans correctly. - Models missing from the price table trigger a runtime warning and an
"unpriced spans" section in
stepcost report— never a silent $0.
Report CLI
stepcost report <db> # account summary: by feature/customer/kind, top traces, waste
stepcost report <db> --trace <id> # one trace's cost tree (per-node tokens + $)
stepcost report <db> --json # machine-readable
Privacy
Metadata-only by default (PayloadCapture.NONE): token counts, model, and your
business dimensions — never prompt/response content. Fully offline; SQLite stays
local.
Develop
pytest # 50 tests
ruff check stepcost tests scripts
python scripts/bench_overhead.py # p99 span-emit overhead (<5ms gate)
Metadata
Release files for stepcost 0.3.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| stepcost-0.3.2.tar.gz | 51.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| stepcost-0.3.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 98.6 kB
Release files / stepcost-0.3.2.tar.gz
| Download URL | stepcost-0.3.2.tar.gz |
|---|---|
| Size | 51.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
52cfcc45d4ddbf584008734236f94cbb7a87dbfde98847589299a8824cc3da11
|
|
BLAKE2b-256 checksum How to use checksums |
2ceb7a34ffc677361f7549211aaf26cd0e1d49711831c035ff403b31e51b9ca1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Release files / stepcost-0.3.2-py3-none-any.whl
| Download URL | stepcost-0.3.2-py3-none-any.whl |
|---|---|
| Size | 47.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
18a349d7f3ac90d68e19b045e3956f582b79cfd9981fe6156ce0c35b0a0a2211
|
|
BLAKE2b-256 checksum How to use checksums |
aa9588b25fa1b37b09b8ea1b993ef9f0bb5238a4d1596d9e9751137c0f88b448
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|