From 0a1c6a0135d997baa5475d1f6417772bae160a05 Mon Sep 17 00:00:00 2001
From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com>
Date: Mon, 19 May 2025 19:52:16 +0000
Subject: [PATCH 1/8] fix: copilot first attempt
---
src/AnthropicClient/AnthropicApiClient.cs | 112 +++++++++------------
src/AnthropicClient/IAnthropicApiClient.cs | 39 ++++---
2 files changed, 75 insertions(+), 76 deletions(-)
diff --git a/src/AnthropicClient/AnthropicApiClient.cs b/src/AnthropicClient/AnthropicApiClient.cs
index 826b735..5ea4e02 100644
--- a/src/AnthropicClient/AnthropicApiClient.cs
+++ b/src/AnthropicClient/AnthropicApiClient.cs
@@ -1,4 +1,5 @@
using System.Net.Http.Headers;
+using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
@@ -50,13 +51,12 @@ public AnthropicApiClient(string apiKey, HttpClient httpClient)
_httpClient.DefaultRequestHeaders.Add(pair.Key, pair.Value);
}
}
-
///
- public async Task> CreateMessageAsync(MessageRequest request)
+ public async Task> CreateMessageAsync(MessageRequest request, CancellationToken cancellationToken = default)
{
- var response = await SendRequestAsync(MessagesEndpoint, request);
+ var response = await SendRequestAsync(MessagesEndpoint, request, cancellationToken);
var anthropicHeaders = new AnthropicHeaders(response.Headers);
- var responseContent = await response.Content.ReadAsStringAsync();
+ var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
if (response.IsSuccessStatusCode is false)
{
@@ -75,13 +75,13 @@ public async Task> CreateMessageAsync(MessageRe
}
///
- public async IAsyncEnumerable CreateMessageAsync(StreamMessageRequest request)
+ public async IAsyncEnumerable CreateMessageAsync(StreamMessageRequest request, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
- var response = await SendRequestAsync(MessagesEndpoint, request);
+ var response = await SendRequestAsync(MessagesEndpoint, request, cancellationToken);
if (response.IsSuccessStatusCode is false)
{
- var error = Deserialize(await response.Content.ReadAsStringAsync()) ?? new AnthropicError();
+ var error = Deserialize(await response.Content.ReadAsStringAsync(cancellationToken)) ?? new AnthropicError();
yield return new AnthropicEvent(EventType.Error, new ErrorEventData(error.Error));
yield break;
}
@@ -237,73 +237,66 @@ msgResponse is not null
}
} while (true);
}
-
///
- public async Task> CreateMessageBatchAsync(MessageBatchRequest request)
+ public async Task> CreateMessageBatchAsync(MessageBatchRequest request, CancellationToken cancellationToken = default)
{
- var response = await SendRequestAsync(MessageBatchesEndpoint, request);
- return await CreateResultAsync(response);
+ var response = await SendRequestAsync(MessageBatchesEndpoint, request, cancellationToken);
+ return await CreateResultAsync(response, cancellationToken);
}
-
///
- public async Task> GetMessageBatchAsync(string batchId)
+ public async Task> GetMessageBatchAsync(string batchId, CancellationToken cancellationToken = default)
{
- var response = await SendRequestAsync($"{MessageBatchesEndpoint}/{batchId}");
- return await CreateResultAsync(response);
+ var response = await SendRequestAsync($"{MessageBatchesEndpoint}/{batchId}", cancellationToken: cancellationToken);
+ return await CreateResultAsync(response, cancellationToken);
}
-
///
- public async Task>> ListMessageBatchesAsync(PagingRequest? request = null)
+ public async Task>> ListMessageBatchesAsync(PagingRequest? request = null, CancellationToken cancellationToken = default)
{
var pagingRequest = request ?? new PagingRequest();
var endpoint = $"{MessageBatchesEndpoint}?{pagingRequest.ToQueryParameters()}";
- var response = await SendRequestAsync(endpoint);
- return await CreateResultAsync>(response);
+ var response = await SendRequestAsync(endpoint, cancellationToken: cancellationToken);
+ return await CreateResultAsync>(response, cancellationToken);
}
-
///
- public async IAsyncEnumerable>> ListAllMessageBatchesAsync(int limit = 20)
+ public async IAsyncEnumerable>> ListAllMessageBatchesAsync(int limit = 20, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
- await foreach (var result in GetAllPagesAsync(MessageBatchesEndpoint, limit))
+ await foreach (var result in GetAllPagesAsync(MessageBatchesEndpoint, limit, cancellationToken))
{
yield return result;
}
}
-
///
- public async Task> CancelMessageBatchAsync(string batchId)
+ public async Task> CancelMessageBatchAsync(string batchId, CancellationToken cancellationToken = default)
{
var endpoint = $"{MessageBatchesEndpoint}/{batchId}/cancel";
- var response = await SendRequestAsync(endpoint, HttpMethod.Post);
- return await CreateResultAsync(response);
+ var response = await SendRequestAsync(endpoint, HttpMethod.Post, cancellationToken);
+ return await CreateResultAsync(response, cancellationToken);
}
-
///
- public async Task> DeleteMessageBatchAsync(string batchId)
+ public async Task> DeleteMessageBatchAsync(string batchId, CancellationToken cancellationToken = default)
{
var endpoint = $"{MessageBatchesEndpoint}/{batchId}";
- var response = await SendRequestAsync(endpoint, HttpMethod.Delete);
- return await CreateResultAsync(response);
+ var response = await SendRequestAsync(endpoint, HttpMethod.Delete, cancellationToken);
+ return await CreateResultAsync(response, cancellationToken);
}
-
///
- public async Task>> GetMessageBatchResultsAsync(string batchId)
+ public async Task>> GetMessageBatchResultsAsync(string batchId, CancellationToken cancellationToken = default)
{
- var response = await SendRequestAsync($"{MessageBatchesEndpoint}/{batchId}/results");
+ var response = await SendRequestAsync($"{MessageBatchesEndpoint}/{batchId}/results", cancellationToken: cancellationToken);
var anthropicHeaders = new AnthropicHeaders(response.Headers);
if (response.IsSuccessStatusCode is false)
{
- var content = await response.Content.ReadAsStringAsync();
+ var content = await response.Content.ReadAsStringAsync(cancellationToken);
var error = Deserialize(content) ?? new AnthropicError();
return AnthropicResult>.Failure(error, anthropicHeaders);
}
return AnthropicResult>.Success(ReadResultsAsync(), anthropicHeaders);
- async IAsyncEnumerable ReadResultsAsync()
+ async IAsyncEnumerable ReadResultsAsync([EnumeratorCancellation] CancellationToken ct = default)
{
- using var responseContent = await response.Content.ReadAsStreamAsync();
+ using var responseContent = await response.Content.ReadAsStreamAsync(ct);
using var streamReader = new StreamReader(responseContent);
var line = await streamReader.ReadLineAsync();
@@ -317,41 +310,36 @@ async IAsyncEnumerable ReadResultsAsync()
}
}
}
-
///
- public async Task> CountMessageTokensAsync(CountMessageTokensRequest request)
+ public async Task> CountMessageTokensAsync(CountMessageTokensRequest request, CancellationToken cancellationToken = default)
{
- var response = await SendRequestAsync(CountTokensEndpoint, request);
- return await CreateResultAsync(response);
+ var response = await SendRequestAsync(CountTokensEndpoint, request, cancellationToken);
+ return await CreateResultAsync(response, cancellationToken);
}
-
///
- public async Task>> ListModelsAsync(PagingRequest? request = null)
+ public async Task>> ListModelsAsync(PagingRequest? request = null, CancellationToken cancellationToken = default)
{
var pagingRequest = request ?? new PagingRequest();
var endpoint = $"{ModelsEndpoint}?{pagingRequest.ToQueryParameters()}";
- var response = await SendRequestAsync(endpoint);
- return await CreateResultAsync>(response);
+ var response = await SendRequestAsync(endpoint, cancellationToken: cancellationToken);
+ return await CreateResultAsync>(response, cancellationToken);
}
-
///
- public async IAsyncEnumerable>> ListAllModelsAsync(int limit = 20)
+ public async IAsyncEnumerable>> ListAllModelsAsync(int limit = 20, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
- await foreach (var result in GetAllPagesAsync(ModelsEndpoint, limit))
+ await foreach (var result in GetAllPagesAsync(ModelsEndpoint, limit, cancellationToken))
{
yield return result;
}
}
-
///
- public async Task> GetModelAsync(string modelId)
+ public async Task> GetModelAsync(string modelId, CancellationToken cancellationToken = default)
{
var endpoint = $"{ModelsEndpoint}/{modelId}";
- var response = await SendRequestAsync(endpoint);
- return await CreateResultAsync(response);
+ var response = await SendRequestAsync(endpoint, cancellationToken: cancellationToken);
+ return await CreateResultAsync(response, cancellationToken);
}
-
- private async IAsyncEnumerable>> GetAllPagesAsync(string endpoint, int limit = 20)
+ private async IAsyncEnumerable>> GetAllPagesAsync(string endpoint, int limit = 20, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var pagingRequest = new PagingRequest(limit: limit);
string Endpoint() => $"{endpoint}?{pagingRequest.ToQueryParameters()}";
@@ -359,9 +347,9 @@ private async IAsyncEnumerable>> GetAllPagesAsync(str
do
{
- var response = await SendRequestAsync(Endpoint());
+ var response = await SendRequestAsync(Endpoint(), cancellationToken: cancellationToken);
var anthropicHeaders = new AnthropicHeaders(response.Headers);
- var responseContent = await response.Content.ReadAsStringAsync();
+ var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
if (response.IsSuccessStatusCode is false)
{
@@ -404,11 +392,10 @@ private async IAsyncEnumerable>> GetAllPagesAsync(str
return new ToolCall(tool, toolUse);
}
-
- private async Task> CreateResultAsync(HttpResponseMessage response) where T : new()
+ private async Task> CreateResultAsync(HttpResponseMessage response, CancellationToken cancellationToken = default) where T : new()
{
var anthropicHeaders = new AnthropicHeaders(response.Headers);
- var responseContent = await response.Content.ReadAsStringAsync();
+ var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
if (response.IsSuccessStatusCode is false)
{
@@ -419,18 +406,17 @@ private async IAsyncEnumerable>> GetAllPagesAsync(str
var model = Deserialize(responseContent) ?? new T();
return AnthropicResult.Success(model, anthropicHeaders);
}
-
- private async Task SendRequestAsync(string endpoint, HttpMethod? method = null)
+ private async Task SendRequestAsync(string endpoint, HttpMethod? method = null, CancellationToken cancellationToken = default)
{
var request = new HttpRequestMessage(method ?? HttpMethod.Get, endpoint);
- return await _httpClient.SendAsync(request);
+ return await _httpClient.SendAsync(request, cancellationToken);
}
- private async Task SendRequestAsync(string endpoint, T request)
+ private async Task SendRequestAsync(string endpoint, T request, CancellationToken cancellationToken = default)
{
var requestJson = Serialize(request);
var requestContent = new StringContent(requestJson, Encoding.UTF8, JsonContentType);
- return await _httpClient.PostAsync(endpoint, requestContent);
+ return await _httpClient.PostAsync(endpoint, requestContent, cancellationToken);
}
private string Serialize(T obj) => JsonSerializer.Serialize(obj, JsonSerializationOptions.DefaultOptions);
diff --git a/src/AnthropicClient/IAnthropicApiClient.cs b/src/AnthropicClient/IAnthropicApiClient.cs
index 27c7e00..7b33bbe 100644
--- a/src/AnthropicClient/IAnthropicApiClient.cs
+++ b/src/AnthropicClient/IAnthropicApiClient.cs
@@ -11,91 +11,104 @@ public interface IAnthropicApiClient
/// Creates a message asynchronously.
///
/// The message request to create.
+ /// A token to cancel the asynchronous operation.
/// A task that represents the asynchronous operation. The task result contains the response as an .
- Task> CreateMessageAsync(MessageRequest request);
+ Task> CreateMessageAsync(MessageRequest request, CancellationToken cancellationToken = default);
///
/// Creates a message asynchronously and streams the response.
///
/// The message request to create.
+ /// A token to cancel the asynchronous operation.
/// An asynchronous enumerable that yields the response event by event.
- IAsyncEnumerable CreateMessageAsync(StreamMessageRequest request);
+ IAsyncEnumerable CreateMessageAsync(StreamMessageRequest request, CancellationToken cancellationToken = default);
///
/// Creates a batch of messages asynchronously.
///
/// The message batch request to create.
+ /// A token to cancel the asynchronous operation.
/// A task that represents the asynchronous operation. The task result contains the response as an where T is .
- Task> CreateMessageBatchAsync(MessageBatchRequest request);
+ Task> CreateMessageBatchAsync(MessageBatchRequest request, CancellationToken cancellationToken = default);
///
/// Gets a message batch asynchronously.
///
/// The ID of the message batch to get.
+ /// A token to cancel the asynchronous operation.
/// A task that represents the asynchronous operation. The task result contains the response as an where T is .
- Task> GetMessageBatchAsync(string batchId);
+ Task> GetMessageBatchAsync(string batchId, CancellationToken cancellationToken = default);
///
/// Lists the message batches asynchronously.
///
/// The paging request to use for listing the message batches.
+ /// A token to cancel the asynchronous operation.
/// A task that represents the asynchronous operation. The task result contains the response as an where T is where T is .
- Task>> ListMessageBatchesAsync(PagingRequest? request = null);
+ Task>> ListMessageBatchesAsync(PagingRequest? request = null, CancellationToken cancellationToken = default);
///
/// Lists all message batches asynchronously.
///
/// The maximum number of message batches to return in each page.
+ /// A token to cancel the asynchronous operation.
/// An asynchronous enumerable that yields the response as an where T is where T is .
- IAsyncEnumerable>> ListAllMessageBatchesAsync(int limit = 20);
+ IAsyncEnumerable>> ListAllMessageBatchesAsync(int limit = 20, CancellationToken cancellationToken = default);
///
/// Cancels a message batch asynchronously.
///
/// The ID of the message batch to cancel.
+ /// A token to cancel the asynchronous operation.
/// A task that represents the asynchronous operation. The task result contains the response as an where T is .
- Task> CancelMessageBatchAsync(string batchId);
+ Task> CancelMessageBatchAsync(string batchId, CancellationToken cancellationToken = default);
///
/// Deletes a message batch asynchronously.
///
/// The ID of the message batch to delete.
+ /// A token to cancel the asynchronous operation.
/// A task that represents the asynchronous operation. The task result contains the response as an where T is .
- Task> DeleteMessageBatchAsync(string batchId);
+ Task> DeleteMessageBatchAsync(string batchId, CancellationToken cancellationToken = default);
///
/// Gets the results of a message batch asynchronously.
///
/// The ID of the message batch to get the results for.
+ /// A token to cancel the asynchronous operation.
/// A task that represents the asynchronous operation. The task result contains the response as an where T is where T is .
- Task>> GetMessageBatchResultsAsync(string batchId);
+ Task>> GetMessageBatchResultsAsync(string batchId, CancellationToken cancellationToken = default);
///
/// Counts the tokens in a message asynchronously.
///
/// The count message tokens request.
+ /// A token to cancel the asynchronous operation.
/// A task that represents the asynchronous operation. The task result contains the response as an where T is .
- Task> CountMessageTokensAsync(CountMessageTokensRequest request);
+ Task> CountMessageTokensAsync(CountMessageTokensRequest request, CancellationToken cancellationToken = default);
///
/// Lists the models asynchronously.
///
/// The paging request to use for listing the models.
+ /// A token to cancel the asynchronous operation.
/// A task that represents the asynchronous operation. The task result contains the response as an where T is where T is .
- Task>> ListModelsAsync(PagingRequest? request = null);
+ Task>> ListModelsAsync(PagingRequest? request = null, CancellationToken cancellationToken = default);
///
/// Lists the models asynchronously
///
/// The maximum number of models to return in each page.
+ /// A token to cancel the asynchronous operation.
/// An asynchronous enumerable that yields the response as an where T is where T is .
///
- IAsyncEnumerable>> ListAllModelsAsync(int limit = 20);
+ IAsyncEnumerable>> ListAllModelsAsync(int limit = 20, CancellationToken cancellationToken = default);
///
/// Gets a model by its ID asynchronously.
///
/// The ID of the model to get.
+ /// A token to cancel the asynchronous operation.
/// A task that represents the asynchronous operation. The task result contains the response as an where T is .
- Task> GetModelAsync(string modelId);
+ Task> GetModelAsync(string modelId, CancellationToken cancellationToken = default);
}
\ No newline at end of file
From 595326c7a9454e3c9d4a5c9d95777e723896e1a0 Mon Sep 17 00:00:00 2001
From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com>
Date: Mon, 19 May 2025 15:14:11 -0500
Subject: [PATCH 2/8] fix: cleanup copilot mistakes with passing cancellation
token to methods that don't accept them
---
src/AnthropicClient/AnthropicApiClient.cs | 46 +++++++++++++++--------
1 file changed, 31 insertions(+), 15 deletions(-)
diff --git a/src/AnthropicClient/AnthropicApiClient.cs b/src/AnthropicClient/AnthropicApiClient.cs
index 5ea4e02..58f0944 100644
--- a/src/AnthropicClient/AnthropicApiClient.cs
+++ b/src/AnthropicClient/AnthropicApiClient.cs
@@ -51,12 +51,13 @@ public AnthropicApiClient(string apiKey, HttpClient httpClient)
_httpClient.DefaultRequestHeaders.Add(pair.Key, pair.Value);
}
}
+
///
public async Task> CreateMessageAsync(MessageRequest request, CancellationToken cancellationToken = default)
{
var response = await SendRequestAsync(MessagesEndpoint, request, cancellationToken);
var anthropicHeaders = new AnthropicHeaders(response.Headers);
- var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
+ var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode is false)
{
@@ -81,7 +82,8 @@ public async IAsyncEnumerable CreateMessageAsync(StreamMessageRe
if (response.IsSuccessStatusCode is false)
{
- var error = Deserialize(await response.Content.ReadAsStringAsync(cancellationToken)) ?? new AnthropicError();
+ var errorContent = await response.Content.ReadAsStringAsync();
+ var error = Deserialize(errorContent) ?? new AnthropicError();
yield return new AnthropicEvent(EventType.Error, new ErrorEventData(error.Error));
yield break;
}
@@ -237,26 +239,30 @@ msgResponse is not null
}
} while (true);
}
+
///
public async Task> CreateMessageBatchAsync(MessageBatchRequest request, CancellationToken cancellationToken = default)
{
var response = await SendRequestAsync(MessageBatchesEndpoint, request, cancellationToken);
- return await CreateResultAsync(response, cancellationToken);
+ return await CreateResultAsync(response);
}
+
///
public async Task> GetMessageBatchAsync(string batchId, CancellationToken cancellationToken = default)
{
var response = await SendRequestAsync($"{MessageBatchesEndpoint}/{batchId}", cancellationToken: cancellationToken);
- return await CreateResultAsync(response, cancellationToken);
+ return await CreateResultAsync(response);
}
+
///
public async Task>> ListMessageBatchesAsync(PagingRequest? request = null, CancellationToken cancellationToken = default)
{
var pagingRequest = request ?? new PagingRequest();
var endpoint = $"{MessageBatchesEndpoint}?{pagingRequest.ToQueryParameters()}";
var response = await SendRequestAsync(endpoint, cancellationToken: cancellationToken);
- return await CreateResultAsync>(response, cancellationToken);
+ return await CreateResultAsync>(response);
}
+
///
public async IAsyncEnumerable>> ListAllMessageBatchesAsync(int limit = 20, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
@@ -265,20 +271,23 @@ public async IAsyncEnumerable>> ListA
yield return result;
}
}
+
///
public async Task> CancelMessageBatchAsync(string batchId, CancellationToken cancellationToken = default)
{
var endpoint = $"{MessageBatchesEndpoint}/{batchId}/cancel";
var response = await SendRequestAsync(endpoint, HttpMethod.Post, cancellationToken);
- return await CreateResultAsync(response, cancellationToken);
+ return await CreateResultAsync(response);
}
+
///
public async Task> DeleteMessageBatchAsync(string batchId, CancellationToken cancellationToken = default)
{
var endpoint = $"{MessageBatchesEndpoint}/{batchId}";
var response = await SendRequestAsync(endpoint, HttpMethod.Delete, cancellationToken);
- return await CreateResultAsync(response, cancellationToken);
+ return await CreateResultAsync(response);
}
+
///
public async Task>> GetMessageBatchResultsAsync(string batchId, CancellationToken cancellationToken = default)
{
@@ -287,7 +296,7 @@ public async Task>> Get
if (response.IsSuccessStatusCode is false)
{
- var content = await response.Content.ReadAsStringAsync(cancellationToken);
+ var content = await response.Content.ReadAsStringAsync();
var error = Deserialize(content) ?? new AnthropicError();
return AnthropicResult>.Failure(error, anthropicHeaders);
}
@@ -296,7 +305,7 @@ public async Task>> Get
async IAsyncEnumerable ReadResultsAsync([EnumeratorCancellation] CancellationToken ct = default)
{
- using var responseContent = await response.Content.ReadAsStreamAsync(ct);
+ using var responseContent = await response.Content.ReadAsStreamAsync();
using var streamReader = new StreamReader(responseContent);
var line = await streamReader.ReadLineAsync();
@@ -310,20 +319,23 @@ async IAsyncEnumerable ReadResultsAsync([EnumeratorCance
}
}
}
+
///
public async Task> CountMessageTokensAsync(CountMessageTokensRequest request, CancellationToken cancellationToken = default)
{
var response = await SendRequestAsync(CountTokensEndpoint, request, cancellationToken);
- return await CreateResultAsync(response, cancellationToken);
+ return await CreateResultAsync(response);
}
+
///
public async Task>> ListModelsAsync(PagingRequest? request = null, CancellationToken cancellationToken = default)
{
var pagingRequest = request ?? new PagingRequest();
var endpoint = $"{ModelsEndpoint}?{pagingRequest.ToQueryParameters()}";
var response = await SendRequestAsync(endpoint, cancellationToken: cancellationToken);
- return await CreateResultAsync>(response, cancellationToken);
+ return await CreateResultAsync>(response);
}
+
///
public async IAsyncEnumerable>> ListAllModelsAsync(int limit = 20, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
@@ -332,13 +344,15 @@ public async IAsyncEnumerable>> ListAllMode
yield return result;
}
}
+
///
public async Task> GetModelAsync(string modelId, CancellationToken cancellationToken = default)
{
var endpoint = $"{ModelsEndpoint}/{modelId}";
var response = await SendRequestAsync(endpoint, cancellationToken: cancellationToken);
- return await CreateResultAsync(response, cancellationToken);
+ return await CreateResultAsync(response);
}
+
private async IAsyncEnumerable>> GetAllPagesAsync(string endpoint, int limit = 20, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var pagingRequest = new PagingRequest(limit: limit);
@@ -349,7 +363,7 @@ private async IAsyncEnumerable>> GetAllPagesAsync(str
{
var response = await SendRequestAsync(Endpoint(), cancellationToken: cancellationToken);
var anthropicHeaders = new AnthropicHeaders(response.Headers);
- var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
+ var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode is false)
{
@@ -392,10 +406,11 @@ private async IAsyncEnumerable>> GetAllPagesAsync(str
return new ToolCall(tool, toolUse);
}
- private async Task> CreateResultAsync(HttpResponseMessage response, CancellationToken cancellationToken = default) where T : new()
+
+ private async Task> CreateResultAsync(HttpResponseMessage response) where T : new()
{
var anthropicHeaders = new AnthropicHeaders(response.Headers);
- var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);
+ var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode is false)
{
@@ -406,6 +421,7 @@ private async IAsyncEnumerable>> GetAllPagesAsync(str
var model = Deserialize(responseContent) ?? new T();
return AnthropicResult.Success(model, anthropicHeaders);
}
+
private async Task SendRequestAsync(string endpoint, HttpMethod? method = null, CancellationToken cancellationToken = default)
{
var request = new HttpRequestMessage(method ?? HttpMethod.Get, endpoint);
From 24ecff969ed47b49fb4f0246032816ae4b9888d6 Mon Sep 17 00:00:00 2001
From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com>
Date: Mon, 19 May 2025 15:14:50 -0500
Subject: [PATCH 3/8] chore: upgrade test project to .NET 9
---
tests/AnthropicClient.Tests/AnthropicClient.Tests.csproj | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/AnthropicClient.Tests/AnthropicClient.Tests.csproj b/tests/AnthropicClient.Tests/AnthropicClient.Tests.csproj
index 0a5f3db..6be8f1a 100644
--- a/tests/AnthropicClient.Tests/AnthropicClient.Tests.csproj
+++ b/tests/AnthropicClient.Tests/AnthropicClient.Tests.csproj
@@ -1,7 +1,7 @@
- net8.0
+ net9.0
enable
enable
false
@@ -54,7 +54,7 @@
PreserveNewest
-
+
PreserveNewest
From e68428c8bacd0d5073f182ba61551821c5cb6996 Mon Sep 17 00:00:00 2001
From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com>
Date: Mon, 19 May 2025 15:16:53 -0500
Subject: [PATCH 4/8] chore: upgrade dependencies
---
src/AnthropicClient/AnthropicClient.csproj | 4 ++--
.../AnthropicClient.Tests.csproj | 18 +++++++++---------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/AnthropicClient/AnthropicClient.csproj b/src/AnthropicClient/AnthropicClient.csproj
index 8f16d24..0a58e81 100644
--- a/src/AnthropicClient/AnthropicClient.csproj
+++ b/src/AnthropicClient/AnthropicClient.csproj
@@ -34,8 +34,8 @@
-
-
+
+
diff --git a/tests/AnthropicClient.Tests/AnthropicClient.Tests.csproj b/tests/AnthropicClient.Tests/AnthropicClient.Tests.csproj
index 6be8f1a..1962db3 100644
--- a/tests/AnthropicClient.Tests/AnthropicClient.Tests.csproj
+++ b/tests/AnthropicClient.Tests/AnthropicClient.Tests.csproj
@@ -10,21 +10,21 @@
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
From e2d4ee735adeb5823b7908e17e7e3b353684d656 Mon Sep 17 00:00:00 2001
From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com>
Date: Mon, 19 May 2025 15:21:51 -0500
Subject: [PATCH 5/8] chore: update workflows to use .NET 9
---
.github/workflows/publish.yml | 12 ++++++------
.github/workflows/pull_request.yml | 8 ++++----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 2825527..8668753 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -13,10 +13,10 @@ jobs:
with:
fetch-depth: 0
token: ${{ secrets.ACTIONS_PAT }}
- - name: Setup .NET 8
+ - name: Setup .NET 9
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ dotnet-version: 9.x
- name: Install versionize
run: dotnet tool install --global Versionize
- name: Setup git
@@ -53,10 +53,10 @@ jobs:
fetch-depth: 0
ref: ${{ github.ref }}
token: ${{ secrets.ACTIONS_PAT }}
- - name: Setup .NET 8
+ - name: Setup .NET 9
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ dotnet-version: 9.x
- name: Get project version
uses: kzrnm/get-net-sdk-project-versions-action@v1
id: get-version
@@ -88,10 +88,10 @@ jobs:
fetch-depth: 0
ref: ${{ github.ref }}
token: ${{ secrets.ACTIONS_PAT }}
- - name: Setup .NET 8
+ - name: Setup .NET 9
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ dotnet-version: 9.x
- name: Install Docfx
run: dotnet tool install --global docfx
- name: Get project version
diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml
index b6a83cd..f12943b 100644
--- a/.github/workflows/pull_request.yml
+++ b/.github/workflows/pull_request.yml
@@ -15,10 +15,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
- - name: Setup .NET 8
+ - name: Setup .NET 9
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ dotnet-version: 9.x
- name: Restore dependencies
run: dotnet restore
- name: Format code
@@ -28,10 +28,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
- - name: Setup .NET 8
+ - name: Setup .NET 9
uses: actions/setup-dotnet@v4
with:
- dotnet-version: 8.x
+ dotnet-version: 9.x
- name: Install report generator
run: dotnet tool install --global dotnet-reportgenerator-globaltool --version 5.3.7
- name: Restore dependencies
From 5d4fb290ba24095ea564cf8a33366dd53ab4ba44 Mon Sep 17 00:00:00 2001
From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com>
Date: Mon, 19 May 2025 15:28:08 -0500
Subject: [PATCH 6/8] fix: cleanup based on copilot review comments
---
.vscode/settings.json | 9 +++++++++
src/AnthropicClient/AnthropicApiClient.cs | 2 +-
src/AnthropicClient/IAnthropicApiClient.cs | 4 ++--
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/.vscode/settings.json b/.vscode/settings.json
index b2f391d..11a990d 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -3,9 +3,18 @@
"dotnet.defaultSolution": "AnthropicClient.sln",
"cSpell.words": [
"Browsable",
+ "buildtransitive",
+ "contentfiles",
+ "Docfx",
+ "globaltool",
"haikus",
+ "Linq",
+ "msbuild",
"nameof",
+ "reportgenerator",
+ "reporttypes",
"Szalay",
+ "targetdir",
"typeof"
],
"dotnet.unitTests.runSettingsPath": "./tests/AnthropicClient.Tests/.runsettings"
diff --git a/src/AnthropicClient/AnthropicApiClient.cs b/src/AnthropicClient/AnthropicApiClient.cs
index 58f0944..f05f3e6 100644
--- a/src/AnthropicClient/AnthropicApiClient.cs
+++ b/src/AnthropicClient/AnthropicApiClient.cs
@@ -303,7 +303,7 @@ public async Task>> Get
return AnthropicResult>.Success(ReadResultsAsync(), anthropicHeaders);
- async IAsyncEnumerable ReadResultsAsync([EnumeratorCancellation] CancellationToken ct = default)
+ async IAsyncEnumerable ReadResultsAsync()
{
using var responseContent = await response.Content.ReadAsStreamAsync();
using var streamReader = new StreamReader(responseContent);
diff --git a/src/AnthropicClient/IAnthropicApiClient.cs b/src/AnthropicClient/IAnthropicApiClient.cs
index 7b33bbe..12d98c7 100644
--- a/src/AnthropicClient/IAnthropicApiClient.cs
+++ b/src/AnthropicClient/IAnthropicApiClient.cs
@@ -88,7 +88,7 @@ public interface IAnthropicApiClient
Task> CountMessageTokensAsync(CountMessageTokensRequest request, CancellationToken cancellationToken = default);
///
- /// Lists the models asynchronously.
+ /// Lists the models asynchronously getting a page of models.
///
/// The paging request to use for listing the models.
/// A token to cancel the asynchronous operation.
@@ -96,7 +96,7 @@ public interface IAnthropicApiClient
Task>> ListModelsAsync(PagingRequest? request = null, CancellationToken cancellationToken = default);
///
- /// Lists the models asynchronously
+ /// Lists the model asynchronously getting all the pages of models.
///
/// The maximum number of models to return in each page.
/// A token to cancel the asynchronous operation.
From 702685bd10b94211f03f3ab28c9a25ad5b2b9e8f Mon Sep 17 00:00:00 2001
From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com>
Date: Mon, 19 May 2025 15:30:12 -0500
Subject: [PATCH 7/8] docs: update src/AnthropicClient/IAnthropicApiClient.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
src/AnthropicClient/IAnthropicApiClient.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/AnthropicClient/IAnthropicApiClient.cs b/src/AnthropicClient/IAnthropicApiClient.cs
index 12d98c7..26d22b8 100644
--- a/src/AnthropicClient/IAnthropicApiClient.cs
+++ b/src/AnthropicClient/IAnthropicApiClient.cs
@@ -88,7 +88,7 @@ public interface IAnthropicApiClient
Task> CountMessageTokensAsync(CountMessageTokensRequest request, CancellationToken cancellationToken = default);
///
- /// Lists the models asynchronously getting a page of models.
+ /// Lists models asynchronously, returning a single page of results.
///
/// The paging request to use for listing the models.
/// A token to cancel the asynchronous operation.
From 16ee80a3a4346d537b0d0b784698482009c1f424 Mon Sep 17 00:00:00 2001
From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com>
Date: Mon, 19 May 2025 15:30:29 -0500
Subject: [PATCH 8/8] docs: update src/AnthropicClient/IAnthropicApiClient.cs
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
src/AnthropicClient/IAnthropicApiClient.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/AnthropicClient/IAnthropicApiClient.cs b/src/AnthropicClient/IAnthropicApiClient.cs
index 26d22b8..e4f63b9 100644
--- a/src/AnthropicClient/IAnthropicApiClient.cs
+++ b/src/AnthropicClient/IAnthropicApiClient.cs
@@ -96,7 +96,7 @@ public interface IAnthropicApiClient
Task>> ListModelsAsync(PagingRequest? request = null, CancellationToken cancellationToken = default);
///
- /// Lists the model asynchronously getting all the pages of models.
+ /// Lists all models asynchronously, returning every page of results.
///
/// The maximum number of models to return in each page.
/// A token to cancel the asynchronous operation.