Skip to content

feat: OpenUsage rate limits panel (from dpcode)#63

Open
aaditagrawal wants to merge 2 commits intomainfrom
feat/dpcode-rate-limits
Open

feat: OpenUsage rate limits panel (from dpcode)#63
aaditagrawal wants to merge 2 commits intomainfrom
feat/dpcode-rate-limits

Conversation

@aaditagrawal
Copy link
Copy Markdown
Owner

@aaditagrawal aaditagrawal commented Apr 12, 2026

Summary

Ports the OpenUsage rate limits feature from the dpcode fork. This adds:

  • Rate limits library (lib/rateLimits.ts) — shared rate-limit parsing, normalization, formatting
  • OpenUsage integration (lib/openUsageRateLimits.ts) — normalizes snapshots from the local OpenUsage HTTP service (port 6736) into the shared rate-limit model
  • React Query hooks (lib/openUsageReactQuery.ts) — polls OpenUsage every 15s with graceful fallback
  • Rate Limits Panel (RateLimitsPanel.tsx) — collapsible panel showing per-provider rate limits
  • Rate Limit Summary List (RateLimitSummaryList.tsx) — compact rate-limit row renderer
  • Rate Limit Banner (chat/RateLimitBanner.tsx) — alert banner for rate-limit warnings

Extended provider mappings to support all 8 providers (codex, claude, copilot, cursor, opencode, gemini, amp, kilo).

Test plan

  • Rate limit normalization tests included
  • Panel helper tests included
  • Manual: verify panel renders when OpenUsage is running

Summary by CodeRabbit

  • New Features

    • Collapsible rate limits panel showing remaining capacity, reset timing, and “Learn more” link when available.
    • Inline rate limit summary list for compact display when data exists; shows percent remaining and reset info.
    • Rate limit alert banner that surfaces rejections and warning-level utilization.
    • Integrated external OpenUsage snapshot fetching and normalization for richer provider data.
    • Centralized icon exports for UI consistency.
  • Tests

    • Added comprehensive tests covering rate-limit normalization, merging, row derivation, and formatting.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 12, 2026

📝 Walkthrough

Walkthrough

Adds client-side rate-limit parsing, normalization, and UI: new React components (panel, list, banner), core rate-limit utilities, OpenUsage snapshot normalization and React Query integration, a centralized icon module, and accompanying tests.

Changes

Cohort / File(s) Summary
Rate‑Limit UI Components
apps/web/src/components/RateLimitSummaryList.tsx, apps/web/src/components/RateLimitsPanel.tsx, apps/web/src/components/chat/RateLimitBanner.tsx
New React components: summary list renders rows (label, remaining%, optional reset time); collapsible panel computes rate limits from threads and shows “Learn more” link; banner derives and displays latest account rate-limit status.
Rate‑Limit Core Utilities
apps/web/src/lib/rateLimits.ts
New centralized parsing/normalization/merge/format helpers and types (RateLimitWindow, ProviderRateLimit, VisibleRateLimitRow); derives provider rate limits from orchestration activities, aggregates UI rows, formats percent/reset strings, and computes learn-more URLs.
OpenUsage Integration
apps/web/src/lib/openUsageRateLimits.ts, apps/web/src/lib/openUsageReactQuery.ts
Parses OpenUsage snapshots into provider-normalized rate-limit windows and usage lines; exposes provider ID mapping and React Query options to fetch provider snapshots (15s stale/refetch, disabled when provider unsupported).
Icon Library
apps/web/src/lib/icons.tsx
New centralized icon exports and LucideIcon type aliases for consistent app-wide icon usage (many named exports and aliases).
Tests
apps/web/src/components/RateLimitsPanel.test.tsx, apps/web/src/lib/openUsageRateLimits.test.ts
New Vitest suites covering rate-limit derivation/aggregation/tie-breaking, formatting, OpenUsage snapshot normalization, provider merging, and usage-line parsing.

Sequence Diagram(s)

sequenceDiagram
    participant UI as RateLimitsPanel
    participant Threads as OrchestrationThreads
    participant Derive as deriveAccountRateLimits()
    participant Rows as deriveVisibleRateLimitRows()
    participant Summary as RateLimitSummaryList
    participant Query as openUsageProviderSnapshotQuery
    participant OpenUsage as OpenUsage API

    UI->>Derive: provide threads
    Derive->>Threads: scan activities (account.rate-limits / rate-limited)
    Derive-->>UI: ProviderRateLimit[] (normalized)
    UI->>Rows: rateLimits
    Rows-->>UI: VisibleRateLimitRow[] (deduped, remaining%)
    UI->>Summary: render rows
    Query->>OpenUsage: GET /v1/usage/{providerId}
    OpenUsage-->>Query: snapshot JSON / 204/404/null
    Query-->>UI: normalized snapshot (or null)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰
