Skip to content

💳 feat: Show Balance in the Context Gauge as Credits, Currency, or Percent - #16762

Merged
danny-avila merged 6 commits into
devfrom
danny-avila/librechat-balance-limits-ui-12ea06
Oct 5, 2026
Merged

danny-avila merged 6 commits into
devfrom
danny-avila/librechat-balance-limits-ui-12ea06

Conversation

@danny-avila

@danny-avila danny-avila commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

A user's balance is only visible as a raw credit count in the account menu ("Balance: 3100000") and in Settings › Account › Billing, where the same number renders differently ("3100000.00"). Neither says how much of the period's allotment is gone or when it refills, and a deployment that prices in money or wants to hide raw credits has no way to show it differently, even though interface.currency already exists for the context gauge's Cost row.

This PR moves the balance into the composer's context gauge, below the context window, and adds balance.display to choose how it reads: credits (default, today's figure), currency (credits converted at 1,000,000 credits per USD and formatted with the existing interface.currency code and rate) or percent (only the share of the period's allotment spent, with no credit or money figure anywhere). The allotment is the refill amount under auto-refill, otherwise startBalance. The section shows a bar of the share spent and when the next refill becomes available, turns amber from 90% spent and red with "Out of credits" at zero, and in percent mode says "Usage unavailable" when nothing measures the spend.

Settings › Account › Billing renders the same summary component from the same hook, so the gauge and the settings dialog show identical figures, bar and refill timing in every mode; its Refill Amount row follows the display mode and hides in percent, and a non-positive refill amount reads as no auto-refill in both, since the server never applies one. The insufficient-funds error follows the same mode (money in currency, no figures in percent), and the auto-refill row carries its own loading and error states for when Settings search shows it alone. The account menu's balance line is removed.

The gauge stays visible on a fresh chat when balance is on (the card then shows the balance alone), and a deployment with interface.contextUsage: false but balance on gets a balance-only gauge whose ring is the share spent, tinted with the balance's tone, without mounting the context hooks.

How it works

One reading, two surfaces:

useBalanceSummary()                      # hooks/useBalanceSummary.ts
  useGetStartupConfig → balance.{enabled, display, startBalance}, interface.currency
  useGetUserBalance   → tokenCredits, refill fields
  summarizeBalance()  → { credits, allotment, usedPercent, tone, refillAmount, nextRefill }   # utils/balance.ts

<Balance />  → <Summary state currency />   # components/Balance
  ├── TokenUsage card, below Breakdown + Compact   # Chat/Input/TokenUsage/index.tsx
  ├── BalanceIndicator (contextUsage: false)
  └── Settings › Billing: TokenCredits, AutoRefill  # Nav/Settings/BillingControls.tsx

The gauge's hover/pin popover logic moved unchanged from TokenUsage/index.tsx into TokenUsage/Popover.tsx so the balance-only gauge reuses it. The Langfuse link query now lives in a ContextCard mounted only while the card is open, which is the same condition the old popoverOpen gate expressed.

Progress (@librechat/client) gains a variant (default | warning | error) for the tone fills, and now passes value to the Radix root so the bar reports aria-valuenow.

Auto-refill only applies when a request would take the balance to zero after the interval has passed, so a future eligibility reads "Refill available in 3 days" rather than promising a deposit, and a past-due one reads "Refills when you run out".

Type of change

  • Feature
  • Tests / tooling / CI

Testing

Tested environments/configuration: real TokenUsage, BillingControls and client/src/style.css mounted in Chromium (Playwright) with data hooks stubbed, in dark and light themes, covering credits, currency, percent, running low, out of credits, fresh chat, contextUsage: false and no auto-refill. In all nine states the gauge card's balance text and the settings dialog's text were identical, with no console errors.

Automated tests:

  • client/src/utils/__tests__/balance.spec.ts: allotment selection, percent clamping and flooring (never "100% used" while credits remain), tones, currency conversion, relative refill time.
  • client/src/components/Balance/__tests__/Summary.spec.tsx: each display mode, loading, error, empty record, no auto-refill, out of credits.
  • client/src/components/Chat/Input/TokenUsage/index.spec.tsx: fresh-chat visibility with and without balance, placement below the context window, balance-only gauge when context usage is off, gauge and settings rendering the same text in all three modes, the card's viewport caps, the balance-only ring's tone and meter semantics, and the non-positive refill amount. Every one of these tests was checked to fail with its fix removed.
  • packages/client/src/components/Progress.spec.tsx: variants, aria-valuenow, and a reference theme.
  • Focused client suites (TokenUsage, Balance, Nav/Settings, UnifiedSidebar) plus the message error spec: 54 suites, 509 tests pass. npx tsc --noEmit clean in client, packages/client and packages/data-provider.

Screenshots / recordings

Each image is the real gauge card (bottom left, opened) beside the real Settings › Account › Billing rows (top right), rendered under the app stylesheet in the harness described in Testing. "Before" is dev at the base of this branch with the same balance (3,100,000 credits, 5,000,000 refill every 7 days); the account-menu line it also showed is not pictured.

Before (dev) After (balance.display: credits)
Before, dark After, credits, dark
Before, light After, currency, light

The other states have no "before", since the section is new:

currency percent
Currency mode Percent mode
Running low (92% used) Out of credits
Running low Out of credits
Fresh chat, no context yet interface.contextUsage: false
Fresh chat Balance-only gauge
No auto-refill
No auto-refill

Risk / compatibility

  • The percent is measured against the allotment under the current configuration. If an admin changes refillAmount or startBalance, existing users' percent moves immediately and settles at their next refill; measuring against the allotment that produced their current credits would need a per-user persisted allotment, which this display change does not add.
  • New config field balance.display, defaulting to credits, so the figure itself is unchanged for existing deployments; the location moves from the account menu to the gauge.
  • The gauge now appears on message-less chats when balance is enabled.
  • com_nav_info_balance is no longer used and was removed from the English locale.
  • The shadcn/no-arbitrary-values suppression for the popover's transition class moved with the code from TokenUsage/index.tsx to TokenUsage/Popover.tsx.

@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-05T10:31:23.253729Z 2d21b74 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: 185588307a

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const enabled = config?.enabled === true;
const query = useGetUserBalance({
enabled: isAuthenticated === true && enabled,
staleTime: BALANCE_STALE_MS,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refresh the balance after billed turns

staleTime only controls when React Query considers cached data stale; it does not schedule a refetch. No turn-completion path invalidates QueryKeys.balance, so the balance-only indicator remains on its initial value for the entire mounted chat, while reopening the normal gauge within 30 seconds can also reuse the pre-turn value indefinitely if left open. Invalidate or refetch the balance when a billed turn settles.

AGENTS.md reference: AGENTS.md:L201-L203

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not changing this — the premise doesn't hold. Both stream hooks refetch the balance query when a turn settles and when it errors: useResumableSSE.ts calls balanceQuery.refetch() in the final handler (L2241) and the error path (L3184), and useSSE.ts does the same (L142, L209). refetch() ignores staleTime and writes the shared [QueryKeys.balance] cache entry, so every observer re-renders with the post-turn value, including the balance-only indicator and an open card. staleTime here only stops a hover-mounted card from issuing its own fetch within 30 s of a reading.

Comment thread client/src/locales/en/translation.json Outdated
Comment on lines +66 to +68
"com_ui_balance_refill_amount_in": "+{{0}} {{1}}",
"com_ui_balance_refill_amount_when_empty": "+{{0}} when you run out",
"com_ui_balance_refill_in": "Refills {{0}}",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Label the refill date as an eligibility date

For auto-refill users whose balance can still cover another prompt, this copy promises a refill at the displayed time, but packages/data-schemas/src/methods/transaction.ts:516 applies it only after the interval has elapsed and the attempted charge would exhaust the balance. Thus Refills in 3 days or +$5.00 in 3 days can pass without any refill; describe this as becoming eligible in that time rather than as a scheduled deposit.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 88def90. Future eligibility now reads "Refill available in 3 days" / "+$5.00 available in 3 days"; past-due keeps "Refills when you run out", which matches transaction.ts:516 (applied when a charge would exhaust the balance). Specs updated in Summary.spec.tsx.

}
}}
className={cn(
'border-border-medium bg-surface-secondary text-text-primary z-[200] rounded-xl border p-3 shadow-lg focus:outline-none',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore viewport bounds on the usage popover

On narrow or short viewports, the extracted popover no longer has the previous max-w-[calc(100vw-1rem)], max-h-[calc(100dvh-1rem)], or overflow scrolling, while both callers still render a fixed w-72 child. The card can therefore extend beyond the viewport and make balance/context details unreachable, especially on small mobile screens or landscape layouts; restore the viewport caps and scrolling behavior.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 88def90. Valid, and a regression of my own: the extraction was written from a read of TokenUsage/index.tsx taken before the branch synced with dev, so it dropped dev's max-h-[calc(100dvh-1rem)] max-w-[calc(100vw-1rem)] overflow-y-auto overscroll-contain, the hideOnInteractOutside close fix, the v4 outline-hidden rename and w-72 max-w-full. All restored verbatim; the remaining diff against dev in that file is only code moved into Popover.tsx. index.spec.tsx "keeps the card inside the viewport" fails with the caps removed.

Comment on lines +193 to +197
role="meter"
aria-valuemin={0}
aria-valuemax={100}
aria-valuenow={usedPercent ?? undefined}
aria-label={localize('com_ui_balance_used_label')}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid rendering an indeterminate meter

While the balance request is loading or failed, and whenever no positive allotment is available, usedPercent is null, so this new role="meter" is rendered without the required aria-valuenow. Unlike a progress bar, a meter has no indeterminate state, leaving assistive technology without a valid current value during every initial balance-only load. Render a non-meter loading/error indicator until the percentage is known, or supply separate valid semantics for those states.

AGENTS.md reference: AGENTS.md:L199-L200

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 88def90. The balance-only trigger is a role="meter" with aria-valuenow only once there is a share to report; while loading, failed, or with nothing to measure against, the ring is aria-hidden and the button's aria-label names it (and the button is aria-busy while loading). Covered by "exposes no valueless meter…" in index.spec.tsx, which fails with the guard removed.

Comment on lines +56 to +58
let value = '';
if (display === 'percent') {
value = usedPercent != null ? localize('com_ui_balance_used', { 0: String(usedPercent) }) : '';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle percent mode without a positive allotment

When an existing valid configuration uses display: percent with startBalance: 0 or a negative value and auto-refill is off, positive(startBalance) produces no allotment and this branch deliberately renders the primary balance value as an empty string. The schema still accepts those startBalance values, so users see a Usage limit heading with no usage figure at all. Either reject this configuration, derive a valid denominator, or show an explicit localized unavailable state instead of a blank successful reading.

AGENTS.md reference: AGENTS.md:L49-L52

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 88def90. Percent mode without a positive allotment now shows a localized "Usage unavailable" instead of a blank figure, and an empty balance reads "100% used" / "Out of credits" whatever it is measured against (getUsedPercent checks credits before the allotment). Both cases are in Summary.spec.tsx and each fails with its fix removed.

aria-label={localize('com_ui_balance_used_label')}
className="flex items-center justify-center"
>
<Gauge percent={usedPercent ?? 0} indeterminate={usedPercent == null} />

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the balance gauge amber until it is empty

When interface.contextUsage is disabled and a user has 91–99% of their allotment spent, this balance-only ring is passed to the generic context Gauge, whose getStrokeClass switches to stroke-status-error above 90%. The balance summary, however, classifies every nonempty balance from 90–99% as warning and renders it amber, reserving red/danger for zero credits. Use the balance tone when coloring this ring so the closed gauge does not report an error while its card reports only a warning.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 88def90. Gauge takes an optional tone, and the balance-only ring passes the summary's tone, so 90–99% spent is amber in both the ring and the card and red is reserved for an empty balance. "tints the balance-only ring with the balance tone" in index.spec.tsx asserts stroke-status-warning at 92% and fails without the prop.

@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@codegraph-librechat codegraph-librechat Bot added the 🗺️ Chat Frontend codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9) label Oct 5, 2026

@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: 06e749bc6f

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +72 to +73
const allotment = refillAmount ?? positive(startBalance);
const usedPercent = getUsedPercent(credits, allotment);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve the allotment that produced the current balance

When an administrator changes startBalance or refillAmount, this denominator immediately adopts the new configuration even though existing credits still came from the old allotment. In particular, packages/api/src/middleware/balance.ts:75-76 leaves existing credits untouched, while lines 101-103 overwrite the stored refill amount; for non-refilling users, the original starting balance is not stored at all. An existing user with 5,000 of a 10,000-credit allotment therefore jumps from 50% to 95% used, including a false warning tone, if the configured allotment becomes 100,000. Persist the allotment associated with the current balance or rebase the balance when the configuration changes before deriving this percentage.

AGENTS.md reference: AGENTS.md:L49-L52

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not changing this in this PR — it's a definitional choice, now documented in the PR's Risk section. The percent is measured against the allotment one full period grants under the current configuration: refillAmount with auto-refill, else startBalance. After an admin raises it, the next refill adds the new amount (transaction.ts applies record.refillAmount, which middleware/balance.ts:101-103 has already synced), so the reading converges at the next refill; reading 95% in the meantime says accurately how much of a full period's grant remains under the new terms. Measuring against the allotment that produced the current credits needs a per-user persisted allotment (a data-schemas field on the balance record and a migration for existing users), which is a backend change outside a display PR. Both surfaces read the same denominator, so the gauge and Settings never disagree.

@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@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: 06e749bc6f

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +3399 to +3400
/** How the UI presents the balance; `credits` keeps the raw figure. */
display: z.enum(BALANCE_DISPLAY_MODES).optional().default('credits'),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply balance display mode to insufficient-funds errors

When an administrator selects currency or percent, an unaffordable request still reaches BalanceError.tsx, whose summary formats both tokenCost and balance as raw credits and explicitly labels them as credits. This bypasses the new UI-wide display setting; most notably, percent mode exposes the exact credit figures it is intended to hide. Have this failure surface honor the configured mode, using currency formatting or percent-safe copy as appropriate.

AGENTS.md reference: AGENTS.md:L49-L52

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 5790676. BalanceError now reads the deployment's mode through useBalanceDisplay() and formats with the same formatBalanceAmount the gauge and settings use: credits keep the existing copy, currency says "It costs $8.40 and your balance is $1.25", and percent shows "You do not have enough balance left for this request." with no figures. The old formatCredits helper in parts.tsx is gone. Two new cases in Error.spec.tsx (currency, percent) each fail with their branch removed. I also swept the client for other credit/balance renderers (tokenCredits, tokenCost, balance reads); this was the only remaining one.

Comment on lines +16 to +17
if (state.status !== 'success' || balance == null) {
return null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Render auto-refill query states in filtered settings

When a user searches Settings for “Auto-Refill,” the registry mounts this entry without the sibling TokenCredits entry. During the balance request's initial load or after it fails, this return therefore leaves the matched search result completely blank; the loader or error rendered by Balance is absent because that component was filtered out. Render an appropriate loading/error state here instead of returning null.

AGENTS.md reference: AGENTS.md:L49-L52

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 5790676. AutoRefill now renders its own skeleton (aria-busy) while the balance loads and "Error loading auto-refill settings." (role="alert") when it fails, so a search that matches only this entry is never blank. Both states are covered in index.spec.tsx and fail with their branch removed.

@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@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: 5790676bcc

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/utils/balance.ts Outdated
Comment on lines +102 to +104
/** Whole credits, except below one, where a rounded "0" would hide a real amount */
const fraction = Math.abs(credits) < 1 ? 2 : 0;
return new Intl.NumberFormat(undefined, { maximumFractionDigits: fraction }).format(credits);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve fractional precision for credit amounts

When pricing uses a fractional credits-per-token multiplier, stored balances and request costs can both contain fractional credits, but this formatter drops all decimals as soon as the value reaches 1. Since BalanceError now formats both figures through this helper, an insufficient-funds case such as a cost of 100.4 against a balance of 100.3 is reported as needing 100 credits with a balance of 100 credits; the balance summary is similarly inaccurate. Preserve fractional precision in credits mode, as the previous maximum-two-decimal formatter did.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in 599fa8e. Credits mode formats with maximumFractionDigits: 2 at every magnitude, as the old error formatter did, so 100.4 against 100.3 stays distinguishable while whole balances still print as 3,100,000. balance.spec.ts "formats credits without hiding fractional differences" fails with the previous rounding restored.

…rcent

Move the balance out of the account menu into the composer's context gauge,
below the context window, and add `balance.display` (credits | currency |
percent, default credits) to choose how it reads. Currency reuses
`interface.currency` at 1,000,000 credits per USD; percent shows only the
share of the period's allotment spent.

Settings > Account > Billing renders the same summary from the same hook, so
both surfaces show identical figures, bar and refill timing in every mode.
…n Hover

Admin overrides reach the client without schema validation, so an unknown
`balance.display` now reads as credits instead of being typed as a mode it is
not. Hovering the gauge mounts the balance reader each time the card opens; a
30 s stale window stops every hover from refetching, while the explicit
refetch after each turn still bypasses it.
The popover extraction was written from a pre-sync read of TokenUsage, so it
dropped dev's viewport caps and scrolling, the hideOnInteractOutside close fix,
the Tailwind v4 outline-hidden rename, and the card's max-w-full; restore them.

Refill copy now says when a refill becomes available rather than promising a
deposit, since one lands only once the interval has passed and a charge would
exhaust the balance. An empty balance reads as fully used even without an
allotment, percent mode without one says usage is unavailable instead of
leaving the figure blank, the balance-only ring takes the balance tone (amber
until empty) and is a meter only once it has a value.
The server never refills when the amount is not positive, and the balance
summary already says so; Settings showed its load error instead.
The token-balance error still printed raw credit figures, so `percent` leaked
the numbers it hides and `currency` mixed units with the gauge. It now reads
the same display mode and formatter as the balance summary: credits as before,
money in currency mode, no figures in percent mode.

The auto-refill settings row also renders its own loading and failure states,
since settings search can show it without the balance row beside it.
Credit amounts keep up to two decimals, so an insufficient-funds message no
longer reads 100.4 against 100.3 as 100 against 100; whole amounts still print
without decimals.

The design-rule backlog may not follow code into a new file, so the extracted
popover uses the standard `transition` utility instead of the arbitrary
`transition-[opacity,transform]` (which also misses Tailwind v4's separate
`translate` and `scale` properties) and its suppression is removed. The
composer geometry spec now reads the classes from `Popover.tsx`, where the
gauge button lives.
@danny-avila
danny-avila force-pushed the danny-avila/librechat-balance-limits-ui-12ea06 branch from 599fa8e to 2d21b74 Compare October 5, 2026 10:22
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: 2d21b740b1

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danny-avila
danny-avila marked this pull request as ready for review October 5, 2026 10:46
@danny-avila
danny-avila merged commit 82cde52 into dev Oct 5, 2026
57 of 58 checks passed
@danny-avila
danny-avila deleted the danny-avila/librechat-balance-limits-ui-12ea06 branch October 5, 2026 10:46
@romy651

romy651 commented Oct 5, 2026

Copy link
Copy Markdown

Hi @danny-avila,
Can you check if this PR is aligned with this feature:
#16774

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🗺️ Chat Frontend codegraph: the taxonomy area this belongs to (classifier, confidence ≥ 0.9)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants