56 lines
1.0 KiB
Go
56 lines
1.0 KiB
Go
package llm
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
type retryableError struct {
|
|
err error
|
|
}
|
|
|
|
func (e retryableError) Error() string {
|
|
if e.err == nil {
|
|
return ""
|
|
}
|
|
return e.err.Error()
|
|
}
|
|
|
|
func (e retryableError) Unwrap() error {
|
|
return e.err
|
|
}
|
|
|
|
func validateOutputTarget(out any) error {
|
|
if out == nil {
|
|
return fmt.Errorf("structured completion output target must be a non-nil pointer")
|
|
}
|
|
value := reflect.ValueOf(out)
|
|
if value.Kind() != reflect.Pointer || value.IsNil() {
|
|
return fmt.Errorf("structured completion output target must be a non-nil pointer")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func canRetry(ctx context.Context, attempt int, maxRetries int, err error) bool {
|
|
if attempt >= maxRetries {
|
|
return false
|
|
}
|
|
if ctx.Err() != nil {
|
|
return false
|
|
}
|
|
var retryable retryableError
|
|
return errors.As(err, &retryable)
|
|
}
|
|
|
|
func firstNonEmpty(values ...string) string {
|
|
for _, value := range values {
|
|
if trimmed := strings.TrimSpace(value); trimmed != "" {
|
|
return trimmed
|
|
}
|
|
}
|
|
return ""
|
|
}
|