Skip to content

fix(cost): exempt BYOK inference from the managed-credit budget - #5218

Merged
M3gA-Mind merged 3 commits into
tinyhumansai:mainfrom
M3gA-Mind:fix/GH-5016-byok-budget-exemption
Jul 27, 2026
Merged

M3gA-Mind merged 3 commits into
tinyhumansai:mainfrom
M3gA-Mind:fix/GH-5016-byok-budget-exemption

Conversation

@M3gA-Mind

@M3gA-Mind M3gA-Mind commented Jul 27, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • The local [cost] daily/monthly limits now apply to managed (OpenHuman-credit) inference only. Bring-your-own-key and local inference is still recorded and still shown in usage totals, but can no longer refuse a request.
  • A pure-BYOK user has zero managed spend, so the "You're out of credits" gate is structurally unreachable for them.
  • The billing route is derived from the model id each record already carries, so existing history classifies correctly with no migration — an affected user is unblocked the moment they upgrade.
  • The dashboard budget gauge (budget_utilization / budget_status) also narrows to managed spend; month_to_date_usd, period_total_usd and by_model stay all-route totals.
  • Real managed-credit exhaustion is untouched — it is enforced server-side and surfaces through the backend's own billing error.

Problem

Reported by two users with no OpenHuman credits configured, routing all inference through their own keys (OpenRouter, plus a self-hosted OpenAI-compatible gateway). Both were refused service at a $10/day limit they never set, for inference OpenHuman never billed them for.

The chain, traced end to end:

  1. CostConfig defaults to enabled: true, daily_limit_usd: 10.00, monthly_limit_usd: 100.00 (config/schema/identity_cost.rs) — enforcement is on by default with no UI toggle, which is why BYOK configured (OpenRouter + OmniRoute fallback), but token usage counter keeps increasing with a phantom $10/day limit #5016 could not find where the limit was configured.
  2. BYOK providers echo no charged_amount_usd, so the recording sites price the call locally from cost::catalog (agent/harness/subagent_runner/ops/graph.rs, tinyagents/observability.rs) and persist that estimate as spend.
  3. CostStorage aggregated every record into a single daily/monthly figure, and CostTracker::check_budget compared that figure against the managed-credit limit.
  4. CostBudgetMiddleware::before_model turned BudgetCheck::Exceeded into LimitExceeded("cost budget exceeded: Day spend $10.0136 ≥ limit $10.0000") — the exact string in You're out of credits #5127's screenshot.
  5. web_chat::web_errors matches that on r"budget.*exceed" and renders "You're out of credits, so I can't run the managed (cloud) model right now."

So the counter, the phantom limit, and the refusal message in both reports are one bug: a managed-credit cap applied to spend that was never charged.

Solution

New src/openhuman/cost/route.rs — CostRoute::{Managed, Byok} and route_for_model(). CostStorage keeps its existing all-route aggregates for reporting and adds a managed-only subset; check_budget reads the managed subset. Everything else about recording is unchanged.

Why the route is derived rather than stored. Managed inference is addressed by the backend's own tier slugs (chat-v1, agentic-v1, …); a BYOK provider is always addressed by a real model id (minimax/minimax-m3, llama3:8b), because the tier vocabulary only means anything to the managed backend. Every recording site and every persisted record already carries the model id, so:

  • no call site has to learn about routing, and
  • records written by older builds classify correctly with no migration.

A stored route field would have had to pick a serde default for every pre-existing record, and both options are bad: defaulting to Managed leaves affected users blocked for up to a month on the monthly limit — i.e. it would not actually fix the reported incident on upgrade — while defaulting to BYOK silently discards real managed history. Deriving from data that already exists sidesteps the choice entirely. legacy_byok_records_are_exempt_after_an_aggregate_rebuild pins this.

Failure direction. Unknown model ids classify as Byok. The consequence of a wrong guess is under-enforcing a local convenience cap, never over-charging — actual credit exhaustion is enforced by the backend. Matching is exact after normalising case/whitespace and stripping hint: / openhuman/ prefixes; a_byok_model_merely_containing_a_tier_name_is_not_managed guards against a substring match quietly re-introducing the bug.

