IsStreamTruncationError reports whether err indicates the model stream was cut off before a clean completion: the connection was dropped or the body was truncated mid-stream. See [streamTruncationPatterns] for why this happens and why it is treated as retryable. Context cancellation/deadline is exc
(err error)
| 426 | // request down (e.g. the idle-timeout cancel or a user Ctrl+C), not an upstream |
| 427 | // drop, and must stay non-retryable. |
| 428 | func IsStreamTruncationError(err error) bool { |
| 429 | if err == nil { |
| 430 | return false |
| 431 | } |
| 432 | if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { |
| 433 | return false |
| 434 | } |
| 435 | msg := strings.ToLower(err.Error()) |
| 436 | for _, p := range streamTruncationPatterns { |
| 437 | if strings.Contains(msg, p) { |
| 438 | return true |
| 439 | } |
| 440 | } |
| 441 | return false |
| 442 | } |
| 443 | |
| 444 | // nonRetryablePatterns contains error message substrings that indicate a |
| 445 | // permanent/non-retryable failure. Numeric status codes (429, 401, etc.) are |