From 900a7a354941f6b5a1357cacbafb64cd8220d918 Mon Sep 17 00:00:00 2001
From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com>
Date: Fri, 16 Aug 2024 09:21:43 -0500
Subject: [PATCH] tests: update tests to account for serialization and
deserialization changes with new/modified model properties to support caching
---
src/AnthropicClient/AnthropicApiClient.cs | 2 +
.../Json/JsonSerializationOptions.cs | 1 -
.../Models/BaseMessageRequest.cs | 29 +++++++++++-
.../Unit/Models/AnthropicEventTests.cs | 8 +++-
.../Unit/Models/MessageDeltaEventDataTests.cs | 28 +++++++++--
.../Unit/Models/MessageRequestTests.cs | 47 ++++++++++++++-----
.../Unit/Models/MessageResponseTests.cs | 14 +++++-
.../Unit/Models/MessageStartEventDataTests.cs | 4 +-
.../Unit/Models/StreamMessageRequestTests.cs | 7 ++-
.../Unit/Models/UsageTests.cs | 28 +++++++++--
10 files changed, 137 insertions(+), 31 deletions(-)
diff --git a/src/AnthropicClient/AnthropicApiClient.cs b/src/AnthropicClient/AnthropicApiClient.cs
index ad5d0c8..2c57cdd 100644
--- a/src/AnthropicClient/AnthropicApiClient.cs
+++ b/src/AnthropicClient/AnthropicApiClient.cs
@@ -191,6 +191,8 @@ public class AnthropicApiClient : IAnthropicApiClient
{
InputTokens = existingUsage.InputTokens + msgDeltaData.Usage.InputTokens,
OutputTokens = existingUsage.OutputTokens + msgDeltaData.Usage.OutputTokens,
+ CacheCreationInputTokens = existingUsage.CacheCreationInputTokens + msgDeltaData.Usage.CacheCreationInputTokens,
+ CacheReadInputTokens = existingUsage.CacheReadInputTokens + msgDeltaData.Usage.CacheReadInputTokens,
};
msgResponse = new MessageResponse()
diff --git a/src/AnthropicClient/Json/JsonSerializationOptions.cs b/src/AnthropicClient/Json/JsonSerializationOptions.cs
index a5a9ce8..6e9dece 100644
--- a/src/AnthropicClient/Json/JsonSerializationOptions.cs
+++ b/src/AnthropicClient/Json/JsonSerializationOptions.cs
@@ -17,7 +17,6 @@ static class JsonSerializationOptions
new EventDataConverter(),
new ContentDeltaConverter(),
new JsonStringEnumConverter(),
- new MessageRequestConverter(),
},
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
};
diff --git a/src/AnthropicClient/Models/BaseMessageRequest.cs b/src/AnthropicClient/Models/BaseMessageRequest.cs
index 7765310..fb5413b 100644
--- a/src/AnthropicClient/Models/BaseMessageRequest.cs
+++ b/src/AnthropicClient/Models/BaseMessageRequest.cs
@@ -15,15 +15,40 @@ public abstract class BaseMessageRequest
public string Model { get; init; } = string.Empty;
///
- /// Gets the system prompt to use for the request.
+ /// Gets the system message that will be used as the system prompt if no system messages are provided.
///
+ [JsonIgnore]
public string? System { get; init; } = null;
///
- /// Gets the messages to send to the model.
+ /// Gets the system messages to send to the model to be used as the system prompt.
///
+ [JsonIgnore]
public List? SystemMessages { get; init; } = null;
+ ///
+ /// Gets the system prompt that will be used for the request.
+ /// If will return the system messages if they are provided, otherwise it will return the system message.
+ /// If neither are provided, it will return null.
+ ///
+ [JsonPropertyName("system")]
+ public List? SystemPrompt => GetSystemPrompt();
+
+ private List? GetSystemPrompt()
+ {
+ if (SystemMessages is not null)
+ {
+ return SystemMessages;
+ }
+
+ if (System is not null)
+ {
+ return [new TextContent(System)];
+ }
+
+ return null;
+ }
+
///
/// Gets the messages to send to the model.
///
diff --git a/tests/AnthropicClient.Tests/Unit/Models/AnthropicEventTests.cs b/tests/AnthropicClient.Tests/Unit/Models/AnthropicEventTests.cs
index 931616b..28da978 100644
--- a/tests/AnthropicClient.Tests/Unit/Models/AnthropicEventTests.cs
+++ b/tests/AnthropicClient.Tests/Unit/Models/AnthropicEventTests.cs
@@ -13,7 +13,9 @@ public class AnthropicEventTests : SerializationTest
""stop_sequence"": """",
""usage"": {
""input_tokens"": 472,
- ""output_tokens"": 2
+ ""output_tokens"": 2,
+ ""cache_creation_input_tokens"": 0,
+ ""cache_read_input_tokens"": 0
},
""content"": [],
""stop_reason"": """"
@@ -70,7 +72,9 @@ public class AnthropicEventTests : SerializationTest
},
""usage"": {
""output_tokens"": 89,
- ""input_tokens"": 0
+ ""input_tokens"": 0,
+ ""cache_creation_input_tokens"": 0,
+ ""cache_read_input_tokens"": 0
},
""type"": ""message_delta""
}
diff --git a/tests/AnthropicClient.Tests/Unit/Models/MessageDeltaEventDataTests.cs b/tests/AnthropicClient.Tests/Unit/Models/MessageDeltaEventDataTests.cs
index 0d22412..b164915 100644
--- a/tests/AnthropicClient.Tests/Unit/Models/MessageDeltaEventDataTests.cs
+++ b/tests/AnthropicClient.Tests/Unit/Models/MessageDeltaEventDataTests.cs
@@ -10,7 +10,9 @@ public class MessageDeltaEventDataTests : SerializationTest
},
""usage"": {
""input_tokens"": 1,
- ""output_tokens"": 1
+ ""output_tokens"": 1,
+ ""cache_creation_input_tokens"": 1,
+ ""cache_read_input_tokens"": 1
}
}";
@@ -18,7 +20,13 @@ public class MessageDeltaEventDataTests : SerializationTest
public void Constructor_WhenCalled_ItShouldInitializeProperties()
{
var expectedDelta = new MessageDelta("max_tokens", "max_tokens");
- var expectedUsage = new Usage { InputTokens = 1, OutputTokens = 1 };
+ var expectedUsage = new Usage
+ {
+ InputTokens = 1,
+ OutputTokens = 1,
+ CacheCreationInputTokens = 1,
+ CacheReadInputTokens = 1,
+ };
var messageDeltaEventData = new MessageDeltaEventData(expectedDelta, expectedUsage);
@@ -30,7 +38,13 @@ public class MessageDeltaEventDataTests : SerializationTest
public void JsonSerialization_WhenSerialized_ItShouldHaveExpectedShape()
{
var expectedDelta = new MessageDelta("max_tokens", "max_tokens");
- var expectedUsage = new Usage { InputTokens = 1, OutputTokens = 1 };
+ var expectedUsage = new Usage
+ {
+ InputTokens = 1,
+ OutputTokens = 1,
+ CacheCreationInputTokens = 1,
+ CacheReadInputTokens = 1,
+ };
var messageDeltaEventData = new MessageDeltaEventData(expectedDelta, expectedUsage);
@@ -43,7 +57,13 @@ public class MessageDeltaEventDataTests : SerializationTest
public void JsonDeserialization_WhenDeserialized_ItShouldHaveExpectedValues()
{
var expectedDelta = new MessageDelta("max_tokens", "max_tokens");
- var expectedUsage = new Usage { InputTokens = 1, OutputTokens = 1 };
+ var expectedUsage = new Usage
+ {
+ InputTokens = 1,
+ OutputTokens = 1,
+ CacheCreationInputTokens = 1,
+ CacheReadInputTokens = 1,
+ };
var messageDeltaEventData = Deserialize(_testJson);
diff --git a/tests/AnthropicClient.Tests/Unit/Models/MessageRequestTests.cs b/tests/AnthropicClient.Tests/Unit/Models/MessageRequestTests.cs
index a1ae3b0..bcd3532 100644
--- a/tests/AnthropicClient.Tests/Unit/Models/MessageRequestTests.cs
+++ b/tests/AnthropicClient.Tests/Unit/Models/MessageRequestTests.cs
@@ -4,7 +4,10 @@ public class MessageRequestTests : SerializationTest
{
private readonly string _testJson = @"{
""model"": ""claude-3-sonnet-20240229"",
- ""system"": ""test-system"",
+ ""system"": [{
+ ""type"": ""text"",
+ ""text"": ""test-system""
+ }],
""messages"": [
{ ""role"": ""user"", ""content"": [{ ""text"": ""Hello!"", ""type"": ""text"" }] }
],
@@ -21,7 +24,10 @@ public class MessageRequestTests : SerializationTest
private readonly string _testJsonWithAnyToolChoice = @"{
""model"": ""claude-3-sonnet-20240229"",
- ""system"": ""test-system"",
+ ""system"": [{
+ ""type"": ""text"",
+ ""text"": ""test-system""
+ }],
""messages"":[
{ ""role"": ""user"", ""content"": [{ ""text"": ""Hello!"", ""type"":""text"" }] }
],
@@ -38,7 +44,10 @@ public class MessageRequestTests : SerializationTest
private readonly string _testJsonWithSpecificToolChoice = @"{
""model"": ""claude-3-sonnet-20240229"",
- ""system"": ""test-system"",
+ ""system"": [{
+ ""type"": ""text"",
+ ""text"": ""test-system""
+ }],
""messages"": [
{ ""role"": ""user"", ""content"": [{ ""text"": ""Hello!"", ""type"": ""text"" }] }
],
@@ -55,7 +64,10 @@ public class MessageRequestTests : SerializationTest
private readonly string _testJsonWithImageContent = @"{
""model"": ""claude-3-sonnet-20240229"",
- ""system"": ""test-system"",
+ ""system"": [{
+ ""type"": ""text"",
+ ""text"": ""test-system""
+ }],
""messages"":[
{
""role"": ""user"",
@@ -80,7 +92,10 @@ public class MessageRequestTests : SerializationTest
private readonly string _testJsonWithUnknownContent = @"{
""model"": ""claude-3-sonnet-20240229"",
- ""system"": ""test-system"",
+ ""system"": [{
+ ""type"": ""text"",
+ ""text"": ""test-system""
+ }],
""messages"": [{ ""role"": ""user"", ""content"": [{ ""type"": ""unknown"", ""text"": ""text"" }] }],
""max_tokens"": 512,
""metadata"": { ""test"": ""test"" },
@@ -95,7 +110,10 @@ public class MessageRequestTests : SerializationTest
private readonly string _testJsonWithToolUseContent = @"{
""model"": ""claude-3-sonnet-20240229"",
- ""system"": ""test-system"",
+ ""system"": [{
+ ""type"": ""text"",
+ ""text"": ""test-system""
+ }],
""messages"": [
{
""role"": ""assistant"",
@@ -124,7 +142,10 @@ public class MessageRequestTests : SerializationTest
private readonly string _testJsonWithToolResultContent = @"{
""model"": ""claude-3-sonnet-20240229"",
- ""system"": ""test-system"",
+ ""system"": [{
+ ""type"": ""text"",
+ ""text"": ""test-system""
+ }],
""messages"": [
{
""role"": ""assistant"",
@@ -307,7 +328,7 @@ public class MessageRequestTests : SerializationTest
var messageRequest = Deserialize(_testJson);
messageRequest!.Model.Should().Be(AnthropicModels.Claude3Sonnet);
- messageRequest.System.Should().Be("test-system");
+ messageRequest.System.Should().BeNull();
messageRequest.Messages.Should().HaveCount(1);
messageRequest.MaxTokens.Should().Be(512);
messageRequest.Metadata.Should().HaveCount(1);
@@ -330,7 +351,7 @@ public class MessageRequestTests : SerializationTest
var messageRequest = Deserialize(_testJsonWithAnyToolChoice);
messageRequest!.Model.Should().Be(AnthropicModels.Claude3Sonnet);
- messageRequest.System.Should().Be("test-system");
+ messageRequest.System.Should().BeNull();
messageRequest.Messages.Should().HaveCount(1);
messageRequest.MaxTokens.Should().Be(512);
messageRequest.Metadata.Should().HaveCount(1);
@@ -352,7 +373,7 @@ public class MessageRequestTests : SerializationTest
var messageRequest = Deserialize(_testJsonWithSpecificToolChoice);
messageRequest!.Model.Should().Be(AnthropicModels.Claude3Sonnet);
- messageRequest.System.Should().Be("test-system");
+ messageRequest.System.Should().BeNull();
messageRequest.Messages.Should().HaveCount(1);
messageRequest.MaxTokens.Should().Be(512);
messageRequest.Metadata.Should().HaveCount(1);
@@ -387,7 +408,7 @@ public class MessageRequestTests : SerializationTest
var messageRequest = Deserialize(_testJsonWithImageContent);
messageRequest!.Model.Should().Be(AnthropicModels.Claude3Sonnet);
- messageRequest.System.Should().Be("test-system");
+ messageRequest.System.Should().BeNull();
messageRequest.Messages.Should().HaveCount(1);
messageRequest.MaxTokens.Should().Be(512);
messageRequest.Metadata.Should().HaveCount(1);
@@ -416,7 +437,7 @@ public class MessageRequestTests : SerializationTest
var messageRequest = Deserialize(_testJsonWithToolUseContent);
messageRequest!.Model.Should().Be(AnthropicModels.Claude3Sonnet);
- messageRequest.System.Should().Be("test-system");
+ messageRequest.System.Should().BeNull();
messageRequest.Messages.Should().HaveCount(1);
messageRequest.MaxTokens.Should().Be(512);
messageRequest.Metadata.Should().HaveCount(1);
@@ -447,7 +468,7 @@ public class MessageRequestTests : SerializationTest
var messageRequest = Deserialize(_testJsonWithToolResultContent);
messageRequest!.Model.Should().Be(AnthropicModels.Claude3Sonnet);
- messageRequest.System.Should().Be("test-system");
+ messageRequest.System.Should().BeNull();
messageRequest.Messages.Should().HaveCount(1);
messageRequest.MaxTokens.Should().Be(512);
messageRequest.Metadata.Should().HaveCount(1);
diff --git a/tests/AnthropicClient.Tests/Unit/Models/MessageResponseTests.cs b/tests/AnthropicClient.Tests/Unit/Models/MessageResponseTests.cs
index e2bf053..43a3e02 100644
--- a/tests/AnthropicClient.Tests/Unit/Models/MessageResponseTests.cs
+++ b/tests/AnthropicClient.Tests/Unit/Models/MessageResponseTests.cs
@@ -53,7 +53,12 @@ public class MessageResponseTests : SerializationTest
""stop_reason"": ""stop reason"",
""stop_sequence"": ""stop sequence"",
""type"": ""type"",
- ""usage"": { ""input_tokens"": 1, ""output_tokens"": 2 },
+ ""usage"": {
+ ""input_tokens"": 1,
+ ""output_tokens"": 2,
+ ""cache_creation_input_tokens"": 0,
+ ""cache_read_input_tokens"": 0
+ },
""content"": [
{ ""text"": ""text content"", ""type"": ""text"" }
]
@@ -93,7 +98,12 @@ public class MessageResponseTests : SerializationTest
""stop_reason"": ""stop reason"",
""stop_sequence"": ""stop sequence"",
""type"": ""type"",
- ""usage"": { ""input_tokens"": 1, ""output_tokens"": 2 },
+ ""usage"": {
+ ""input_tokens"": 1,
+ ""output_tokens"": 2,
+ ""cache_creation_input_tokens"": 0,
+ ""cache_read_input_tokens"": 0
+ },
""content"": [
{ ""text"": ""text content"", ""type"": ""text"" }
]
diff --git a/tests/AnthropicClient.Tests/Unit/Models/MessageStartEventDataTests.cs b/tests/AnthropicClient.Tests/Unit/Models/MessageStartEventDataTests.cs
index 3a550d8..bc6a5fd 100644
--- a/tests/AnthropicClient.Tests/Unit/Models/MessageStartEventDataTests.cs
+++ b/tests/AnthropicClient.Tests/Unit/Models/MessageStartEventDataTests.cs
@@ -14,7 +14,9 @@ public class MessageStartEventDataTests : SerializationTest
""stop_sequence"": """",
""usage"": {
""input_tokens"": 25,
- ""output_tokens"": 1
+ ""output_tokens"": 1,
+ ""cache_creation_input_tokens"": 0,
+ ""cache_read_input_tokens"": 0
}
}
}";
diff --git a/tests/AnthropicClient.Tests/Unit/Models/StreamMessageRequestTests.cs b/tests/AnthropicClient.Tests/Unit/Models/StreamMessageRequestTests.cs
index 16c1274..67ebd1e 100644
--- a/tests/AnthropicClient.Tests/Unit/Models/StreamMessageRequestTests.cs
+++ b/tests/AnthropicClient.Tests/Unit/Models/StreamMessageRequestTests.cs
@@ -4,7 +4,10 @@ public class StreamMessageRequestTests : SerializationTest
{
private readonly string _testJson = @"{
""model"": ""claude-3-sonnet-20240229"",
- ""system"": ""test-system"",
+ ""system"": [{
+ ""type"": ""text"",
+ ""text"": ""test-system""
+ }],
""messages"": [
{ ""role"": ""user"", ""content"": [{ ""text"": ""Hello!"", ""type"": ""text"" }] }
],
@@ -178,7 +181,7 @@ public class StreamMessageRequestTests : SerializationTest
var messageRequest = Deserialize(_testJson);
messageRequest!.Model.Should().Be(AnthropicModels.Claude3Sonnet);
- messageRequest.System.Should().Be("test-system");
+ messageRequest.System.Should().BeNull();
messageRequest.Messages.Should().HaveCount(1);
messageRequest.MaxTokens.Should().Be(512);
messageRequest.Metadata.Should().HaveCount(1);
diff --git a/tests/AnthropicClient.Tests/Unit/Models/UsageTests.cs b/tests/AnthropicClient.Tests/Unit/Models/UsageTests.cs
index 345527a..a0ca68f 100644
--- a/tests/AnthropicClient.Tests/Unit/Models/UsageTests.cs
+++ b/tests/AnthropicClient.Tests/Unit/Models/UsageTests.cs
@@ -7,26 +7,39 @@ public class UsageTests : SerializationTest
{
var expectedInputTokens = 1;
var expectedOutputTokens = 2;
+ var expectedCacheCreationInputTokens = 3;
+ var expectedCacheReadInputTokens = 4;
var usage = new Usage
{
InputTokens = expectedInputTokens,
- OutputTokens = expectedOutputTokens
+ OutputTokens = expectedOutputTokens,
+ CacheCreationInputTokens = expectedCacheCreationInputTokens,
+ CacheReadInputTokens = expectedCacheReadInputTokens
};
usage.InputTokens.Should().Be(expectedInputTokens);
usage.OutputTokens.Should().Be(expectedOutputTokens);
+ usage.CacheCreationInputTokens.Should().Be(expectedCacheCreationInputTokens);
+ usage.CacheReadInputTokens.Should().Be(expectedCacheReadInputTokens);
}
[Fact]
public void JsonSerialization_WhenCalled_ItShouldSerializeCorrectly()
{
- var expectedJson = @"{ ""input_tokens"": 1, ""output_tokens"": 2 }";
+ var expectedJson = @"{
+ ""input_tokens"": 1,
+ ""output_tokens"": 2,
+ ""cache_creation_input_tokens"": 3,
+ ""cache_read_input_tokens"": 4
+ }";
var usage = new Usage
{
InputTokens = 1,
- OutputTokens = 2
+ OutputTokens = 2,
+ CacheCreationInputTokens = 3,
+ CacheReadInputTokens = 4
};
var actual = Serialize(usage);
@@ -37,11 +50,18 @@ public class UsageTests : SerializationTest
[Fact]
public void JsonDeserialization_WhenCalled_ItShouldDeserializeCorrectly()
{
- var json = @"{ ""input_tokens"": 1, ""output_tokens"": 2 }";
+ var json = @"{
+ ""input_tokens"": 1,
+ ""output_tokens"": 2,
+ ""cache_creation_input_tokens"": 3,
+ ""cache_read_input_tokens"": 4
+ }";
var usage = Deserialize(json);
usage!.InputTokens.Should().Be(1);
usage.OutputTokens.Should().Be(2);
+ usage.CacheCreationInputTokens.Should().Be(3);
+ usage.CacheReadInputTokens.Should().Be(4);
}
}
\ No newline at end of file