on main help sign in
fix: improve retry

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>

commitfa822909be01eda4de16064eb188160a9e9db77b authorCarlos Alexandro Becker <caarlos0@users.noreply.github.com> dateWed 24 Sep 2025, 14:38 (1 year ago) parent685c81b
3 files changed+39−3
internal/llm/provider/anthropic.go+12−1 internal/llm/provider/gemini.go+15−1 internal/llm/provider/openai.go+12−1
internal/llm/provider/anthropic.go+12−1
@@ -509,7 +509,18 @@ func (a *anthropicClient) shouldRetry(attempts int, err error) (bool, int64, err
509509 isOverloaded := strings.Contains(apiErr.Error(), "overloaded") || strings.Contains(apiErr.Error(), "rate limit exceeded")
510510 // 529 (unofficial): The service is overloaded
511511 if apiErr.StatusCode != http.StatusTooManyRequests && apiErr.StatusCode != 529 && !isOverloaded {
512− return false, 0, err
512+ prev := a.providerOptions.apiKey
513+ // in case the key comes from a script, we try to re-evaluate it.
514+ a.providerOptions.apiKey, err = config.Get().Resolve(a.providerOptions.config.APIKey)
515+ if err != nil {
516+ return false, 0, fmt.Errorf("failed to resolve API key: %w", err)
517+ }
518+ // if it didn't change, do not retry.
519+ if prev == a.providerOptions.apiKey {
520+ return false, 0, err
521+ }
522+ a.client = createAnthropicClient(a.providerOptions, a.tp)
523+ return true, 0, nil
513524 }
514525
515526 retryMs := 0
internal/llm/provider/gemini.go+15−1
@@ -436,7 +436,21 @@ func (g *geminiClient) shouldRetry(attempts int, err error) (bool, int64, error)
436436
437437 // Check for token expiration (401 Unauthorized)
438438 if contains(errMsg, "unauthorized", "invalid api key", "api key expired") {
439− return false, 0, err
439+ prev := g.providerOptions.apiKey
440+ // in case the key comes from a script, we try to re-evaluate it.
441+ g.providerOptions.apiKey, err = config.Get().Resolve(g.providerOptions.config.APIKey)
442+ if err != nil {
443+ return false, 0, fmt.Errorf("failed to resolve API key: %w", err)
444+ }
445+ // if it didn't change, do not retry.
446+ if prev == g.providerOptions.apiKey {
447+ return false, 0, err
448+ }
449+ g.client, err = createGeminiClient(g.providerOptions)
450+ if err != nil {
451+ return false, 0, fmt.Errorf("failed to create Gemini client after API key refresh: %w", err)
452+ }
453+ return true, 0, nil
440454 }
441455
442456 // Check for common rate limit error messages
internal/llm/provider/openai.go+12−1
@@ -515,7 +515,18 @@ func (o *openaiClient) shouldRetry(attempts int, err error) (bool, int64, error)
515515 if errors.As(err, &apiErr) {
516516 // Check for token expiration (401 Unauthorized)
517517 if apiErr.StatusCode == http.StatusUnauthorized {
518− return false, 0, err
518+ prev := o.providerOptions.apiKey
519+ // in case the key comes from a script, we try to re-evaluate it.
520+ o.providerOptions.apiKey, err = config.Get().Resolve(o.providerOptions.config.APIKey)
521+ if err != nil {
522+ return false, 0, fmt.Errorf("failed to resolve API key: %w", err)
523+ }
524+ // if it didn't change, do not retry.
525+ if prev == o.providerOptions.apiKey {
526+ return false, 0, err
527+ }
528+ o.client = createOpenAIClient(o.providerOptions)
529+ return true, 0, nil
519530 }
520531
521532 if apiErr.StatusCode != http.StatusTooManyRequests && apiErr.StatusCode != http.StatusInternalServerError {