Commit a09545a
feat: cost tracking and estimation — per-call tracking, budget caps, pre-run estimates (Milestone #16)
- quorum/cost.py: CostTracker (thread-safe, thread-local file context), CallRecord,
CostSummary, CostEstimate Pydantic models, BudgetExceededError, estimate_cost()
with hardcoded rates for Claude/GPT/Gemini/Mistral, _FALLBACK_RATE for unknowns
- providers/base.py: BaseProvider.__init__ accepts optional cost_tracker
- providers/litellm_provider.py: extracts token usage + calls litellm.completion_cost()
after each complete() call; handles None/exception from completion_cost gracefully
- config.py: max_cost: float | None = None field on QuorumConfig
- pipeline.py: CostTracker created per run_validation() and shared across
run_batch_validation() workers; budget check after critics (single) and after
each file (batch) via BudgetExceededError; cost added to run-manifest.json and
batch-manifest.json with per-file breakdown; progressive running_cost_usd in
batch manifests
- cli.py: --max-cost USD flag, --yes/-y flag, pre-run cost estimate with
conditional confirm prompt (skipped when < $0.50 or --yes), post-run cost
summary (Cost: $X.XXXX, per-file breakdown)
- tests/test_cost.py: 33 tests covering thread safety, budget caps, model rates,
estimate accuracy, provider integration, graceful error handling
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1 parent 6e8c553 commit a09545a
7 files changed
Lines changed: 968 additions & 4 deletions
File tree
- reference-implementation
- quorum
- providers
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
125 | 125 | | |
126 | 126 | | |
127 | 127 | | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
128 | 141 | | |
129 | 142 | | |
130 | 143 | | |
| |||
137 | 150 | | |
138 | 151 | | |
139 | 152 | | |
| 153 | + | |
| 154 | + | |
140 | 155 | | |
141 | 156 | | |
142 | 157 | | |
| |||
221 | 236 | | |
222 | 237 | | |
223 | 238 | | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
224 | 243 | | |
225 | 244 | | |
226 | 245 | | |
| |||
241 | 260 | | |
242 | 261 | | |
243 | 262 | | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
244 | 266 | | |
245 | 267 | | |
246 | 268 | | |
| |||
253 | 275 | | |
254 | 276 | | |
255 | 277 | | |
| 278 | + | |
256 | 279 | | |
257 | 280 | | |
258 | 281 | | |
| |||
290 | 313 | | |
291 | 314 | | |
292 | 315 | | |
| 316 | + | |
293 | 317 | | |
294 | 318 | | |
295 | 319 | | |
| |||
598 | 622 | | |
599 | 623 | | |
600 | 624 | | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
| 704 | + | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
| 708 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
62 | 66 | | |
63 | 67 | | |
64 | 68 | | |
| |||
0 commit comments