Skip to content

Conversation

roomote[bot]
Copy link

@roomote roomote bot commented Sep 12, 2025

Fixes #7922

Summary

This PR improves the UI display when rate limits are triggered by replacing error-like text with a neutral loading state that includes a spinner and countdown timer.

Changes

  • Created new RateLimitCountdown component to display rate limit messages with neutral styling
  • Shows a progress spinner with countdown timer and retry attempt information
  • Uses neutral colors instead of error colors for better UX
  • Added translation strings for rate limit messages
  • Updated ChatRow component to properly handle api_req_retry_delayed messages

Testing

  • All existing tests pass
  • Linting and type checking pass
  • The component properly parses and displays rate limit messages with countdown

Screenshots

The new component displays:

  • A neutral loading spinner
  • Countdown timer showing seconds remaining
  • Current retry attempt number
  • Smooth transition to "Retrying now..." when countdown reaches 0

This provides a much better user experience compared to the previous error-like display.


Important

Adds RateLimitCountdown component for neutral rate limit UI with spinner and countdown, updating ChatRow and translations.

  • UI Component:
    • Adds RateLimitCountdown component in RateLimitCountdown.tsx to display rate limit messages with a spinner and countdown timer.
    • Uses neutral colors instead of error colors.
  • Integration:
    • Updates ChatRow.tsx to handle api_req_retry_delayed messages using RateLimitCountdown.
  • Translations:
    • Adds translation strings for rate limit messages in multiple language files including chat.json for ca, de, and en.
  • Behavior:
    • Displays a spinner, countdown timer, and retry attempt number.
    • Smooth transition to "Retrying now..." when countdown reaches 0.

This description was created by Ellipsis for 7c1dc63. You can customize this summary. It will automatically update as commits are pushed.

- Created RateLimitCountdown component to display rate limit messages
- Shows spinner with countdown timer and retry attempt info
- Uses neutral styling instead of error colors
- Added translations for rate limit messages
- Updated ChatRow to properly handle api_req_retry_delayed messages

Fixes #7922
@roomote roomote bot requested review from mrubens, cte and jr as code owners September 12, 2025 03:22
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. UI/UX UI/UX related or focused labels Sep 12, 2025
Copy link
Author

@roomote roomote bot left a comment

Choose a reason for hiding this comment

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

Reviewing my own code is like debugging in a mirror - everything looks backwards but the bugs are still mine.

const isRetryingNow = message.toLowerCase().includes("retrying now")

return (
<div
Copy link
Author

Choose a reason for hiding this comment

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

This component uses extensive inline styles instead of Tailwind CSS classes. Is this intentional? The rest of the codebase follows the Tailwind convention (as mentioned in the rules), so it would be more consistent to use classes like instead of inline styles.

isRetrying?: boolean
}

export const RateLimitCountdown: React.FC<RateLimitCountdownProps> = ({ message, isRetrying = false }) => {
Copy link
Author

Choose a reason for hiding this comment

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

The prop is passed in but never actually used in the component logic. Only is checked for determining the title. Could we either remove this prop or use it as intended?

// Parse the message to extract countdown seconds and retry attempt info
const { seconds, attemptInfo } = useMemo(() => {
// Match patterns like "Retrying in X seconds" or "Rate limiting for X seconds"
const secondsMatch = message.match(/(\d+)\s+second/i)
Copy link
Author

Choose a reason for hiding this comment

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

These regex patterns might fail with unexpected message formats. Could we add more robust parsing or fallback behavior? For example:

isRetrying?: boolean
}

export const RateLimitCountdown: React.FC<RateLimitCountdownProps> = ({ message, isRetrying = false }) => {
Copy link
Author

Choose a reason for hiding this comment

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

Since this component will re-render frequently with countdown updates, could we wrap it in to improve performance? The component only needs to re-render when the message prop actually changes.

maxHeight: "200px",
overflowY: "auto",
}}>
{message.split("\n\n")[0]}
Copy link
Author

Choose a reason for hiding this comment

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

This logic for extracting error details seems fragile. The component splits by "

" and shows the first part, but is this guaranteed to contain the actual error details? Could we make this more explicit or add a comment explaining the expected message format?

@@ -0,0 +1,113 @@
import React, { useMemo } from "react"
Copy link
Author

Choose a reason for hiding this comment

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

Missing test coverage for this new component. Could we add tests to verify:

  • Correct parsing of countdown seconds
  • Proper display of retry attempts
  • Transition to "Retrying now..." state
  • Error details expansion/collapse behavior

- Added rate limit translations to all locale files
- Ensures consistency across all supported languages
@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Sep 12, 2025
@@ -390,5 +390,15 @@
"slashCommand": {
"wantsToRun": "Roo 想要執行斜線指令:",
"didRun": "Roo 執行了斜線指令:"
},
"rateLimit": {
Copy link

Choose a reason for hiding this comment

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

The new translation keys 'rateLimit' and 'rateLimitRetry' (lines 394-403) still contain English strings. Please provide proper Traditional Chinese translations to maintain localization consistency.

This comment was generated because it violated a code review rule: irule_C0ez7Rji6ANcGkkX.

@daniel-lxs daniel-lxs moved this from Triage to PR [Needs Prelim Review] in Roo Code Roadmap Sep 12, 2025
@hannesrudolph hannesrudolph added PR - Needs Preliminary Review and removed Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. labels Sep 12, 2025
@daniel-lxs
Copy link
Collaborator

Here's how it looks now
image
I would love to have this in a single block and just have it update rather than having a ton of these blocks throughout my task.

Also I see the word "retry" a lot, this could be way more compact.

@daniel-lxs daniel-lxs moved this from PR [Needs Prelim Review] to PR [Needs Review] in Roo Code Roadmap Sep 12, 2025
@daniel-lxs daniel-lxs moved this from PR [Needs Review] to PR [Changes Requested] in Roo Code Roadmap Sep 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR - Changes Requested size:L This PR changes 100-499 lines, ignoring generated files. UI/UX UI/UX related or focused
Projects
Status: PR [Changes Requested]
Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT] Spinner + countdown with rate limit triggered — please wait
3 participants