Budget gauge. budget_utilization and budget_status describe a limit that now only gates managed spend, so driving them off the all-route total would leave a BYOK user's gauge pinned at 100% against a cap that can never fire — the same phantom limit, just rendered. They now use managed month-to-date. Spend figures themselves stay all-route: #5016 explicitly wanted to understand his usage, not lose sight of it.

Out of scope: the billing/credits system itself, backend credit accounting, and any change to how BYOK spend is estimated.

Submission Checklist

If a section does not apply to this change, mark the item as N/A with a one-line reason.

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — changed lines (Vitest + cargo-llvm-cov merged via diff-cover) meet the gate enforced by .github/workflows/ci-lite.yml. Run pnpm test:coverage and pnpm test:rust locally; PRs below 80% on changed lines will not merge. — every changed line is exercised by the 13 tests below; the local suites were not run (see "Validation Blocked"), so the CI coverage lane is the authority here.
  • Coverage matrix updated — added/removed/renamed feature rows in docs/TEST-COVERAGE-MATRIX.md reflect this change (or N/A: behaviour-only change) — N/A: behaviour-only change; no feature added, removed or renamed, and the matrix has no cost/budget row.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related — N/A: the matrix contains no cost/budget feature ID; stated under ## Related rather than inventing one.
  • No new external network dependencies introduced (mock backend used per Testing Strategy) — pure in-process logic over a TempDir JSONL store; no network at all.
  • Manual smoke checklist updated if this touches release-cut surfaces (docs/RELEASE-MANUAL-SMOKE.md) — N/A: no new surface; this removes an incorrect refusal on an existing path.
  • Linked issue closed via Closes #NNN in the ## Related section — uses the equivalent Fixes #5016 / Fixes #5127.

Impact

  • Platform: Rust core only. No frontend, Tauri, CLI, or schema changes.
  • User-visible: BYOK-only users stop being refused with "You're out of credits", and their budget gauge stops filling from spend that cannot gate them. Their usage figures are unchanged and still visible.
  • Managed users: unchanged. Managed spend still counts and still gates, at the same limits — budget_exceeded_daily_limit / budget_monthly_exceeded still pass, retargeted to a managed tier id.
  • Mixed users (BYOK chat + managed background workloads): only the managed portion can trip the limit; pinned by managed_spend_still_gates_when_byok_spend_is_also_present.
  • Data/migration: none. No persisted schema change; costs.jsonl is read and written exactly as before.
  • Security/perf: the managed aggregate is computed in the existing single pass over records; get_managed_cost_for_month adds one scan on the dashboard path only, matching the existing get_cost_for_month. No secrets or PII in the new debug log (USD figures only).
  • Risk of under-enforcement: a model id not recognised as a managed tier stops counting toward the local cap. Bounded by the drift-guard test, and the backend remains the authority on real credits.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

Commit & Branch

  • Branch: fix/GH-5016-byok-budget-exemption
  • Commit SHA: 0e3b73137

Validation Run

  • pnpm --filter openhuman-app format:check — N/A: no files under app/ changed.
  • pnpm typecheck — N/A: no TypeScript changed.
  • Focused tests: written but not executed locally — see "Validation Blocked". 13 tests: 6 in cost/route.rs (tier slugs classify managed; drift guard against the backend tier constants; the reported BYOK/local model shapes classify BYOK; case/whitespace/hint:/openhuman/ normalisation; substring near-misses stay BYOK; only managed counts) and 7 in cost/tracker_tests.rs (BYOK exempt from the daily limit, the monthly limit and the warning threshold; BYOK still recorded for the dashboard; mixed managed+BYOK gates only on the managed portion; legacy pre-upgrade BYOK history exempt after an aggregate rebuild; dashboard gauge managed-only while spend totals stay complete).
  • Rust fmt/check (if changed): cargo fmt --check clean. cargo check --lib was clean over the classifier, storage fields, aggregate rebuild and the check_budget switch; the later hunks were not re-compiled locally — see below.
  • Tauri fmt/check (if changed): N/A: no files under app/src-tauri/ changed.

