fix: add rate-limit retry with exponential backoff
The retry loop only handled context/token errors, letting 429s and rate-limit responses fail immediately. Add detection for 429, rate_limit, resource_exhausted, overloaded, quota, and too_many_requests errors with exponential backoff (5s, 10s, 20s). Works regardless of whether fallback candidates are configured.
This commit is contained in:
parent
09061d8175
commit
751c7f4839
1 changed files with 30 additions and 2 deletions
|
|
@ -617,8 +617,8 @@ func (al *AgentLoop) runLLMIteration(ctx context.Context, agent *AgentInstance,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retry loop for context/token errors
|
// Retry loop for recoverable errors (context window + rate limits).
|
||||||
maxRetries := 2
|
maxRetries := 3
|
||||||
for retry := 0; retry <= maxRetries; retry++ {
|
for retry := 0; retry <= maxRetries; retry++ {
|
||||||
response, err = callLLM()
|
response, err = callLLM()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
@ -626,6 +626,34 @@ func (al *AgentLoop) runLLMIteration(ctx context.Context, agent *AgentInstance,
|
||||||
}
|
}
|
||||||
|
|
||||||
errMsg := strings.ToLower(err.Error())
|
errMsg := strings.ToLower(err.Error())
|
||||||
|
|
||||||
|
// Rate-limit / transient errors: wait with exponential backoff.
|
||||||
|
isRateLimitError := strings.Contains(errMsg, "429") ||
|
||||||
|
strings.Contains(errMsg, "rate limit") ||
|
||||||
|
strings.Contains(errMsg, "rate_limit") ||
|
||||||
|
strings.Contains(errMsg, "resource_exhausted") ||
|
||||||
|
strings.Contains(errMsg, "resource exhausted") ||
|
||||||
|
strings.Contains(errMsg, "too many requests") ||
|
||||||
|
strings.Contains(errMsg, "overloaded") ||
|
||||||
|
strings.Contains(errMsg, "quota")
|
||||||
|
|
||||||
|
if isRateLimitError && retry < maxRetries {
|
||||||
|
backoff := time.Duration(1<<uint(retry)) * 5 * time.Second // 5s, 10s, 20s
|
||||||
|
logger.WarnCF("agent", "Rate limit detected, backing off", map[string]interface{}{
|
||||||
|
"error": err.Error(),
|
||||||
|
"retry": retry + 1,
|
||||||
|
"backoff": backoff.String(),
|
||||||
|
})
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return "", iteration, ctx.Err()
|
||||||
|
case <-time.After(backoff):
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context window errors: compress history and retry.
|
||||||
isContextError := strings.Contains(errMsg, "token") ||
|
isContextError := strings.Contains(errMsg, "token") ||
|
||||||
strings.Contains(errMsg, "context") ||
|
strings.Contains(errMsg, "context") ||
|
||||||
strings.Contains(errMsg, "invalidparameter") ||
|
strings.Contains(errMsg, "invalidparameter") ||
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue