diff --git a/Anthropic.SDK/Anthropic.SDK.csproj b/Anthropic.SDK/Anthropic.SDK.csproj
index 2a87a04..fce3ba6 100644
--- a/Anthropic.SDK/Anthropic.SDK.csproj
+++ b/Anthropic.SDK/Anthropic.SDK.csproj
@@ -14,12 +14,12 @@
Claude, AI, ML, API, Anthropic
Claude API
- Update to latest version of Microsoft.Extensions.AI.Abstractions
+ Fixes a critical bug that causes the library to make double requests, increasing latency and cost.
Anthropic.SDK
- 5.2.1
- 5.2.1.0
- 5.2.1.0
+ 5.2.2
+ 5.2.2.0
+ 5.2.2.0
True
README.md
icon.png
diff --git a/Anthropic.SDK/BaseEndpoint.cs b/Anthropic.SDK/BaseEndpoint.cs
index ec8e38a..90f5877 100644
--- a/Anthropic.SDK/BaseEndpoint.cs
+++ b/Anthropic.SDK/BaseEndpoint.cs
@@ -11,6 +11,7 @@
using System.Threading;
using System.Threading.Tasks;
using Anthropic.SDK.Messaging;
+using System.Linq;
namespace Anthropic.SDK
{
@@ -57,10 +58,37 @@ protected async Task HttpRequestMessages(string url = null
using var ms = new MemoryStream(Encoding.UTF8.GetBytes(resultAsString));
var res = await JsonSerializer.DeserializeAsync(ms, options, cancellationToken: ctx).ConfigureAwait(false);
-
+ if (res is MessageResponse messageResponse)
+ {
+ messageResponse.RateLimits = GetRateLimits(response);
+ }
return res;
}
+ protected RateLimits GetRateLimits(HttpResponseMessage message)
+ {
+ var rateLimits = new RateLimits();
+
+ TryParseHeaderValue(message, "anthropic-ratelimit-requests-limit", long.Parse, value => rateLimits.RequestsLimit = value);
+ TryParseHeaderValue(message, "anthropic-ratelimit-requests-remaining", long.Parse, value => rateLimits.RequestsRemaining = value);
+ TryParseHeaderValue(message, "anthropic-ratelimit-requests-reset", DateTime.Parse, value => rateLimits.RequestsReset = value);
+ TryParseHeaderValue(message, "anthropic-ratelimit-tokens-limit", long.Parse, value => rateLimits.TokensLimit = value);
+ TryParseHeaderValue(message, "anthropic-ratelimit-tokens-remaining", long.Parse, value => rateLimits.TokensRemaining = value);
+ TryParseHeaderValue(message, "anthropic-ratelimit-tokens-reset", DateTime.Parse, value => rateLimits.TokensReset = value);
+
+ return rateLimits;
+ }
+
+ private static void TryParseHeaderValue(HttpResponseMessage message, string headerName, Func parser, Action setter)
+ {
+ if (message.Headers.TryGetValues(headerName, out var values) &&
+ values.FirstOrDefault() is string value &&
+ parser(value) is T parsedValue)
+ {
+ setter(parsedValue);
+ }
+ }
+
///
/// Makes an HTTP request and deserializes the response to the specified type without custom converters.
///
diff --git a/Anthropic.SDK/EndpointBase.cs b/Anthropic.SDK/EndpointBase.cs
index c58c157..152fa78 100644
--- a/Anthropic.SDK/EndpointBase.cs
+++ b/Anthropic.SDK/EndpointBase.cs
@@ -102,22 +102,7 @@ private string GetErrorMessage(string resultAsString, HttpResponseMessage respon
return $"{resultAsString ?? ""}";
}
- ///
- /// Override the base HttpRequestMessages to add rate limits
- ///
- protected new async Task HttpRequestMessages(string url = null, HttpMethod verb = null,
- object postData = null, CancellationToken ctx = default)
- {
- var response = await base.HttpRequestMessages(url, verb, postData, ctx).ConfigureAwait(false);
-
- if (response is MessageResponse messageResponse)
- {
- messageResponse.RateLimits = GetRateLimits(await HttpRequestRaw(url, verb, postData, false, ctx));
- }
-
- return response;
- }
-
+
protected async IAsyncEnumerable HttpStreamingRequestBatches(string url = null,
HttpMethod verb = null,
object postData = null, [EnumeratorCancellation] CancellationToken ctx = default)
@@ -168,29 +153,7 @@ protected async IAsyncEnumerable HttpStreamingRequestBatchesJsonl(string
}
}
- private static RateLimits GetRateLimits(HttpResponseMessage message)
- {
- var rateLimits = new RateLimits();
-
- TryParseHeaderValue(message, "anthropic-ratelimit-requests-limit", long.Parse, value => rateLimits.RequestsLimit = value);
- TryParseHeaderValue(message, "anthropic-ratelimit-requests-remaining", long.Parse, value => rateLimits.RequestsRemaining = value);
- TryParseHeaderValue(message, "anthropic-ratelimit-requests-reset", DateTime.Parse, value => rateLimits.RequestsReset = value);
- TryParseHeaderValue(message, "anthropic-ratelimit-tokens-limit", long.Parse, value => rateLimits.TokensLimit = value);
- TryParseHeaderValue(message, "anthropic-ratelimit-tokens-remaining", long.Parse, value => rateLimits.TokensRemaining = value);
- TryParseHeaderValue(message, "anthropic-ratelimit-tokens-reset", DateTime.Parse, value => rateLimits.TokensReset = value);
-
- return rateLimits;
- }
-
- private static void TryParseHeaderValue(HttpResponseMessage message, string headerName, Func parser, Action setter)
- {
- if (message.Headers.TryGetValues(headerName, out var values) &&
- values.FirstOrDefault() is string value &&
- parser(value) is T parsedValue)
- {
- setter(parsedValue);
- }
- }
+
///
/// Handle error responses from the API