Repository navigation
Releases: magna56/fiscallm
Release list
v0.6.0: spending caps that hold during an outage
What's new
Until now, meter.check failed fully open: if FiscaLLM was slow or down, every call went through, including a looping agent's. Now:
- Sticky deny: a user FiscaLLM already refused stays refused while it is unreachable, until it answers "allow" again.
checkOnError: "deny"(check_on_error="deny"in Python): refuse everyone while FiscaLLM is unreachable, if you prefer failing closed. Default is still "allow".- Local limit: the SDK counts each user's AI calls, tokens and exact costs in your own process, and
checkrefuses past the limit with no network call, so a runaway loop stops even when FiscaLLM is down. With several servers, each enforces it separately. - Results now include
source:server,local,last-knownorunreachable.
const meter = createMeter({ apiKey, checkOnError: "deny", localLimit: { requests: 60, tokens: 500_000, windowSeconds: 300 } });meter = Meter(api_key, check_on_error="deny", local_limit=LocalLimit(requests=60, tokens=500_000, window_seconds=300))Behavior change: a user refused earlier is now refused during an outage instead of allowed.
Next on the roadmap: per-user downgrade, a budget setting between Alert and Block that switches the user to a cheaper model instead of cutting them off.
SDKs: npm install fiscallm@0.6.0 / pip install fiscallm==0.6.0. No server or database changes.
Full list: CHANGELOG.md · Docs: https://fiscallm.com/docs#caps
v0.5.0: Jobs (cost of refunded and unresolved pay-per-job work)
What's new
- Jobs, for apps that charge per job (credits held when a job starts, then captured or returned). Tag AI calls with a
jobId, and report each job aspending,capturedorrefundedwithmeter.trackJob({ jobId, userId, status })(TypeScript),meter.track_job(...)(Python) orPOST /api/v1/jobs. - New Jobs page in the dashboard: AI cost of captured, refunded, unresolved and in-progress jobs, plus the users whose refunded or unresolved jobs cost you money.
jobId/job_idworks ontrack,trackOpenAI,trackStreamand the other helpers.
The newest status wins, and a late pending never reopens a captured or refunded job, so retries and out-of-order reports are safe. A job with no final status an hour after its last event counts as unresolved (e.g. a provider timeout you haven't reconciled). If a failed job was still billed by the provider, track its cost anyway, then report refunded.
meter.trackJob({ jobId, userId, status: "pending" });
meter.track({ userId, provider: "fal", model: "veo-3", units: 15, unit: "second", jobId });
meter.trackJob({ jobId, userId, status: "captured" }); // or "refunded"Self-hosters: run pnpm db:migrate (adds the jobs table and ai_events.job_id).
SDKs: npm install fiscallm@0.5.0 / pip install fiscallm==0.5.0.
Full list: CHANGELOG.md · Docs: https://fiscallm.com/docs#jobs
v0.4.0: spending caps, Slack alerts, loop alert
What's new
- Spending caps: mark a per-user budget as Block, then call
meter.check(userId)(TypeScript) ormeter.check(user_id)/acheck(Python) before an AI call. It returnsallow: falseonce the user reaches the amount, and fails open if FiscaLLM is slow or down. AlsoPOST /api/v1/check. - Slack alerts: paste a Slack incoming-webhook URL as an alert's webhook.
- Runaway-loop alert: get alerted when one user uses more than N tokens in 5 minutes.
Caps use cost that is already recorded, so a user can overshoot slightly. There is no automatic model downgrade yet (see the docs for a downgrade example).
SDKs: npm install fiscallm@0.4.0 / pip install fiscallm==0.4.0.
Full list: CHANGELOG.md
v0.3.2
First tagged release.
SDKs: TypeScript npm install fiscallm and Python pip install fiscallm, both at 0.3.2.
Highlights
- Per-user AI cost and margin joined with RevenueCat revenue
- Stripe connector (beta)
- Kill switch in both SDKs (
FISCALLM_DISABLED=1) - Budget alerts, weekly report, CSV export
- Open source (MIT) with a self-hosting guide
See CHANGELOG.md and the public roadmap.