Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions agent/agent_runtime_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,7 @@ def restore_primary_runtime(agent) -> bool:
# ── Reset fallback chain for the new turn ──
agent._fallback_activated = False
agent._fallback_index = 0

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

restore_primary_runtime() runs before the restored primary has made a successful request. Resetting here means a primary that immediately 429s again always starts at the 30-minute tier, so the proposed exponential sequence never advances. Reset only after an actual successful primary completion.

agent._rate_limit_backoff_count = 0 # reset exponential backoff counter

logging.info(
"Primary runtime restored for new turn: %s (%s)",
Expand Down
11 changes: 10 additions & 1 deletion agent/chat_completion_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,16 @@ def try_activate_fallback(agent, reason: "FailoverReason | None" = None) -> bool
current_provider = (getattr(agent, "provider", "") or "").strip().lower()
primary_provider = ((agent._primary_runtime or {}).get("provider") or "").strip().lower()
if (not fallback_already_active) or (primary_provider and current_provider == primary_provider):
agent._rate_limited_until = time.monotonic() + 60
# Exponential backoff: 30min → 1h → 2h → 4h cap
# Counter is reset by restore_primary_runtime on successful restore.
backoff_count = getattr(agent, "_rate_limit_backoff_count", 0)
agent._rate_limit_backoff_count = backoff_count + 1
backoff_seconds = min(1800 * (2 ** backoff_count), 14400)
agent._rate_limited_until = time.monotonic() + backoff_seconds
logging.info(
"Rate-limit backoff level %d: cooldown %d s (%.1f min, backoff#%d)",
backoff_count, backoff_seconds, backoff_seconds / 60, backoff_count + 1,
)
if agent._fallback_index >= len(agent._fallback_chain):
return False

Expand Down