governer 1.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- governer-1.0.2/LICENSE +21 -0
- governer-1.0.2/PKG-INFO +254 -0
- governer-1.0.2/README.md +231 -0
- governer-1.0.2/governer.egg-info/PKG-INFO +254 -0
- governer-1.0.2/governer.egg-info/SOURCES.txt +9 -0
- governer-1.0.2/governer.egg-info/dependency_links.txt +1 -0
- governer-1.0.2/governer.egg-info/entry_points.txt +2 -0
- governer-1.0.2/governer.egg-info/top_level.txt +1 -0
- governer-1.0.2/governer.py +983 -0
- governer-1.0.2/pyproject.toml +35 -0
- governer-1.0.2/setup.cfg +4 -0
governer-1.0.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kaiser0733 / Vastraa Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
governer-1.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: governer
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: Hard spend breaker for AI agents — prices cache reads, bills real usage, and refuses the request that would cross your budget.
|
|
5
|
+
Author-email: Kaiser0733 <amardeepkumar0733@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Kaiser0733/governer
|
|
8
|
+
Project-URL: Issues, https://github.com/Kaiser0733/governer/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/Kaiser0733/governer/blob/main/CHANGELOG.md
|
|
10
|
+
Keywords: ai,agents,llm,cost,finops,budget,tokens,openai,anthropic
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
18
|
+
Classifier: Topic :: System :: Monitoring
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# governer
|
|
25
|
+
|
|
26
|
+
[](https://github.com/Kaiser0733/governer/actions/workflows/test.yml)
|
|
27
|
+
|
|
28
|
+
**Your agent spent $37,901 while you slept. The budget alert told you afterwards.**
|
|
29
|
+
|
|
30
|
+
`governer` prices every request the way the provider actually bills it — cache
|
|
31
|
+
reads and writes included — then **refuses the request that would cross your
|
|
32
|
+
line**. Not a warning. Not a dashboard. A kill switch.
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
$ governer box
|
|
36
|
+
wallet $10.00 · gpt-6-astra · 200,000 tok/turn · CACHE MISSING
|
|
37
|
+
|
|
38
|
+
turn 1 $ 2.02 / $10.00
|
|
39
|
+
turn 2 $ 4.05 / $10.00
|
|
40
|
+
turn 3 $ 6.07 / $10.00
|
|
41
|
+
turn 4 $ 8.10 / $10.00
|
|
42
|
+
turn 5 BLOCKED (would have cost $2.0250)
|
|
43
|
+
|
|
44
|
+
🛑 BREAKER TRIPPED at $8.10 of $10.00 — agent stopped
|
|
45
|
+
|
|
46
|
+
paid $ 8.10 (5 turns)
|
|
47
|
+
same run, cached $ 0.90
|
|
48
|
+
you paid 9x the cached price — this is the $38k bug
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
No API key, no network, ninety seconds.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pipx install governer # or: pip install governer
|
|
57
|
+
governer box
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
No dependencies either way. Prefer a file? Two curls and you're done:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
curl -O https://raw.githubusercontent.com/Kaiser0733/governer/main/governer.py
|
|
64
|
+
curl -O https://raw.githubusercontent.com/Kaiser0733/governer/main/prices.json
|
|
65
|
+
python3 governer.py box
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Python 3.9+.
|
|
69
|
+
|
|
70
|
+
## Commands
|
|
71
|
+
|
|
72
|
+
| command | what it does |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `governer proxy --limit 5` | OpenAI-compatible shim: point your agent at it, it refuses anything past $5 |
|
|
75
|
+
| `governer box` | simulated agent in a virtual wallet — watch the breaker trip, no key needed |
|
|
76
|
+
| `governer check usage.json --limit 20` | true cost of a real log, plus where a $20 cap would have stopped it |
|
|
77
|
+
| `governer prices` | what every model costs right now, with its verified date |
|
|
78
|
+
| `governer prices --refresh` | pull live prices from the gateway — 459 models, cache pricing included |
|
|
79
|
+
| `governer prices --live` | every known model, cheapest first |
|
|
80
|
+
| `governer prices --upcoming` | announced price changes — Gemini 3.8 Flash doubles 2027-01-01 |
|
|
81
|
+
| `governer free` | which models are free *right now*, fetched live |
|
|
82
|
+
| `governer status spend.jsonl --limit 20` | the meter: spent, burn rate, projection, per-agent split |
|
|
83
|
+
| `governer verify ledger.jsonl` | checks a spend ledger for tampering |
|
|
84
|
+
|
|
85
|
+
## Put it in front of your agent
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
$ governer proxy --limit 5 --ledger spend.jsonl
|
|
89
|
+
|
|
90
|
+
governer http://127.0.0.1:8787 → https://openrouter.ai/api/v1
|
|
91
|
+
wallet $5.00 · unknown models billed $0.0/$0.0 per M
|
|
92
|
+
|
|
93
|
+
export OPENAI_BASE_URL=http://127.0.0.1:8787/v1
|
|
94
|
+
export OPENAI_API_KEY=<your key> # governer never stores it
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Your agent keeps working unchanged. Every request is priced at its worst case
|
|
98
|
+
*before it leaves the machine*, forwarded with your own key, then billed at its
|
|
99
|
+
real usage. Cross the limit and the request comes back `402` with
|
|
100
|
+
`type: governer_breaker_tripped` — and your provider never sees it.
|
|
101
|
+
|
|
102
|
+
Streaming passes straight through — governer adds `stream_options.include_usage`
|
|
103
|
+
so the final usage block still arrives and the stream can be billed. Unpriced models
|
|
104
|
+
fall back to `--default-in/--default-out`, which is also how you *shadow-price* a
|
|
105
|
+
free model to see what it would have cost:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
✓ 200 nvidia/nemotron-3.5-lightning:free $0.001230 $0.0012/$5.00
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
When the provider reports its own `cost` field, governer compares it against
|
|
112
|
+
its own number and warns when `prices.json` has gone stale.
|
|
113
|
+
|
|
114
|
+
### Budgets per agent, per day
|
|
115
|
+
|
|
116
|
+
One proxy, several caps. Copy `governer.example.json` and pass it:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"limit": 20.0,
|
|
121
|
+
"ledger": "spend.jsonl",
|
|
122
|
+
"notify": "https://ntfy.sh/your-topic",
|
|
123
|
+
"agents": {
|
|
124
|
+
"claude-code": { "limit": 5.0, "per": "day" },
|
|
125
|
+
"ci": { "limit": 2.0, "per": "run" }
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
governer proxy --config governer.example.json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The agent names itself with a header — `X-Governer-Agent: claude-code` — and the
|
|
135
|
+
cap applies to it alone. `day` resets at UTC midnight, `run` lasts the process.
|
|
136
|
+
Both are rebuilt from the ledger on restart, so bouncing the proxy cannot reset a
|
|
137
|
+
budget. `notify` receives a POST when the breaker trips.
|
|
138
|
+
|
|
139
|
+
### Watch for a week before you enforce
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
governer proxy --limit 20 --dry-run --ledger spend.jsonl
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Dry run books the true spend and refuses nothing, so you learn what a normal week
|
|
146
|
+
costs before a cap starts costing you work. Anything it would have refused is
|
|
147
|
+
marked `◌` in the console.
|
|
148
|
+
|
|
149
|
+
## Audit a log you already have
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
$ governer check usage.json --limit 20
|
|
153
|
+
requests 100
|
|
154
|
+
true cost $52.00
|
|
155
|
+
cache miss 100 request(s) billed uncached while sending ≥10k tokens
|
|
156
|
+
$43.20 of that was avoidable — ~83% of the bill
|
|
157
|
+
at $20.00 cap: stopped at request 39, $32.24 never spent (62% saved)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Reads Anthropic (`input_tokens`), OpenAI (`prompt_tokens`) and OpenRouter
|
|
161
|
+
(`cached_tokens`) field names, as a JSON array or JSONL.
|
|
162
|
+
|
|
163
|
+
## It prices models nobody told it about
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
$ governer prices --refresh
|
|
167
|
+
459 models refreshed from https://openrouter.ai/api/v1
|
|
168
|
+
free right now: 20
|
|
169
|
+
vendor-confirmed cache pricing: 313
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Curated entries are hand-verified, each with a date and a source. Everything
|
|
173
|
+
else is pulled live, so an agent that switches to a model released last week
|
|
174
|
+
still gets priced — instead of silently costing nothing in your ledger because
|
|
175
|
+
nobody typed it into a table.
|
|
176
|
+
|
|
177
|
+
## Gate a pull request on cost
|
|
178
|
+
|
|
179
|
+
```yaml
|
|
180
|
+
- uses: Kaiser0733/governer@main
|
|
181
|
+
with:
|
|
182
|
+
usage-file: ci/agent-usage.json
|
|
183
|
+
budget: "2.50"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
`governer check --fail-over 2.50` exits `1` when the run costs more. Tests
|
|
187
|
+
should not be the only thing a PR can fail.
|
|
188
|
+
|
|
189
|
+
## The meter, not just the wall
|
|
190
|
+
|
|
191
|
+
A hard cap alone does not fix behaviour — it just moves the spending to the last week
|
|
192
|
+
of the month. The number has to be in front of you while you decide whether to kick off
|
|
193
|
+
another run.
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
$ governer status spend.jsonl --limit 20
|
|
197
|
+
spent $2.40 of $20.00 (12% used)
|
|
198
|
+
burn rate $0.40/h over 6.0h
|
|
199
|
+
projected $9.60/day at this rate
|
|
200
|
+
runs out in 44.0h at this rate
|
|
201
|
+
agent claude-code $2.10
|
|
202
|
+
agent ci $0.30
|
|
203
|
+
chain OK — 3 records · $2.4000 · chain intact
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
It refuses to project from a window shorter than 30 minutes, because extrapolating three
|
|
207
|
+
records in the same minute produces confident nonsense.
|
|
208
|
+
|
|
209
|
+
## Why this instead of the other options
|
|
210
|
+
|
|
211
|
+
| option | what it covers | what it misses |
|
|
212
|
+
|---|---|---|
|
|
213
|
+
| provider credit / key limits | a hard stop per account | not per agent, not cross-vendor, and it is exactly the layer that failed the $38k case |
|
|
214
|
+
| an in-process library (`budget-guard`, npm) | a cap inside one Node app | one language, needs a code change, no help for a CLI agent you did not write |
|
|
215
|
+
| an agent runtime with budgets (`cx`, Claude Extender) | caps for agents inside that runtime | requires adopting the whole runtime |
|
|
216
|
+
| gateway budgets (litellm, OmniRoute) | budget fields in the gateway | enforcement is soft, and litellm's was silently bypassed (#26672) |
|
|
217
|
+
| **governer** | any client in any language, no code change, cross-vendor, cache-aware pricing, tamper-evident ledger, CI gate, audit of logs you already have | one process per ledger — do not point two proxies at the same file |
|
|
218
|
+
|
|
219
|
+
## Why the bill explodes at night
|
|
220
|
+
|
|
221
|
+
- **1M-token contexts are table stakes**, so the cached prefix is replayed on
|
|
222
|
+
every call. Cache reads dominate agent bills — and they are billed even when
|
|
223
|
+
that content is truncated before the model attends to it.
|
|
224
|
+
- **"Prompt caching is supported" is not "your stack is caching."** The
|
|
225
|
+
expensive failure is silent: status 200, normal-looking output, invoice 100×.
|
|
226
|
+
- **Alerts are not limits.** Email after the money is gone is not a safety
|
|
227
|
+
mechanism, and neither are credits or a dashboard you check on Mondays.
|
|
228
|
+
|
|
229
|
+
## Receipts
|
|
230
|
+
|
|
231
|
+
The spend ledger is append-only and hash-chained: every record carries the hash
|
|
232
|
+
of the one before it, so editing a number breaks the chain and `verify` says so.
|
|
233
|
+
Tamper-evident bookkeeping, because a budget you can quietly rewrite is not a
|
|
234
|
+
budget.
|
|
235
|
+
|
|
236
|
+
## Prices are data, not truth
|
|
237
|
+
|
|
238
|
+
Every model in `prices.json` carries a `verified` date and a source. Cache
|
|
239
|
+
prices marked `~` are derived from the vendor convention (0.1× read, 1.25×
|
|
240
|
+
write) rather than confirmed. Re-verify before betting a number that matters,
|
|
241
|
+
and open a PR when a vendor moves.
|
|
242
|
+
|
|
243
|
+
## Roadmap
|
|
244
|
+
|
|
245
|
+
- ~~v0.2~~ proxy, live `free` check, CI gate — shipped
|
|
246
|
+
- ~~v0.5~~ price table refreshed from the gateway instead of hand-maintained — shipped
|
|
247
|
+
- **v0.3** per-agent and per-workflow budgets on one proxy
|
|
248
|
+
- **v0.4** phone push the second a breaker trips
|
|
249
|
+
|
|
250
|
+
## License
|
|
251
|
+
|
|
252
|
+
**Docs and demo:** https://kaiser0733.github.io/governer/
|
|
253
|
+
|
|
254
|
+
MIT. Built by [Kaiser0733](https://github.com/Kaiser0733) at Vastraa Labs.
|
governer-1.0.2/README.md
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# governer
|
|
2
|
+
|
|
3
|
+
[](https://github.com/Kaiser0733/governer/actions/workflows/test.yml)
|
|
4
|
+
|
|
5
|
+
**Your agent spent $37,901 while you slept. The budget alert told you afterwards.**
|
|
6
|
+
|
|
7
|
+
`governer` prices every request the way the provider actually bills it — cache
|
|
8
|
+
reads and writes included — then **refuses the request that would cross your
|
|
9
|
+
line**. Not a warning. Not a dashboard. A kill switch.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
$ governer box
|
|
13
|
+
wallet $10.00 · gpt-6-astra · 200,000 tok/turn · CACHE MISSING
|
|
14
|
+
|
|
15
|
+
turn 1 $ 2.02 / $10.00
|
|
16
|
+
turn 2 $ 4.05 / $10.00
|
|
17
|
+
turn 3 $ 6.07 / $10.00
|
|
18
|
+
turn 4 $ 8.10 / $10.00
|
|
19
|
+
turn 5 BLOCKED (would have cost $2.0250)
|
|
20
|
+
|
|
21
|
+
🛑 BREAKER TRIPPED at $8.10 of $10.00 — agent stopped
|
|
22
|
+
|
|
23
|
+
paid $ 8.10 (5 turns)
|
|
24
|
+
same run, cached $ 0.90
|
|
25
|
+
you paid 9x the cached price — this is the $38k bug
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
No API key, no network, ninety seconds.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pipx install governer # or: pip install governer
|
|
34
|
+
governer box
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
No dependencies either way. Prefer a file? Two curls and you're done:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
curl -O https://raw.githubusercontent.com/Kaiser0733/governer/main/governer.py
|
|
41
|
+
curl -O https://raw.githubusercontent.com/Kaiser0733/governer/main/prices.json
|
|
42
|
+
python3 governer.py box
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Python 3.9+.
|
|
46
|
+
|
|
47
|
+
## Commands
|
|
48
|
+
|
|
49
|
+
| command | what it does |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `governer proxy --limit 5` | OpenAI-compatible shim: point your agent at it, it refuses anything past $5 |
|
|
52
|
+
| `governer box` | simulated agent in a virtual wallet — watch the breaker trip, no key needed |
|
|
53
|
+
| `governer check usage.json --limit 20` | true cost of a real log, plus where a $20 cap would have stopped it |
|
|
54
|
+
| `governer prices` | what every model costs right now, with its verified date |
|
|
55
|
+
| `governer prices --refresh` | pull live prices from the gateway — 459 models, cache pricing included |
|
|
56
|
+
| `governer prices --live` | every known model, cheapest first |
|
|
57
|
+
| `governer prices --upcoming` | announced price changes — Gemini 3.8 Flash doubles 2027-01-01 |
|
|
58
|
+
| `governer free` | which models are free *right now*, fetched live |
|
|
59
|
+
| `governer status spend.jsonl --limit 20` | the meter: spent, burn rate, projection, per-agent split |
|
|
60
|
+
| `governer verify ledger.jsonl` | checks a spend ledger for tampering |
|
|
61
|
+
|
|
62
|
+
## Put it in front of your agent
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
$ governer proxy --limit 5 --ledger spend.jsonl
|
|
66
|
+
|
|
67
|
+
governer http://127.0.0.1:8787 → https://openrouter.ai/api/v1
|
|
68
|
+
wallet $5.00 · unknown models billed $0.0/$0.0 per M
|
|
69
|
+
|
|
70
|
+
export OPENAI_BASE_URL=http://127.0.0.1:8787/v1
|
|
71
|
+
export OPENAI_API_KEY=<your key> # governer never stores it
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Your agent keeps working unchanged. Every request is priced at its worst case
|
|
75
|
+
*before it leaves the machine*, forwarded with your own key, then billed at its
|
|
76
|
+
real usage. Cross the limit and the request comes back `402` with
|
|
77
|
+
`type: governer_breaker_tripped` — and your provider never sees it.
|
|
78
|
+
|
|
79
|
+
Streaming passes straight through — governer adds `stream_options.include_usage`
|
|
80
|
+
so the final usage block still arrives and the stream can be billed. Unpriced models
|
|
81
|
+
fall back to `--default-in/--default-out`, which is also how you *shadow-price* a
|
|
82
|
+
free model to see what it would have cost:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
✓ 200 nvidia/nemotron-3.5-lightning:free $0.001230 $0.0012/$5.00
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
When the provider reports its own `cost` field, governer compares it against
|
|
89
|
+
its own number and warns when `prices.json` has gone stale.
|
|
90
|
+
|
|
91
|
+
### Budgets per agent, per day
|
|
92
|
+
|
|
93
|
+
One proxy, several caps. Copy `governer.example.json` and pass it:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"limit": 20.0,
|
|
98
|
+
"ledger": "spend.jsonl",
|
|
99
|
+
"notify": "https://ntfy.sh/your-topic",
|
|
100
|
+
"agents": {
|
|
101
|
+
"claude-code": { "limit": 5.0, "per": "day" },
|
|
102
|
+
"ci": { "limit": 2.0, "per": "run" }
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
governer proxy --config governer.example.json
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The agent names itself with a header — `X-Governer-Agent: claude-code` — and the
|
|
112
|
+
cap applies to it alone. `day` resets at UTC midnight, `run` lasts the process.
|
|
113
|
+
Both are rebuilt from the ledger on restart, so bouncing the proxy cannot reset a
|
|
114
|
+
budget. `notify` receives a POST when the breaker trips.
|
|
115
|
+
|
|
116
|
+
### Watch for a week before you enforce
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
governer proxy --limit 20 --dry-run --ledger spend.jsonl
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Dry run books the true spend and refuses nothing, so you learn what a normal week
|
|
123
|
+
costs before a cap starts costing you work. Anything it would have refused is
|
|
124
|
+
marked `◌` in the console.
|
|
125
|
+
|
|
126
|
+
## Audit a log you already have
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
$ governer check usage.json --limit 20
|
|
130
|
+
requests 100
|
|
131
|
+
true cost $52.00
|
|
132
|
+
cache miss 100 request(s) billed uncached while sending ≥10k tokens
|
|
133
|
+
$43.20 of that was avoidable — ~83% of the bill
|
|
134
|
+
at $20.00 cap: stopped at request 39, $32.24 never spent (62% saved)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Reads Anthropic (`input_tokens`), OpenAI (`prompt_tokens`) and OpenRouter
|
|
138
|
+
(`cached_tokens`) field names, as a JSON array or JSONL.
|
|
139
|
+
|
|
140
|
+
## It prices models nobody told it about
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
$ governer prices --refresh
|
|
144
|
+
459 models refreshed from https://openrouter.ai/api/v1
|
|
145
|
+
free right now: 20
|
|
146
|
+
vendor-confirmed cache pricing: 313
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Curated entries are hand-verified, each with a date and a source. Everything
|
|
150
|
+
else is pulled live, so an agent that switches to a model released last week
|
|
151
|
+
still gets priced — instead of silently costing nothing in your ledger because
|
|
152
|
+
nobody typed it into a table.
|
|
153
|
+
|
|
154
|
+
## Gate a pull request on cost
|
|
155
|
+
|
|
156
|
+
```yaml
|
|
157
|
+
- uses: Kaiser0733/governer@main
|
|
158
|
+
with:
|
|
159
|
+
usage-file: ci/agent-usage.json
|
|
160
|
+
budget: "2.50"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`governer check --fail-over 2.50` exits `1` when the run costs more. Tests
|
|
164
|
+
should not be the only thing a PR can fail.
|
|
165
|
+
|
|
166
|
+
## The meter, not just the wall
|
|
167
|
+
|
|
168
|
+
A hard cap alone does not fix behaviour — it just moves the spending to the last week
|
|
169
|
+
of the month. The number has to be in front of you while you decide whether to kick off
|
|
170
|
+
another run.
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
$ governer status spend.jsonl --limit 20
|
|
174
|
+
spent $2.40 of $20.00 (12% used)
|
|
175
|
+
burn rate $0.40/h over 6.0h
|
|
176
|
+
projected $9.60/day at this rate
|
|
177
|
+
runs out in 44.0h at this rate
|
|
178
|
+
agent claude-code $2.10
|
|
179
|
+
agent ci $0.30
|
|
180
|
+
chain OK — 3 records · $2.4000 · chain intact
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
It refuses to project from a window shorter than 30 minutes, because extrapolating three
|
|
184
|
+
records in the same minute produces confident nonsense.
|
|
185
|
+
|
|
186
|
+
## Why this instead of the other options
|
|
187
|
+
|
|
188
|
+
| option | what it covers | what it misses |
|
|
189
|
+
|---|---|---|
|
|
190
|
+
| provider credit / key limits | a hard stop per account | not per agent, not cross-vendor, and it is exactly the layer that failed the $38k case |
|
|
191
|
+
| an in-process library (`budget-guard`, npm) | a cap inside one Node app | one language, needs a code change, no help for a CLI agent you did not write |
|
|
192
|
+
| an agent runtime with budgets (`cx`, Claude Extender) | caps for agents inside that runtime | requires adopting the whole runtime |
|
|
193
|
+
| gateway budgets (litellm, OmniRoute) | budget fields in the gateway | enforcement is soft, and litellm's was silently bypassed (#26672) |
|
|
194
|
+
| **governer** | any client in any language, no code change, cross-vendor, cache-aware pricing, tamper-evident ledger, CI gate, audit of logs you already have | one process per ledger — do not point two proxies at the same file |
|
|
195
|
+
|
|
196
|
+
## Why the bill explodes at night
|
|
197
|
+
|
|
198
|
+
- **1M-token contexts are table stakes**, so the cached prefix is replayed on
|
|
199
|
+
every call. Cache reads dominate agent bills — and they are billed even when
|
|
200
|
+
that content is truncated before the model attends to it.
|
|
201
|
+
- **"Prompt caching is supported" is not "your stack is caching."** The
|
|
202
|
+
expensive failure is silent: status 200, normal-looking output, invoice 100×.
|
|
203
|
+
- **Alerts are not limits.** Email after the money is gone is not a safety
|
|
204
|
+
mechanism, and neither are credits or a dashboard you check on Mondays.
|
|
205
|
+
|
|
206
|
+
## Receipts
|
|
207
|
+
|
|
208
|
+
The spend ledger is append-only and hash-chained: every record carries the hash
|
|
209
|
+
of the one before it, so editing a number breaks the chain and `verify` says so.
|
|
210
|
+
Tamper-evident bookkeeping, because a budget you can quietly rewrite is not a
|
|
211
|
+
budget.
|
|
212
|
+
|
|
213
|
+
## Prices are data, not truth
|
|
214
|
+
|
|
215
|
+
Every model in `prices.json` carries a `verified` date and a source. Cache
|
|
216
|
+
prices marked `~` are derived from the vendor convention (0.1× read, 1.25×
|
|
217
|
+
write) rather than confirmed. Re-verify before betting a number that matters,
|
|
218
|
+
and open a PR when a vendor moves.
|
|
219
|
+
|
|
220
|
+
## Roadmap
|
|
221
|
+
|
|
222
|
+
- ~~v0.2~~ proxy, live `free` check, CI gate — shipped
|
|
223
|
+
- ~~v0.5~~ price table refreshed from the gateway instead of hand-maintained — shipped
|
|
224
|
+
- **v0.3** per-agent and per-workflow budgets on one proxy
|
|
225
|
+
- **v0.4** phone push the second a breaker trips
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
**Docs and demo:** https://kaiser0733.github.io/governer/
|
|
230
|
+
|
|
231
|
+
MIT. Built by [Kaiser0733](https://github.com/Kaiser0733) at Vastraa Labs.
|