I nibble through the rate‑limit logs at night,
I stitch windows, percentages, and light,
Panels open neat, banners warn with art,
OpenUsage whispers every beating heart,
Hop, click, and now the limits play their part.

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: OpenUsage rate limits panel (from dpcode)' clearly and specifically summarizes the main change—adding an OpenUsage-based rate limits panel feature ported from the dpcode fork.
Description check ✅ Passed The PR description covers all key required sections: a clear summary of changes, implementation details across components and libraries, extended provider support, and a test plan with both completed and pending manual verification.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dpcode-rate-limits

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 effective changed lines (test files excluded in mixed PRs). labels Apr 12, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/lib/icons.tsx`:
- Around line 1-5: The imports (PiGitCommit, PiSquareSplitHorizontal,
PiSquareSplitVertical, RiApps2Line, TbArrowsRightLeft, TbPlug) in
apps/web/src/lib/icons.tsx reference packages that are not declared in any
package.json; add the missing dependencies (`@tabler/icons-react` and react-icons)
to the repository package manifest (e.g., run bun add or npm/yarn add) for the
web app so the imports resolve, then commit the updated package.json and
lockfile before merging.
- Around line 78-80: Several icon wrappers typed as LucideIcon (AppsIcon,
GitCommitIcon, PlugIcon, HandoffIcon, SquareSplitHorizontal,
SquareSplitVertical) drop props and thus violate the SVGProps contract; update
each component to forward all incoming props to the underlying react-icon
component (use {...props}) following the existing adaptIcon pattern so aria-*,
role, event handlers, sizing, className/style merge correctly and no props are
lost. Locate the functions AppsIcon, GitCommitIcon, PlugIcon, HandoffIcon,
SquareSplitHorizontal and SquareSplitVertical and change their JSX to pass
{...props} into the rendered icon element while keeping any existing
className/style handling consistent with other icons.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8c4b9b7a-36b5-4571-addd-53315829ab72

📥 Commits

Reviewing files that changed from the base of the PR and between b3bd5c3 and 81f1997.

📒 Files selected for processing (9)
  • apps/web/src/components/RateLimitSummaryList.tsx
  • apps/web/src/components/RateLimitsPanel.test.tsx
  • apps/web/src/components/RateLimitsPanel.tsx
  • apps/web/src/components/chat/RateLimitBanner.tsx
  • apps/web/src/lib/icons.tsx
  • apps/web/src/lib/openUsageRateLimits.test.ts
  • apps/web/src/lib/openUsageRateLimits.ts
  • apps/web/src/lib/openUsageReactQuery.ts
  • apps/web/src/lib/rateLimits.ts
👮 Files not reviewed due to content moderation or server errors (8)
  • apps/web/src/components/RateLimitSummaryList.tsx
  • apps/web/src/components/RateLimitsPanel.tsx
  • apps/web/src/lib/openUsageRateLimits.test.ts
  • apps/web/src/components/RateLimitsPanel.test.tsx
  • apps/web/src/lib/openUsageReactQuery.ts
  • apps/web/src/components/chat/RateLimitBanner.tsx
  • apps/web/src/lib/openUsageRateLimits.ts
  • apps/web/src/lib/rateLimits.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/lib/icons.tsx`:
- Around line 133-134: SquareSplitHorizontal and SquareSplitVertical are both
assigned to SplitIcon so they render identical glyphs; update the export for
SquareSplitVertical to point to the correct vertical variant or create a
vertical variant instead of reusing SplitIcon. Locate the exports for
SquareSplitHorizontal, SquareSplitVertical and change SquareSplitVertical to
reference the proper component (e.g., SplitVerticalIcon or a newly created
VerticalSplitIcon), or adjust SplitIcon to accept an orientation prop and export
SquareSplitHorizontal = (props) => <SplitIcon orientation="horizontal"
{...props}> and SquareSplitVertical = (props) => <SplitIcon
orientation="vertical" {...props}> so the two exports render distinct oriented
glyphs.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: abad348e-231d-45ae-9713-56305d27fba0

📥 Commits

Reviewing files that changed from the base of the PR and between 81f1997 and 97f179f.

📒 Files selected for processing (4)
  • apps/web/src/components/RateLimitsPanel.test.tsx
  • apps/web/src/components/RateLimitsPanel.tsx
  • apps/web/src/components/chat/RateLimitBanner.tsx
  • apps/web/src/lib/icons.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/web/src/components/chat/RateLimitBanner.tsx
  • apps/web/src/components/RateLimitsPanel.tsx
  • apps/web/src/components/RateLimitsPanel.test.tsx

Comment on lines +133 to +134
export const SquareSplitHorizontal = SplitIcon;
export const SquareSplitVertical = SplitIcon;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

SquareSplitHorizontal and SquareSplitVertical currently render the same glyph.

Line 133 and Line 134 both point to SplitIcon, so UI contexts that expect orientation-specific visuals won’t be distinguishable.

Suggested fix
 export const SquareSplitHorizontal = SplitIcon;
-export const SquareSplitVertical = SplitIcon;
+export const SquareSplitVertical: LucideIcon = (props) => (
+  <SplitIcon
+    {...props}
+    style={{
+      ...(props.style ?? {}),
+      transform: "rotate(90deg)",
+      transformOrigin: "center",
+    }}
+  />
+);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const SquareSplitHorizontal = SplitIcon;
export const SquareSplitVertical = SplitIcon;
export const SquareSplitHorizontal = SplitIcon;
export const SquareSplitVertical: LucideIcon = (props) => (
<SplitIcon
{...props}
style={{
...(props.style ?? {}),
transform: "rotate(90deg)",
transformOrigin: "center",
}}
/>
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/lib/icons.tsx` around lines 133 - 134, SquareSplitHorizontal and
SquareSplitVertical are both assigned to SplitIcon so they render identical
glyphs; update the export for SquareSplitVertical to point to the correct
vertical variant or create a vertical variant instead of reusing SplitIcon.
Locate the exports for SquareSplitHorizontal, SquareSplitVertical and change
SquareSplitVertical to reference the proper component (e.g., SplitVerticalIcon
or a newly created VerticalSplitIcon), or adjust SplitIcon to accept an
orientation prop and export SquareSplitHorizontal = (props) => <SplitIcon
orientation="horizontal" {...props}> and SquareSplitVertical = (props) =>
<SplitIcon orientation="vertical" {...props}> so the two exports render distinct
oriented glyphs.

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

Labels

size:XL 500-999 effective changed lines (test files excluded in mixed PRs). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant