Skip to content

feat(billing): drop rate-limit UI, surface cycle usage insights - #2027

Merged
M3gA-Mind merged 9 commits into
tinyhumansai:mainfrom
senamakel:feat/drop-rate-limits-show-usage
May 19, 2026
Merged

M3gA-Mind merged 9 commits into
tinyhumansai:mainfrom
senamakel:feat/drop-rate-limits-show-usage

Conversation

@senamakel

@senamakel senamakel commented May 18, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Removes the 5-hour rate-limit UI (modal, countdown pill, banner branch, i18n copy) now that backend tinyhumansai/backend#790 made checkWindowAvailability and assertDailySpendAvailable no-ops.
  • Rebuilds the TeamUsage type + normalizer for the new GET /teams/me/usage shape (cycleSpentUsd, plan{}, insights{} with daily series + top-10 models/integrations).
  • Replaces the Settings → Billing inference panel with a cycle-spend breakdown, daily inference-vs-integrations chart, and top models/integrations rankings.
  • Refocuses PLANS and i18n on the per-call discount story (BASIC 50%, PRO 90%) instead of "X-hour cap" / "weekly limit" framing.

Problem

The backend dropped the rolling 5-hour window and daily-cap gates, so the app was still rendering UI for caps that no longer enforce. The /teams/me/usage response also reshaped — cycleLimit5hr, fiveHourCapUsd, fiveHourResetsAt, bypassCycleLimit, and cycleLimit7day are gone, replaced by cycleSpentUsd, a plan block, and an insights block. Without this PR the client over-reports caps users no longer hit, and the new spend-insights payload is wasted.

Solution

  • creditsApi.ts: rewrote TeamUsage + normalizeTeamUsage to the new contract (kept Rust handler unchanged — it's a JSON passthrough).
  • useUsageState: dropped isRateLimited / usagePct10h derivations; usagePct now derives from cycle budget alone.
  • UsageLimitModal.tsx deleted along with the composer-feedback showLimitModal flag. Budget exhaustion still surfaces inline.
  • Conversations.tsx: removed the 5h LimitPill, the rate-limit banner branch, and the modal mount. Cycle pill + tooltip now show cycleSpentUsd / cycleBudgetUsd / remainingUsd only.
  • AIPanel.tsx: swapped the "5h window" tile for "Cycle total spend" (inference + integration split) and pointed "Week remaining" detail at cycleSpentUsd.
  • InferenceBudget.tsx: rebuilt with cycle-spend bar, breakdown card, daily chart, top models, top integrations, and a discount badge driven by plan.discountVsPayAsYouGoPercent.
  • Home.tsx, TokenUsagePill.tsx, GlobalUpsellBanner.tsx: pruned rate-limit branches; use usagePct.
  • billingHelpers.ts + en/zh-CN/id i18n: rate-limit-flavoured strings out, cycle/discount strings in.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • N/A: Diff coverage gate is run by CI — local pnpm test passes 2500 tests; touched files all have updated unit tests for the new shape (creditsApi.test.ts, useUsageState.test.ts, AIPanel.test.tsx, Conversations.render.test.tsx, billingApi.test.ts, billingHelpers.test.ts, composerSendDecision.test.ts, Home.test.tsx).
  • N/A: behaviour-only change — billing feature row in TEST-COVERAGE-MATRIX is unchanged in scope (rate-limit gating UI was incidental, no matrix row).
  • N/A: no feature IDs touched by this PR.
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • N/A: not a release-cut surface — purely client-side rendering of an existing RPC.
  • N/A: no linked issue — driven by backend PR tinyhumansai/backend#790.

Impact

  • Runtime: desktop only; no Rust core changes (team_get_usage is already a JSON passthrough — the new shape flows through unchanged).
  • User-visible: in-app rate-limit modal and 5-hour countdown are gone. Budget-exhaustion banner remains. Settings → Billing now shows a richer cycle-insights panel.
  • Compatibility: depends on backend PR test(threads): harden JSON-RPC validation coverage #790 being deployed. With the old backend the new normalizer still produces safe defaults (zeroed insights, FREE plan summary) rather than crashing.
  • Migration: none.

Related

  • Closes: N/A
  • Follow-up PR(s)/TODOs: N/A

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

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/drop-rate-limits-show-usage
  • Commit SHA: 2ab8f7dfbc0f10f771a00b83bdb0e2a55bb05a66

Validation Run

  • pnpm --filter openhuman-app format:check
  • pnpm typecheck
  • Focused tests: pnpm --filter openhuman-app test -- --run — 2500 passed, 3 skipped
  • N/A: no Rust source changes (handler is a passthrough)
  • N/A: no Tauri shell changes

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: stop rendering 5-hour rate-limit UI and expose cycle spend insights.
  • User-visible effect: rate-limit modal/banner removed; Billing panel shows daily spend chart, top models, top integrations, plan discount.

Parity Contract

  • Legacy behavior preserved: budget-exhausted state still blocks sends with an inline error; backend still rejects out-of-budget callers via BalanceService.canAfford.
  • Guard/fallback/dispatch parity checks: normalizeTeamUsage returns safe defaults (zeroed insights, FREE plan summary) for empty / malformed payloads, matching the previous defensive contract.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: this one
  • Resolution: N/A

Summary by CodeRabbit

  • New Features

    • Cycle-based budget tracking: shows USD spent, cycle end dates, daily breakdowns, top models/integrations and discount badges.
  • Bug Fixes & Improvements

    • Unified usage percentage and simplified near-limit/exhaustion logic.
    • Replaced rate-limit/weekly wording with cycle/budget language across the app.
  • UI/UX Updates

    • Removed limit-reached modal; blocking and feedback are now inline.
    • Limit pill/banner now use “Cycle” labeling and updated copy; translations updated.

Review Change Stack

Backend PR tinyhumansai/backend#790 disabled 5-hour and daily-cap
rate-limit enforcement and reshaped GET /teams/me/usage. The cap fields
(cycleLimit5hr, fiveHourCapUsd, fiveHourResetsAt, bypassCycleLimit,
cycleLimit7day) are gone; the response now exposes cycleSpentUsd, a
plan{} block (margin + discountVsPayAsYouGoPercent), and an insights{}
block (per-day spend series, top-10 models, top-10 integrations,
inference-vs-integrations totals).

Frontend changes:

- TeamUsage type + normalizer rebuilt for the new shape.
- useUsageState: dropped isRateLimited / usagePct10h; usagePct now
  derives from the cycle budget alone.
- Removed UsageLimitModal entirely (no more 5-hour countdown modal)
  and the composer block-feedback's showLimitModal flag.
- Conversations: dropped 5h LimitPill, rate-limit banner branch, modal
  mount. The cycle pill + tooltip now shows cycleSpentUsd / budget /
  remaining only.
- AIPanel ledger: replaced "5h window" tile with "Cycle total spend"
  (inference + integration breakdown) and pointed "Week remaining"
  detail at cycleSpentUsd.
- InferenceBudget panel rebuilt with cycle-spend breakdown, daily
  inference/integrations chart, top models, top integrations, and a
  plan-discount badge driven by plan.discountVsPayAsYouGoPercent.
- PLANS: removed fiveHourCapUsd, refocused features on per-call
  discount (BASIC 50%, PRO 90%) per the new backend pricing story.
- Home: dropped isRateLimited banner branch.
- TokenUsagePill / GlobalUpsellBanner: use the unified usagePct.
- i18n (en/zh-CN/id): dropped chat.rateLimitReached, chat.fiveHourLimit,
  chat.weeklyLimit; added chat.cycle / cycleSpent / cycleRemaining and
  retuned chat.weeklyLimitHit copy.
- Types: dropped fiveHourCapUsd from CurrentPlanData.

Tests updated for the new shape (creditsApi, useUsageState, AIPanel,
Conversations.render, billingApi, billingHelpers, Home,
composerSendDecision). 2500 passing.

The Rust team_get_usage handler is a passthrough so no core-side
changes are required — the new JSON flows through unchanged.
@senamakel
senamakel requested a review from a team May 18, 2026 01:49
@coderabbitai

coderabbitai Bot commented May 18, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Refactors quota handling from short-term rate limits to a unified cycle-budget model: API types/normalizers now expose cycleSpent and insights, useUsageState exposes a single usagePct, billing UI shows cycle spend and charts, modal-based limit flow removed, and pages/tests/i18n updated.

Changes

Cycle-Based Usage Budget Refactor

Layer / File(s) Summary
API Contract & Type Updates
app/src/services/api/creditsApi.ts, app/src/types/api.ts
TeamUsage now exposes cycleSpentUsd, plan, and insights; legacy rate-limit/cap fields removed; CurrentPlanData gains subscription and monthly/weekly budget fields.
API Tests & Normalizer Tests
app/src/services/api/__tests__/billingApi.test.ts, app/src/services/api/__tests__/creditsApi.test.ts
Tests updated to validate nested plan/insights shape, camelCase RPC fields, and new safe defaults; legacy cycle-limit expectations removed.
Usage State Hook
app/src/hooks/useUsageState.ts
Hook now returns single usagePct computed from cycleBudgetUsd/remainingUsd; dropped usagePct10h/usagePct7d and isRateLimited; isNearLimit/isAtLimit derived from budget state.
Usage Hook Tests
app/src/hooks/useUsageState.test.ts
Introduced builder helpers (buildUsage, freePlan, basicPlan) and updated assertions for usagePct and simplified limit logic.
Plan Definitions
app/src/components/settings/panels/billingHelpers.ts
Removed fiveHourCapUsd from PlanMeta; updated discountPercent values and feature copy to describe per-call discounts vs pay-as-you-go.
Billing Helper Tests
app/src/components/settings/panels/__tests__/billingHelpers.test.ts
Adjusted plan assertions to new discountPercent values and removed fiveHourCapUsd checks; updated test fixtures.
Billing UI: InferenceBudget
app/src/components/settings/panels/billing/InferenceBudget.tsx
Reworked to use cycle-based labels/formatters, progress bar for remaining budget, conditional discount badge, and added UsageBreakdown, DailyChart, TopModels, TopIntegrations.
Metrics Panel
app/src/components/settings/panels/AIPanel.tsx, app/src/components/settings/panels/__tests__/AIPanel.test.tsx
Recent usage tiles now show "Cycle remaining" and bind to cycleSpentUsd/insights.totals; test fixtures updated.
Composer Send Blocking
app/src/pages/conversations/composerSendDecision.ts, tests
Removed showLimitModal from feedback shape; getComposerBlockedSendFeedback returns only an error payload with updated budget-exhaustion message.
Conversations Page Refactor
app/src/pages/Conversations.tsx
Removed UsageLimitModal and related state, use usagePct for approaching-limit banner, tightened budget banner gating, updated quota pill tooltip to show cycle spent/remaining, and adjusted send-block flow to no longer trigger a modal.
Conversations Tests
app/src/pages/__tests__/Conversations.render.test.tsx
Mocks and assertions migrated to the cycle-based usage contract; pill label now "Cycle"; modal-based limit assertions removed and replaced with send-suppression checks.
Simple Components
app/src/components/chat/TokenUsagePill.tsx, app/src/components/upsell/GlobalUpsellBanner.tsx
Both now use usagePct for severity/percentage calculations and remove window-specific fields.
Home Page
app/src/pages/Home.tsx, tests
Home no longer reads isRateLimited; short-term cap banner removed; tests updated mock shape.
Internationalization
app/src/lib/i18n/en.ts, app/src/lib/i18n/chunks/*
Replaced rate-limit/window keys with cycle-budget keys (chat.cycle, chat.cycleSpent, chat.cycleRemaining) and updated limit-hit wording to reference included cycle budget across locales.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • graycyrus

🐰 "I hopped from windows to cycles new,
Spent shown in charts, the pill turns hue—
No modal pops, just budgets bright,
A rabbit cheers the clearer sight!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately summarizes the primary changes: removal of rate-limit UI elements and addition of cycle usage insights visualization, which are the main objectives across the changeset.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. working A PR that is being worked on by the team. labels May 18, 2026
coderabbitai[bot]
coderabbitai Bot previously requested changes May 18, 2026

@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: 3

🧹 Nitpick comments (3)
app/src/hooks/useUsageState.test.ts (1)

87-207: ⚡ Quick win

Add a regression case for over-remaining budgets.

Please add one case where remainingUsd > cycleBudgetUsd and assert usagePct === 0 plus isNearLimit === false to lock the lower-bound behavior.

🤖 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 `@app/src/hooks/useUsageState.test.ts` around lines 87 - 207, Add a test in
useUsageState.test.ts that simulates an over-remaining budget by importing
useUsageState, stubbing mockGetCurrentPlan (e.g. basicPlan()) and
mockGetTeamUsage to return buildUsage({ remainingUsd: 15, cycleBudgetUsd: 10 }),
render the hook, wait for isLoading to be false, and assert that
result.current.usagePct === 0 and result.current.isNearLimit === false
(optionally also assert isBudgetExhausted === false) to lock the lower-bound
behavior for over-remaining budgets.
app/src/pages/__tests__/Conversations.render.test.tsx (1)

618-627: ⚡ Quick win

Assert inline error feedback in the over-budget send test.

This test correctly verifies chatSend suppression, but it should also assert the inline budget-exhausted message to lock in the modal-removal UX behavior.

Suggested test assertion update
   it('blocks the send when the account is over budget (no rate-limit modal anymore)', async () => {
     const { textarea } = await renderSelectedConversation({ isAtLimit: true });

     await submitComposerText(textarea, 'hello at limit');

     // Backend PR `#790` removed the rate-limit modal; over-budget now surfaces
     // only the inline send-error (which clears as soon as the user keeps
     // typing). The contract we still care about: chatSend is suppressed.
     expect(chatSend).not.toHaveBeenCalled();
+    expect(screen.getByText(/Included budget exhausted/i)).toBeInTheDocument();
   });

As per coding guidelines: "Prefer testing behavior over implementation details."

🤖 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 `@app/src/pages/__tests__/Conversations.render.test.tsx` around lines 618 -
627, Update the test "blocks the send when the account is over budget (no
rate-limit modal anymore)" to also assert the inline budget-exhausted feedback
is shown: after calling renderSelectedConversation({ isAtLimit: true }) and
submitComposerText(textarea, 'hello at limit'), keep the existing
expect(chatSend).not.toHaveBeenCalled() and add an assertion that the inline
error message element or text for the budget-exhausted state is present (use the
same query utilities used elsewhere in the file to find the inline send-error).
Locate this test by the it(...) description and use renderSelectedConversation,
submitComposerText, and textarea to place the new assertion so the test verifies
both suppression of chatSend and the inline error UX.
app/src/components/settings/panels/AIPanel.tsx (1)

900-1339: 🏗️ Heavy lift

Extract the diagnostics/ledger section into separate modules.

This file has grown far beyond single-responsibility size, and the added budget diagnostics increase coupling and review/test overhead.

As per coding guidelines **/*.{js,ts,tsx,jsx}: Prefer files ≤ ~500 lines per source file; split modules when growing to maintain readability and single responsibility.

🤖 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 `@app/src/components/settings/panels/AIPanel.tsx` around lines 900 - 1339, The
AIPanel.tsx file is too large—extract the recent usage ledger and budget/loop
diagnostic sections into separate components to reduce size and coupling: create
e.g. LedgerPanel, BudgetMathPanel, and LoopCallBudgetPanel (or a single
DiagnosticsLedger component) that encapsulate the JSX around MetricTile,
FormulaRow, the "Latest spend" block, "Top actions" and "Top hours" lists and
the surrounding state usage (props: usage, spendSample, spendRows, latestSpend,
actionSummary, hourSummary, backgroundApiReadsPerWeek,
calendarPlannerCallsPerWeek, etc.), export them and replace the in-file sections
with imports and a single component invocation passing the necessary props
(preserve handlers like refresh/runPlannerNow only if used); ensure all
referenced symbols (MetricTile, FormulaRow, spendAmount, formatUsd, formatCount,
COMPOSIO_PERIODIC_TICK_MINUTES, MEMORY_WORKERS, MEMORY_POLL_SECONDS) remain
available via imports or prop drilling and update tests/imports accordingly.
🤖 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 `@app/src/components/settings/panels/billing/InferenceBudget.tsx`:
- Around line 43-46: The progress bar width calculation in InferenceBudget.tsx
uses (teamUsage.remainingUsd / teamUsage.cycleBudgetUsd) * 100 which can produce
negative or >100 values; fix by computing the percent from
teamUsage.remainingUsd and teamUsage.cycleBudgetUsd, guard against
division-by-zero, then clamp that percent into the 0–100 range (e.g. with
Math.max/Math.min) before interpolating into the width style so the style.width
always yields a valid percentage.
- Line 55: The "Cycle ends" line should validate and consistently format
teamUsage.cycleEndsAt to avoid "Invalid Date" or local-time shifts for
UTC-midnight values: in the InferenceBudget component, check
Date.parse(teamUsage.cycleEndsAt) (or new Date(...) validity) and if invalid
render a safe placeholder (e.g. "—" or "Invalid date"); otherwise create a Date
object and format with toLocaleDateString('en-US', { timeZone: 'UTC' }) (or an
explicit timezone option) when rendering the "Cycle ends {…}" text so
UTC-midnight timestamps don't shift to the previous/next day in the user's local
timezone.

In `@app/src/hooks/useUsageState.ts`:
- Around line 111-114: The computed usagePct in useUsageState.ts can be negative
when teamUsage.remainingUsd > teamUsage.cycleBudgetUsd; update the calculation
for the usagePct variable to clamp the value to the [0,1] range by applying
Math.max(0, ...) around the current fraction (and keep Math.min(1, ...)) so
usagePct never becomes negative while still respecting the upper bound; locate
the usagePct declaration that references teamUsage.cycleBudgetUsd and
teamUsage.remainingUsd and replace the expression accordingly.

---

Nitpick comments:
In `@app/src/components/settings/panels/AIPanel.tsx`:
- Around line 900-1339: The AIPanel.tsx file is too large—extract the recent
usage ledger and budget/loop diagnostic sections into separate components to
reduce size and coupling: create e.g. LedgerPanel, BudgetMathPanel, and
LoopCallBudgetPanel (or a single DiagnosticsLedger component) that encapsulate
the JSX around MetricTile, FormulaRow, the "Latest spend" block, "Top actions"
and "Top hours" lists and the surrounding state usage (props: usage,
spendSample, spendRows, latestSpend, actionSummary, hourSummary,
backgroundApiReadsPerWeek, calendarPlannerCallsPerWeek, etc.), export them and
replace the in-file sections with imports and a single component invocation
passing the necessary props (preserve handlers like refresh/runPlannerNow only
if used); ensure all referenced symbols (MetricTile, FormulaRow, spendAmount,
formatUsd, formatCount, COMPOSIO_PERIODIC_TICK_MINUTES, MEMORY_WORKERS,
MEMORY_POLL_SECONDS) remain available via imports or prop drilling and update
tests/imports accordingly.

In `@app/src/hooks/useUsageState.test.ts`:
- Around line 87-207: Add a test in useUsageState.test.ts that simulates an
over-remaining budget by importing useUsageState, stubbing mockGetCurrentPlan
(e.g. basicPlan()) and mockGetTeamUsage to return buildUsage({ remainingUsd: 15,
cycleBudgetUsd: 10 }), render the hook, wait for isLoading to be false, and
assert that result.current.usagePct === 0 and result.current.isNearLimit ===
false (optionally also assert isBudgetExhausted === false) to lock the
lower-bound behavior for over-remaining budgets.

In `@app/src/pages/__tests__/Conversations.render.test.tsx`:
- Around line 618-627: Update the test "blocks the send when the account is over
budget (no rate-limit modal anymore)" to also assert the inline budget-exhausted
feedback is shown: after calling renderSelectedConversation({ isAtLimit: true })
and submitComposerText(textarea, 'hello at limit'), keep the existing
expect(chatSend).not.toHaveBeenCalled() and add an assertion that the inline
error message element or text for the budget-exhausted state is present (use the
same query utilities used elsewhere in the file to find the inline send-error).
Locate this test by the it(...) description and use renderSelectedConversation,
submitComposerText, and textarea to place the new assertion so the test verifies
both suppression of chatSend and the inline error UX.
🪄 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: 3936170a-dd39-49c0-8bfb-13742018bf65

📥 Commits

Reviewing files that changed from the base of the PR and between db087a7 and 2ab8f7d.

📒 Files selected for processing (23)
  • app/src/components/chat/TokenUsagePill.tsx
  • app/src/components/settings/panels/AIPanel.tsx
  • app/src/components/settings/panels/__tests__/AIPanel.test.tsx
  • app/src/components/settings/panels/__tests__/billingHelpers.test.ts
  • app/src/components/settings/panels/billing/InferenceBudget.tsx
  • app/src/components/settings/panels/billingHelpers.ts
  • app/src/components/upsell/GlobalUpsellBanner.tsx
  • app/src/components/upsell/UsageLimitModal.tsx
  • app/src/hooks/useUsageState.test.ts
  • app/src/hooks/useUsageState.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/src/pages/Conversations.tsx
  • app/src/pages/Home.tsx
  • app/src/pages/__tests__/Conversations.render.test.tsx
  • app/src/pages/__tests__/Home.test.tsx
  • app/src/pages/conversations/composerSendDecision.test.ts
  • app/src/pages/conversations/composerSendDecision.ts
  • app/src/services/api/__tests__/billingApi.test.ts
  • app/src/services/api/__tests__/creditsApi.test.ts
  • app/src/services/api/creditsApi.ts
  • app/src/types/api.ts
💤 Files with no reviewable changes (3)
  • app/src/components/upsell/UsageLimitModal.tsx
  • app/src/types/api.ts
  • app/src/services/api/tests/billingApi.test.ts

Comment thread app/src/hooks/useUsageState.ts Resolved
Address CodeRabbit review on PR tinyhumansai#2027:

- useUsageState: clamp usagePct to [0,1] so an overage (remainingUsd >
  cycleBudgetUsd) can't leak a negative ratio into the chat pill and
  near-limit derivations.
- InferenceBudget: clamp progress-bar width to [0,100] for the same
  reason, and route the cycle-end label through a formatter that
  validates the timestamp and renders in UTC so a UTC-midnight cycle
  end doesn't shift a day in the user's local TZ.
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 18, 2026
…ts-show-usage

# Conflicts:
#	app/src/components/settings/panels/billing/InferenceBudget.tsx
#	app/src/components/upsell/GlobalUpsellBanner.tsx
#	app/src/components/upsell/UsageLimitModal.tsx
#	app/src/lib/i18n/id.ts
#	app/src/lib/i18n/zh-CN.ts

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (8)
app/src/lib/i18n/chunks/fr-2.ts (1)

289-297: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace weekly-limit phrasing with cycle-budget phrasing.

Line 289 is still weekly-limit copy, while Lines 295-297 are cycle-based labels. Please align chat.weeklyLimitHit with the cycle-budget terminology.

🤖 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 `@app/src/lib/i18n/chunks/fr-2.ts` around lines 289 - 297, Update the French
translation for the key chat.weeklyLimitHit to use cycle-budget terminology
instead of weekly wording; locate the chat.weeklyLimitHit entry and replace "Tu
as atteint ta limite hebdomadaire." with a cycle-consistent phrase such as "Tu
as atteint ton budget pour ce cycle." to align with the surrounding keys
(chat.cycle, chat.cycleSpent, chat.cycleRemaining).
app/src/lib/i18n/chunks/bn-2.ts (1)

284-292: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update weekly-limit copy to cycle-budget copy in this locale.

Line 284 still references a weekly limit while Lines 290-292 moved to cycle wording. Please align chat.weeklyLimitHit with the cycle-budget model.

🤖 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 `@app/src/lib/i18n/chunks/bn-2.ts` around lines 284 - 292, Update the
'chat.weeklyLimitHit' translation to use the cycle-budget wording (to match
'chat.cycle', 'chat.cycleSpent', and 'chat.cycleRemaining') by replacing the
current weekly-limit text with a cycle-budget message — e.g., change the value
for chat.weeklyLimitHit to something like "আপনি আপনার চক্রের বাজেটে পৌঁছেছেন।"
so all budget-related keys consistently use "চক্র" (cycle) terminology.
app/src/lib/i18n/chunks/es-2.ts (1)

287-295: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep chat.weeklyLimitHit consistent with cycle-based UX.

Line 287 still says weekly limit, but Lines 293-295 use cycle terminology. Please update the weekly-limit string to cycle-budget wording.

🤖 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 `@app/src/lib/i18n/chunks/es-2.ts` around lines 287 - 295, The key
'chat.weeklyLimitHit' uses "weekly" while surrounding keys ('chat.cycle',
'chat.cycleSpent', 'chat.cycleRemaining', 'chat.budgetComplete') use
cycle/budget terminology—update the value for 'chat.weeklyLimitHit' to match
cycle-based UX (e.g., change the string to mention "presupuesto de ciclo" or
"ciclo" instead of "semanal") so it is consistent with the other cycle-related
keys.
app/src/lib/i18n/chunks/ru-2.ts (1)

282-290: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Make chat.weeklyLimitHit consistent with cycle-budget copy.

Line 282 still says weekly-limit messaging, which conflicts with cycle labels on Lines 288-290. Please localize this message to the cycle-budget concept.

🤖 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 `@app/src/lib/i18n/chunks/ru-2.ts` around lines 282 - 290, The message for
'chat.weeklyLimitHit' is inconsistent with the cycle-budget terminology used by
'chat.cycle', 'chat.cycleSpent', and 'chat.cycleRemaining'; update the
localization for the 'chat.weeklyLimitHit' entry to mention the cycle-based
limit (e.g., replace any "weekly" wording with "cycle" or equivalent Russian
phrasing) so it matches the cycle-budget copy used elsewhere in this file.
app/src/lib/i18n/chunks/ar-2.ts (1)

274-281: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align chat.weeklyLimitHit text with cycle-budget terminology.

Line 274 still communicates a weekly limit, which conflicts with the new cycle labels on Lines 279-281. Please update this locale string to the cycle-budget concept.

🤖 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 `@app/src/lib/i18n/chunks/ar-2.ts` around lines 274 - 281, Update the locale
entry for chat.weeklyLimitHit to use cycle-budget terminology: replace the
current Arabic text "لقد وصلت إلى حدك الأسبوعي." with a cycle-focused phrase
such as "لقد وصلت إلى حدك في هذه الدورة." to match keys like chat.cycle,
chat.cycleSpent and chat.cycleRemaining; modify the value for the
'chat.weeklyLimitHit' key accordingly.
app/src/lib/i18n/chunks/hi-2.ts (1)

282-289: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align chat.weeklyLimitHit with cycle-budget messaging.

Line 282 still refers to a weekly limit, which conflicts with the cycle labels on Lines 287-289. Please update the string to cycle-budget wording.

🤖 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 `@app/src/lib/i18n/chunks/hi-2.ts` around lines 282 - 289, Update the
'chat.weeklyLimitHit' translation to use cycle-budget terminology so it aligns
with the surrounding keys ('chat.cycle', 'chat.cycleSpent',
'chat.cycleRemaining'); locate the 'chat.weeklyLimitHit' entry in hi-2.ts and
replace the "साप्ताहिक सीमा" wording with a phrase that references the
cycle/budget (consistent tone with 'chat.budgetComplete' and 'chat.cycle'),
ensuring the key remains unchanged.
app/src/lib/i18n/chunks/pt-2.ts (1)

287-295: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update weekly-limit string to the cycle-budget model.

Line 287 still communicates a weekly limit, while Lines 293-295 moved to cycle semantics. Please align chat.weeklyLimitHit accordingly.

🤖 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 `@app/src/lib/i18n/chunks/pt-2.ts` around lines 287 - 295, Update the
'chat.weeklyLimitHit' translation to use cycle-budget wording to match the rest
of the keys (e.g., chat.cycle, chat.cycleSpent, chat.cycleRemaining,
chat.budgetComplete); replace the weekly-specific phrase ("Você atingiu seu
limite semanal.") with a Portuguese message that communicates the cycle budget
has been reached (e.g., using "ciclo" or "orçamento do ciclo") so all
cycle-related strings are consistent.
app/src/lib/i18n/chunks/zh-CN-2.ts (1)

265-265: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update non-English translations to match cycle-based messaging.

The chat.weeklyLimitHit key is actively used in app/src/pages/Conversations.tsx:1855 for quota exhaustion messages. However, there's a localization inconsistency: the English versions (en-2.ts and en.ts) say "You've used your included cycle budget." (cycle-based), while the Chinese and most other locales still say "weekly limit" (time-window-based).

Update the following locale files to use cycle terminology instead of weekly:

  • zh-CN-2.ts line 265: change '已达到每周限制。' to '已使用包含的循环预算。'
  • fr-2.ts, es-2.ts, pt-2.ts, ru-2.ts, ar-2.ts, hi-2.ts, id-2.ts, bn-2.ts: align translations to match the English cycle-based message
🤖 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 `@app/src/lib/i18n/chunks/zh-CN-2.ts` at line 265, Update the localization key
'chat.weeklyLimitHit' to use cycle-based wording instead of "weekly" for the
listed locales; specifically in zh-CN-2.ts replace '已达到每周限制。' with '已使用包含的循环预算。'
and apply equivalent cycle-based translations in fr-2.ts, es-2.ts, pt-2.ts,
ru-2.ts, ar-2.ts, hi-2.ts, id-2.ts, and bn-2.ts so they match the English
message "You've used your included cycle budget." Ensure the exact key
'chat.weeklyLimitHit' is updated in each file and keep punctuation/period
consistent with other locale entries.
🤖 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.

Outside diff comments:
In `@app/src/lib/i18n/chunks/ar-2.ts`:
- Around line 274-281: Update the locale entry for chat.weeklyLimitHit to use
cycle-budget terminology: replace the current Arabic text "لقد وصلت إلى حدك
الأسبوعي." with a cycle-focused phrase such as "لقد وصلت إلى حدك في هذه الدورة."
to match keys like chat.cycle, chat.cycleSpent and chat.cycleRemaining; modify
the value for the 'chat.weeklyLimitHit' key accordingly.

In `@app/src/lib/i18n/chunks/bn-2.ts`:
- Around line 284-292: Update the 'chat.weeklyLimitHit' translation to use the
cycle-budget wording (to match 'chat.cycle', 'chat.cycleSpent', and
'chat.cycleRemaining') by replacing the current weekly-limit text with a
cycle-budget message — e.g., change the value for chat.weeklyLimitHit to
something like "আপনি আপনার চক্রের বাজেটে পৌঁছেছেন।" so all budget-related keys
consistently use "চক্র" (cycle) terminology.

In `@app/src/lib/i18n/chunks/es-2.ts`:
- Around line 287-295: The key 'chat.weeklyLimitHit' uses "weekly" while
surrounding keys ('chat.cycle', 'chat.cycleSpent', 'chat.cycleRemaining',
'chat.budgetComplete') use cycle/budget terminology—update the value for
'chat.weeklyLimitHit' to match cycle-based UX (e.g., change the string to
mention "presupuesto de ciclo" or "ciclo" instead of "semanal") so it is
consistent with the other cycle-related keys.

In `@app/src/lib/i18n/chunks/fr-2.ts`:
- Around line 289-297: Update the French translation for the key
chat.weeklyLimitHit to use cycle-budget terminology instead of weekly wording;
locate the chat.weeklyLimitHit entry and replace "Tu as atteint ta limite
hebdomadaire." with a cycle-consistent phrase such as "Tu as atteint ton budget
pour ce cycle." to align with the surrounding keys (chat.cycle, chat.cycleSpent,
chat.cycleRemaining).

In `@app/src/lib/i18n/chunks/hi-2.ts`:
- Around line 282-289: Update the 'chat.weeklyLimitHit' translation to use
cycle-budget terminology so it aligns with the surrounding keys ('chat.cycle',
'chat.cycleSpent', 'chat.cycleRemaining'); locate the 'chat.weeklyLimitHit'
entry in hi-2.ts and replace the "साप्ताहिक सीमा" wording with a phrase that
references the cycle/budget (consistent tone with 'chat.budgetComplete' and
'chat.cycle'), ensuring the key remains unchanged.

In `@app/src/lib/i18n/chunks/pt-2.ts`:
- Around line 287-295: Update the 'chat.weeklyLimitHit' translation to use
cycle-budget wording to match the rest of the keys (e.g., chat.cycle,
chat.cycleSpent, chat.cycleRemaining, chat.budgetComplete); replace the
weekly-specific phrase ("Você atingiu seu limite semanal.") with a Portuguese
message that communicates the cycle budget has been reached (e.g., using "ciclo"
or "orçamento do ciclo") so all cycle-related strings are consistent.

In `@app/src/lib/i18n/chunks/ru-2.ts`:
- Around line 282-290: The message for 'chat.weeklyLimitHit' is inconsistent
with the cycle-budget terminology used by 'chat.cycle', 'chat.cycleSpent', and
'chat.cycleRemaining'; update the localization for the 'chat.weeklyLimitHit'
entry to mention the cycle-based limit (e.g., replace any "weekly" wording with
"cycle" or equivalent Russian phrasing) so it matches the cycle-budget copy used
elsewhere in this file.

In `@app/src/lib/i18n/chunks/zh-CN-2.ts`:
- Line 265: Update the localization key 'chat.weeklyLimitHit' to use cycle-based
wording instead of "weekly" for the listed locales; specifically in zh-CN-2.ts
replace '已达到每周限制。' with '已使用包含的循环预算。' and apply equivalent cycle-based
translations in fr-2.ts, es-2.ts, pt-2.ts, ru-2.ts, ar-2.ts, hi-2.ts, id-2.ts,
and bn-2.ts so they match the English message "You've used your included cycle
budget." Ensure the exact key 'chat.weeklyLimitHit' is updated in each file and
keep punctuation/period consistent with other locale entries.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b81aa590-8367-472f-8042-24a24d6dd95d

📥 Commits

Reviewing files that changed from the base of the PR and between 23474d6 and c9f15d3.

📒 Files selected for processing (13)
  • app/src/components/settings/panels/AIPanel.tsx
  • app/src/components/upsell/GlobalUpsellBanner.tsx
  • app/src/lib/i18n/chunks/ar-2.ts
  • app/src/lib/i18n/chunks/bn-2.ts
  • app/src/lib/i18n/chunks/en-2.ts
  • app/src/lib/i18n/chunks/es-2.ts
  • app/src/lib/i18n/chunks/fr-2.ts
  • app/src/lib/i18n/chunks/hi-2.ts
  • app/src/lib/i18n/chunks/id-2.ts
  • app/src/lib/i18n/chunks/pt-2.ts
  • app/src/lib/i18n/chunks/ru-2.ts
  • app/src/lib/i18n/chunks/zh-CN-2.ts
  • app/src/lib/i18n/en.ts
✅ Files skipped from review due to trivial changes (1)
  • app/src/lib/i18n/chunks/id-2.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/src/components/settings/panels/AIPanel.tsx
  • app/src/lib/i18n/en.ts
  • app/src/components/upsell/GlobalUpsellBanner.tsx

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 18, 2026
@M3gA-Mind

Copy link
Copy Markdown
Collaborator

Code Review

Overview

Clean, well-scoped removal of the 5-hour rate-limit UI driven by backend PR #790. The TeamUsage type is fully rewritten to the new contract, InferenceBudget.tsx is rebuilt as a richer insights panel, and all consuming components/tests are updated consistently. +597 / -685 is a net deletion. CodeRabbit approved.


Strengths

  • normalizeTeamUsage is cleaner — pulls each sub-object into its own typed helper (normalizePlanSummary, normalizeInsights, normalizeDailyPoint). The !Array.isArray(payload) guard is a genuine correctness improvement over the old code.
  • useUsageState simplification is correct: Math.max(0, Math.min(1, ...)) replaces the unguarded clamp, and removing usagePct10h/usagePct7d/isRateLimited eliminates a whole class of stale state.
  • Test fixture helpers (buildUsage, freePlan, basicPlan) reduce boilerplate well.
  • formatCycleEnds using timeZone: 'UTC' is the right call — noted in a comment.

Issues to Fix

1. DailyChart percentage-height bug (InferenceBudget.tsx ~L362–370)

Bar divs use style={{ height: '${inferenceHeight}%' }} inside flex-1 flex flex-col-reverse columns with no explicit height set on the column. Percentage heights only resolve against a parent with a defined height — the column's height is driven by its children, creating a circular dependency. In practice the bars collapse to 0px and nothing renders.

Fix: add h-full to the column div:

<div key={p.date} className="flex-1 h-full flex flex-col-reverse" ...>

2. normalizeUsd used for integer calls fields (creditsApi.ts, normalizeModelRow / normalizeIntegrationRow)

calls: normalizeUsd(r.calls),  // wrong — calls is a count, not USD

normalizeUsd is named/documented for currency. Using it for call counts is semantically wrong and could coerce fractional values silently. Use Math.round(Number(r.calls) || 0) instead.

3. Hardcoded English strings in InferenceBudget.tsx

The rebuilt component (~190 lines) drops useT() and has ~15 user-visible strings ("Inference Budget", "Loading…", "Cycle spend", "No inference usage this cycle.", etc.) hardcoded in English. The rest of the billing UI is translated into 10+ locales. Either add i18n keys or leave a // TODO: i18n comment so the gap is tracked.

4. fmtUsd duplicates formatUsd (InferenceBudget.tsx L187)

AIPanel.tsx in the same directory imports a formatUsd helper. Introducing a local fmtUsd creates a second USD formatter. Import and reuse the shared one.


Risks

5. Silent budget-block UX regression (composerSendDecision.ts)

The old usage_limit_reached path surfaced a modal with an upsell path. The new path sets a transient inline send-error that clears on the next keystroke. For free-tier users with cycleBudgetUsd=0, shouldShowBudgetCompletedMessage is false, so neither the budget banner nor the modal shows — the user just sees an error that disappears as soon as they type. Consider keeping the error persistent while isAtLimit is true.

6. Missing snake_case fallback tolerance

The old normalizer handled remaining_usd, cycle_budget_usd, etc. for partial-rollout tolerance. The new one silently returns zeroed defaults if backend #790 hasn't deployed yet. The PR notes this is intentional — just confirm it's been verified against the pre-#790 staging response shape.


Test Coverage

7. InferenceBudget.tsx has no tests

The rebuilt component has distinct sub-components (UsageBreakdown, DailyChart, TopModels, TopIntegrations) and several conditional render paths (loading, null, zero-budget, discount badge). It's the most complex new code in the PR with no dedicated test file. At minimum, add render tests for: loading state, null/empty-data state, and the full happy-path with all fields populated.


Nits

  • AIPanel.tsx L1143: label="Week remaining" wasn't updated to "Cycle remaining" — inconsistent with the tooltip in Conversations.tsx which now uses t('chat.cycleRemaining').
  • TopModels key: \${r.provider}::${r.model}`— if both are empty string, rows would collide. Add a fallback index:`${r.provider}::${r.model}::${i}``.

M3gA-Mind added 2 commits May 19, 2026 15:05
# Conflicts:
#	app/src/components/settings/panels/billing/InferenceBudget.tsx
#	app/src/components/upsell/UsageLimitModal.tsx
#	app/src/pages/Conversations.tsx
- InferenceBudget DailyChart: add h-full to bar column divs so
  percentage heights resolve against the container (were collapsing to 0)
- creditsApi: use Math.round(Number(x)||0) for call-count fields instead
  of normalizeUsd (which is for currency amounts, not integer counts)
- AIPanel: rename "Week remaining" tile label to "Cycle remaining" to
  match the tooltip i18n key (chat.cycleRemaining) updated in the PR
- AIPanel test: update assertion to match new "Cycle remaining" label
- TopModels / TopIntegrations: add index suffix to list keys to prevent
  collisions when provider or model is an empty string
Dark-mode class additions and uiLocale wiring from upstream/main that
were accidentally omitted from the merge commit (unstaged during conflict
resolution, never re-staged).

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/src/components/settings/panels/AIPanel.tsx (1)

1279-1333: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Align remaining “Week” labels with cycle-based metrics.

Line 1280 (Week budget) and Line 1330 (Rows per full week budget) still use week wording, while this panel is now cycle-based. Renaming these avoids mixed terminology in the same card group.

Suggested copy fix
-              label="Week budget"
+              label="Cycle budget"
...
-                label="Rows per full week budget"
+                label="Rows per full cycle budget"
🤖 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 `@app/src/components/settings/panels/AIPanel.tsx` around lines 1279 - 1333, The
labels use "Week" but the panel is cycle-based; update the MetricTile and
FormulaRow label props to cycle wording—replace the MetricTile with label="Week
budget" (symbol: MetricTile at the first occurrence) to label="Cycle budget" and
change the FormulaRow with label="Rows per full week budget" (symbol: FormulaRow
where value uses estimatedRowsPerBudget) to label="Rows per cycle budget" so all
terminology in the card group consistently refers to the cycle.
🧹 Nitpick comments (1)
app/src/pages/__tests__/Conversations.render.test.tsx (1)

618-627: ⚡ Quick win

Strengthen the over-budget send-block test with a visible-feedback assertion.

This case currently only checks that chatSend is suppressed. Add an assertion for the expected over-budget user feedback so UX regressions don’t become silent.

🤖 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 `@app/src/pages/__tests__/Conversations.render.test.tsx` around lines 618 -
627, Add an assertion that the over-budget inline feedback is visible after
submitting while isAtLimit is true and that it clears when the user continues
typing: after calling renderSelectedConversation({ isAtLimit: true }) and
submitComposerText(textarea, 'hello at limit'), assert the inline send-error
element/text (e.g., the "over budget" message or element with class/name used by
the composer send-error) is present/visible using findByText/getByText (or
equivalent test-id), then simulate typing (use submitComposerText or
userEvent.type) and assert the same element is no longer present (queryByText
returns null). Reference: chatSend, renderSelectedConversation,
submitComposerText, isAtLimit.
🤖 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.

Outside diff comments:
In `@app/src/components/settings/panels/AIPanel.tsx`:
- Around line 1279-1333: The labels use "Week" but the panel is cycle-based;
update the MetricTile and FormulaRow label props to cycle wording—replace the
MetricTile with label="Week budget" (symbol: MetricTile at the first occurrence)
to label="Cycle budget" and change the FormulaRow with label="Rows per full week
budget" (symbol: FormulaRow where value uses estimatedRowsPerBudget) to
label="Rows per cycle budget" so all terminology in the card group consistently
refers to the cycle.

---

Nitpick comments:
In `@app/src/pages/__tests__/Conversations.render.test.tsx`:
- Around line 618-627: Add an assertion that the over-budget inline feedback is
visible after submitting while isAtLimit is true and that it clears when the
user continues typing: after calling renderSelectedConversation({ isAtLimit:
true }) and submitComposerText(textarea, 'hello at limit'), assert the inline
send-error element/text (e.g., the "over budget" message or element with
class/name used by the composer send-error) is present/visible using
findByText/getByText (or equivalent test-id), then simulate typing (use
submitComposerText or userEvent.type) and assert the same element is no longer
present (queryByText returns null). Reference: chatSend,
renderSelectedConversation, submitComposerText, isAtLimit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8c6f4873-6601-4020-90c9-7c541358e7a9

📥 Commits

Reviewing files that changed from the base of the PR and between c9f15d3 and f467f7e.

📒 Files selected for processing (17)
  • app/src/components/chat/TokenUsagePill.tsx
  • app/src/components/settings/panels/AIPanel.tsx
  • app/src/components/settings/panels/__tests__/AIPanel.test.tsx
  • app/src/components/settings/panels/billing/InferenceBudget.tsx
  • app/src/lib/i18n/chunks/ar-2.ts
  • app/src/lib/i18n/chunks/bn-2.ts
  • app/src/lib/i18n/chunks/es-2.ts
  • app/src/lib/i18n/chunks/fr-2.ts
  • app/src/lib/i18n/chunks/hi-2.ts
  • app/src/lib/i18n/chunks/id-2.ts
  • app/src/lib/i18n/chunks/pt-2.ts
  • app/src/lib/i18n/chunks/ru-2.ts
  • app/src/lib/i18n/chunks/zh-CN-2.ts
  • app/src/lib/i18n/en.ts
  • app/src/pages/Home.tsx
  • app/src/pages/__tests__/Conversations.render.test.tsx
  • app/src/pages/__tests__/Home.test.tsx
✅ Files skipped from review due to trivial changes (2)
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/chunks/fr-2.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • app/src/components/chat/TokenUsagePill.tsx
  • app/src/pages/tests/Home.test.tsx
  • app/src/components/settings/panels/tests/AIPanel.test.tsx
  • app/src/lib/i18n/chunks/ru-2.ts
  • app/src/pages/Home.tsx
  • app/src/lib/i18n/chunks/ar-2.ts
  • app/src/lib/i18n/chunks/es-2.ts
  • app/src/lib/i18n/chunks/pt-2.ts
  • app/src/components/settings/panels/billing/InferenceBudget.tsx
  • app/src/lib/i18n/chunks/id-2.ts

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 19, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 19, 2026
…t keys

it-2.ts was added in the main merge with the old rate-limit i18n shape.
Replace chat.rateLimitReached / chat.fiveHourLimit / chat.weeklyLimit with
chat.cycle / chat.cycleSpent / chat.cycleRemaining to match the English
reference and unblock the i18n coverage CI check.
M3gA-Mind added 2 commits May 19, 2026 17:02
Adds Vitest tests for five files that the coverage CI flagged as
under-covered in PR tinyhumansai#2027:

- InferenceBudget.test.tsx: full branch coverage for loading,
  null-usage, cycleBudgetUsd>0/=0, plan discount, UsageBreakdown,
  DailyChart, TopModels, and TopIntegrations paths
- GlobalUpsellBanner.test.tsx: covers at-limit (upgrade), near-limit
  free-tier (warning with pct), and null-return branches
- Home.test.tsx: spy-based useUsageState mock; new test for
  shouldShowBudgetCompletedMessage=true rendering UsageLimitBanner
- Conversations.render.test.tsx: three new tests for the
  budgetComplete/cycleEndsAt/loading-pulse paths (lines 1871, 1903-1904, 1910)
- creditsApi.test.ts: normalizer default-branch tests for
  normalizeDailyPoint, normalizeModelRow, normalizeIntegrationRow,
  and normalizePlanSummary missing-field cases
@M3gA-Mind
M3gA-Mind dismissed coderabbitai[bot]’s stale review May 19, 2026 11:54

All review feedback addressed and CI passing. Dismissing to unblock merge.

@M3gA-Mind
M3gA-Mind merged commit 3aa2984 into tinyhumansai:main May 19, 2026
23 checks passed
AusAgentSmith pushed a commit to AusAgentSmith/openhuman that referenced this pull request May 23, 2026
senamakel added a commit to nocstah/openhuman that referenced this pull request Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Net-new user-facing capability or product behavior. working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants