Skip to content

Conversation

@chrarnoldus
Copy link
Contributor

@chrarnoldus chrarnoldus commented Oct 2, 2025

Kilo PR: Kilo-Org/kilocode#2583

Related GitHub Issue

Maybe fixes: #7770

Description

We received reports from users being rate limited for long periods (longer than the maximum 60s allowed in the UI) without ever enabling the rate limiter (one user mentioned using a laptop with a bad battery). This PR aims to rectify this issue by replacing the non-monotonic Date.now by the monotonic performance.now. Additionally, a check was introduced to never rate-limit for longer than the configured time.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to an approved GitHub Issue (see "Related GitHub Issue" above).
  • Scope: My changes are focused on the linked issue (one major feature/fix per PR).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: New and/or updated tests have been added to cover my changes (if applicable).
  • Documentation Impact: I have considered if my changes require documentation updates (see "Documentation Updates" section below).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Screenshots / Videos

before:

Additional Notes

Also changed the background usage collecting to use performance.now

Get in Touch

Christiaan in shared Slack


Important

Replace Date.now with performance.now for monotonic clock usage in rate limiting and add a check to prevent exceeding configured time.

  • Behavior:
    • Replace Date.now with performance.now in Task.ts for monotonic clock usage in rate limiting.
    • Add check to prevent rate limiting beyond configured time in Task.ts.
  • Tests:
    • Update tests in Task.spec.ts to mock performance.now for simulating time passage.
    • Ensure rate limiting logic is correctly enforced and tested in Task.spec.ts.

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

const originalDateNow = Date.now
const mockTime = Date.now() + (mockApiConfig.rateLimitSeconds + 1) * 1000
Date.now = vi.fn(() => mockTime)
const originalPerformanceNow = performance.now
Copy link
Contributor

Choose a reason for hiding this comment

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

When overriding performance.now here, consider wrapping the override in a try…finally block so that the original function is always restored even if the test fails.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Oct 2, 2025
Copy link
Contributor

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

I found some issues that need attention related to rate-limit delay computation clarity and test robustness.

const timeSinceLastRequest = now - Task.lastGlobalApiRequestTime
const rateLimit = apiConfiguration?.rateLimitSeconds || 0
rateLimitDelay = Math.ceil(Math.max(0, rateLimit * 1000 - timeSinceLastRequest) / 1000)
rateLimitDelay = Math.ceil(Math.min(rateLimit, Math.max(0, rateLimit * 1000 - timeSinceLastRequest) / 1000))
Copy link
Contributor

Choose a reason for hiding this comment

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

P2: Now that this uses a monotonic clock, consider extracting this remaining-delay calculation into a small helper (with unit tests) to make the ms→s conversion and clamping intent explicit. For example: min(rateLimitSeconds, ceil(max(0, remainingMs)/1000)). This helps avoid future regressions and clarifies that lastGlobalApiRequestTime and now are performance.now() values (ms, monotonic).

const originalPerformanceNow = performance.now
const mockTime = performance.now() + (mockApiConfig.rateLimitSeconds + 1) * 1000
performance.now = vi.fn(() => mockTime)

Copy link
Contributor

Choose a reason for hiding this comment

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

P3: Instead of reassigning performance.now directly, prefer vi.spyOn(performance, 'now').mockReturnValue(...) and restore with mockRestore(). This avoids mutating globals and plays nicer with parallel tests.

@dosubot dosubot bot added size:S This PR changes 10-29 lines, ignoring generated files. bug Something isn't working labels Oct 2, 2025
@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Oct 27, 2025
@mrubens mrubens merged commit c232057 into RooCodeInc:main Oct 27, 2025
23 checks passed
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Oct 27, 2025
@github-project-automation github-project-automation bot moved this from Triage to Done in Roo Code Roadmap Oct 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. lgtm This PR has been approved by a maintainer size:S This PR changes 10-29 lines, ignoring generated files.