Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions Anthropic.SDK.Tests/CacheControlTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,11 @@ public async Task TestCacheControlStreaming()
Assert.IsTrue(messageResponses.First().StreamStartMessage.Usage.CacheCreationInputTokens > 0 ||
messageResponses.First().StreamStartMessage.Usage.CacheReadInputTokens > 0);

if (messageResponses.First().StreamStartMessage.Usage.CacheCreationInputTokens > 0)
{
Assert.IsTrue(messageResponses.First().StreamStartMessage.Usage.CacheCreation.Ephemeral5mInputTokens > 0);
}

messages.Add(new Message(messageResponses));
messages.Add(new Message(RoleType.User, "Who is the main character and how old is he?"));

Expand Down Expand Up @@ -487,7 +492,11 @@ public async Task TestCacheControlOfAssistantMessages()
var systemMessages = new List<SystemMessage>()
{
new SystemMessage("You are an expert at analyzing literary texts."),
new SystemMessage(content, new CacheControl() { Type = CacheControlType.ephemeral })
new SystemMessage(content, new CacheControl()
{
Type = CacheControlType.ephemeral,
TTL = CacheDuration.OneHour,
})
};
var parameters = new MessageParameters()
{
Expand All @@ -505,15 +514,20 @@ public async Task TestCacheControlOfAssistantMessages()
Assert.IsTrue(res.Usage.CacheCreationInputTokens > 0 || res.Usage.CacheReadInputTokens > 0);

//try caching an assistant message
res.Message.Content.First().CacheControl = new CacheControl() { Type = CacheControlType.ephemeral };
res.Message.Content.First().CacheControl = new CacheControl()
{
Type = CacheControlType.ephemeral,
TTL = CacheDuration.OneHour,
};

messages.Add(res.Message);
messages.Add(new Message(RoleType.User, "Who is the main character and how old is he?"));

var res2 = await client.Messages.GetClaudeMessageAsync(parameters);

Assert.IsTrue(res2.Usage.CacheReadInputTokens > 0);

Assert.IsNotNull(res2.Usage.CacheCreation);
Assert.IsTrue(res2.Usage.CacheCreation.Ephemeral1hInputTokens > 0);
Assert.IsNotNull(res2.Message.ToString());

//message 3
Expand Down
18 changes: 8 additions & 10 deletions Anthropic.SDK.Tests/DocumentTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using Anthropic.SDK.Constants;
using Anthropic.SDK.Messaging;

Expand Down Expand Up @@ -41,7 +35,8 @@ public async Task TestPDF()
},
CacheControl = new CacheControl()
{
Type = CacheControlType.ephemeral
Type = CacheControlType.ephemeral,
TTL = CacheDuration.FiveMinutes,
}
}),
new Message(RoleType.User, "Which model has the highest human preference win rates across each use-case?"),
Expand All @@ -60,8 +55,11 @@ public async Task TestPDF()

Assert.IsNotNull(res.FirstMessage.ToString());
Assert.IsTrue(res.Usage.CacheCreationInputTokens > 0 || res.Usage.CacheReadInputTokens > 0);


if (res.Usage.CacheCreationInputTokens > 0)
{
Assert.IsNotNull(res.Usage.CacheCreation);
Assert.IsTrue(res.Usage.CacheCreation.Ephemeral5mInputTokens > 0);
}
}

[TestMethod]
Expand Down
8 changes: 8 additions & 0 deletions Anthropic.SDK/Messaging/CacheControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ public class CacheControl
{
[JsonPropertyName("type")]
public CacheControlType Type { get; set; }

/// <summary>
/// The duration to cache.
/// Supported values are <see cref="CacheDuration5Minutes"/> or <see cref="CacheDuration1Hour"/>
/// </summary>
[JsonPropertyName("ttl")]
[JsonConverter(typeof(CacheDurationConverter))]
public CacheDuration TTL { get; set; }
}

[JsonConverter(typeof(JsonStringEnumConverter))]
Expand Down
36 changes: 36 additions & 0 deletions Anthropic.SDK/Messaging/CacheDurationConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Anthropic.SDK.Messaging;

public enum CacheDuration
{
FiveMinutes,
OneHour
}

public class CacheDurationConverter : JsonConverter<CacheDuration>
{
public override CacheDuration Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
string? value = reader.GetString();
return value switch
{
"5m" => CacheDuration.FiveMinutes,
"1h" => CacheDuration.OneHour,
_ => throw new JsonException($"Invalid cache duration: {value}")
};
}

public override void Write(Utf8JsonWriter writer, CacheDuration value, JsonSerializerOptions options)
{
string str = value switch
{
CacheDuration.FiveMinutes => "5m",
CacheDuration.OneHour => "1h",
_ => throw new JsonException($"Invalid cache duration enum: {value}")
};
writer.WriteStringValue(str);
}
}
12 changes: 12 additions & 0 deletions Anthropic.SDK/Messaging/MessageResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
public Delta Delta { get; set; }

[JsonPropertyName("content_block")]
public ContentBlock? ContentBlock { get; set; }

Check warning on line 40 in Anthropic.SDK/Messaging/MessageResponse.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

[JsonPropertyName("message")]
public StreamMessage StreamStartMessage { get; set; }
Expand Down Expand Up @@ -116,7 +116,7 @@
public string Name { get; set; }

[JsonPropertyName("partial_json")]
public string? PartialJson { get; set; }

Check warning on line 119 in Anthropic.SDK/Messaging/MessageResponse.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
[JsonPropertyName("citation")]
public CitationResult Citation { get; set; }
}
Expand All @@ -127,21 +127,21 @@
public string Type { get; set; }

[JsonPropertyName("id")]
public string? Id { get; set; }

Check warning on line 130 in Anthropic.SDK/Messaging/MessageResponse.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

[JsonPropertyName("text")]
public string? Text { get; set; }

Check warning on line 133 in Anthropic.SDK/Messaging/MessageResponse.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

[JsonPropertyName("name")]
public string? Name { get; set; }

Check warning on line 136 in Anthropic.SDK/Messaging/MessageResponse.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

[JsonPropertyName("server_name")]
public string? ServerName { get; set; }

Check warning on line 139 in Anthropic.SDK/Messaging/MessageResponse.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

[JsonPropertyName("data")]
public string? Data { get; set; }

Check warning on line 142 in Anthropic.SDK/Messaging/MessageResponse.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
[JsonPropertyName("tool_use_id")]
public string? ToolUseId { get; set; }

Check warning on line 144 in Anthropic.SDK/Messaging/MessageResponse.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
[JsonPropertyName("content")]
public List<ContentBase> Content { get; set; }

Expand All @@ -165,6 +165,18 @@

[JsonPropertyName("server_tool_use")]
public ServerToolUse ServerToolUse { get; set; }

[JsonPropertyName("cache_creation")]
public CacheCreation CacheCreation { get; set; }
}

public class CacheCreation
{
[JsonPropertyName("ephemeral_5m_input_tokens")]
public int? Ephemeral5mInputTokens { get; set; }

[JsonPropertyName("ephemeral_1h_input_tokens")]
public int? Ephemeral1hInputTokens { get; set; }
}

public class ServerToolUse
Expand Down
Loading