mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-02-03 15:43:06 +00:00
fix: address 3 new CodeRabbit review comments
1. agent.py: Reset opposite retry counter when entering rate_limit or error status to prevent mixed events from inflating delays 2. rate_limit_utils.py: Fix parse_retry_after() regex to reject minute/hour units - patterns now require explicit "seconds"/"s" unit or end of string 3. test_rate_limit_utils.py: Add tests for "retry after 5 minutes" and other minute/hour variants to ensure they return None Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
4
agent.py
4
agent.py
@@ -372,6 +372,8 @@ async def run_autonomous_agent(
|
|||||||
|
|
||||||
elif status == "rate_limit":
|
elif status == "rate_limit":
|
||||||
# Smart rate limit handling with exponential backoff
|
# Smart rate limit handling with exponential backoff
|
||||||
|
# Reset error counter so mixed events don't inflate delays
|
||||||
|
error_retries = 0
|
||||||
if response != "unknown":
|
if response != "unknown":
|
||||||
try:
|
try:
|
||||||
delay_seconds = clamp_retry_delay(int(response))
|
delay_seconds = clamp_retry_delay(int(response))
|
||||||
@@ -390,6 +392,8 @@ async def run_autonomous_agent(
|
|||||||
|
|
||||||
elif status == "error":
|
elif status == "error":
|
||||||
# Non-rate-limit errors: linear backoff capped at 5 minutes
|
# Non-rate-limit errors: linear backoff capped at 5 minutes
|
||||||
|
# Reset rate limit counter so mixed events don't inflate delays
|
||||||
|
rate_limit_retries = 0
|
||||||
error_retries += 1
|
error_retries += 1
|
||||||
delay_seconds = calculate_error_backoff(error_retries)
|
delay_seconds = calculate_error_backoff(error_retries)
|
||||||
print("\nSession encountered an error")
|
print("\nSession encountered an error")
|
||||||
|
|||||||
@@ -45,9 +45,13 @@ def parse_retry_after(error_message: str) -> Optional[int]:
|
|||||||
Returns:
|
Returns:
|
||||||
Seconds to wait, or None if not parseable.
|
Seconds to wait, or None if not parseable.
|
||||||
"""
|
"""
|
||||||
|
# Patterns require explicit "seconds" or "s" unit, OR no unit at all (end of string/sentence)
|
||||||
|
# This prevents matching "30 minutes" or "1 hour" since those have non-seconds units
|
||||||
patterns = [
|
patterns = [
|
||||||
r"retry.?after[:\s]+(\d+)\s*(?:seconds?)?",
|
r"retry.?after[:\s]+(\d+)\s*(?:seconds?|s\b)", # Requires seconds unit
|
||||||
r"try again in\s+(\d+)\s*(?:seconds?|s\b)",
|
r"retry.?after[:\s]+(\d+)(?:\s*$|\s*[,.])", # Or end of string/sentence
|
||||||
|
r"try again in\s+(\d+)\s*(?:seconds?|s\b)", # Requires seconds unit
|
||||||
|
r"try again in\s+(\d+)(?:\s*$|\s*[,.])", # Or end of string/sentence
|
||||||
r"(\d+)\s*seconds?\s*(?:remaining|left|until)",
|
r"(\d+)\s*seconds?\s*(?:remaining|left|until)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,12 @@ class TestParseRetryAfter(unittest.TestCase):
|
|||||||
def test_minutes_not_supported(self):
|
def test_minutes_not_supported(self):
|
||||||
"""Test that minutes are not parsed (by design)."""
|
"""Test that minutes are not parsed (by design)."""
|
||||||
# We only support seconds to avoid complexity
|
# We only support seconds to avoid complexity
|
||||||
|
# These patterns should NOT match when followed by minute/hour units
|
||||||
assert parse_retry_after("wait 5 minutes") is None
|
assert parse_retry_after("wait 5 minutes") is None
|
||||||
assert parse_retry_after("try again in 2 minutes") is None
|
assert parse_retry_after("try again in 2 minutes") is None
|
||||||
|
assert parse_retry_after("retry after 5 minutes") is None
|
||||||
|
assert parse_retry_after("retry after 1 hour") is None
|
||||||
|
assert parse_retry_after("try again in 30 min") is None
|
||||||
|
|
||||||
|
|
||||||
class TestIsRateLimitError(unittest.TestCase):
|
class TestIsRateLimitError(unittest.TestCase):
|
||||||
|
|||||||
Reference in New Issue
Block a user