ea967142df26ac768ab10830a95f91387e9a09c6
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
1b12af2765 |
fix(providers): enforce per-plan budget in FallbackSelector.select()
CI / lint (pull_request) Successful in 40s
CI / helm (pull_request) Successful in 35s
CI / build (pull_request) Successful in 56s
CI / quality (pull_request) Successful in 1m29s
CI / typecheck (pull_request) Successful in 1m36s
CI / security (pull_request) Successful in 1m35s
CI / push-validation (pull_request) Successful in 26s
CI / unit_tests (pull_request) Successful in 6m2s
CI / docker (pull_request) Successful in 1m44s
CI / integration_tests (pull_request) Successful in 9m56s
CI / coverage (pull_request) Successful in 12m16s
CI / status-check (pull_request) Successful in 17s
Imported CostMetadata into fallback_selector.py to access per-plan budget data. Extended FallbackSelector.__init__ with cost_metadata: CostMetadata | None = None and stored it in self._cost_metadata. Implemented per-plan budget check in FallbackSelector.select() immediately after the daily budget validation to enforce per-plan limits during selection. Added two new TDD scenarios to features/cost_controls.feature to exercise per-plan budget behavior, tagged @tdd_issue @tdd_issue_10471. Added new test steps at features/steps/tdd_fallback_plan_budget_steps.py to support the new scenarios. ISSUES CLOSED: #10485 |
||
|
|
5a3678cd6c |
fix(concurrency): protect CostTracker._daily_costs with a threading.Lock
CI / typecheck (pull_request) Successful in 59s
CI / security (pull_request) Successful in 54s
CI / quality (pull_request) Successful in 40s
CI / lint (pull_request) Successful in 3m21s
CI / build (pull_request) Successful in 17s
CI / helm (pull_request) Successful in 21s
CI / unit_tests (pull_request) Successful in 6m50s
CI / e2e_tests (pull_request) Successful in 19m16s
CI / docker (pull_request) Successful in 1m21s
CI / integration_tests (pull_request) Successful in 21m37s
CI / coverage (pull_request) Successful in 14m51s
CI / status-check (pull_request) Successful in 1s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Successful in 57m40s
The record_usage method performed an unprotected read-modify-write on _daily_costs, a classic TOCTOU race condition. In multi-threaded execution (ThreadPoolExecutor for parallel plan steps), two threads could interleave their .get() read and = write, causing one thread's cost increment to be silently overwritten by the other. Changes: - Add _daily_costs_lock: threading.Lock to CostTracker.__init__ - Wrap the read-modify-write in record_usage with self._daily_costs_lock - Protect reads in check_daily_budget and get_daily_spend with the same lock - Add Behave @concurrency scenario: 20 threads concurrently call record_usage; final daily spend must equal the sum of all individual costs - Add Robot Framework integration smoke test via helper_cost_controls.py cost-tracker-concurrent command All accesses to _daily_costs are now lock-protected. nox -e typecheck passes with zero errors. Existing cost_controls tests continue to pass. ISSUES CLOSED: #1919 |
||
|
|
134dce896a |
feat(provider): add cost controls and fallback
CI / benchmark-publish (pull_request) Has been skipped
CI / build (pull_request) Successful in 17s
CI / lint (pull_request) Successful in 18s
CI / quality (pull_request) Successful in 20s
CI / security (pull_request) Successful in 34s
CI / typecheck (pull_request) Successful in 37s
CI / integration_tests (pull_request) Successful in 3m46s
CI / unit_tests (pull_request) Successful in 8m32s
CI / docker (pull_request) Successful in 39s
CI / benchmark-regression (pull_request) Successful in 19m26s
CI / coverage (pull_request) Successful in 31m23s
CI / lint (push) Successful in 13s
CI / build (push) Successful in 15s
CI / quality (push) Successful in 16s
CI / typecheck (push) Successful in 30s
CI / benchmark-regression (push) Has been skipped
CI / security (push) Successful in 33s
CI / integration_tests (push) Successful in 3m44s
CI / unit_tests (push) Successful in 8m53s
CI / docker (push) Successful in 1m1s
CI / benchmark-publish (push) Successful in 10m35s
CI / coverage (push) Successful in 37m55s
Add token/cost tracking, budget enforcement (per-plan and per-day), provider fallback selection with capability filtering, and cost metadata for plan models. New modules: - providers/cost_table.py: CostEntry + ProviderCostTable with default pricing for OpenAI, Anthropic, Google, Groq, Together, Cohere, Mock - providers/cost_tracker.py: BudgetStatus enum, BudgetCheckResult, CostTracker with warn-at-90%/block-at-100% enforcement - providers/fallback_selector.py: FallbackSelector with capability filtering (tool_calls, streaming, vision, json_mode) and budget - domain/models/core/cost_metadata.py: CostMetadata + BudgetExhaustionEvent Modified: - config/settings.py: budget_per_plan, budget_per_day, fallback_providers - domain/models/core/plan.py: cost_metadata field + CLI dict surfacing - providers/__init__.py: public exports for new classes Testing: - 71 Behave scenarios in features/cost_controls.feature (all pass) - 6 Robot Framework integration tests (all pass) - ASV benchmarks in benchmarks/cost_controls_bench.py - nox lint, typecheck, format, docs, build, dead_code, security_scan pass Closes #324 |