Validation Blocked

  • command: cargo test --lib cost:: / cargo check --tests
  • error: not attempted — local compile and test runs were explicitly disallowed on this machine part-way through the change (shared-host load), so verification was stopped and handed to CI.
  • impact: Moderate and specific, stated plainly. cargo check --lib passed over the bulk of the non-test change, and one cargo test --lib cost:: run that was already in flight reported exactly one error — a private-module import in route.rs's test module — which means everything else in the lib and test tree compiled. That import was corrected to crate::openhuman::config::{…}, the path inference/provider/factory.rs already uses. Edits made after that point (the corrected import, two small route.rs simplifications, doc comments in identity_cost.rs) have not been compiled. cargo fmt --check passes, so every file is at least syntactically valid. If a lane fails, it will be one of these; I will fix on the PR.

Behavior Changes

  • Intended behavior change: the local [cost] daily/monthly budget gates managed (OpenHuman-credit) inference only; BYOK and local inference is recorded but never gated.
  • User-visible effect: a BYOK-only user is no longer told "You're out of credits" by the local cap, and their budget gauge reflects only spend that can actually gate them. Usage totals are unchanged.

Parity Contract

  • Legacy behavior preserved: managed spend counts and gates exactly as before, at the same defaults; all-route totals (get_summary, get_monthly_cost, get_daily_history, month_to_date_usd, period_total_usd, by_model) are byte-for-byte unchanged; cost.enabled = false still short-circuits enforcement first; recording behaviour and the persisted JSONL format are untouched.
  • Guard/fallback/dispatch parity checks: unknown model ids fall back to Byok (under-enforce a local cap rather than over-charge); legacy records classify from the model id they already store, so no migration and no default-guessing; managed_tier_slugs_stay_in_sync fails if a backend tier is added upstream without being classified, so managed spend cannot silently stop counting; server-side credit enforcement is not touched by any of this.

Duplicate / Superseded PR Handling

Summary by CodeRabbit

  • New Features

    • Added billing-route classification for managed and BYOK inference.
    • Budget limits and warnings now apply only to managed inference.
    • BYOK and local inference remain recorded for usage dashboards without being blocked.
    • Budget dashboards now show managed inference spend separately from total recorded usage.
  • Bug Fixes

    • Corrected budget tracking for mixed managed and BYOK usage.
    • Preserved correct handling of previously recorded BYOK usage.

The local [cost] daily/monthly limits exist to cap spend against OpenHuman
credits, but they were enforced against every recorded call. A user routing
all inference through their own key accrued phantom spend and was refused
service at the default $10/day cap for inference OpenHuman never billed:

  - BYOK providers echo no charged_amount_usd, so the recording sites price
    the call locally from cost::catalog and persist that as spend.
  - CostStorage aggregated every record into one daily/monthly figure and
    check_budget compared it against the managed-credit limit.
  - CostBudgetMiddleware turned Exceeded into "cost budget exceeded: Day
    spend ... >= limit ...", which web_errors classifies as budget-exhausted
    and renders as "You're out of credits".

Split the aggregates by billing route and gate on the managed subset only.
A pure-BYOK user has zero managed spend, so the gate is now structurally
unreachable for them. Real managed-credit exhaustion is unaffected: it is
enforced server-side and surfaces through the backend's own billing error.

The route is derived from the model id each record already carries (managed
= the backend tier slugs; BYOK is always a real provider id such as
minimax/minimax-m3) rather than stored as a new field. Persisted history
therefore classifies correctly with no migration, which unblocks an
affected user on upgrade instead of making them wait out the window; a
stored field would have had to guess a default for every existing record.
Unknown ids classify as BYOK, so the failure direction is under-enforcing a
local convenience cap rather than over-charging.

BYOK spend is still recorded and still shown in usage totals - the reporter
wanted to understand the counter, not lose it. Only the budget gauge and
the enforcement gate are narrowed to managed spend, since a gauge filling
to 100% against a cap that can never fire is the same phantom limit.

Fixes tinyhumansai#5016
Fixes tinyhumansai#5127
@M3gA-Mind
M3gA-Mind requested a review from a team July 27, 2026 14:48
@M3gA-Mind

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 17 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dfd3a8d6-3b96-4473-b3cb-d0d6afe1085e

📥 Commits

Reviewing files that changed from the base of the PR and between 0e3b731 and de31e8d.

📒 Files selected for processing (4)
  • src/openhuman/cost/route.rs
  • src/openhuman/cost/tracker.rs
  • src/openhuman/cost/tracker_tests.rs
  • src/openhuman/tinyagents/middleware.rs
📝 Walkthrough

Walkthrough

Managed and BYOK/local inference are now classified separately. Budget enforcement and dashboard utilization use managed-route costs, while all-route usage remains recorded and visible. Storage maintains both aggregate categories, with tests covering normalization, exemptions, mixed usage, legacy records, and dashboard states.

Changes

Managed-route budget enforcement

Layer / File(s) Summary
Route classification contract
src/openhuman/cost/route.rs, src/openhuman/cost/mod.rs
Adds managed/BYOK route classification, model normalization, budget-counting behavior, public exports, and unit tests.
Managed cost aggregation
src/openhuman/cost/tracker.rs
Tracks managed daily and monthly aggregates during rebuilds, incremental updates, and monthly cost queries.
Budget and dashboard behavior
src/openhuman/config/schema/identity_cost.rs, src/openhuman/cost/tracker.rs, src/openhuman/cost/tracker_tests.rs
Uses managed costs for budget gates and utilization while retaining all-route reporting, with coverage for BYOK, mixed usage, legacy records, and dashboard states.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • tinyhumansai/openhuman#5016 — The changes implement managed-only budget enforcement and BYOK exemption behavior.

Suggested labels: bug

Suggested reviewers: sanil-23, codeghost21, al629176

Poem

I’m a rabbit with routes in my basket,
Managed costs now answer the casket.
BYOK still shines,
In dashboard lines,
While budget gates do what we ask it.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: BYOK inference is exempted from managed-credit budget enforcement.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0e3b73137e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/openhuman/cost/tracker.rs
Comment thread src/openhuman/cost/route.rs
@greptile-apps

greptile-apps Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

Greptile Summary

This PR fixes a regression where BYOK (bring-your-own-key) and local inference spend — locally estimated because BYOK providers don't echo charged_amount_usd — was incorrectly accumulated against the managed-credit daily/monthly cap, causing pure-BYOK users to hit a $10/day "You're out of credits" wall for inference OpenHuman never billed for.

  • Introduces cost/route.rs with CostRoute::{Managed, Byok} and route_for_model(), which derives the billing route from the model ID already present on every record — no schema change, and pre-existing BYOK records are reclassified correctly on first rebuild_aggregates call post-upgrade.
  • CostStorage grows two parallel managed-only accumulators (daily_managed_cost_usd, monthly_managed_cost_usd); check_budget and the dashboard's budget_utilization/budget_status now read the managed subset, while all all-route totals (month_to_date_usd, by_model, etc.) remain unchanged.
  • CostBudgetMiddleware::before_model gains an early-return that skips the gate entirely for BYOK requests by route-checking the in-flight model ID, preventing a mixed-route user's BYOK calls from being blocked once legitimate managed spend has crossed the cap.

Confidence Score: 5/5

Safe to merge — the fix is well-scoped, all-route dashboard totals are untouched, and legacy BYOK records reclassify correctly without a migration.

The change narrows the budget gate to managed spend only via two independent layers (middleware early-return and tracker aggregate), both covered by tests. The normalization loop correctly handles the prefix-ordering bug raised in a previous review. Existing managed-user behaviour is unchanged: the managed accumulators are a strict additive split of the existing aggregates, and the all-route totals exposed to the dashboard are byte-for-byte identical to the pre-PR path.

Files Needing Attention: No files require special attention. Worth noting post-merge: get_dashboard calls get_managed_monthly_cost (a full file scan) for data already cached in monthly_managed_cost_usd, making it a second scan alongside the existing get_cost_for_month scan — not a correctness issue, but worth optimising if costs.jsonl grows large.

Important Files Changed

Filename Overview
src/openhuman/cost/route.rs New classification module — CostRoute enum, MANAGED_MODEL_SLUGS constant, route_for_model(), and normalize_model_id() loop (order-independent prefix stripping). Six unit tests including a drift-guard against the upstream tier constants. Previous review concern about single-pass prefix ordering is resolved by the loop approach.
src/openhuman/cost/tracker.rs Core change: adds daily_managed_cost_usd/monthly_managed_cost_usd accumulators to CostStorage, threads managed-only classification through rebuild_aggregates and add_record, and switches check_budget and budget_utilization/budget_status to use managed-only totals. Debug logging is now correctly guarded with a tracing::enabled! check.
src/openhuman/tinyagents/middleware.rs Adds an early-return in before_model that skips the budget gate for BYOK/local routes by classifying request.model; handles the mixed-route user case where legitimate managed exhaustion must not block a BYOK in-flight call.
src/openhuman/cost/tracker_tests.rs Seven new integration tests covering: BYOK exempt from daily/monthly limit and warning threshold; BYOK still visible in dashboard totals; mixed managed+BYOK only gates on managed portion; legacy pre-upgrade BYOK records exempt after aggregate rebuild; dashboard budget gauge reflects managed spend only.
src/openhuman/cost/mod.rs Adds pub mod route declaration and re-exports route_for_model and CostRoute at the cost crate level.
src/openhuman/config/schema/identity_cost.rs Doc-comment-only update clarifying that daily_limit_usd and monthly_limit_usd apply to managed inference only.

Sequence Diagram

sequenceDiagram
    participant App as Inference Request
    participant MW as CostBudgetMiddleware
    participant Router as route_for_model()
    participant CT as CostTracker
    participant Storage as CostStorage (JSONL)

    Note over App,Storage: BYOK / local model path (e.g. "minimax/minimax-m3")
    App->>MW: before_model(request)
    MW->>Router: route_for_model(request.model)
    Router-->>MW: CostRoute::Byok
    MW-->>App: Ok() — budget gate skipped entirely

    Note over App,Storage: Managed tier path (e.g. "chat-v1")
    App->>MW: before_model(request)
    MW->>Router: route_for_model(request.model)
    Router-->>MW: CostRoute::Managed
    MW->>CT: check_budget(0.0)
    CT->>Storage: get_aggregated_managed_costs()
    Note right of Storage: reads daily_managed_cost_usd<br/>& monthly_managed_cost_usd<br/>(BYOK spend excluded)
    Storage-->>CT: (managed_daily_usd, managed_monthly_usd)
    CT-->>MW: BudgetCheck::Allowed or Exceeded
    MW-->>App: Ok() or LimitExceeded error

    Note over App,Storage: Record phase (both routes)
    App->>CT: record_usage(usage)
    CT->>Storage: add_record(record)
    Note right of Storage: all-route totals updated always<br/>managed totals updated only<br/>if route_for_model → Managed
Loading

Reviews (3): Last reviewed commit: "fix(cost): exempt the current BYOK reque..." | Re-trigger Greptile

Comment thread src/openhuman/cost/route.rs
Comment thread src/openhuman/cost/tracker.rs Outdated
Comment thread src/openhuman/cost/route.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/openhuman/cost/tracker.rs (2)

339-340: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Two full scans of costs.jsonl where one would do.

get_monthly_cost and get_managed_monthly_cost each take the lock and iterate every record in the append-only store; combined with get_daily_history(7) above, get_dashboard now makes three full passes. The store has no rotation, so this grows unbounded with workspace age.

