diff --git a/.dotnet/src/Custom/OpenAIClientOptions.cs b/.dotnet/src/Custom/OpenAIClientOptions.cs index 610341c52..be6829632 100644 --- a/.dotnet/src/Custom/OpenAIClientOptions.cs +++ b/.dotnet/src/Custom/OpenAIClientOptions.cs @@ -9,6 +9,11 @@ namespace OpenAI; [CodeGenModel("OpenAIClientOptions")] public partial class OpenAIClientOptions : ClientPipelineOptions { + public OpenAIClientOptions() + { + RetryPolicy = new HeaderInformedRetryPolicy(); + } + /// /// A non-default base endpoint that clients should use when connecting. /// @@ -28,4 +33,32 @@ public partial class OpenAIClientOptions : ClientPipelineOptions /// An optional ID added to OpenAI-Project header /// public string ProjectId { get; init; } + + private class HeaderInformedRetryPolicy : ClientRetryPolicy + { + protected override TimeSpan GetNextDelay(PipelineMessage message, int tryCount) + { + TimeSpan? TryGetTimeSpanFromHeader(string headerName, int millisecondsPerValue = 1, bool allowDateTimeOffset = false) + { + if (double.TryParse( + message?.Response?.Headers?.TryGetValue(headerName, out string textValue) == true ? textValue : null, + out double doubleValue) == true) + { + return TimeSpan.FromMilliseconds(millisecondsPerValue * doubleValue); + } + else if (allowDateTimeOffset && DateTimeOffset.TryParse(headerName, out DateTimeOffset delayUntil)) + { + return delayUntil - DateTimeOffset.Now; + } + return null; + } + + TimeSpan? delayFromHeader = + TryGetTimeSpanFromHeader("retry-after-ms") + ?? TryGetTimeSpanFromHeader("x-ms-retry-after-ms") + ?? TryGetTimeSpanFromHeader("Retry-After", millisecondsPerValue: 1000, allowDateTimeOffset: true); + + return delayFromHeader ?? base.GetNextDelay(message, tryCount); + } + } }