@@ -5,7 +5,6 @@ import (
5 "encoding/json"
5 "encoding/json"
@@ -88,7 +87,6 @@ func (a *anthropicProvider) SendMessages(ctx context.Context, messages []message
91− option.WithMaxRetries(8),
93 if err != nil {
91 if err != nil {
94 return nil, err
92 return nil, err
@@ -256,11 +254,37 @@ func (a *anthropicProvider) StreamResponse(ctx context.Context, messages []messa
256 // Check for stream errors
254 // Check for stream errors
257 err := stream.Err()
255 err := stream.Err()
258 if err != nil {
256 if err != nil {
259− log.Println("error", err)
261 var apierr *anthropic.Error
257 var apierr *anthropic.Error
262− if errors.As(err, &apierr) && apierr.StatusCode == 429 {
258+ if errors.As(err, &apierr) {
259+ if apierr.StatusCode == 429 || apierr.StatusCode == 529 {
260+ // Check for Retry-After header
261+ if retryAfterValues := apierr.Response.Header.Values("Retry-After"); len(retryAfterValues) > 0 {
262+ // Parse the retry after value (seconds)
263+ var retryAfterSec int
264+ if _, err := fmt.Sscanf(retryAfterValues[0], "%d", &retryAfterSec); err == nil {
265+ retryMs := retryAfterSec * 1000
267+ // Inform user of retry with specific wait time
268+ eventChan <- ProviderEvent{
270+ Info: fmt.Sprintf("[Rate limited: waiting %d seconds as specified by API]", retryAfterSec),
273+ // Sleep respecting context cancellation
276+ eventChan <- ProviderEvent{Type: EventError, Error: ctx.Err()}
278+ case <-time.After(time.Duration(retryMs) * time.Millisecond):
279+ // Continue with retry after specified delay
285+ // Fall back to exponential backoff if Retry-After parsing failed
263− continue
286+ continue
266 // For non-rate limit errors, report and exit
290 // For non-rate limit errors, report and exit
@@ -380,3 +404,4 @@ func (a *anthropicProvider) convertToAnthropicMessages(messages []message.Messag
381 return anthropicMessages
405 return anthropicMessages