A single CostStorage::get_month_costs(year, month) -> (all, managed) accumulating both in one for_each_record closure removes the added pass.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/cost/tracker.rs` around lines 339 - 340, Replace the separate
get_monthly_cost and get_managed_monthly_cost calls in get_dashboard with a
single CostStorage::get_month_costs(year, month) operation that scans records
once and returns both totals; preserve the existing month-to-date values and
error propagation.

78-88: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Log the decision, not just the inputs.

The debug line fires before any branch, so a refusal (Exceeded) or Warning leaves no grep-able record of which limit tripped and on which route. Given this is the exact flow that produced the phantom "out of credits" reports, emitting the outcome makes future reports diagnosable from logs alone.

As per coding guidelines, new or changed flows must include verbose, grep-friendly diagnostics covering entry/exit, branches, and state transitions.

♻️ Sketch: log the exceeded/warning branches
         let projected_daily = daily_cost + estimated_cost_usd;
         if projected_daily > self.config.daily_limit_usd {
+            tracing::debug!(
+                current_usd = daily_cost,
+                limit_usd = self.config.daily_limit_usd,
+                "[cost] budget check exit=exceeded period=day route=managed"
+            );
             return Ok(BudgetCheck::Exceeded {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/cost/tracker.rs` around lines 78 - 88, Update the budget-check
flow surrounding the existing tracing::debug! call to emit grep-friendly
diagnostics for each decision outcome, including whether the result is exceeded,
warning, or allowed, which limit triggered it, and the affected route. Cover the
relevant branches and final state transition so logs capture the decision rather
than only the cost inputs, while preserving the existing cost calculations and
behavior.

Source: Coding guidelines

src/openhuman/cost/tracker_tests.rs (1)

250-434: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider splitting the route-exemption tests into their own file.

This addition pushes tracker_tests.rs well past 584 lines. The BYOK/managed cluster is cohesive enough to live in e.g. tracker_route_tests.rs alongside the shared dated_record / write_raw_record helpers.

As per coding guidelines, keep files preferably at or below approximately 500 lines and favor small, single-responsibility modules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/cost/tracker_tests.rs` around lines 250 - 434, Move the
cohesive BYOK/managed route-exemption tests, including the tests beginning with
byok_spend_* and managed_spend_still_gates_when_byok_spend_is_also_present, into
a dedicated tracker_route_tests.rs module. Reuse or expose the existing
dated_record and write_raw_record helpers there, and update module
declarations/imports so the tests compile while tracker_tests.rs remains within
the preferred size.

Source: Coding guidelines

src/openhuman/cost/route.rs (1)

40-60: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the tier sync check exhaustive

managed_tier_slugs_stay_in_sync only covers the hand-written upstream array, so a new MODEL_*_V1 constant can be added in crate::openhuman::config::schema::types without tripping this test. Export a single authoritative tier slice from crate::openhuman::config and derive the check from that source so adding a tier forces an update here too.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/openhuman/cost/route.rs` around lines 40 - 60, Export a single
authoritative slice of all managed tier slugs from crate::openhuman::config,
then update managed_tier_slugs_stay_in_sync to compare MANAGED_MODEL_SLUGS
against that exported slice rather than a hand-written upstream array. Ensure
the authoritative slice includes every MODEL_*_V1 constant so adding a new tier
makes the sync test fail until this local billing list is updated.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/openhuman/cost/tracker.rs`:
- Around line 333-345: Update the CostDashboard utilization documentation near
budget_utilization to state that it is calculated from managed monthly spend,
not month_to_date_usd. Keep the month_to_date_usd documentation describing the
all-route total and ensure the documented contract matches the
managed_month_to_date_usd calculation.

---

Nitpick comments:
In `@src/openhuman/cost/route.rs`:
- Around line 40-60: Export a single authoritative slice of all managed tier
slugs from crate::openhuman::config, then update managed_tier_slugs_stay_in_sync
to compare MANAGED_MODEL_SLUGS against that exported slice rather than a
hand-written upstream array. Ensure the authoritative slice includes every
MODEL_*_V1 constant so adding a new tier makes the sync test fail until this
local billing list is updated.

In `@src/openhuman/cost/tracker_tests.rs`:
- Around line 250-434: Move the cohesive BYOK/managed route-exemption tests,
including the tests beginning with byok_spend_* and
managed_spend_still_gates_when_byok_spend_is_also_present, into a dedicated
tracker_route_tests.rs module. Reuse or expose the existing dated_record and
write_raw_record helpers there, and update module declarations/imports so the
tests compile while tracker_tests.rs remains within the preferred size.

In `@src/openhuman/cost/tracker.rs`:
- Around line 339-340: Replace the separate get_monthly_cost and
get_managed_monthly_cost calls in get_dashboard with a single
CostStorage::get_month_costs(year, month) operation that scans records once and
returns both totals; preserve the existing month-to-date values and error
propagation.
- Around line 78-88: Update the budget-check flow surrounding the existing
tracing::debug! call to emit grep-friendly diagnostics for each decision
outcome, including whether the result is exceeded, warning, or allowed, which
limit triggered it, and the affected route. Cover the relevant branches and
final state transition so logs capture the decision rather than only the cost
inputs, while preserving the existing cost calculations and behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 081e1a1f-4db9-4e5c-bd1e-8f30fd544db0

📥 Commits

Reviewing files that changed from the base of the PR and between 35f3b1c and 0e3b731.

📒 Files selected for processing (5)
  • src/openhuman/config/schema/identity_cost.rs
  • src/openhuman/cost/mod.rs
  • src/openhuman/cost/route.rs
  • src/openhuman/cost/tracker.rs
  • src/openhuman/cost/tracker_tests.rs

Comment thread src/openhuman/cost/tracker.rs
…ai#5016)

Both BYOK budget tests failed in CI. The implementation is correct — the
assertions were over-specified.

They called `check_budget(0.01)` against a $0.01 limit, i.e. charging the
entire cap to the current request. With BYOK history correctly excluded the
managed total is $0.00, so the request is NOT blocked, but projecting the
current request's own $0.01 lands at 100% of the limit and trips the 80%
warning. The tests then read that `Warning` as a failure.

`Warning` explicitly means "request can proceed"; only `Exceeded` gates.
So estimate 0.0 (what `CostBudgetMiddleware::before_model` actually passes,
and what the sibling warning-threshold test already used) for the `Allowed`
assertion, and pin the real guarantee separately: even a request consuming
the whole remaining limit is never `Exceeded` because of BYOK history.
@M3gA-Mind

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

…yhumansai#5016)

P1 (Codex) — the exemption was only half applied. Excluding BYOK from the
managed *totals* still refused a mixed-route user's own-key calls once their
managed spend had legitimately crossed the cap: `CostBudgetMiddleware::
before_model` ignored the request and asked `check_budget(0.0)`, which
answers from managed totals alone with no idea what route the current call
takes. Managed exhaustion therefore disabled the provider OpenHuman never
bills for — exactly the bug this issue is about. The middleware now classifies
the current request's model via `route_for_model` and skips the gate when
OpenHuman is not the biller.

P2 (Greptile) — `normalize_model_id` stripped `hint:` then `openhuman/` in a
fixed order, so `openhuman/hint:chat-v1` normalized to `hint:chat-v1` and
classified as BYOK while `hint:openhuman/chat-v1` classified as Managed.
Managed spend could silently stop counting toward the cap depending only on
which decoration a recording site applied first. Stripping now loops until
neither prefix applies, making the two order-independent, with tests pinning
both orders in both directions.

P2 (Greptile) — the all-routes aggregate was computed on every budget check
purely to populate a debug log (tracing evaluates fields eagerly). It is now
behind a `tracing::enabled!` guard.
@M3gA-Mind

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@M3gA-Mind
M3gA-Mind merged commit 0639478 into tinyhumansai:main Jul 27, 2026
21 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in Team Openhuman Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

You're out of credits BYOK configured (OpenRouter + OmniRoute fallback), but token usage counter keeps increasing with a phantom $10/day limit

1 participant