From 7c4b7457f7d32da04cf21865f8daff626901f286 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 13 Jan 2026 21:36:29 +0000 Subject: [PATCH 01/41] chore(readme): remove beta warning now that we're in ga From 5e32bb5ed0488321c6809aab25c72a85a0296aa6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 16:39:59 +0000 Subject: [PATCH 02/41] chore(internal): codegen related update From 0738e6548fefbd207b016a3b05b45448ff71896e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 13 Jan 2026 21:36:29 +0000 Subject: [PATCH 03/41] chore(readme): remove beta warning now that we're in ga From fc997b8829b7a6a89d9e52695a6f919a45f771ef Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 16:39:59 +0000 Subject: [PATCH 04/41] chore(internal): codegen related update From 4b6812d30003832fe61bb193d00cd4b1f5cb7df9 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 21 Jan 2026 13:22:15 -0500 Subject: [PATCH 05/41] Fix IChatClient usage deltas to be considered cumulative (#99) --- .../AnthropicClientExtensionsTestsBase.cs | 71 ++++++++++++++++++- src/Anthropic/AnthropicClientExtensions.cs | 12 +--- .../Messages/AnthropicBetaClientExtensions.cs | 12 +--- 3 files changed, 76 insertions(+), 19 deletions(-) diff --git a/src/Anthropic.Tests/AnthropicClientExtensionsTestsBase.cs b/src/Anthropic.Tests/AnthropicClientExtensionsTestsBase.cs index 56e91c04e..b645e1f68 100644 --- a/src/Anthropic.Tests/AnthropicClientExtensionsTestsBase.cs +++ b/src/Anthropic.Tests/AnthropicClientExtensionsTestsBase.cs @@ -3659,7 +3659,7 @@ public async Task GetStreamingResponseAsync_AccumulatesUsageFromMultipleMessageS data: {"type":"content_block_stop","index":0} event: message_delta - data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":2}} + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":15,"output_tokens":2}} event: message_stop data: {"type":"message_stop"} @@ -3689,10 +3689,79 @@ var update in chatClient.GetStreamingResponseAsync( .SelectMany(u => u.Contents.OfType()) .FirstOrDefault(); Assert.NotNull(usageContent); + Assert.Equal(15, usageContent.Details.InputTokenCount); Assert.Equal(2, usageContent.Details.OutputTokenCount); } + [Fact] + public async Task GetStreamingResponseAsync_UsageFromDeltaOverridesStartEvent() + { + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "hello" + }] + }], + "stream": true + } + """, + actualResponse: """ + event: message_start + data: {"type":"message_start","message":{"id":"msg_01","type":"message","role":"assistant","model":"claude-haiku-4-5","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":8,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":8}}} + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello!"}} + + event: content_block_stop + data: {"type":"content_block_stop","index":0} + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":8,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":12}} + + event: message_stop + data: {"type":"message_stop"} + + """ + ); + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + List updates = []; + await foreach ( + var update in chatClient.GetStreamingResponseAsync( + "hello", + new(), + TestContext.Current.CancellationToken + ) + ) + { + updates.Add(update); + } + + Assert.NotEmpty(updates); + var usageUpdates = updates.Where(u => u.Contents.Any(c => c is UsageContent)).ToList(); + Assert.NotEmpty(usageUpdates); + + var usageContent = usageUpdates + .SelectMany(u => u.Contents.OfType()) + .FirstOrDefault(); + Assert.NotNull(usageContent); + + Assert.Equal(8, usageContent.Details.InputTokenCount); + Assert.Equal(12, usageContent.Details.OutputTokenCount); + Assert.Equal(20, usageContent.Details.TotalTokenCount); + } + [Fact] public async Task GetResponseAsync_FunctionResult_WithSingleTextContent() { diff --git a/src/Anthropic/AnthropicClientExtensions.cs b/src/Anthropic/AnthropicClientExtensions.cs index dc872647c..2aa20fa17 100644 --- a/src/Anthropic/AnthropicClientExtensions.cs +++ b/src/Anthropic/AnthropicClientExtensions.cs @@ -242,15 +242,9 @@ var createResult in _anthropicClient finishReason = ToFinishReason(rawMessageDelta.Delta.StopReason); if (rawMessageDelta.Usage is { } deltaUsage) { - UsageDetails current = ToUsageDetails(deltaUsage); - if (usageDetails is null) - { - usageDetails = current; - } - else - { - usageDetails.Add(current); - } + // https://platform.claude.com/docs/en/build-with-claude/streaming + // "The token counts shown in the usage field of the message_delta event are cumulative." + usageDetails = ToUsageDetails(deltaUsage); } break; diff --git a/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs b/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs index 2597cd1d5..2dd0c2eb5 100644 --- a/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs +++ b/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs @@ -320,15 +320,9 @@ var createResult in _betaService finishReason = ToFinishReason(rawMessageDelta.Delta.StopReason); if (rawMessageDelta.Usage is { } deltaUsage) { - UsageDetails current = ToUsageDetails(deltaUsage); - if (usageDetails is null) - { - usageDetails = current; - } - else - { - usageDetails.Add(current); - } + // https://platform.claude.com/docs/en/build-with-claude/streaming + // "The token counts shown in the usage field of the message_delta event are cumulative." + usageDetails = ToUsageDetails(deltaUsage); } break; From 7b0a0e862ac2adcdf05be8635662ca2f01b93ca9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 26 Jan 2026 15:39:33 +0000 Subject: [PATCH 06/41] chore(internal): codegen related update --- src/Anthropic/Anthropic.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Anthropic/Anthropic.csproj b/src/Anthropic/Anthropic.csproj index c8aed0d79..e81c1024b 100644 --- a/src/Anthropic/Anthropic.csproj +++ b/src/Anthropic/Anthropic.csproj @@ -13,12 +13,12 @@ - - - - - - + + + + + + From 3188edef63bd6103c095cb32d5ef85fe89ad3274 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 17:04:46 +0000 Subject: [PATCH 07/41] fix(ci): don't throw an error about missing lsof --- scripts/test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/test b/scripts/test index a562fa22b..f47e4b7f6 100755 --- a/scripts/test +++ b/scripts/test @@ -14,6 +14,10 @@ function prism_is_running() { } kill_server_on_port() { + if [ ! "$(which lsof)" ]; then + echo "Warning: lsof not found. Prism will not be killed." + return 0 + fi pids=$(lsof -t -i tcp:"$1" || echo "") if [ "$pids" != "" ]; then kill "$pids" From 4e6f6ddd0cfff4d301f7adf608256480e5d3703c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 20:29:50 +0000 Subject: [PATCH 08/41] chore(internal): version bump From e24676bda5b1409059c65064d1bf52d09973d884 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 21:23:25 +0000 Subject: [PATCH 09/41] feat(api): migrate sending message format in output_config rather than output_format --- .stats.yml | 6 +- .../Messages/Batches/BatchCreateParamsTest.cs | 264 ++++++++++++++++-- .../Beta/Messages/BetaContentBlockTest.cs | 4 +- .../Beta/Messages/BetaOutputConfigTest.cs | 73 ++++- .../BetaRawContentBlockStartEventTest.cs | 4 +- .../Messages/BetaServerToolUseBlockTest.cs | 126 +++++++-- .../BetaWebSearchToolResultErrorCodeTest.cs | 2 + .../Messages/MessageCountTokensParamsTest.cs | 48 +++- .../Beta/Messages/MessageCreateParamsTest.cs | 48 +++- .../Messages/WebSearchToolRequestErrorTest.cs | 2 + .../Messages/WebSearchToolResultErrorTest.cs | 2 + .../Beta/Messages/BatchServiceTest.cs | 12 +- .../Messages/Batches/BatchCreateParams.cs | 10 +- .../Models/Beta/Messages/BetaOutputConfig.cs | 15 + .../Beta/Messages/BetaServerToolUseBlock.cs | 146 +++++----- .../BetaWebSearchToolResultErrorCode.cs | 3 + .../Beta/Messages/MessageCountTokensParams.cs | 10 +- .../Beta/Messages/MessageCreateParams.cs | 10 +- .../Messages/WebSearchToolRequestError.cs | 3 + .../Messages/WebSearchToolResultError.cs | 3 + 20 files changed, 642 insertions(+), 149 deletions(-) diff --git a/.stats.yml b/.stats.yml index 8ee87af83..4bbd93aa0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 32 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-211390f4627177361550415b571a2b580b18c5882e3c2fc961b527e7b3474b0f.yml -openapi_spec_hash: c93ef3808c58e233b01966ff154f31ce -config_hash: 38518261acfb569e37162f9e1d4c4fdf +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-f7bcdc13402c6129b30be620021a724945de44cffc6add091798f9cce33a1e32.yml +openapi_spec_hash: e78807e31b9233abc50ccc00304bfa4d +config_hash: 92ca93edc068c543f2da38737239322d diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs index c4d95a6cf..b0de5f635 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs @@ -70,7 +70,17 @@ public void FieldRoundtrip_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -192,7 +202,17 @@ public void FieldRoundtrip_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -335,7 +355,17 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -469,7 +499,17 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -606,7 +646,17 @@ public void Url_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -742,7 +792,17 @@ public void AddHeadersToRequest_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -876,7 +936,17 @@ public void FieldRoundtrip_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -988,7 +1058,17 @@ public void FieldRoundtrip_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -1108,7 +1188,17 @@ public void SerializationRoundtrip_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -1231,7 +1321,17 @@ public void FieldRoundtripThroughSerialization_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -1350,7 +1450,17 @@ public void FieldRoundtripThroughSerialization_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -1470,7 +1580,17 @@ public void Validation_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -1590,7 +1710,17 @@ public void FieldRoundtrip_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -1705,7 +1835,17 @@ public void FieldRoundtrip_Works() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b", }; - Messages::BetaOutputConfig expectedOutputConfig = new() { Effort = Messages::Effort.Low }; + Messages::BetaOutputConfig expectedOutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; Messages::BetaJsonOutputFormat expectedOutputFormat = new() { Schema = new Dictionary() @@ -1861,7 +2001,17 @@ public void SerializationRoundtrip_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -1980,7 +2130,17 @@ public void FieldRoundtripThroughSerialization_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -2099,7 +2259,17 @@ public void FieldRoundtripThroughSerialization_Works() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b", }; - Messages::BetaOutputConfig expectedOutputConfig = new() { Effort = Messages::Effort.Low }; + Messages::BetaOutputConfig expectedOutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; Messages::BetaJsonOutputFormat expectedOutputFormat = new() { Schema = new Dictionary() @@ -2255,7 +2425,17 @@ public void Validation_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -2612,7 +2792,17 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -2699,7 +2889,17 @@ public void OptionalNullablePropertiesUnsetValidation_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -2781,7 +2981,17 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -2872,7 +3082,17 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Messages::Effort.Low }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockTest.cs index 9ed4f587b..142fb8539 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockTest.cs @@ -69,12 +69,12 @@ public void ServerToolUseValidationWorks() BetaContentBlock value = new BetaServerToolUseBlock() { ID = "srvtoolu_SQfNkl1n_JR_", - Caller = new BetaDirectCaller(), Input = new Dictionary() { { "foo", JsonSerializer.SerializeToElement("bar") }, }, Name = Name.WebSearch, + Caller = new BetaDirectCaller(), }; value.Validate(); } @@ -280,12 +280,12 @@ public void ServerToolUseSerializationRoundtripWorks() BetaContentBlock value = new BetaServerToolUseBlock() { ID = "srvtoolu_SQfNkl1n_JR_", - Caller = new BetaDirectCaller(), Input = new Dictionary() { { "foo", JsonSerializer.SerializeToElement("bar") }, }, Name = Name.WebSearch, + Caller = new BetaDirectCaller(), }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs index d8f49f1b0..ea5a9ea76 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Text.Json; using Anthropic.Core; using Anthropic.Exceptions; @@ -10,17 +11,45 @@ public class BetaOutputConfigTest : TestBase [Fact] public void FieldRoundtrip_Works() { - var model = new BetaOutputConfig { Effort = Effort.Low }; + var model = new BetaOutputConfig + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; ApiEnum expectedEffort = Effort.Low; + BetaJsonOutputFormat expectedFormat = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; Assert.Equal(expectedEffort, model.Effort); + Assert.Equal(expectedFormat, model.Format); } [Fact] public void SerializationRoundtrip_Works() { - var model = new BetaOutputConfig { Effort = Effort.Low }; + var model = new BetaOutputConfig + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -34,7 +63,17 @@ public void SerializationRoundtrip_Works() [Fact] public void FieldRoundtripThroughSerialization_Works() { - var model = new BetaOutputConfig { Effort = Effort.Low }; + var model = new BetaOutputConfig + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -44,14 +83,32 @@ public void FieldRoundtripThroughSerialization_Works() Assert.NotNull(deserialized); ApiEnum expectedEffort = Effort.Low; + BetaJsonOutputFormat expectedFormat = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; Assert.Equal(expectedEffort, deserialized.Effort); + Assert.Equal(expectedFormat, deserialized.Format); } [Fact] public void Validation_Works() { - var model = new BetaOutputConfig { Effort = Effort.Low }; + var model = new BetaOutputConfig + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; model.Validate(); } @@ -63,6 +120,8 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() Assert.Null(model.Effort); Assert.False(model.RawData.ContainsKey("effort")); + Assert.Null(model.Format); + Assert.False(model.RawData.ContainsKey("format")); } [Fact] @@ -76,16 +135,18 @@ public void OptionalNullablePropertiesUnsetValidation_Works() [Fact] public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() { - var model = new BetaOutputConfig { Effort = null }; + var model = new BetaOutputConfig { Effort = null, Format = null }; Assert.Null(model.Effort); Assert.True(model.RawData.ContainsKey("effort")); + Assert.Null(model.Format); + Assert.True(model.RawData.ContainsKey("format")); } [Fact] public void OptionalNullablePropertiesSetToNullValidation_Works() { - var model = new BetaOutputConfig { Effort = null }; + var model = new BetaOutputConfig { Effort = null, Format = null }; model.Validate(); } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs index b05028246..c18978c45 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs @@ -235,12 +235,12 @@ public void BetaServerToolUseValidationWorks() ContentBlock value = new BetaServerToolUseBlock() { ID = "srvtoolu_SQfNkl1n_JR_", - Caller = new BetaDirectCaller(), Input = new Dictionary() { { "foo", JsonSerializer.SerializeToElement("bar") }, }, Name = Name.WebSearch, + Caller = new BetaDirectCaller(), }; value.Validate(); } @@ -446,12 +446,12 @@ public void BetaServerToolUseSerializationRoundtripWorks() ContentBlock value = new BetaServerToolUseBlock() { ID = "srvtoolu_SQfNkl1n_JR_", - Caller = new BetaDirectCaller(), Input = new Dictionary() { { "foo", JsonSerializer.SerializeToElement("bar") }, }, Name = Name.WebSearch, + Caller = new BetaDirectCaller(), }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockTest.cs index 350e9d1fe..6f25e3182 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockTest.cs @@ -14,25 +14,24 @@ public void FieldRoundtrip_Works() var model = new BetaServerToolUseBlock { ID = "srvtoolu_SQfNkl1n_JR_", - Caller = new BetaDirectCaller(), Input = new Dictionary() { { "foo", JsonSerializer.SerializeToElement("bar") }, }, Name = Name.WebSearch, + Caller = new BetaDirectCaller(), }; string expectedID = "srvtoolu_SQfNkl1n_JR_"; - Caller expectedCaller = new BetaDirectCaller(); Dictionary expectedInput = new() { { "foo", JsonSerializer.SerializeToElement("bar") }, }; ApiEnum expectedName = Name.WebSearch; JsonElement expectedType = JsonSerializer.SerializeToElement("server_tool_use"); + Caller expectedCaller = new BetaDirectCaller(); Assert.Equal(expectedID, model.ID); - Assert.Equal(expectedCaller, model.Caller); Assert.Equal(expectedInput.Count, model.Input.Count); foreach (var item in expectedInput) { @@ -42,6 +41,7 @@ public void FieldRoundtrip_Works() } Assert.Equal(expectedName, model.Name); Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); + Assert.Equal(expectedCaller, model.Caller); } [Fact] @@ -50,12 +50,12 @@ public void SerializationRoundtrip_Works() var model = new BetaServerToolUseBlock { ID = "srvtoolu_SQfNkl1n_JR_", - Caller = new BetaDirectCaller(), Input = new Dictionary() { { "foo", JsonSerializer.SerializeToElement("bar") }, }, Name = Name.WebSearch, + Caller = new BetaDirectCaller(), }; string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); @@ -73,12 +73,12 @@ public void FieldRoundtripThroughSerialization_Works() var model = new BetaServerToolUseBlock { ID = "srvtoolu_SQfNkl1n_JR_", - Caller = new BetaDirectCaller(), Input = new Dictionary() { { "foo", JsonSerializer.SerializeToElement("bar") }, }, Name = Name.WebSearch, + Caller = new BetaDirectCaller(), }; string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); @@ -89,16 +89,15 @@ public void FieldRoundtripThroughSerialization_Works() Assert.NotNull(deserialized); string expectedID = "srvtoolu_SQfNkl1n_JR_"; - Caller expectedCaller = new BetaDirectCaller(); Dictionary expectedInput = new() { { "foo", JsonSerializer.SerializeToElement("bar") }, }; ApiEnum expectedName = Name.WebSearch; JsonElement expectedType = JsonSerializer.SerializeToElement("server_tool_use"); + Caller expectedCaller = new BetaDirectCaller(); Assert.Equal(expectedID, deserialized.ID); - Assert.Equal(expectedCaller, deserialized.Caller); Assert.Equal(expectedInput.Count, deserialized.Input.Count); foreach (var item in expectedInput) { @@ -108,6 +107,7 @@ public void FieldRoundtripThroughSerialization_Works() } Assert.Equal(expectedName, deserialized.Name); Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); + Assert.Equal(expectedCaller, deserialized.Caller); } [Fact] @@ -116,52 +116,87 @@ public void Validation_Works() var model = new BetaServerToolUseBlock { ID = "srvtoolu_SQfNkl1n_JR_", - Caller = new BetaDirectCaller(), Input = new Dictionary() { { "foo", JsonSerializer.SerializeToElement("bar") }, }, Name = Name.WebSearch, + Caller = new BetaDirectCaller(), }; model.Validate(); } -} -public class CallerTest : TestBase -{ [Fact] - public void BetaDirectValidationWorks() + public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() { - Caller value = new BetaDirectCaller(); - value.Validate(); + var model = new BetaServerToolUseBlock + { + ID = "srvtoolu_SQfNkl1n_JR_", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = Name.WebSearch, + }; + + Assert.Null(model.Caller); + Assert.False(model.RawData.ContainsKey("caller")); } [Fact] - public void BetaServerToolValidationWorks() + public void OptionalNonNullablePropertiesUnsetValidation_Works() { - Caller value = new BetaServerToolCaller("srvtoolu_SQfNkl1n_JR_"); - value.Validate(); + var model = new BetaServerToolUseBlock + { + ID = "srvtoolu_SQfNkl1n_JR_", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = Name.WebSearch, + }; + + model.Validate(); } [Fact] - public void BetaDirectSerializationRoundtripWorks() + public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() { - Caller value = new BetaDirectCaller(); - string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); - var deserialized = JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + var model = new BetaServerToolUseBlock + { + ID = "srvtoolu_SQfNkl1n_JR_", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = Name.WebSearch, - Assert.Equal(value, deserialized); + // Null should be interpreted as omitted for these properties + Caller = null, + }; + + Assert.Null(model.Caller); + Assert.False(model.RawData.ContainsKey("caller")); } [Fact] - public void BetaServerToolSerializationRoundtripWorks() + public void OptionalNonNullablePropertiesSetToNullValidation_Works() { - Caller value = new BetaServerToolCaller("srvtoolu_SQfNkl1n_JR_"); - string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); - var deserialized = JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + var model = new BetaServerToolUseBlock + { + ID = "srvtoolu_SQfNkl1n_JR_", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = Name.WebSearch, - Assert.Equal(value, deserialized); + // Null should be interpreted as omitted for these properties + Caller = null, + }; + + model.Validate(); } } @@ -232,3 +267,40 @@ public void InvalidEnumSerializationRoundtrip_Works() Assert.Equal(value, deserialized); } } + +public class CallerTest : TestBase +{ + [Fact] + public void BetaDirectValidationWorks() + { + Caller value = new BetaDirectCaller(); + value.Validate(); + } + + [Fact] + public void BetaServerToolValidationWorks() + { + Caller value = new BetaServerToolCaller("srvtoolu_SQfNkl1n_JR_"); + value.Validate(); + } + + [Fact] + public void BetaDirectSerializationRoundtripWorks() + { + Caller value = new BetaDirectCaller(); + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + + Assert.Equal(value, deserialized); + } + + [Fact] + public void BetaServerToolSerializationRoundtripWorks() + { + Caller value = new BetaServerToolCaller("srvtoolu_SQfNkl1n_JR_"); + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + + Assert.Equal(value, deserialized); + } +} diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultErrorCodeTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultErrorCodeTest.cs index 6a83ca357..f7ff740be 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultErrorCodeTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultErrorCodeTest.cs @@ -13,6 +13,7 @@ public class BetaWebSearchToolResultErrorCodeTest : TestBase [InlineData(BetaWebSearchToolResultErrorCode.MaxUsesExceeded)] [InlineData(BetaWebSearchToolResultErrorCode.TooManyRequests)] [InlineData(BetaWebSearchToolResultErrorCode.QueryTooLong)] + [InlineData(BetaWebSearchToolResultErrorCode.RequestTooLarge)] public void Validation_Works(BetaWebSearchToolResultErrorCode rawValue) { // force implicit conversion because Theory can't do that for us @@ -38,6 +39,7 @@ public void InvalidEnumValidationThrows_Works() [InlineData(BetaWebSearchToolResultErrorCode.MaxUsesExceeded)] [InlineData(BetaWebSearchToolResultErrorCode.TooManyRequests)] [InlineData(BetaWebSearchToolResultErrorCode.QueryTooLong)] + [InlineData(BetaWebSearchToolResultErrorCode.RequestTooLarge)] public void SerializationRoundtrip_Works(BetaWebSearchToolResultErrorCode rawValue) { // force implicit conversion because Theory can't do that for us diff --git a/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs index accfc9154..4339289f1 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs @@ -42,7 +42,17 @@ public void FieldRoundtrip_Works() ToolConfiguration = new() { AllowedTools = ["string"], Enabled = true }, }, ], - OutputConfig = new() { Effort = Effort.Low }, + OutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -130,7 +140,17 @@ public void FieldRoundtrip_Works() ToolConfiguration = new() { AllowedTools = ["string"], Enabled = true }, }, ]; - BetaOutputConfig expectedOutputConfig = new() { Effort = Effort.Low }; + BetaOutputConfig expectedOutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; BetaJsonOutputFormat expectedOutputFormat = new() { Schema = new Dictionary() @@ -344,7 +364,17 @@ public void OptionalNullableParamsUnsetAreNotSet_Works() ToolConfiguration = new() { AllowedTools = ["string"], Enabled = true }, }, ], - OutputConfig = new() { Effort = Effort.Low }, + OutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, System = new( [ new BetaTextBlockParam() @@ -422,7 +452,17 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() ToolConfiguration = new() { AllowedTools = ["string"], Enabled = true }, }, ], - OutputConfig = new() { Effort = Effort.Low }, + OutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, System = new( [ new BetaTextBlockParam() diff --git a/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs index 557b35968..bcb89755b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs @@ -58,7 +58,17 @@ public void FieldRoundtrip_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Effort.Low }, + OutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() @@ -169,7 +179,17 @@ public void FieldRoundtrip_Works() }, ]; BetaMetadata expectedMetadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }; - BetaOutputConfig expectedOutputConfig = new() { Effort = Effort.Low }; + BetaOutputConfig expectedOutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; BetaJsonOutputFormat expectedOutputFormat = new() { Schema = new Dictionary() @@ -461,7 +481,17 @@ public void OptionalNullableParamsUnsetAreNotSet_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Effort.Low }, + OutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], System = new( @@ -548,7 +578,17 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Effort.Low }, + OutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], System = new( diff --git a/src/Anthropic.Tests/Models/Messages/WebSearchToolRequestErrorTest.cs b/src/Anthropic.Tests/Models/Messages/WebSearchToolRequestErrorTest.cs index 32a9d11f6..4bd948a10 100644 --- a/src/Anthropic.Tests/Models/Messages/WebSearchToolRequestErrorTest.cs +++ b/src/Anthropic.Tests/Models/Messages/WebSearchToolRequestErrorTest.cs @@ -73,6 +73,7 @@ public class ErrorCodeTest : TestBase [InlineData(ErrorCode.MaxUsesExceeded)] [InlineData(ErrorCode.TooManyRequests)] [InlineData(ErrorCode.QueryTooLong)] + [InlineData(ErrorCode.RequestTooLarge)] public void Validation_Works(ErrorCode rawValue) { // force implicit conversion because Theory can't do that for us @@ -98,6 +99,7 @@ public void InvalidEnumValidationThrows_Works() [InlineData(ErrorCode.MaxUsesExceeded)] [InlineData(ErrorCode.TooManyRequests)] [InlineData(ErrorCode.QueryTooLong)] + [InlineData(ErrorCode.RequestTooLarge)] public void SerializationRoundtrip_Works(ErrorCode rawValue) { // force implicit conversion because Theory can't do that for us diff --git a/src/Anthropic.Tests/Models/Messages/WebSearchToolResultErrorTest.cs b/src/Anthropic.Tests/Models/Messages/WebSearchToolResultErrorTest.cs index 7ef96d060..2002a4159 100644 --- a/src/Anthropic.Tests/Models/Messages/WebSearchToolResultErrorTest.cs +++ b/src/Anthropic.Tests/Models/Messages/WebSearchToolResultErrorTest.cs @@ -87,6 +87,7 @@ public class WebSearchToolResultErrorErrorCodeTest : TestBase [InlineData(WebSearchToolResultErrorErrorCode.MaxUsesExceeded)] [InlineData(WebSearchToolResultErrorErrorCode.TooManyRequests)] [InlineData(WebSearchToolResultErrorErrorCode.QueryTooLong)] + [InlineData(WebSearchToolResultErrorErrorCode.RequestTooLarge)] public void Validation_Works(WebSearchToolResultErrorErrorCode rawValue) { // force implicit conversion because Theory can't do that for us @@ -112,6 +113,7 @@ public void InvalidEnumValidationThrows_Works() [InlineData(WebSearchToolResultErrorErrorCode.MaxUsesExceeded)] [InlineData(WebSearchToolResultErrorErrorCode.TooManyRequests)] [InlineData(WebSearchToolResultErrorErrorCode.QueryTooLong)] + [InlineData(WebSearchToolResultErrorErrorCode.RequestTooLarge)] public void SerializationRoundtrip_Works(WebSearchToolResultErrorErrorCode rawValue) { // force implicit conversion because Theory can't do that for us diff --git a/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs b/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs index c47244df1..143eee26a 100644 --- a/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs +++ b/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs @@ -68,7 +68,17 @@ public async Task Create_Works(IAnthropicClient client) }, ], Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() { Effort = Effort.Low }, + OutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, OutputFormat = new() { Schema = new Dictionary() diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs index 6453f3813..5e4428817 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs @@ -418,8 +418,8 @@ public BetaMetadata? Metadata } /// - /// Configuration options for the model's output. Controls aspects like how much - /// effort the model puts into its response. + /// Configuration options for the model's output. Controls aspects like output + /// format or how much effort the model puts into its response. /// public BetaOutputConfig? OutputConfig { @@ -440,8 +440,12 @@ public BetaOutputConfig? OutputConfig } /// - /// A schema to specify Claude's output format in responses. + /// Deprecated: Use `output_config.format` instead. See [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + /// + /// A schema to specify Claude's output format in responses. This parameter + /// will be removed in a future release. /// + [System::Obsolete("deprecated")] public BetaJsonOutputFormat? OutputFormat { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs b/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs index bad39a913..6b5880d3a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs @@ -25,10 +25,25 @@ public ApiEnum? Effort init { this._rawData.Set("effort", value); } } + /// + /// A schema to specify Claude's output format in responses. See [structured + /// outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + /// + public BetaJsonOutputFormat? Format + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("format"); + } + init { this._rawData.Set("format", value); } + } + /// public override void Validate() { this.Effort?.Validate(); + this.Format?.Validate(); } public BetaOutputConfig() { } diff --git a/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs index 43b6fb5e9..8bf17a7dd 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs @@ -22,19 +22,6 @@ public required string ID init { this._rawData.Set("id", value); } } - /// - /// Tool invocation directly from the model. - /// - public required Caller Caller - { - get - { - this._rawData.Freeze(); - return this._rawData.GetNotNullClass("caller"); - } - init { this._rawData.Set("caller", value); } - } - public required IReadOnlyDictionary Input { get @@ -71,11 +58,31 @@ public JsonElement Type init { this._rawData.Set("type", value); } } + /// + /// Tool invocation directly from the model. + /// + public Caller? Caller + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("caller"); + } + init + { + if (value == null) + { + return; + } + + this._rawData.Set("caller", value); + } + } + /// public override void Validate() { _ = this.ID; - this.Caller.Validate(); _ = this.Input; this.Name.Validate(); if ( @@ -84,6 +91,7 @@ public override void Validate() { throw new AnthropicInvalidDataException("Invalid value given for constant"); } + this.Caller?.Validate(); } public BetaServerToolUseBlock() @@ -126,6 +134,61 @@ IReadOnlyDictionary rawData ) => BetaServerToolUseBlock.FromRawUnchecked(rawData); } +[JsonConverter(typeof(NameConverter))] +public enum Name +{ + WebSearch, + WebFetch, + CodeExecution, + BashCodeExecution, + TextEditorCodeExecution, + ToolSearchToolRegex, + ToolSearchToolBm25, +} + +sealed class NameConverter : JsonConverter +{ + public override Name Read( + ref Utf8JsonReader reader, + System::Type typeToConvert, + JsonSerializerOptions options + ) + { + return JsonSerializer.Deserialize(ref reader, options) switch + { + "web_search" => Name.WebSearch, + "web_fetch" => Name.WebFetch, + "code_execution" => Name.CodeExecution, + "bash_code_execution" => Name.BashCodeExecution, + "text_editor_code_execution" => Name.TextEditorCodeExecution, + "tool_search_tool_regex" => Name.ToolSearchToolRegex, + "tool_search_tool_bm25" => Name.ToolSearchToolBm25, + _ => (Name)(-1), + }; + } + + public override void Write(Utf8JsonWriter writer, Name value, JsonSerializerOptions options) + { + JsonSerializer.Serialize( + writer, + value switch + { + Name.WebSearch => "web_search", + Name.WebFetch => "web_fetch", + Name.CodeExecution => "code_execution", + Name.BashCodeExecution => "bash_code_execution", + Name.TextEditorCodeExecution => "text_editor_code_execution", + Name.ToolSearchToolRegex => "tool_search_tool_regex", + Name.ToolSearchToolBm25 => "tool_search_tool_bm25", + _ => throw new AnthropicInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); + } +} + /// /// Tool invocation directly from the model. /// @@ -402,58 +465,3 @@ public override void Write(Utf8JsonWriter writer, Caller value, JsonSerializerOp JsonSerializer.Serialize(writer, value.Json, options); } } - -[JsonConverter(typeof(NameConverter))] -public enum Name -{ - WebSearch, - WebFetch, - CodeExecution, - BashCodeExecution, - TextEditorCodeExecution, - ToolSearchToolRegex, - ToolSearchToolBm25, -} - -sealed class NameConverter : JsonConverter -{ - public override Name Read( - ref Utf8JsonReader reader, - System::Type typeToConvert, - JsonSerializerOptions options - ) - { - return JsonSerializer.Deserialize(ref reader, options) switch - { - "web_search" => Name.WebSearch, - "web_fetch" => Name.WebFetch, - "code_execution" => Name.CodeExecution, - "bash_code_execution" => Name.BashCodeExecution, - "text_editor_code_execution" => Name.TextEditorCodeExecution, - "tool_search_tool_regex" => Name.ToolSearchToolRegex, - "tool_search_tool_bm25" => Name.ToolSearchToolBm25, - _ => (Name)(-1), - }; - } - - public override void Write(Utf8JsonWriter writer, Name value, JsonSerializerOptions options) - { - JsonSerializer.Serialize( - writer, - value switch - { - Name.WebSearch => "web_search", - Name.WebFetch => "web_fetch", - Name.CodeExecution => "code_execution", - Name.BashCodeExecution => "bash_code_execution", - Name.TextEditorCodeExecution => "text_editor_code_execution", - Name.ToolSearchToolRegex => "tool_search_tool_regex", - Name.ToolSearchToolBm25 => "tool_search_tool_bm25", - _ => throw new AnthropicInvalidDataException( - string.Format("Invalid value '{0}' in {1}", value, nameof(value)) - ), - }, - options - ); - } -} diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultErrorCode.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultErrorCode.cs index 64277e7c1..1a77997b7 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultErrorCode.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultErrorCode.cs @@ -13,6 +13,7 @@ public enum BetaWebSearchToolResultErrorCode MaxUsesExceeded, TooManyRequests, QueryTooLong, + RequestTooLarge, } sealed class BetaWebSearchToolResultErrorCodeConverter @@ -31,6 +32,7 @@ JsonSerializerOptions options "max_uses_exceeded" => BetaWebSearchToolResultErrorCode.MaxUsesExceeded, "too_many_requests" => BetaWebSearchToolResultErrorCode.TooManyRequests, "query_too_long" => BetaWebSearchToolResultErrorCode.QueryTooLong, + "request_too_large" => BetaWebSearchToolResultErrorCode.RequestTooLarge, _ => (BetaWebSearchToolResultErrorCode)(-1), }; } @@ -50,6 +52,7 @@ JsonSerializerOptions options BetaWebSearchToolResultErrorCode.MaxUsesExceeded => "max_uses_exceeded", BetaWebSearchToolResultErrorCode.TooManyRequests => "too_many_requests", BetaWebSearchToolResultErrorCode.QueryTooLong => "query_too_long", + BetaWebSearchToolResultErrorCode.RequestTooLarge => "request_too_large", _ => throw new AnthropicInvalidDataException( string.Format("Invalid value '{0}' in {1}", value, nameof(value)) ), diff --git a/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs b/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs index 45077e74b..d783af87c 100644 --- a/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs +++ b/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs @@ -155,8 +155,8 @@ public IReadOnlyList? McpServers } /// - /// Configuration options for the model's output. Controls aspects like how much - /// effort the model puts into its response. + /// Configuration options for the model's output. Controls aspects like output + /// format or how much effort the model puts into its response. /// public BetaOutputConfig? OutputConfig { @@ -177,8 +177,12 @@ public BetaOutputConfig? OutputConfig } /// - /// A schema to specify Claude's output format in responses. + /// Deprecated: Use `output_config.format` instead. See [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + /// + /// A schema to specify Claude's output format in responses. This parameter + /// will be removed in a future release. /// + [System::Obsolete("deprecated")] public BetaJsonOutputFormat? OutputFormat { get diff --git a/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs b/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs index 733fa1d16..e9d978eec 100644 --- a/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs @@ -208,8 +208,8 @@ public BetaMetadata? Metadata } /// - /// Configuration options for the model's output. Controls aspects like how much - /// effort the model puts into its response. + /// Configuration options for the model's output. Controls aspects like output + /// format or how much effort the model puts into its response. /// public BetaOutputConfig? OutputConfig { @@ -230,8 +230,12 @@ public BetaOutputConfig? OutputConfig } /// - /// A schema to specify Claude's output format in responses. + /// Deprecated: Use `output_config.format` instead. See [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + /// + /// A schema to specify Claude's output format in responses. This parameter + /// will be removed in a future release. /// + [System::Obsolete("deprecated")] public BetaJsonOutputFormat? OutputFormat { get diff --git a/src/Anthropic/Models/Messages/WebSearchToolRequestError.cs b/src/Anthropic/Models/Messages/WebSearchToolRequestError.cs index 3297c0856..e161a43f0 100644 --- a/src/Anthropic/Models/Messages/WebSearchToolRequestError.cs +++ b/src/Anthropic/Models/Messages/WebSearchToolRequestError.cs @@ -104,6 +104,7 @@ public enum ErrorCode MaxUsesExceeded, TooManyRequests, QueryTooLong, + RequestTooLarge, } sealed class ErrorCodeConverter : JsonConverter @@ -121,6 +122,7 @@ JsonSerializerOptions options "max_uses_exceeded" => ErrorCode.MaxUsesExceeded, "too_many_requests" => ErrorCode.TooManyRequests, "query_too_long" => ErrorCode.QueryTooLong, + "request_too_large" => ErrorCode.RequestTooLarge, _ => (ErrorCode)(-1), }; } @@ -140,6 +142,7 @@ JsonSerializerOptions options ErrorCode.MaxUsesExceeded => "max_uses_exceeded", ErrorCode.TooManyRequests => "too_many_requests", ErrorCode.QueryTooLong => "query_too_long", + ErrorCode.RequestTooLarge => "request_too_large", _ => throw new AnthropicInvalidDataException( string.Format("Invalid value '{0}' in {1}", value, nameof(value)) ), diff --git a/src/Anthropic/Models/Messages/WebSearchToolResultError.cs b/src/Anthropic/Models/Messages/WebSearchToolResultError.cs index 3b0bbdbb3..bb5d8a4e2 100644 --- a/src/Anthropic/Models/Messages/WebSearchToolResultError.cs +++ b/src/Anthropic/Models/Messages/WebSearchToolResultError.cs @@ -106,6 +106,7 @@ public enum WebSearchToolResultErrorErrorCode MaxUsesExceeded, TooManyRequests, QueryTooLong, + RequestTooLarge, } sealed class WebSearchToolResultErrorErrorCodeConverter @@ -124,6 +125,7 @@ JsonSerializerOptions options "max_uses_exceeded" => WebSearchToolResultErrorErrorCode.MaxUsesExceeded, "too_many_requests" => WebSearchToolResultErrorErrorCode.TooManyRequests, "query_too_long" => WebSearchToolResultErrorErrorCode.QueryTooLong, + "request_too_large" => WebSearchToolResultErrorErrorCode.RequestTooLarge, _ => (WebSearchToolResultErrorErrorCode)(-1), }; } @@ -143,6 +145,7 @@ JsonSerializerOptions options WebSearchToolResultErrorErrorCode.MaxUsesExceeded => "max_uses_exceeded", WebSearchToolResultErrorErrorCode.TooManyRequests => "too_many_requests", WebSearchToolResultErrorErrorCode.QueryTooLong => "query_too_long", + WebSearchToolResultErrorErrorCode.RequestTooLarge => "request_too_large", _ => throw new AnthropicInvalidDataException( string.Format("Invalid value '{0}' in {1}", value, nameof(value)) ), From 7099a5d38f7692a6dbeb4dcf7a06b60492555733 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 18:34:40 +0000 Subject: [PATCH 10/41] chore(internal): update `actions/checkout` version --- .github/workflows/ci.yml | 6 +++--- .github/workflows/create-releases.yml | 2 +- .github/workflows/publish-nuget.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f58af350..4dd60f452 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up .NET uses: actions/setup-dotnet@v3 @@ -39,7 +39,7 @@ jobs: if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up .NET uses: actions/setup-dotnet@v3 @@ -55,7 +55,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/anthropic-csharp' && 'depot-windows-2022' || 'windows-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up .NET uses: actions/setup-dotnet@v5 diff --git a/.github/workflows/create-releases.yml b/.github/workflows/create-releases.yml index 96dfbda4f..c2f4fab9f 100644 --- a/.github/workflows/create-releases.yml +++ b/.github/workflows/create-releases.yml @@ -14,7 +14,7 @@ jobs: environment: production-release steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: stainless-api/trigger-release-please@v1 id: release diff --git a/.github/workflows/publish-nuget.yml b/.github/workflows/publish-nuget.yml index 31b120965..c9a9457eb 100644 --- a/.github/workflows/publish-nuget.yml +++ b/.github/workflows/publish-nuget.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up .NET uses: actions/setup-dotnet@v5 From 6c1887d3e5ae0f0744bb67a455b7c2dd066884ce Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 20:47:48 +0000 Subject: [PATCH 11/41] feat(client): add `ToString` to `ApiEnum` --- src/Anthropic/Core/ApiEnum.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Anthropic/Core/ApiEnum.cs b/src/Anthropic/Core/ApiEnum.cs index 8780ea6fb..299a3f6c0 100644 --- a/src/Anthropic/Core/ApiEnum.cs +++ b/src/Anthropic/Core/ApiEnum.cs @@ -94,6 +94,9 @@ public virtual bool Equals(ApiEnum? other) return other != null && JsonElement.DeepEquals(this.Json, other.Json); } + public override string ToString() => + JsonSerializer.Serialize(this.Json, ModelBase.ToStringSerializerOptions); + public override int GetHashCode() { return 0; From 8324572350d980ea4695f2830320b4c70bd9125c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 21:01:43 +0000 Subject: [PATCH 12/41] chore(internal): simplify imports --- .../Messages/Batches/BatchCreateParams.cs | 25 ++++++--------- .../Messages/Batches/BatchCreateParams.cs | 26 +++++++--------- .../Services/Beta/IMessageService.cs | 18 +++++------ src/Anthropic/Services/Beta/IModelService.cs | 16 ++++------ src/Anthropic/Services/Beta/MessageService.cs | 31 ++++++------------- src/Anthropic/Services/Beta/ModelService.cs | 27 ++++++---------- 6 files changed, 51 insertions(+), 92 deletions(-) diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs index 5e4428817..dc1d7bb09 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs @@ -340,14 +340,12 @@ public required ApiEnum Model /// /// Container identifier for reuse across requests. /// - public global::Anthropic.Models.Beta.Messages.Batches.Container? Container + public Container? Container { get { this._rawData.Freeze(); - return this._rawData.GetNullableClass( - "container" - ); + return this._rawData.GetNullableClass("container"); } init { this._rawData.Set("container", value); } } @@ -832,7 +830,7 @@ public Params FromRawUnchecked(IReadOnlyDictionary rawData) /// /// Container identifier for reuse across requests. /// -[JsonConverter(typeof(global::Anthropic.Models.Beta.Messages.Batches.ContainerConverter))] +[JsonConverter(typeof(ContainerConverter))] public record class Container : ModelBase { public object? Value { get; } = null; @@ -985,13 +983,9 @@ public T Match( }; } - public static implicit operator global::Anthropic.Models.Beta.Messages.Batches.Container( - BetaContainerParams value - ) => new(value); + public static implicit operator Container(BetaContainerParams value) => new(value); - public static implicit operator global::Anthropic.Models.Beta.Messages.Batches.Container( - string value - ) => new(value); + public static implicit operator Container(string value) => new(value); /// /// Validates that the instance was constructed with a known variant and that this variant is valid @@ -1012,7 +1006,7 @@ public override void Validate() this.Switch((betaContainerParams) => betaContainerParams.Validate(), (_) => { }); } - public virtual bool Equals(global::Anthropic.Models.Beta.Messages.Batches.Container? other) + public virtual bool Equals(Container? other) { return other != null && JsonElement.DeepEquals(this.Json, other.Json); } @@ -1026,10 +1020,9 @@ public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); } -sealed class ContainerConverter - : JsonConverter +sealed class ContainerConverter : JsonConverter { - public override global::Anthropic.Models.Beta.Messages.Batches.Container? Read( + public override Container? Read( ref Utf8JsonReader reader, System::Type typeToConvert, JsonSerializerOptions options @@ -1068,7 +1061,7 @@ JsonSerializerOptions options public override void Write( Utf8JsonWriter writer, - global::Anthropic.Models.Beta.Messages.Batches.Container? value, + Container? value, JsonSerializerOptions options ) { diff --git a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs index d4b59af83..b76e79b74 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs @@ -336,14 +336,12 @@ public Metadata? Metadata /// Anthropic offers different levels of service for your API requests. /// See [service-tiers](https://docs.claude.com/en/api/service-tiers) for details. /// - public ApiEnum? ServiceTier + public ApiEnum? ServiceTier { get { this._rawData.Freeze(); - return this._rawData.GetNullableClass< - ApiEnum - >("service_tier"); + return this._rawData.GetNullableClass>("service_tier"); } init { @@ -701,17 +699,16 @@ public Params FromRawUnchecked(IReadOnlyDictionary rawData) /// Anthropic offers different levels of service for your API requests. See /// [service-tiers](https://docs.claude.com/en/api/service-tiers) for details. /// -[JsonConverter(typeof(global::Anthropic.Models.Messages.Batches.ServiceTierConverter))] +[JsonConverter(typeof(ServiceTierConverter))] public enum ServiceTier { Auto, StandardOnly, } -sealed class ServiceTierConverter - : JsonConverter +sealed class ServiceTierConverter : JsonConverter { - public override global::Anthropic.Models.Messages.Batches.ServiceTier Read( + public override ServiceTier Read( ref Utf8JsonReader reader, System::Type typeToConvert, JsonSerializerOptions options @@ -719,15 +716,15 @@ JsonSerializerOptions options { return JsonSerializer.Deserialize(ref reader, options) switch { - "auto" => global::Anthropic.Models.Messages.Batches.ServiceTier.Auto, - "standard_only" => global::Anthropic.Models.Messages.Batches.ServiceTier.StandardOnly, - _ => (global::Anthropic.Models.Messages.Batches.ServiceTier)(-1), + "auto" => ServiceTier.Auto, + "standard_only" => ServiceTier.StandardOnly, + _ => (ServiceTier)(-1), }; } public override void Write( Utf8JsonWriter writer, - global::Anthropic.Models.Messages.Batches.ServiceTier value, + ServiceTier value, JsonSerializerOptions options ) { @@ -735,9 +732,8 @@ JsonSerializerOptions options writer, value switch { - global::Anthropic.Models.Messages.Batches.ServiceTier.Auto => "auto", - global::Anthropic.Models.Messages.Batches.ServiceTier.StandardOnly => - "standard_only", + ServiceTier.Auto => "auto", + ServiceTier.StandardOnly => "standard_only", _ => throw new AnthropicInvalidDataException( string.Format("Invalid value '{0}' in {1}", value, nameof(value)) ), diff --git a/src/Anthropic/Services/Beta/IMessageService.cs b/src/Anthropic/Services/Beta/IMessageService.cs index 1c004f92f..31479f0dd 100644 --- a/src/Anthropic/Services/Beta/IMessageService.cs +++ b/src/Anthropic/Services/Beta/IMessageService.cs @@ -19,16 +19,14 @@ public interface IMessageService /// Returns a view of this service that provides access to raw HTTP responses /// for each method. /// - global::Anthropic.Services.Beta.IMessageServiceWithRawResponse WithRawResponse { get; } + IMessageServiceWithRawResponse WithRawResponse { get; } /// /// Returns a view of this service with the given option modifications applied. /// /// The original service is not modified. /// - global::Anthropic.Services.Beta.IMessageService WithOptions( - Func modifier - ); + IMessageService WithOptions(Func modifier); IBatchService Batches { get; } @@ -75,7 +73,7 @@ Task CountTokens( } /// -/// A view of that provides access to raw +/// A view of that provides access to raw /// HTTP responses for each method. /// public interface IMessageServiceWithRawResponse @@ -85,15 +83,13 @@ public interface IMessageServiceWithRawResponse /// /// The original service is not modified. /// - global::Anthropic.Services.Beta.IMessageServiceWithRawResponse WithOptions( - Func modifier - ); + IMessageServiceWithRawResponse WithOptions(Func modifier); IBatchServiceWithRawResponse Batches { get; } /// /// Returns a raw HTTP response for `post /v1/messages?beta=true`, but is otherwise the - /// same as . + /// same as . /// Task> Create( MessageCreateParams parameters, @@ -102,7 +98,7 @@ Task> Create( /// /// Returns a raw HTTP response for `post /v1/messages?beta=true`, but is otherwise the - /// same as . + /// same as . /// Task> CreateStreaming( MessageCreateParams parameters, @@ -111,7 +107,7 @@ Task> CreateStreaming( /// /// Returns a raw HTTP response for `post /v1/messages/count_tokens?beta=true`, but is otherwise the - /// same as . + /// same as . /// Task> CountTokens( MessageCountTokensParams parameters, diff --git a/src/Anthropic/Services/Beta/IModelService.cs b/src/Anthropic/Services/Beta/IModelService.cs index bb7930e15..0436eafc8 100644 --- a/src/Anthropic/Services/Beta/IModelService.cs +++ b/src/Anthropic/Services/Beta/IModelService.cs @@ -17,16 +17,14 @@ public interface IModelService /// Returns a view of this service that provides access to raw HTTP responses /// for each method. /// - global::Anthropic.Services.Beta.IModelServiceWithRawResponse WithRawResponse { get; } + IModelServiceWithRawResponse WithRawResponse { get; } /// /// Returns a view of this service with the given option modifications applied. /// /// The original service is not modified. /// - global::Anthropic.Services.Beta.IModelService WithOptions( - Func modifier - ); + IModelService WithOptions(Func modifier); /// /// Get a specific model. @@ -59,7 +57,7 @@ Task List( } /// -/// A view of that provides access to raw +/// A view of that provides access to raw /// HTTP responses for each method. /// public interface IModelServiceWithRawResponse @@ -69,13 +67,11 @@ public interface IModelServiceWithRawResponse /// /// The original service is not modified. /// - global::Anthropic.Services.Beta.IModelServiceWithRawResponse WithOptions( - Func modifier - ); + IModelServiceWithRawResponse WithOptions(Func modifier); /// /// Returns a raw HTTP response for `get /v1/models/{model_id}?beta=true`, but is otherwise the - /// same as . + /// same as . /// Task> Retrieve( ModelRetrieveParams parameters, @@ -91,7 +87,7 @@ Task> Retrieve( /// /// Returns a raw HTTP response for `get /v1/models?beta=true`, but is otherwise the - /// same as . + /// same as . /// Task> List( ModelListParams? parameters = null, diff --git a/src/Anthropic/Services/Beta/MessageService.cs b/src/Anthropic/Services/Beta/MessageService.cs index 3c84861e9..47a99b953 100644 --- a/src/Anthropic/Services/Beta/MessageService.cs +++ b/src/Anthropic/Services/Beta/MessageService.cs @@ -13,12 +13,12 @@ namespace Anthropic.Services.Beta; /// -public sealed class MessageService : global::Anthropic.Services.Beta.IMessageService +public sealed class MessageService : IMessageService { - readonly Lazy _withRawResponse; + readonly Lazy _withRawResponse; /// - public global::Anthropic.Services.Beta.IMessageServiceWithRawResponse WithRawResponse + public IMessageServiceWithRawResponse WithRawResponse { get { return _withRawResponse.Value; } } @@ -26,24 +26,16 @@ public sealed class MessageService : global::Anthropic.Services.Beta.IMessageSer internal readonly IAnthropicClient _client; /// - public global::Anthropic.Services.Beta.IMessageService WithOptions( - Func modifier - ) + public IMessageService WithOptions(Func modifier) { - return new global::Anthropic.Services.Beta.MessageService( - this._client.WithOptions(modifier) - ); + return new MessageService(this._client.WithOptions(modifier)); } public MessageService(IAnthropicClient client) { _client = client; - _withRawResponse = new(() => - new global::Anthropic.Services.Beta.MessageServiceWithRawResponse( - client.WithRawResponse - ) - ); + _withRawResponse = new(() => new MessageServiceWithRawResponse(client.WithRawResponse)); _batches = new(() => new BatchService(client)); } @@ -94,19 +86,14 @@ public async Task CountTokens( } /// -public sealed class MessageServiceWithRawResponse - : global::Anthropic.Services.Beta.IMessageServiceWithRawResponse +public sealed class MessageServiceWithRawResponse : IMessageServiceWithRawResponse { readonly IAnthropicClientWithRawResponse _client; /// - public global::Anthropic.Services.Beta.IMessageServiceWithRawResponse WithOptions( - Func modifier - ) + public IMessageServiceWithRawResponse WithOptions(Func modifier) { - return new global::Anthropic.Services.Beta.MessageServiceWithRawResponse( - this._client.WithOptions(modifier) - ); + return new MessageServiceWithRawResponse(this._client.WithOptions(modifier)); } public MessageServiceWithRawResponse(IAnthropicClientWithRawResponse client) diff --git a/src/Anthropic/Services/Beta/ModelService.cs b/src/Anthropic/Services/Beta/ModelService.cs index 4c19b6d53..4d096e094 100644 --- a/src/Anthropic/Services/Beta/ModelService.cs +++ b/src/Anthropic/Services/Beta/ModelService.cs @@ -9,12 +9,12 @@ namespace Anthropic.Services.Beta; /// -public sealed class ModelService : global::Anthropic.Services.Beta.IModelService +public sealed class ModelService : IModelService { - readonly Lazy _withRawResponse; + readonly Lazy _withRawResponse; /// - public global::Anthropic.Services.Beta.IModelServiceWithRawResponse WithRawResponse + public IModelServiceWithRawResponse WithRawResponse { get { return _withRawResponse.Value; } } @@ -22,20 +22,16 @@ public sealed class ModelService : global::Anthropic.Services.Beta.IModelService readonly IAnthropicClient _client; /// - public global::Anthropic.Services.Beta.IModelService WithOptions( - Func modifier - ) + public IModelService WithOptions(Func modifier) { - return new global::Anthropic.Services.Beta.ModelService(this._client.WithOptions(modifier)); + return new ModelService(this._client.WithOptions(modifier)); } public ModelService(IAnthropicClient client) { _client = client; - _withRawResponse = new(() => - new global::Anthropic.Services.Beta.ModelServiceWithRawResponse(client.WithRawResponse) - ); + _withRawResponse = new(() => new ModelServiceWithRawResponse(client.WithRawResponse)); } /// @@ -76,19 +72,14 @@ public async Task List( } /// -public sealed class ModelServiceWithRawResponse - : global::Anthropic.Services.Beta.IModelServiceWithRawResponse +public sealed class ModelServiceWithRawResponse : IModelServiceWithRawResponse { readonly IAnthropicClientWithRawResponse _client; /// - public global::Anthropic.Services.Beta.IModelServiceWithRawResponse WithOptions( - Func modifier - ) + public IModelServiceWithRawResponse WithOptions(Func modifier) { - return new global::Anthropic.Services.Beta.ModelServiceWithRawResponse( - this._client.WithOptions(modifier) - ); + return new ModelServiceWithRawResponse(this._client.WithOptions(modifier)); } public ModelServiceWithRawResponse(IAnthropicClientWithRawResponse client) From 3be53975b406cca32cb0cd311a0cf684863855a8 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 16 Jan 2026 22:06:09 +0000 Subject: [PATCH 13/41] feat(client): add Equals and ToString to params --- .../Models/Beta/Files/FileDeleteParamsTest.cs | 10 ++ .../Beta/Files/FileDownloadParamsTest.cs | 10 ++ .../Models/Beta/Files/FileListParamsTest.cs | 16 ++ .../Files/FileRetrieveMetadataParamsTest.cs | 10 ++ .../Messages/Batches/BatchCancelParamsTest.cs | 14 ++ .../Messages/Batches/BatchCreateParamsTest.cs | 146 ++++++++++++++++++ .../Messages/Batches/BatchDeleteParamsTest.cs | 14 ++ .../Messages/Batches/BatchListParamsTest.cs | 16 ++ .../Batches/BatchResultsParamsTest.cs | 14 ++ .../Batches/BatchRetrieveParamsTest.cs | 14 ++ .../Messages/MessageCountTokensParamsTest.cs | 108 +++++++++++++ .../Beta/Messages/MessageCreateParamsTest.cs | 128 +++++++++++++++ .../Models/Beta/Models/ModelListParamsTest.cs | 16 ++ .../Beta/Models/ModelRetrieveParamsTest.cs | 10 ++ .../Beta/Skills/SkillDeleteParamsTest.cs | 10 ++ .../Models/Beta/Skills/SkillListParamsTest.cs | 16 ++ .../Beta/Skills/SkillRetrieveParamsTest.cs | 10 ++ .../Versions/VersionDeleteParamsTest.cs | 15 ++ .../Skills/Versions/VersionListParamsTest.cs | 16 ++ .../Versions/VersionRetrieveParamsTest.cs | 15 ++ .../Messages/Batches/BatchCancelParamsTest.cs | 10 ++ .../Messages/Batches/BatchCreateParamsTest.cs | 76 +++++++++ .../Messages/Batches/BatchDeleteParamsTest.cs | 10 ++ .../Messages/Batches/BatchListParamsTest.cs | 15 ++ .../Batches/BatchResultsParamsTest.cs | 10 ++ .../Batches/BatchRetrieveParamsTest.cs | 10 ++ .../Messages/MessageCountTokensParamsTest.cs | 55 +++++++ .../Messages/MessageCreateParamsTest.cs | 62 ++++++++ .../Models/Models/ModelListParamsTest.cs | 16 ++ .../Models/Models/ModelRetrieveParamsTest.cs | 10 ++ .../Models/Beta/Files/FileDeleteParams.cs | 36 ++++- .../Models/Beta/Files/FileDownloadParams.cs | 36 ++++- .../Models/Beta/Files/FileListParams.cs | 34 +++- .../Beta/Files/FileRetrieveMetadataParams.cs | 36 ++++- .../Messages/Batches/BatchCancelParams.cs | 36 ++++- .../Messages/Batches/BatchCreateParams.cs | 36 ++++- .../Messages/Batches/BatchDeleteParams.cs | 36 ++++- .../Beta/Messages/Batches/BatchListParams.cs | 34 +++- .../Messages/Batches/BatchResultsParams.cs | 36 ++++- .../Messages/Batches/BatchRetrieveParams.cs | 36 ++++- .../Beta/Messages/MessageCountTokensParams.cs | 36 ++++- .../Beta/Messages/MessageCreateParams.cs | 36 ++++- .../Models/Beta/Models/ModelListParams.cs | 34 +++- .../Models/Beta/Models/ModelRetrieveParams.cs | 36 ++++- .../Models/Beta/Skills/SkillCreateParams.cs | 14 +- .../Models/Beta/Skills/SkillDeleteParams.cs | 36 ++++- .../Models/Beta/Skills/SkillListParams.cs | 34 +++- .../Models/Beta/Skills/SkillRetrieveParams.cs | 36 ++++- .../Skills/Versions/VersionCreateParams.cs | 14 +- .../Skills/Versions/VersionDeleteParams.cs | 38 ++++- .../Beta/Skills/Versions/VersionListParams.cs | 36 ++++- .../Skills/Versions/VersionRetrieveParams.cs | 38 ++++- .../Messages/Batches/BatchCancelParams.cs | 36 ++++- .../Messages/Batches/BatchCreateParams.cs | 36 ++++- .../Messages/Batches/BatchDeleteParams.cs | 36 ++++- .../Messages/Batches/BatchListParams.cs | 34 +++- .../Messages/Batches/BatchResultsParams.cs | 36 ++++- .../Messages/Batches/BatchRetrieveParams.cs | 36 ++++- .../Messages/MessageCountTokensParams.cs | 36 ++++- .../Models/Messages/MessageCreateParams.cs | 36 ++++- .../Models/Models/ModelListParams.cs | 34 +++- .../Models/Models/ModelRetrieveParams.cs | 36 ++++- 62 files changed, 1950 insertions(+), 32 deletions(-) diff --git a/src/Anthropic.Tests/Models/Beta/Files/FileDeleteParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Files/FileDeleteParamsTest.cs index 3e576c0c0..ef28f357d 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/FileDeleteParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/FileDeleteParamsTest.cs @@ -73,4 +73,14 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new FileDeleteParams { FileID = "file_id", Betas = ["string"] }; + + FileDeleteParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Files/FileDownloadParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Files/FileDownloadParamsTest.cs index 5353d8a92..5916a60bd 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/FileDownloadParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/FileDownloadParamsTest.cs @@ -73,4 +73,14 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new FileDownloadParams { FileID = "file_id", Betas = ["string"] }; + + FileDownloadParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Files/FileListParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Files/FileListParamsTest.cs index d622f3010..bd580bc61 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/FileListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/FileListParamsTest.cs @@ -106,4 +106,20 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new FileListParams + { + AfterID = "after_id", + BeforeID = "before_id", + Limit = 1, + Betas = ["string"], + }; + + FileListParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Files/FileRetrieveMetadataParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Files/FileRetrieveMetadataParamsTest.cs index ca9b5163f..22ad6dbe7 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/FileRetrieveMetadataParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/FileRetrieveMetadataParamsTest.cs @@ -73,4 +73,14 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new FileRetrieveMetadataParams { FileID = "file_id", Betas = ["string"] }; + + FileRetrieveMetadataParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCancelParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCancelParamsTest.cs index e8fcdeeb4..a7a1b400a 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCancelParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCancelParamsTest.cs @@ -84,4 +84,18 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchCancelParams + { + MessageBatchID = "message_batch_id", + Betas = ["string"], + }; + + BatchCancelParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs index b0de5f635..7da0e0c73 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs @@ -883,6 +883,152 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchCreateParams + { + Requests = + [ + new() + { + CustomID = "my-custom-id-1", + Params = new() + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Container = new Messages::BetaContainerParams() + { + ID = "id", + Skills = + [ + new() + { + SkillID = "x", + Type = Messages::BetaSkillParamsType.Anthropic, + Version = "x", + }, + ], + }, + ContextManagement = new() + { + Edits = + [ + new Messages::BetaClearToolUses20250919Edit() + { + ClearAtLeast = new(0), + ClearToolInputs = true, + ExcludeTools = ["string"], + Keep = new(0), + Trigger = new Messages::BetaInputTokensTrigger(1), + }, + ], + }, + McpServers = + [ + new() + { + Name = "name", + Url = "url", + AuthorizationToken = "authorization_token", + ToolConfiguration = new() + { + AllowedTools = ["string"], + Enabled = true, + }, + }, + ], + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + OutputFormat = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::BetaTextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::BetaCitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::BetaThinkingConfigEnabled(1024), + ToolChoice = new Messages::BetaToolChoiceAuto() + { + DisableParallelToolUse = true, + }, + Tools = + [ + new Messages::BetaTool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + AllowedCallers = [Messages::BetaToolAllowedCaller.Direct], + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + DeferLoading = true, + Description = "Get the current weather in a given location", + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + Type = Messages::BetaToolType.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }, + }, + ], + Betas = ["string"], + }; + + BatchCreateParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } public class RequestTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchDeleteParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchDeleteParamsTest.cs index 323663256..fc17a9ff8 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchDeleteParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchDeleteParamsTest.cs @@ -84,4 +84,18 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchDeleteParams + { + MessageBatchID = "message_batch_id", + Betas = ["string"], + }; + + BatchDeleteParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListParamsTest.cs index df9035458..ef400702b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListParamsTest.cs @@ -106,4 +106,20 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchListParams + { + AfterID = "after_id", + BeforeID = "before_id", + Limit = 1, + Betas = ["string"], + }; + + BatchListParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchResultsParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchResultsParamsTest.cs index 39f89f896..27f19e0fb 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchResultsParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchResultsParamsTest.cs @@ -84,4 +84,18 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchResultsParams + { + MessageBatchID = "message_batch_id", + Betas = ["string"], + }; + + BatchResultsParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchRetrieveParamsTest.cs index 268f3eef9..55fc65a13 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchRetrieveParamsTest.cs @@ -84,4 +84,18 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchRetrieveParams + { + MessageBatchID = "message_batch_id", + Betas = ["string"], + }; + + BatchRetrieveParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs index 4339289f1..374c420fd 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs @@ -555,6 +555,114 @@ public void AddHeadersToRequest_Works() Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new MessageCountTokensParams + { + Messages = [new() { Content = "string", Role = Role.User }], + Model = Messages::Model.ClaudeOpus4_5_20251101, + ContextManagement = new() + { + Edits = + [ + new BetaClearToolUses20250919Edit() + { + ClearAtLeast = new(0), + ClearToolInputs = true, + ExcludeTools = ["string"], + Keep = new(0), + Trigger = new BetaInputTokensTrigger(1), + }, + ], + }, + McpServers = + [ + new() + { + Name = "name", + Url = "url", + AuthorizationToken = "authorization_token", + ToolConfiguration = new() { AllowedTools = ["string"], Enabled = true }, + }, + ], + OutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + OutputFormat = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + System = new( + [ + new BetaTextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = + [ + new BetaCitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Thinking = new BetaThinkingConfigEnabled(1024), + ToolChoice = new BetaToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new BetaTool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + AllowedCallers = [BetaToolAllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + Description = "Get the current weather in a given location", + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + Type = BetaToolType.Custom, + }, + ], + Betas = ["string"], + }; + + MessageCountTokensParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } public class MessageCountTokensParamsSystemTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs index bcb89755b..70c00809a 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs @@ -691,6 +691,134 @@ public void AddHeadersToRequest_Works() Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new MessageCreateParams + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Role.User }], + Model = Messages::Model.ClaudeSonnet4_5_20250929, + Container = new BetaContainerParams() + { + ID = "id", + Skills = + [ + new() + { + SkillID = "x", + Type = BetaSkillParamsType.Anthropic, + Version = "x", + }, + ], + }, + ContextManagement = new() + { + Edits = + [ + new BetaClearToolUses20250919Edit() + { + ClearAtLeast = new(0), + ClearToolInputs = true, + ExcludeTools = ["string"], + Keep = new(0), + Trigger = new BetaInputTokensTrigger(1), + }, + ], + }, + McpServers = + [ + new() + { + Name = "name", + Url = "url", + AuthorizationToken = "authorization_token", + ToolConfiguration = new() { AllowedTools = ["string"], Enabled = true }, + }, + ], + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + OutputFormat = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + System = new( + [ + new BetaTextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = + [ + new BetaCitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new BetaThinkingConfigEnabled(1024), + ToolChoice = new BetaToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new BetaTool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + AllowedCallers = [BetaToolAllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + Description = "Get the current weather in a given location", + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + Type = BetaToolType.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + Betas = ["string"], + }; + + MessageCreateParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } public class ContainerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Models/ModelListParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Models/ModelListParamsTest.cs index f922e531f..6b5cc0a22 100644 --- a/src/Anthropic.Tests/Models/Beta/Models/ModelListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Models/ModelListParamsTest.cs @@ -103,4 +103,20 @@ public void AddHeadersToRequest_Works() Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new ModelListParams + { + AfterID = "after_id", + BeforeID = "before_id", + Limit = 1, + Betas = ["string"], + }; + + ModelListParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Models/ModelRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Models/ModelRetrieveParamsTest.cs index 934f24dc2..f8d227ae3 100644 --- a/src/Anthropic.Tests/Models/Beta/Models/ModelRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Models/ModelRetrieveParamsTest.cs @@ -70,4 +70,14 @@ public void AddHeadersToRequest_Works() Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new ModelRetrieveParams { ModelID = "model_id", Betas = ["string"] }; + + ModelRetrieveParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteParamsTest.cs index 23b39e22c..a6f34b713 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteParamsTest.cs @@ -73,4 +73,14 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new SkillDeleteParams { SkillID = "skill_id", Betas = ["string"] }; + + SkillDeleteParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillListParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillListParamsTest.cs index e73d6aec6..a98225e59 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillListParamsTest.cs @@ -126,4 +126,20 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new SkillListParams + { + Limit = 0, + Page = "page", + Source = "source", + Betas = ["string"], + }; + + SkillListParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveParamsTest.cs index f4dfb5ba2..bc8697155 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveParamsTest.cs @@ -73,4 +73,14 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new SkillRetrieveParams { SkillID = "skill_id", Betas = ["string"] }; + + SkillRetrieveParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteParamsTest.cs index 8bc3d96ae..f2f6c090b 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteParamsTest.cs @@ -86,4 +86,19 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new VersionDeleteParams + { + SkillID = "skill_id", + Version = "version", + Betas = ["string"], + }; + + VersionDeleteParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListParamsTest.cs index 38d21efc8..21903559f 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListParamsTest.cs @@ -127,4 +127,20 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new VersionListParams + { + SkillID = "skill_id", + Limit = 0, + Page = "page", + Betas = ["string"], + }; + + VersionListParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveParamsTest.cs index 21acb56f4..1a8e595b3 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveParamsTest.cs @@ -86,4 +86,19 @@ public void AddHeadersToRequest_Works() requestMessage.Headers.GetValues("anthropic-beta") ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new VersionRetrieveParams + { + SkillID = "skill_id", + Version = "version", + Betas = ["string"], + }; + + VersionRetrieveParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/BatchCancelParamsTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/BatchCancelParamsTest.cs index 906a10c5c..a024976f4 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/BatchCancelParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/BatchCancelParamsTest.cs @@ -27,4 +27,14 @@ public void Url_Works() url ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchCancelParams { MessageBatchID = "message_batch_id" }; + + BatchCancelParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs index a4bfe20e9..b1ccf8470 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs @@ -225,6 +225,82 @@ public void Url_Works() Assert.Equal(new Uri("https://api.anthropic.com/v1/messages/batches"), url); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchCreateParams + { + Requests = + [ + new() + { + CustomID = "my-custom-id-1", + Params = new() + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeSonnet4_5_20250929, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() + { + DisableParallelToolUse = true, + }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }, + }, + ], + }; + + BatchCreateParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } public class RequestTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/Batches/BatchDeleteParamsTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/BatchDeleteParamsTest.cs index eeec86932..06432c34a 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/BatchDeleteParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/BatchDeleteParamsTest.cs @@ -27,4 +27,14 @@ public void Url_Works() url ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchDeleteParams { MessageBatchID = "message_batch_id" }; + + BatchDeleteParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/BatchListParamsTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/BatchListParamsTest.cs index 411f0e2d3..141b0712c 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/BatchListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/BatchListParamsTest.cs @@ -75,4 +75,19 @@ public void Url_Works() url ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchListParams + { + AfterID = "after_id", + BeforeID = "before_id", + Limit = 1, + }; + + BatchListParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/BatchResultsParamsTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/BatchResultsParamsTest.cs index 51ad98918..f40ff5d8f 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/BatchResultsParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/BatchResultsParamsTest.cs @@ -27,4 +27,14 @@ public void Url_Works() url ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchResultsParams { MessageBatchID = "message_batch_id" }; + + BatchResultsParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/BatchRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/BatchRetrieveParamsTest.cs index 831b93410..6f08bc568 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/BatchRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/BatchRetrieveParamsTest.cs @@ -27,4 +27,14 @@ public void Url_Works() url ); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new BatchRetrieveParams { MessageBatchID = "message_batch_id" }; + + BatchRetrieveParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs b/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs index 4ef6ab026..b7717ccb7 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs @@ -182,6 +182,61 @@ public void Url_Works() Assert.Equal(new Uri("https://api.anthropic.com/v1/messages/count_tokens"), url); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new Messages::MessageCountTokensParams + { + Messages = [new() { Content = "string", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeOpus4_5_20251101, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + Type = Messages::Type.Custom, + }, + ], + }; + + Messages::MessageCountTokensParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } public class MessageCountTokensParamsSystemTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs b/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs index 3abb7ea31..fc3f39cae 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs @@ -245,6 +245,68 @@ public void Url_Works() Assert.Equal(new Uri("https://api.anthropic.com/v1/messages"), url); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new Messages::MessageCreateParams + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeSonnet4_5_20250929, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + ServiceTier = Messages::ServiceTier.Auto, + StopSequences = ["string"], + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }; + + Messages::MessageCreateParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } public class ServiceTierTest : TestBase diff --git a/src/Anthropic.Tests/Models/Models/ModelListParamsTest.cs b/src/Anthropic.Tests/Models/Models/ModelListParamsTest.cs index 6995d4030..a6dae8e77 100644 --- a/src/Anthropic.Tests/Models/Models/ModelListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Models/ModelListParamsTest.cs @@ -103,4 +103,20 @@ public void AddHeadersToRequest_Works() Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new ModelListParams + { + AfterID = "after_id", + BeforeID = "before_id", + Limit = 1, + Betas = ["string"], + }; + + ModelListParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic.Tests/Models/Models/ModelRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Models/ModelRetrieveParamsTest.cs index bbf79ea83..1b5a45a14 100644 --- a/src/Anthropic.Tests/Models/Models/ModelRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Models/ModelRetrieveParamsTest.cs @@ -70,4 +70,14 @@ public void AddHeadersToRequest_Works() Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); } + + [Fact] + public void CopyConstructor_Works() + { + var parameters = new ModelRetrieveParams { ModelID = "model_id", Betas = ["string"] }; + + ModelRetrieveParams copied = new(parameters); + + Assert.Equal(parameters, copied); + } } diff --git a/src/Anthropic/Models/Beta/Files/FileDeleteParams.cs b/src/Anthropic/Models/Beta/Files/FileDeleteParams.cs index e480f6c61..1cba83766 100644 --- a/src/Anthropic/Models/Beta/Files/FileDeleteParams.cs +++ b/src/Anthropic/Models/Beta/Files/FileDeleteParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Files; /// /// Delete File +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class FileDeleteParams : ParamsBase +public record class FileDeleteParams : ParamsBase { public string? FileID { get; init; } @@ -45,11 +49,14 @@ public IReadOnlyList>? Betas public FileDeleteParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public FileDeleteParams(FileDeleteParams fileDeleteParams) : base(fileDeleteParams) { this.FileID = fileDeleteParams.FileID; } +#pragma warning restore CS8618 public FileDeleteParams( IReadOnlyDictionary rawHeaderData, @@ -84,6 +91,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["FileID"] = this.FileID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(FileDeleteParams? other) + { + if (other == null) + { + return false; + } + return (this.FileID?.Equals(other.FileID) ?? other.FileID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -104,4 +133,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Files/FileDownloadParams.cs b/src/Anthropic/Models/Beta/Files/FileDownloadParams.cs index 90499fa68..cd4affee9 100644 --- a/src/Anthropic/Models/Beta/Files/FileDownloadParams.cs +++ b/src/Anthropic/Models/Beta/Files/FileDownloadParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Files; /// /// Download File +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class FileDownloadParams : ParamsBase +public record class FileDownloadParams : ParamsBase { public string? FileID { get; init; } @@ -45,11 +49,14 @@ public IReadOnlyList>? Betas public FileDownloadParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public FileDownloadParams(FileDownloadParams fileDownloadParams) : base(fileDownloadParams) { this.FileID = fileDownloadParams.FileID; } +#pragma warning restore CS8618 public FileDownloadParams( IReadOnlyDictionary rawHeaderData, @@ -84,6 +91,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["FileID"] = this.FileID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(FileDownloadParams? other) + { + if (other == null) + { + return false; + } + return (this.FileID?.Equals(other.FileID) ?? other.FileID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -104,4 +133,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Files/FileListParams.cs b/src/Anthropic/Models/Beta/Files/FileListParams.cs index ca0ee38e4..b59c7869c 100644 --- a/src/Anthropic/Models/Beta/Files/FileListParams.cs +++ b/src/Anthropic/Models/Beta/Files/FileListParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Files; /// /// List Files +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class FileListParams : ParamsBase +public record class FileListParams : ParamsBase { /// /// ID of the object to use as a cursor for pagination. When provided, returns @@ -110,8 +114,11 @@ public IReadOnlyList>? Betas public FileListParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public FileListParams(FileListParams fileListParams) : base(fileListParams) { } +#pragma warning restore CS8618 public FileListParams( IReadOnlyDictionary rawHeaderData, @@ -146,6 +153,26 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(FileListParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder(options.BaseUrl.ToString().TrimEnd('/') + "/v1/files?beta=true") @@ -163,4 +190,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Files/FileRetrieveMetadataParams.cs b/src/Anthropic/Models/Beta/Files/FileRetrieveMetadataParams.cs index c5b1c319d..002ec819c 100644 --- a/src/Anthropic/Models/Beta/Files/FileRetrieveMetadataParams.cs +++ b/src/Anthropic/Models/Beta/Files/FileRetrieveMetadataParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Files; /// /// Get File Metadata +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class FileRetrieveMetadataParams : ParamsBase +public record class FileRetrieveMetadataParams : ParamsBase { public string? FileID { get; init; } @@ -45,11 +49,14 @@ public IReadOnlyList>? Betas public FileRetrieveMetadataParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public FileRetrieveMetadataParams(FileRetrieveMetadataParams fileRetrieveMetadataParams) : base(fileRetrieveMetadataParams) { this.FileID = fileRetrieveMetadataParams.FileID; } +#pragma warning restore CS8618 public FileRetrieveMetadataParams( IReadOnlyDictionary rawHeaderData, @@ -84,6 +91,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["FileID"] = this.FileID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(FileRetrieveMetadataParams? other) + { + if (other == null) + { + return false; + } + return (this.FileID?.Equals(other.FileID) ?? other.FileID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -104,4 +133,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchCancelParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchCancelParams.cs index f69478abd..cd239cb12 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchCancelParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchCancelParams.cs @@ -20,8 +20,12 @@ namespace Anthropic.Models.Beta.Messages.Batches; /// Note that cancellation may not result in any canceled requests if they were non-interruptible. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchCancelParams : ParamsBase +public record class BatchCancelParams : ParamsBase { public string? MessageBatchID { get; init; } @@ -53,11 +57,14 @@ public IReadOnlyList>? Betas public BatchCancelParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchCancelParams(BatchCancelParams batchCancelParams) : base(batchCancelParams) { this.MessageBatchID = batchCancelParams.MessageBatchID; } +#pragma warning restore CS8618 public BatchCancelParams( IReadOnlyDictionary rawHeaderData, @@ -92,6 +99,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["MessageBatchID"] = this.MessageBatchID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchCancelParams? other) + { + if (other == null) + { + return false; + } + return (this.MessageBatchID?.Equals(other.MessageBatchID) ?? other.MessageBatchID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -112,4 +141,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs index dc1d7bb09..93409b123 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs @@ -22,8 +22,12 @@ namespace Anthropic.Models.Beta.Messages.Batches; /// can take up to 24 hours to complete. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchCreateParams : ParamsBase +public record class BatchCreateParams : ParamsBase { readonly JsonDictionary _rawBodyData = new(); public IReadOnlyDictionary RawBodyData @@ -79,11 +83,14 @@ public IReadOnlyList>? Betas public BatchCreateParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchCreateParams(BatchCreateParams batchCreateParams) : base(batchCreateParams) { this._rawBodyData = new(batchCreateParams._rawBodyData); } +#pragma warning restore CS8618 public BatchCreateParams( IReadOnlyDictionary rawHeaderData, @@ -124,6 +131,28 @@ IReadOnlyDictionary rawBodyData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + ["BodyData"] = this._rawBodyData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchCreateParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData) + && this._rawBodyData.Equals(other._rawBodyData); + } + public override System::Uri Url(ClientOptions options) { return new System::UriBuilder( @@ -152,6 +181,11 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } [JsonConverter(typeof(JsonModelConverter))] diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchDeleteParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchDeleteParams.cs index c34df583e..11c0e6d2b 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchDeleteParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchDeleteParams.cs @@ -17,8 +17,12 @@ namespace Anthropic.Models.Beta.Messages.Batches; /// you'd like to delete an in-progress batch, you must first cancel it. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchDeleteParams : ParamsBase +public record class BatchDeleteParams : ParamsBase { public string? MessageBatchID { get; init; } @@ -50,11 +54,14 @@ public IReadOnlyList>? Betas public BatchDeleteParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchDeleteParams(BatchDeleteParams batchDeleteParams) : base(batchDeleteParams) { this.MessageBatchID = batchDeleteParams.MessageBatchID; } +#pragma warning restore CS8618 public BatchDeleteParams( IReadOnlyDictionary rawHeaderData, @@ -89,6 +96,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["MessageBatchID"] = this.MessageBatchID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchDeleteParams? other) + { + if (other == null) + { + return false; + } + return (this.MessageBatchID?.Equals(other.MessageBatchID) ?? other.MessageBatchID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -109,4 +138,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchListParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchListParams.cs index 9ffe042d4..3250593a3 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchListParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchListParams.cs @@ -15,8 +15,12 @@ namespace Anthropic.Models.Beta.Messages.Batches; /// returned first. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchListParams : ParamsBase +public record class BatchListParams : ParamsBase { /// /// ID of the object to use as a cursor for pagination. When provided, returns @@ -113,8 +117,11 @@ public IReadOnlyList>? Betas public BatchListParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchListParams(BatchListParams batchListParams) : base(batchListParams) { } +#pragma warning restore CS8618 public BatchListParams( IReadOnlyDictionary rawHeaderData, @@ -149,6 +156,26 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchListParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -168,4 +195,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchResultsParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchResultsParams.cs index 2b154384a..69cd74f85 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchResultsParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchResultsParams.cs @@ -18,8 +18,12 @@ namespace Anthropic.Models.Beta.Messages.Batches; /// as requests. Use the `custom_id` field to match results to requests. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchResultsParams : ParamsBase +public record class BatchResultsParams : ParamsBase { public string? MessageBatchID { get; init; } @@ -51,11 +55,14 @@ public IReadOnlyList>? Betas public BatchResultsParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchResultsParams(BatchResultsParams batchResultsParams) : base(batchResultsParams) { this.MessageBatchID = batchResultsParams.MessageBatchID; } +#pragma warning restore CS8618 public BatchResultsParams( IReadOnlyDictionary rawHeaderData, @@ -90,6 +97,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["MessageBatchID"] = this.MessageBatchID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchResultsParams? other) + { + if (other == null) + { + return false; + } + return (this.MessageBatchID?.Equals(other.MessageBatchID) ?? other.MessageBatchID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -110,4 +139,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchRetrieveParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchRetrieveParams.cs index 0d81a8120..064ebfedd 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchRetrieveParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchRetrieveParams.cs @@ -16,8 +16,12 @@ namespace Anthropic.Models.Beta.Messages.Batches; /// field in the response. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchRetrieveParams : ParamsBase +public record class BatchRetrieveParams : ParamsBase { public string? MessageBatchID { get; init; } @@ -49,11 +53,14 @@ public IReadOnlyList>? Betas public BatchRetrieveParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchRetrieveParams(BatchRetrieveParams batchRetrieveParams) : base(batchRetrieveParams) { this.MessageBatchID = batchRetrieveParams.MessageBatchID; } +#pragma warning restore CS8618 public BatchRetrieveParams( IReadOnlyDictionary rawHeaderData, @@ -88,6 +95,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["MessageBatchID"] = this.MessageBatchID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchRetrieveParams? other) + { + if (other == null) + { + return false; + } + return (this.MessageBatchID?.Equals(other.MessageBatchID) ?? other.MessageBatchID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -108,4 +137,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs b/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs index d783af87c..f45fbeef4 100644 --- a/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs +++ b/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs @@ -20,8 +20,12 @@ namespace Anthropic.Models.Beta.Messages; /// including tools, images, and documents, without creating it. /// /// Learn more about token counting in our [user guide](https://docs.claude.com/en/docs/build-with-claude/token-counting) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class MessageCountTokensParams : ParamsBase +public record class MessageCountTokensParams : ParamsBase { readonly JsonDictionary _rawBodyData = new(); public IReadOnlyDictionary RawBodyData @@ -363,11 +367,14 @@ public IReadOnlyList>? Betas public MessageCountTokensParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageCountTokensParams(MessageCountTokensParams messageCountTokensParams) : base(messageCountTokensParams) { this._rawBodyData = new(messageCountTokensParams._rawBodyData); } +#pragma warning restore CS8618 public MessageCountTokensParams( IReadOnlyDictionary rawHeaderData, @@ -408,6 +415,28 @@ IReadOnlyDictionary rawBodyData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + ["BodyData"] = this._rawBodyData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(MessageCountTokensParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData) + && this._rawBodyData.Equals(other._rawBodyData); + } + public override System::Uri Url(ClientOptions options) { return new System::UriBuilder( @@ -435,6 +464,11 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } /// diff --git a/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs b/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs index e9d978eec..7529e94b9 100644 --- a/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs @@ -20,8 +20,12 @@ namespace Anthropic.Models.Beta.Messages; /// The Messages API can be used for either single queries or stateless multi-turn conversations. /// /// Learn more about the Messages API in our [user guide](https://docs.claude.com/en/docs/initial-setup) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class MessageCreateParams : ParamsBase +public record class MessageCreateParams : ParamsBase { readonly JsonDictionary _rawBodyData = new(); public IReadOnlyDictionary RawBodyData @@ -556,11 +560,14 @@ public IReadOnlyList>? Betas public MessageCreateParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageCreateParams(MessageCreateParams messageCreateParams) : base(messageCreateParams) { this._rawBodyData = new(messageCreateParams._rawBodyData); } +#pragma warning restore CS8618 public MessageCreateParams( IReadOnlyDictionary rawHeaderData, @@ -601,6 +608,28 @@ IReadOnlyDictionary rawBodyData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + ["BodyData"] = this._rawBodyData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(MessageCreateParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData) + && this._rawBodyData.Equals(other._rawBodyData); + } + public override System::Uri Url(ClientOptions options) { return new System::UriBuilder( @@ -628,6 +657,11 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } /// diff --git a/src/Anthropic/Models/Beta/Models/ModelListParams.cs b/src/Anthropic/Models/Beta/Models/ModelListParams.cs index e170993ec..892009862 100644 --- a/src/Anthropic/Models/Beta/Models/ModelListParams.cs +++ b/src/Anthropic/Models/Beta/Models/ModelListParams.cs @@ -14,8 +14,12 @@ namespace Anthropic.Models.Beta.Models; /// /// The Models API response can be used to determine which models are available /// for use in the API. More recently released models are listed first. +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class ModelListParams : ParamsBase +public record class ModelListParams : ParamsBase { /// /// ID of the object to use as a cursor for pagination. When provided, returns @@ -112,8 +116,11 @@ public IReadOnlyList>? Betas public ModelListParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ModelListParams(ModelListParams modelListParams) : base(modelListParams) { } +#pragma warning restore CS8618 public ModelListParams( IReadOnlyDictionary rawHeaderData, @@ -148,6 +155,26 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(ModelListParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder(options.BaseUrl.ToString().TrimEnd('/') + "/v1/models?beta=true") @@ -164,4 +191,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Models/ModelRetrieveParams.cs b/src/Anthropic/Models/Beta/Models/ModelRetrieveParams.cs index 7daa0ef0a..824eb9aeb 100644 --- a/src/Anthropic/Models/Beta/Models/ModelRetrieveParams.cs +++ b/src/Anthropic/Models/Beta/Models/ModelRetrieveParams.cs @@ -14,8 +14,12 @@ namespace Anthropic.Models.Beta.Models; /// /// The Models API response can be used to determine information about a specific /// model or resolve a model alias to a model ID. +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class ModelRetrieveParams : ParamsBase +public record class ModelRetrieveParams : ParamsBase { public string? ModelID { get; init; } @@ -47,11 +51,14 @@ public IReadOnlyList>? Betas public ModelRetrieveParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ModelRetrieveParams(ModelRetrieveParams modelRetrieveParams) : base(modelRetrieveParams) { this.ModelID = modelRetrieveParams.ModelID; } +#pragma warning restore CS8618 public ModelRetrieveParams( IReadOnlyDictionary rawHeaderData, @@ -86,6 +93,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["ModelID"] = this.ModelID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(ModelRetrieveParams? other) + { + if (other == null) + { + return false; + } + return (this.ModelID?.Equals(other.ModelID) ?? other.ModelID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -105,4 +134,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Skills/SkillCreateParams.cs b/src/Anthropic/Models/Beta/Skills/SkillCreateParams.cs index 04bf3ac79..9bf91b6a6 100644 --- a/src/Anthropic/Models/Beta/Skills/SkillCreateParams.cs +++ b/src/Anthropic/Models/Beta/Skills/SkillCreateParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Skills; /// /// Create Skill +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class SkillCreateParams : ParamsBase +public record class SkillCreateParams : ParamsBase { readonly MultipartJsonDictionary _rawBodyData = new(); public IReadOnlyDictionary RawBodyData @@ -87,11 +91,14 @@ public IReadOnlyList>? Betas public SkillCreateParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SkillCreateParams(SkillCreateParams skillCreateParams) : base(skillCreateParams) { this._rawBodyData = new(skillCreateParams._rawBodyData); } +#pragma warning restore CS8618 public SkillCreateParams( IReadOnlyDictionary rawHeaderData, @@ -154,4 +161,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Skills/SkillDeleteParams.cs b/src/Anthropic/Models/Beta/Skills/SkillDeleteParams.cs index 73bcdc395..c48cba37d 100644 --- a/src/Anthropic/Models/Beta/Skills/SkillDeleteParams.cs +++ b/src/Anthropic/Models/Beta/Skills/SkillDeleteParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Skills; /// /// Delete Skill +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class SkillDeleteParams : ParamsBase +public record class SkillDeleteParams : ParamsBase { public string? SkillID { get; init; } @@ -45,11 +49,14 @@ public IReadOnlyList>? Betas public SkillDeleteParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SkillDeleteParams(SkillDeleteParams skillDeleteParams) : base(skillDeleteParams) { this.SkillID = skillDeleteParams.SkillID; } +#pragma warning restore CS8618 public SkillDeleteParams( IReadOnlyDictionary rawHeaderData, @@ -84,6 +91,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["SkillID"] = this.SkillID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(SkillDeleteParams? other) + { + if (other == null) + { + return false; + } + return (this.SkillID?.Equals(other.SkillID) ?? other.SkillID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -104,4 +133,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Skills/SkillListParams.cs b/src/Anthropic/Models/Beta/Skills/SkillListParams.cs index 44cdbdf2a..4eca00d83 100644 --- a/src/Anthropic/Models/Beta/Skills/SkillListParams.cs +++ b/src/Anthropic/Models/Beta/Skills/SkillListParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Skills; /// /// List Skills +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class SkillListParams : ParamsBase +public record class SkillListParams : ParamsBase { /// /// Number of results to return per page. @@ -99,8 +103,11 @@ public IReadOnlyList>? Betas public SkillListParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SkillListParams(SkillListParams skillListParams) : base(skillListParams) { } +#pragma warning restore CS8618 public SkillListParams( IReadOnlyDictionary rawHeaderData, @@ -135,6 +142,26 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(SkillListParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder(options.BaseUrl.ToString().TrimEnd('/') + "/v1/skills?beta=true") @@ -152,4 +179,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Skills/SkillRetrieveParams.cs b/src/Anthropic/Models/Beta/Skills/SkillRetrieveParams.cs index a50e376b1..a8f53830a 100644 --- a/src/Anthropic/Models/Beta/Skills/SkillRetrieveParams.cs +++ b/src/Anthropic/Models/Beta/Skills/SkillRetrieveParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Skills; /// /// Get Skill +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class SkillRetrieveParams : ParamsBase +public record class SkillRetrieveParams : ParamsBase { public string? SkillID { get; init; } @@ -45,11 +49,14 @@ public IReadOnlyList>? Betas public SkillRetrieveParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SkillRetrieveParams(SkillRetrieveParams skillRetrieveParams) : base(skillRetrieveParams) { this.SkillID = skillRetrieveParams.SkillID; } +#pragma warning restore CS8618 public SkillRetrieveParams( IReadOnlyDictionary rawHeaderData, @@ -84,6 +91,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["SkillID"] = this.SkillID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(SkillRetrieveParams? other) + { + if (other == null) + { + return false; + } + return (this.SkillID?.Equals(other.SkillID) ?? other.SkillID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -104,4 +133,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Skills/Versions/VersionCreateParams.cs b/src/Anthropic/Models/Beta/Skills/Versions/VersionCreateParams.cs index e2e7b3b83..8b9a8803c 100644 --- a/src/Anthropic/Models/Beta/Skills/Versions/VersionCreateParams.cs +++ b/src/Anthropic/Models/Beta/Skills/Versions/VersionCreateParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Skills.Versions; /// /// Create Skill Version +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class VersionCreateParams : ParamsBase +public record class VersionCreateParams : ParamsBase { readonly MultipartJsonDictionary _rawBodyData = new(); public IReadOnlyDictionary RawBodyData @@ -73,6 +77,8 @@ public IReadOnlyList>? Betas public VersionCreateParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public VersionCreateParams(VersionCreateParams versionCreateParams) : base(versionCreateParams) { @@ -80,6 +86,7 @@ public VersionCreateParams(VersionCreateParams versionCreateParams) this._rawBodyData = new(versionCreateParams._rawBodyData); } +#pragma warning restore CS8618 public VersionCreateParams( IReadOnlyDictionary rawHeaderData, @@ -145,4 +152,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Skills/Versions/VersionDeleteParams.cs b/src/Anthropic/Models/Beta/Skills/Versions/VersionDeleteParams.cs index 6a9ecd1ea..755d8595d 100644 --- a/src/Anthropic/Models/Beta/Skills/Versions/VersionDeleteParams.cs +++ b/src/Anthropic/Models/Beta/Skills/Versions/VersionDeleteParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Skills.Versions; /// /// Delete Skill Version +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class VersionDeleteParams : ParamsBase +public record class VersionDeleteParams : ParamsBase { public required string SkillID { get; init; } @@ -47,12 +51,15 @@ public IReadOnlyList>? Betas public VersionDeleteParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public VersionDeleteParams(VersionDeleteParams versionDeleteParams) : base(versionDeleteParams) { this.SkillID = versionDeleteParams.SkillID; this.Version = versionDeleteParams.Version; } +#pragma warning restore CS8618 public VersionDeleteParams( IReadOnlyDictionary rawHeaderData, @@ -87,6 +94,30 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["SkillID"] = this.SkillID, + ["Version"] = this.Version, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(VersionDeleteParams? other) + { + if (other == null) + { + return false; + } + return this.SkillID.Equals(other.SkillID) + && (this.Version?.Equals(other.Version) ?? other.Version == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -107,4 +138,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Skills/Versions/VersionListParams.cs b/src/Anthropic/Models/Beta/Skills/Versions/VersionListParams.cs index c5d449c50..86e4aaac8 100644 --- a/src/Anthropic/Models/Beta/Skills/Versions/VersionListParams.cs +++ b/src/Anthropic/Models/Beta/Skills/Versions/VersionListParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Skills.Versions; /// /// List Skill Versions +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class VersionListParams : ParamsBase +public record class VersionListParams : ParamsBase { public string? SkillID { get; init; } @@ -73,11 +77,14 @@ public IReadOnlyList>? Betas public VersionListParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public VersionListParams(VersionListParams versionListParams) : base(versionListParams) { this.SkillID = versionListParams.SkillID; } +#pragma warning restore CS8618 public VersionListParams( IReadOnlyDictionary rawHeaderData, @@ -112,6 +119,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["SkillID"] = this.SkillID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(VersionListParams? other) + { + if (other == null) + { + return false; + } + return (this.SkillID?.Equals(other.SkillID) ?? other.SkillID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -132,4 +161,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Beta/Skills/Versions/VersionRetrieveParams.cs b/src/Anthropic/Models/Beta/Skills/Versions/VersionRetrieveParams.cs index adb15db10..b86de3ed2 100644 --- a/src/Anthropic/Models/Beta/Skills/Versions/VersionRetrieveParams.cs +++ b/src/Anthropic/Models/Beta/Skills/Versions/VersionRetrieveParams.cs @@ -12,8 +12,12 @@ namespace Anthropic.Models.Beta.Skills.Versions; /// /// Get Skill Version +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class VersionRetrieveParams : ParamsBase +public record class VersionRetrieveParams : ParamsBase { public required string SkillID { get; init; } @@ -47,12 +51,15 @@ public IReadOnlyList>? Betas public VersionRetrieveParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public VersionRetrieveParams(VersionRetrieveParams versionRetrieveParams) : base(versionRetrieveParams) { this.SkillID = versionRetrieveParams.SkillID; this.Version = versionRetrieveParams.Version; } +#pragma warning restore CS8618 public VersionRetrieveParams( IReadOnlyDictionary rawHeaderData, @@ -87,6 +94,30 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["SkillID"] = this.SkillID, + ["Version"] = this.Version, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(VersionRetrieveParams? other) + { + if (other == null) + { + return false; + } + return this.SkillID.Equals(other.SkillID) + && (this.Version?.Equals(other.Version) ?? other.Version == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -107,4 +138,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Messages/Batches/BatchCancelParams.cs b/src/Anthropic/Models/Messages/Batches/BatchCancelParams.cs index 177591289..5021694d9 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchCancelParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchCancelParams.cs @@ -18,18 +18,25 @@ namespace Anthropic.Models.Messages.Batches; /// Note that cancellation may not result in any canceled requests if they were non-interruptible. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchCancelParams : ParamsBase +public record class BatchCancelParams : ParamsBase { public string? MessageBatchID { get; init; } public BatchCancelParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchCancelParams(BatchCancelParams batchCancelParams) : base(batchCancelParams) { this.MessageBatchID = batchCancelParams.MessageBatchID; } +#pragma warning restore CS8618 public BatchCancelParams( IReadOnlyDictionary rawHeaderData, @@ -64,6 +71,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["MessageBatchID"] = this.MessageBatchID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchCancelParams? other) + { + if (other == null) + { + return false; + } + return (this.MessageBatchID?.Equals(other.MessageBatchID) ?? other.MessageBatchID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -83,4 +112,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs index b76e79b74..d98edc7f1 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs @@ -20,8 +20,12 @@ namespace Anthropic.Models.Messages.Batches; /// can take up to 24 hours to complete. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchCreateParams : ParamsBase +public record class BatchCreateParams : ParamsBase { readonly JsonDictionary _rawBodyData = new(); public IReadOnlyDictionary RawBodyData @@ -51,11 +55,14 @@ public required IReadOnlyList Requests public BatchCreateParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchCreateParams(BatchCreateParams batchCreateParams) : base(batchCreateParams) { this._rawBodyData = new(batchCreateParams._rawBodyData); } +#pragma warning restore CS8618 public BatchCreateParams( IReadOnlyDictionary rawHeaderData, @@ -96,6 +103,28 @@ IReadOnlyDictionary rawBodyData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + ["BodyData"] = this._rawBodyData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchCreateParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData) + && this._rawBodyData.Equals(other._rawBodyData); + } + public override System::Uri Url(ClientOptions options) { return new System::UriBuilder( @@ -123,6 +152,11 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } [JsonConverter(typeof(JsonModelConverter))] diff --git a/src/Anthropic/Models/Messages/Batches/BatchDeleteParams.cs b/src/Anthropic/Models/Messages/Batches/BatchDeleteParams.cs index da9a0b054..499c9b649 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchDeleteParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchDeleteParams.cs @@ -15,18 +15,25 @@ namespace Anthropic.Models.Messages.Batches; /// you'd like to delete an in-progress batch, you must first cancel it. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchDeleteParams : ParamsBase +public record class BatchDeleteParams : ParamsBase { public string? MessageBatchID { get; init; } public BatchDeleteParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchDeleteParams(BatchDeleteParams batchDeleteParams) : base(batchDeleteParams) { this.MessageBatchID = batchDeleteParams.MessageBatchID; } +#pragma warning restore CS8618 public BatchDeleteParams( IReadOnlyDictionary rawHeaderData, @@ -61,6 +68,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["MessageBatchID"] = this.MessageBatchID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchDeleteParams? other) + { + if (other == null) + { + return false; + } + return (this.MessageBatchID?.Equals(other.MessageBatchID) ?? other.MessageBatchID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -80,4 +109,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Messages/Batches/BatchListParams.cs b/src/Anthropic/Models/Messages/Batches/BatchListParams.cs index 0f36db652..3ae58159b 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchListParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchListParams.cs @@ -13,8 +13,12 @@ namespace Anthropic.Models.Messages.Batches; /// returned first. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchListParams : ParamsBase +public record class BatchListParams : ParamsBase { /// /// ID of the object to use as a cursor for pagination. When provided, returns @@ -85,8 +89,11 @@ public long? Limit public BatchListParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchListParams(BatchListParams batchListParams) : base(batchListParams) { } +#pragma warning restore CS8618 public BatchListParams( IReadOnlyDictionary rawHeaderData, @@ -121,6 +128,26 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchListParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder(options.BaseUrl.ToString().TrimEnd('/') + "/v1/messages/batches") @@ -137,4 +164,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Messages/Batches/BatchResultsParams.cs b/src/Anthropic/Models/Messages/Batches/BatchResultsParams.cs index b401a817d..f1ac5d384 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchResultsParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchResultsParams.cs @@ -16,18 +16,25 @@ namespace Anthropic.Models.Messages.Batches; /// as requests. Use the `custom_id` field to match results to requests. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchResultsParams : ParamsBase +public record class BatchResultsParams : ParamsBase { public string? MessageBatchID { get; init; } public BatchResultsParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchResultsParams(BatchResultsParams batchResultsParams) : base(batchResultsParams) { this.MessageBatchID = batchResultsParams.MessageBatchID; } +#pragma warning restore CS8618 public BatchResultsParams( IReadOnlyDictionary rawHeaderData, @@ -62,6 +69,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["MessageBatchID"] = this.MessageBatchID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchResultsParams? other) + { + if (other == null) + { + return false; + } + return (this.MessageBatchID?.Equals(other.MessageBatchID) ?? other.MessageBatchID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -81,4 +110,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Messages/Batches/BatchRetrieveParams.cs b/src/Anthropic/Models/Messages/Batches/BatchRetrieveParams.cs index 863ed0b1f..8345183dc 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchRetrieveParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchRetrieveParams.cs @@ -14,18 +14,25 @@ namespace Anthropic.Models.Messages.Batches; /// field in the response. /// /// Learn more about the Message Batches API in our [user guide](https://docs.claude.com/en/docs/build-with-claude/batch-processing) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class BatchRetrieveParams : ParamsBase +public record class BatchRetrieveParams : ParamsBase { public string? MessageBatchID { get; init; } public BatchRetrieveParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchRetrieveParams(BatchRetrieveParams batchRetrieveParams) : base(batchRetrieveParams) { this.MessageBatchID = batchRetrieveParams.MessageBatchID; } +#pragma warning restore CS8618 public BatchRetrieveParams( IReadOnlyDictionary rawHeaderData, @@ -60,6 +67,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["MessageBatchID"] = this.MessageBatchID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(BatchRetrieveParams? other) + { + if (other == null) + { + return false; + } + return (this.MessageBatchID?.Equals(other.MessageBatchID) ?? other.MessageBatchID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -79,4 +108,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Messages/MessageCountTokensParams.cs b/src/Anthropic/Models/Messages/MessageCountTokensParams.cs index 70ea8ecce..0edf1ec5e 100644 --- a/src/Anthropic/Models/Messages/MessageCountTokensParams.cs +++ b/src/Anthropic/Models/Messages/MessageCountTokensParams.cs @@ -19,8 +19,12 @@ namespace Anthropic.Models.Messages; /// including tools, images, and documents, without creating it. /// /// Learn more about token counting in our [user guide](https://docs.claude.com/en/docs/build-with-claude/token-counting) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class MessageCountTokensParams : ParamsBase +public record class MessageCountTokensParams : ParamsBase { readonly JsonDictionary _rawBodyData = new(); public IReadOnlyDictionary RawBodyData @@ -255,11 +259,14 @@ public IReadOnlyList? Tools public MessageCountTokensParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageCountTokensParams(MessageCountTokensParams messageCountTokensParams) : base(messageCountTokensParams) { this._rawBodyData = new(messageCountTokensParams._rawBodyData); } +#pragma warning restore CS8618 public MessageCountTokensParams( IReadOnlyDictionary rawHeaderData, @@ -300,6 +307,28 @@ IReadOnlyDictionary rawBodyData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + ["BodyData"] = this._rawBodyData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(MessageCountTokensParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData) + && this._rawBodyData.Equals(other._rawBodyData); + } + public override System::Uri Url(ClientOptions options) { return new System::UriBuilder( @@ -327,6 +356,11 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } /// diff --git a/src/Anthropic/Models/Messages/MessageCreateParams.cs b/src/Anthropic/Models/Messages/MessageCreateParams.cs index f59f638f5..bb2e34dba 100644 --- a/src/Anthropic/Models/Messages/MessageCreateParams.cs +++ b/src/Anthropic/Models/Messages/MessageCreateParams.cs @@ -19,8 +19,12 @@ namespace Anthropic.Models.Messages; /// The Messages API can be used for either single queries or stateless multi-turn conversations. /// /// Learn more about the Messages API in our [user guide](https://docs.claude.com/en/docs/initial-setup) +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class MessageCreateParams : ParamsBase +public record class MessageCreateParams : ParamsBase { readonly JsonDictionary _rawBodyData = new(); public IReadOnlyDictionary RawBodyData @@ -433,11 +437,14 @@ public double? TopP public MessageCreateParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageCreateParams(MessageCreateParams messageCreateParams) : base(messageCreateParams) { this._rawBodyData = new(messageCreateParams._rawBodyData); } +#pragma warning restore CS8618 public MessageCreateParams( IReadOnlyDictionary rawHeaderData, @@ -478,6 +485,28 @@ IReadOnlyDictionary rawBodyData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + ["BodyData"] = this._rawBodyData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(MessageCreateParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData) + && this._rawBodyData.Equals(other._rawBodyData); + } + public override System::Uri Url(ClientOptions options) { return new System::UriBuilder(options.BaseUrl.ToString().TrimEnd('/') + "/v1/messages") @@ -503,6 +532,11 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } /// diff --git a/src/Anthropic/Models/Models/ModelListParams.cs b/src/Anthropic/Models/Models/ModelListParams.cs index 050aebe5a..e144522e0 100644 --- a/src/Anthropic/Models/Models/ModelListParams.cs +++ b/src/Anthropic/Models/Models/ModelListParams.cs @@ -15,8 +15,12 @@ namespace Anthropic.Models.Models; /// /// The Models API response can be used to determine which models are available /// for use in the API. More recently released models are listed first. +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class ModelListParams : ParamsBase +public record class ModelListParams : ParamsBase { /// /// ID of the object to use as a cursor for pagination. When provided, returns @@ -113,8 +117,11 @@ public IReadOnlyList>? Betas public ModelListParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ModelListParams(ModelListParams modelListParams) : base(modelListParams) { } +#pragma warning restore CS8618 public ModelListParams( IReadOnlyDictionary rawHeaderData, @@ -149,6 +156,26 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(ModelListParams? other) + { + if (other == null) + { + return false; + } + return this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder(options.BaseUrl.ToString().TrimEnd('/') + "/v1/models") @@ -165,4 +192,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } diff --git a/src/Anthropic/Models/Models/ModelRetrieveParams.cs b/src/Anthropic/Models/Models/ModelRetrieveParams.cs index c677c85eb..ec6624b26 100644 --- a/src/Anthropic/Models/Models/ModelRetrieveParams.cs +++ b/src/Anthropic/Models/Models/ModelRetrieveParams.cs @@ -15,8 +15,12 @@ namespace Anthropic.Models.Models; /// /// The Models API response can be used to determine information about a specific /// model or resolve a model alias to a model ID. +/// +/// NOTE: Do not inherit from this type outside the SDK unless you're okay with +/// breaking changes in non-major versions. We may add new methods in the future that +/// cause existing derived classes to break. /// -public sealed record class ModelRetrieveParams : ParamsBase +public record class ModelRetrieveParams : ParamsBase { public string? ModelID { get; init; } @@ -48,11 +52,14 @@ public IReadOnlyList>? Betas public ModelRetrieveParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ModelRetrieveParams(ModelRetrieveParams modelRetrieveParams) : base(modelRetrieveParams) { this.ModelID = modelRetrieveParams.ModelID; } +#pragma warning restore CS8618 public ModelRetrieveParams( IReadOnlyDictionary rawHeaderData, @@ -87,6 +94,28 @@ IReadOnlyDictionary rawQueryData ); } + public override string ToString() => + JsonSerializer.Serialize( + new Dictionary() + { + ["ModelID"] = this.ModelID, + ["HeaderData"] = this._rawHeaderData.Freeze(), + ["QueryData"] = this._rawQueryData.Freeze(), + }, + ModelBase.ToStringSerializerOptions + ); + + public virtual bool Equals(ModelRetrieveParams? other) + { + if (other == null) + { + return false; + } + return (this.ModelID?.Equals(other.ModelID) ?? other.ModelID == null) + && this._rawHeaderData.Equals(other._rawHeaderData) + && this._rawQueryData.Equals(other._rawQueryData); + } + public override Uri Url(ClientOptions options) { return new UriBuilder( @@ -105,4 +134,9 @@ internal override void AddHeadersToRequest(HttpRequestMessage request, ClientOpt ParamsBase.AddHeaderElementToRequest(request, item.Key, item.Value); } } + + public override int GetHashCode() + { + return 0; + } } From 5915cfe6b9a0df56b5acda9ac7cef0d89ae4dbe1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 22 Jan 2026 15:03:19 +0000 Subject: [PATCH 14/41] chore(internal): add copy constructor tests --- .../Models/ApiErrorObjectTest.cs | 10 + .../Models/AuthenticationErrorTest.cs | 10 + .../Models/Beta/BetaApiErrorTest.cs | 10 + .../Beta/BetaAuthenticationErrorTest.cs | 10 + .../Models/Beta/BetaBillingErrorTest.cs | 10 + .../Models/Beta/BetaErrorResponseTest.cs | 14 + .../Beta/BetaGatewayTimeoutErrorTest.cs | 10 + .../Beta/BetaInvalidRequestErrorTest.cs | 10 + .../Models/Beta/BetaNotFoundErrorTest.cs | 10 + .../Models/Beta/BetaOverloadedErrorTest.cs | 10 + .../Models/Beta/BetaPermissionErrorTest.cs | 10 + .../Models/Beta/BetaRateLimitErrorTest.cs | 10 + .../Models/Beta/Files/DeletedFileTest.cs | 10 + .../Beta/Files/FileListPageResponseTest.cs | 27 ++ .../Models/Beta/Files/FileMetadataTest.cs | 18 ++ .../Messages/Batches/BatchCreateParamsTest.cs | 260 ++++++++++++++++++ .../Batches/BatchListPageResponseTest.cs | 38 +++ .../Batches/BetaDeletedMessageBatchTest.cs | 10 + .../BetaMessageBatchCanceledResultTest.cs | 10 + .../BetaMessageBatchErroredResultTest.cs | 17 ++ .../BetaMessageBatchExpiredResultTest.cs | 10 + .../BetaMessageBatchIndividualResponseTest.cs | 78 ++++++ .../BetaMessageBatchRequestCountsTest.cs | 17 ++ .../BetaMessageBatchSucceededResultTest.cs | 75 +++++ .../Messages/Batches/BetaMessageBatchTest.cs | 29 ++ .../Beta/Messages/BetaAllThinkingTurnsTest.cs | 10 + .../Messages/BetaBase64ImageSourceTest.cs | 14 + .../Beta/Messages/BetaBase64PdfSourceTest.cs | 10 + ...taBashCodeExecutionOutputBlockParamTest.cs | 10 + .../BetaBashCodeExecutionOutputBlockTest.cs | 10 + ...taBashCodeExecutionResultBlockParamTest.cs | 16 ++ .../BetaBashCodeExecutionResultBlockTest.cs | 16 ++ ...shCodeExecutionToolResultBlockParamTest.cs | 17 ++ ...etaBashCodeExecutionToolResultBlockTest.cs | 14 + ...shCodeExecutionToolResultErrorParamTest.cs | 13 + ...etaBashCodeExecutionToolResultErrorTest.cs | 13 + .../Messages/BetaCacheControlEphemeralTest.cs | 10 + .../Beta/Messages/BetaCacheCreationTest.cs | 14 + .../BetaCitationCharLocationParamTest.cs | 17 ++ .../Messages/BetaCitationCharLocationTest.cs | 18 ++ .../Beta/Messages/BetaCitationConfigTest.cs | 10 + ...taCitationContentBlockLocationParamTest.cs | 17 ++ .../BetaCitationContentBlockLocationTest.cs | 18 ++ .../BetaCitationPageLocationParamTest.cs | 17 ++ .../Messages/BetaCitationPageLocationTest.cs | 18 ++ ...taCitationSearchResultLocationParamTest.cs | 18 ++ .../BetaCitationSearchResultLocationTest.cs | 18 ++ ...itationWebSearchResultLocationParamTest.cs | 16 ++ .../Messages/BetaCitationsConfigParamTest.cs | 10 + .../Beta/Messages/BetaCitationsDeltaTest.cs | 21 ++ ...etaCitationsWebSearchResultLocationTest.cs | 16 ++ ...taClearThinking20251015EditResponseTest.cs | 14 + .../BetaClearThinking20251015EditTest.cs | 10 + ...taClearToolUses20250919EditResponseTest.cs | 14 + .../BetaClearToolUses20250919EditTest.cs | 17 ++ .../BetaCodeExecutionOutputBlockParamTest.cs | 10 + .../BetaCodeExecutionOutputBlockTest.cs | 10 + .../BetaCodeExecutionResultBlockParamTest.cs | 16 ++ .../BetaCodeExecutionResultBlockTest.cs | 16 ++ .../BetaCodeExecutionTool20250522Test.cs | 16 ++ .../BetaCodeExecutionTool20250825Test.cs | 16 ++ ...taCodeExecutionToolResultBlockParamTest.cs | 17 ++ .../BetaCodeExecutionToolResultBlockTest.cs | 16 ++ ...taCodeExecutionToolResultErrorParamTest.cs | 13 + .../BetaCodeExecutionToolResultErrorTest.cs | 13 + .../Beta/Messages/BetaContainerParamsTest.cs | 22 ++ .../Models/Beta/Messages/BetaContainerTest.cs | 23 ++ .../BetaContainerUploadBlockParamTest.cs | 14 + .../Messages/BetaContainerUploadBlockTest.cs | 10 + .../Messages/BetaContentBlockSourceTest.cs | 10 + .../BetaContextManagementConfigTest.cs | 23 ++ .../BetaContextManagementResponseTest.cs | 20 ++ ...ountTokensContextManagementResponseTest.cs | 10 + .../Beta/Messages/BetaDirectCallerTest.cs | 10 + .../Beta/Messages/BetaDocumentBlockTest.cs | 15 + .../Messages/BetaFileDocumentSourceTest.cs | 10 + .../Beta/Messages/BetaFileImageSourceTest.cs | 10 + .../Beta/Messages/BetaImageBlockParamTest.cs | 18 ++ .../Beta/Messages/BetaInputJsonDeltaTest.cs | 10 + .../BetaInputTokensClearAtLeastTest.cs | 10 + .../Messages/BetaInputTokensTriggerTest.cs | 10 + .../Beta/Messages/BetaJsonOutputFormatTest.cs | 16 ++ .../Beta/Messages/BetaMcpToolConfigTest.cs | 10 + .../Messages/BetaMcpToolDefaultConfigTest.cs | 10 + .../Messages/BetaMcpToolResultBlockTest.cs | 15 + .../Messages/BetaMcpToolUseBlockParamTest.cs | 20 ++ .../Beta/Messages/BetaMcpToolUseBlockTest.cs | 19 ++ .../Beta/Messages/BetaMcpToolsetTest.cs | 22 ++ ...BetaMemoryTool20250818CreateCommandTest.cs | 14 + ...BetaMemoryTool20250818DeleteCommandTest.cs | 10 + ...BetaMemoryTool20250818InsertCommandTest.cs | 15 + ...BetaMemoryTool20250818RenameCommandTest.cs | 14 + ...MemoryTool20250818StrReplaceCommandTest.cs | 15 + .../Messages/BetaMemoryTool20250818Test.cs | 23 ++ .../BetaMemoryTool20250818ViewCommandTest.cs | 14 + .../Messages/BetaMessageDeltaUsageTest.cs | 17 ++ .../Beta/Messages/BetaMessageParamTest.cs | 10 + .../Models/Beta/Messages/BetaMessageTest.cs | 68 +++++ .../Messages/BetaMessageTokensCountTest.cs | 10 + .../Models/Beta/Messages/BetaMetadataTest.cs | 10 + .../Beta/Messages/BetaOutputConfigTest.cs | 20 ++ .../Beta/Messages/BetaPlainTextSourceTest.cs | 10 + .../BetaRawContentBlockDeltaEventTest.cs | 14 + .../BetaRawContentBlockStartEventTest.cs | 29 ++ .../BetaRawContentBlockStopEventTest.cs | 10 + .../Messages/BetaRawMessageDeltaEventTest.cs | 76 +++++ .../Messages/BetaRawMessageStartEventTest.cs | 75 +++++ .../Messages/BetaRawMessageStopEventTest.cs | 10 + .../BetaRedactedThinkingBlockParamTest.cs | 10 + .../Messages/BetaRedactedThinkingBlockTest.cs | 10 + .../Messages/BetaRequestDocumentBlockTest.cs | 17 ++ ...taRequestMcpServerToolConfigurationTest.cs | 14 + .../BetaRequestMcpServerUrlDefinitionTest.cs | 16 ++ .../BetaRequestMcpToolResultBlockParamTest.cs | 16 ++ .../BetaSearchResultBlockParamTest.cs | 35 +++ .../Beta/Messages/BetaServerToolCallerTest.cs | 10 + .../Beta/Messages/BetaServerToolUsageTest.cs | 10 + .../BetaServerToolUseBlockParamTest.cs | 20 ++ .../Messages/BetaServerToolUseBlockTest.cs | 19 ++ .../Beta/Messages/BetaSignatureDeltaTest.cs | 10 + .../Beta/Messages/BetaSkillParamsTest.cs | 15 + .../Models/Beta/Messages/BetaSkillTest.cs | 15 + .../Beta/Messages/BetaTextBlockParamTest.cs | 25 ++ .../Models/Beta/Messages/BetaTextBlockTest.cs | 25 ++ .../Models/Beta/Messages/BetaTextDeltaTest.cs | 10 + ...CodeExecutionCreateResultBlockParamTest.cs | 10 + ...ditorCodeExecutionCreateResultBlockTest.cs | 10 + ...ExecutionStrReplaceResultBlockParamTest.cs | 17 ++ ...rCodeExecutionStrReplaceResultBlockTest.cs | 17 ++ ...orCodeExecutionToolResultBlockParamTest.cs | 20 ++ ...tEditorCodeExecutionToolResultBlockTest.cs | 18 ++ ...orCodeExecutionToolResultErrorParamTest.cs | 14 + ...tEditorCodeExecutionToolResultErrorTest.cs | 14 + ...orCodeExecutionViewResultBlockParamTest.cs | 17 ++ ...tEditorCodeExecutionViewResultBlockTest.cs | 17 ++ .../Messages/BetaThinkingBlockParamTest.cs | 10 + .../Beta/Messages/BetaThinkingBlockTest.cs | 10 + .../BetaThinkingConfigDisabledTest.cs | 10 + .../Messages/BetaThinkingConfigEnabledTest.cs | 10 + .../Beta/Messages/BetaThinkingDeltaTest.cs | 10 + .../Beta/Messages/BetaThinkingTurnsTest.cs | 10 + .../Beta/Messages/BetaToolBash20241022Test.cs | 23 ++ .../Beta/Messages/BetaToolBash20250124Test.cs | 23 ++ .../Beta/Messages/BetaToolChoiceAnyTest.cs | 10 + .../Beta/Messages/BetaToolChoiceAutoTest.cs | 10 + .../Beta/Messages/BetaToolChoiceNoneTest.cs | 10 + .../Beta/Messages/BetaToolChoiceToolTest.cs | 10 + .../BetaToolComputerUse20241022Test.cs | 26 ++ .../BetaToolComputerUse20250124Test.cs | 26 ++ .../BetaToolComputerUse20251124Test.cs | 27 ++ .../BetaToolReferenceBlockParamTest.cs | 14 + .../Messages/BetaToolReferenceBlockTest.cs | 10 + .../Messages/BetaToolResultBlockParamTest.cs | 16 ++ .../BetaToolSearchToolBm25_20251119Test.cs | 17 ++ .../BetaToolSearchToolRegex20251119Test.cs | 17 ++ .../BetaToolSearchToolResultBlockParamTest.cs | 17 ++ .../BetaToolSearchToolResultBlockTest.cs | 18 ++ .../BetaToolSearchToolResultErrorParamTest.cs | 13 + .../BetaToolSearchToolResultErrorTest.cs | 14 + ...oolSearchToolSearchResultBlockParamTest.cs | 20 ++ ...BetaToolSearchToolSearchResultBlockTest.cs | 10 + .../Models/Beta/Messages/BetaToolTest.cs | 53 ++++ .../BetaToolTextEditor20241022Test.cs | 23 ++ .../BetaToolTextEditor20250124Test.cs | 23 ++ .../BetaToolTextEditor20250429Test.cs | 23 ++ .../BetaToolTextEditor20250728Test.cs | 24 ++ .../Messages/BetaToolUseBlockParamTest.cs | 20 ++ .../Beta/Messages/BetaToolUseBlockTest.cs | 19 ++ .../Beta/Messages/BetaToolUsesKeepTest.cs | 10 + .../Beta/Messages/BetaToolUsesTriggerTest.cs | 10 + .../Beta/Messages/BetaUrlImageSourceTest.cs | 10 + .../Beta/Messages/BetaUrlPdfSourceTest.cs | 10 + .../Models/Beta/Messages/BetaUsageTest.cs | 19 ++ .../Messages/BetaWebFetchBlockParamTest.cs | 22 ++ .../Beta/Messages/BetaWebFetchBlockTest.cs | 20 ++ .../Messages/BetaWebFetchTool20250910Test.cs | 21 ++ .../BetaWebFetchToolResultBlockParamTest.cs | 17 ++ .../BetaWebFetchToolResultBlockTest.cs | 16 ++ ...taWebFetchToolResultErrorBlockParamTest.cs | 13 + .../BetaWebFetchToolResultErrorBlockTest.cs | 13 + .../BetaWebSearchResultBlockParamTest.cs | 16 ++ .../Messages/BetaWebSearchResultBlockTest.cs | 16 ++ .../Messages/BetaWebSearchTool20250305Test.cs | 42 +++ .../BetaWebSearchToolRequestErrorTest.cs | 13 + .../BetaWebSearchToolResultBlockParamTest.cs | 25 ++ .../BetaWebSearchToolResultBlockTest.cs | 16 ++ .../BetaWebSearchToolResultErrorTest.cs | 13 + .../Models/Beta/Models/BetaModelInfoTest.cs | 15 + .../Beta/Models/ModelListPageResponseTest.cs | 24 ++ .../Beta/Skills/SkillCreateResponseTest.cs | 19 ++ .../Beta/Skills/SkillDeleteResponseTest.cs | 14 + .../Beta/Skills/SkillListPageResponseTest.cs | 27 ++ .../Beta/Skills/SkillListResponseTest.cs | 19 ++ .../Beta/Skills/SkillRetrieveResponseTest.cs | 19 ++ .../Versions/VersionCreateResponseTest.cs | 20 ++ .../Versions/VersionDeleteResponseTest.cs | 10 + .../Versions/VersionListPageResponseTest.cs | 28 ++ .../Versions/VersionListResponseTest.cs | 20 ++ .../Versions/VersionRetrieveResponseTest.cs | 20 ++ .../Models/BillingErrorTest.cs | 10 + .../Models/ErrorResponseTest.cs | 14 + .../Models/GatewayTimeoutErrorTest.cs | 10 + .../Models/InvalidRequestErrorTest.cs | 10 + .../Models/Messages/Base64ImageSourceTest.cs | 14 + .../Models/Messages/Base64PdfSourceTest.cs | 10 + .../Messages/Batches/BatchCreateParamsTest.cs | 130 +++++++++ .../Batches/BatchListPageResponseTest.cs | 38 +++ .../Batches/DeletedMessageBatchTest.cs | 10 + .../Batches/MessageBatchCanceledResultTest.cs | 10 + .../Batches/MessageBatchErroredResultTest.cs | 13 + .../Batches/MessageBatchExpiredResultTest.cs | 10 + .../MessageBatchIndividualResponseTest.cs | 55 ++++ .../Batches/MessageBatchRequestCountsTest.cs | 17 ++ .../MessageBatchSucceededResultTest.cs | 52 ++++ .../Messages/Batches/MessageBatchTest.cs | 29 ++ .../Messages/CacheControlEphemeralTest.cs | 10 + .../Models/Messages/CacheCreationTest.cs | 10 + .../Messages/CitationCharLocationParamTest.cs | 17 ++ .../Messages/CitationCharLocationTest.cs | 18 ++ .../CitationContentBlockLocationParamTest.cs | 17 ++ .../CitationContentBlockLocationTest.cs | 18 ++ .../Messages/CitationPageLocationParamTest.cs | 17 ++ .../Messages/CitationPageLocationTest.cs | 18 ++ .../CitationSearchResultLocationParamTest.cs | 18 ++ ...itationWebSearchResultLocationParamTest.cs | 16 ++ .../Messages/CitationsConfigParamTest.cs | 10 + .../Models/Messages/CitationsDeltaTest.cs | 21 ++ .../CitationsSearchResultLocationTest.cs | 18 ++ .../CitationsWebSearchResultLocationTest.cs | 16 ++ .../Models/Messages/ContentBlockSourceTest.cs | 10 + .../Models/Messages/DocumentBlockParamTest.cs | 17 ++ .../Models/Messages/ImageBlockParamTest.cs | 18 ++ .../Models/Messages/InputJsonDeltaTest.cs | 10 + .../Models/Messages/MessageDeltaUsageTest.cs | 17 ++ .../Models/Messages/MessageParamTest.cs | 10 + .../Models/Messages/MessageTest.cs | 45 +++ .../Models/Messages/MessageTokensCountTest.cs | 10 + .../Models/Messages/MetadataTest.cs | 10 + .../Models/Messages/PlainTextSourceTest.cs | 10 + .../Messages/RawContentBlockDeltaEventTest.cs | 10 + .../Messages/RawContentBlockStartEventTest.cs | 29 ++ .../Messages/RawContentBlockStopEventTest.cs | 10 + .../Messages/RawMessageDeltaEventTest.cs | 31 +++ .../Messages/RawMessageStartEventTest.cs | 52 ++++ .../Messages/RawMessageStopEventTest.cs | 10 + .../RedactedThinkingBlockParamTest.cs | 10 + .../Messages/RedactedThinkingBlockTest.cs | 10 + .../Messages/SearchResultBlockParamTest.cs | 35 +++ .../Models/Messages/ServerToolUsageTest.cs | 10 + .../Messages/ServerToolUseBlockParamTest.cs | 18 ++ .../Models/Messages/ServerToolUseBlockTest.cs | 17 ++ .../Models/Messages/SignatureDeltaTest.cs | 10 + .../Models/Messages/TextBlockParamTest.cs | 25 ++ .../Models/Messages/TextBlockTest.cs | 25 ++ .../Models/Messages/TextDeltaTest.cs | 10 + .../Models/Messages/ThinkingBlockParamTest.cs | 10 + .../Models/Messages/ThinkingBlockTest.cs | 10 + .../Messages/ThinkingConfigDisabledTest.cs | 10 + .../Messages/ThinkingConfigEnabledTest.cs | 10 + .../Models/Messages/ThinkingDeltaTest.cs | 10 + .../Models/Messages/ToolBash20250124Test.cs | 10 + .../Models/Messages/ToolChoiceAnyTest.cs | 10 + .../Models/Messages/ToolChoiceAutoTest.cs | 10 + .../Models/Messages/ToolChoiceNoneTest.cs | 10 + .../Models/Messages/ToolChoiceToolTest.cs | 10 + .../Messages/ToolResultBlockParamTest.cs | 16 ++ .../Models/Messages/ToolTest.cs | 43 +++ .../Messages/ToolTextEditor20250124Test.cs | 10 + .../Messages/ToolTextEditor20250429Test.cs | 10 + .../Messages/ToolTextEditor20250728Test.cs | 14 + .../Models/Messages/ToolUseBlockParamTest.cs | 19 ++ .../Models/Messages/ToolUseBlockTest.cs | 18 ++ .../Models/Messages/UrlImageSourceTest.cs | 10 + .../Models/Messages/UrlPdfSourceTest.cs | 10 + .../Models/Messages/UsageTest.cs | 19 ++ .../Messages/WebSearchResultBlockParamTest.cs | 16 ++ .../Messages/WebSearchResultBlockTest.cs | 16 ++ .../Messages/WebSearchTool20250305Test.cs | 39 +++ .../Messages/WebSearchToolRequestErrorTest.cs | 10 + .../WebSearchToolResultBlockParamTest.cs | 25 ++ .../Messages/WebSearchToolResultBlockTest.cs | 16 ++ .../Messages/WebSearchToolResultErrorTest.cs | 13 + .../Models/Models/ModelInfoTest.cs | 15 + .../Models/ModelListPageResponseTest.cs | 24 ++ .../Models/NotFoundErrorTest.cs | 10 + .../Models/OverloadedErrorTest.cs | 10 + .../Models/PermissionErrorTest.cs | 10 + .../Models/RateLimitErrorTest.cs | 10 + src/Anthropic/Models/ApiErrorObject.cs | 3 + src/Anthropic/Models/AuthenticationError.cs | 3 + src/Anthropic/Models/Beta/BetaApiError.cs | 3 + .../Models/Beta/BetaAuthenticationError.cs | 3 + src/Anthropic/Models/Beta/BetaBillingError.cs | 3 + .../Models/Beta/BetaErrorResponse.cs | 3 + .../Models/Beta/BetaGatewayTimeoutError.cs | 3 + .../Models/Beta/BetaInvalidRequestError.cs | 3 + .../Models/Beta/BetaNotFoundError.cs | 3 + .../Models/Beta/BetaOverloadedError.cs | 3 + .../Models/Beta/BetaPermissionError.cs | 3 + .../Models/Beta/BetaRateLimitError.cs | 3 + .../Models/Beta/Files/DeletedFile.cs | 3 + .../Models/Beta/Files/FileListPageResponse.cs | 3 + .../Models/Beta/Files/FileMetadata.cs | 3 + .../Messages/Batches/BatchCreateParams.cs | 6 + .../Messages/Batches/BatchListPageResponse.cs | 3 + .../Batches/BetaDeletedMessageBatch.cs | 3 + .../Beta/Messages/Batches/BetaMessageBatch.cs | 3 + .../Batches/BetaMessageBatchCanceledResult.cs | 3 + .../Batches/BetaMessageBatchErroredResult.cs | 3 + .../Batches/BetaMessageBatchExpiredResult.cs | 3 + .../BetaMessageBatchIndividualResponse.cs | 3 + .../Batches/BetaMessageBatchRequestCounts.cs | 3 + .../BetaMessageBatchSucceededResult.cs | 3 + .../Beta/Messages/BetaAllThinkingTurns.cs | 3 + .../Beta/Messages/BetaBase64ImageSource.cs | 3 + .../Beta/Messages/BetaBase64PdfSource.cs | 3 + .../BetaBashCodeExecutionOutputBlock.cs | 3 + .../BetaBashCodeExecutionOutputBlockParam.cs | 3 + .../BetaBashCodeExecutionResultBlock.cs | 3 + .../BetaBashCodeExecutionResultBlockParam.cs | 3 + .../BetaBashCodeExecutionToolResultBlock.cs | 3 + ...taBashCodeExecutionToolResultBlockParam.cs | 3 + .../BetaBashCodeExecutionToolResultError.cs | 3 + ...taBashCodeExecutionToolResultErrorParam.cs | 3 + .../Messages/BetaCacheControlEphemeral.cs | 3 + .../Models/Beta/Messages/BetaCacheCreation.cs | 3 + .../Beta/Messages/BetaCitationCharLocation.cs | 3 + .../Messages/BetaCitationCharLocationParam.cs | 3 + .../Beta/Messages/BetaCitationConfig.cs | 3 + .../BetaCitationContentBlockLocation.cs | 3 + .../BetaCitationContentBlockLocationParam.cs | 3 + .../Beta/Messages/BetaCitationPageLocation.cs | 3 + .../Messages/BetaCitationPageLocationParam.cs | 3 + .../BetaCitationSearchResultLocation.cs | 3 + .../BetaCitationSearchResultLocationParam.cs | 3 + ...etaCitationWebSearchResultLocationParam.cs | 3 + .../Beta/Messages/BetaCitationsConfigParam.cs | 3 + .../Beta/Messages/BetaCitationsDelta.cs | 3 + .../BetaCitationsWebSearchResultLocation.cs | 3 + .../Messages/BetaClearThinking20251015Edit.cs | 3 + .../BetaClearThinking20251015EditResponse.cs | 3 + .../Messages/BetaClearToolUses20250919Edit.cs | 3 + .../BetaClearToolUses20250919EditResponse.cs | 3 + .../Messages/BetaCodeExecutionOutputBlock.cs | 3 + .../BetaCodeExecutionOutputBlockParam.cs | 3 + .../Messages/BetaCodeExecutionResultBlock.cs | 3 + .../BetaCodeExecutionResultBlockParam.cs | 3 + .../Messages/BetaCodeExecutionTool20250522.cs | 3 + .../Messages/BetaCodeExecutionTool20250825.cs | 3 + .../BetaCodeExecutionToolResultBlock.cs | 3 + .../BetaCodeExecutionToolResultBlockParam.cs | 3 + .../BetaCodeExecutionToolResultError.cs | 3 + .../BetaCodeExecutionToolResultErrorParam.cs | 3 + .../Models/Beta/Messages/BetaContainer.cs | 3 + .../Beta/Messages/BetaContainerParams.cs | 3 + .../Beta/Messages/BetaContainerUploadBlock.cs | 3 + .../Messages/BetaContainerUploadBlockParam.cs | 3 + .../Beta/Messages/BetaContentBlockSource.cs | 3 + .../Messages/BetaContextManagementConfig.cs | 3 + .../Messages/BetaContextManagementResponse.cs | 3 + ...etaCountTokensContextManagementResponse.cs | 3 + .../Models/Beta/Messages/BetaDirectCaller.cs | 3 + .../Models/Beta/Messages/BetaDocumentBlock.cs | 3 + .../Beta/Messages/BetaFileDocumentSource.cs | 3 + .../Beta/Messages/BetaFileImageSource.cs | 3 + .../Beta/Messages/BetaImageBlockParam.cs | 3 + .../Beta/Messages/BetaInputJsonDelta.cs | 3 + .../Messages/BetaInputTokensClearAtLeast.cs | 3 + .../Beta/Messages/BetaInputTokensTrigger.cs | 3 + .../Beta/Messages/BetaJsonOutputFormat.cs | 3 + .../Models/Beta/Messages/BetaMcpToolConfig.cs | 3 + .../Beta/Messages/BetaMcpToolDefaultConfig.cs | 3 + .../Beta/Messages/BetaMcpToolResultBlock.cs | 3 + .../Beta/Messages/BetaMcpToolUseBlock.cs | 3 + .../Beta/Messages/BetaMcpToolUseBlockParam.cs | 3 + .../Models/Beta/Messages/BetaMcpToolset.cs | 3 + .../Beta/Messages/BetaMemoryTool20250818.cs | 3 + .../BetaMemoryTool20250818CreateCommand.cs | 3 + .../BetaMemoryTool20250818DeleteCommand.cs | 3 + .../BetaMemoryTool20250818InsertCommand.cs | 3 + .../BetaMemoryTool20250818RenameCommand.cs | 3 + ...BetaMemoryTool20250818StrReplaceCommand.cs | 3 + .../BetaMemoryTool20250818ViewCommand.cs | 3 + .../Models/Beta/Messages/BetaMessage.cs | 3 + .../Beta/Messages/BetaMessageDeltaUsage.cs | 3 + .../Models/Beta/Messages/BetaMessageParam.cs | 3 + .../Beta/Messages/BetaMessageTokensCount.cs | 3 + .../Models/Beta/Messages/BetaMetadata.cs | 3 + .../Models/Beta/Messages/BetaOutputConfig.cs | 3 + .../Beta/Messages/BetaPlainTextSource.cs | 3 + .../Messages/BetaRawContentBlockDeltaEvent.cs | 3 + .../Messages/BetaRawContentBlockStartEvent.cs | 3 + .../Messages/BetaRawContentBlockStopEvent.cs | 3 + .../Beta/Messages/BetaRawMessageDeltaEvent.cs | 6 + .../Beta/Messages/BetaRawMessageStartEvent.cs | 3 + .../Beta/Messages/BetaRawMessageStopEvent.cs | 3 + .../Messages/BetaRedactedThinkingBlock.cs | 3 + .../BetaRedactedThinkingBlockParam.cs | 3 + .../Beta/Messages/BetaRequestDocumentBlock.cs | 3 + .../BetaRequestMcpServerToolConfiguration.cs | 3 + .../BetaRequestMcpServerUrlDefinition.cs | 3 + .../BetaRequestMcpToolResultBlockParam.cs | 3 + .../Messages/BetaSearchResultBlockParam.cs | 3 + .../Beta/Messages/BetaServerToolCaller.cs | 3 + .../Beta/Messages/BetaServerToolUsage.cs | 3 + .../Beta/Messages/BetaServerToolUseBlock.cs | 3 + .../Messages/BetaServerToolUseBlockParam.cs | 3 + .../Beta/Messages/BetaSignatureDelta.cs | 3 + .../Models/Beta/Messages/BetaSkill.cs | 3 + .../Models/Beta/Messages/BetaSkillParams.cs | 3 + .../Models/Beta/Messages/BetaTextBlock.cs | 3 + .../Beta/Messages/BetaTextBlockParam.cs | 3 + .../Models/Beta/Messages/BetaTextDelta.cs | 3 + ...extEditorCodeExecutionCreateResultBlock.cs | 3 + ...itorCodeExecutionCreateResultBlockParam.cs | 3 + ...ditorCodeExecutionStrReplaceResultBlock.cs | 3 + ...CodeExecutionStrReplaceResultBlockParam.cs | 3 + ...aTextEditorCodeExecutionToolResultBlock.cs | 3 + ...EditorCodeExecutionToolResultBlockParam.cs | 3 + ...aTextEditorCodeExecutionToolResultError.cs | 3 + ...EditorCodeExecutionToolResultErrorParam.cs | 3 + ...aTextEditorCodeExecutionViewResultBlock.cs | 3 + ...EditorCodeExecutionViewResultBlockParam.cs | 3 + .../Models/Beta/Messages/BetaThinkingBlock.cs | 3 + .../Beta/Messages/BetaThinkingBlockParam.cs | 3 + .../Messages/BetaThinkingConfigDisabled.cs | 3 + .../Messages/BetaThinkingConfigEnabled.cs | 3 + .../Models/Beta/Messages/BetaThinkingDelta.cs | 3 + .../Models/Beta/Messages/BetaThinkingTurns.cs | 3 + .../Models/Beta/Messages/BetaTool.cs | 6 + .../Beta/Messages/BetaToolBash20241022.cs | 3 + .../Beta/Messages/BetaToolBash20250124.cs | 3 + .../Models/Beta/Messages/BetaToolChoiceAny.cs | 3 + .../Beta/Messages/BetaToolChoiceAuto.cs | 3 + .../Beta/Messages/BetaToolChoiceNone.cs | 3 + .../Beta/Messages/BetaToolChoiceTool.cs | 3 + .../Messages/BetaToolComputerUse20241022.cs | 3 + .../Messages/BetaToolComputerUse20250124.cs | 3 + .../Messages/BetaToolComputerUse20251124.cs | 3 + .../Beta/Messages/BetaToolReferenceBlock.cs | 3 + .../Messages/BetaToolReferenceBlockParam.cs | 3 + .../Beta/Messages/BetaToolResultBlockParam.cs | 3 + .../BetaToolSearchToolBm25_20251119.cs | 3 + .../BetaToolSearchToolRegex20251119.cs | 3 + .../Messages/BetaToolSearchToolResultBlock.cs | 3 + .../BetaToolSearchToolResultBlockParam.cs | 3 + .../Messages/BetaToolSearchToolResultError.cs | 3 + .../BetaToolSearchToolResultErrorParam.cs | 3 + .../BetaToolSearchToolSearchResultBlock.cs | 3 + ...etaToolSearchToolSearchResultBlockParam.cs | 3 + .../Messages/BetaToolTextEditor20241022.cs | 3 + .../Messages/BetaToolTextEditor20250124.cs | 3 + .../Messages/BetaToolTextEditor20250429.cs | 3 + .../Messages/BetaToolTextEditor20250728.cs | 3 + .../Models/Beta/Messages/BetaToolUseBlock.cs | 3 + .../Beta/Messages/BetaToolUseBlockParam.cs | 3 + .../Models/Beta/Messages/BetaToolUsesKeep.cs | 3 + .../Beta/Messages/BetaToolUsesTrigger.cs | 3 + .../Beta/Messages/BetaUrlImageSource.cs | 3 + .../Models/Beta/Messages/BetaUrlPdfSource.cs | 3 + .../Models/Beta/Messages/BetaUsage.cs | 3 + .../Models/Beta/Messages/BetaWebFetchBlock.cs | 3 + .../Beta/Messages/BetaWebFetchBlockParam.cs | 3 + .../Beta/Messages/BetaWebFetchTool20250910.cs | 3 + .../Messages/BetaWebFetchToolResultBlock.cs | 3 + .../BetaWebFetchToolResultBlockParam.cs | 3 + .../BetaWebFetchToolResultErrorBlock.cs | 3 + .../BetaWebFetchToolResultErrorBlockParam.cs | 3 + .../Beta/Messages/BetaWebSearchResultBlock.cs | 3 + .../Messages/BetaWebSearchResultBlockParam.cs | 3 + .../Messages/BetaWebSearchTool20250305.cs | 6 + .../Messages/BetaWebSearchToolRequestError.cs | 3 + .../Messages/BetaWebSearchToolResultBlock.cs | 3 + .../BetaWebSearchToolResultBlockParam.cs | 3 + .../Messages/BetaWebSearchToolResultError.cs | 3 + .../Models/Beta/Models/BetaModelInfo.cs | 3 + .../Beta/Models/ModelListPageResponse.cs | 3 + .../Models/Beta/Skills/SkillCreateResponse.cs | 3 + .../Models/Beta/Skills/SkillDeleteResponse.cs | 3 + .../Beta/Skills/SkillListPageResponse.cs | 3 + .../Models/Beta/Skills/SkillListResponse.cs | 3 + .../Beta/Skills/SkillRetrieveResponse.cs | 3 + .../Skills/Versions/VersionCreateResponse.cs | 3 + .../Skills/Versions/VersionDeleteResponse.cs | 3 + .../Versions/VersionListPageResponse.cs | 3 + .../Skills/Versions/VersionListResponse.cs | 3 + .../Versions/VersionRetrieveResponse.cs | 3 + src/Anthropic/Models/BillingError.cs | 3 + src/Anthropic/Models/ErrorResponse.cs | 3 + src/Anthropic/Models/GatewayTimeoutError.cs | 3 + src/Anthropic/Models/InvalidRequestError.cs | 3 + .../Models/Messages/Base64ImageSource.cs | 3 + .../Models/Messages/Base64PdfSource.cs | 3 + .../Messages/Batches/BatchCreateParams.cs | 6 + .../Messages/Batches/BatchListPageResponse.cs | 3 + .../Messages/Batches/DeletedMessageBatch.cs | 3 + .../Models/Messages/Batches/MessageBatch.cs | 3 + .../Batches/MessageBatchCanceledResult.cs | 3 + .../Batches/MessageBatchErroredResult.cs | 3 + .../Batches/MessageBatchExpiredResult.cs | 3 + .../Batches/MessageBatchIndividualResponse.cs | 3 + .../Batches/MessageBatchRequestCounts.cs | 3 + .../Batches/MessageBatchSucceededResult.cs | 3 + .../Models/Messages/CacheControlEphemeral.cs | 3 + .../Models/Messages/CacheCreation.cs | 3 + .../Models/Messages/CitationCharLocation.cs | 3 + .../Messages/CitationCharLocationParam.cs | 3 + .../Messages/CitationContentBlockLocation.cs | 3 + .../CitationContentBlockLocationParam.cs | 3 + .../Models/Messages/CitationPageLocation.cs | 3 + .../Messages/CitationPageLocationParam.cs | 3 + .../CitationSearchResultLocationParam.cs | 3 + .../CitationWebSearchResultLocationParam.cs | 3 + .../Models/Messages/CitationsConfigParam.cs | 3 + .../Models/Messages/CitationsDelta.cs | 3 + .../Messages/CitationsSearchResultLocation.cs | 3 + .../CitationsWebSearchResultLocation.cs | 3 + .../Models/Messages/ContentBlockSource.cs | 3 + .../Models/Messages/DocumentBlockParam.cs | 3 + .../Models/Messages/ImageBlockParam.cs | 3 + .../Models/Messages/InputJsonDelta.cs | 3 + src/Anthropic/Models/Messages/Message.cs | 3 + .../Models/Messages/MessageDeltaUsage.cs | 3 + src/Anthropic/Models/Messages/MessageParam.cs | 3 + .../Models/Messages/MessageTokensCount.cs | 3 + src/Anthropic/Models/Messages/Metadata.cs | 3 + .../Models/Messages/PlainTextSource.cs | 3 + .../Messages/RawContentBlockDeltaEvent.cs | 3 + .../Messages/RawContentBlockStartEvent.cs | 3 + .../Messages/RawContentBlockStopEvent.cs | 3 + .../Models/Messages/RawMessageDeltaEvent.cs | 6 + .../Models/Messages/RawMessageStartEvent.cs | 3 + .../Models/Messages/RawMessageStopEvent.cs | 3 + .../Models/Messages/RedactedThinkingBlock.cs | 3 + .../Messages/RedactedThinkingBlockParam.cs | 3 + .../Models/Messages/SearchResultBlockParam.cs | 3 + .../Models/Messages/ServerToolUsage.cs | 3 + .../Models/Messages/ServerToolUseBlock.cs | 3 + .../Messages/ServerToolUseBlockParam.cs | 3 + .../Models/Messages/SignatureDelta.cs | 3 + src/Anthropic/Models/Messages/TextBlock.cs | 3 + .../Models/Messages/TextBlockParam.cs | 3 + src/Anthropic/Models/Messages/TextDelta.cs | 3 + .../Models/Messages/ThinkingBlock.cs | 3 + .../Models/Messages/ThinkingBlockParam.cs | 3 + .../Models/Messages/ThinkingConfigDisabled.cs | 3 + .../Models/Messages/ThinkingConfigEnabled.cs | 3 + .../Models/Messages/ThinkingDelta.cs | 3 + src/Anthropic/Models/Messages/Tool.cs | 6 + .../Models/Messages/ToolBash20250124.cs | 3 + .../Models/Messages/ToolChoiceAny.cs | 3 + .../Models/Messages/ToolChoiceAuto.cs | 3 + .../Models/Messages/ToolChoiceNone.cs | 3 + .../Models/Messages/ToolChoiceTool.cs | 3 + .../Models/Messages/ToolResultBlockParam.cs | 3 + .../Models/Messages/ToolTextEditor20250124.cs | 3 + .../Models/Messages/ToolTextEditor20250429.cs | 3 + .../Models/Messages/ToolTextEditor20250728.cs | 3 + src/Anthropic/Models/Messages/ToolUseBlock.cs | 3 + .../Models/Messages/ToolUseBlockParam.cs | 3 + .../Models/Messages/UrlImageSource.cs | 3 + src/Anthropic/Models/Messages/UrlPdfSource.cs | 3 + src/Anthropic/Models/Messages/Usage.cs | 3 + .../Models/Messages/WebSearchResultBlock.cs | 3 + .../Messages/WebSearchResultBlockParam.cs | 3 + .../Models/Messages/WebSearchTool20250305.cs | 6 + .../Messages/WebSearchToolRequestError.cs | 3 + .../Messages/WebSearchToolResultBlock.cs | 3 + .../Messages/WebSearchToolResultBlockParam.cs | 3 + .../Messages/WebSearchToolResultError.cs | 3 + src/Anthropic/Models/Models/ModelInfo.cs | 3 + .../Models/Models/ModelListPageResponse.cs | 3 + src/Anthropic/Models/NotFoundError.cs | 3 + src/Anthropic/Models/OverloadedError.cs | 3 + src/Anthropic/Models/PermissionError.cs | 3 + src/Anthropic/Models/RateLimitError.cs | 3 + 576 files changed, 6163 insertions(+) diff --git a/src/Anthropic.Tests/Models/ApiErrorObjectTest.cs b/src/Anthropic.Tests/Models/ApiErrorObjectTest.cs index 876131aa2..e6b5f867d 100644 --- a/src/Anthropic.Tests/Models/ApiErrorObjectTest.cs +++ b/src/Anthropic.Tests/Models/ApiErrorObjectTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ApiErrorObject { Message = "message" }; + + ApiErrorObject copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/AuthenticationErrorTest.cs b/src/Anthropic.Tests/Models/AuthenticationErrorTest.cs index 2f016a202..64db49e94 100644 --- a/src/Anthropic.Tests/Models/AuthenticationErrorTest.cs +++ b/src/Anthropic.Tests/Models/AuthenticationErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new AuthenticationError { Message = "message" }; + + AuthenticationError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/BetaApiErrorTest.cs b/src/Anthropic.Tests/Models/Beta/BetaApiErrorTest.cs index f051e8af2..d12d781c1 100644 --- a/src/Anthropic.Tests/Models/Beta/BetaApiErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/BetaApiErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaApiError { Message = "message" }; + + BetaApiError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/BetaAuthenticationErrorTest.cs b/src/Anthropic.Tests/Models/Beta/BetaAuthenticationErrorTest.cs index a90200dfc..3e8caed21 100644 --- a/src/Anthropic.Tests/Models/Beta/BetaAuthenticationErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/BetaAuthenticationErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaAuthenticationError { Message = "message" }; + + BetaAuthenticationError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/BetaBillingErrorTest.cs b/src/Anthropic.Tests/Models/Beta/BetaBillingErrorTest.cs index 02aa67bf3..63f78d78f 100644 --- a/src/Anthropic.Tests/Models/Beta/BetaBillingErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/BetaBillingErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBillingError { Message = "message" }; + + BetaBillingError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/BetaErrorResponseTest.cs b/src/Anthropic.Tests/Models/Beta/BetaErrorResponseTest.cs index ceb05040e..86a72cbf3 100644 --- a/src/Anthropic.Tests/Models/Beta/BetaErrorResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/BetaErrorResponseTest.cs @@ -78,4 +78,18 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaErrorResponse + { + Error = new BetaInvalidRequestError("message"), + RequestID = "request_id", + }; + + BetaErrorResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/BetaGatewayTimeoutErrorTest.cs b/src/Anthropic.Tests/Models/Beta/BetaGatewayTimeoutErrorTest.cs index f2bbe712d..6def0e0ab 100644 --- a/src/Anthropic.Tests/Models/Beta/BetaGatewayTimeoutErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/BetaGatewayTimeoutErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaGatewayTimeoutError { Message = "message" }; + + BetaGatewayTimeoutError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/BetaInvalidRequestErrorTest.cs b/src/Anthropic.Tests/Models/Beta/BetaInvalidRequestErrorTest.cs index 2b8c94d2a..6f92f74ce 100644 --- a/src/Anthropic.Tests/Models/Beta/BetaInvalidRequestErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/BetaInvalidRequestErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaInvalidRequestError { Message = "message" }; + + BetaInvalidRequestError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/BetaNotFoundErrorTest.cs b/src/Anthropic.Tests/Models/Beta/BetaNotFoundErrorTest.cs index 940ce21ec..a57000c8a 100644 --- a/src/Anthropic.Tests/Models/Beta/BetaNotFoundErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/BetaNotFoundErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaNotFoundError { Message = "message" }; + + BetaNotFoundError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/BetaOverloadedErrorTest.cs b/src/Anthropic.Tests/Models/Beta/BetaOverloadedErrorTest.cs index a0eb89f11..e8710de03 100644 --- a/src/Anthropic.Tests/Models/Beta/BetaOverloadedErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/BetaOverloadedErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaOverloadedError { Message = "message" }; + + BetaOverloadedError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/BetaPermissionErrorTest.cs b/src/Anthropic.Tests/Models/Beta/BetaPermissionErrorTest.cs index d750f8d7c..b77bb4248 100644 --- a/src/Anthropic.Tests/Models/Beta/BetaPermissionErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/BetaPermissionErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaPermissionError { Message = "message" }; + + BetaPermissionError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/BetaRateLimitErrorTest.cs b/src/Anthropic.Tests/Models/Beta/BetaRateLimitErrorTest.cs index ded6a5a72..9a7cd44bc 100644 --- a/src/Anthropic.Tests/Models/Beta/BetaRateLimitErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/BetaRateLimitErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRateLimitError { Message = "message" }; + + BetaRateLimitError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Files/DeletedFileTest.cs b/src/Anthropic.Tests/Models/Beta/Files/DeletedFileTest.cs index 7b859dddb..e0a4ace88 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/DeletedFileTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/DeletedFileTest.cs @@ -105,6 +105,16 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new DeletedFile { ID = "id", Type = Type.FileDeleted }; + + DeletedFile copied = new(model); + + Assert.Equal(model, copied); + } } public class TypeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Files/FileListPageResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Files/FileListPageResponseTest.cs index 3deb1507c..40eaad61a 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/FileListPageResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/FileListPageResponseTest.cs @@ -374,4 +374,31 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new FileListPageResponse + { + Data = + [ + new() + { + ID = "id", + CreatedAt = DateTimeOffset.Parse("2019-12-27T18:11:19.117Z"), + Filename = "x", + MimeType = "x", + SizeBytes = 0, + Downloadable = true, + }, + ], + FirstID = "first_id", + HasMore = true, + LastID = "last_id", + }; + + FileListPageResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Files/FileMetadataTest.cs b/src/Anthropic.Tests/Models/Beta/Files/FileMetadataTest.cs index 520e7d475..a02048493 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/FileMetadataTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/FileMetadataTest.cs @@ -179,4 +179,22 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new FileMetadata + { + ID = "id", + CreatedAt = DateTimeOffset.Parse("2019-12-27T18:11:19.117Z"), + Filename = "x", + MimeType = "x", + SizeBytes = 0, + Downloadable = true, + }; + + FileMetadata copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs index 7da0e0c73..01dbe7c49 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs @@ -1806,6 +1806,138 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Request + { + CustomID = "my-custom-id-1", + Params = new() + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Container = new Messages::BetaContainerParams() + { + ID = "id", + Skills = + [ + new() + { + SkillID = "x", + Type = Messages::BetaSkillParamsType.Anthropic, + Version = "x", + }, + ], + }, + ContextManagement = new() + { + Edits = + [ + new Messages::BetaClearToolUses20250919Edit() + { + ClearAtLeast = new(0), + ClearToolInputs = true, + ExcludeTools = ["string"], + Keep = new(0), + Trigger = new Messages::BetaInputTokensTrigger(1), + }, + ], + }, + McpServers = + [ + new() + { + Name = "name", + Url = "url", + AuthorizationToken = "authorization_token", + ToolConfiguration = new() { AllowedTools = ["string"], Enabled = true }, + }, + ], + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + OutputFormat = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::BetaTextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::BetaCitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::BetaThinkingConfigEnabled(1024), + ToolChoice = new Messages::BetaToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::BetaTool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + AllowedCallers = [Messages::BetaToolAllowedCaller.Direct], + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + DeferLoading = true, + Description = "Get the current weather in a given location", + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + Type = Messages::BetaToolType.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }, + }; + + Request copied = new(model); + + Assert.Equal(model, copied); + } } public class ParamsTest : TestBase @@ -3304,6 +3436,134 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Params + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Container = new Messages::BetaContainerParams() + { + ID = "id", + Skills = + [ + new() + { + SkillID = "x", + Type = Messages::BetaSkillParamsType.Anthropic, + Version = "x", + }, + ], + }, + ContextManagement = new() + { + Edits = + [ + new Messages::BetaClearToolUses20250919Edit() + { + ClearAtLeast = new(0), + ClearToolInputs = true, + ExcludeTools = ["string"], + Keep = new(0), + Trigger = new Messages::BetaInputTokensTrigger(1), + }, + ], + }, + McpServers = + [ + new() + { + Name = "name", + Url = "url", + AuthorizationToken = "authorization_token", + ToolConfiguration = new() { AllowedTools = ["string"], Enabled = true }, + }, + ], + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + OutputFormat = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::BetaTextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::BetaCitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::BetaThinkingConfigEnabled(1024), + ToolChoice = new Messages::BetaToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::BetaTool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + AllowedCallers = [Messages::BetaToolAllowedCaller.Direct], + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + DeferLoading = true, + Description = "Get the current weather in a given location", + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + Type = Messages::BetaToolType.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }; + + Params copied = new(model); + + Assert.Equal(model, copied); + } } public class ContainerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListPageResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListPageResponseTest.cs index 0e76e1e0d..6303254fe 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListPageResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListPageResponseTest.cs @@ -232,4 +232,42 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BatchListPageResponse + { + Data = + [ + new() + { + ID = "msgbatch_013Zva2CMHLNnXjNJJKqJ2EF", + ArchivedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + CancelInitiatedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + CreatedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + EndedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + ExpiresAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + ProcessingStatus = ProcessingStatus.InProgress, + RequestCounts = new() + { + Canceled = 10, + Errored = 30, + Expired = 10, + Processing = 100, + Succeeded = 50, + }, + ResultsUrl = + "https://api.anthropic.com/v1/messages/batches/msgbatch_013Zva2CMHLNnXjNJJKqJ2EF/results", + }, + ], + FirstID = "first_id", + HasMore = true, + LastID = "last_id", + }; + + BatchListPageResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaDeletedMessageBatchTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaDeletedMessageBatchTest.cs index b890b5a1a..a69b38541 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaDeletedMessageBatchTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaDeletedMessageBatchTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaDeletedMessageBatch { ID = "msgbatch_013Zva2CMHLNnXjNJJKqJ2EF" }; + + BetaDeletedMessageBatch copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchCanceledResultTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchCanceledResultTest.cs index 4f47680ee..1b95c89a8 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchCanceledResultTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchCanceledResultTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageBatchCanceledResult { }; + + BetaMessageBatchCanceledResult copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchErroredResultTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchErroredResultTest.cs index 8cf189b93..9bcc883b2 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchErroredResultTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchErroredResultTest.cs @@ -95,4 +95,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageBatchErroredResult + { + Error = new() + { + Error = new BetaInvalidRequestError("message"), + RequestID = "request_id", + }, + }; + + BetaMessageBatchErroredResult copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchExpiredResultTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchExpiredResultTest.cs index 58f61fb58..6871bca13 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchExpiredResultTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchExpiredResultTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageBatchExpiredResult { }; + + BetaMessageBatchExpiredResult copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponseTest.cs index a5d72796f..5e7c59107 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponseTest.cs @@ -461,4 +461,82 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageBatchIndividualResponse + { + CustomID = "my-custom-id-1", + Result = new BetaMessageBatchSucceededResult( + new Messages::BetaMessage() + { + ID = "msg_013Zva2CMHLNnXjNJJKqJ2EF", + Container = new() + { + ID = "id", + ExpiresAt = DateTimeOffset.Parse("2019-12-27T18:11:19.117Z"), + Skills = + [ + new() + { + SkillID = "x", + Type = Messages::Type.Anthropic, + Version = "x", + }, + ], + }, + Content = + [ + new Messages::BetaTextBlock() + { + Citations = + [ + new Messages::BetaCitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "Hi! My name is Claude.", + }, + ], + ContextManagement = new( + [ + new Messages::BetaClearToolUses20250919EditResponse() + { + ClearedInputTokens = 0, + ClearedToolUses = 0, + }, + ] + ), + Model = Model.ClaudeSonnet4_5_20250929, + StopReason = Messages::BetaStopReason.EndTurn, + StopSequence = null, + Usage = new() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, + ServiceTier = Messages::BetaUsageServiceTier.Standard, + }, + } + ), + }; + + BetaMessageBatchIndividualResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchRequestCountsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchRequestCountsTest.cs index c3d4ecc39..827c00311 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchRequestCountsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchRequestCountsTest.cs @@ -98,4 +98,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageBatchRequestCounts + { + Canceled = 10, + Errored = 30, + Expired = 10, + Processing = 100, + Succeeded = 50, + }; + + BetaMessageBatchRequestCounts copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResultTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResultTest.cs index 67ee2ed16..da86ab802 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResultTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResultTest.cs @@ -437,4 +437,79 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageBatchSucceededResult + { + Message = new() + { + ID = "msg_013Zva2CMHLNnXjNJJKqJ2EF", + Container = new() + { + ID = "id", + ExpiresAt = DateTimeOffset.Parse("2019-12-27T18:11:19.117Z"), + Skills = + [ + new() + { + SkillID = "x", + Type = Messages::Type.Anthropic, + Version = "x", + }, + ], + }, + Content = + [ + new Messages::BetaTextBlock() + { + Citations = + [ + new Messages::BetaCitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "Hi! My name is Claude.", + }, + ], + ContextManagement = new( + [ + new Messages::BetaClearToolUses20250919EditResponse() + { + ClearedInputTokens = 0, + ClearedToolUses = 0, + }, + ] + ), + Model = Model.ClaudeSonnet4_5_20250929, + StopReason = Messages::BetaStopReason.EndTurn, + StopSequence = null, + Usage = new() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, + ServiceTier = Messages::BetaUsageServiceTier.Standard, + }, + }, + }; + + BetaMessageBatchSucceededResult copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchTest.cs index b027c616a..0362c3829 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchTest.cs @@ -188,6 +188,35 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageBatch + { + ID = "msgbatch_013Zva2CMHLNnXjNJJKqJ2EF", + ArchivedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + CancelInitiatedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + CreatedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + EndedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + ExpiresAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + ProcessingStatus = ProcessingStatus.InProgress, + RequestCounts = new() + { + Canceled = 10, + Errored = 30, + Expired = 10, + Processing = 100, + Succeeded = 50, + }, + ResultsUrl = + "https://api.anthropic.com/v1/messages/batches/msgbatch_013Zva2CMHLNnXjNJJKqJ2EF/results", + }; + + BetaMessageBatch copied = new(model); + + Assert.Equal(model, copied); + } } public class ProcessingStatusTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaAllThinkingTurnsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaAllThinkingTurnsTest.cs index d9a695f67..dc554f38c 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaAllThinkingTurnsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaAllThinkingTurnsTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaAllThinkingTurns { }; + + BetaAllThinkingTurns copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaBase64ImageSourceTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaBase64ImageSourceTest.cs index ef9da291c..c4aec464c 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaBase64ImageSourceTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaBase64ImageSourceTest.cs @@ -79,6 +79,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBase64ImageSource + { + Data = "U3RhaW5sZXNzIHJvY2tz", + MediaType = MediaType.ImageJpeg, + }; + + BetaBase64ImageSource copied = new(model); + + Assert.Equal(model, copied); + } } public class MediaTypeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaBase64PdfSourceTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaBase64PdfSourceTest.cs index 5c000a1af..a280b0c96 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaBase64PdfSourceTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaBase64PdfSourceTest.cs @@ -62,4 +62,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBase64PdfSource { Data = "U3RhaW5sZXNzIHJvY2tz" }; + + BetaBase64PdfSource copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockParamTest.cs index 38b42c759..5f8aef2fc 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockParamTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBashCodeExecutionOutputBlockParam { FileID = "file_id" }; + + BetaBashCodeExecutionOutputBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockTest.cs index f4aa42966..af16f174f 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBashCodeExecutionOutputBlock { FileID = "file_id" }; + + BetaBashCodeExecutionOutputBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionResultBlockParamTest.cs index a0e208a93..6be078ee2 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionResultBlockParamTest.cs @@ -103,4 +103,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBashCodeExecutionResultBlockParam + { + Content = [new("file_id")], + ReturnCode = 0, + Stderr = "stderr", + Stdout = "stdout", + }; + + BetaBashCodeExecutionResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionResultBlockTest.cs index c637e4529..2d69bbcde 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionResultBlockTest.cs @@ -103,4 +103,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBashCodeExecutionResultBlock + { + Content = [new("file_id")], + ReturnCode = 0, + Stderr = "stderr", + Stdout = "stdout", + }; + + BetaBashCodeExecutionResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParamTest.cs index 9a47b50d9..8da831841 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParamTest.cs @@ -166,6 +166,23 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBashCodeExecutionToolResultBlockParam + { + Content = new BetaBashCodeExecutionToolResultErrorParam( + BetaBashCodeExecutionToolResultErrorParamErrorCode.InvalidToolInput + ), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaBashCodeExecutionToolResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaBashCodeExecutionToolResultBlockParamContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockTest.cs index b1c0add43..80e4859d0 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockTest.cs @@ -86,6 +86,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBashCodeExecutionToolResultBlock + { + Content = new BetaBashCodeExecutionToolResultError(ErrorCode.InvalidToolInput), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + }; + + BetaBashCodeExecutionToolResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } public class ContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorParamTest.cs index b64a2343c..5295dc2fe 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorParamTest.cs @@ -77,6 +77,19 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBashCodeExecutionToolResultErrorParam + { + ErrorCode = BetaBashCodeExecutionToolResultErrorParamErrorCode.InvalidToolInput, + }; + + BetaBashCodeExecutionToolResultErrorParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaBashCodeExecutionToolResultErrorParamErrorCodeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorTest.cs index 9361bd989..f64eb0cbb 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorTest.cs @@ -75,6 +75,19 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaBashCodeExecutionToolResultError + { + ErrorCode = ErrorCode.InvalidToolInput, + }; + + BetaBashCodeExecutionToolResultError copied = new(model); + + Assert.Equal(model, copied); + } } public class ErrorCodeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCacheControlEphemeralTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCacheControlEphemeralTest.cs index ed2d3d652..9e7d1f041 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCacheControlEphemeralTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCacheControlEphemeralTest.cs @@ -101,6 +101,16 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCacheControlEphemeral { Ttl = Ttl.Ttl5m }; + + BetaCacheControlEphemeral copied = new(model); + + Assert.Equal(model, copied); + } } public class TtlTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCacheCreationTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCacheCreationTest.cs index 2370a85a6..29e0b5678 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCacheCreationTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCacheCreationTest.cs @@ -74,4 +74,18 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCacheCreation + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }; + + BetaCacheCreation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationCharLocationParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationCharLocationParamTest.cs index 47cd5b9ed..c05873547 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationCharLocationParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationCharLocationParamTest.cs @@ -102,4 +102,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationCharLocationParam + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }; + + BetaCitationCharLocationParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationCharLocationTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationCharLocationTest.cs index 793e1802a..69f217d06 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationCharLocationTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationCharLocationTest.cs @@ -110,4 +110,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationCharLocation + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }; + + BetaCitationCharLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationConfigTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationConfigTest.cs index 5e3e04e53..1d1a9db42 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationConfigTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationConfigTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationConfig { Enabled = true }; + + BetaCitationConfig copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationContentBlockLocationParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationContentBlockLocationParamTest.cs index 535169369..a9179cc37 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationContentBlockLocationParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationContentBlockLocationParamTest.cs @@ -102,4 +102,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationContentBlockLocationParam + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndBlockIndex = 0, + StartBlockIndex = 0, + }; + + BetaCitationContentBlockLocationParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationContentBlockLocationTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationContentBlockLocationTest.cs index 99e0814f6..299358b77 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationContentBlockLocationTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationContentBlockLocationTest.cs @@ -110,4 +110,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationContentBlockLocation + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndBlockIndex = 0, + FileID = "file_id", + StartBlockIndex = 0, + }; + + BetaCitationContentBlockLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationPageLocationParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationPageLocationParamTest.cs index db8985791..3de1f3f53 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationPageLocationParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationPageLocationParamTest.cs @@ -102,4 +102,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationPageLocationParam + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndPageNumber = 0, + StartPageNumber = 1, + }; + + BetaCitationPageLocationParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationPageLocationTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationPageLocationTest.cs index b75508476..655005c93 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationPageLocationTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationPageLocationTest.cs @@ -110,4 +110,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationPageLocation + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndPageNumber = 0, + FileID = "file_id", + StartPageNumber = 1, + }; + + BetaCitationPageLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationSearchResultLocationParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationSearchResultLocationParamTest.cs index feb504b72..ddbe6d201 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationSearchResultLocationParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationSearchResultLocationParamTest.cs @@ -110,4 +110,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationSearchResultLocationParam + { + CitedText = "cited_text", + EndBlockIndex = 0, + SearchResultIndex = 0, + Source = "source", + StartBlockIndex = 0, + Title = "title", + }; + + BetaCitationSearchResultLocationParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationSearchResultLocationTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationSearchResultLocationTest.cs index 8a12afaac..4f6e2ea14 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationSearchResultLocationTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationSearchResultLocationTest.cs @@ -110,4 +110,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationSearchResultLocation + { + CitedText = "cited_text", + EndBlockIndex = 0, + SearchResultIndex = 0, + Source = "source", + StartBlockIndex = 0, + Title = "title", + }; + + BetaCitationSearchResultLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationWebSearchResultLocationParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationWebSearchResultLocationParamTest.cs index 22ba16a77..d218711fc 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationWebSearchResultLocationParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationWebSearchResultLocationParamTest.cs @@ -94,4 +94,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationWebSearchResultLocationParam + { + CitedText = "cited_text", + EncryptedIndex = "encrypted_index", + Title = "x", + Url = "x", + }; + + BetaCitationWebSearchResultLocationParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsConfigParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsConfigParamTest.cs index 3906148d9..57567e641 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsConfigParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsConfigParamTest.cs @@ -96,4 +96,14 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationsConfigParam { Enabled = true }; + + BetaCitationsConfigParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsDeltaTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsDeltaTest.cs index fa9b8195a..1b19358c8 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsDeltaTest.cs @@ -118,6 +118,27 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationsDelta + { + Citation = new BetaCitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + }; + + BetaCitationsDelta copied = new(model); + + Assert.Equal(model, copied); + } } public class CitationTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsWebSearchResultLocationTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsWebSearchResultLocationTest.cs index 2920a700b..29da3ccac 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsWebSearchResultLocationTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCitationsWebSearchResultLocationTest.cs @@ -94,4 +94,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCitationsWebSearchResultLocation + { + CitedText = "cited_text", + EncryptedIndex = "encrypted_index", + Title = "title", + Url = "url", + }; + + BetaCitationsWebSearchResultLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaClearThinking20251015EditResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaClearThinking20251015EditResponseTest.cs index 503ce68f9..b4bd0d2ef 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaClearThinking20251015EditResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaClearThinking20251015EditResponseTest.cs @@ -78,4 +78,18 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaClearThinking20251015EditResponse + { + ClearedInputTokens = 0, + ClearedThinkingTurns = 0, + }; + + BetaClearThinking20251015EditResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaClearThinking20251015EditTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaClearThinking20251015EditTest.cs index 15aad57e1..ef18c5614 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaClearThinking20251015EditTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaClearThinking20251015EditTest.cs @@ -101,6 +101,16 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaClearThinking20251015Edit { Keep = new BetaThinkingTurns(1) }; + + BetaClearThinking20251015Edit copied = new(model); + + Assert.Equal(model, copied); + } } public class KeepTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaClearToolUses20250919EditResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaClearToolUses20250919EditResponseTest.cs index 28728644b..c0f22b1c7 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaClearToolUses20250919EditResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaClearToolUses20250919EditResponseTest.cs @@ -78,4 +78,18 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaClearToolUses20250919EditResponse + { + ClearedInputTokens = 0, + ClearedToolUses = 0, + }; + + BetaClearToolUses20250919EditResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaClearToolUses20250919EditTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaClearToolUses20250919EditTest.cs index 9b04dddbb..399b55de4 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaClearToolUses20250919EditTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaClearToolUses20250919EditTest.cs @@ -245,6 +245,23 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaClearToolUses20250919Edit + { + ClearAtLeast = new(0), + ClearToolInputs = true, + ExcludeTools = ["string"], + Keep = new(0), + Trigger = new BetaInputTokensTrigger(1), + }; + + BetaClearToolUses20250919Edit copied = new(model); + + Assert.Equal(model, copied); + } } public class ClearToolInputsTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionOutputBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionOutputBlockParamTest.cs index 9742c5bb1..19b00536b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionOutputBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionOutputBlockParamTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCodeExecutionOutputBlockParam { FileID = "file_id" }; + + BetaCodeExecutionOutputBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionOutputBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionOutputBlockTest.cs index 3b2981668..015c43b20 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionOutputBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionOutputBlockTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCodeExecutionOutputBlock { FileID = "file_id" }; + + BetaCodeExecutionOutputBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionResultBlockParamTest.cs index b7304d396..5cb409622 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionResultBlockParamTest.cs @@ -103,4 +103,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCodeExecutionResultBlockParam + { + Content = [new("file_id")], + ReturnCode = 0, + Stderr = "stderr", + Stdout = "stdout", + }; + + BetaCodeExecutionResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionResultBlockTest.cs index a18526fda..d1a712a76 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionResultBlockTest.cs @@ -103,4 +103,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCodeExecutionResultBlock + { + Content = [new("file_id")], + ReturnCode = 0, + Stderr = "stderr", + Stdout = "stdout", + }; + + BetaCodeExecutionResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionTool20250522Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionTool20250522Test.cs index 733e46054..76ced3fb7 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionTool20250522Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionTool20250522Test.cs @@ -226,6 +226,22 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCodeExecutionTool20250522 + { + AllowedCallers = [AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + Strict = true, + }; + + BetaCodeExecutionTool20250522 copied = new(model); + + Assert.Equal(model, copied); + } } public class AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionTool20250825Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionTool20250825Test.cs index 3826f0aaa..b106ccbaa 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionTool20250825Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionTool20250825Test.cs @@ -232,6 +232,22 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCodeExecutionTool20250825 + { + AllowedCallers = [BetaCodeExecutionTool20250825AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + Strict = true, + }; + + BetaCodeExecutionTool20250825 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaCodeExecutionTool20250825AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParamTest.cs index 1e3785317..909b5b82e 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParamTest.cs @@ -162,4 +162,21 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCodeExecutionToolResultBlockParam + { + Content = new BetaCodeExecutionToolResultErrorParam( + BetaCodeExecutionToolResultErrorCode.InvalidToolInput + ), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaCodeExecutionToolResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultBlockTest.cs index 5ff07298e..33a54b57c 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultBlockTest.cs @@ -92,4 +92,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCodeExecutionToolResultBlock + { + Content = new BetaCodeExecutionToolResultError( + BetaCodeExecutionToolResultErrorCode.InvalidToolInput + ), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + }; + + BetaCodeExecutionToolResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultErrorParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultErrorParamTest.cs index adceba3e4..df34eea75 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultErrorParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultErrorParamTest.cs @@ -76,4 +76,17 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCodeExecutionToolResultErrorParam + { + ErrorCode = BetaCodeExecutionToolResultErrorCode.InvalidToolInput, + }; + + BetaCodeExecutionToolResultErrorParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultErrorTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultErrorTest.cs index 5baa6c684..82db49d5b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCodeExecutionToolResultErrorTest.cs @@ -76,4 +76,17 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCodeExecutionToolResultError + { + ErrorCode = BetaCodeExecutionToolResultErrorCode.InvalidToolInput, + }; + + BetaCodeExecutionToolResultError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerParamsTest.cs index 566ca04c8..0d28b42a3 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerParamsTest.cs @@ -171,4 +171,26 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaContainerParams + { + ID = "id", + Skills = + [ + new() + { + SkillID = "x", + Type = BetaSkillParamsType.Anthropic, + Version = "x", + }, + ], + }; + + BetaContainerParams copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerTest.cs index a6ec74db5..b01c7e7d4 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerTest.cs @@ -142,4 +142,27 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Messages::BetaContainer + { + ID = "id", + ExpiresAt = DateTimeOffset.Parse("2019-12-27T18:11:19.117Z"), + Skills = + [ + new() + { + SkillID = "x", + Type = Messages::Type.Anthropic, + Version = "x", + }, + ], + }; + + Messages::BetaContainer copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerUploadBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerUploadBlockParamTest.cs index da7bfe6dc..e224182b1 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerUploadBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerUploadBlockParamTest.cs @@ -122,4 +122,18 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaContainerUploadBlockParam + { + FileID = "file_id", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaContainerUploadBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerUploadBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerUploadBlockTest.cs index b7a7be2fa..991f302d4 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerUploadBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContainerUploadBlockTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaContainerUploadBlock { FileID = "file_id" }; + + BetaContainerUploadBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockSourceTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockSourceTest.cs index 9d0e89d84..afd9a7046 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockSourceTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockSourceTest.cs @@ -58,6 +58,16 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaContentBlockSource { Content = "string" }; + + BetaContentBlockSource copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaContentBlockSourceContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementConfigTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementConfigTest.cs index 003d61bc1..9112053a9 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementConfigTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementConfigTest.cs @@ -179,6 +179,29 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaContextManagementConfig + { + Edits = + [ + new BetaClearToolUses20250919Edit() + { + ClearAtLeast = new(0), + ClearToolInputs = true, + ExcludeTools = ["string"], + Keep = new(0), + Trigger = new BetaInputTokensTrigger(1), + }, + ], + }; + + BetaContextManagementConfig copied = new(model); + + Assert.Equal(model, copied); + } } public class EditTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementResponseTest.cs index 1ebc1d073..3448d66d7 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementResponseTest.cs @@ -117,6 +117,26 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaContextManagementResponse + { + AppliedEdits = + [ + new BetaClearToolUses20250919EditResponse() + { + ClearedInputTokens = 0, + ClearedToolUses = 0, + }, + ], + }; + + BetaContextManagementResponse copied = new(model); + + Assert.Equal(model, copied); + } } public class AppliedEditTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCountTokensContextManagementResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCountTokensContextManagementResponseTest.cs index f19e73107..5b5cc4ecf 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaCountTokensContextManagementResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCountTokensContextManagementResponseTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCountTokensContextManagementResponse { OriginalInputTokens = 0 }; + + BetaCountTokensContextManagementResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaDirectCallerTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaDirectCallerTest.cs index 5d54a15d4..e459c9201 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaDirectCallerTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaDirectCallerTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaDirectCaller { }; + + BetaDirectCaller copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaDocumentBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaDocumentBlockTest.cs index 33da1bfef..0be29069c 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaDocumentBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaDocumentBlockTest.cs @@ -86,6 +86,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaDocumentBlock + { + Citations = new(true), + Source = new BetaBase64PdfSource("U3RhaW5sZXNzIHJvY2tz"), + Title = "title", + }; + + BetaDocumentBlock copied = new(model); + + Assert.Equal(model, copied); + } } public class SourceTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaFileDocumentSourceTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaFileDocumentSourceTest.cs index 154fa28f1..d35277c84 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaFileDocumentSourceTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaFileDocumentSourceTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaFileDocumentSource { FileID = "file_id" }; + + BetaFileDocumentSource copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaFileImageSourceTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaFileImageSourceTest.cs index 73319424f..32436fa8c 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaFileImageSourceTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaFileImageSourceTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaFileImageSource { FileID = "file_id" }; + + BetaFileImageSource copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaImageBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaImageBlockParamTest.cs index fd071ef32..b0243a17e 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaImageBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaImageBlockParamTest.cs @@ -168,6 +168,24 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaImageBlockParam + { + Source = new BetaBase64ImageSource() + { + Data = "U3RhaW5sZXNzIHJvY2tz", + MediaType = MediaType.ImageJpeg, + }, + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaImageBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaImageBlockParamSourceTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaInputJsonDeltaTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaInputJsonDeltaTest.cs index 3a0cb22eb..738ab93e3 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaInputJsonDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaInputJsonDeltaTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaInputJsonDelta { PartialJson = "partial_json" }; + + BetaInputJsonDelta copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensClearAtLeastTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensClearAtLeastTest.cs index c7741101e..3242b2ee8 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensClearAtLeastTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensClearAtLeastTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaInputTokensClearAtLeast { Value = 0 }; + + BetaInputTokensClearAtLeast copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensTriggerTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensTriggerTest.cs index fa8eeb766..aafcbe4e5 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensTriggerTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensTriggerTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaInputTokensTrigger { Value = 1 }; + + BetaInputTokensTrigger copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaJsonOutputFormatTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaJsonOutputFormatTest.cs index 5c25067c5..0472373e1 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaJsonOutputFormatTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaJsonOutputFormatTest.cs @@ -101,4 +101,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaJsonOutputFormat + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; + + BetaJsonOutputFormat copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolConfigTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolConfigTest.cs index f4ac049ae..5cacbba5a 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolConfigTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolConfigTest.cs @@ -106,4 +106,14 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMcpToolConfig { DeferLoading = true, Enabled = true }; + + BetaMcpToolConfig copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolDefaultConfigTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolDefaultConfigTest.cs index 37c2a62cb..71a744064 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolDefaultConfigTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolDefaultConfigTest.cs @@ -106,4 +106,14 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMcpToolDefaultConfig { DeferLoading = true, Enabled = true }; + + BetaMcpToolDefaultConfig copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolResultBlockTest.cs index b0698db01..174145556 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolResultBlockTest.cs @@ -86,6 +86,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMcpToolResultBlock + { + Content = "string", + IsError = true, + ToolUseID = "tool_use_id", + }; + + BetaMcpToolResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaMcpToolResultBlockContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolUseBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolUseBlockParamTest.cs index f8fbe5c3b..cedf4687d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolUseBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolUseBlockParamTest.cs @@ -207,4 +207,24 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMcpToolUseBlockParam + { + ID = "id", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = "name", + ServerName = "server_name", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaMcpToolUseBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolUseBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolUseBlockTest.cs index b1e56008d..f39d17514 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolUseBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolUseBlockTest.cs @@ -125,4 +125,23 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMcpToolUseBlock + { + ID = "id", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = "name", + ServerName = "server_name", + }; + + BetaMcpToolUseBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolsetTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolsetTest.cs index 9b2ee36e8..ca28250b1 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolsetTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMcpToolsetTest.cs @@ -297,4 +297,26 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMcpToolset + { + McpServerName = "x", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Configs = new Dictionary() + { + { + "foo", + new() { DeferLoading = true, Enabled = true } + }, + }, + DefaultConfig = new() { DeferLoading = true, Enabled = true }, + }; + + BetaMcpToolset copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818CreateCommandTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818CreateCommandTest.cs index 311508beb..127bd5692 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818CreateCommandTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818CreateCommandTest.cs @@ -80,4 +80,18 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMemoryTool20250818CreateCommand + { + FileText = "Meeting notes:\n- Discussed project timeline\n- Next steps defined\n", + Path = "/memories/notes.txt", + }; + + BetaMemoryTool20250818CreateCommand copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818DeleteCommandTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818DeleteCommandTest.cs index 666752ece..03b38013b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818DeleteCommandTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818DeleteCommandTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMemoryTool20250818DeleteCommand { Path = "/memories/old_file.txt" }; + + BetaMemoryTool20250818DeleteCommand copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818InsertCommandTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818InsertCommandTest.cs index 13d6e6ab0..690ae6d5d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818InsertCommandTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818InsertCommandTest.cs @@ -86,4 +86,19 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMemoryTool20250818InsertCommand + { + InsertLine = 2, + InsertText = "- Review memory tool documentation\n", + Path = "/memories/todo.txt", + }; + + BetaMemoryTool20250818InsertCommand copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818RenameCommandTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818RenameCommandTest.cs index 8c57b7997..c5d2a11a5 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818RenameCommandTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818RenameCommandTest.cs @@ -78,4 +78,18 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMemoryTool20250818RenameCommand + { + NewPath = "/memories/final.txt", + OldPath = "/memories/draft.txt", + }; + + BetaMemoryTool20250818RenameCommand copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818StrReplaceCommandTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818StrReplaceCommandTest.cs index 810441fa6..f41a30a4b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818StrReplaceCommandTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818StrReplaceCommandTest.cs @@ -86,4 +86,19 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMemoryTool20250818StrReplaceCommand + { + NewStr = "Favorite color: green", + OldStr = "Favorite color: blue", + Path = "/memories/preferences.txt", + }; + + BetaMemoryTool20250818StrReplaceCommand copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818Test.cs index f7fbb154d..d6fb5b864 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818Test.cs @@ -332,6 +332,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMemoryTool20250818 + { + AllowedCallers = [BetaMemoryTool20250818AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + }; + + BetaMemoryTool20250818 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaMemoryTool20250818AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818ViewCommandTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818ViewCommandTest.cs index b46f883e1..5b743302f 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818ViewCommandTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMemoryTool20250818ViewCommandTest.cs @@ -135,4 +135,18 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMemoryTool20250818ViewCommand + { + Path = "/memories", + ViewRange = [1, 10], + }; + + BetaMemoryTool20250818ViewCommand copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageDeltaUsageTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageDeltaUsageTest.cs index 9e1417c4f..b8f21407d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageDeltaUsageTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageDeltaUsageTest.cs @@ -106,4 +106,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageDeltaUsage + { + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, + }; + + BetaMessageDeltaUsage copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageParamTest.cs index 5f2887b7a..c29b96941 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageParamTest.cs @@ -59,6 +59,16 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageParam { Content = "string", Role = Role.User }; + + BetaMessageParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaMessageParamContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTest.cs index 8fc472fc0..21a175920 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTest.cs @@ -429,4 +429,72 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Messages::BetaMessage + { + ID = "msg_013Zva2CMHLNnXjNJJKqJ2EF", + Container = new() + { + ID = "id", + ExpiresAt = DateTimeOffset.Parse("2019-12-27T18:11:19.117Z"), + Skills = + [ + new() + { + SkillID = "x", + Type = Messages::Type.Anthropic, + Version = "x", + }, + ], + }, + Content = + [ + new Messages::BetaTextBlock() + { + Citations = + [ + new Messages::BetaCitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "Hi! My name is Claude.", + }, + ], + ContextManagement = new( + [ + new Messages::BetaClearToolUses20250919EditResponse() + { + ClearedInputTokens = 0, + ClearedToolUses = 0, + }, + ] + ), + Model = Model.ClaudeSonnet4_5_20250929, + StopReason = Messages::BetaStopReason.EndTurn, + StopSequence = null, + Usage = new() + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, + ServiceTier = Messages::BetaUsageServiceTier.Standard, + }, + }; + + Messages::BetaMessage copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTokensCountTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTokensCountTest.cs index 52a00c8ee..8bd5de298 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTokensCountTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTokensCountTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageTokensCount { ContextManagement = new(0), InputTokens = 2095 }; + + BetaMessageTokensCount copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMetadataTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMetadataTest.cs index 0ffbf4c0e..b1d250d40 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMetadataTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMetadataTest.cs @@ -88,4 +88,14 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMetadata { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }; + + BetaMetadata copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs index ea5a9ea76..800c50feb 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs @@ -150,6 +150,26 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaOutputConfig + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; + + BetaOutputConfig copied = new(model); + + Assert.Equal(model, copied); + } } public class EffortTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaPlainTextSourceTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaPlainTextSourceTest.cs index cfa41cc2f..bc8606ee2 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaPlainTextSourceTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaPlainTextSourceTest.cs @@ -62,4 +62,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaPlainTextSource { Data = "data" }; + + BetaPlainTextSource copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockDeltaEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockDeltaEventTest.cs index 92d7afb66..a4e9ce76d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockDeltaEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockDeltaEventTest.cs @@ -78,4 +78,18 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRawContentBlockDeltaEvent + { + Delta = new BetaTextDelta("text"), + Index = 0, + }; + + BetaRawContentBlockDeltaEvent copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs index c18978c45..b02880e1a 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs @@ -169,6 +169,35 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRawContentBlockStartEvent + { + ContentBlock = new BetaTextBlock() + { + Citations = + [ + new BetaCitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "text", + }, + Index = 0, + }; + + BetaRawContentBlockStartEvent copied = new(model); + + Assert.Equal(model, copied); + } } public class ContentBlockTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStopEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStopEventTest.cs index 009e2f531..75960aea3 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStopEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStopEventTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRawContentBlockStopEvent { Index = 0 }; + + BetaRawContentBlockStopEvent copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageDeltaEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageDeltaEventTest.cs index 4ece5031c..970a01f0c 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageDeltaEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageDeltaEventTest.cs @@ -285,6 +285,54 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Messages::BetaRawMessageDeltaEvent + { + ContextManagement = new( + [ + new Messages::BetaClearToolUses20250919EditResponse() + { + ClearedInputTokens = 0, + ClearedToolUses = 0, + }, + ] + ), + Delta = new() + { + Container = new() + { + ID = "id", + ExpiresAt = DateTimeOffset.Parse("2019-12-27T18:11:19.117Z"), + Skills = + [ + new() + { + SkillID = "x", + Type = Messages::Type.Anthropic, + Version = "x", + }, + ], + }, + StopReason = Messages::BetaStopReason.EndTurn, + StopSequence = "stop_sequence", + }, + Usage = new() + { + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, + }, + }; + + Messages::BetaRawMessageDeltaEvent copied = new(model); + + Assert.Equal(model, copied); + } } public class DeltaTest : TestBase @@ -445,4 +493,32 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Messages::Delta + { + Container = new() + { + ID = "id", + ExpiresAt = DateTimeOffset.Parse("2019-12-27T18:11:19.117Z"), + Skills = + [ + new() + { + SkillID = "x", + Type = Messages::Type.Anthropic, + Version = "x", + }, + ], + }, + StopReason = Messages::BetaStopReason.EndTurn, + StopSequence = "stop_sequence", + }; + + Messages::Delta copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStartEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStartEventTest.cs index a4c5f8743..d163ee474 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStartEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStartEventTest.cs @@ -436,4 +436,79 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Messages::BetaRawMessageStartEvent + { + Message = new() + { + ID = "msg_013Zva2CMHLNnXjNJJKqJ2EF", + Container = new() + { + ID = "id", + ExpiresAt = DateTimeOffset.Parse("2019-12-27T18:11:19.117Z"), + Skills = + [ + new() + { + SkillID = "x", + Type = Messages::Type.Anthropic, + Version = "x", + }, + ], + }, + Content = + [ + new Messages::BetaTextBlock() + { + Citations = + [ + new Messages::BetaCitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "Hi! My name is Claude.", + }, + ], + ContextManagement = new( + [ + new Messages::BetaClearToolUses20250919EditResponse() + { + ClearedInputTokens = 0, + ClearedToolUses = 0, + }, + ] + ), + Model = Model.ClaudeSonnet4_5_20250929, + StopReason = Messages::BetaStopReason.EndTurn, + StopSequence = null, + Usage = new() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, + ServiceTier = Messages::BetaUsageServiceTier.Standard, + }, + }, + }; + + Messages::BetaRawMessageStartEvent copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStopEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStopEventTest.cs index 4e5db42fd..8cfb136dc 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStopEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStopEventTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRawMessageStopEvent { }; + + BetaRawMessageStopEvent copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRedactedThinkingBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRedactedThinkingBlockParamTest.cs index cdb43df36..4e386ce23 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRedactedThinkingBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRedactedThinkingBlockParamTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRedactedThinkingBlockParam { Data = "data" }; + + BetaRedactedThinkingBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRedactedThinkingBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRedactedThinkingBlockTest.cs index 71e3608d6..ab5631224 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRedactedThinkingBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRedactedThinkingBlockTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRedactedThinkingBlock { Data = "data" }; + + BetaRedactedThinkingBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestDocumentBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestDocumentBlockTest.cs index de138c3e9..b304532ee 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestDocumentBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestDocumentBlockTest.cs @@ -174,6 +174,23 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRequestDocumentBlock + { + Source = new BetaBase64PdfSource("U3RhaW5sZXNzIHJvY2tz"), + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = new() { Enabled = true }, + Context = "x", + Title = "x", + }; + + BetaRequestDocumentBlock copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaRequestDocumentBlockSourceTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpServerToolConfigurationTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpServerToolConfigurationTest.cs index de0ddb243..f6260f049 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpServerToolConfigurationTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpServerToolConfigurationTest.cs @@ -131,4 +131,18 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRequestMcpServerToolConfiguration + { + AllowedTools = ["string"], + Enabled = true, + }; + + BetaRequestMcpServerToolConfiguration copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpServerUrlDefinitionTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpServerUrlDefinitionTest.cs index 6991f8d4b..05fa8133f 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpServerUrlDefinitionTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpServerUrlDefinitionTest.cs @@ -154,4 +154,20 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRequestMcpServerUrlDefinition + { + Name = "name", + Url = "url", + AuthorizationToken = "authorization_token", + ToolConfiguration = new() { AllowedTools = ["string"], Enabled = true }, + }; + + BetaRequestMcpServerUrlDefinition copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpToolResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpToolResultBlockParamTest.cs index 053dfb733..c1a7aba51 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpToolResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRequestMcpToolResultBlockParamTest.cs @@ -214,6 +214,22 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaRequestMcpToolResultBlockParam + { + ToolUseID = "tool_use_id", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Content = "string", + IsError = true, + }; + + BetaRequestMcpToolResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaRequestMcpToolResultBlockParamContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaSearchResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaSearchResultBlockParamTest.cs index b8a45ed5e..72fcdce4b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaSearchResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaSearchResultBlockParamTest.cs @@ -489,4 +489,39 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaSearchResultBlockParam + { + Content = + [ + new() + { + Text = "x", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = + [ + new BetaCitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ], + Source = "source", + Title = "title", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = new() { Enabled = true }, + }; + + BetaSearchResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolCallerTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolCallerTest.cs index 158e1493c..e8fb7fc70 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolCallerTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolCallerTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaServerToolCaller { ToolID = "srvtoolu_SQfNkl1n_JR_" }; + + BetaServerToolCaller copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUsageTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUsageTest.cs index 92439a5a6..052dd6ad2 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUsageTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUsageTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaServerToolUsage { WebFetchRequests = 2, WebSearchRequests = 0 }; + + BetaServerToolUsage copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockParamTest.cs index fc046f325..070cc57d6 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockParamTest.cs @@ -286,6 +286,26 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaServerToolUseBlockParam + { + ID = "srvtoolu_SQfNkl1n_JR_", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = BetaServerToolUseBlockParamName.WebSearch, + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Caller = new BetaDirectCaller(), + }; + + BetaServerToolUseBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaServerToolUseBlockParamNameTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockTest.cs index 6f25e3182..1aca19df0 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaServerToolUseBlockTest.cs @@ -198,6 +198,25 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaServerToolUseBlock + { + ID = "srvtoolu_SQfNkl1n_JR_", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = Name.WebSearch, + Caller = new BetaDirectCaller(), + }; + + BetaServerToolUseBlock copied = new(model); + + Assert.Equal(model, copied); + } } public class NameTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaSignatureDeltaTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaSignatureDeltaTest.cs index b599458ff..6d42033cc 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaSignatureDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaSignatureDeltaTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaSignatureDelta { Signature = "signature" }; + + BetaSignatureDelta copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaSkillParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaSkillParamsTest.cs index f531d6e2a..ad55042e1 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaSkillParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaSkillParamsTest.cs @@ -131,6 +131,21 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaSkillParams + { + SkillID = "x", + Type = BetaSkillParamsType.Anthropic, + Version = "x", + }; + + BetaSkillParams copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaSkillParamsTypeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaSkillTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaSkillTest.cs index 79af98a68..a71419003 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaSkillTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaSkillTest.cs @@ -80,6 +80,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaSkill + { + SkillID = "x", + Type = Type.Anthropic, + Version = "x", + }; + + BetaSkill copied = new(model); + + Assert.Equal(model, copied); + } } public class TypeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextBlockParamTest.cs index 96951731f..1db26789d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextBlockParamTest.cs @@ -207,4 +207,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextBlockParam + { + Text = "x", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = + [ + new BetaCitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }; + + BetaTextBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextBlockTest.cs index 84664d8b3..84c9f3caa 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextBlockTest.cs @@ -155,4 +155,29 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextBlock + { + Citations = + [ + new BetaCitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "text", + }; + + BetaTextBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextDeltaTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextDeltaTest.cs index 054f04f19..fd4beed7c 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextDeltaTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextDelta { Text = "text" }; + + BetaTextDelta copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockParamTest.cs index cbc09f6ac..9debf0fe5 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockParamTest.cs @@ -64,4 +64,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextEditorCodeExecutionCreateResultBlockParam { IsFileUpdate = true }; + + BetaTextEditorCodeExecutionCreateResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockTest.cs index f7d2bccfc..69def26f5 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockTest.cs @@ -62,4 +62,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextEditorCodeExecutionCreateResultBlock { IsFileUpdate = true }; + + BetaTextEditorCodeExecutionCreateResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockParamTest.cs index 15264def9..1f633d62a 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockParamTest.cs @@ -183,4 +183,21 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextEditorCodeExecutionStrReplaceResultBlockParam + { + Lines = ["string"], + NewLines = 0, + NewStart = 0, + OldLines = 0, + OldStart = 0, + }; + + BetaTextEditorCodeExecutionStrReplaceResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockTest.cs index 09d25d3ef..2c84a8891 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockTest.cs @@ -119,4 +119,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextEditorCodeExecutionStrReplaceResultBlock + { + Lines = ["string"], + NewLines = 0, + NewStart = 0, + OldLines = 0, + OldStart = 0, + }; + + BetaTextEditorCodeExecutionStrReplaceResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParamTest.cs index ff014dc5f..af9026ee0 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParamTest.cs @@ -198,6 +198,26 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextEditorCodeExecutionToolResultBlockParam + { + Content = new BetaTextEditorCodeExecutionToolResultErrorParam() + { + ErrorCode = + BetaTextEditorCodeExecutionToolResultErrorParamErrorCode.InvalidToolInput, + ErrorMessage = "error_message", + }, + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaTextEditorCodeExecutionToolResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaTextEditorCodeExecutionToolResultBlockParamContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockTest.cs index 73fb53a2b..ef9655fab 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockTest.cs @@ -108,6 +108,24 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextEditorCodeExecutionToolResultBlock + { + Content = new BetaTextEditorCodeExecutionToolResultError() + { + ErrorCode = BetaTextEditorCodeExecutionToolResultErrorErrorCode.InvalidToolInput, + ErrorMessage = "error_message", + }, + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + }; + + BetaTextEditorCodeExecutionToolResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaTextEditorCodeExecutionToolResultBlockContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorParamTest.cs index 19e878d8b..7db56116d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorParamTest.cs @@ -143,6 +143,20 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextEditorCodeExecutionToolResultErrorParam + { + ErrorCode = BetaTextEditorCodeExecutionToolResultErrorParamErrorCode.InvalidToolInput, + ErrorMessage = "error_message", + }; + + BetaTextEditorCodeExecutionToolResultErrorParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaTextEditorCodeExecutionToolResultErrorParamErrorCodeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorTest.cs index 29905aafe..2b20fc79c 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorTest.cs @@ -85,6 +85,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextEditorCodeExecutionToolResultError + { + ErrorCode = BetaTextEditorCodeExecutionToolResultErrorErrorCode.InvalidToolInput, + ErrorMessage = "error_message", + }; + + BetaTextEditorCodeExecutionToolResultError copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaTextEditorCodeExecutionToolResultErrorErrorCodeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockParamTest.cs index b4163845f..7d6b32fca 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockParamTest.cs @@ -177,6 +177,23 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextEditorCodeExecutionViewResultBlockParam + { + Content = "content", + FileType = BetaTextEditorCodeExecutionViewResultBlockParamFileType.Text, + NumLines = 0, + StartLine = 0, + TotalLines = 0, + }; + + BetaTextEditorCodeExecutionViewResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaTextEditorCodeExecutionViewResultBlockParamFileTypeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockTest.cs index 2f63adc3f..13a61d56b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockTest.cs @@ -107,6 +107,23 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTextEditorCodeExecutionViewResultBlock + { + Content = "content", + FileType = FileType.Text, + NumLines = 0, + StartLine = 0, + TotalLines = 0, + }; + + BetaTextEditorCodeExecutionViewResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } public class FileTypeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingBlockParamTest.cs index 6934eefae..1b607e06e 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingBlockParamTest.cs @@ -62,4 +62,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaThinkingBlockParam { Signature = "signature", Thinking = "thinking" }; + + BetaThinkingBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingBlockTest.cs index b92455b28..732584368 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingBlockTest.cs @@ -62,4 +62,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaThinkingBlock { Signature = "signature", Thinking = "thinking" }; + + BetaThinkingBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigDisabledTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigDisabledTest.cs index 1d4278eac..38cd58034 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigDisabledTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigDisabledTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaThinkingConfigDisabled { }; + + BetaThinkingConfigDisabled copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigEnabledTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigEnabledTest.cs index 8f7629b96..5b7d375ef 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigEnabledTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigEnabledTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaThinkingConfigEnabled { BudgetTokens = 1024 }; + + BetaThinkingConfigEnabled copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingDeltaTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingDeltaTest.cs index f0eb0f861..487b6465f 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingDeltaTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaThinkingDelta { Thinking = "thinking" }; + + BetaThinkingDelta copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingTurnsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingTurnsTest.cs index 05e79e572..99e52b8ac 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingTurnsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingTurnsTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaThinkingTurns { Value = 1 }; + + BetaThinkingTurns copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolBash20241022Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolBash20241022Test.cs index f1f650d00..fbb04e32a 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolBash20241022Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolBash20241022Test.cs @@ -332,6 +332,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolBash20241022 + { + AllowedCallers = [BetaToolBash20241022AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + }; + + BetaToolBash20241022 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolBash20241022AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolBash20250124Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolBash20250124Test.cs index 9738a973c..ebe588950 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolBash20250124Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolBash20250124Test.cs @@ -332,6 +332,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolBash20250124 + { + AllowedCallers = [BetaToolBash20250124AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + }; + + BetaToolBash20250124 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolBash20250124AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceAnyTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceAnyTest.cs index 32705bf7e..43bc00890 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceAnyTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceAnyTest.cs @@ -100,4 +100,14 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolChoiceAny { DisableParallelToolUse = true }; + + BetaToolChoiceAny copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceAutoTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceAutoTest.cs index 9d8c699ec..b14948962 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceAutoTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceAutoTest.cs @@ -100,4 +100,14 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolChoiceAuto { DisableParallelToolUse = true }; + + BetaToolChoiceAuto copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceNoneTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceNoneTest.cs index 806082dc6..4463cfb9d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceNoneTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceNoneTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolChoiceNone { }; + + BetaToolChoiceNone copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceToolTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceToolTest.cs index f29ac25a7..871a4c84d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceToolTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolChoiceToolTest.cs @@ -108,4 +108,14 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolChoiceTool { Name = "name", DisableParallelToolUse = true }; + + BetaToolChoiceTool copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20241022Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20241022Test.cs index 25fed043b..0fc3695ab 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20241022Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20241022Test.cs @@ -388,6 +388,32 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolComputerUse20241022 + { + DisplayHeightPx = 1, + DisplayWidthPx = 1, + AllowedCallers = [BetaToolComputerUse20241022AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + DisplayNumber = 0, + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + }; + + BetaToolComputerUse20241022 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolComputerUse20241022AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20250124Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20250124Test.cs index c94da2157..c71bc030e 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20250124Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20250124Test.cs @@ -388,6 +388,32 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolComputerUse20250124 + { + DisplayHeightPx = 1, + DisplayWidthPx = 1, + AllowedCallers = [BetaToolComputerUse20250124AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + DisplayNumber = 0, + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + }; + + BetaToolComputerUse20250124 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolComputerUse20250124AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20251124Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20251124Test.cs index ac9eda937..f65d04348 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20251124Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolComputerUse20251124Test.cs @@ -406,6 +406,33 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolComputerUse20251124 + { + DisplayHeightPx = 1, + DisplayWidthPx = 1, + AllowedCallers = [BetaToolComputerUse20251124AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + DisplayNumber = 0, + EnableZoom = true, + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + }; + + BetaToolComputerUse20251124 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolComputerUse20251124AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolReferenceBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolReferenceBlockParamTest.cs index 851694d8b..c964e7fab 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolReferenceBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolReferenceBlockParamTest.cs @@ -122,4 +122,18 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolReferenceBlockParam + { + ToolName = "tool_name", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaToolReferenceBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolReferenceBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolReferenceBlockTest.cs index 694adb24a..0cc1cbd05 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolReferenceBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolReferenceBlockTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolReferenceBlock { ToolName = "tool_name" }; + + BetaToolReferenceBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolResultBlockParamTest.cs index 59489f58f..c261b3b0e 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolResultBlockParamTest.cs @@ -214,6 +214,22 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolResultBlockParam + { + ToolUseID = "tool_use_id", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Content = "string", + IsError = true, + }; + + BetaToolResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolResultBlockParamContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolBm25_20251119Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolBm25_20251119Test.cs index df9365284..6318ca18d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolBm25_20251119Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolBm25_20251119Test.cs @@ -250,6 +250,23 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolSearchToolBm25_20251119 + { + Type = BetaToolSearchToolBm25_20251119Type.ToolSearchToolBm25_20251119, + AllowedCallers = [BetaToolSearchToolBm25_20251119AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + Strict = true, + }; + + BetaToolSearchToolBm25_20251119 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolSearchToolBm25_20251119TypeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolRegex20251119Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolRegex20251119Test.cs index c356fa355..7a27a2d9a 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolRegex20251119Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolRegex20251119Test.cs @@ -250,6 +250,23 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolSearchToolRegex20251119 + { + Type = BetaToolSearchToolRegex20251119Type.ToolSearchToolRegex20251119, + AllowedCallers = [BetaToolSearchToolRegex20251119AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + Strict = true, + }; + + BetaToolSearchToolRegex20251119 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolSearchToolRegex20251119TypeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultBlockParamTest.cs index 998195c63..691cfca91 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultBlockParamTest.cs @@ -162,6 +162,23 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolSearchToolResultBlockParam + { + Content = new BetaToolSearchToolResultErrorParam( + BetaToolSearchToolResultErrorParamErrorCode.InvalidToolInput + ), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaToolSearchToolResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolSearchToolResultBlockParamContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultBlockTest.cs index d558b7945..d81a2bdb3 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultBlockTest.cs @@ -102,6 +102,24 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolSearchToolResultBlock + { + Content = new BetaToolSearchToolResultError() + { + ErrorCode = BetaToolSearchToolResultErrorErrorCode.InvalidToolInput, + ErrorMessage = "error_message", + }, + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + }; + + BetaToolSearchToolResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolSearchToolResultBlockContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultErrorParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultErrorParamTest.cs index 1d3526ca4..1eef4eaa0 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultErrorParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultErrorParamTest.cs @@ -77,6 +77,19 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolSearchToolResultErrorParam + { + ErrorCode = BetaToolSearchToolResultErrorParamErrorCode.InvalidToolInput, + }; + + BetaToolSearchToolResultErrorParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolSearchToolResultErrorParamErrorCodeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultErrorTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultErrorTest.cs index e1c275a87..2d3615398 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolResultErrorTest.cs @@ -85,6 +85,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolSearchToolResultError + { + ErrorCode = BetaToolSearchToolResultErrorErrorCode.InvalidToolInput, + ErrorMessage = "error_message", + }; + + BetaToolSearchToolResultError copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolSearchToolResultErrorErrorCodeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockParamTest.cs index 0090ecfb1..647010049 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockParamTest.cs @@ -125,4 +125,24 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolSearchToolSearchResultBlockParam + { + ToolReferences = + [ + new() + { + ToolName = "tool_name", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }, + ], + }; + + BetaToolSearchToolSearchResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockTest.cs index 3e9dc958e..9c8eaaebc 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockTest.cs @@ -71,4 +71,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolSearchToolSearchResultBlock { ToolReferences = [new("tool_name")] }; + + BetaToolSearchToolSearchResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTest.cs index 7e1def19b..5384a8809 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTest.cs @@ -507,6 +507,41 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaTool + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + AllowedCallers = [BetaToolAllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + Description = "Get the current weather in a given location", + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + Type = BetaToolType.Custom, + }; + + BetaTool copied = new(model); + + Assert.Equal(model, copied); + } } public class InputSchemaTest : TestBase @@ -669,6 +704,24 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new InputSchema + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }; + + InputSchema copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolAllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20241022Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20241022Test.cs index c3755d3b7..e5d6c662a 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20241022Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20241022Test.cs @@ -332,6 +332,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolTextEditor20241022 + { + AllowedCallers = [BetaToolTextEditor20241022AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + }; + + BetaToolTextEditor20241022 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolTextEditor20241022AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250124Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250124Test.cs index 7d3af5bf9..b87b88aa7 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250124Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250124Test.cs @@ -332,6 +332,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolTextEditor20250124 + { + AllowedCallers = [BetaToolTextEditor20250124AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + }; + + BetaToolTextEditor20250124 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolTextEditor20250124AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250429Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250429Test.cs index 6d8524a6b..1b6097cb9 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250429Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250429Test.cs @@ -332,6 +332,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolTextEditor20250429 + { + AllowedCallers = [BetaToolTextEditor20250429AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + Strict = true, + }; + + BetaToolTextEditor20250429 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolTextEditor20250429AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250728Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250728Test.cs index 882daa41d..c80cc0026 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250728Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTextEditor20250728Test.cs @@ -356,6 +356,30 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolTextEditor20250728 + { + AllowedCallers = [BetaToolTextEditor20250728AllowedCaller.Direct], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + InputExamples = + [ + new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + ], + MaxCharacters = 1, + Strict = true, + }; + + BetaToolTextEditor20250728 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolTextEditor20250728AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUseBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUseBlockParamTest.cs index 6f06491cb..9c6fc55d8 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUseBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUseBlockParamTest.cs @@ -283,6 +283,26 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolUseBlockParam + { + ID = "id", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = "x", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Caller = new BetaDirectCaller(), + }; + + BetaToolUseBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolUseBlockParamCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUseBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUseBlockTest.cs index 119268639..5352436dd 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUseBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUseBlockTest.cs @@ -197,6 +197,25 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolUseBlock + { + ID = "id", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = "x", + Caller = new BetaDirectCaller(), + }; + + BetaToolUseBlock copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaToolUseBlockCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUsesKeepTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUsesKeepTest.cs index bd15bfb06..b8e9ec571 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUsesKeepTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUsesKeepTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolUsesKeep { Value = 0 }; + + BetaToolUsesKeep copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUsesTriggerTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUsesTriggerTest.cs index 90904aab2..2ee4df0db 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUsesTriggerTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUsesTriggerTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaToolUsesTrigger { Value = 1 }; + + BetaToolUsesTrigger copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaUrlImageSourceTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaUrlImageSourceTest.cs index 79d6a1bde..f9ac6b2cb 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaUrlImageSourceTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaUrlImageSourceTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaUrlImageSource { Url = "url" }; + + BetaUrlImageSource copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaUrlPdfSourceTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaUrlPdfSourceTest.cs index e68c758ca..411f42cf7 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaUrlPdfSourceTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaUrlPdfSourceTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaUrlPdfSource { Url = "url" }; + + BetaUrlPdfSource copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaUsageTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaUsageTest.cs index ca4926ecb..8d2bc85ce 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaUsageTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaUsageTest.cs @@ -128,6 +128,25 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, + ServiceTier = BetaUsageServiceTier.Standard, + }; + + BetaUsage copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaUsageServiceTierTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchBlockParamTest.cs index 918887d09..3ca7e4ad6 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchBlockParamTest.cs @@ -210,4 +210,26 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebFetchBlockParam + { + Content = new() + { + Source = new BetaBase64PdfSource("U3RhaW5sZXNzIHJvY2tz"), + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = new() { Enabled = true }, + Context = "x", + Title = "x", + }, + Url = "url", + RetrievedAt = "retrieved_at", + }; + + BetaWebFetchBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchBlockTest.cs index 233b30291..2204af084 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchBlockTest.cs @@ -116,4 +116,24 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebFetchBlock + { + Content = new() + { + Citations = new(true), + Source = new BetaBase64PdfSource("U3RhaW5sZXNzIHJvY2tz"), + Title = "title", + }, + RetrievedAt = "retrieved_at", + Url = "url", + }; + + BetaWebFetchBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchTool20250910Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchTool20250910Test.cs index 6de5efb75..627f446ff 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchTool20250910Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchTool20250910Test.cs @@ -348,6 +348,27 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebFetchTool20250910 + { + AllowedCallers = [BetaWebFetchTool20250910AllowedCaller.Direct], + AllowedDomains = ["string"], + BlockedDomains = ["string"], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = new() { Enabled = true }, + DeferLoading = true, + MaxContentTokens = 1, + MaxUses = 1, + Strict = true, + }; + + BetaWebFetchTool20250910 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaWebFetchTool20250910AllowedCallerTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultBlockParamTest.cs index aa1af227a..88c3fd265 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultBlockParamTest.cs @@ -162,6 +162,23 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebFetchToolResultBlockParam + { + Content = new BetaWebFetchToolResultErrorBlockParam( + BetaWebFetchToolResultErrorCode.InvalidToolInput + ), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaWebFetchToolResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaWebFetchToolResultBlockParamContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultBlockTest.cs index e9d1442c7..760c2ce9c 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultBlockTest.cs @@ -90,6 +90,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebFetchToolResultBlock + { + Content = new BetaWebFetchToolResultErrorBlock( + BetaWebFetchToolResultErrorCode.InvalidToolInput + ), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + }; + + BetaWebFetchToolResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaWebFetchToolResultBlockContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockParamTest.cs index fd183342a..501d30e8b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockParamTest.cs @@ -72,4 +72,17 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebFetchToolResultErrorBlockParam + { + ErrorCode = BetaWebFetchToolResultErrorCode.InvalidToolInput, + }; + + BetaWebFetchToolResultErrorBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockTest.cs index 1e0ac1567..a20df63b4 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockTest.cs @@ -72,4 +72,17 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebFetchToolResultErrorBlock + { + ErrorCode = BetaWebFetchToolResultErrorCode.InvalidToolInput, + }; + + BetaWebFetchToolResultErrorBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchResultBlockParamTest.cs index fe725f4df..b58c0f58b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchResultBlockParamTest.cs @@ -152,4 +152,20 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebSearchResultBlockParam + { + EncryptedContent = "encrypted_content", + Title = "title", + Url = "url", + PageAge = "page_age", + }; + + BetaWebSearchResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchResultBlockTest.cs index bd560240f..6b634592b 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchResultBlockTest.cs @@ -94,4 +94,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebSearchResultBlock + { + EncryptedContent = "encrypted_content", + PageAge = "page_age", + Title = "title", + Url = "url", + }; + + BetaWebSearchResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchTool20250305Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchTool20250305Test.cs index 1c07b3d4a..db7a4244a 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchTool20250305Test.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchTool20250305Test.cs @@ -390,6 +390,32 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebSearchTool20250305 + { + AllowedCallers = [BetaWebSearchTool20250305AllowedCaller.Direct], + AllowedDomains = ["string"], + BlockedDomains = ["string"], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + DeferLoading = true, + MaxUses = 1, + Strict = true, + UserLocation = new() + { + City = "New York", + Country = "US", + Region = "California", + Timezone = "America/New_York", + }, + }; + + BetaWebSearchTool20250305 copied = new(model); + + Assert.Equal(model, copied); + } } public class BetaWebSearchTool20250305AllowedCallerTest : TestBase @@ -594,4 +620,20 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new UserLocation + { + City = "New York", + Country = "US", + Region = "California", + Timezone = "America/New_York", + }; + + UserLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolRequestErrorTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolRequestErrorTest.cs index 3447f61d7..012df9b3e 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolRequestErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolRequestErrorTest.cs @@ -76,4 +76,17 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebSearchToolRequestError + { + ErrorCode = BetaWebSearchToolResultErrorCode.InvalidToolInput, + }; + + BetaWebSearchToolRequestError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultBlockParamTest.cs index e7707fd4a..d797b031e 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultBlockParamTest.cs @@ -240,4 +240,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebSearchToolResultBlockParam + { + Content = new( + [ + new BetaWebSearchResultBlockParam() + { + EncryptedContent = "encrypted_content", + Title = "title", + Url = "url", + PageAge = "page_age", + }, + ] + ), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaWebSearchToolResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultBlockTest.cs index 1cbed1764..72baf1125 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultBlockTest.cs @@ -90,4 +90,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebSearchToolResultBlock + { + Content = new BetaWebSearchToolResultError( + BetaWebSearchToolResultErrorCode.InvalidToolInput + ), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + }; + + BetaWebSearchToolResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultErrorTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultErrorTest.cs index bb479368b..10a9141a0 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultErrorTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaWebSearchToolResultErrorTest.cs @@ -76,4 +76,17 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaWebSearchToolResultError + { + ErrorCode = BetaWebSearchToolResultErrorCode.InvalidToolInput, + }; + + BetaWebSearchToolResultError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Models/BetaModelInfoTest.cs b/src/Anthropic.Tests/Models/Beta/Models/BetaModelInfoTest.cs index d2b969634..409a057a8 100644 --- a/src/Anthropic.Tests/Models/Beta/Models/BetaModelInfoTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Models/BetaModelInfoTest.cs @@ -87,4 +87,19 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaModelInfo + { + ID = "claude-sonnet-4-20250514", + CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), + DisplayName = "Claude Sonnet 4", + }; + + BetaModelInfo copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Models/ModelListPageResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Models/ModelListPageResponseTest.cs index b374eb2a7..08dfc014d 100644 --- a/src/Anthropic.Tests/Models/Beta/Models/ModelListPageResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Models/ModelListPageResponseTest.cs @@ -148,4 +148,28 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ModelListPageResponse + { + Data = + [ + new() + { + ID = "claude-sonnet-4-20250514", + CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), + DisplayName = "Claude Sonnet 4", + }, + ], + FirstID = "first_id", + HasMore = true, + LastID = "last_id", + }; + + ModelListPageResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillCreateResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillCreateResponseTest.cs index 094191027..fe3f5bddc 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillCreateResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillCreateResponseTest.cs @@ -114,4 +114,23 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new SkillCreateResponse + { + ID = "skill_01JAbcdefghijklmnopqrstuvw", + CreatedAt = "2024-10-30T23:58:27.427722Z", + DisplayTitle = "My Custom Skill", + LatestVersion = "1759178010641129", + Source = "custom", + Type = "type", + UpdatedAt = "2024-10-30T23:58:27.427722Z", + }; + + SkillCreateResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteResponseTest.cs index e036ac804..c5d3619c8 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteResponseTest.cs @@ -74,4 +74,18 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new SkillDeleteResponse + { + ID = "skill_01JAbcdefghijklmnopqrstuvw", + Type = "type", + }; + + SkillDeleteResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillListPageResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillListPageResponseTest.cs index 7e5c6dac3..537bd5ffa 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillListPageResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillListPageResponseTest.cs @@ -163,4 +163,31 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new SkillListPageResponse + { + Data = + [ + new() + { + ID = "skill_01JAbcdefghijklmnopqrstuvw", + CreatedAt = "2024-10-30T23:58:27.427722Z", + DisplayTitle = "My Custom Skill", + LatestVersion = "1759178010641129", + Source = "custom", + Type = "type", + UpdatedAt = "2024-10-30T23:58:27.427722Z", + }, + ], + HasMore = true, + NextPage = "page_MjAyNS0wNS0xNFQwMDowMDowMFo=", + }; + + SkillListPageResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillListResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillListResponseTest.cs index bc467e936..fde71990a 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillListResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillListResponseTest.cs @@ -114,4 +114,23 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new SkillListResponse + { + ID = "skill_01JAbcdefghijklmnopqrstuvw", + CreatedAt = "2024-10-30T23:58:27.427722Z", + DisplayTitle = "My Custom Skill", + LatestVersion = "1759178010641129", + Source = "custom", + Type = "type", + UpdatedAt = "2024-10-30T23:58:27.427722Z", + }; + + SkillListResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveResponseTest.cs index 0d0f5ccbb..c747e46fb 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveResponseTest.cs @@ -114,4 +114,23 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new SkillRetrieveResponse + { + ID = "skill_01JAbcdefghijklmnopqrstuvw", + CreatedAt = "2024-10-30T23:58:27.427722Z", + DisplayTitle = "My Custom Skill", + LatestVersion = "1759178010641129", + Source = "custom", + Type = "type", + UpdatedAt = "2024-10-30T23:58:27.427722Z", + }; + + SkillRetrieveResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionCreateResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionCreateResponseTest.cs index e51f56b4b..e88cd0ed0 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionCreateResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionCreateResponseTest.cs @@ -122,4 +122,24 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new VersionCreateResponse + { + ID = "skillver_01JAbcdefghijklmnopqrstuvw", + CreatedAt = "2024-10-30T23:58:27.427722Z", + Description = "A custom skill for doing something useful", + Directory = "my-skill", + Name = "my-skill", + SkillID = "skill_01JAbcdefghijklmnopqrstuvw", + Type = "type", + Version = "1759178010641129", + }; + + VersionCreateResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteResponseTest.cs index c6820f56a..7464bc773 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteResponseTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new VersionDeleteResponse { ID = "1759178010641129", Type = "type" }; + + VersionDeleteResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListPageResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListPageResponseTest.cs index 952758e44..772f563c2 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListPageResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListPageResponseTest.cs @@ -169,4 +169,32 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new VersionListPageResponse + { + Data = + [ + new() + { + ID = "skillver_01JAbcdefghijklmnopqrstuvw", + CreatedAt = "2024-10-30T23:58:27.427722Z", + Description = "A custom skill for doing something useful", + Directory = "my-skill", + Name = "my-skill", + SkillID = "skill_01JAbcdefghijklmnopqrstuvw", + Type = "type", + Version = "1759178010641129", + }, + ], + HasMore = true, + NextPage = "page_MjAyNS0wNS0xNFQwMDowMDowMFo=", + }; + + VersionListPageResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListResponseTest.cs index bde446913..66bca8da9 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListResponseTest.cs @@ -122,4 +122,24 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new VersionListResponse + { + ID = "skillver_01JAbcdefghijklmnopqrstuvw", + CreatedAt = "2024-10-30T23:58:27.427722Z", + Description = "A custom skill for doing something useful", + Directory = "my-skill", + Name = "my-skill", + SkillID = "skill_01JAbcdefghijklmnopqrstuvw", + Type = "type", + Version = "1759178010641129", + }; + + VersionListResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveResponseTest.cs index f01e0ac07..3983c7b9d 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveResponseTest.cs @@ -122,4 +122,24 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new VersionRetrieveResponse + { + ID = "skillver_01JAbcdefghijklmnopqrstuvw", + CreatedAt = "2024-10-30T23:58:27.427722Z", + Description = "A custom skill for doing something useful", + Directory = "my-skill", + Name = "my-skill", + SkillID = "skill_01JAbcdefghijklmnopqrstuvw", + Type = "type", + Version = "1759178010641129", + }; + + VersionRetrieveResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/BillingErrorTest.cs b/src/Anthropic.Tests/Models/BillingErrorTest.cs index 8610b4f56..8fc159155 100644 --- a/src/Anthropic.Tests/Models/BillingErrorTest.cs +++ b/src/Anthropic.Tests/Models/BillingErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BillingError { Message = "message" }; + + BillingError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/ErrorResponseTest.cs b/src/Anthropic.Tests/Models/ErrorResponseTest.cs index 36178c8cd..88538a03f 100644 --- a/src/Anthropic.Tests/Models/ErrorResponseTest.cs +++ b/src/Anthropic.Tests/Models/ErrorResponseTest.cs @@ -78,4 +78,18 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ErrorResponse + { + Error = new InvalidRequestError("message"), + RequestID = "request_id", + }; + + ErrorResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/GatewayTimeoutErrorTest.cs b/src/Anthropic.Tests/Models/GatewayTimeoutErrorTest.cs index f719ddee7..feff72828 100644 --- a/src/Anthropic.Tests/Models/GatewayTimeoutErrorTest.cs +++ b/src/Anthropic.Tests/Models/GatewayTimeoutErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new GatewayTimeoutError { Message = "message" }; + + GatewayTimeoutError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/InvalidRequestErrorTest.cs b/src/Anthropic.Tests/Models/InvalidRequestErrorTest.cs index 85e4fc095..c6ce75513 100644 --- a/src/Anthropic.Tests/Models/InvalidRequestErrorTest.cs +++ b/src/Anthropic.Tests/Models/InvalidRequestErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new InvalidRequestError { Message = "message" }; + + InvalidRequestError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Base64ImageSourceTest.cs b/src/Anthropic.Tests/Models/Messages/Base64ImageSourceTest.cs index c104642ba..48119b182 100644 --- a/src/Anthropic.Tests/Models/Messages/Base64ImageSourceTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Base64ImageSourceTest.cs @@ -79,6 +79,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Base64ImageSource + { + Data = "U3RhaW5sZXNzIHJvY2tz", + MediaType = MediaType.ImageJpeg, + }; + + Base64ImageSource copied = new(model); + + Assert.Equal(model, copied); + } } public class MediaTypeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/Base64PdfSourceTest.cs b/src/Anthropic.Tests/Models/Messages/Base64PdfSourceTest.cs index c01641952..cada7ad5c 100644 --- a/src/Anthropic.Tests/Models/Messages/Base64PdfSourceTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Base64PdfSourceTest.cs @@ -62,4 +62,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Base64PdfSource { Data = "U3RhaW5sZXNzIHJvY2tz" }; + + Base64PdfSource copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs index b1ccf8470..0fbe78e9e 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs @@ -688,6 +688,73 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Request + { + CustomID = "my-custom-id-1", + Params = new() + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeSonnet4_5_20250929, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }, + }; + + Request copied = new(model); + + Assert.Equal(model, copied); + } } public class ParamsTest : TestBase @@ -1238,6 +1305,69 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Params + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeSonnet4_5_20250929, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }; + + Params copied = new(model); + + Assert.Equal(model, copied); + } } public class ServiceTierTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/Batches/BatchListPageResponseTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/BatchListPageResponseTest.cs index ad0d5d94f..f18d4e41f 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/BatchListPageResponseTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/BatchListPageResponseTest.cs @@ -232,4 +232,42 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BatchListPageResponse + { + Data = + [ + new() + { + ID = "msgbatch_013Zva2CMHLNnXjNJJKqJ2EF", + ArchivedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + CancelInitiatedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + CreatedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + EndedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + ExpiresAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + ProcessingStatus = ProcessingStatus.InProgress, + RequestCounts = new() + { + Canceled = 10, + Errored = 30, + Expired = 10, + Processing = 100, + Succeeded = 50, + }, + ResultsUrl = + "https://api.anthropic.com/v1/messages/batches/msgbatch_013Zva2CMHLNnXjNJJKqJ2EF/results", + }, + ], + FirstID = "first_id", + HasMore = true, + LastID = "last_id", + }; + + BatchListPageResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/DeletedMessageBatchTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/DeletedMessageBatchTest.cs index 5811e9957..f1a97f09b 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/DeletedMessageBatchTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/DeletedMessageBatchTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new DeletedMessageBatch { ID = "msgbatch_013Zva2CMHLNnXjNJJKqJ2EF" }; + + DeletedMessageBatch copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchCanceledResultTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchCanceledResultTest.cs index 0c430b8e4..b9d304060 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchCanceledResultTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchCanceledResultTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new MessageBatchCanceledResult { }; + + MessageBatchCanceledResult copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchErroredResultTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchErroredResultTest.cs index f74d8e4ca..112c85539 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchErroredResultTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchErroredResultTest.cs @@ -79,4 +79,17 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new MessageBatchErroredResult + { + Error = new() { Error = new InvalidRequestError("message"), RequestID = "request_id" }, + }; + + MessageBatchErroredResult copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchExpiredResultTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchExpiredResultTest.cs index 4b9460d1b..50d492c70 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchExpiredResultTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchExpiredResultTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new MessageBatchExpiredResult { }; + + MessageBatchExpiredResult copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchIndividualResponseTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchIndividualResponseTest.cs index c67456dcd..1023651ce 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchIndividualResponseTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchIndividualResponseTest.cs @@ -321,4 +321,59 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new MessageBatchIndividualResponse + { + CustomID = "my-custom-id-1", + Result = new MessageBatchSucceededResult( + new Message() + { + ID = "msg_013Zva2CMHLNnXjNJJKqJ2EF", + Content = + [ + new TextBlock() + { + Citations = + [ + new CitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "Hi! My name is Claude.", + }, + ], + Model = Model.ClaudeSonnet4_5_20250929, + StopReason = StopReason.EndTurn, + StopSequence = null, + Usage = new() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new(0), + ServiceTier = UsageServiceTier.Standard, + }, + } + ), + }; + + MessageBatchIndividualResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchRequestCountsTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchRequestCountsTest.cs index c0392f755..b4f9b6d4a 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchRequestCountsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchRequestCountsTest.cs @@ -98,4 +98,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new MessageBatchRequestCounts + { + Canceled = 10, + Errored = 30, + Expired = 10, + Processing = 100, + Succeeded = 50, + }; + + MessageBatchRequestCounts copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchSucceededResultTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchSucceededResultTest.cs index 8b08ed593..d73d1361d 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchSucceededResultTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchSucceededResultTest.cs @@ -297,4 +297,56 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new MessageBatchSucceededResult + { + Message = new() + { + ID = "msg_013Zva2CMHLNnXjNJJKqJ2EF", + Content = + [ + new TextBlock() + { + Citations = + [ + new CitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "Hi! My name is Claude.", + }, + ], + Model = Model.ClaudeSonnet4_5_20250929, + StopReason = StopReason.EndTurn, + StopSequence = null, + Usage = new() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new(0), + ServiceTier = UsageServiceTier.Standard, + }, + }, + }; + + MessageBatchSucceededResult copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchTest.cs index 1533b2094..346a14a00 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchTest.cs @@ -188,6 +188,35 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new MessageBatch + { + ID = "msgbatch_013Zva2CMHLNnXjNJJKqJ2EF", + ArchivedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + CancelInitiatedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + CreatedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + EndedAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + ExpiresAt = DateTimeOffset.Parse("2024-08-20T18:37:24.100435Z"), + ProcessingStatus = ProcessingStatus.InProgress, + RequestCounts = new() + { + Canceled = 10, + Errored = 30, + Expired = 10, + Processing = 100, + Succeeded = 50, + }, + ResultsUrl = + "https://api.anthropic.com/v1/messages/batches/msgbatch_013Zva2CMHLNnXjNJJKqJ2EF/results", + }; + + MessageBatch copied = new(model); + + Assert.Equal(model, copied); + } } public class ProcessingStatusTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/CacheControlEphemeralTest.cs b/src/Anthropic.Tests/Models/Messages/CacheControlEphemeralTest.cs index 02e92494f..17d21b83e 100644 --- a/src/Anthropic.Tests/Models/Messages/CacheControlEphemeralTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CacheControlEphemeralTest.cs @@ -101,6 +101,16 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CacheControlEphemeral { Ttl = Ttl.Ttl5m }; + + CacheControlEphemeral copied = new(model); + + Assert.Equal(model, copied); + } } public class TtlTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/CacheCreationTest.cs b/src/Anthropic.Tests/Models/Messages/CacheCreationTest.cs index 1653dc0e1..0d27c54b4 100644 --- a/src/Anthropic.Tests/Models/Messages/CacheCreationTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CacheCreationTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CacheCreation { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }; + + CacheCreation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationCharLocationParamTest.cs b/src/Anthropic.Tests/Models/Messages/CitationCharLocationParamTest.cs index c0be0ec59..9a916c3df 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationCharLocationParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationCharLocationParamTest.cs @@ -102,4 +102,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationCharLocationParam + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }; + + CitationCharLocationParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationCharLocationTest.cs b/src/Anthropic.Tests/Models/Messages/CitationCharLocationTest.cs index 024ddab9f..c13169867 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationCharLocationTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationCharLocationTest.cs @@ -110,4 +110,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationCharLocation + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }; + + CitationCharLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationContentBlockLocationParamTest.cs b/src/Anthropic.Tests/Models/Messages/CitationContentBlockLocationParamTest.cs index 2f6502620..bb0945c55 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationContentBlockLocationParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationContentBlockLocationParamTest.cs @@ -102,4 +102,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationContentBlockLocationParam + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndBlockIndex = 0, + StartBlockIndex = 0, + }; + + CitationContentBlockLocationParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationContentBlockLocationTest.cs b/src/Anthropic.Tests/Models/Messages/CitationContentBlockLocationTest.cs index fd5737e74..dda7a0c26 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationContentBlockLocationTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationContentBlockLocationTest.cs @@ -110,4 +110,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationContentBlockLocation + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndBlockIndex = 0, + FileID = "file_id", + StartBlockIndex = 0, + }; + + CitationContentBlockLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationPageLocationParamTest.cs b/src/Anthropic.Tests/Models/Messages/CitationPageLocationParamTest.cs index ca442417d..d1700cffe 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationPageLocationParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationPageLocationParamTest.cs @@ -102,4 +102,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationPageLocationParam + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndPageNumber = 0, + StartPageNumber = 1, + }; + + CitationPageLocationParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationPageLocationTest.cs b/src/Anthropic.Tests/Models/Messages/CitationPageLocationTest.cs index 3237e95af..db0601699 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationPageLocationTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationPageLocationTest.cs @@ -110,4 +110,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationPageLocation + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndPageNumber = 0, + FileID = "file_id", + StartPageNumber = 1, + }; + + CitationPageLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationSearchResultLocationParamTest.cs b/src/Anthropic.Tests/Models/Messages/CitationSearchResultLocationParamTest.cs index a4e046ba5..9fc310815 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationSearchResultLocationParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationSearchResultLocationParamTest.cs @@ -110,4 +110,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationSearchResultLocationParam + { + CitedText = "cited_text", + EndBlockIndex = 0, + SearchResultIndex = 0, + Source = "source", + StartBlockIndex = 0, + Title = "title", + }; + + CitationSearchResultLocationParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationWebSearchResultLocationParamTest.cs b/src/Anthropic.Tests/Models/Messages/CitationWebSearchResultLocationParamTest.cs index 4f8ab66c2..e3538ef5b 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationWebSearchResultLocationParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationWebSearchResultLocationParamTest.cs @@ -94,4 +94,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationWebSearchResultLocationParam + { + CitedText = "cited_text", + EncryptedIndex = "encrypted_index", + Title = "x", + Url = "x", + }; + + CitationWebSearchResultLocationParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationsConfigParamTest.cs b/src/Anthropic.Tests/Models/Messages/CitationsConfigParamTest.cs index ded39a9f4..177ace363 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationsConfigParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationsConfigParamTest.cs @@ -96,4 +96,14 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationsConfigParam { Enabled = true }; + + CitationsConfigParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationsDeltaTest.cs b/src/Anthropic.Tests/Models/Messages/CitationsDeltaTest.cs index a8a98f06f..7160d42a5 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationsDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationsDeltaTest.cs @@ -118,6 +118,27 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationsDelta + { + Citation = new CitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + }; + + CitationsDelta copied = new(model); + + Assert.Equal(model, copied); + } } public class CitationTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/CitationsSearchResultLocationTest.cs b/src/Anthropic.Tests/Models/Messages/CitationsSearchResultLocationTest.cs index 86b533008..d0b11db14 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationsSearchResultLocationTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationsSearchResultLocationTest.cs @@ -110,4 +110,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationsSearchResultLocation + { + CitedText = "cited_text", + EndBlockIndex = 0, + SearchResultIndex = 0, + Source = "source", + StartBlockIndex = 0, + Title = "title", + }; + + CitationsSearchResultLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/CitationsWebSearchResultLocationTest.cs b/src/Anthropic.Tests/Models/Messages/CitationsWebSearchResultLocationTest.cs index 0baf20be8..b73317ad7 100644 --- a/src/Anthropic.Tests/Models/Messages/CitationsWebSearchResultLocationTest.cs +++ b/src/Anthropic.Tests/Models/Messages/CitationsWebSearchResultLocationTest.cs @@ -94,4 +94,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new CitationsWebSearchResultLocation + { + CitedText = "cited_text", + EncryptedIndex = "encrypted_index", + Title = "title", + Url = "url", + }; + + CitationsWebSearchResultLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ContentBlockSourceTest.cs b/src/Anthropic.Tests/Models/Messages/ContentBlockSourceTest.cs index c804b8d76..42b8ccef4 100644 --- a/src/Anthropic.Tests/Models/Messages/ContentBlockSourceTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ContentBlockSourceTest.cs @@ -58,6 +58,16 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ContentBlockSource { Content = "string" }; + + ContentBlockSource copied = new(model); + + Assert.Equal(model, copied); + } } public class ContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/DocumentBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/DocumentBlockParamTest.cs index 6148970d1..35ce27ea7 100644 --- a/src/Anthropic.Tests/Models/Messages/DocumentBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/DocumentBlockParamTest.cs @@ -164,6 +164,23 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new DocumentBlockParam + { + Source = new Base64PdfSource("U3RhaW5sZXNzIHJvY2tz"), + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = new() { Enabled = true }, + Context = "x", + Title = "x", + }; + + DocumentBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class SourceTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/ImageBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/ImageBlockParamTest.cs index 4198baf9a..04ff473cb 100644 --- a/src/Anthropic.Tests/Models/Messages/ImageBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ImageBlockParamTest.cs @@ -168,6 +168,24 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ImageBlockParam + { + Source = new Base64ImageSource() + { + Data = "U3RhaW5sZXNzIHJvY2tz", + MediaType = MediaType.ImageJpeg, + }, + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + ImageBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class ImageBlockParamSourceTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/InputJsonDeltaTest.cs b/src/Anthropic.Tests/Models/Messages/InputJsonDeltaTest.cs index 9e0b03e54..43d4427cc 100644 --- a/src/Anthropic.Tests/Models/Messages/InputJsonDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Messages/InputJsonDeltaTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new InputJsonDelta { PartialJson = "partial_json" }; + + InputJsonDelta copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/MessageDeltaUsageTest.cs b/src/Anthropic.Tests/Models/Messages/MessageDeltaUsageTest.cs index a79c477bf..af1281b72 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageDeltaUsageTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageDeltaUsageTest.cs @@ -98,4 +98,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new MessageDeltaUsage + { + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new(0), + }; + + MessageDeltaUsage copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/MessageParamTest.cs b/src/Anthropic.Tests/Models/Messages/MessageParamTest.cs index a5d9a416d..d92d8b82e 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageParamTest.cs @@ -59,6 +59,16 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new MessageParam { Content = "string", Role = Role.User }; + + MessageParam copied = new(model); + + Assert.Equal(model, copied); + } } public class MessageParamContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/MessageTest.cs b/src/Anthropic.Tests/Models/Messages/MessageTest.cs index 6c7d1f078..51e428f12 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageTest.cs @@ -280,4 +280,49 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Message + { + ID = "msg_013Zva2CMHLNnXjNJJKqJ2EF", + Content = + [ + new TextBlock() + { + Citations = + [ + new CitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "Hi! My name is Claude.", + }, + ], + Model = Model.ClaudeSonnet4_5_20250929, + StopReason = StopReason.EndTurn, + StopSequence = null, + Usage = new() + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new(0), + ServiceTier = UsageServiceTier.Standard, + }, + }; + + Message copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/MessageTokensCountTest.cs b/src/Anthropic.Tests/Models/Messages/MessageTokensCountTest.cs index 5320a290f..10933e597 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageTokensCountTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageTokensCountTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new MessageTokensCount { InputTokens = 2095 }; + + MessageTokensCount copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/MetadataTest.cs b/src/Anthropic.Tests/Models/Messages/MetadataTest.cs index 3dc4d1cc4..74a82472c 100644 --- a/src/Anthropic.Tests/Models/Messages/MetadataTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MetadataTest.cs @@ -85,4 +85,14 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Metadata { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }; + + Metadata copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/PlainTextSourceTest.cs b/src/Anthropic.Tests/Models/Messages/PlainTextSourceTest.cs index a1e497716..233c20634 100644 --- a/src/Anthropic.Tests/Models/Messages/PlainTextSourceTest.cs +++ b/src/Anthropic.Tests/Models/Messages/PlainTextSourceTest.cs @@ -62,4 +62,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new PlainTextSource { Data = "data" }; + + PlainTextSource copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/RawContentBlockDeltaEventTest.cs b/src/Anthropic.Tests/Models/Messages/RawContentBlockDeltaEventTest.cs index 8f88a02e7..b5b61f5c1 100644 --- a/src/Anthropic.Tests/Models/Messages/RawContentBlockDeltaEventTest.cs +++ b/src/Anthropic.Tests/Models/Messages/RawContentBlockDeltaEventTest.cs @@ -62,4 +62,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new RawContentBlockDeltaEvent { Delta = new TextDelta("text"), Index = 0 }; + + RawContentBlockDeltaEvent copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/RawContentBlockStartEventTest.cs b/src/Anthropic.Tests/Models/Messages/RawContentBlockStartEventTest.cs index 1f8480b7e..01cdc0059 100644 --- a/src/Anthropic.Tests/Models/Messages/RawContentBlockStartEventTest.cs +++ b/src/Anthropic.Tests/Models/Messages/RawContentBlockStartEventTest.cs @@ -169,6 +169,35 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new RawContentBlockStartEvent + { + ContentBlock = new TextBlock() + { + Citations = + [ + new CitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "text", + }, + Index = 0, + }; + + RawContentBlockStartEvent copied = new(model); + + Assert.Equal(model, copied); + } } public class RawContentBlockStartEventContentBlockTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/RawContentBlockStopEventTest.cs b/src/Anthropic.Tests/Models/Messages/RawContentBlockStopEventTest.cs index 937ddf3a7..2ecbbe168 100644 --- a/src/Anthropic.Tests/Models/Messages/RawContentBlockStopEventTest.cs +++ b/src/Anthropic.Tests/Models/Messages/RawContentBlockStopEventTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new RawContentBlockStopEvent { Index = 0 }; + + RawContentBlockStopEvent copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/RawMessageDeltaEventTest.cs b/src/Anthropic.Tests/Models/Messages/RawMessageDeltaEventTest.cs index 9717b4b06..59ae68759 100644 --- a/src/Anthropic.Tests/Models/Messages/RawMessageDeltaEventTest.cs +++ b/src/Anthropic.Tests/Models/Messages/RawMessageDeltaEventTest.cs @@ -128,6 +128,27 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new RawMessageDeltaEvent + { + Delta = new() { StopReason = StopReason.EndTurn, StopSequence = "stop_sequence" }, + Usage = new() + { + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new(0), + }, + }; + + RawMessageDeltaEvent copied = new(model); + + Assert.Equal(model, copied); + } } public class DeltaTest : TestBase @@ -178,4 +199,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Delta { StopReason = StopReason.EndTurn, StopSequence = "stop_sequence" }; + + Delta copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/RawMessageStartEventTest.cs b/src/Anthropic.Tests/Models/Messages/RawMessageStartEventTest.cs index 527865784..13ead7f43 100644 --- a/src/Anthropic.Tests/Models/Messages/RawMessageStartEventTest.cs +++ b/src/Anthropic.Tests/Models/Messages/RawMessageStartEventTest.cs @@ -296,4 +296,56 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new RawMessageStartEvent + { + Message = new() + { + ID = "msg_013Zva2CMHLNnXjNJJKqJ2EF", + Content = + [ + new TextBlock() + { + Citations = + [ + new CitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "Hi! My name is Claude.", + }, + ], + Model = Model.ClaudeSonnet4_5_20250929, + StopReason = StopReason.EndTurn, + StopSequence = null, + Usage = new() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new(0), + ServiceTier = UsageServiceTier.Standard, + }, + }, + }; + + RawMessageStartEvent copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/RawMessageStopEventTest.cs b/src/Anthropic.Tests/Models/Messages/RawMessageStopEventTest.cs index 98cab8558..f557be34e 100644 --- a/src/Anthropic.Tests/Models/Messages/RawMessageStopEventTest.cs +++ b/src/Anthropic.Tests/Models/Messages/RawMessageStopEventTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new RawMessageStopEvent { }; + + RawMessageStopEvent copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/RedactedThinkingBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/RedactedThinkingBlockParamTest.cs index bb251db8a..97ede5c82 100644 --- a/src/Anthropic.Tests/Models/Messages/RedactedThinkingBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/RedactedThinkingBlockParamTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new RedactedThinkingBlockParam { Data = "data" }; + + RedactedThinkingBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/RedactedThinkingBlockTest.cs b/src/Anthropic.Tests/Models/Messages/RedactedThinkingBlockTest.cs index 2d5f39017..a1962ace0 100644 --- a/src/Anthropic.Tests/Models/Messages/RedactedThinkingBlockTest.cs +++ b/src/Anthropic.Tests/Models/Messages/RedactedThinkingBlockTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new RedactedThinkingBlock { Data = "data" }; + + RedactedThinkingBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/SearchResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/SearchResultBlockParamTest.cs index 50d63a9f4..044943c7f 100644 --- a/src/Anthropic.Tests/Models/Messages/SearchResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/SearchResultBlockParamTest.cs @@ -489,4 +489,39 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new SearchResultBlockParam + { + Content = + [ + new() + { + Text = "x", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = + [ + new CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ], + Source = "source", + Title = "title", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = new() { Enabled = true }, + }; + + SearchResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ServerToolUsageTest.cs b/src/Anthropic.Tests/Models/Messages/ServerToolUsageTest.cs index b3eb44046..c762dd635 100644 --- a/src/Anthropic.Tests/Models/Messages/ServerToolUsageTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ServerToolUsageTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ServerToolUsage { WebSearchRequests = 0 }; + + ServerToolUsage copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ServerToolUseBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/ServerToolUseBlockParamTest.cs index a45471865..bbbff80d3 100644 --- a/src/Anthropic.Tests/Models/Messages/ServerToolUseBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ServerToolUseBlockParamTest.cs @@ -187,4 +187,22 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ServerToolUseBlockParam + { + ID = "srvtoolu_SQfNkl1n_JR_", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + ServerToolUseBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ServerToolUseBlockTest.cs b/src/Anthropic.Tests/Models/Messages/ServerToolUseBlockTest.cs index cca95d548..7b742f01d 100644 --- a/src/Anthropic.Tests/Models/Messages/ServerToolUseBlockTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ServerToolUseBlockTest.cs @@ -113,4 +113,21 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ServerToolUseBlock + { + ID = "srvtoolu_SQfNkl1n_JR_", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; + + ServerToolUseBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/SignatureDeltaTest.cs b/src/Anthropic.Tests/Models/Messages/SignatureDeltaTest.cs index 0765f35c1..cf237d6e2 100644 --- a/src/Anthropic.Tests/Models/Messages/SignatureDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Messages/SignatureDeltaTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new SignatureDelta { Signature = "signature" }; + + SignatureDelta copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/TextBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/TextBlockParamTest.cs index 86affa688..35a2d06fa 100644 --- a/src/Anthropic.Tests/Models/Messages/TextBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/TextBlockParamTest.cs @@ -207,4 +207,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new TextBlockParam + { + Text = "x", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Citations = + [ + new CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }; + + TextBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/TextBlockTest.cs b/src/Anthropic.Tests/Models/Messages/TextBlockTest.cs index 32fcce9e1..1199b3f97 100644 --- a/src/Anthropic.Tests/Models/Messages/TextBlockTest.cs +++ b/src/Anthropic.Tests/Models/Messages/TextBlockTest.cs @@ -152,4 +152,29 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new TextBlock + { + Citations = + [ + new CitationCharLocation() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "document_title", + EndCharIndex = 0, + FileID = "file_id", + StartCharIndex = 0, + }, + ], + Text = "text", + }; + + TextBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/TextDeltaTest.cs b/src/Anthropic.Tests/Models/Messages/TextDeltaTest.cs index ad67cb0c0..e11e31272 100644 --- a/src/Anthropic.Tests/Models/Messages/TextDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Messages/TextDeltaTest.cs @@ -55,4 +55,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new TextDelta { Text = "text" }; + + TextDelta copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ThinkingBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/ThinkingBlockParamTest.cs index 5c207ad1e..3a908b810 100644 --- a/src/Anthropic.Tests/Models/Messages/ThinkingBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ThinkingBlockParamTest.cs @@ -62,4 +62,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ThinkingBlockParam { Signature = "signature", Thinking = "thinking" }; + + ThinkingBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ThinkingBlockTest.cs b/src/Anthropic.Tests/Models/Messages/ThinkingBlockTest.cs index 117c425b4..b0bee95de 100644 --- a/src/Anthropic.Tests/Models/Messages/ThinkingBlockTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ThinkingBlockTest.cs @@ -62,4 +62,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ThinkingBlock { Signature = "signature", Thinking = "thinking" }; + + ThinkingBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ThinkingConfigDisabledTest.cs b/src/Anthropic.Tests/Models/Messages/ThinkingConfigDisabledTest.cs index c68a07bcf..bc7f0b93f 100644 --- a/src/Anthropic.Tests/Models/Messages/ThinkingConfigDisabledTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ThinkingConfigDisabledTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ThinkingConfigDisabled { }; + + ThinkingConfigDisabled copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ThinkingConfigEnabledTest.cs b/src/Anthropic.Tests/Models/Messages/ThinkingConfigEnabledTest.cs index 0da0048bf..96cedbdd2 100644 --- a/src/Anthropic.Tests/Models/Messages/ThinkingConfigEnabledTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ThinkingConfigEnabledTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ThinkingConfigEnabled { BudgetTokens = 1024 }; + + ThinkingConfigEnabled copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ThinkingDeltaTest.cs b/src/Anthropic.Tests/Models/Messages/ThinkingDeltaTest.cs index ecf1e2b16..dd49d85b1 100644 --- a/src/Anthropic.Tests/Models/Messages/ThinkingDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ThinkingDeltaTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ThinkingDelta { Thinking = "thinking" }; + + ThinkingDelta copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolBash20250124Test.cs b/src/Anthropic.Tests/Models/Messages/ToolBash20250124Test.cs index 25cfb79ba..803d2fc36 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolBash20250124Test.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolBash20250124Test.cs @@ -96,4 +96,14 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolBash20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + + ToolBash20250124 copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolChoiceAnyTest.cs b/src/Anthropic.Tests/Models/Messages/ToolChoiceAnyTest.cs index 08f9bfb9f..d55575eb5 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolChoiceAnyTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolChoiceAnyTest.cs @@ -100,4 +100,14 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolChoiceAny { DisableParallelToolUse = true }; + + ToolChoiceAny copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolChoiceAutoTest.cs b/src/Anthropic.Tests/Models/Messages/ToolChoiceAutoTest.cs index 5c60a5322..485673af1 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolChoiceAutoTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolChoiceAutoTest.cs @@ -100,4 +100,14 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolChoiceAuto { DisableParallelToolUse = true }; + + ToolChoiceAuto copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolChoiceNoneTest.cs b/src/Anthropic.Tests/Models/Messages/ToolChoiceNoneTest.cs index 20d29435e..d1a429a86 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolChoiceNoneTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolChoiceNoneTest.cs @@ -54,4 +54,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolChoiceNone { }; + + ToolChoiceNone copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolChoiceToolTest.cs b/src/Anthropic.Tests/Models/Messages/ToolChoiceToolTest.cs index 645c2b3f6..cccce37d2 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolChoiceToolTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolChoiceToolTest.cs @@ -108,4 +108,14 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolChoiceTool { Name = "name", DisableParallelToolUse = true }; + + ToolChoiceTool copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/ToolResultBlockParamTest.cs index 4007c2e5c..a145588be 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolResultBlockParamTest.cs @@ -214,6 +214,22 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolResultBlockParam + { + ToolUseID = "tool_use_id", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Content = "string", + IsError = true, + }; + + ToolResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } public class ToolResultBlockParamContentTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/ToolTest.cs b/src/Anthropic.Tests/Models/Messages/ToolTest.cs index 7b9ecc342..407d0e317 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolTest.cs @@ -334,6 +334,31 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Tool + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + Type = Type.Custom, + }; + + Tool copied = new(model); + + Assert.Equal(model, copied); + } } public class InputSchemaTest : TestBase @@ -496,6 +521,24 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new InputSchema + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }; + + InputSchema copied = new(model); + + Assert.Equal(model, copied); + } } public class TypeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250124Test.cs b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250124Test.cs index ecf4fe8cf..c74a4f224 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250124Test.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250124Test.cs @@ -96,4 +96,14 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolTextEditor20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + + ToolTextEditor20250124 copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250429Test.cs b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250429Test.cs index 9fe62f27f..e3d62512a 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250429Test.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250429Test.cs @@ -96,4 +96,14 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolTextEditor20250429 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + + ToolTextEditor20250429 copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250728Test.cs b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250728Test.cs index 1980ec898..2f9745510 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250728Test.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250728Test.cs @@ -120,4 +120,18 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolTextEditor20250728 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + MaxCharacters = 1, + }; + + ToolTextEditor20250728 copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolUseBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/ToolUseBlockParamTest.cs index 6587a5813..685147a66 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolUseBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolUseBlockParamTest.cs @@ -195,4 +195,23 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolUseBlockParam + { + ID = "id", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = "x", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + ToolUseBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolUseBlockTest.cs b/src/Anthropic.Tests/Models/Messages/ToolUseBlockTest.cs index 9a9f20632..2acec8d2d 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolUseBlockTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolUseBlockTest.cs @@ -117,4 +117,22 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ToolUseBlock + { + ID = "id", + Input = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + Name = "x", + }; + + ToolUseBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/UrlImageSourceTest.cs b/src/Anthropic.Tests/Models/Messages/UrlImageSourceTest.cs index 52321624d..d9cdd071f 100644 --- a/src/Anthropic.Tests/Models/Messages/UrlImageSourceTest.cs +++ b/src/Anthropic.Tests/Models/Messages/UrlImageSourceTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new UrlImageSource { Url = "url" }; + + UrlImageSource copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/UrlPdfSourceTest.cs b/src/Anthropic.Tests/Models/Messages/UrlPdfSourceTest.cs index dcbb68137..9fba1b290 100644 --- a/src/Anthropic.Tests/Models/Messages/UrlPdfSourceTest.cs +++ b/src/Anthropic.Tests/Models/Messages/UrlPdfSourceTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new UrlPdfSource { Url = "url" }; + + UrlPdfSource copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/UsageTest.cs b/src/Anthropic.Tests/Models/Messages/UsageTest.cs index cd18d68e4..b23f80561 100644 --- a/src/Anthropic.Tests/Models/Messages/UsageTest.cs +++ b/src/Anthropic.Tests/Models/Messages/UsageTest.cs @@ -117,6 +117,25 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new Usage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 2051, + CacheReadInputTokens = 2051, + InputTokens = 2095, + OutputTokens = 503, + ServerToolUse = new(0), + ServiceTier = UsageServiceTier.Standard, + }; + + Usage copied = new(model); + + Assert.Equal(model, copied); + } } public class UsageServiceTierTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/WebSearchResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/WebSearchResultBlockParamTest.cs index 8b505bbdc..0ce7d27d8 100644 --- a/src/Anthropic.Tests/Models/Messages/WebSearchResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/WebSearchResultBlockParamTest.cs @@ -152,4 +152,20 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new WebSearchResultBlockParam + { + EncryptedContent = "encrypted_content", + Title = "title", + Url = "url", + PageAge = "page_age", + }; + + WebSearchResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/WebSearchResultBlockTest.cs b/src/Anthropic.Tests/Models/Messages/WebSearchResultBlockTest.cs index 2daf61bb8..fc25dae43 100644 --- a/src/Anthropic.Tests/Models/Messages/WebSearchResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Messages/WebSearchResultBlockTest.cs @@ -94,4 +94,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new WebSearchResultBlock + { + EncryptedContent = "encrypted_content", + PageAge = "page_age", + Title = "title", + Url = "url", + }; + + WebSearchResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/WebSearchTool20250305Test.cs b/src/Anthropic.Tests/Models/Messages/WebSearchTool20250305Test.cs index 7caaa5ff3..eadca1851 100644 --- a/src/Anthropic.Tests/Models/Messages/WebSearchTool20250305Test.cs +++ b/src/Anthropic.Tests/Models/Messages/WebSearchTool20250305Test.cs @@ -227,6 +227,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new WebSearchTool20250305 + { + AllowedDomains = ["string"], + BlockedDomains = ["string"], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + MaxUses = 1, + UserLocation = new() + { + City = "New York", + Country = "US", + Region = "California", + Timezone = "America/New_York", + }, + }; + + WebSearchTool20250305 copied = new(model); + + Assert.Equal(model, copied); + } } public class UserLocationTest : TestBase @@ -377,4 +400,20 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new UserLocation + { + City = "New York", + Country = "US", + Region = "California", + Timezone = "America/New_York", + }; + + UserLocation copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/WebSearchToolRequestErrorTest.cs b/src/Anthropic.Tests/Models/Messages/WebSearchToolRequestErrorTest.cs index 4bd948a10..ace1a6c1c 100644 --- a/src/Anthropic.Tests/Models/Messages/WebSearchToolRequestErrorTest.cs +++ b/src/Anthropic.Tests/Models/Messages/WebSearchToolRequestErrorTest.cs @@ -63,6 +63,16 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new WebSearchToolRequestError { ErrorCode = ErrorCode.InvalidToolInput }; + + WebSearchToolRequestError copied = new(model); + + Assert.Equal(model, copied); + } } public class ErrorCodeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Messages/WebSearchToolResultBlockParamTest.cs b/src/Anthropic.Tests/Models/Messages/WebSearchToolResultBlockParamTest.cs index bec6991c9..fa1cac712 100644 --- a/src/Anthropic.Tests/Models/Messages/WebSearchToolResultBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/WebSearchToolResultBlockParamTest.cs @@ -240,4 +240,29 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new WebSearchToolResultBlockParam + { + Content = new( + [ + new WebSearchResultBlockParam() + { + EncryptedContent = "encrypted_content", + Title = "title", + Url = "url", + PageAge = "page_age", + }, + ] + ), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + WebSearchToolResultBlockParam copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/WebSearchToolResultBlockTest.cs b/src/Anthropic.Tests/Models/Messages/WebSearchToolResultBlockTest.cs index 03e1add2f..2a51582c0 100644 --- a/src/Anthropic.Tests/Models/Messages/WebSearchToolResultBlockTest.cs +++ b/src/Anthropic.Tests/Models/Messages/WebSearchToolResultBlockTest.cs @@ -90,4 +90,20 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new WebSearchToolResultBlock + { + Content = new WebSearchToolResultError( + WebSearchToolResultErrorErrorCode.InvalidToolInput + ), + ToolUseID = "srvtoolu_SQfNkl1n_JR_", + }; + + WebSearchToolResultBlock copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Messages/WebSearchToolResultErrorTest.cs b/src/Anthropic.Tests/Models/Messages/WebSearchToolResultErrorTest.cs index 2002a4159..b0241b3a4 100644 --- a/src/Anthropic.Tests/Models/Messages/WebSearchToolResultErrorTest.cs +++ b/src/Anthropic.Tests/Models/Messages/WebSearchToolResultErrorTest.cs @@ -77,6 +77,19 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new WebSearchToolResultError + { + ErrorCode = WebSearchToolResultErrorErrorCode.InvalidToolInput, + }; + + WebSearchToolResultError copied = new(model); + + Assert.Equal(model, copied); + } } public class WebSearchToolResultErrorErrorCodeTest : TestBase diff --git a/src/Anthropic.Tests/Models/Models/ModelInfoTest.cs b/src/Anthropic.Tests/Models/Models/ModelInfoTest.cs index 0b9fb9575..906ddb457 100644 --- a/src/Anthropic.Tests/Models/Models/ModelInfoTest.cs +++ b/src/Anthropic.Tests/Models/Models/ModelInfoTest.cs @@ -84,4 +84,19 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ModelInfo + { + ID = "claude-sonnet-4-20250514", + CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), + DisplayName = "Claude Sonnet 4", + }; + + ModelInfo copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/Models/ModelListPageResponseTest.cs b/src/Anthropic.Tests/Models/Models/ModelListPageResponseTest.cs index 9cfe9c5e0..2cdb37e2d 100644 --- a/src/Anthropic.Tests/Models/Models/ModelListPageResponseTest.cs +++ b/src/Anthropic.Tests/Models/Models/ModelListPageResponseTest.cs @@ -148,4 +148,28 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ModelListPageResponse + { + Data = + [ + new() + { + ID = "claude-sonnet-4-20250514", + CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), + DisplayName = "Claude Sonnet 4", + }, + ], + FirstID = "first_id", + HasMore = true, + LastID = "last_id", + }; + + ModelListPageResponse copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/NotFoundErrorTest.cs b/src/Anthropic.Tests/Models/NotFoundErrorTest.cs index 610644f6b..c86244742 100644 --- a/src/Anthropic.Tests/Models/NotFoundErrorTest.cs +++ b/src/Anthropic.Tests/Models/NotFoundErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new NotFoundError { Message = "message" }; + + NotFoundError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/OverloadedErrorTest.cs b/src/Anthropic.Tests/Models/OverloadedErrorTest.cs index c1ff9b6a8..453a4b1e0 100644 --- a/src/Anthropic.Tests/Models/OverloadedErrorTest.cs +++ b/src/Anthropic.Tests/Models/OverloadedErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new OverloadedError { Message = "message" }; + + OverloadedError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/PermissionErrorTest.cs b/src/Anthropic.Tests/Models/PermissionErrorTest.cs index c0f986e97..a7abff0ae 100644 --- a/src/Anthropic.Tests/Models/PermissionErrorTest.cs +++ b/src/Anthropic.Tests/Models/PermissionErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new PermissionError { Message = "message" }; + + PermissionError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic.Tests/Models/RateLimitErrorTest.cs b/src/Anthropic.Tests/Models/RateLimitErrorTest.cs index d7e6ae403..f15f47615 100644 --- a/src/Anthropic.Tests/Models/RateLimitErrorTest.cs +++ b/src/Anthropic.Tests/Models/RateLimitErrorTest.cs @@ -58,4 +58,14 @@ public void Validation_Works() model.Validate(); } + + [Fact] + public void CopyConstructor_Works() + { + var model = new RateLimitError { Message = "message" }; + + RateLimitError copied = new(model); + + Assert.Equal(model, copied); + } } diff --git a/src/Anthropic/Models/ApiErrorObject.cs b/src/Anthropic/Models/ApiErrorObject.cs index ad5f69e3e..04d8f7726 100644 --- a/src/Anthropic/Models/ApiErrorObject.cs +++ b/src/Anthropic/Models/ApiErrorObject.cs @@ -46,8 +46,11 @@ public ApiErrorObject() this.Type = JsonSerializer.SerializeToElement("api_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ApiErrorObject(ApiErrorObject apiErrorObject) : base(apiErrorObject) { } +#pragma warning restore CS8618 public ApiErrorObject(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/AuthenticationError.cs b/src/Anthropic/Models/AuthenticationError.cs index 1104d0725..6a1eb42c1 100644 --- a/src/Anthropic/Models/AuthenticationError.cs +++ b/src/Anthropic/Models/AuthenticationError.cs @@ -51,8 +51,11 @@ public AuthenticationError() this.Type = JsonSerializer.SerializeToElement("authentication_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public AuthenticationError(AuthenticationError authenticationError) : base(authenticationError) { } +#pragma warning restore CS8618 public AuthenticationError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/BetaApiError.cs b/src/Anthropic/Models/Beta/BetaApiError.cs index c5b2213e0..8c94c09a8 100644 --- a/src/Anthropic/Models/Beta/BetaApiError.cs +++ b/src/Anthropic/Models/Beta/BetaApiError.cs @@ -46,8 +46,11 @@ public BetaApiError() this.Type = JsonSerializer.SerializeToElement("api_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaApiError(BetaApiError betaApiError) : base(betaApiError) { } +#pragma warning restore CS8618 public BetaApiError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/BetaAuthenticationError.cs b/src/Anthropic/Models/Beta/BetaAuthenticationError.cs index 9859c814f..53062c858 100644 --- a/src/Anthropic/Models/Beta/BetaAuthenticationError.cs +++ b/src/Anthropic/Models/Beta/BetaAuthenticationError.cs @@ -51,8 +51,11 @@ public BetaAuthenticationError() this.Type = JsonSerializer.SerializeToElement("authentication_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaAuthenticationError(BetaAuthenticationError betaAuthenticationError) : base(betaAuthenticationError) { } +#pragma warning restore CS8618 public BetaAuthenticationError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/BetaBillingError.cs b/src/Anthropic/Models/Beta/BetaBillingError.cs index 80fd4021c..43a086d09 100644 --- a/src/Anthropic/Models/Beta/BetaBillingError.cs +++ b/src/Anthropic/Models/Beta/BetaBillingError.cs @@ -46,8 +46,11 @@ public BetaBillingError() this.Type = JsonSerializer.SerializeToElement("billing_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBillingError(BetaBillingError betaBillingError) : base(betaBillingError) { } +#pragma warning restore CS8618 public BetaBillingError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/BetaErrorResponse.cs b/src/Anthropic/Models/Beta/BetaErrorResponse.cs index 744305a24..5b301003b 100644 --- a/src/Anthropic/Models/Beta/BetaErrorResponse.cs +++ b/src/Anthropic/Models/Beta/BetaErrorResponse.cs @@ -57,8 +57,11 @@ public BetaErrorResponse() this.Type = JsonSerializer.SerializeToElement("error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaErrorResponse(BetaErrorResponse betaErrorResponse) : base(betaErrorResponse) { } +#pragma warning restore CS8618 public BetaErrorResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/BetaGatewayTimeoutError.cs b/src/Anthropic/Models/Beta/BetaGatewayTimeoutError.cs index dcadd4661..3f06a5a98 100644 --- a/src/Anthropic/Models/Beta/BetaGatewayTimeoutError.cs +++ b/src/Anthropic/Models/Beta/BetaGatewayTimeoutError.cs @@ -46,8 +46,11 @@ public BetaGatewayTimeoutError() this.Type = JsonSerializer.SerializeToElement("timeout_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaGatewayTimeoutError(BetaGatewayTimeoutError betaGatewayTimeoutError) : base(betaGatewayTimeoutError) { } +#pragma warning restore CS8618 public BetaGatewayTimeoutError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/BetaInvalidRequestError.cs b/src/Anthropic/Models/Beta/BetaInvalidRequestError.cs index 74c6d125b..dc9408b27 100644 --- a/src/Anthropic/Models/Beta/BetaInvalidRequestError.cs +++ b/src/Anthropic/Models/Beta/BetaInvalidRequestError.cs @@ -51,8 +51,11 @@ public BetaInvalidRequestError() this.Type = JsonSerializer.SerializeToElement("invalid_request_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaInvalidRequestError(BetaInvalidRequestError betaInvalidRequestError) : base(betaInvalidRequestError) { } +#pragma warning restore CS8618 public BetaInvalidRequestError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/BetaNotFoundError.cs b/src/Anthropic/Models/Beta/BetaNotFoundError.cs index ff366b17f..a8e665b1c 100644 --- a/src/Anthropic/Models/Beta/BetaNotFoundError.cs +++ b/src/Anthropic/Models/Beta/BetaNotFoundError.cs @@ -48,8 +48,11 @@ public BetaNotFoundError() this.Type = JsonSerializer.SerializeToElement("not_found_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaNotFoundError(BetaNotFoundError betaNotFoundError) : base(betaNotFoundError) { } +#pragma warning restore CS8618 public BetaNotFoundError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/BetaOverloadedError.cs b/src/Anthropic/Models/Beta/BetaOverloadedError.cs index fde08041c..a490f00b1 100644 --- a/src/Anthropic/Models/Beta/BetaOverloadedError.cs +++ b/src/Anthropic/Models/Beta/BetaOverloadedError.cs @@ -51,8 +51,11 @@ public BetaOverloadedError() this.Type = JsonSerializer.SerializeToElement("overloaded_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaOverloadedError(BetaOverloadedError betaOverloadedError) : base(betaOverloadedError) { } +#pragma warning restore CS8618 public BetaOverloadedError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/BetaPermissionError.cs b/src/Anthropic/Models/Beta/BetaPermissionError.cs index 6a4971c44..be7e3cb47 100644 --- a/src/Anthropic/Models/Beta/BetaPermissionError.cs +++ b/src/Anthropic/Models/Beta/BetaPermissionError.cs @@ -51,8 +51,11 @@ public BetaPermissionError() this.Type = JsonSerializer.SerializeToElement("permission_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaPermissionError(BetaPermissionError betaPermissionError) : base(betaPermissionError) { } +#pragma warning restore CS8618 public BetaPermissionError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/BetaRateLimitError.cs b/src/Anthropic/Models/Beta/BetaRateLimitError.cs index fffef1944..635cb2646 100644 --- a/src/Anthropic/Models/Beta/BetaRateLimitError.cs +++ b/src/Anthropic/Models/Beta/BetaRateLimitError.cs @@ -51,8 +51,11 @@ public BetaRateLimitError() this.Type = JsonSerializer.SerializeToElement("rate_limit_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRateLimitError(BetaRateLimitError betaRateLimitError) : base(betaRateLimitError) { } +#pragma warning restore CS8618 public BetaRateLimitError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Files/DeletedFile.cs b/src/Anthropic/Models/Beta/Files/DeletedFile.cs index ee6229f45..6a78faf0c 100644 --- a/src/Anthropic/Models/Beta/Files/DeletedFile.cs +++ b/src/Anthropic/Models/Beta/Files/DeletedFile.cs @@ -59,8 +59,11 @@ public override void Validate() public DeletedFile() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public DeletedFile(DeletedFile deletedFile) : base(deletedFile) { } +#pragma warning restore CS8618 public DeletedFile(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Files/FileListPageResponse.cs b/src/Anthropic/Models/Beta/Files/FileListPageResponse.cs index 482d3827e..414eaec35 100644 --- a/src/Anthropic/Models/Beta/Files/FileListPageResponse.cs +++ b/src/Anthropic/Models/Beta/Files/FileListPageResponse.cs @@ -91,8 +91,11 @@ public override void Validate() public FileListPageResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public FileListPageResponse(FileListPageResponse fileListPageResponse) : base(fileListPageResponse) { } +#pragma warning restore CS8618 public FileListPageResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Files/FileMetadata.cs b/src/Anthropic/Models/Beta/Files/FileMetadata.cs index 06b5ae91a..39e0cbf04 100644 --- a/src/Anthropic/Models/Beta/Files/FileMetadata.cs +++ b/src/Anthropic/Models/Beta/Files/FileMetadata.cs @@ -135,8 +135,11 @@ public FileMetadata() this.Type = JsonSerializer.SerializeToElement("file"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public FileMetadata(FileMetadata fileMetadata) : base(fileMetadata) { } +#pragma warning restore CS8618 public FileMetadata(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs index 93409b123..d859b2c7c 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs @@ -232,8 +232,11 @@ public override void Validate() public Request() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Request(Request request) : base(request) { } +#pragma warning restore CS8618 public Request(IReadOnlyDictionary rawData) { @@ -831,8 +834,11 @@ public override void Validate() public Params() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Params(Params params_) : base(params_) { } +#pragma warning restore CS8618 public Params(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchListPageResponse.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchListPageResponse.cs index 010ffb3bd..7769cc084 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchListPageResponse.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchListPageResponse.cs @@ -80,8 +80,11 @@ public override void Validate() public BatchListPageResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchListPageResponse(BatchListPageResponse batchListPageResponse) : base(batchListPageResponse) { } +#pragma warning restore CS8618 public BatchListPageResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BetaDeletedMessageBatch.cs b/src/Anthropic/Models/Beta/Messages/Batches/BetaDeletedMessageBatch.cs index f80cf60b8..55bf5d9df 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BetaDeletedMessageBatch.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BetaDeletedMessageBatch.cs @@ -59,8 +59,11 @@ public BetaDeletedMessageBatch() this.Type = JsonSerializer.SerializeToElement("message_batch_deleted"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaDeletedMessageBatch(BetaDeletedMessageBatch betaDeletedMessageBatch) : base(betaDeletedMessageBatch) { } +#pragma warning restore CS8618 public BetaDeletedMessageBatch(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatch.cs b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatch.cs index fcc2bb869..7e320aee3 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatch.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatch.cs @@ -187,8 +187,11 @@ public BetaMessageBatch() this.Type = JsonSerializer.SerializeToElement("message_batch"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessageBatch(BetaMessageBatch betaMessageBatch) : base(betaMessageBatch) { } +#pragma warning restore CS8618 public BetaMessageBatch(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchCanceledResult.cs b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchCanceledResult.cs index a0cf33618..3a25cac97 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchCanceledResult.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchCanceledResult.cs @@ -40,10 +40,13 @@ public BetaMessageBatchCanceledResult() this.Type = JsonSerializer.SerializeToElement("canceled"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessageBatchCanceledResult( BetaMessageBatchCanceledResult betaMessageBatchCanceledResult ) : base(betaMessageBatchCanceledResult) { } +#pragma warning restore CS8618 public BetaMessageBatchCanceledResult(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchErroredResult.cs b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchErroredResult.cs index 27d32f6ca..ee1abb121 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchErroredResult.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchErroredResult.cs @@ -48,10 +48,13 @@ public BetaMessageBatchErroredResult() this.Type = JsonSerializer.SerializeToElement("errored"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessageBatchErroredResult( BetaMessageBatchErroredResult betaMessageBatchErroredResult ) : base(betaMessageBatchErroredResult) { } +#pragma warning restore CS8618 public BetaMessageBatchErroredResult(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchExpiredResult.cs b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchExpiredResult.cs index f11302ab1..2f18c2fe0 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchExpiredResult.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchExpiredResult.cs @@ -37,10 +37,13 @@ public BetaMessageBatchExpiredResult() this.Type = JsonSerializer.SerializeToElement("expired"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessageBatchExpiredResult( BetaMessageBatchExpiredResult betaMessageBatchExpiredResult ) : base(betaMessageBatchExpiredResult) { } +#pragma warning restore CS8618 public BetaMessageBatchExpiredResult(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponse.cs b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponse.cs index 172b8e264..fe5ce3469 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponse.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponse.cs @@ -61,10 +61,13 @@ public override void Validate() public BetaMessageBatchIndividualResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessageBatchIndividualResponse( BetaMessageBatchIndividualResponse betaMessageBatchIndividualResponse ) : base(betaMessageBatchIndividualResponse) { } +#pragma warning restore CS8618 public BetaMessageBatchIndividualResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchRequestCounts.cs b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchRequestCounts.cs index 1d1ea1b74..e9c21a496 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchRequestCounts.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchRequestCounts.cs @@ -97,10 +97,13 @@ public override void Validate() public BetaMessageBatchRequestCounts() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessageBatchRequestCounts( BetaMessageBatchRequestCounts betaMessageBatchRequestCounts ) : base(betaMessageBatchRequestCounts) { } +#pragma warning restore CS8618 public BetaMessageBatchRequestCounts(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResult.cs b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResult.cs index 8d3e5a82d..f3dafb66b 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResult.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResult.cs @@ -51,10 +51,13 @@ public BetaMessageBatchSucceededResult() this.Type = JsonSerializer.SerializeToElement("succeeded"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessageBatchSucceededResult( BetaMessageBatchSucceededResult betaMessageBatchSucceededResult ) : base(betaMessageBatchSucceededResult) { } +#pragma warning restore CS8618 public BetaMessageBatchSucceededResult(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaAllThinkingTurns.cs b/src/Anthropic/Models/Beta/Messages/BetaAllThinkingTurns.cs index 1a878f5cb..c517f6b1f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaAllThinkingTurns.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaAllThinkingTurns.cs @@ -35,8 +35,11 @@ public BetaAllThinkingTurns() this.Type = JsonSerializer.SerializeToElement("all"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaAllThinkingTurns(BetaAllThinkingTurns betaAllThinkingTurns) : base(betaAllThinkingTurns) { } +#pragma warning restore CS8618 public BetaAllThinkingTurns(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaBase64ImageSource.cs b/src/Anthropic/Models/Beta/Messages/BetaBase64ImageSource.cs index 9f51da5ad..914d96ece 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBase64ImageSource.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBase64ImageSource.cs @@ -58,8 +58,11 @@ public BetaBase64ImageSource() this.Type = JsonSerializer.SerializeToElement("base64"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBase64ImageSource(BetaBase64ImageSource betaBase64ImageSource) : base(betaBase64ImageSource) { } +#pragma warning restore CS8618 public BetaBase64ImageSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaBase64PdfSource.cs b/src/Anthropic/Models/Beta/Messages/BetaBase64PdfSource.cs index 76c3c3a79..21d9c0f8b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBase64PdfSource.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBase64PdfSource.cs @@ -66,8 +66,11 @@ public BetaBase64PdfSource() this.Type = JsonSerializer.SerializeToElement("base64"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBase64PdfSource(BetaBase64PdfSource betaBase64PdfSource) : base(betaBase64PdfSource) { } +#pragma warning restore CS8618 public BetaBase64PdfSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionOutputBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionOutputBlock.cs index 3170d9b6b..4c1457cc5 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionOutputBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionOutputBlock.cs @@ -56,10 +56,13 @@ public BetaBashCodeExecutionOutputBlock() this.Type = JsonSerializer.SerializeToElement("bash_code_execution_output"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBashCodeExecutionOutputBlock( BetaBashCodeExecutionOutputBlock betaBashCodeExecutionOutputBlock ) : base(betaBashCodeExecutionOutputBlock) { } +#pragma warning restore CS8618 public BetaBashCodeExecutionOutputBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockParam.cs index 82b4f37a0..a3a180c95 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionOutputBlockParam.cs @@ -56,10 +56,13 @@ public BetaBashCodeExecutionOutputBlockParam() this.Type = JsonSerializer.SerializeToElement("bash_code_execution_output"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBashCodeExecutionOutputBlockParam( BetaBashCodeExecutionOutputBlockParam betaBashCodeExecutionOutputBlockParam ) : base(betaBashCodeExecutionOutputBlockParam) { } +#pragma warning restore CS8618 public BetaBashCodeExecutionOutputBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionResultBlock.cs index 518de8cbc..0e94621cc 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionResultBlock.cs @@ -101,10 +101,13 @@ public BetaBashCodeExecutionResultBlock() this.Type = JsonSerializer.SerializeToElement("bash_code_execution_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBashCodeExecutionResultBlock( BetaBashCodeExecutionResultBlock betaBashCodeExecutionResultBlock ) : base(betaBashCodeExecutionResultBlock) { } +#pragma warning restore CS8618 public BetaBashCodeExecutionResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionResultBlockParam.cs index 4c2e0b7f8..b6ee5cf44 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionResultBlockParam.cs @@ -101,10 +101,13 @@ public BetaBashCodeExecutionResultBlockParam() this.Type = JsonSerializer.SerializeToElement("bash_code_execution_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBashCodeExecutionResultBlockParam( BetaBashCodeExecutionResultBlockParam betaBashCodeExecutionResultBlockParam ) : base(betaBashCodeExecutionResultBlockParam) { } +#pragma warning restore CS8618 public BetaBashCodeExecutionResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlock.cs index 49c74c3ec..edd962864 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlock.cs @@ -68,10 +68,13 @@ public BetaBashCodeExecutionToolResultBlock() this.Type = JsonSerializer.SerializeToElement("bash_code_execution_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBashCodeExecutionToolResultBlock( BetaBashCodeExecutionToolResultBlock betaBashCodeExecutionToolResultBlock ) : base(betaBashCodeExecutionToolResultBlock) { } +#pragma warning restore CS8618 public BetaBashCodeExecutionToolResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParam.cs index a9d2b6a9d..36fc1ac9a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParam.cs @@ -84,10 +84,13 @@ public BetaBashCodeExecutionToolResultBlockParam() this.Type = JsonSerializer.SerializeToElement("bash_code_execution_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBashCodeExecutionToolResultBlockParam( BetaBashCodeExecutionToolResultBlockParam betaBashCodeExecutionToolResultBlockParam ) : base(betaBashCodeExecutionToolResultBlockParam) { } +#pragma warning restore CS8618 public BetaBashCodeExecutionToolResultBlockParam( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultError.cs b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultError.cs index 84df8c919..611a8e6f3 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultError.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultError.cs @@ -57,10 +57,13 @@ public BetaBashCodeExecutionToolResultError() this.Type = JsonSerializer.SerializeToElement("bash_code_execution_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBashCodeExecutionToolResultError( BetaBashCodeExecutionToolResultError betaBashCodeExecutionToolResultError ) : base(betaBashCodeExecutionToolResultError) { } +#pragma warning restore CS8618 public BetaBashCodeExecutionToolResultError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorParam.cs b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorParam.cs index c9fc47ab1..8230d671a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultErrorParam.cs @@ -59,10 +59,13 @@ public BetaBashCodeExecutionToolResultErrorParam() this.Type = JsonSerializer.SerializeToElement("bash_code_execution_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaBashCodeExecutionToolResultErrorParam( BetaBashCodeExecutionToolResultErrorParam betaBashCodeExecutionToolResultErrorParam ) : base(betaBashCodeExecutionToolResultErrorParam) { } +#pragma warning restore CS8618 public BetaBashCodeExecutionToolResultErrorParam( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaCacheControlEphemeral.cs b/src/Anthropic/Models/Beta/Messages/BetaCacheControlEphemeral.cs index eb101b81f..e57d4fe6a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCacheControlEphemeral.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCacheControlEphemeral.cs @@ -64,8 +64,11 @@ public BetaCacheControlEphemeral() this.Type = JsonSerializer.SerializeToElement("ephemeral"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCacheControlEphemeral(BetaCacheControlEphemeral betaCacheControlEphemeral) : base(betaCacheControlEphemeral) { } +#pragma warning restore CS8618 public BetaCacheControlEphemeral(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCacheCreation.cs b/src/Anthropic/Models/Beta/Messages/BetaCacheCreation.cs index e197af779..7d5338734 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCacheCreation.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCacheCreation.cs @@ -45,8 +45,11 @@ public override void Validate() public BetaCacheCreation() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCacheCreation(BetaCacheCreation betaCacheCreation) : base(betaCacheCreation) { } +#pragma warning restore CS8618 public BetaCacheCreation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationCharLocation.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationCharLocation.cs index f372f72ff..0ff8afce0 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationCharLocation.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationCharLocation.cs @@ -103,8 +103,11 @@ public BetaCitationCharLocation() this.Type = JsonSerializer.SerializeToElement("char_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationCharLocation(BetaCitationCharLocation betaCitationCharLocation) : base(betaCitationCharLocation) { } +#pragma warning restore CS8618 public BetaCitationCharLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationCharLocationParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationCharLocationParam.cs index e2e19b6c4..4d089017c 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationCharLocationParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationCharLocationParam.cs @@ -92,10 +92,13 @@ public BetaCitationCharLocationParam() this.Type = JsonSerializer.SerializeToElement("char_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationCharLocationParam( BetaCitationCharLocationParam betaCitationCharLocationParam ) : base(betaCitationCharLocationParam) { } +#pragma warning restore CS8618 public BetaCitationCharLocationParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationConfig.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationConfig.cs index e9cf73715..ef0e12340 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationConfig.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationConfig.cs @@ -28,8 +28,11 @@ public override void Validate() public BetaCitationConfig() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationConfig(BetaCitationConfig betaCitationConfig) : base(betaCitationConfig) { } +#pragma warning restore CS8618 public BetaCitationConfig(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationContentBlockLocation.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationContentBlockLocation.cs index c10d0552e..1714b20d0 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationContentBlockLocation.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationContentBlockLocation.cs @@ -111,10 +111,13 @@ public BetaCitationContentBlockLocation() this.Type = JsonSerializer.SerializeToElement("content_block_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationContentBlockLocation( BetaCitationContentBlockLocation betaCitationContentBlockLocation ) : base(betaCitationContentBlockLocation) { } +#pragma warning restore CS8618 public BetaCitationContentBlockLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationContentBlockLocationParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationContentBlockLocationParam.cs index 5af1c5af3..67f7e1298 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationContentBlockLocationParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationContentBlockLocationParam.cs @@ -100,10 +100,13 @@ public BetaCitationContentBlockLocationParam() this.Type = JsonSerializer.SerializeToElement("content_block_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationContentBlockLocationParam( BetaCitationContentBlockLocationParam betaCitationContentBlockLocationParam ) : base(betaCitationContentBlockLocationParam) { } +#pragma warning restore CS8618 public BetaCitationContentBlockLocationParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationPageLocation.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationPageLocation.cs index 922c6cc20..6ac11744a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationPageLocation.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationPageLocation.cs @@ -103,8 +103,11 @@ public BetaCitationPageLocation() this.Type = JsonSerializer.SerializeToElement("page_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationPageLocation(BetaCitationPageLocation betaCitationPageLocation) : base(betaCitationPageLocation) { } +#pragma warning restore CS8618 public BetaCitationPageLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationPageLocationParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationPageLocationParam.cs index 03e493c46..30618e6fe 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationPageLocationParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationPageLocationParam.cs @@ -92,10 +92,13 @@ public BetaCitationPageLocationParam() this.Type = JsonSerializer.SerializeToElement("page_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationPageLocationParam( BetaCitationPageLocationParam betaCitationPageLocationParam ) : base(betaCitationPageLocationParam) { } +#pragma warning restore CS8618 public BetaCitationPageLocationParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationSearchResultLocation.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationSearchResultLocation.cs index 742b450ff..8bc72951f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationSearchResultLocation.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationSearchResultLocation.cs @@ -111,10 +111,13 @@ public BetaCitationSearchResultLocation() this.Type = JsonSerializer.SerializeToElement("search_result_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationSearchResultLocation( BetaCitationSearchResultLocation betaCitationSearchResultLocation ) : base(betaCitationSearchResultLocation) { } +#pragma warning restore CS8618 public BetaCitationSearchResultLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationSearchResultLocationParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationSearchResultLocationParam.cs index 27d26fdd1..40946d9e2 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationSearchResultLocationParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationSearchResultLocationParam.cs @@ -111,10 +111,13 @@ public BetaCitationSearchResultLocationParam() this.Type = JsonSerializer.SerializeToElement("search_result_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationSearchResultLocationParam( BetaCitationSearchResultLocationParam betaCitationSearchResultLocationParam ) : base(betaCitationSearchResultLocationParam) { } +#pragma warning restore CS8618 public BetaCitationSearchResultLocationParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationWebSearchResultLocationParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationWebSearchResultLocationParam.cs index 0b2ba320c..8c42d00a5 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationWebSearchResultLocationParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationWebSearchResultLocationParam.cs @@ -89,10 +89,13 @@ public BetaCitationWebSearchResultLocationParam() this.Type = JsonSerializer.SerializeToElement("web_search_result_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationWebSearchResultLocationParam( BetaCitationWebSearchResultLocationParam betaCitationWebSearchResultLocationParam ) : base(betaCitationWebSearchResultLocationParam) { } +#pragma warning restore CS8618 public BetaCitationWebSearchResultLocationParam( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationsConfigParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationsConfigParam.cs index fb5459a05..9b2bf1974 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationsConfigParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationsConfigParam.cs @@ -38,8 +38,11 @@ public override void Validate() public BetaCitationsConfigParam() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationsConfigParam(BetaCitationsConfigParam betaCitationsConfigParam) : base(betaCitationsConfigParam) { } +#pragma warning restore CS8618 public BetaCitationsConfigParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationsDelta.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationsDelta.cs index 252bc1ede..9ca66d69e 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationsDelta.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationsDelta.cs @@ -49,8 +49,11 @@ public BetaCitationsDelta() this.Type = JsonSerializer.SerializeToElement("citations_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationsDelta(BetaCitationsDelta betaCitationsDelta) : base(betaCitationsDelta) { } +#pragma warning restore CS8618 public BetaCitationsDelta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationsWebSearchResultLocation.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationsWebSearchResultLocation.cs index 49c53165e..957b73b11 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationsWebSearchResultLocation.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationsWebSearchResultLocation.cs @@ -89,10 +89,13 @@ public BetaCitationsWebSearchResultLocation() this.Type = JsonSerializer.SerializeToElement("web_search_result_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCitationsWebSearchResultLocation( BetaCitationsWebSearchResultLocation betaCitationsWebSearchResultLocation ) : base(betaCitationsWebSearchResultLocation) { } +#pragma warning restore CS8618 public BetaCitationsWebSearchResultLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015Edit.cs b/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015Edit.cs index 063a26068..e0ed8a9b3 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015Edit.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015Edit.cs @@ -66,10 +66,13 @@ public BetaClearThinking20251015Edit() this.Type = JsonSerializer.SerializeToElement("clear_thinking_20251015"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaClearThinking20251015Edit( BetaClearThinking20251015Edit betaClearThinking20251015Edit ) : base(betaClearThinking20251015Edit) { } +#pragma warning restore CS8618 public BetaClearThinking20251015Edit(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015EditResponse.cs b/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015EditResponse.cs index 793f38e6c..fc4761d0a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015EditResponse.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015EditResponse.cs @@ -76,10 +76,13 @@ public BetaClearThinking20251015EditResponse() this.Type = JsonSerializer.SerializeToElement("clear_thinking_20251015"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaClearThinking20251015EditResponse( BetaClearThinking20251015EditResponse betaClearThinking20251015EditResponse ) : base(betaClearThinking20251015EditResponse) { } +#pragma warning restore CS8618 public BetaClearThinking20251015EditResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs b/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs index 4f3576ce1..4f4eefca4 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs @@ -137,10 +137,13 @@ public BetaClearToolUses20250919Edit() this.Type = JsonSerializer.SerializeToElement("clear_tool_uses_20250919"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaClearToolUses20250919Edit( BetaClearToolUses20250919Edit betaClearToolUses20250919Edit ) : base(betaClearToolUses20250919Edit) { } +#pragma warning restore CS8618 public BetaClearToolUses20250919Edit(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919EditResponse.cs b/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919EditResponse.cs index cd6df3f1f..0ee5224e4 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919EditResponse.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919EditResponse.cs @@ -76,10 +76,13 @@ public BetaClearToolUses20250919EditResponse() this.Type = JsonSerializer.SerializeToElement("clear_tool_uses_20250919"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaClearToolUses20250919EditResponse( BetaClearToolUses20250919EditResponse betaClearToolUses20250919EditResponse ) : base(betaClearToolUses20250919EditResponse) { } +#pragma warning restore CS8618 public BetaClearToolUses20250919EditResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionOutputBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionOutputBlock.cs index 274d5c99e..5eb64d042 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionOutputBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionOutputBlock.cs @@ -53,8 +53,11 @@ public BetaCodeExecutionOutputBlock() this.Type = JsonSerializer.SerializeToElement("code_execution_output"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCodeExecutionOutputBlock(BetaCodeExecutionOutputBlock betaCodeExecutionOutputBlock) : base(betaCodeExecutionOutputBlock) { } +#pragma warning restore CS8618 public BetaCodeExecutionOutputBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionOutputBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionOutputBlockParam.cs index f3d7f901a..5b28a0560 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionOutputBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionOutputBlockParam.cs @@ -56,10 +56,13 @@ public BetaCodeExecutionOutputBlockParam() this.Type = JsonSerializer.SerializeToElement("code_execution_output"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCodeExecutionOutputBlockParam( BetaCodeExecutionOutputBlockParam betaCodeExecutionOutputBlockParam ) : base(betaCodeExecutionOutputBlockParam) { } +#pragma warning restore CS8618 public BetaCodeExecutionOutputBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionResultBlock.cs index 246e30867..cbc0153ae 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionResultBlock.cs @@ -98,8 +98,11 @@ public BetaCodeExecutionResultBlock() this.Type = JsonSerializer.SerializeToElement("code_execution_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCodeExecutionResultBlock(BetaCodeExecutionResultBlock betaCodeExecutionResultBlock) : base(betaCodeExecutionResultBlock) { } +#pragma warning restore CS8618 public BetaCodeExecutionResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionResultBlockParam.cs index a90d27b14..729e4556c 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionResultBlockParam.cs @@ -101,10 +101,13 @@ public BetaCodeExecutionResultBlockParam() this.Type = JsonSerializer.SerializeToElement("code_execution_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCodeExecutionResultBlockParam( BetaCodeExecutionResultBlockParam betaCodeExecutionResultBlockParam ) : base(betaCodeExecutionResultBlockParam) { } +#pragma warning restore CS8618 public BetaCodeExecutionResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250522.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250522.cs index 48715f720..084656ff4 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250522.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250522.cs @@ -147,10 +147,13 @@ public BetaCodeExecutionTool20250522() this.Type = JsonSerializer.SerializeToElement("code_execution_20250522"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCodeExecutionTool20250522( BetaCodeExecutionTool20250522 betaCodeExecutionTool20250522 ) : base(betaCodeExecutionTool20250522) { } +#pragma warning restore CS8618 public BetaCodeExecutionTool20250522(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250825.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250825.cs index 5edfa3a4f..0ca6103ea 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250825.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250825.cs @@ -148,10 +148,13 @@ public BetaCodeExecutionTool20250825() this.Type = JsonSerializer.SerializeToElement("code_execution_20250825"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCodeExecutionTool20250825( BetaCodeExecutionTool20250825 betaCodeExecutionTool20250825 ) : base(betaCodeExecutionTool20250825) { } +#pragma warning restore CS8618 public BetaCodeExecutionTool20250825(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlock.cs index c40375c89..b1d5c4c49 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlock.cs @@ -69,10 +69,13 @@ public BetaCodeExecutionToolResultBlock() this.Type = JsonSerializer.SerializeToElement("code_execution_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCodeExecutionToolResultBlock( BetaCodeExecutionToolResultBlock betaCodeExecutionToolResultBlock ) : base(betaCodeExecutionToolResultBlock) { } +#pragma warning restore CS8618 public BetaCodeExecutionToolResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParam.cs index 2b90f8aae..83f8eeb06 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParam.cs @@ -83,10 +83,13 @@ public BetaCodeExecutionToolResultBlockParam() this.Type = JsonSerializer.SerializeToElement("code_execution_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCodeExecutionToolResultBlockParam( BetaCodeExecutionToolResultBlockParam betaCodeExecutionToolResultBlockParam ) : base(betaCodeExecutionToolResultBlockParam) { } +#pragma warning restore CS8618 public BetaCodeExecutionToolResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultError.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultError.cs index 72a5ca45b..6f3ecbacc 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultError.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultError.cs @@ -58,10 +58,13 @@ public BetaCodeExecutionToolResultError() this.Type = JsonSerializer.SerializeToElement("code_execution_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCodeExecutionToolResultError( BetaCodeExecutionToolResultError betaCodeExecutionToolResultError ) : base(betaCodeExecutionToolResultError) { } +#pragma warning restore CS8618 public BetaCodeExecutionToolResultError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultErrorParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultErrorParam.cs index 92ae85a16..26588dc98 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultErrorParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultErrorParam.cs @@ -58,10 +58,13 @@ public BetaCodeExecutionToolResultErrorParam() this.Type = JsonSerializer.SerializeToElement("code_execution_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCodeExecutionToolResultErrorParam( BetaCodeExecutionToolResultErrorParam betaCodeExecutionToolResultErrorParam ) : base(betaCodeExecutionToolResultErrorParam) { } +#pragma warning restore CS8618 public BetaCodeExecutionToolResultErrorParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaContainer.cs b/src/Anthropic/Models/Beta/Messages/BetaContainer.cs index e0bf5891d..62dc2a076 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContainer.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContainer.cs @@ -73,8 +73,11 @@ public override void Validate() public BetaContainer() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaContainer(BetaContainer betaContainer) : base(betaContainer) { } +#pragma warning restore CS8618 public BetaContainer(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaContainerParams.cs b/src/Anthropic/Models/Beta/Messages/BetaContainerParams.cs index ad8d3bf91..73fd144ba 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContainerParams.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContainerParams.cs @@ -58,8 +58,11 @@ public override void Validate() public BetaContainerParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaContainerParams(BetaContainerParams betaContainerParams) : base(betaContainerParams) { } +#pragma warning restore CS8618 public BetaContainerParams(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaContainerUploadBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaContainerUploadBlock.cs index bdcb977b4..ea63ba1a8 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContainerUploadBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContainerUploadBlock.cs @@ -56,8 +56,11 @@ public BetaContainerUploadBlock() this.Type = JsonSerializer.SerializeToElement("container_upload"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaContainerUploadBlock(BetaContainerUploadBlock betaContainerUploadBlock) : base(betaContainerUploadBlock) { } +#pragma warning restore CS8618 public BetaContainerUploadBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaContainerUploadBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaContainerUploadBlockParam.cs index f0e48a885..22c434954 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContainerUploadBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContainerUploadBlockParam.cs @@ -71,10 +71,13 @@ public BetaContainerUploadBlockParam() this.Type = JsonSerializer.SerializeToElement("container_upload"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaContainerUploadBlockParam( BetaContainerUploadBlockParam betaContainerUploadBlockParam ) : base(betaContainerUploadBlockParam) { } +#pragma warning restore CS8618 public BetaContainerUploadBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaContentBlockSource.cs b/src/Anthropic/Models/Beta/Messages/BetaContentBlockSource.cs index 1b57589e2..0d2667dc0 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContentBlockSource.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContentBlockSource.cs @@ -48,8 +48,11 @@ public BetaContentBlockSource() this.Type = JsonSerializer.SerializeToElement("content"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaContentBlockSource(BetaContentBlockSource betaContentBlockSource) : base(betaContentBlockSource) { } +#pragma warning restore CS8618 public BetaContentBlockSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs b/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs index 3773078f4..5536cadd5 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs @@ -50,8 +50,11 @@ public override void Validate() public BetaContextManagementConfig() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaContextManagementConfig(BetaContextManagementConfig betaContextManagementConfig) : base(betaContextManagementConfig) { } +#pragma warning restore CS8618 public BetaContextManagementConfig(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaContextManagementResponse.cs b/src/Anthropic/Models/Beta/Messages/BetaContextManagementResponse.cs index 62603ccb2..eeab4d2f2 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContextManagementResponse.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContextManagementResponse.cs @@ -45,10 +45,13 @@ public override void Validate() public BetaContextManagementResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaContextManagementResponse( BetaContextManagementResponse betaContextManagementResponse ) : base(betaContextManagementResponse) { } +#pragma warning restore CS8618 public BetaContextManagementResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCountTokensContextManagementResponse.cs b/src/Anthropic/Models/Beta/Messages/BetaCountTokensContextManagementResponse.cs index 144b9a918..9f084385e 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCountTokensContextManagementResponse.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCountTokensContextManagementResponse.cs @@ -36,10 +36,13 @@ public override void Validate() public BetaCountTokensContextManagementResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaCountTokensContextManagementResponse( BetaCountTokensContextManagementResponse betaCountTokensContextManagementResponse ) : base(betaCountTokensContextManagementResponse) { } +#pragma warning restore CS8618 public BetaCountTokensContextManagementResponse( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaDirectCaller.cs b/src/Anthropic/Models/Beta/Messages/BetaDirectCaller.cs index 04f8d806e..4361ef165 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaDirectCaller.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaDirectCaller.cs @@ -38,8 +38,11 @@ public BetaDirectCaller() this.Type = JsonSerializer.SerializeToElement("direct"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaDirectCaller(BetaDirectCaller betaDirectCaller) : base(betaDirectCaller) { } +#pragma warning restore CS8618 public BetaDirectCaller(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaDocumentBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaDocumentBlock.cs index 65c1cc6fb..be32d89aa 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaDocumentBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaDocumentBlock.cs @@ -75,8 +75,11 @@ public BetaDocumentBlock() this.Type = JsonSerializer.SerializeToElement("document"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaDocumentBlock(BetaDocumentBlock betaDocumentBlock) : base(betaDocumentBlock) { } +#pragma warning restore CS8618 public BetaDocumentBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaFileDocumentSource.cs b/src/Anthropic/Models/Beta/Messages/BetaFileDocumentSource.cs index 843fe6241..a08ab5b7a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaFileDocumentSource.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaFileDocumentSource.cs @@ -46,8 +46,11 @@ public BetaFileDocumentSource() this.Type = JsonSerializer.SerializeToElement("file"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaFileDocumentSource(BetaFileDocumentSource betaFileDocumentSource) : base(betaFileDocumentSource) { } +#pragma warning restore CS8618 public BetaFileDocumentSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaFileImageSource.cs b/src/Anthropic/Models/Beta/Messages/BetaFileImageSource.cs index 9aed17780..3b008e4f6 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaFileImageSource.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaFileImageSource.cs @@ -46,8 +46,11 @@ public BetaFileImageSource() this.Type = JsonSerializer.SerializeToElement("file"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaFileImageSource(BetaFileImageSource betaFileImageSource) : base(betaFileImageSource) { } +#pragma warning restore CS8618 public BetaFileImageSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaImageBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaImageBlockParam.cs index 3bb97f990..fabc95264 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaImageBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaImageBlockParam.cs @@ -61,8 +61,11 @@ public BetaImageBlockParam() this.Type = JsonSerializer.SerializeToElement("image"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaImageBlockParam(BetaImageBlockParam betaImageBlockParam) : base(betaImageBlockParam) { } +#pragma warning restore CS8618 public BetaImageBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaInputJsonDelta.cs b/src/Anthropic/Models/Beta/Messages/BetaInputJsonDelta.cs index 27a1162e8..80fa4b7a3 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaInputJsonDelta.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaInputJsonDelta.cs @@ -51,8 +51,11 @@ public BetaInputJsonDelta() this.Type = JsonSerializer.SerializeToElement("input_json_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaInputJsonDelta(BetaInputJsonDelta betaInputJsonDelta) : base(betaInputJsonDelta) { } +#pragma warning restore CS8618 public BetaInputJsonDelta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaInputTokensClearAtLeast.cs b/src/Anthropic/Models/Beta/Messages/BetaInputTokensClearAtLeast.cs index 0f9f6951d..b6bd8a529 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaInputTokensClearAtLeast.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaInputTokensClearAtLeast.cs @@ -48,8 +48,11 @@ public BetaInputTokensClearAtLeast() this.Type = JsonSerializer.SerializeToElement("input_tokens"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaInputTokensClearAtLeast(BetaInputTokensClearAtLeast betaInputTokensClearAtLeast) : base(betaInputTokensClearAtLeast) { } +#pragma warning restore CS8618 public BetaInputTokensClearAtLeast(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaInputTokensTrigger.cs b/src/Anthropic/Models/Beta/Messages/BetaInputTokensTrigger.cs index 26787ac6a..f1f75820a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaInputTokensTrigger.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaInputTokensTrigger.cs @@ -46,8 +46,11 @@ public BetaInputTokensTrigger() this.Type = JsonSerializer.SerializeToElement("input_tokens"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaInputTokensTrigger(BetaInputTokensTrigger betaInputTokensTrigger) : base(betaInputTokensTrigger) { } +#pragma warning restore CS8618 public BetaInputTokensTrigger(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaJsonOutputFormat.cs b/src/Anthropic/Models/Beta/Messages/BetaJsonOutputFormat.cs index 63ccfffc4..442766132 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaJsonOutputFormat.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaJsonOutputFormat.cs @@ -55,8 +55,11 @@ public BetaJsonOutputFormat() this.Type = JsonSerializer.SerializeToElement("json_schema"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaJsonOutputFormat(BetaJsonOutputFormat betaJsonOutputFormat) : base(betaJsonOutputFormat) { } +#pragma warning restore CS8618 public BetaJsonOutputFormat(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMcpToolConfig.cs b/src/Anthropic/Models/Beta/Messages/BetaMcpToolConfig.cs index e515a58fe..cc639a5a1 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMcpToolConfig.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMcpToolConfig.cs @@ -58,8 +58,11 @@ public override void Validate() public BetaMcpToolConfig() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMcpToolConfig(BetaMcpToolConfig betaMcpToolConfig) : base(betaMcpToolConfig) { } +#pragma warning restore CS8618 public BetaMcpToolConfig(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMcpToolDefaultConfig.cs b/src/Anthropic/Models/Beta/Messages/BetaMcpToolDefaultConfig.cs index 198d4990e..7d77acc92 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMcpToolDefaultConfig.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMcpToolDefaultConfig.cs @@ -60,8 +60,11 @@ public override void Validate() public BetaMcpToolDefaultConfig() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMcpToolDefaultConfig(BetaMcpToolDefaultConfig betaMcpToolDefaultConfig) : base(betaMcpToolDefaultConfig) { } +#pragma warning restore CS8618 public BetaMcpToolDefaultConfig(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMcpToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaMcpToolResultBlock.cs index e4f54434a..1765bd426 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMcpToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMcpToolResultBlock.cs @@ -72,8 +72,11 @@ public BetaMcpToolResultBlock() this.Type = JsonSerializer.SerializeToElement("mcp_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMcpToolResultBlock(BetaMcpToolResultBlock betaMcpToolResultBlock) : base(betaMcpToolResultBlock) { } +#pragma warning restore CS8618 public BetaMcpToolResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMcpToolUseBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaMcpToolUseBlock.cs index a21454760..63ba5557f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMcpToolUseBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMcpToolUseBlock.cs @@ -91,8 +91,11 @@ public BetaMcpToolUseBlock() this.Type = JsonSerializer.SerializeToElement("mcp_tool_use"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMcpToolUseBlock(BetaMcpToolUseBlock betaMcpToolUseBlock) : base(betaMcpToolUseBlock) { } +#pragma warning restore CS8618 public BetaMcpToolUseBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMcpToolUseBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaMcpToolUseBlockParam.cs index 6dbe191f5..2e1c3b741 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMcpToolUseBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMcpToolUseBlockParam.cs @@ -104,8 +104,11 @@ public BetaMcpToolUseBlockParam() this.Type = JsonSerializer.SerializeToElement("mcp_tool_use"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMcpToolUseBlockParam(BetaMcpToolUseBlockParam betaMcpToolUseBlockParam) : base(betaMcpToolUseBlockParam) { } +#pragma warning restore CS8618 public BetaMcpToolUseBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMcpToolset.cs b/src/Anthropic/Models/Beta/Messages/BetaMcpToolset.cs index 39456e578..881b80224 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMcpToolset.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMcpToolset.cs @@ -119,8 +119,11 @@ public BetaMcpToolset() this.Type = JsonSerializer.SerializeToElement("mcp_toolset"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMcpToolset(BetaMcpToolset betaMcpToolset) : base(betaMcpToolset) { } +#pragma warning restore CS8618 public BetaMcpToolset(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818.cs b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818.cs index 85dccd999..b7e5f5ea2 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818.cs @@ -173,8 +173,11 @@ public BetaMemoryTool20250818() this.Type = JsonSerializer.SerializeToElement("memory_20250818"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMemoryTool20250818(BetaMemoryTool20250818 betaMemoryTool20250818) : base(betaMemoryTool20250818) { } +#pragma warning restore CS8618 public BetaMemoryTool20250818(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818CreateCommand.cs b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818CreateCommand.cs index a68cc5a6a..7c873ac4b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818CreateCommand.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818CreateCommand.cs @@ -71,10 +71,13 @@ public BetaMemoryTool20250818CreateCommand() this.Command = JsonSerializer.SerializeToElement("create"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMemoryTool20250818CreateCommand( BetaMemoryTool20250818CreateCommand betaMemoryTool20250818CreateCommand ) : base(betaMemoryTool20250818CreateCommand) { } +#pragma warning restore CS8618 public BetaMemoryTool20250818CreateCommand(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818DeleteCommand.cs b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818DeleteCommand.cs index 0e06fe8ff..85758fd45 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818DeleteCommand.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818DeleteCommand.cs @@ -57,10 +57,13 @@ public BetaMemoryTool20250818DeleteCommand() this.Command = JsonSerializer.SerializeToElement("delete"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMemoryTool20250818DeleteCommand( BetaMemoryTool20250818DeleteCommand betaMemoryTool20250818DeleteCommand ) : base(betaMemoryTool20250818DeleteCommand) { } +#pragma warning restore CS8618 public BetaMemoryTool20250818DeleteCommand(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818InsertCommand.cs b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818InsertCommand.cs index 2bd620d20..260795d84 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818InsertCommand.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818InsertCommand.cs @@ -85,10 +85,13 @@ public BetaMemoryTool20250818InsertCommand() this.Command = JsonSerializer.SerializeToElement("insert"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMemoryTool20250818InsertCommand( BetaMemoryTool20250818InsertCommand betaMemoryTool20250818InsertCommand ) : base(betaMemoryTool20250818InsertCommand) { } +#pragma warning restore CS8618 public BetaMemoryTool20250818InsertCommand(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818RenameCommand.cs b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818RenameCommand.cs index 8582dab75..70be0d50d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818RenameCommand.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818RenameCommand.cs @@ -71,10 +71,13 @@ public BetaMemoryTool20250818RenameCommand() this.Command = JsonSerializer.SerializeToElement("rename"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMemoryTool20250818RenameCommand( BetaMemoryTool20250818RenameCommand betaMemoryTool20250818RenameCommand ) : base(betaMemoryTool20250818RenameCommand) { } +#pragma warning restore CS8618 public BetaMemoryTool20250818RenameCommand(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818StrReplaceCommand.cs b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818StrReplaceCommand.cs index 5ff914d47..89ded4d8a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818StrReplaceCommand.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818StrReplaceCommand.cs @@ -85,10 +85,13 @@ public BetaMemoryTool20250818StrReplaceCommand() this.Command = JsonSerializer.SerializeToElement("str_replace"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMemoryTool20250818StrReplaceCommand( BetaMemoryTool20250818StrReplaceCommand betaMemoryTool20250818StrReplaceCommand ) : base(betaMemoryTool20250818StrReplaceCommand) { } +#pragma warning restore CS8618 public BetaMemoryTool20250818StrReplaceCommand(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818ViewCommand.cs b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818ViewCommand.cs index 51d77ada6..545988ba6 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818ViewCommand.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818ViewCommand.cs @@ -83,10 +83,13 @@ public BetaMemoryTool20250818ViewCommand() this.Command = JsonSerializer.SerializeToElement("view"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMemoryTool20250818ViewCommand( BetaMemoryTool20250818ViewCommand betaMemoryTool20250818ViewCommand ) : base(betaMemoryTool20250818ViewCommand) { } +#pragma warning restore CS8618 public BetaMemoryTool20250818ViewCommand(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMessage.cs b/src/Anthropic/Models/Beta/Messages/BetaMessage.cs index f36c3eca4..2d37e4ff5 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMessage.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMessage.cs @@ -237,8 +237,11 @@ public BetaMessage() this.Type = JsonSerializer.SerializeToElement("message"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessage(BetaMessage betaMessage) : base(betaMessage) { } +#pragma warning restore CS8618 public BetaMessage(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMessageDeltaUsage.cs b/src/Anthropic/Models/Beta/Messages/BetaMessageDeltaUsage.cs index d85bd3817..7e60296de 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMessageDeltaUsage.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMessageDeltaUsage.cs @@ -87,8 +87,11 @@ public override void Validate() public BetaMessageDeltaUsage() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessageDeltaUsage(BetaMessageDeltaUsage betaMessageDeltaUsage) : base(betaMessageDeltaUsage) { } +#pragma warning restore CS8618 public BetaMessageDeltaUsage(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMessageParam.cs b/src/Anthropic/Models/Beta/Messages/BetaMessageParam.cs index c49d8bb4f..5297e35ae 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMessageParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMessageParam.cs @@ -42,8 +42,11 @@ public override void Validate() public BetaMessageParam() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessageParam(BetaMessageParam betaMessageParam) : base(betaMessageParam) { } +#pragma warning restore CS8618 public BetaMessageParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMessageTokensCount.cs b/src/Anthropic/Models/Beta/Messages/BetaMessageTokensCount.cs index 4429dc149..64506d923 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMessageTokensCount.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMessageTokensCount.cs @@ -48,8 +48,11 @@ public override void Validate() public BetaMessageTokensCount() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMessageTokensCount(BetaMessageTokensCount betaMessageTokensCount) : base(betaMessageTokensCount) { } +#pragma warning restore CS8618 public BetaMessageTokensCount(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaMetadata.cs b/src/Anthropic/Models/Beta/Messages/BetaMetadata.cs index 95562a165..b6b201946 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMetadata.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMetadata.cs @@ -35,8 +35,11 @@ public override void Validate() public BetaMetadata() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaMetadata(BetaMetadata betaMetadata) : base(betaMetadata) { } +#pragma warning restore CS8618 public BetaMetadata(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs b/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs index 6b5880d3a..89bbc8dc8 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs @@ -48,8 +48,11 @@ public override void Validate() public BetaOutputConfig() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaOutputConfig(BetaOutputConfig betaOutputConfig) : base(betaOutputConfig) { } +#pragma warning restore CS8618 public BetaOutputConfig(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaPlainTextSource.cs b/src/Anthropic/Models/Beta/Messages/BetaPlainTextSource.cs index 9382ce006..9ce8c94b6 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaPlainTextSource.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaPlainTextSource.cs @@ -63,8 +63,11 @@ public BetaPlainTextSource() this.Type = JsonSerializer.SerializeToElement("text"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaPlainTextSource(BetaPlainTextSource betaPlainTextSource) : base(betaPlainTextSource) { } +#pragma warning restore CS8618 public BetaPlainTextSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDeltaEvent.cs b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDeltaEvent.cs index cb528e127..0b694b53f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDeltaEvent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDeltaEvent.cs @@ -64,10 +64,13 @@ public BetaRawContentBlockDeltaEvent() this.Type = JsonSerializer.SerializeToElement("content_block_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRawContentBlockDeltaEvent( BetaRawContentBlockDeltaEvent betaRawContentBlockDeltaEvent ) : base(betaRawContentBlockDeltaEvent) { } +#pragma warning restore CS8618 public BetaRawContentBlockDeltaEvent(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs index 0573d8b6b..d190603d7 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs @@ -68,10 +68,13 @@ public BetaRawContentBlockStartEvent() this.Type = JsonSerializer.SerializeToElement("content_block_start"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRawContentBlockStartEvent( BetaRawContentBlockStartEvent betaRawContentBlockStartEvent ) : base(betaRawContentBlockStartEvent) { } +#pragma warning restore CS8618 public BetaRawContentBlockStartEvent(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStopEvent.cs b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStopEvent.cs index dbda0f195..8ea0b6abc 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStopEvent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStopEvent.cs @@ -53,8 +53,11 @@ public BetaRawContentBlockStopEvent() this.Type = JsonSerializer.SerializeToElement("content_block_stop"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRawContentBlockStopEvent(BetaRawContentBlockStopEvent betaRawContentBlockStopEvent) : base(betaRawContentBlockStopEvent) { } +#pragma warning restore CS8618 public BetaRawContentBlockStopEvent(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawMessageDeltaEvent.cs b/src/Anthropic/Models/Beta/Messages/BetaRawMessageDeltaEvent.cs index 8715175e7..16ee9953a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawMessageDeltaEvent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawMessageDeltaEvent.cs @@ -92,8 +92,11 @@ public BetaRawMessageDeltaEvent() this.Type = JsonSerializer.SerializeToElement("message_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRawMessageDeltaEvent(BetaRawMessageDeltaEvent betaRawMessageDeltaEvent) : base(betaRawMessageDeltaEvent) { } +#pragma warning restore CS8618 public BetaRawMessageDeltaEvent(IReadOnlyDictionary rawData) { @@ -173,8 +176,11 @@ public override void Validate() public Delta() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Delta(Delta delta) : base(delta) { } +#pragma warning restore CS8618 public Delta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawMessageStartEvent.cs b/src/Anthropic/Models/Beta/Messages/BetaRawMessageStartEvent.cs index 504fb91f8..6f1f33e8f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawMessageStartEvent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawMessageStartEvent.cs @@ -48,8 +48,11 @@ public BetaRawMessageStartEvent() this.Type = JsonSerializer.SerializeToElement("message_start"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRawMessageStartEvent(BetaRawMessageStartEvent betaRawMessageStartEvent) : base(betaRawMessageStartEvent) { } +#pragma warning restore CS8618 public BetaRawMessageStartEvent(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawMessageStopEvent.cs b/src/Anthropic/Models/Beta/Messages/BetaRawMessageStopEvent.cs index d876b56bf..5c1d37a76 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawMessageStopEvent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawMessageStopEvent.cs @@ -35,8 +35,11 @@ public BetaRawMessageStopEvent() this.Type = JsonSerializer.SerializeToElement("message_stop"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRawMessageStopEvent(BetaRawMessageStopEvent betaRawMessageStopEvent) : base(betaRawMessageStopEvent) { } +#pragma warning restore CS8618 public BetaRawMessageStopEvent(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRedactedThinkingBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaRedactedThinkingBlock.cs index 925c9e009..3052b74e5 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRedactedThinkingBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRedactedThinkingBlock.cs @@ -53,8 +53,11 @@ public BetaRedactedThinkingBlock() this.Type = JsonSerializer.SerializeToElement("redacted_thinking"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRedactedThinkingBlock(BetaRedactedThinkingBlock betaRedactedThinkingBlock) : base(betaRedactedThinkingBlock) { } +#pragma warning restore CS8618 public BetaRedactedThinkingBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRedactedThinkingBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaRedactedThinkingBlockParam.cs index aa08f60d4..d3598023b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRedactedThinkingBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRedactedThinkingBlockParam.cs @@ -56,10 +56,13 @@ public BetaRedactedThinkingBlockParam() this.Type = JsonSerializer.SerializeToElement("redacted_thinking"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRedactedThinkingBlockParam( BetaRedactedThinkingBlockParam betaRedactedThinkingBlockParam ) : base(betaRedactedThinkingBlockParam) { } +#pragma warning restore CS8618 public BetaRedactedThinkingBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRequestDocumentBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaRequestDocumentBlock.cs index 5deb89140..abf2e2053 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRequestDocumentBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRequestDocumentBlock.cs @@ -96,8 +96,11 @@ public BetaRequestDocumentBlock() this.Type = JsonSerializer.SerializeToElement("document"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRequestDocumentBlock(BetaRequestDocumentBlock betaRequestDocumentBlock) : base(betaRequestDocumentBlock) { } +#pragma warning restore CS8618 public BetaRequestDocumentBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRequestMcpServerToolConfiguration.cs b/src/Anthropic/Models/Beta/Messages/BetaRequestMcpServerToolConfiguration.cs index 79459fe90..c165a7fe3 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRequestMcpServerToolConfiguration.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRequestMcpServerToolConfiguration.cs @@ -51,10 +51,13 @@ public override void Validate() public BetaRequestMcpServerToolConfiguration() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRequestMcpServerToolConfiguration( BetaRequestMcpServerToolConfiguration betaRequestMcpServerToolConfiguration ) : base(betaRequestMcpServerToolConfiguration) { } +#pragma warning restore CS8618 public BetaRequestMcpServerToolConfiguration(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRequestMcpServerUrlDefinition.cs b/src/Anthropic/Models/Beta/Messages/BetaRequestMcpServerUrlDefinition.cs index bcc63a1f0..17dfa58be 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRequestMcpServerUrlDefinition.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRequestMcpServerUrlDefinition.cs @@ -86,10 +86,13 @@ public BetaRequestMcpServerUrlDefinition() this.Type = JsonSerializer.SerializeToElement("url"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRequestMcpServerUrlDefinition( BetaRequestMcpServerUrlDefinition betaRequestMcpServerUrlDefinition ) : base(betaRequestMcpServerUrlDefinition) { } +#pragma warning restore CS8618 public BetaRequestMcpServerUrlDefinition(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaRequestMcpToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaRequestMcpToolResultBlockParam.cs index 0520c78a4..30940989e 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRequestMcpToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRequestMcpToolResultBlockParam.cs @@ -109,10 +109,13 @@ public BetaRequestMcpToolResultBlockParam() this.Type = JsonSerializer.SerializeToElement("mcp_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaRequestMcpToolResultBlockParam( BetaRequestMcpToolResultBlockParam betaRequestMcpToolResultBlockParam ) : base(betaRequestMcpToolResultBlockParam) { } +#pragma warning restore CS8618 public BetaRequestMcpToolResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaSearchResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaSearchResultBlockParam.cs index 0bbd8f216..160872e73 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaSearchResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaSearchResultBlockParam.cs @@ -113,8 +113,11 @@ public BetaSearchResultBlockParam() this.Type = JsonSerializer.SerializeToElement("search_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaSearchResultBlockParam(BetaSearchResultBlockParam betaSearchResultBlockParam) : base(betaSearchResultBlockParam) { } +#pragma warning restore CS8618 public BetaSearchResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaServerToolCaller.cs b/src/Anthropic/Models/Beta/Messages/BetaServerToolCaller.cs index 46309da5b..32170364a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaServerToolCaller.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaServerToolCaller.cs @@ -54,8 +54,11 @@ public BetaServerToolCaller() this.Type = JsonSerializer.SerializeToElement("code_execution_20250825"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaServerToolCaller(BetaServerToolCaller betaServerToolCaller) : base(betaServerToolCaller) { } +#pragma warning restore CS8618 public BetaServerToolCaller(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaServerToolUsage.cs b/src/Anthropic/Models/Beta/Messages/BetaServerToolUsage.cs index 7a8969aca..c03e55eba 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaServerToolUsage.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaServerToolUsage.cs @@ -45,8 +45,11 @@ public override void Validate() public BetaServerToolUsage() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaServerToolUsage(BetaServerToolUsage betaServerToolUsage) : base(betaServerToolUsage) { } +#pragma warning restore CS8618 public BetaServerToolUsage(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs index 8bf17a7dd..32215d57c 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs @@ -99,8 +99,11 @@ public BetaServerToolUseBlock() this.Type = JsonSerializer.SerializeToElement("server_tool_use"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaServerToolUseBlock(BetaServerToolUseBlock betaServerToolUseBlock) : base(betaServerToolUseBlock) { } +#pragma warning restore CS8618 public BetaServerToolUseBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlockParam.cs index 8c928a088..eb79f4015 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlockParam.cs @@ -117,8 +117,11 @@ public BetaServerToolUseBlockParam() this.Type = JsonSerializer.SerializeToElement("server_tool_use"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaServerToolUseBlockParam(BetaServerToolUseBlockParam betaServerToolUseBlockParam) : base(betaServerToolUseBlockParam) { } +#pragma warning restore CS8618 public BetaServerToolUseBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaSignatureDelta.cs b/src/Anthropic/Models/Beta/Messages/BetaSignatureDelta.cs index b30bfeedb..70b996644 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaSignatureDelta.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaSignatureDelta.cs @@ -48,8 +48,11 @@ public BetaSignatureDelta() this.Type = JsonSerializer.SerializeToElement("signature_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaSignatureDelta(BetaSignatureDelta betaSignatureDelta) : base(betaSignatureDelta) { } +#pragma warning restore CS8618 public BetaSignatureDelta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaSkill.cs b/src/Anthropic/Models/Beta/Messages/BetaSkill.cs index 800b93994..fbba6a9a6 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaSkill.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaSkill.cs @@ -66,8 +66,11 @@ public override void Validate() public BetaSkill() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaSkill(BetaSkill betaSkill) : base(betaSkill) { } +#pragma warning restore CS8618 public BetaSkill(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaSkillParams.cs b/src/Anthropic/Models/Beta/Messages/BetaSkillParams.cs index dfd6b6a0b..7c104136b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaSkillParams.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaSkillParams.cs @@ -72,8 +72,11 @@ public override void Validate() public BetaSkillParams() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaSkillParams(BetaSkillParams betaSkillParams) : base(betaSkillParams) { } +#pragma warning restore CS8618 public BetaSkillParams(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaTextBlock.cs index 01468c736..1fdb6a5cd 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextBlock.cs @@ -74,8 +74,11 @@ public BetaTextBlock() this.Type = JsonSerializer.SerializeToElement("text"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextBlock(BetaTextBlock betaTextBlock) : base(betaTextBlock) { } +#pragma warning restore CS8618 public BetaTextBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaTextBlockParam.cs index 7df593c33..ab433e5f8 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextBlockParam.cs @@ -83,8 +83,11 @@ public BetaTextBlockParam() this.Type = JsonSerializer.SerializeToElement("text"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextBlockParam(BetaTextBlockParam betaTextBlockParam) : base(betaTextBlockParam) { } +#pragma warning restore CS8618 public BetaTextBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextDelta.cs b/src/Anthropic/Models/Beta/Messages/BetaTextDelta.cs index c4bd5d12c..8073cc7e6 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextDelta.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextDelta.cs @@ -46,8 +46,11 @@ public BetaTextDelta() this.Type = JsonSerializer.SerializeToElement("text_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextDelta(BetaTextDelta betaTextDelta) : base(betaTextDelta) { } +#pragma warning restore CS8618 public BetaTextDelta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlock.cs index aef2fce9c..042d8f85b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlock.cs @@ -56,10 +56,13 @@ public BetaTextEditorCodeExecutionCreateResultBlock() this.Type = JsonSerializer.SerializeToElement("text_editor_code_execution_create_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextEditorCodeExecutionCreateResultBlock( BetaTextEditorCodeExecutionCreateResultBlock betaTextEditorCodeExecutionCreateResultBlock ) : base(betaTextEditorCodeExecutionCreateResultBlock) { } +#pragma warning restore CS8618 public BetaTextEditorCodeExecutionCreateResultBlock( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockParam.cs index f7189eaca..c59aa7755 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionCreateResultBlockParam.cs @@ -56,10 +56,13 @@ public BetaTextEditorCodeExecutionCreateResultBlockParam() this.Type = JsonSerializer.SerializeToElement("text_editor_code_execution_create_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextEditorCodeExecutionCreateResultBlockParam( BetaTextEditorCodeExecutionCreateResultBlockParam betaTextEditorCodeExecutionCreateResultBlockParam ) : base(betaTextEditorCodeExecutionCreateResultBlockParam) { } +#pragma warning restore CS8618 public BetaTextEditorCodeExecutionCreateResultBlockParam( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlock.cs index 11eadbd70..ba6b06bd6 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlock.cs @@ -109,10 +109,13 @@ public BetaTextEditorCodeExecutionStrReplaceResultBlock() ); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextEditorCodeExecutionStrReplaceResultBlock( BetaTextEditorCodeExecutionStrReplaceResultBlock betaTextEditorCodeExecutionStrReplaceResultBlock ) : base(betaTextEditorCodeExecutionStrReplaceResultBlock) { } +#pragma warning restore CS8618 public BetaTextEditorCodeExecutionStrReplaceResultBlock( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockParam.cs index 1c55c15ac..5a9ec7ac3 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionStrReplaceResultBlockParam.cs @@ -109,10 +109,13 @@ public BetaTextEditorCodeExecutionStrReplaceResultBlockParam() ); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextEditorCodeExecutionStrReplaceResultBlockParam( BetaTextEditorCodeExecutionStrReplaceResultBlockParam betaTextEditorCodeExecutionStrReplaceResultBlockParam ) : base(betaTextEditorCodeExecutionStrReplaceResultBlockParam) { } +#pragma warning restore CS8618 public BetaTextEditorCodeExecutionStrReplaceResultBlockParam( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlock.cs index fa3159bb0..080252174 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlock.cs @@ -70,10 +70,13 @@ public BetaTextEditorCodeExecutionToolResultBlock() this.Type = JsonSerializer.SerializeToElement("text_editor_code_execution_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextEditorCodeExecutionToolResultBlock( BetaTextEditorCodeExecutionToolResultBlock betaTextEditorCodeExecutionToolResultBlock ) : base(betaTextEditorCodeExecutionToolResultBlock) { } +#pragma warning restore CS8618 public BetaTextEditorCodeExecutionToolResultBlock( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParam.cs index 9ee860384..81218b81b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParam.cs @@ -84,10 +84,13 @@ public BetaTextEditorCodeExecutionToolResultBlockParam() this.Type = JsonSerializer.SerializeToElement("text_editor_code_execution_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextEditorCodeExecutionToolResultBlockParam( BetaTextEditorCodeExecutionToolResultBlockParam betaTextEditorCodeExecutionToolResultBlockParam ) : base(betaTextEditorCodeExecutionToolResultBlockParam) { } +#pragma warning restore CS8618 public BetaTextEditorCodeExecutionToolResultBlockParam( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultError.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultError.cs index b975ea799..7e274b768 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultError.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultError.cs @@ -72,10 +72,13 @@ public BetaTextEditorCodeExecutionToolResultError() ); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextEditorCodeExecutionToolResultError( BetaTextEditorCodeExecutionToolResultError betaTextEditorCodeExecutionToolResultError ) : base(betaTextEditorCodeExecutionToolResultError) { } +#pragma warning restore CS8618 public BetaTextEditorCodeExecutionToolResultError( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorParam.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorParam.cs index 640ee0830..2db396509 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultErrorParam.cs @@ -75,10 +75,13 @@ public BetaTextEditorCodeExecutionToolResultErrorParam() ); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextEditorCodeExecutionToolResultErrorParam( BetaTextEditorCodeExecutionToolResultErrorParam betaTextEditorCodeExecutionToolResultErrorParam ) : base(betaTextEditorCodeExecutionToolResultErrorParam) { } +#pragma warning restore CS8618 public BetaTextEditorCodeExecutionToolResultErrorParam( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlock.cs index 4ba9d2485..c6fd840af 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlock.cs @@ -101,10 +101,13 @@ public BetaTextEditorCodeExecutionViewResultBlock() this.Type = JsonSerializer.SerializeToElement("text_editor_code_execution_view_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextEditorCodeExecutionViewResultBlock( BetaTextEditorCodeExecutionViewResultBlock betaTextEditorCodeExecutionViewResultBlock ) : base(betaTextEditorCodeExecutionViewResultBlock) { } +#pragma warning restore CS8618 public BetaTextEditorCodeExecutionViewResultBlock( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockParam.cs index f80dd311d..3297487b3 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionViewResultBlockParam.cs @@ -106,10 +106,13 @@ public BetaTextEditorCodeExecutionViewResultBlockParam() this.Type = JsonSerializer.SerializeToElement("text_editor_code_execution_view_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTextEditorCodeExecutionViewResultBlockParam( BetaTextEditorCodeExecutionViewResultBlockParam betaTextEditorCodeExecutionViewResultBlockParam ) : base(betaTextEditorCodeExecutionViewResultBlockParam) { } +#pragma warning restore CS8618 public BetaTextEditorCodeExecutionViewResultBlockParam( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaThinkingBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaThinkingBlock.cs index 79a0c228b..ae324013c 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaThinkingBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaThinkingBlock.cs @@ -57,8 +57,11 @@ public BetaThinkingBlock() this.Type = JsonSerializer.SerializeToElement("thinking"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaThinkingBlock(BetaThinkingBlock betaThinkingBlock) : base(betaThinkingBlock) { } +#pragma warning restore CS8618 public BetaThinkingBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaThinkingBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaThinkingBlockParam.cs index 5f383f110..371c1db36 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaThinkingBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaThinkingBlockParam.cs @@ -57,8 +57,11 @@ public BetaThinkingBlockParam() this.Type = JsonSerializer.SerializeToElement("thinking"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaThinkingBlockParam(BetaThinkingBlockParam betaThinkingBlockParam) : base(betaThinkingBlockParam) { } +#pragma warning restore CS8618 public BetaThinkingBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigDisabled.cs b/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigDisabled.cs index 78168819c..a0b2f6755 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigDisabled.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigDisabled.cs @@ -37,8 +37,11 @@ public BetaThinkingConfigDisabled() this.Type = JsonSerializer.SerializeToElement("disabled"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaThinkingConfigDisabled(BetaThinkingConfigDisabled betaThinkingConfigDisabled) : base(betaThinkingConfigDisabled) { } +#pragma warning restore CS8618 public BetaThinkingConfigDisabled(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigEnabled.cs b/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigEnabled.cs index fef4e91bd..ba4cdf2fa 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigEnabled.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigEnabled.cs @@ -58,8 +58,11 @@ public BetaThinkingConfigEnabled() this.Type = JsonSerializer.SerializeToElement("enabled"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaThinkingConfigEnabled(BetaThinkingConfigEnabled betaThinkingConfigEnabled) : base(betaThinkingConfigEnabled) { } +#pragma warning restore CS8618 public BetaThinkingConfigEnabled(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaThinkingDelta.cs b/src/Anthropic/Models/Beta/Messages/BetaThinkingDelta.cs index 994985c58..e3016d495 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaThinkingDelta.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaThinkingDelta.cs @@ -46,8 +46,11 @@ public BetaThinkingDelta() this.Type = JsonSerializer.SerializeToElement("thinking_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaThinkingDelta(BetaThinkingDelta betaThinkingDelta) : base(betaThinkingDelta) { } +#pragma warning restore CS8618 public BetaThinkingDelta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaThinkingTurns.cs b/src/Anthropic/Models/Beta/Messages/BetaThinkingTurns.cs index b61517693..e5e52e684 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaThinkingTurns.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaThinkingTurns.cs @@ -46,8 +46,11 @@ public BetaThinkingTurns() this.Type = JsonSerializer.SerializeToElement("thinking_turns"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaThinkingTurns(BetaThinkingTurns betaThinkingTurns) : base(betaThinkingTurns) { } +#pragma warning restore CS8618 public BetaThinkingTurns(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaTool.cs b/src/Anthropic/Models/Beta/Messages/BetaTool.cs index 7063b9caf..a43ce5d16 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTool.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTool.cs @@ -206,8 +206,11 @@ public override void Validate() public BetaTool() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaTool(BetaTool betaTool) : base(betaTool) { } +#pragma warning restore CS8618 public BetaTool(IReadOnlyDictionary rawData) { @@ -305,8 +308,11 @@ public InputSchema() this.Type = JsonSerializer.SerializeToElement("object"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public InputSchema(InputSchema inputSchema) : base(inputSchema) { } +#pragma warning restore CS8618 public InputSchema(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolBash20241022.cs b/src/Anthropic/Models/Beta/Messages/BetaToolBash20241022.cs index 5e9169449..63d1b2bac 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolBash20241022.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolBash20241022.cs @@ -172,8 +172,11 @@ public BetaToolBash20241022() this.Type = JsonSerializer.SerializeToElement("bash_20241022"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolBash20241022(BetaToolBash20241022 betaToolBash20241022) : base(betaToolBash20241022) { } +#pragma warning restore CS8618 public BetaToolBash20241022(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolBash20250124.cs b/src/Anthropic/Models/Beta/Messages/BetaToolBash20250124.cs index 772b8a6be..4590d653f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolBash20250124.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolBash20250124.cs @@ -172,8 +172,11 @@ public BetaToolBash20250124() this.Type = JsonSerializer.SerializeToElement("bash_20250124"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolBash20250124(BetaToolBash20250124 betaToolBash20250124) : base(betaToolBash20250124) { } +#pragma warning restore CS8618 public BetaToolBash20250124(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolChoiceAny.cs b/src/Anthropic/Models/Beta/Messages/BetaToolChoiceAny.cs index e3ef716ef..f4bf3cc4d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolChoiceAny.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolChoiceAny.cs @@ -63,8 +63,11 @@ public BetaToolChoiceAny() this.Type = JsonSerializer.SerializeToElement("any"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolChoiceAny(BetaToolChoiceAny betaToolChoiceAny) : base(betaToolChoiceAny) { } +#pragma warning restore CS8618 public BetaToolChoiceAny(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolChoiceAuto.cs b/src/Anthropic/Models/Beta/Messages/BetaToolChoiceAuto.cs index f2f8c04d8..67d5497f7 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolChoiceAuto.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolChoiceAuto.cs @@ -63,8 +63,11 @@ public BetaToolChoiceAuto() this.Type = JsonSerializer.SerializeToElement("auto"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolChoiceAuto(BetaToolChoiceAuto betaToolChoiceAuto) : base(betaToolChoiceAuto) { } +#pragma warning restore CS8618 public BetaToolChoiceAuto(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolChoiceNone.cs b/src/Anthropic/Models/Beta/Messages/BetaToolChoiceNone.cs index 71609db92..6a560630d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolChoiceNone.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolChoiceNone.cs @@ -38,8 +38,11 @@ public BetaToolChoiceNone() this.Type = JsonSerializer.SerializeToElement("none"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolChoiceNone(BetaToolChoiceNone betaToolChoiceNone) : base(betaToolChoiceNone) { } +#pragma warning restore CS8618 public BetaToolChoiceNone(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolChoiceTool.cs b/src/Anthropic/Models/Beta/Messages/BetaToolChoiceTool.cs index d5a73049b..236d99d2d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolChoiceTool.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolChoiceTool.cs @@ -77,8 +77,11 @@ public BetaToolChoiceTool() this.Type = JsonSerializer.SerializeToElement("tool"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolChoiceTool(BetaToolChoiceTool betaToolChoiceTool) : base(betaToolChoiceTool) { } +#pragma warning restore CS8618 public BetaToolChoiceTool(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20241022.cs b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20241022.cs index 894bee339..d1b097236 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20241022.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20241022.cs @@ -220,8 +220,11 @@ public BetaToolComputerUse20241022() this.Type = JsonSerializer.SerializeToElement("computer_20241022"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolComputerUse20241022(BetaToolComputerUse20241022 betaToolComputerUse20241022) : base(betaToolComputerUse20241022) { } +#pragma warning restore CS8618 public BetaToolComputerUse20241022(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20250124.cs b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20250124.cs index b694b20dc..80713407f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20250124.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20250124.cs @@ -220,8 +220,11 @@ public BetaToolComputerUse20250124() this.Type = JsonSerializer.SerializeToElement("computer_20250124"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolComputerUse20250124(BetaToolComputerUse20250124 betaToolComputerUse20250124) : base(betaToolComputerUse20250124) { } +#pragma warning restore CS8618 public BetaToolComputerUse20250124(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20251124.cs b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20251124.cs index a86e50f90..f4d7eaff5 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20251124.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20251124.cs @@ -242,8 +242,11 @@ public BetaToolComputerUse20251124() this.Type = JsonSerializer.SerializeToElement("computer_20251124"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolComputerUse20251124(BetaToolComputerUse20251124 betaToolComputerUse20251124) : base(betaToolComputerUse20251124) { } +#pragma warning restore CS8618 public BetaToolComputerUse20251124(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolReferenceBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaToolReferenceBlock.cs index fd382f9bb..bd059b6b0 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolReferenceBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolReferenceBlock.cs @@ -46,8 +46,11 @@ public BetaToolReferenceBlock() this.Type = JsonSerializer.SerializeToElement("tool_reference"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolReferenceBlock(BetaToolReferenceBlock betaToolReferenceBlock) : base(betaToolReferenceBlock) { } +#pragma warning restore CS8618 public BetaToolReferenceBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolReferenceBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaToolReferenceBlockParam.cs index 5a81b2c4b..9087d095d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolReferenceBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolReferenceBlockParam.cs @@ -65,8 +65,11 @@ public BetaToolReferenceBlockParam() this.Type = JsonSerializer.SerializeToElement("tool_reference"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolReferenceBlockParam(BetaToolReferenceBlockParam betaToolReferenceBlockParam) : base(betaToolReferenceBlockParam) { } +#pragma warning restore CS8618 public BetaToolReferenceBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaToolResultBlockParam.cs index 3a19028d6..71d892b23 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolResultBlockParam.cs @@ -102,8 +102,11 @@ public BetaToolResultBlockParam() this.Type = JsonSerializer.SerializeToElement("tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolResultBlockParam(BetaToolResultBlockParam betaToolResultBlockParam) : base(betaToolResultBlockParam) { } +#pragma warning restore CS8618 public BetaToolResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolBm25_20251119.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolBm25_20251119.cs index ec4674be8..fae3dc3cc 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolBm25_20251119.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolBm25_20251119.cs @@ -149,10 +149,13 @@ public BetaToolSearchToolBm25_20251119() this.Name = JsonSerializer.SerializeToElement("tool_search_tool_bm25"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolSearchToolBm25_20251119( BetaToolSearchToolBm25_20251119 betaToolSearchToolBm25_20251119 ) : base(betaToolSearchToolBm25_20251119) { } +#pragma warning restore CS8618 public BetaToolSearchToolBm25_20251119(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolRegex20251119.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolRegex20251119.cs index bcc3ed0e7..cef63a353 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolRegex20251119.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolRegex20251119.cs @@ -149,10 +149,13 @@ public BetaToolSearchToolRegex20251119() this.Name = JsonSerializer.SerializeToElement("tool_search_tool_regex"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolSearchToolRegex20251119( BetaToolSearchToolRegex20251119 betaToolSearchToolRegex20251119 ) : base(betaToolSearchToolRegex20251119) { } +#pragma warning restore CS8618 public BetaToolSearchToolRegex20251119(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlock.cs index 675281100..0f67f217f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlock.cs @@ -65,10 +65,13 @@ public BetaToolSearchToolResultBlock() this.Type = JsonSerializer.SerializeToElement("tool_search_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolSearchToolResultBlock( BetaToolSearchToolResultBlock betaToolSearchToolResultBlock ) : base(betaToolSearchToolResultBlock) { } +#pragma warning restore CS8618 public BetaToolSearchToolResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlockParam.cs index 0a45cae6f..163cec93d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlockParam.cs @@ -84,10 +84,13 @@ public BetaToolSearchToolResultBlockParam() this.Type = JsonSerializer.SerializeToElement("tool_search_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolSearchToolResultBlockParam( BetaToolSearchToolResultBlockParam betaToolSearchToolResultBlockParam ) : base(betaToolSearchToolResultBlockParam) { } +#pragma warning restore CS8618 public BetaToolSearchToolResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultError.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultError.cs index 90b9c4f02..64906cdda 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultError.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultError.cs @@ -67,10 +67,13 @@ public BetaToolSearchToolResultError() this.Type = JsonSerializer.SerializeToElement("tool_search_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolSearchToolResultError( BetaToolSearchToolResultError betaToolSearchToolResultError ) : base(betaToolSearchToolResultError) { } +#pragma warning restore CS8618 public BetaToolSearchToolResultError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultErrorParam.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultErrorParam.cs index 3f49f5404..652bfe90d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultErrorParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultErrorParam.cs @@ -59,10 +59,13 @@ public BetaToolSearchToolResultErrorParam() this.Type = JsonSerializer.SerializeToElement("tool_search_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolSearchToolResultErrorParam( BetaToolSearchToolResultErrorParam betaToolSearchToolResultErrorParam ) : base(betaToolSearchToolResultErrorParam) { } +#pragma warning restore CS8618 public BetaToolSearchToolResultErrorParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolSearchResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolSearchResultBlock.cs index 9058ecf5a..8f670413d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolSearchResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolSearchResultBlock.cs @@ -68,10 +68,13 @@ public BetaToolSearchToolSearchResultBlock() this.Type = JsonSerializer.SerializeToElement("tool_search_tool_search_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolSearchToolSearchResultBlock( BetaToolSearchToolSearchResultBlock betaToolSearchToolSearchResultBlock ) : base(betaToolSearchToolSearchResultBlock) { } +#pragma warning restore CS8618 public BetaToolSearchToolSearchResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockParam.cs index 6789f81a9..b52da3b83 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolSearchResultBlockParam.cs @@ -68,10 +68,13 @@ public BetaToolSearchToolSearchResultBlockParam() this.Type = JsonSerializer.SerializeToElement("tool_search_tool_search_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolSearchToolSearchResultBlockParam( BetaToolSearchToolSearchResultBlockParam betaToolSearchToolSearchResultBlockParam ) : base(betaToolSearchToolSearchResultBlockParam) { } +#pragma warning restore CS8618 public BetaToolSearchToolSearchResultBlockParam( IReadOnlyDictionary rawData diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20241022.cs b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20241022.cs index 01cb73760..d985480b1 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20241022.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20241022.cs @@ -183,8 +183,11 @@ public BetaToolTextEditor20241022() this.Type = JsonSerializer.SerializeToElement("text_editor_20241022"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolTextEditor20241022(BetaToolTextEditor20241022 betaToolTextEditor20241022) : base(betaToolTextEditor20241022) { } +#pragma warning restore CS8618 public BetaToolTextEditor20241022(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250124.cs b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250124.cs index 0692fff31..25d1c127a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250124.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250124.cs @@ -183,8 +183,11 @@ public BetaToolTextEditor20250124() this.Type = JsonSerializer.SerializeToElement("text_editor_20250124"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolTextEditor20250124(BetaToolTextEditor20250124 betaToolTextEditor20250124) : base(betaToolTextEditor20250124) { } +#pragma warning restore CS8618 public BetaToolTextEditor20250124(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250429.cs b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250429.cs index d427804f9..9e05b75fa 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250429.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250429.cs @@ -183,8 +183,11 @@ public BetaToolTextEditor20250429() this.Type = JsonSerializer.SerializeToElement("text_editor_20250429"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolTextEditor20250429(BetaToolTextEditor20250429 betaToolTextEditor20250429) : base(betaToolTextEditor20250429) { } +#pragma warning restore CS8618 public BetaToolTextEditor20250429(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250728.cs b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250728.cs index ce8991d7e..90df6396d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250728.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250728.cs @@ -198,8 +198,11 @@ public BetaToolTextEditor20250728() this.Type = JsonSerializer.SerializeToElement("text_editor_20250728"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolTextEditor20250728(BetaToolTextEditor20250728 betaToolTextEditor20250728) : base(betaToolTextEditor20250728) { } +#pragma warning restore CS8618 public BetaToolTextEditor20250728(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolUseBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaToolUseBlock.cs index e82891f7b..8f476ae17 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolUseBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolUseBlock.cs @@ -97,8 +97,11 @@ public BetaToolUseBlock() this.Type = JsonSerializer.SerializeToElement("tool_use"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolUseBlock(BetaToolUseBlock betaToolUseBlock) : base(betaToolUseBlock) { } +#pragma warning restore CS8618 public BetaToolUseBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolUseBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaToolUseBlockParam.cs index d571b2d6b..7062988a5 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolUseBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolUseBlockParam.cs @@ -111,8 +111,11 @@ public BetaToolUseBlockParam() this.Type = JsonSerializer.SerializeToElement("tool_use"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolUseBlockParam(BetaToolUseBlockParam betaToolUseBlockParam) : base(betaToolUseBlockParam) { } +#pragma warning restore CS8618 public BetaToolUseBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolUsesKeep.cs b/src/Anthropic/Models/Beta/Messages/BetaToolUsesKeep.cs index 7d1215ce3..567bddf5d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolUsesKeep.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolUsesKeep.cs @@ -46,8 +46,11 @@ public BetaToolUsesKeep() this.Type = JsonSerializer.SerializeToElement("tool_uses"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolUsesKeep(BetaToolUsesKeep betaToolUsesKeep) : base(betaToolUsesKeep) { } +#pragma warning restore CS8618 public BetaToolUsesKeep(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolUsesTrigger.cs b/src/Anthropic/Models/Beta/Messages/BetaToolUsesTrigger.cs index 0f2f5142c..7eb26bf11 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolUsesTrigger.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolUsesTrigger.cs @@ -46,8 +46,11 @@ public BetaToolUsesTrigger() this.Type = JsonSerializer.SerializeToElement("tool_uses"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaToolUsesTrigger(BetaToolUsesTrigger betaToolUsesTrigger) : base(betaToolUsesTrigger) { } +#pragma warning restore CS8618 public BetaToolUsesTrigger(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaUrlImageSource.cs b/src/Anthropic/Models/Beta/Messages/BetaUrlImageSource.cs index 5ee610985..735736877 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaUrlImageSource.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaUrlImageSource.cs @@ -46,8 +46,11 @@ public BetaUrlImageSource() this.Type = JsonSerializer.SerializeToElement("url"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaUrlImageSource(BetaUrlImageSource betaUrlImageSource) : base(betaUrlImageSource) { } +#pragma warning restore CS8618 public BetaUrlImageSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaUrlPdfSource.cs b/src/Anthropic/Models/Beta/Messages/BetaUrlPdfSource.cs index 269199b80..4235a72bb 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaUrlPdfSource.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaUrlPdfSource.cs @@ -46,8 +46,11 @@ public BetaUrlPdfSource() this.Type = JsonSerializer.SerializeToElement("url"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaUrlPdfSource(BetaUrlPdfSource betaUrlPdfSource) : base(betaUrlPdfSource) { } +#pragma warning restore CS8618 public BetaUrlPdfSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaUsage.cs b/src/Anthropic/Models/Beta/Messages/BetaUsage.cs index 2d166d791..743aa9a5f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaUsage.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaUsage.cs @@ -119,8 +119,11 @@ public override void Validate() public BetaUsage() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaUsage(BetaUsage betaUsage) : base(betaUsage) { } +#pragma warning restore CS8618 public BetaUsage(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebFetchBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaWebFetchBlock.cs index c04f325de..0bbaca5be 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebFetchBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebFetchBlock.cs @@ -79,8 +79,11 @@ public BetaWebFetchBlock() this.Type = JsonSerializer.SerializeToElement("web_fetch_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebFetchBlock(BetaWebFetchBlock betaWebFetchBlock) : base(betaWebFetchBlock) { } +#pragma warning restore CS8618 public BetaWebFetchBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebFetchBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaWebFetchBlockParam.cs index 85df556b1..44f0ef85e 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebFetchBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebFetchBlockParam.cs @@ -79,8 +79,11 @@ public BetaWebFetchBlockParam() this.Type = JsonSerializer.SerializeToElement("web_fetch_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebFetchBlockParam(BetaWebFetchBlockParam betaWebFetchBlockParam) : base(betaWebFetchBlockParam) { } +#pragma warning restore CS8618 public BetaWebFetchBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebFetchTool20250910.cs b/src/Anthropic/Models/Beta/Messages/BetaWebFetchTool20250910.cs index 466038fd0..58ea64050 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebFetchTool20250910.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebFetchTool20250910.cs @@ -229,8 +229,11 @@ public BetaWebFetchTool20250910() this.Type = JsonSerializer.SerializeToElement("web_fetch_20250910"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebFetchTool20250910(BetaWebFetchTool20250910 betaWebFetchTool20250910) : base(betaWebFetchTool20250910) { } +#pragma warning restore CS8618 public BetaWebFetchTool20250910(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlock.cs index 0010dc71b..79c5f1c34 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlock.cs @@ -65,8 +65,11 @@ public BetaWebFetchToolResultBlock() this.Type = JsonSerializer.SerializeToElement("web_fetch_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebFetchToolResultBlock(BetaWebFetchToolResultBlock betaWebFetchToolResultBlock) : base(betaWebFetchToolResultBlock) { } +#pragma warning restore CS8618 public BetaWebFetchToolResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlockParam.cs index 03e58cb9f..521020d80 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlockParam.cs @@ -84,10 +84,13 @@ public BetaWebFetchToolResultBlockParam() this.Type = JsonSerializer.SerializeToElement("web_fetch_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebFetchToolResultBlockParam( BetaWebFetchToolResultBlockParam betaWebFetchToolResultBlockParam ) : base(betaWebFetchToolResultBlockParam) { } +#pragma warning restore CS8618 public BetaWebFetchToolResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultErrorBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultErrorBlock.cs index 7f93da146..0b0063b0f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultErrorBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultErrorBlock.cs @@ -58,10 +58,13 @@ public BetaWebFetchToolResultErrorBlock() this.Type = JsonSerializer.SerializeToElement("web_fetch_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebFetchToolResultErrorBlock( BetaWebFetchToolResultErrorBlock betaWebFetchToolResultErrorBlock ) : base(betaWebFetchToolResultErrorBlock) { } +#pragma warning restore CS8618 public BetaWebFetchToolResultErrorBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockParam.cs index 17a421ab9..808162722 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultErrorBlockParam.cs @@ -58,10 +58,13 @@ public BetaWebFetchToolResultErrorBlockParam() this.Type = JsonSerializer.SerializeToElement("web_fetch_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebFetchToolResultErrorBlockParam( BetaWebFetchToolResultErrorBlockParam betaWebFetchToolResultErrorBlockParam ) : base(betaWebFetchToolResultErrorBlockParam) { } +#pragma warning restore CS8618 public BetaWebFetchToolResultErrorBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchResultBlock.cs index 741cf99dd..5c76428a1 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchResultBlock.cs @@ -86,8 +86,11 @@ public BetaWebSearchResultBlock() this.Type = JsonSerializer.SerializeToElement("web_search_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebSearchResultBlock(BetaWebSearchResultBlock betaWebSearchResultBlock) : base(betaWebSearchResultBlock) { } +#pragma warning restore CS8618 public BetaWebSearchResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchResultBlockParam.cs index 9fe2342f5..6b5bf2f6b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchResultBlockParam.cs @@ -86,10 +86,13 @@ public BetaWebSearchResultBlockParam() this.Type = JsonSerializer.SerializeToElement("web_search_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebSearchResultBlockParam( BetaWebSearchResultBlockParam betaWebSearchResultBlockParam ) : base(betaWebSearchResultBlockParam) { } +#pragma warning restore CS8618 public BetaWebSearchResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchTool20250305.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchTool20250305.cs index 5b560a72c..79c6c5089 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchTool20250305.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchTool20250305.cs @@ -215,8 +215,11 @@ public BetaWebSearchTool20250305() this.Type = JsonSerializer.SerializeToElement("web_search_20250305"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebSearchTool20250305(BetaWebSearchTool20250305 betaWebSearchTool20250305) : base(betaWebSearchTool20250305) { } +#pragma warning restore CS8618 public BetaWebSearchTool20250305(IReadOnlyDictionary rawData) { @@ -385,8 +388,11 @@ public UserLocation() this.Type = JsonSerializer.SerializeToElement("approximate"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public UserLocation(UserLocation userLocation) : base(userLocation) { } +#pragma warning restore CS8618 public UserLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolRequestError.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolRequestError.cs index b556087bd..3ab818521 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolRequestError.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolRequestError.cs @@ -55,10 +55,13 @@ public BetaWebSearchToolRequestError() this.Type = JsonSerializer.SerializeToElement("web_search_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebSearchToolRequestError( BetaWebSearchToolRequestError betaWebSearchToolRequestError ) : base(betaWebSearchToolRequestError) { } +#pragma warning restore CS8618 public BetaWebSearchToolRequestError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlock.cs index 83af7e1cf..ee43b2dd1 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlock.cs @@ -64,8 +64,11 @@ public BetaWebSearchToolResultBlock() this.Type = JsonSerializer.SerializeToElement("web_search_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebSearchToolResultBlock(BetaWebSearchToolResultBlock betaWebSearchToolResultBlock) : base(betaWebSearchToolResultBlock) { } +#pragma warning restore CS8618 public BetaWebSearchToolResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockParam.cs index 80300443f..1f7b5606c 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockParam.cs @@ -83,10 +83,13 @@ public BetaWebSearchToolResultBlockParam() this.Type = JsonSerializer.SerializeToElement("web_search_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebSearchToolResultBlockParam( BetaWebSearchToolResultBlockParam betaWebSearchToolResultBlockParam ) : base(betaWebSearchToolResultBlockParam) { } +#pragma warning restore CS8618 public BetaWebSearchToolResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultError.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultError.cs index 7a543a7fb..6efd0aaa0 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultError.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultError.cs @@ -55,8 +55,11 @@ public BetaWebSearchToolResultError() this.Type = JsonSerializer.SerializeToElement("web_search_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaWebSearchToolResultError(BetaWebSearchToolResultError betaWebSearchToolResultError) : base(betaWebSearchToolResultError) { } +#pragma warning restore CS8618 public BetaWebSearchToolResultError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Models/BetaModelInfo.cs b/src/Anthropic/Models/Beta/Models/BetaModelInfo.cs index ca5fcdb08..cf411ab02 100644 --- a/src/Anthropic/Models/Beta/Models/BetaModelInfo.cs +++ b/src/Anthropic/Models/Beta/Models/BetaModelInfo.cs @@ -84,8 +84,11 @@ public BetaModelInfo() this.Type = JsonSerializer.SerializeToElement("model"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BetaModelInfo(BetaModelInfo betaModelInfo) : base(betaModelInfo) { } +#pragma warning restore CS8618 public BetaModelInfo(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Models/ModelListPageResponse.cs b/src/Anthropic/Models/Beta/Models/ModelListPageResponse.cs index 097be6313..5683c8966 100644 --- a/src/Anthropic/Models/Beta/Models/ModelListPageResponse.cs +++ b/src/Anthropic/Models/Beta/Models/ModelListPageResponse.cs @@ -80,8 +80,11 @@ public override void Validate() public ModelListPageResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ModelListPageResponse(ModelListPageResponse modelListPageResponse) : base(modelListPageResponse) { } +#pragma warning restore CS8618 public ModelListPageResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Skills/SkillCreateResponse.cs b/src/Anthropic/Models/Beta/Skills/SkillCreateResponse.cs index 03a8b518b..3cb1f3ee3 100644 --- a/src/Anthropic/Models/Beta/Skills/SkillCreateResponse.cs +++ b/src/Anthropic/Models/Beta/Skills/SkillCreateResponse.cs @@ -127,8 +127,11 @@ public override void Validate() public SkillCreateResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SkillCreateResponse(SkillCreateResponse skillCreateResponse) : base(skillCreateResponse) { } +#pragma warning restore CS8618 public SkillCreateResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Skills/SkillDeleteResponse.cs b/src/Anthropic/Models/Beta/Skills/SkillDeleteResponse.cs index b2826d35a..3e06968f1 100644 --- a/src/Anthropic/Models/Beta/Skills/SkillDeleteResponse.cs +++ b/src/Anthropic/Models/Beta/Skills/SkillDeleteResponse.cs @@ -49,8 +49,11 @@ public override void Validate() public SkillDeleteResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SkillDeleteResponse(SkillDeleteResponse skillDeleteResponse) : base(skillDeleteResponse) { } +#pragma warning restore CS8618 public SkillDeleteResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Skills/SkillListPageResponse.cs b/src/Anthropic/Models/Beta/Skills/SkillListPageResponse.cs index 2b4fb5ffc..5f4f22568 100644 --- a/src/Anthropic/Models/Beta/Skills/SkillListPageResponse.cs +++ b/src/Anthropic/Models/Beta/Skills/SkillListPageResponse.cs @@ -75,8 +75,11 @@ public override void Validate() public SkillListPageResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SkillListPageResponse(SkillListPageResponse skillListPageResponse) : base(skillListPageResponse) { } +#pragma warning restore CS8618 public SkillListPageResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Skills/SkillListResponse.cs b/src/Anthropic/Models/Beta/Skills/SkillListResponse.cs index e5019580a..314c189c8 100644 --- a/src/Anthropic/Models/Beta/Skills/SkillListResponse.cs +++ b/src/Anthropic/Models/Beta/Skills/SkillListResponse.cs @@ -127,8 +127,11 @@ public override void Validate() public SkillListResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SkillListResponse(SkillListResponse skillListResponse) : base(skillListResponse) { } +#pragma warning restore CS8618 public SkillListResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Skills/SkillRetrieveResponse.cs b/src/Anthropic/Models/Beta/Skills/SkillRetrieveResponse.cs index 2a64f3ed3..e8341459a 100644 --- a/src/Anthropic/Models/Beta/Skills/SkillRetrieveResponse.cs +++ b/src/Anthropic/Models/Beta/Skills/SkillRetrieveResponse.cs @@ -127,8 +127,11 @@ public override void Validate() public SkillRetrieveResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SkillRetrieveResponse(SkillRetrieveResponse skillRetrieveResponse) : base(skillRetrieveResponse) { } +#pragma warning restore CS8618 public SkillRetrieveResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Skills/Versions/VersionCreateResponse.cs b/src/Anthropic/Models/Beta/Skills/Versions/VersionCreateResponse.cs index fa67fd6f1..f1caa1ec0 100644 --- a/src/Anthropic/Models/Beta/Skills/Versions/VersionCreateResponse.cs +++ b/src/Anthropic/Models/Beta/Skills/Versions/VersionCreateResponse.cs @@ -141,8 +141,11 @@ public override void Validate() public VersionCreateResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public VersionCreateResponse(VersionCreateResponse versionCreateResponse) : base(versionCreateResponse) { } +#pragma warning restore CS8618 public VersionCreateResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Skills/Versions/VersionDeleteResponse.cs b/src/Anthropic/Models/Beta/Skills/Versions/VersionDeleteResponse.cs index 188dca462..74450cda1 100644 --- a/src/Anthropic/Models/Beta/Skills/Versions/VersionDeleteResponse.cs +++ b/src/Anthropic/Models/Beta/Skills/Versions/VersionDeleteResponse.cs @@ -49,8 +49,11 @@ public override void Validate() public VersionDeleteResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public VersionDeleteResponse(VersionDeleteResponse versionDeleteResponse) : base(versionDeleteResponse) { } +#pragma warning restore CS8618 public VersionDeleteResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Skills/Versions/VersionListPageResponse.cs b/src/Anthropic/Models/Beta/Skills/Versions/VersionListPageResponse.cs index 4b06cf57e..ca6d2fd2c 100644 --- a/src/Anthropic/Models/Beta/Skills/Versions/VersionListPageResponse.cs +++ b/src/Anthropic/Models/Beta/Skills/Versions/VersionListPageResponse.cs @@ -70,8 +70,11 @@ public override void Validate() public VersionListPageResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public VersionListPageResponse(VersionListPageResponse versionListPageResponse) : base(versionListPageResponse) { } +#pragma warning restore CS8618 public VersionListPageResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Skills/Versions/VersionListResponse.cs b/src/Anthropic/Models/Beta/Skills/Versions/VersionListResponse.cs index e21749092..a928632c7 100644 --- a/src/Anthropic/Models/Beta/Skills/Versions/VersionListResponse.cs +++ b/src/Anthropic/Models/Beta/Skills/Versions/VersionListResponse.cs @@ -141,8 +141,11 @@ public override void Validate() public VersionListResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public VersionListResponse(VersionListResponse versionListResponse) : base(versionListResponse) { } +#pragma warning restore CS8618 public VersionListResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Beta/Skills/Versions/VersionRetrieveResponse.cs b/src/Anthropic/Models/Beta/Skills/Versions/VersionRetrieveResponse.cs index 716e40a2a..26064d734 100644 --- a/src/Anthropic/Models/Beta/Skills/Versions/VersionRetrieveResponse.cs +++ b/src/Anthropic/Models/Beta/Skills/Versions/VersionRetrieveResponse.cs @@ -141,8 +141,11 @@ public override void Validate() public VersionRetrieveResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public VersionRetrieveResponse(VersionRetrieveResponse versionRetrieveResponse) : base(versionRetrieveResponse) { } +#pragma warning restore CS8618 public VersionRetrieveResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/BillingError.cs b/src/Anthropic/Models/BillingError.cs index b107c0b53..19eb93317 100644 --- a/src/Anthropic/Models/BillingError.cs +++ b/src/Anthropic/Models/BillingError.cs @@ -46,8 +46,11 @@ public BillingError() this.Type = JsonSerializer.SerializeToElement("billing_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BillingError(BillingError billingError) : base(billingError) { } +#pragma warning restore CS8618 public BillingError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/ErrorResponse.cs b/src/Anthropic/Models/ErrorResponse.cs index ed4d515c1..63c4d5011 100644 --- a/src/Anthropic/Models/ErrorResponse.cs +++ b/src/Anthropic/Models/ErrorResponse.cs @@ -57,8 +57,11 @@ public ErrorResponse() this.Type = JsonSerializer.SerializeToElement("error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ErrorResponse(ErrorResponse errorResponse) : base(errorResponse) { } +#pragma warning restore CS8618 public ErrorResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/GatewayTimeoutError.cs b/src/Anthropic/Models/GatewayTimeoutError.cs index 087dadd04..de636e376 100644 --- a/src/Anthropic/Models/GatewayTimeoutError.cs +++ b/src/Anthropic/Models/GatewayTimeoutError.cs @@ -46,8 +46,11 @@ public GatewayTimeoutError() this.Type = JsonSerializer.SerializeToElement("timeout_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public GatewayTimeoutError(GatewayTimeoutError gatewayTimeoutError) : base(gatewayTimeoutError) { } +#pragma warning restore CS8618 public GatewayTimeoutError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/InvalidRequestError.cs b/src/Anthropic/Models/InvalidRequestError.cs index bf6056e69..1c7702470 100644 --- a/src/Anthropic/Models/InvalidRequestError.cs +++ b/src/Anthropic/Models/InvalidRequestError.cs @@ -51,8 +51,11 @@ public InvalidRequestError() this.Type = JsonSerializer.SerializeToElement("invalid_request_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public InvalidRequestError(InvalidRequestError invalidRequestError) : base(invalidRequestError) { } +#pragma warning restore CS8618 public InvalidRequestError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Base64ImageSource.cs b/src/Anthropic/Models/Messages/Base64ImageSource.cs index 72aed5ac6..b216f9cfa 100644 --- a/src/Anthropic/Models/Messages/Base64ImageSource.cs +++ b/src/Anthropic/Models/Messages/Base64ImageSource.cs @@ -58,8 +58,11 @@ public Base64ImageSource() this.Type = JsonSerializer.SerializeToElement("base64"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Base64ImageSource(Base64ImageSource base64ImageSource) : base(base64ImageSource) { } +#pragma warning restore CS8618 public Base64ImageSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Base64PdfSource.cs b/src/Anthropic/Models/Messages/Base64PdfSource.cs index a6de06c24..b6bdd2dfc 100644 --- a/src/Anthropic/Models/Messages/Base64PdfSource.cs +++ b/src/Anthropic/Models/Messages/Base64PdfSource.cs @@ -66,8 +66,11 @@ public Base64PdfSource() this.Type = JsonSerializer.SerializeToElement("base64"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Base64PdfSource(Base64PdfSource base64PdfSource) : base(base64PdfSource) { } +#pragma warning restore CS8618 public Base64PdfSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs index d98edc7f1..bb208d796 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs @@ -203,8 +203,11 @@ public override void Validate() public Request() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Request(Request request) : base(request) { } +#pragma warning restore CS8618 public Request(IReadOnlyDictionary rawData) { @@ -696,8 +699,11 @@ public override void Validate() public Params() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Params(Params params_) : base(params_) { } +#pragma warning restore CS8618 public Params(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Batches/BatchListPageResponse.cs b/src/Anthropic/Models/Messages/Batches/BatchListPageResponse.cs index 6be2743ad..b5b77255e 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchListPageResponse.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchListPageResponse.cs @@ -80,8 +80,11 @@ public override void Validate() public BatchListPageResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public BatchListPageResponse(BatchListPageResponse batchListPageResponse) : base(batchListPageResponse) { } +#pragma warning restore CS8618 public BatchListPageResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Batches/DeletedMessageBatch.cs b/src/Anthropic/Models/Messages/Batches/DeletedMessageBatch.cs index 808628907..74a20cbd9 100644 --- a/src/Anthropic/Models/Messages/Batches/DeletedMessageBatch.cs +++ b/src/Anthropic/Models/Messages/Batches/DeletedMessageBatch.cs @@ -59,8 +59,11 @@ public DeletedMessageBatch() this.Type = JsonSerializer.SerializeToElement("message_batch_deleted"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public DeletedMessageBatch(DeletedMessageBatch deletedMessageBatch) : base(deletedMessageBatch) { } +#pragma warning restore CS8618 public DeletedMessageBatch(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Batches/MessageBatch.cs b/src/Anthropic/Models/Messages/Batches/MessageBatch.cs index 0d5af7ca1..659514aa4 100644 --- a/src/Anthropic/Models/Messages/Batches/MessageBatch.cs +++ b/src/Anthropic/Models/Messages/Batches/MessageBatch.cs @@ -187,8 +187,11 @@ public MessageBatch() this.Type = JsonSerializer.SerializeToElement("message_batch"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageBatch(MessageBatch messageBatch) : base(messageBatch) { } +#pragma warning restore CS8618 public MessageBatch(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Batches/MessageBatchCanceledResult.cs b/src/Anthropic/Models/Messages/Batches/MessageBatchCanceledResult.cs index 5b8d3092c..8f1729fb0 100644 --- a/src/Anthropic/Models/Messages/Batches/MessageBatchCanceledResult.cs +++ b/src/Anthropic/Models/Messages/Batches/MessageBatchCanceledResult.cs @@ -37,8 +37,11 @@ public MessageBatchCanceledResult() this.Type = JsonSerializer.SerializeToElement("canceled"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageBatchCanceledResult(MessageBatchCanceledResult messageBatchCanceledResult) : base(messageBatchCanceledResult) { } +#pragma warning restore CS8618 public MessageBatchCanceledResult(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Batches/MessageBatchErroredResult.cs b/src/Anthropic/Models/Messages/Batches/MessageBatchErroredResult.cs index a4d3746b5..a5b5bd6b2 100644 --- a/src/Anthropic/Models/Messages/Batches/MessageBatchErroredResult.cs +++ b/src/Anthropic/Models/Messages/Batches/MessageBatchErroredResult.cs @@ -48,8 +48,11 @@ public MessageBatchErroredResult() this.Type = JsonSerializer.SerializeToElement("errored"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageBatchErroredResult(MessageBatchErroredResult messageBatchErroredResult) : base(messageBatchErroredResult) { } +#pragma warning restore CS8618 public MessageBatchErroredResult(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Batches/MessageBatchExpiredResult.cs b/src/Anthropic/Models/Messages/Batches/MessageBatchExpiredResult.cs index 897ebe9cc..0bd531819 100644 --- a/src/Anthropic/Models/Messages/Batches/MessageBatchExpiredResult.cs +++ b/src/Anthropic/Models/Messages/Batches/MessageBatchExpiredResult.cs @@ -37,8 +37,11 @@ public MessageBatchExpiredResult() this.Type = JsonSerializer.SerializeToElement("expired"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageBatchExpiredResult(MessageBatchExpiredResult messageBatchExpiredResult) : base(messageBatchExpiredResult) { } +#pragma warning restore CS8618 public MessageBatchExpiredResult(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Batches/MessageBatchIndividualResponse.cs b/src/Anthropic/Models/Messages/Batches/MessageBatchIndividualResponse.cs index 1dcff8c7f..c7683e186 100644 --- a/src/Anthropic/Models/Messages/Batches/MessageBatchIndividualResponse.cs +++ b/src/Anthropic/Models/Messages/Batches/MessageBatchIndividualResponse.cs @@ -61,10 +61,13 @@ public override void Validate() public MessageBatchIndividualResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageBatchIndividualResponse( MessageBatchIndividualResponse messageBatchIndividualResponse ) : base(messageBatchIndividualResponse) { } +#pragma warning restore CS8618 public MessageBatchIndividualResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Batches/MessageBatchRequestCounts.cs b/src/Anthropic/Models/Messages/Batches/MessageBatchRequestCounts.cs index 306e261b5..c7ffefff8 100644 --- a/src/Anthropic/Models/Messages/Batches/MessageBatchRequestCounts.cs +++ b/src/Anthropic/Models/Messages/Batches/MessageBatchRequestCounts.cs @@ -97,8 +97,11 @@ public override void Validate() public MessageBatchRequestCounts() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageBatchRequestCounts(MessageBatchRequestCounts messageBatchRequestCounts) : base(messageBatchRequestCounts) { } +#pragma warning restore CS8618 public MessageBatchRequestCounts(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Batches/MessageBatchSucceededResult.cs b/src/Anthropic/Models/Messages/Batches/MessageBatchSucceededResult.cs index 67166f371..e0d41058f 100644 --- a/src/Anthropic/Models/Messages/Batches/MessageBatchSucceededResult.cs +++ b/src/Anthropic/Models/Messages/Batches/MessageBatchSucceededResult.cs @@ -48,8 +48,11 @@ public MessageBatchSucceededResult() this.Type = JsonSerializer.SerializeToElement("succeeded"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageBatchSucceededResult(MessageBatchSucceededResult messageBatchSucceededResult) : base(messageBatchSucceededResult) { } +#pragma warning restore CS8618 public MessageBatchSucceededResult(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CacheControlEphemeral.cs b/src/Anthropic/Models/Messages/CacheControlEphemeral.cs index 673a7f2e1..a455289f5 100644 --- a/src/Anthropic/Models/Messages/CacheControlEphemeral.cs +++ b/src/Anthropic/Models/Messages/CacheControlEphemeral.cs @@ -62,8 +62,11 @@ public CacheControlEphemeral() this.Type = JsonSerializer.SerializeToElement("ephemeral"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CacheControlEphemeral(CacheControlEphemeral cacheControlEphemeral) : base(cacheControlEphemeral) { } +#pragma warning restore CS8618 public CacheControlEphemeral(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CacheCreation.cs b/src/Anthropic/Models/Messages/CacheCreation.cs index 880d85bfa..0136ff6d5 100644 --- a/src/Anthropic/Models/Messages/CacheCreation.cs +++ b/src/Anthropic/Models/Messages/CacheCreation.cs @@ -45,8 +45,11 @@ public override void Validate() public CacheCreation() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CacheCreation(CacheCreation cacheCreation) : base(cacheCreation) { } +#pragma warning restore CS8618 public CacheCreation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationCharLocation.cs b/src/Anthropic/Models/Messages/CitationCharLocation.cs index 5cf6d4348..164b6c4f5 100644 --- a/src/Anthropic/Models/Messages/CitationCharLocation.cs +++ b/src/Anthropic/Models/Messages/CitationCharLocation.cs @@ -101,8 +101,11 @@ public CitationCharLocation() this.Type = JsonSerializer.SerializeToElement("char_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationCharLocation(CitationCharLocation citationCharLocation) : base(citationCharLocation) { } +#pragma warning restore CS8618 public CitationCharLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationCharLocationParam.cs b/src/Anthropic/Models/Messages/CitationCharLocationParam.cs index 566ae4cae..216538f96 100644 --- a/src/Anthropic/Models/Messages/CitationCharLocationParam.cs +++ b/src/Anthropic/Models/Messages/CitationCharLocationParam.cs @@ -92,8 +92,11 @@ public CitationCharLocationParam() this.Type = JsonSerializer.SerializeToElement("char_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationCharLocationParam(CitationCharLocationParam citationCharLocationParam) : base(citationCharLocationParam) { } +#pragma warning restore CS8618 public CitationCharLocationParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationContentBlockLocation.cs b/src/Anthropic/Models/Messages/CitationContentBlockLocation.cs index fbc5b63e1..bf2bda92f 100644 --- a/src/Anthropic/Models/Messages/CitationContentBlockLocation.cs +++ b/src/Anthropic/Models/Messages/CitationContentBlockLocation.cs @@ -108,8 +108,11 @@ public CitationContentBlockLocation() this.Type = JsonSerializer.SerializeToElement("content_block_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationContentBlockLocation(CitationContentBlockLocation citationContentBlockLocation) : base(citationContentBlockLocation) { } +#pragma warning restore CS8618 public CitationContentBlockLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationContentBlockLocationParam.cs b/src/Anthropic/Models/Messages/CitationContentBlockLocationParam.cs index 18f6cd24f..f4c0365ce 100644 --- a/src/Anthropic/Models/Messages/CitationContentBlockLocationParam.cs +++ b/src/Anthropic/Models/Messages/CitationContentBlockLocationParam.cs @@ -100,10 +100,13 @@ public CitationContentBlockLocationParam() this.Type = JsonSerializer.SerializeToElement("content_block_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationContentBlockLocationParam( CitationContentBlockLocationParam citationContentBlockLocationParam ) : base(citationContentBlockLocationParam) { } +#pragma warning restore CS8618 public CitationContentBlockLocationParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationPageLocation.cs b/src/Anthropic/Models/Messages/CitationPageLocation.cs index 5b7b7611d..ae3a177e7 100644 --- a/src/Anthropic/Models/Messages/CitationPageLocation.cs +++ b/src/Anthropic/Models/Messages/CitationPageLocation.cs @@ -101,8 +101,11 @@ public CitationPageLocation() this.Type = JsonSerializer.SerializeToElement("page_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationPageLocation(CitationPageLocation citationPageLocation) : base(citationPageLocation) { } +#pragma warning restore CS8618 public CitationPageLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationPageLocationParam.cs b/src/Anthropic/Models/Messages/CitationPageLocationParam.cs index 484c44ece..ba6884b27 100644 --- a/src/Anthropic/Models/Messages/CitationPageLocationParam.cs +++ b/src/Anthropic/Models/Messages/CitationPageLocationParam.cs @@ -92,8 +92,11 @@ public CitationPageLocationParam() this.Type = JsonSerializer.SerializeToElement("page_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationPageLocationParam(CitationPageLocationParam citationPageLocationParam) : base(citationPageLocationParam) { } +#pragma warning restore CS8618 public CitationPageLocationParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationSearchResultLocationParam.cs b/src/Anthropic/Models/Messages/CitationSearchResultLocationParam.cs index a09d5a7c5..3980ff75d 100644 --- a/src/Anthropic/Models/Messages/CitationSearchResultLocationParam.cs +++ b/src/Anthropic/Models/Messages/CitationSearchResultLocationParam.cs @@ -111,10 +111,13 @@ public CitationSearchResultLocationParam() this.Type = JsonSerializer.SerializeToElement("search_result_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationSearchResultLocationParam( CitationSearchResultLocationParam citationSearchResultLocationParam ) : base(citationSearchResultLocationParam) { } +#pragma warning restore CS8618 public CitationSearchResultLocationParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationWebSearchResultLocationParam.cs b/src/Anthropic/Models/Messages/CitationWebSearchResultLocationParam.cs index e6a2ca5bc..d721ad4bc 100644 --- a/src/Anthropic/Models/Messages/CitationWebSearchResultLocationParam.cs +++ b/src/Anthropic/Models/Messages/CitationWebSearchResultLocationParam.cs @@ -89,10 +89,13 @@ public CitationWebSearchResultLocationParam() this.Type = JsonSerializer.SerializeToElement("web_search_result_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationWebSearchResultLocationParam( CitationWebSearchResultLocationParam citationWebSearchResultLocationParam ) : base(citationWebSearchResultLocationParam) { } +#pragma warning restore CS8618 public CitationWebSearchResultLocationParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationsConfigParam.cs b/src/Anthropic/Models/Messages/CitationsConfigParam.cs index ea345cc58..abeffa452 100644 --- a/src/Anthropic/Models/Messages/CitationsConfigParam.cs +++ b/src/Anthropic/Models/Messages/CitationsConfigParam.cs @@ -36,8 +36,11 @@ public override void Validate() public CitationsConfigParam() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationsConfigParam(CitationsConfigParam citationsConfigParam) : base(citationsConfigParam) { } +#pragma warning restore CS8618 public CitationsConfigParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationsDelta.cs b/src/Anthropic/Models/Messages/CitationsDelta.cs index 199b08ad9..399257ad5 100644 --- a/src/Anthropic/Models/Messages/CitationsDelta.cs +++ b/src/Anthropic/Models/Messages/CitationsDelta.cs @@ -49,8 +49,11 @@ public CitationsDelta() this.Type = JsonSerializer.SerializeToElement("citations_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationsDelta(CitationsDelta citationsDelta) : base(citationsDelta) { } +#pragma warning restore CS8618 public CitationsDelta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationsSearchResultLocation.cs b/src/Anthropic/Models/Messages/CitationsSearchResultLocation.cs index d9d759669..361dd4780 100644 --- a/src/Anthropic/Models/Messages/CitationsSearchResultLocation.cs +++ b/src/Anthropic/Models/Messages/CitationsSearchResultLocation.cs @@ -108,10 +108,13 @@ public CitationsSearchResultLocation() this.Type = JsonSerializer.SerializeToElement("search_result_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationsSearchResultLocation( CitationsSearchResultLocation citationsSearchResultLocation ) : base(citationsSearchResultLocation) { } +#pragma warning restore CS8618 public CitationsSearchResultLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/CitationsWebSearchResultLocation.cs b/src/Anthropic/Models/Messages/CitationsWebSearchResultLocation.cs index 93891e892..60b56a08f 100644 --- a/src/Anthropic/Models/Messages/CitationsWebSearchResultLocation.cs +++ b/src/Anthropic/Models/Messages/CitationsWebSearchResultLocation.cs @@ -89,10 +89,13 @@ public CitationsWebSearchResultLocation() this.Type = JsonSerializer.SerializeToElement("web_search_result_location"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public CitationsWebSearchResultLocation( CitationsWebSearchResultLocation citationsWebSearchResultLocation ) : base(citationsWebSearchResultLocation) { } +#pragma warning restore CS8618 public CitationsWebSearchResultLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ContentBlockSource.cs b/src/Anthropic/Models/Messages/ContentBlockSource.cs index 6b55b0566..4e0f8e333 100644 --- a/src/Anthropic/Models/Messages/ContentBlockSource.cs +++ b/src/Anthropic/Models/Messages/ContentBlockSource.cs @@ -48,8 +48,11 @@ public ContentBlockSource() this.Type = JsonSerializer.SerializeToElement("content"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ContentBlockSource(ContentBlockSource contentBlockSource) : base(contentBlockSource) { } +#pragma warning restore CS8618 public ContentBlockSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/DocumentBlockParam.cs b/src/Anthropic/Models/Messages/DocumentBlockParam.cs index c64c77a43..89ee7c9e4 100644 --- a/src/Anthropic/Models/Messages/DocumentBlockParam.cs +++ b/src/Anthropic/Models/Messages/DocumentBlockParam.cs @@ -94,8 +94,11 @@ public DocumentBlockParam() this.Type = JsonSerializer.SerializeToElement("document"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public DocumentBlockParam(DocumentBlockParam documentBlockParam) : base(documentBlockParam) { } +#pragma warning restore CS8618 public DocumentBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ImageBlockParam.cs b/src/Anthropic/Models/Messages/ImageBlockParam.cs index 32ea6da86..df49d2a21 100644 --- a/src/Anthropic/Models/Messages/ImageBlockParam.cs +++ b/src/Anthropic/Models/Messages/ImageBlockParam.cs @@ -61,8 +61,11 @@ public ImageBlockParam() this.Type = JsonSerializer.SerializeToElement("image"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ImageBlockParam(ImageBlockParam imageBlockParam) : base(imageBlockParam) { } +#pragma warning restore CS8618 public ImageBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/InputJsonDelta.cs b/src/Anthropic/Models/Messages/InputJsonDelta.cs index 013aca47c..34ceffe52 100644 --- a/src/Anthropic/Models/Messages/InputJsonDelta.cs +++ b/src/Anthropic/Models/Messages/InputJsonDelta.cs @@ -51,8 +51,11 @@ public InputJsonDelta() this.Type = JsonSerializer.SerializeToElement("input_json_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public InputJsonDelta(InputJsonDelta inputJsonDelta) : base(inputJsonDelta) { } +#pragma warning restore CS8618 public InputJsonDelta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Message.cs b/src/Anthropic/Models/Messages/Message.cs index 2f8710e0c..512948e9d 100644 --- a/src/Anthropic/Models/Messages/Message.cs +++ b/src/Anthropic/Models/Messages/Message.cs @@ -204,8 +204,11 @@ public Message() this.Type = JsonSerializer.SerializeToElement("message"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Message(Message message) : base(message) { } +#pragma warning restore CS8618 public Message(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/MessageDeltaUsage.cs b/src/Anthropic/Models/Messages/MessageDeltaUsage.cs index ad3cc9434..47ae9f2a2 100644 --- a/src/Anthropic/Models/Messages/MessageDeltaUsage.cs +++ b/src/Anthropic/Models/Messages/MessageDeltaUsage.cs @@ -87,8 +87,11 @@ public override void Validate() public MessageDeltaUsage() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageDeltaUsage(MessageDeltaUsage messageDeltaUsage) : base(messageDeltaUsage) { } +#pragma warning restore CS8618 public MessageDeltaUsage(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/MessageParam.cs b/src/Anthropic/Models/Messages/MessageParam.cs index 1c90694b3..3f30813c0 100644 --- a/src/Anthropic/Models/Messages/MessageParam.cs +++ b/src/Anthropic/Models/Messages/MessageParam.cs @@ -42,8 +42,11 @@ public override void Validate() public MessageParam() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageParam(MessageParam messageParam) : base(messageParam) { } +#pragma warning restore CS8618 public MessageParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/MessageTokensCount.cs b/src/Anthropic/Models/Messages/MessageTokensCount.cs index 30c881b67..cb8ca2414 100644 --- a/src/Anthropic/Models/Messages/MessageTokensCount.cs +++ b/src/Anthropic/Models/Messages/MessageTokensCount.cs @@ -32,8 +32,11 @@ public override void Validate() public MessageTokensCount() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public MessageTokensCount(MessageTokensCount messageTokensCount) : base(messageTokensCount) { } +#pragma warning restore CS8618 public MessageTokensCount(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Metadata.cs b/src/Anthropic/Models/Messages/Metadata.cs index b9a74ad34..9f5bb96d1 100644 --- a/src/Anthropic/Models/Messages/Metadata.cs +++ b/src/Anthropic/Models/Messages/Metadata.cs @@ -35,8 +35,11 @@ public override void Validate() public Metadata() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Metadata(Metadata metadata) : base(metadata) { } +#pragma warning restore CS8618 public Metadata(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/PlainTextSource.cs b/src/Anthropic/Models/Messages/PlainTextSource.cs index 69231c3d2..99037bdf7 100644 --- a/src/Anthropic/Models/Messages/PlainTextSource.cs +++ b/src/Anthropic/Models/Messages/PlainTextSource.cs @@ -63,8 +63,11 @@ public PlainTextSource() this.Type = JsonSerializer.SerializeToElement("text"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public PlainTextSource(PlainTextSource plainTextSource) : base(plainTextSource) { } +#pragma warning restore CS8618 public PlainTextSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/RawContentBlockDeltaEvent.cs b/src/Anthropic/Models/Messages/RawContentBlockDeltaEvent.cs index 82f80c899..dccbd07a6 100644 --- a/src/Anthropic/Models/Messages/RawContentBlockDeltaEvent.cs +++ b/src/Anthropic/Models/Messages/RawContentBlockDeltaEvent.cs @@ -64,8 +64,11 @@ public RawContentBlockDeltaEvent() this.Type = JsonSerializer.SerializeToElement("content_block_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public RawContentBlockDeltaEvent(RawContentBlockDeltaEvent rawContentBlockDeltaEvent) : base(rawContentBlockDeltaEvent) { } +#pragma warning restore CS8618 public RawContentBlockDeltaEvent(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/RawContentBlockStartEvent.cs b/src/Anthropic/Models/Messages/RawContentBlockStartEvent.cs index b65edbd27..a17da2850 100644 --- a/src/Anthropic/Models/Messages/RawContentBlockStartEvent.cs +++ b/src/Anthropic/Models/Messages/RawContentBlockStartEvent.cs @@ -67,8 +67,11 @@ public RawContentBlockStartEvent() this.Type = JsonSerializer.SerializeToElement("content_block_start"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public RawContentBlockStartEvent(RawContentBlockStartEvent rawContentBlockStartEvent) : base(rawContentBlockStartEvent) { } +#pragma warning restore CS8618 public RawContentBlockStartEvent(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/RawContentBlockStopEvent.cs b/src/Anthropic/Models/Messages/RawContentBlockStopEvent.cs index d07158514..6510c8c32 100644 --- a/src/Anthropic/Models/Messages/RawContentBlockStopEvent.cs +++ b/src/Anthropic/Models/Messages/RawContentBlockStopEvent.cs @@ -53,8 +53,11 @@ public RawContentBlockStopEvent() this.Type = JsonSerializer.SerializeToElement("content_block_stop"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public RawContentBlockStopEvent(RawContentBlockStopEvent rawContentBlockStopEvent) : base(rawContentBlockStopEvent) { } +#pragma warning restore CS8618 public RawContentBlockStopEvent(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/RawMessageDeltaEvent.cs b/src/Anthropic/Models/Messages/RawMessageDeltaEvent.cs index f675fde3d..74dbced00 100644 --- a/src/Anthropic/Models/Messages/RawMessageDeltaEvent.cs +++ b/src/Anthropic/Models/Messages/RawMessageDeltaEvent.cs @@ -74,8 +74,11 @@ public RawMessageDeltaEvent() this.Type = JsonSerializer.SerializeToElement("message_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public RawMessageDeltaEvent(RawMessageDeltaEvent rawMessageDeltaEvent) : base(rawMessageDeltaEvent) { } +#pragma warning restore CS8618 public RawMessageDeltaEvent(IReadOnlyDictionary rawData) { @@ -141,8 +144,11 @@ public override void Validate() public Delta() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Delta(Delta delta) : base(delta) { } +#pragma warning restore CS8618 public Delta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/RawMessageStartEvent.cs b/src/Anthropic/Models/Messages/RawMessageStartEvent.cs index cbc0d4c81..485f923d8 100644 --- a/src/Anthropic/Models/Messages/RawMessageStartEvent.cs +++ b/src/Anthropic/Models/Messages/RawMessageStartEvent.cs @@ -46,8 +46,11 @@ public RawMessageStartEvent() this.Type = JsonSerializer.SerializeToElement("message_start"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public RawMessageStartEvent(RawMessageStartEvent rawMessageStartEvent) : base(rawMessageStartEvent) { } +#pragma warning restore CS8618 public RawMessageStartEvent(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/RawMessageStopEvent.cs b/src/Anthropic/Models/Messages/RawMessageStopEvent.cs index d8a3c9d82..c55603b83 100644 --- a/src/Anthropic/Models/Messages/RawMessageStopEvent.cs +++ b/src/Anthropic/Models/Messages/RawMessageStopEvent.cs @@ -35,8 +35,11 @@ public RawMessageStopEvent() this.Type = JsonSerializer.SerializeToElement("message_stop"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public RawMessageStopEvent(RawMessageStopEvent rawMessageStopEvent) : base(rawMessageStopEvent) { } +#pragma warning restore CS8618 public RawMessageStopEvent(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/RedactedThinkingBlock.cs b/src/Anthropic/Models/Messages/RedactedThinkingBlock.cs index 68e103569..5eb7387ea 100644 --- a/src/Anthropic/Models/Messages/RedactedThinkingBlock.cs +++ b/src/Anthropic/Models/Messages/RedactedThinkingBlock.cs @@ -51,8 +51,11 @@ public RedactedThinkingBlock() this.Type = JsonSerializer.SerializeToElement("redacted_thinking"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public RedactedThinkingBlock(RedactedThinkingBlock redactedThinkingBlock) : base(redactedThinkingBlock) { } +#pragma warning restore CS8618 public RedactedThinkingBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/RedactedThinkingBlockParam.cs b/src/Anthropic/Models/Messages/RedactedThinkingBlockParam.cs index ba2b88466..953358102 100644 --- a/src/Anthropic/Models/Messages/RedactedThinkingBlockParam.cs +++ b/src/Anthropic/Models/Messages/RedactedThinkingBlockParam.cs @@ -53,8 +53,11 @@ public RedactedThinkingBlockParam() this.Type = JsonSerializer.SerializeToElement("redacted_thinking"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public RedactedThinkingBlockParam(RedactedThinkingBlockParam redactedThinkingBlockParam) : base(redactedThinkingBlockParam) { } +#pragma warning restore CS8618 public RedactedThinkingBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/SearchResultBlockParam.cs b/src/Anthropic/Models/Messages/SearchResultBlockParam.cs index f5839d67b..79c84eb48 100644 --- a/src/Anthropic/Models/Messages/SearchResultBlockParam.cs +++ b/src/Anthropic/Models/Messages/SearchResultBlockParam.cs @@ -111,8 +111,11 @@ public SearchResultBlockParam() this.Type = JsonSerializer.SerializeToElement("search_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SearchResultBlockParam(SearchResultBlockParam searchResultBlockParam) : base(searchResultBlockParam) { } +#pragma warning restore CS8618 public SearchResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ServerToolUsage.cs b/src/Anthropic/Models/Messages/ServerToolUsage.cs index 3bc73f450..38fd55958 100644 --- a/src/Anthropic/Models/Messages/ServerToolUsage.cs +++ b/src/Anthropic/Models/Messages/ServerToolUsage.cs @@ -31,8 +31,11 @@ public override void Validate() public ServerToolUsage() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ServerToolUsage(ServerToolUsage serverToolUsage) : base(serverToolUsage) { } +#pragma warning restore CS8618 public ServerToolUsage(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ServerToolUseBlock.cs b/src/Anthropic/Models/Messages/ServerToolUseBlock.cs index 675914d8b..b02ca87ca 100644 --- a/src/Anthropic/Models/Messages/ServerToolUseBlock.cs +++ b/src/Anthropic/Models/Messages/ServerToolUseBlock.cs @@ -80,8 +80,11 @@ public ServerToolUseBlock() this.Type = JsonSerializer.SerializeToElement("server_tool_use"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ServerToolUseBlock(ServerToolUseBlock serverToolUseBlock) : base(serverToolUseBlock) { } +#pragma warning restore CS8618 public ServerToolUseBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ServerToolUseBlockParam.cs b/src/Anthropic/Models/Messages/ServerToolUseBlockParam.cs index 704d176c7..275174434 100644 --- a/src/Anthropic/Models/Messages/ServerToolUseBlockParam.cs +++ b/src/Anthropic/Models/Messages/ServerToolUseBlockParam.cs @@ -94,8 +94,11 @@ public ServerToolUseBlockParam() this.Type = JsonSerializer.SerializeToElement("server_tool_use"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ServerToolUseBlockParam(ServerToolUseBlockParam serverToolUseBlockParam) : base(serverToolUseBlockParam) { } +#pragma warning restore CS8618 public ServerToolUseBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/SignatureDelta.cs b/src/Anthropic/Models/Messages/SignatureDelta.cs index 89ec5154a..fccc848cd 100644 --- a/src/Anthropic/Models/Messages/SignatureDelta.cs +++ b/src/Anthropic/Models/Messages/SignatureDelta.cs @@ -48,8 +48,11 @@ public SignatureDelta() this.Type = JsonSerializer.SerializeToElement("signature_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public SignatureDelta(SignatureDelta signatureDelta) : base(signatureDelta) { } +#pragma warning restore CS8618 public SignatureDelta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/TextBlock.cs b/src/Anthropic/Models/Messages/TextBlock.cs index aba88c88f..086850f67 100644 --- a/src/Anthropic/Models/Messages/TextBlock.cs +++ b/src/Anthropic/Models/Messages/TextBlock.cs @@ -74,8 +74,11 @@ public TextBlock() this.Type = JsonSerializer.SerializeToElement("text"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public TextBlock(TextBlock textBlock) : base(textBlock) { } +#pragma warning restore CS8618 public TextBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/TextBlockParam.cs b/src/Anthropic/Models/Messages/TextBlockParam.cs index a95251f97..9ede8fd16 100644 --- a/src/Anthropic/Models/Messages/TextBlockParam.cs +++ b/src/Anthropic/Models/Messages/TextBlockParam.cs @@ -81,8 +81,11 @@ public TextBlockParam() this.Type = JsonSerializer.SerializeToElement("text"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public TextBlockParam(TextBlockParam textBlockParam) : base(textBlockParam) { } +#pragma warning restore CS8618 public TextBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/TextDelta.cs b/src/Anthropic/Models/Messages/TextDelta.cs index 7966d369a..fd5efc697 100644 --- a/src/Anthropic/Models/Messages/TextDelta.cs +++ b/src/Anthropic/Models/Messages/TextDelta.cs @@ -46,8 +46,11 @@ public TextDelta() this.Type = JsonSerializer.SerializeToElement("text_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public TextDelta(TextDelta textDelta) : base(textDelta) { } +#pragma warning restore CS8618 public TextDelta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ThinkingBlock.cs b/src/Anthropic/Models/Messages/ThinkingBlock.cs index 9f9a3a90d..b7191b3f6 100644 --- a/src/Anthropic/Models/Messages/ThinkingBlock.cs +++ b/src/Anthropic/Models/Messages/ThinkingBlock.cs @@ -57,8 +57,11 @@ public ThinkingBlock() this.Type = JsonSerializer.SerializeToElement("thinking"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ThinkingBlock(ThinkingBlock thinkingBlock) : base(thinkingBlock) { } +#pragma warning restore CS8618 public ThinkingBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ThinkingBlockParam.cs b/src/Anthropic/Models/Messages/ThinkingBlockParam.cs index 298788775..0f2109789 100644 --- a/src/Anthropic/Models/Messages/ThinkingBlockParam.cs +++ b/src/Anthropic/Models/Messages/ThinkingBlockParam.cs @@ -57,8 +57,11 @@ public ThinkingBlockParam() this.Type = JsonSerializer.SerializeToElement("thinking"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ThinkingBlockParam(ThinkingBlockParam thinkingBlockParam) : base(thinkingBlockParam) { } +#pragma warning restore CS8618 public ThinkingBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ThinkingConfigDisabled.cs b/src/Anthropic/Models/Messages/ThinkingConfigDisabled.cs index 196557e9e..54f5f3ad1 100644 --- a/src/Anthropic/Models/Messages/ThinkingConfigDisabled.cs +++ b/src/Anthropic/Models/Messages/ThinkingConfigDisabled.cs @@ -35,8 +35,11 @@ public ThinkingConfigDisabled() this.Type = JsonSerializer.SerializeToElement("disabled"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ThinkingConfigDisabled(ThinkingConfigDisabled thinkingConfigDisabled) : base(thinkingConfigDisabled) { } +#pragma warning restore CS8618 public ThinkingConfigDisabled(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ThinkingConfigEnabled.cs b/src/Anthropic/Models/Messages/ThinkingConfigEnabled.cs index 42c33058d..1f752eae3 100644 --- a/src/Anthropic/Models/Messages/ThinkingConfigEnabled.cs +++ b/src/Anthropic/Models/Messages/ThinkingConfigEnabled.cs @@ -56,8 +56,11 @@ public ThinkingConfigEnabled() this.Type = JsonSerializer.SerializeToElement("enabled"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ThinkingConfigEnabled(ThinkingConfigEnabled thinkingConfigEnabled) : base(thinkingConfigEnabled) { } +#pragma warning restore CS8618 public ThinkingConfigEnabled(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ThinkingDelta.cs b/src/Anthropic/Models/Messages/ThinkingDelta.cs index 51052f391..734eed1f9 100644 --- a/src/Anthropic/Models/Messages/ThinkingDelta.cs +++ b/src/Anthropic/Models/Messages/ThinkingDelta.cs @@ -46,8 +46,11 @@ public ThinkingDelta() this.Type = JsonSerializer.SerializeToElement("thinking_delta"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ThinkingDelta(ThinkingDelta thinkingDelta) : base(thinkingDelta) { } +#pragma warning restore CS8618 public ThinkingDelta(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Tool.cs b/src/Anthropic/Models/Messages/Tool.cs index 895292598..e6fb70f8b 100644 --- a/src/Anthropic/Models/Messages/Tool.cs +++ b/src/Anthropic/Models/Messages/Tool.cs @@ -107,8 +107,11 @@ public override void Validate() public Tool() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Tool(Tool tool) : base(tool) { } +#pragma warning restore CS8618 public Tool(IReadOnlyDictionary rawData) { @@ -206,8 +209,11 @@ public InputSchema() this.Type = JsonSerializer.SerializeToElement("object"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public InputSchema(InputSchema inputSchema) : base(inputSchema) { } +#pragma warning restore CS8618 public InputSchema(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolBash20250124.cs b/src/Anthropic/Models/Messages/ToolBash20250124.cs index 5a19c9243..07a6d5602 100644 --- a/src/Anthropic/Models/Messages/ToolBash20250124.cs +++ b/src/Anthropic/Models/Messages/ToolBash20250124.cs @@ -69,8 +69,11 @@ public ToolBash20250124() this.Type = JsonSerializer.SerializeToElement("bash_20250124"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolBash20250124(ToolBash20250124 toolBash20250124) : base(toolBash20250124) { } +#pragma warning restore CS8618 public ToolBash20250124(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolChoiceAny.cs b/src/Anthropic/Models/Messages/ToolChoiceAny.cs index 4d99b238f..12d47718a 100644 --- a/src/Anthropic/Models/Messages/ToolChoiceAny.cs +++ b/src/Anthropic/Models/Messages/ToolChoiceAny.cs @@ -63,8 +63,11 @@ public ToolChoiceAny() this.Type = JsonSerializer.SerializeToElement("any"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolChoiceAny(ToolChoiceAny toolChoiceAny) : base(toolChoiceAny) { } +#pragma warning restore CS8618 public ToolChoiceAny(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolChoiceAuto.cs b/src/Anthropic/Models/Messages/ToolChoiceAuto.cs index 72fe38e9e..7f82406d7 100644 --- a/src/Anthropic/Models/Messages/ToolChoiceAuto.cs +++ b/src/Anthropic/Models/Messages/ToolChoiceAuto.cs @@ -63,8 +63,11 @@ public ToolChoiceAuto() this.Type = JsonSerializer.SerializeToElement("auto"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolChoiceAuto(ToolChoiceAuto toolChoiceAuto) : base(toolChoiceAuto) { } +#pragma warning restore CS8618 public ToolChoiceAuto(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolChoiceNone.cs b/src/Anthropic/Models/Messages/ToolChoiceNone.cs index a92aa237f..a43759dc7 100644 --- a/src/Anthropic/Models/Messages/ToolChoiceNone.cs +++ b/src/Anthropic/Models/Messages/ToolChoiceNone.cs @@ -38,8 +38,11 @@ public ToolChoiceNone() this.Type = JsonSerializer.SerializeToElement("none"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolChoiceNone(ToolChoiceNone toolChoiceNone) : base(toolChoiceNone) { } +#pragma warning restore CS8618 public ToolChoiceNone(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolChoiceTool.cs b/src/Anthropic/Models/Messages/ToolChoiceTool.cs index e27684cf8..c3aefabf0 100644 --- a/src/Anthropic/Models/Messages/ToolChoiceTool.cs +++ b/src/Anthropic/Models/Messages/ToolChoiceTool.cs @@ -77,8 +77,11 @@ public ToolChoiceTool() this.Type = JsonSerializer.SerializeToElement("tool"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolChoiceTool(ToolChoiceTool toolChoiceTool) : base(toolChoiceTool) { } +#pragma warning restore CS8618 public ToolChoiceTool(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolResultBlockParam.cs b/src/Anthropic/Models/Messages/ToolResultBlockParam.cs index 42fa12d65..514a22bde 100644 --- a/src/Anthropic/Models/Messages/ToolResultBlockParam.cs +++ b/src/Anthropic/Models/Messages/ToolResultBlockParam.cs @@ -100,8 +100,11 @@ public ToolResultBlockParam() this.Type = JsonSerializer.SerializeToElement("tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolResultBlockParam(ToolResultBlockParam toolResultBlockParam) : base(toolResultBlockParam) { } +#pragma warning restore CS8618 public ToolResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolTextEditor20250124.cs b/src/Anthropic/Models/Messages/ToolTextEditor20250124.cs index 51cb0b814..69ad41726 100644 --- a/src/Anthropic/Models/Messages/ToolTextEditor20250124.cs +++ b/src/Anthropic/Models/Messages/ToolTextEditor20250124.cs @@ -79,8 +79,11 @@ public ToolTextEditor20250124() this.Type = JsonSerializer.SerializeToElement("text_editor_20250124"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolTextEditor20250124(ToolTextEditor20250124 toolTextEditor20250124) : base(toolTextEditor20250124) { } +#pragma warning restore CS8618 public ToolTextEditor20250124(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolTextEditor20250429.cs b/src/Anthropic/Models/Messages/ToolTextEditor20250429.cs index d9fcb073a..c34690d2b 100644 --- a/src/Anthropic/Models/Messages/ToolTextEditor20250429.cs +++ b/src/Anthropic/Models/Messages/ToolTextEditor20250429.cs @@ -79,8 +79,11 @@ public ToolTextEditor20250429() this.Type = JsonSerializer.SerializeToElement("text_editor_20250429"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolTextEditor20250429(ToolTextEditor20250429 toolTextEditor20250429) : base(toolTextEditor20250429) { } +#pragma warning restore CS8618 public ToolTextEditor20250429(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolTextEditor20250728.cs b/src/Anthropic/Models/Messages/ToolTextEditor20250728.cs index 909dbad63..cc347102d 100644 --- a/src/Anthropic/Models/Messages/ToolTextEditor20250728.cs +++ b/src/Anthropic/Models/Messages/ToolTextEditor20250728.cs @@ -94,8 +94,11 @@ public ToolTextEditor20250728() this.Type = JsonSerializer.SerializeToElement("text_editor_20250728"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolTextEditor20250728(ToolTextEditor20250728 toolTextEditor20250728) : base(toolTextEditor20250728) { } +#pragma warning restore CS8618 public ToolTextEditor20250728(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolUseBlock.cs b/src/Anthropic/Models/Messages/ToolUseBlock.cs index eb2a38ca8..22d1d25c7 100644 --- a/src/Anthropic/Models/Messages/ToolUseBlock.cs +++ b/src/Anthropic/Models/Messages/ToolUseBlock.cs @@ -74,8 +74,11 @@ public ToolUseBlock() this.Type = JsonSerializer.SerializeToElement("tool_use"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolUseBlock(ToolUseBlock toolUseBlock) : base(toolUseBlock) { } +#pragma warning restore CS8618 public ToolUseBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/ToolUseBlockParam.cs b/src/Anthropic/Models/Messages/ToolUseBlockParam.cs index df4b4c87b..3890d3d25 100644 --- a/src/Anthropic/Models/Messages/ToolUseBlockParam.cs +++ b/src/Anthropic/Models/Messages/ToolUseBlockParam.cs @@ -88,8 +88,11 @@ public ToolUseBlockParam() this.Type = JsonSerializer.SerializeToElement("tool_use"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ToolUseBlockParam(ToolUseBlockParam toolUseBlockParam) : base(toolUseBlockParam) { } +#pragma warning restore CS8618 public ToolUseBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/UrlImageSource.cs b/src/Anthropic/Models/Messages/UrlImageSource.cs index 191088aa5..8bd74c2e0 100644 --- a/src/Anthropic/Models/Messages/UrlImageSource.cs +++ b/src/Anthropic/Models/Messages/UrlImageSource.cs @@ -46,8 +46,11 @@ public UrlImageSource() this.Type = JsonSerializer.SerializeToElement("url"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public UrlImageSource(UrlImageSource urlImageSource) : base(urlImageSource) { } +#pragma warning restore CS8618 public UrlImageSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/UrlPdfSource.cs b/src/Anthropic/Models/Messages/UrlPdfSource.cs index 26fae9f5a..fd7cb56a3 100644 --- a/src/Anthropic/Models/Messages/UrlPdfSource.cs +++ b/src/Anthropic/Models/Messages/UrlPdfSource.cs @@ -46,8 +46,11 @@ public UrlPdfSource() this.Type = JsonSerializer.SerializeToElement("url"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public UrlPdfSource(UrlPdfSource urlPdfSource) : base(urlPdfSource) { } +#pragma warning restore CS8618 public UrlPdfSource(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/Usage.cs b/src/Anthropic/Models/Messages/Usage.cs index 4f00208b5..6cc1b50b9 100644 --- a/src/Anthropic/Models/Messages/Usage.cs +++ b/src/Anthropic/Models/Messages/Usage.cs @@ -119,8 +119,11 @@ public override void Validate() public Usage() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public Usage(Usage usage) : base(usage) { } +#pragma warning restore CS8618 public Usage(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/WebSearchResultBlock.cs b/src/Anthropic/Models/Messages/WebSearchResultBlock.cs index 1e9fb02b6..f43c0b12e 100644 --- a/src/Anthropic/Models/Messages/WebSearchResultBlock.cs +++ b/src/Anthropic/Models/Messages/WebSearchResultBlock.cs @@ -84,8 +84,11 @@ public WebSearchResultBlock() this.Type = JsonSerializer.SerializeToElement("web_search_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public WebSearchResultBlock(WebSearchResultBlock webSearchResultBlock) : base(webSearchResultBlock) { } +#pragma warning restore CS8618 public WebSearchResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/WebSearchResultBlockParam.cs b/src/Anthropic/Models/Messages/WebSearchResultBlockParam.cs index b3eee3e16..035e3771d 100644 --- a/src/Anthropic/Models/Messages/WebSearchResultBlockParam.cs +++ b/src/Anthropic/Models/Messages/WebSearchResultBlockParam.cs @@ -86,8 +86,11 @@ public WebSearchResultBlockParam() this.Type = JsonSerializer.SerializeToElement("web_search_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public WebSearchResultBlockParam(WebSearchResultBlockParam webSearchResultBlockParam) : base(webSearchResultBlockParam) { } +#pragma warning restore CS8618 public WebSearchResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/WebSearchTool20250305.cs b/src/Anthropic/Models/Messages/WebSearchTool20250305.cs index e203ca741..7b8350baa 100644 --- a/src/Anthropic/Models/Messages/WebSearchTool20250305.cs +++ b/src/Anthropic/Models/Messages/WebSearchTool20250305.cs @@ -144,8 +144,11 @@ public WebSearchTool20250305() this.Type = JsonSerializer.SerializeToElement("web_search_20250305"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public WebSearchTool20250305(WebSearchTool20250305 webSearchTool20250305) : base(webSearchTool20250305) { } +#pragma warning restore CS8618 public WebSearchTool20250305(IReadOnlyDictionary rawData) { @@ -267,8 +270,11 @@ public UserLocation() this.Type = JsonSerializer.SerializeToElement("approximate"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public UserLocation(UserLocation userLocation) : base(userLocation) { } +#pragma warning restore CS8618 public UserLocation(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/WebSearchToolRequestError.cs b/src/Anthropic/Models/Messages/WebSearchToolRequestError.cs index e161a43f0..70060623e 100644 --- a/src/Anthropic/Models/Messages/WebSearchToolRequestError.cs +++ b/src/Anthropic/Models/Messages/WebSearchToolRequestError.cs @@ -54,8 +54,11 @@ public WebSearchToolRequestError() this.Type = JsonSerializer.SerializeToElement("web_search_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public WebSearchToolRequestError(WebSearchToolRequestError webSearchToolRequestError) : base(webSearchToolRequestError) { } +#pragma warning restore CS8618 public WebSearchToolRequestError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/WebSearchToolResultBlock.cs b/src/Anthropic/Models/Messages/WebSearchToolResultBlock.cs index 522d25973..9601db4d4 100644 --- a/src/Anthropic/Models/Messages/WebSearchToolResultBlock.cs +++ b/src/Anthropic/Models/Messages/WebSearchToolResultBlock.cs @@ -64,8 +64,11 @@ public WebSearchToolResultBlock() this.Type = JsonSerializer.SerializeToElement("web_search_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public WebSearchToolResultBlock(WebSearchToolResultBlock webSearchToolResultBlock) : base(webSearchToolResultBlock) { } +#pragma warning restore CS8618 public WebSearchToolResultBlock(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/WebSearchToolResultBlockParam.cs b/src/Anthropic/Models/Messages/WebSearchToolResultBlockParam.cs index d9f8354b6..cfc41ca97 100644 --- a/src/Anthropic/Models/Messages/WebSearchToolResultBlockParam.cs +++ b/src/Anthropic/Models/Messages/WebSearchToolResultBlockParam.cs @@ -78,10 +78,13 @@ public WebSearchToolResultBlockParam() this.Type = JsonSerializer.SerializeToElement("web_search_tool_result"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public WebSearchToolResultBlockParam( WebSearchToolResultBlockParam webSearchToolResultBlockParam ) : base(webSearchToolResultBlockParam) { } +#pragma warning restore CS8618 public WebSearchToolResultBlockParam(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Messages/WebSearchToolResultError.cs b/src/Anthropic/Models/Messages/WebSearchToolResultError.cs index bb5d8a4e2..46b327ae4 100644 --- a/src/Anthropic/Models/Messages/WebSearchToolResultError.cs +++ b/src/Anthropic/Models/Messages/WebSearchToolResultError.cs @@ -56,8 +56,11 @@ public WebSearchToolResultError() this.Type = JsonSerializer.SerializeToElement("web_search_tool_result_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public WebSearchToolResultError(WebSearchToolResultError webSearchToolResultError) : base(webSearchToolResultError) { } +#pragma warning restore CS8618 public WebSearchToolResultError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Models/ModelInfo.cs b/src/Anthropic/Models/Models/ModelInfo.cs index 8a31468a0..3503540e7 100644 --- a/src/Anthropic/Models/Models/ModelInfo.cs +++ b/src/Anthropic/Models/Models/ModelInfo.cs @@ -84,8 +84,11 @@ public ModelInfo() this.Type = JsonSerializer.SerializeToElement("model"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ModelInfo(ModelInfo modelInfo) : base(modelInfo) { } +#pragma warning restore CS8618 public ModelInfo(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/Models/ModelListPageResponse.cs b/src/Anthropic/Models/Models/ModelListPageResponse.cs index eac27cddc..cc705d969 100644 --- a/src/Anthropic/Models/Models/ModelListPageResponse.cs +++ b/src/Anthropic/Models/Models/ModelListPageResponse.cs @@ -80,8 +80,11 @@ public override void Validate() public ModelListPageResponse() { } +#pragma warning disable CS8618 + [SetsRequiredMembers] public ModelListPageResponse(ModelListPageResponse modelListPageResponse) : base(modelListPageResponse) { } +#pragma warning restore CS8618 public ModelListPageResponse(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/NotFoundError.cs b/src/Anthropic/Models/NotFoundError.cs index c38111232..de180a17d 100644 --- a/src/Anthropic/Models/NotFoundError.cs +++ b/src/Anthropic/Models/NotFoundError.cs @@ -48,8 +48,11 @@ public NotFoundError() this.Type = JsonSerializer.SerializeToElement("not_found_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public NotFoundError(NotFoundError notFoundError) : base(notFoundError) { } +#pragma warning restore CS8618 public NotFoundError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/OverloadedError.cs b/src/Anthropic/Models/OverloadedError.cs index 954cc2ebe..937129e55 100644 --- a/src/Anthropic/Models/OverloadedError.cs +++ b/src/Anthropic/Models/OverloadedError.cs @@ -51,8 +51,11 @@ public OverloadedError() this.Type = JsonSerializer.SerializeToElement("overloaded_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public OverloadedError(OverloadedError overloadedError) : base(overloadedError) { } +#pragma warning restore CS8618 public OverloadedError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/PermissionError.cs b/src/Anthropic/Models/PermissionError.cs index 7f0f3659f..2da3dae8f 100644 --- a/src/Anthropic/Models/PermissionError.cs +++ b/src/Anthropic/Models/PermissionError.cs @@ -51,8 +51,11 @@ public PermissionError() this.Type = JsonSerializer.SerializeToElement("permission_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public PermissionError(PermissionError permissionError) : base(permissionError) { } +#pragma warning restore CS8618 public PermissionError(IReadOnlyDictionary rawData) { diff --git a/src/Anthropic/Models/RateLimitError.cs b/src/Anthropic/Models/RateLimitError.cs index 1d310551c..793c9b7d9 100644 --- a/src/Anthropic/Models/RateLimitError.cs +++ b/src/Anthropic/Models/RateLimitError.cs @@ -51,8 +51,11 @@ public RateLimitError() this.Type = JsonSerializer.SerializeToElement("rate_limit_error"); } +#pragma warning disable CS8618 + [SetsRequiredMembers] public RateLimitError(RateLimitError rateLimitError) : base(rateLimitError) { } +#pragma warning restore CS8618 public RateLimitError(IReadOnlyDictionary rawData) { From 38a18f9cb6a258a8c59c1478e001ce4ede35af52 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 18:29:52 +0000 Subject: [PATCH 15/41] chore: change visibility of QueryString() and AddDefaultHeaders --- src/Anthropic/Core/ParamsBase.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Anthropic/Core/ParamsBase.cs b/src/Anthropic/Core/ParamsBase.cs index b847c3eb1..4fbc8d728 100644 --- a/src/Anthropic/Core/ParamsBase.cs +++ b/src/Anthropic/Core/ParamsBase.cs @@ -157,7 +157,7 @@ JsonElement element } } - protected string QueryString(ClientOptions options) + internal string QueryString(ClientOptions options) { NameValueCollection collection = []; foreach (var item in this.RawQueryData) @@ -190,7 +190,7 @@ protected string QueryString(ClientOptions options) return null; } - protected static void AddDefaultHeaders(HttpRequestMessage request, ClientOptions options) + internal static void AddDefaultHeaders(HttpRequestMessage request, ClientOptions options) { foreach (var header in defaultHeaders) { From 91fe9dd6ff1f17e1fb1347a749e08722e9d3565e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 18:39:54 +0000 Subject: [PATCH 16/41] feat(client): add `ToString` and `Equals` methods --- src/Anthropic/Core/ClientOptions.cs | 2 +- src/Anthropic/Core/HttpRequest.cs | 15 +++++++++++++++ src/Anthropic/Core/HttpResponse.cs | 14 ++++++++++++++ src/Anthropic/Models/Beta/Files/FileListPage.cs | 13 +++++++++++++ .../Models/Beta/Messages/Batches/BatchListPage.cs | 13 +++++++++++++ src/Anthropic/Models/Beta/Models/ModelListPage.cs | 13 +++++++++++++ src/Anthropic/Models/Beta/Skills/SkillListPage.cs | 13 +++++++++++++ .../Beta/Skills/Versions/VersionListPage.cs | 13 +++++++++++++ .../Models/Messages/Batches/BatchListPage.cs | 13 +++++++++++++ src/Anthropic/Models/Models/ModelListPage.cs | 13 +++++++++++++ 10 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/Anthropic/Core/ClientOptions.cs b/src/Anthropic/Core/ClientOptions.cs index 9e3644c81..a409b297f 100644 --- a/src/Anthropic/Core/ClientOptions.cs +++ b/src/Anthropic/Core/ClientOptions.cs @@ -6,7 +6,7 @@ namespace Anthropic.Core; /// /// A class representing the SDK client configuration. /// -public struct ClientOptions() +public record struct ClientOptions() { /// /// The default value used for . diff --git a/src/Anthropic/Core/HttpRequest.cs b/src/Anthropic/Core/HttpRequest.cs index 234203cac..648a8cda6 100644 --- a/src/Anthropic/Core/HttpRequest.cs +++ b/src/Anthropic/Core/HttpRequest.cs @@ -8,4 +8,19 @@ public sealed class HttpRequest

public required HttpMethod Method { get; init; } public required P Params { get; init; } + + public override string ToString() => + string.Format("Method: {0}\n{1}", this.Method.ToString(), this.Params.ToString()); + + public override bool Equals(object? obj) + { + if (obj is not HttpRequest

other) + { + return false; + } + + return this.Method.Equals(other.Method) && this.Params.Equals(other.Params); + } + + public override int GetHashCode() => 0; } diff --git a/src/Anthropic/Core/HttpResponse.cs b/src/Anthropic/Core/HttpResponse.cs index db1d0ef17..c8d4f6f73 100644 --- a/src/Anthropic/Core/HttpResponse.cs +++ b/src/Anthropic/Core/HttpResponse.cs @@ -39,6 +39,20 @@ public bool TryGetHeaderValues( [NotNullWhen(true)] out IEnumerable? values ) => RawMessage.Headers.TryGetValues(name, out values); + public sealed override string ToString() => this.RawMessage.ToString(); + + public override bool Equals(object? obj) + { + if (obj is not global::Anthropic.Core.HttpResponse other) + { + return false; + } + + return this.RawMessage.Equals(other.RawMessage); + } + + public override int GetHashCode() => this.RawMessage.GetHashCode(); + public async Task Deserialize(Threading::CancellationToken cancellationToken = default) { using var cts = Threading::CancellationTokenSource.CreateLinkedTokenSource( diff --git a/src/Anthropic/Models/Beta/Files/FileListPage.cs b/src/Anthropic/Models/Beta/Files/FileListPage.cs index 53b5ef0fb..60d35a8ca 100644 --- a/src/Anthropic/Models/Beta/Files/FileListPage.cs +++ b/src/Anthropic/Models/Beta/Files/FileListPage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -62,4 +63,16 @@ public void Validate() public override string ToString() => JsonSerializer.Serialize(this.Items, ModelBase.ToStringSerializerOptions); + + public override bool Equals(object? obj) + { + if (obj is not FileListPage other) + { + return false; + } + + return Enumerable.SequenceEqual(this.Items, other.Items); + } + + public override int GetHashCode() => 0; } diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchListPage.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchListPage.cs index 822d119ef..004d66e84 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchListPage.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchListPage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -63,4 +64,16 @@ public void Validate() public override string ToString() => JsonSerializer.Serialize(this.Items, ModelBase.ToStringSerializerOptions); + + public override bool Equals(object? obj) + { + if (obj is not BatchListPage other) + { + return false; + } + + return Enumerable.SequenceEqual(this.Items, other.Items); + } + + public override int GetHashCode() => 0; } diff --git a/src/Anthropic/Models/Beta/Models/ModelListPage.cs b/src/Anthropic/Models/Beta/Models/ModelListPage.cs index a6f19573f..eed451829 100644 --- a/src/Anthropic/Models/Beta/Models/ModelListPage.cs +++ b/src/Anthropic/Models/Beta/Models/ModelListPage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -63,4 +64,16 @@ public void Validate() public override string ToString() => JsonSerializer.Serialize(this.Items, ModelBase.ToStringSerializerOptions); + + public override bool Equals(object? obj) + { + if (obj is not ModelListPage other) + { + return false; + } + + return Enumerable.SequenceEqual(this.Items, other.Items); + } + + public override int GetHashCode() => 0; } diff --git a/src/Anthropic/Models/Beta/Skills/SkillListPage.cs b/src/Anthropic/Models/Beta/Skills/SkillListPage.cs index 4d989e7da..69357b616 100644 --- a/src/Anthropic/Models/Beta/Skills/SkillListPage.cs +++ b/src/Anthropic/Models/Beta/Skills/SkillListPage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -63,4 +64,16 @@ public void Validate() public override string ToString() => JsonSerializer.Serialize(this.Items, ModelBase.ToStringSerializerOptions); + + public override bool Equals(object? obj) + { + if (obj is not SkillListPage other) + { + return false; + } + + return Enumerable.SequenceEqual(this.Items, other.Items); + } + + public override int GetHashCode() => 0; } diff --git a/src/Anthropic/Models/Beta/Skills/Versions/VersionListPage.cs b/src/Anthropic/Models/Beta/Skills/Versions/VersionListPage.cs index 73734dbb0..7648f8f91 100644 --- a/src/Anthropic/Models/Beta/Skills/Versions/VersionListPage.cs +++ b/src/Anthropic/Models/Beta/Skills/Versions/VersionListPage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -63,4 +64,16 @@ public void Validate() public override string ToString() => JsonSerializer.Serialize(this.Items, ModelBase.ToStringSerializerOptions); + + public override bool Equals(object? obj) + { + if (obj is not VersionListPage other) + { + return false; + } + + return Enumerable.SequenceEqual(this.Items, other.Items); + } + + public override int GetHashCode() => 0; } diff --git a/src/Anthropic/Models/Messages/Batches/BatchListPage.cs b/src/Anthropic/Models/Messages/Batches/BatchListPage.cs index c059773f4..1db6f68a5 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchListPage.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchListPage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -62,4 +63,16 @@ public void Validate() public override string ToString() => JsonSerializer.Serialize(this.Items, ModelBase.ToStringSerializerOptions); + + public override bool Equals(object? obj) + { + if (obj is not BatchListPage other) + { + return false; + } + + return Enumerable.SequenceEqual(this.Items, other.Items); + } + + public override int GetHashCode() => 0; } diff --git a/src/Anthropic/Models/Models/ModelListPage.cs b/src/Anthropic/Models/Models/ModelListPage.cs index 23c9b1326..2a791b58a 100644 --- a/src/Anthropic/Models/Models/ModelListPage.cs +++ b/src/Anthropic/Models/Models/ModelListPage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -62,4 +63,16 @@ public void Validate() public override string ToString() => JsonSerializer.Serialize(this.Items, ModelBase.ToStringSerializerOptions); + + public override bool Equals(object? obj) + { + if (obj is not ModelListPage other) + { + return false; + } + + return Enumerable.SequenceEqual(this.Items, other.Items); + } + + public override int GetHashCode() => 0; } From e11aa04c5d0a5dabefb27cc962bfc17ff408a6d4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 23 Jan 2026 23:50:23 +0000 Subject: [PATCH 17/41] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 4bbd93aa0..b0058c14f 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 32 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-f7bcdc13402c6129b30be620021a724945de44cffc6add091798f9cce33a1e32.yml openapi_spec_hash: e78807e31b9233abc50ccc00304bfa4d -config_hash: 92ca93edc068c543f2da38737239322d +config_hash: 712e84f0cacb3436913f57da3d959b5c From 8b4d892a18d6b05ed031bfecb1e78bfc0094cf47 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 19:36:18 +0000 Subject: [PATCH 18/41] chore(internal): improve HttpResponse qualification --- src/Anthropic/Core/HttpResponse.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Anthropic/Core/HttpResponse.cs b/src/Anthropic/Core/HttpResponse.cs index c8d4f6f73..1f54bd0b8 100644 --- a/src/Anthropic/Core/HttpResponse.cs +++ b/src/Anthropic/Core/HttpResponse.cs @@ -43,7 +43,7 @@ public bool TryGetHeaderValues( public override bool Equals(object? obj) { - if (obj is not global::Anthropic.Core.HttpResponse other) + if (obj is not HttpResponse other) { return false; } @@ -109,7 +109,7 @@ public void Dispose() } } -public sealed class HttpResponse : global::Anthropic.Core.HttpResponse +public sealed class HttpResponse : HttpResponse { readonly Func> _deserialize; @@ -120,7 +120,7 @@ internal HttpResponse(Func> deserialize) [SetsRequiredMembers] internal HttpResponse( - global::Anthropic.Core.HttpResponse response, + HttpResponse response, Func> deserialize ) : this(deserialize) @@ -139,7 +139,7 @@ public Task Deserialize(Threading::CancellationToken cancellationToken = defa } } -public sealed class StreamingHttpResponse : global::Anthropic.Core.HttpResponse +public sealed class StreamingHttpResponse : HttpResponse { readonly Func> _enumerate; @@ -152,7 +152,7 @@ internal StreamingHttpResponse( [SetsRequiredMembers] internal StreamingHttpResponse( - global::Anthropic.Core.HttpResponse response, + HttpResponse response, Func> enumerate ) : this(enumerate) From 9dc5b92ae074c54e9287f6e7179a4b5c1dfe02b1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 27 Jan 2026 21:13:45 +0000 Subject: [PATCH 19/41] fix(client): handle unions containing unknown types properly --- .../Models/Beta/Messages/BetaClearToolUses20250919Edit.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs b/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs index 4f4eefca4..b4a368db1 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs @@ -377,7 +377,7 @@ JsonSerializerOptions options var element = JsonSerializer.Deserialize(ref reader, options); try { - return new(JsonSerializer.Deserialize(element, options)); + return new(JsonSerializer.Deserialize(element, options), element); } catch (System::Exception e) when (e is JsonException || e is AnthropicInvalidDataException) { From e8bbba38f9182b2e963f0f994e56b5ee6e96f720 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 28 Jan 2026 14:35:07 +0000 Subject: [PATCH 20/41] chore(client): improve example values --- .../Models/Beta/Files/FileDeleteParamsTest.cs | 25 +++++++++++++---- .../Beta/Files/FileDownloadParamsTest.cs | 25 +++++++++++++---- .../Models/Beta/Files/FileListParamsTest.cs | 13 +++++---- .../Files/FileRetrieveMetadataParamsTest.cs | 25 +++++++++++++---- .../Messages/Batches/BatchCancelParamsTest.cs | 13 +++++---- .../Messages/Batches/BatchCreateParamsTest.cs | 13 +++++---- .../Messages/Batches/BatchDeleteParamsTest.cs | 13 +++++---- .../Messages/Batches/BatchListParamsTest.cs | 13 +++++---- .../Batches/BatchResultsParamsTest.cs | 13 +++++---- .../Batches/BatchRetrieveParamsTest.cs | 13 +++++---- .../Messages/MessageCountTokensParamsTest.cs | 20 ++++++++----- .../Beta/Messages/MessageCreateParamsTest.cs | 20 ++++++++----- .../Models/Beta/Models/ModelListParamsTest.cs | 16 +++++++---- .../Beta/Models/ModelRetrieveParamsTest.cs | 28 +++++++++++++++---- .../Beta/Skills/SkillCreateParamsTest.cs | 9 +++--- .../Beta/Skills/SkillDeleteParamsTest.cs | 25 +++++++++++++---- .../Models/Beta/Skills/SkillListParamsTest.cs | 21 +++++++++----- .../Beta/Skills/SkillRetrieveParamsTest.cs | 25 +++++++++++++---- .../Versions/VersionCreateParamsTest.cs | 17 ++++++++--- .../Versions/VersionDeleteParamsTest.cs | 13 +++++---- .../Skills/Versions/VersionListParamsTest.cs | 25 ++++++++++++----- .../Versions/VersionRetrieveParamsTest.cs | 13 +++++---- .../Models/Models/ModelListParamsTest.cs | 16 +++++++---- .../Models/Models/ModelRetrieveParamsTest.cs | 28 +++++++++++++++---- 24 files changed, 316 insertions(+), 126 deletions(-) diff --git a/src/Anthropic.Tests/Models/Beta/Files/FileDeleteParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Files/FileDeleteParamsTest.cs index ef28f357d..a156a7af5 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/FileDeleteParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/FileDeleteParamsTest.cs @@ -12,10 +12,17 @@ public class FileDeleteParamsTest : TestBase [Fact] public void FieldRoundtrip_Works() { - var parameters = new FileDeleteParams { FileID = "file_id", Betas = ["string"] }; + var parameters = new FileDeleteParams + { + FileID = "file_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; string expectedFileID = "file_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedFileID, parameters.FileID); Assert.NotNull(parameters.Betas); @@ -64,12 +71,16 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - FileDeleteParams parameters = new() { FileID = "file_id", Betas = ["string"] }; + FileDeleteParams parameters = new() + { + FileID = "file_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["files-api-2025-04-14", "string"], + ["files-api-2025-04-14", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -77,7 +88,11 @@ public void AddHeadersToRequest_Works() [Fact] public void CopyConstructor_Works() { - var parameters = new FileDeleteParams { FileID = "file_id", Betas = ["string"] }; + var parameters = new FileDeleteParams + { + FileID = "file_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; FileDeleteParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Files/FileDownloadParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Files/FileDownloadParamsTest.cs index 5916a60bd..53ca67f9b 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/FileDownloadParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/FileDownloadParamsTest.cs @@ -12,10 +12,17 @@ public class FileDownloadParamsTest : TestBase [Fact] public void FieldRoundtrip_Works() { - var parameters = new FileDownloadParams { FileID = "file_id", Betas = ["string"] }; + var parameters = new FileDownloadParams + { + FileID = "file_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; string expectedFileID = "file_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedFileID, parameters.FileID); Assert.NotNull(parameters.Betas); @@ -64,12 +71,16 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - FileDownloadParams parameters = new() { FileID = "file_id", Betas = ["string"] }; + FileDownloadParams parameters = new() + { + FileID = "file_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["files-api-2025-04-14", "string"], + ["files-api-2025-04-14", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -77,7 +88,11 @@ public void AddHeadersToRequest_Works() [Fact] public void CopyConstructor_Works() { - var parameters = new FileDownloadParams { FileID = "file_id", Betas = ["string"] }; + var parameters = new FileDownloadParams + { + FileID = "file_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; FileDownloadParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Files/FileListParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Files/FileListParamsTest.cs index bd580bc61..6c6e56df9 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/FileListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/FileListParamsTest.cs @@ -17,13 +17,16 @@ public void FieldRoundtrip_Works() AfterID = "after_id", BeforeID = "before_id", Limit = 1, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedAfterID = "after_id"; string expectedBeforeID = "before_id"; long expectedLimit = 1; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedAfterID, parameters.AfterID); Assert.Equal(expectedBeforeID, parameters.BeforeID); @@ -97,12 +100,12 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - FileListParams parameters = new() { Betas = ["string"] }; + FileListParams parameters = new() { Betas = [AnthropicBeta.MessageBatches2024_09_24] }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["files-api-2025-04-14", "string"], + ["files-api-2025-04-14", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -115,7 +118,7 @@ public void CopyConstructor_Works() AfterID = "after_id", BeforeID = "before_id", Limit = 1, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; FileListParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Files/FileRetrieveMetadataParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Files/FileRetrieveMetadataParamsTest.cs index 22ad6dbe7..392c805da 100644 --- a/src/Anthropic.Tests/Models/Beta/Files/FileRetrieveMetadataParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Files/FileRetrieveMetadataParamsTest.cs @@ -12,10 +12,17 @@ public class FileRetrieveMetadataParamsTest : TestBase [Fact] public void FieldRoundtrip_Works() { - var parameters = new FileRetrieveMetadataParams { FileID = "file_id", Betas = ["string"] }; + var parameters = new FileRetrieveMetadataParams + { + FileID = "file_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; string expectedFileID = "file_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedFileID, parameters.FileID); Assert.NotNull(parameters.Betas); @@ -64,12 +71,16 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - FileRetrieveMetadataParams parameters = new() { FileID = "file_id", Betas = ["string"] }; + FileRetrieveMetadataParams parameters = new() + { + FileID = "file_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["files-api-2025-04-14", "string"], + ["files-api-2025-04-14", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -77,7 +88,11 @@ public void AddHeadersToRequest_Works() [Fact] public void CopyConstructor_Works() { - var parameters = new FileRetrieveMetadataParams { FileID = "file_id", Betas = ["string"] }; + var parameters = new FileRetrieveMetadataParams + { + FileID = "file_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; FileRetrieveMetadataParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCancelParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCancelParamsTest.cs index a7a1b400a..1832a3a51 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCancelParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCancelParamsTest.cs @@ -15,11 +15,14 @@ public void FieldRoundtrip_Works() var parameters = new BatchCancelParams { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedMessageBatchID = "message_batch_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedMessageBatchID, parameters.MessageBatchID); Assert.NotNull(parameters.Betas); @@ -74,13 +77,13 @@ public void AddHeadersToRequest_Works() BatchCancelParams parameters = new() { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["message-batches-2024-09-24", "string"], + ["message-batches-2024-09-24", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -91,7 +94,7 @@ public void CopyConstructor_Works() var parameters = new BatchCancelParams { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; BatchCancelParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs index 01dbe7c49..4909605ee 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs @@ -151,7 +151,7 @@ public void FieldRoundtrip_Works() }, }, ], - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; List expectedRequests = @@ -283,7 +283,10 @@ public void FieldRoundtrip_Works() }, }, ]; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedRequests.Count, parameters.Requests.Count); for (int i = 0; i < expectedRequests.Count; i++) @@ -873,13 +876,13 @@ public void AddHeadersToRequest_Works() }, }, ], - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["message-batches-2024-09-24", "string"], + ["message-batches-2024-09-24", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -1022,7 +1025,7 @@ public void CopyConstructor_Works() }, }, ], - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; BatchCreateParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchDeleteParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchDeleteParamsTest.cs index fc17a9ff8..bcf0fa360 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchDeleteParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchDeleteParamsTest.cs @@ -15,11 +15,14 @@ public void FieldRoundtrip_Works() var parameters = new BatchDeleteParams { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedMessageBatchID = "message_batch_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedMessageBatchID, parameters.MessageBatchID); Assert.NotNull(parameters.Betas); @@ -74,13 +77,13 @@ public void AddHeadersToRequest_Works() BatchDeleteParams parameters = new() { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["message-batches-2024-09-24", "string"], + ["message-batches-2024-09-24", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -91,7 +94,7 @@ public void CopyConstructor_Works() var parameters = new BatchDeleteParams { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; BatchDeleteParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListParamsTest.cs index ef400702b..ad82903cb 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchListParamsTest.cs @@ -17,13 +17,16 @@ public void FieldRoundtrip_Works() AfterID = "after_id", BeforeID = "before_id", Limit = 1, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedAfterID = "after_id"; string expectedBeforeID = "before_id"; long expectedLimit = 1; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedAfterID, parameters.AfterID); Assert.Equal(expectedBeforeID, parameters.BeforeID); @@ -97,12 +100,12 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - BatchListParams parameters = new() { Betas = ["string"] }; + BatchListParams parameters = new() { Betas = [AnthropicBeta.MessageBatches2024_09_24] }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["message-batches-2024-09-24", "string"], + ["message-batches-2024-09-24", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -115,7 +118,7 @@ public void CopyConstructor_Works() AfterID = "after_id", BeforeID = "before_id", Limit = 1, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; BatchListParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchResultsParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchResultsParamsTest.cs index 27f19e0fb..ee500ddaf 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchResultsParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchResultsParamsTest.cs @@ -15,11 +15,14 @@ public void FieldRoundtrip_Works() var parameters = new BatchResultsParams { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedMessageBatchID = "message_batch_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedMessageBatchID, parameters.MessageBatchID); Assert.NotNull(parameters.Betas); @@ -74,13 +77,13 @@ public void AddHeadersToRequest_Works() BatchResultsParams parameters = new() { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["message-batches-2024-09-24", "string"], + ["message-batches-2024-09-24", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -91,7 +94,7 @@ public void CopyConstructor_Works() var parameters = new BatchResultsParams { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; BatchResultsParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchRetrieveParamsTest.cs index 55fc65a13..4e7dd16ef 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchRetrieveParamsTest.cs @@ -15,11 +15,14 @@ public void FieldRoundtrip_Works() var parameters = new BatchRetrieveParams { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedMessageBatchID = "message_batch_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedMessageBatchID, parameters.MessageBatchID); Assert.NotNull(parameters.Betas); @@ -74,13 +77,13 @@ public void AddHeadersToRequest_Works() BatchRetrieveParams parameters = new() { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["message-batches-2024-09-24", "string"], + ["message-batches-2024-09-24", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -91,7 +94,7 @@ public void CopyConstructor_Works() var parameters = new BatchRetrieveParams { MessageBatchID = "message_batch_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; BatchRetrieveParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs index 374c420fd..95b00c0fb 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs @@ -111,7 +111,7 @@ public void FieldRoundtrip_Works() Type = BetaToolType.Custom, }, ], - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; List expectedMessages = [new() { Content = "string", Role = Role.User }]; @@ -212,7 +212,10 @@ public void FieldRoundtrip_Works() Type = BetaToolType.Custom, }, ]; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedMessages.Count, parameters.Messages.Count); for (int i = 0; i < expectedMessages.Count; i++) @@ -426,7 +429,7 @@ public void OptionalNullableParamsUnsetAreNotSet_Works() Type = BetaToolType.Custom, }, ], - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; Assert.Null(parameters.ContextManagement); @@ -514,7 +517,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() Type = BetaToolType.Custom, }, ], - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], ContextManagement = null, OutputFormat = null, @@ -548,12 +551,15 @@ public void AddHeadersToRequest_Works() { Messages = [new() { Content = "string", Role = Role.User }], Model = Messages::Model.ClaudeOpus4_5_20251101, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); - Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); + Assert.Equal( + ["message-batches-2024-09-24"], + requestMessage.Headers.GetValues("anthropic-beta") + ); } [Fact] @@ -656,7 +662,7 @@ public void CopyConstructor_Works() Type = BetaToolType.Custom, }, ], - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; MessageCountTokensParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs index 70c00809a..dc3e72ab1 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs @@ -132,7 +132,7 @@ public void FieldRoundtrip_Works() ], TopK = 5, TopP = 0.7, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; long expectedMaxTokens = 1024; @@ -256,7 +256,10 @@ public void FieldRoundtrip_Works() ]; long expectedTopK = 5; double expectedTopP = 0.7; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedMaxTokens, parameters.MaxTokens); Assert.Equal(expectedMessages.Count, parameters.Messages.Count); @@ -548,7 +551,7 @@ public void OptionalNullableParamsUnsetAreNotSet_Works() ], TopK = 5, TopP = 0.7, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; Assert.Null(parameters.Container); @@ -645,7 +648,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() ], TopK = 5, TopP = 0.7, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], Container = null, ContextManagement = null, @@ -684,12 +687,15 @@ public void AddHeadersToRequest_Works() MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); - Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); + Assert.Equal( + ["message-batches-2024-09-24"], + requestMessage.Headers.GetValues("anthropic-beta") + ); } [Fact] @@ -812,7 +818,7 @@ public void CopyConstructor_Works() ], TopK = 5, TopP = 0.7, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; MessageCreateParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Models/ModelListParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Models/ModelListParamsTest.cs index 6b5cc0a22..01123f5fe 100644 --- a/src/Anthropic.Tests/Models/Beta/Models/ModelListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Models/ModelListParamsTest.cs @@ -17,13 +17,16 @@ public void FieldRoundtrip_Works() AfterID = "after_id", BeforeID = "before_id", Limit = 1, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedAfterID = "after_id"; string expectedBeforeID = "before_id"; long expectedLimit = 1; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedAfterID, parameters.AfterID); Assert.Equal(expectedBeforeID, parameters.BeforeID); @@ -97,11 +100,14 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - ModelListParams parameters = new() { Betas = ["string"] }; + ModelListParams parameters = new() { Betas = [AnthropicBeta.MessageBatches2024_09_24] }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); - Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); + Assert.Equal( + ["message-batches-2024-09-24"], + requestMessage.Headers.GetValues("anthropic-beta") + ); } [Fact] @@ -112,7 +118,7 @@ public void CopyConstructor_Works() AfterID = "after_id", BeforeID = "before_id", Limit = 1, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; ModelListParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Models/ModelRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Models/ModelRetrieveParamsTest.cs index f8d227ae3..4e9a59b28 100644 --- a/src/Anthropic.Tests/Models/Beta/Models/ModelRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Models/ModelRetrieveParamsTest.cs @@ -12,10 +12,17 @@ public class ModelRetrieveParamsTest : TestBase [Fact] public void FieldRoundtrip_Works() { - var parameters = new ModelRetrieveParams { ModelID = "model_id", Betas = ["string"] }; + var parameters = new ModelRetrieveParams + { + ModelID = "model_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; string expectedModelID = "model_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedModelID, parameters.ModelID); Assert.NotNull(parameters.Betas); @@ -64,17 +71,28 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - ModelRetrieveParams parameters = new() { ModelID = "model_id", Betas = ["string"] }; + ModelRetrieveParams parameters = new() + { + ModelID = "model_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); - Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); + Assert.Equal( + ["message-batches-2024-09-24"], + requestMessage.Headers.GetValues("anthropic-beta") + ); } [Fact] public void CopyConstructor_Works() { - var parameters = new ModelRetrieveParams { ModelID = "model_id", Betas = ["string"] }; + var parameters = new ModelRetrieveParams + { + ModelID = "model_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; ModelRetrieveParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillCreateParamsTest.cs index c8c487892..e8c034cdb 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillCreateParamsTest.cs @@ -1,6 +1,7 @@ using System; using System.Net.Http; using System.Text; +using Anthropic.Models.Beta; using Anthropic.Models.Beta.Skills; namespace Anthropic.Tests.Models.Beta.Skills; @@ -39,7 +40,7 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() [Fact] public void OptionalNullableParamsUnsetAreNotSet_Works() { - var parameters = new SkillCreateParams { Betas = ["string"] }; + var parameters = new SkillCreateParams { Betas = [AnthropicBeta.MessageBatches2024_09_24] }; Assert.Null(parameters.DisplayTitle); Assert.False(parameters.RawBodyData.ContainsKey("display_title")); @@ -52,7 +53,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() { var parameters = new SkillCreateParams { - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], DisplayTitle = null, Files = null, @@ -78,12 +79,12 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - SkillCreateParams parameters = new() { Betas = ["string"] }; + SkillCreateParams parameters = new() { Betas = [AnthropicBeta.MessageBatches2024_09_24] }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["skills-2025-10-02", "string"], + ["skills-2025-10-02", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteParamsTest.cs index a6f34b713..67d9c1f64 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillDeleteParamsTest.cs @@ -12,10 +12,17 @@ public class SkillDeleteParamsTest : TestBase [Fact] public void FieldRoundtrip_Works() { - var parameters = new SkillDeleteParams { SkillID = "skill_id", Betas = ["string"] }; + var parameters = new SkillDeleteParams + { + SkillID = "skill_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; string expectedSkillID = "skill_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedSkillID, parameters.SkillID); Assert.NotNull(parameters.Betas); @@ -64,12 +71,16 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - SkillDeleteParams parameters = new() { SkillID = "skill_id", Betas = ["string"] }; + SkillDeleteParams parameters = new() + { + SkillID = "skill_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["skills-2025-10-02", "string"], + ["skills-2025-10-02", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -77,7 +88,11 @@ public void AddHeadersToRequest_Works() [Fact] public void CopyConstructor_Works() { - var parameters = new SkillDeleteParams { SkillID = "skill_id", Betas = ["string"] }; + var parameters = new SkillDeleteParams + { + SkillID = "skill_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; SkillDeleteParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillListParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillListParamsTest.cs index a98225e59..128c1bd21 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillListParamsTest.cs @@ -17,13 +17,16 @@ public void FieldRoundtrip_Works() Limit = 0, Page = "page", Source = "source", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; long expectedLimit = 0; string expectedPage = "page"; string expectedSource = "source"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedLimit, parameters.Limit); Assert.Equal(expectedPage, parameters.Page); @@ -69,7 +72,11 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() [Fact] public void OptionalNullableParamsUnsetAreNotSet_Works() { - var parameters = new SkillListParams { Limit = 0, Betas = ["string"] }; + var parameters = new SkillListParams + { + Limit = 0, + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; Assert.Null(parameters.Page); Assert.False(parameters.RawQueryData.ContainsKey("page")); @@ -83,7 +90,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() var parameters = new SkillListParams { Limit = 0, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], Page = null, Source = null, @@ -117,12 +124,12 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - SkillListParams parameters = new() { Betas = ["string"] }; + SkillListParams parameters = new() { Betas = [AnthropicBeta.MessageBatches2024_09_24] }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["skills-2025-10-02", "string"], + ["skills-2025-10-02", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -135,7 +142,7 @@ public void CopyConstructor_Works() Limit = 0, Page = "page", Source = "source", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; SkillListParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveParamsTest.cs index bc8697155..ef0aafc8d 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/SkillRetrieveParamsTest.cs @@ -12,10 +12,17 @@ public class SkillRetrieveParamsTest : TestBase [Fact] public void FieldRoundtrip_Works() { - var parameters = new SkillRetrieveParams { SkillID = "skill_id", Betas = ["string"] }; + var parameters = new SkillRetrieveParams + { + SkillID = "skill_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; string expectedSkillID = "skill_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedSkillID, parameters.SkillID); Assert.NotNull(parameters.Betas); @@ -64,12 +71,16 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - SkillRetrieveParams parameters = new() { SkillID = "skill_id", Betas = ["string"] }; + SkillRetrieveParams parameters = new() + { + SkillID = "skill_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["skills-2025-10-02", "string"], + ["skills-2025-10-02", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -77,7 +88,11 @@ public void AddHeadersToRequest_Works() [Fact] public void CopyConstructor_Works() { - var parameters = new SkillRetrieveParams { SkillID = "skill_id", Betas = ["string"] }; + var parameters = new SkillRetrieveParams + { + SkillID = "skill_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; SkillRetrieveParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionCreateParamsTest.cs index e501a0aa9..629aa0d32 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionCreateParamsTest.cs @@ -1,6 +1,7 @@ using System; using System.Net.Http; using System.Text; +using Anthropic.Models.Beta; using Anthropic.Models.Beta.Skills.Versions; namespace Anthropic.Tests.Models.Beta.Skills.Versions; @@ -39,7 +40,11 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() [Fact] public void OptionalNullableParamsUnsetAreNotSet_Works() { - var parameters = new VersionCreateParams { SkillID = "skill_id", Betas = ["string"] }; + var parameters = new VersionCreateParams + { + SkillID = "skill_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; Assert.Null(parameters.Files); Assert.False(parameters.RawBodyData.ContainsKey("files")); @@ -51,7 +56,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() var parameters = new VersionCreateParams { SkillID = "skill_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], Files = null, }; @@ -74,12 +79,16 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - VersionCreateParams parameters = new() { SkillID = "skill_id", Betas = ["string"] }; + VersionCreateParams parameters = new() + { + SkillID = "skill_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["skills-2025-10-02", "string"], + ["skills-2025-10-02", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteParamsTest.cs index f2f6c090b..07bc1019b 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionDeleteParamsTest.cs @@ -16,12 +16,15 @@ public void FieldRoundtrip_Works() { SkillID = "skill_id", Version = "version", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedSkillID = "skill_id"; string expectedVersion = "version"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedSkillID, parameters.SkillID); Assert.Equal(expectedVersion, parameters.Version); @@ -76,13 +79,13 @@ public void AddHeadersToRequest_Works() { SkillID = "skill_id", Version = "version", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["skills-2025-10-02", "string"], + ["skills-2025-10-02", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -94,7 +97,7 @@ public void CopyConstructor_Works() { SkillID = "skill_id", Version = "version", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; VersionDeleteParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListParamsTest.cs index 21903559f..81e221830 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionListParamsTest.cs @@ -17,13 +17,16 @@ public void FieldRoundtrip_Works() SkillID = "skill_id", Limit = 0, Page = "page", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedSkillID = "skill_id"; long expectedLimit = 0; string expectedPage = "page"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedSkillID, parameters.SkillID); Assert.Equal(expectedLimit, parameters.Limit); @@ -70,7 +73,11 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() [Fact] public void OptionalNullableParamsUnsetAreNotSet_Works() { - var parameters = new VersionListParams { SkillID = "skill_id", Betas = ["string"] }; + var parameters = new VersionListParams + { + SkillID = "skill_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; Assert.Null(parameters.Limit); Assert.False(parameters.RawQueryData.ContainsKey("limit")); @@ -84,7 +91,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() var parameters = new VersionListParams { SkillID = "skill_id", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], Limit = null, Page = null, @@ -118,12 +125,16 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - VersionListParams parameters = new() { SkillID = "skill_id", Betas = ["string"] }; + VersionListParams parameters = new() + { + SkillID = "skill_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["skills-2025-10-02", "string"], + ["skills-2025-10-02", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -136,7 +147,7 @@ public void CopyConstructor_Works() SkillID = "skill_id", Limit = 0, Page = "page", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; VersionListParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveParamsTest.cs index 1a8e595b3..d69b8a0aa 100644 --- a/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Skills/Versions/VersionRetrieveParamsTest.cs @@ -16,12 +16,15 @@ public void FieldRoundtrip_Works() { SkillID = "skill_id", Version = "version", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedSkillID = "skill_id"; string expectedVersion = "version"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedSkillID, parameters.SkillID); Assert.Equal(expectedVersion, parameters.Version); @@ -76,13 +79,13 @@ public void AddHeadersToRequest_Works() { SkillID = "skill_id", Version = "version", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); Assert.Equal( - ["skills-2025-10-02", "string"], + ["skills-2025-10-02", "message-batches-2024-09-24"], requestMessage.Headers.GetValues("anthropic-beta") ); } @@ -94,7 +97,7 @@ public void CopyConstructor_Works() { SkillID = "skill_id", Version = "version", - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; VersionRetrieveParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Models/ModelListParamsTest.cs b/src/Anthropic.Tests/Models/Models/ModelListParamsTest.cs index a6dae8e77..23cb74269 100644 --- a/src/Anthropic.Tests/Models/Models/ModelListParamsTest.cs +++ b/src/Anthropic.Tests/Models/Models/ModelListParamsTest.cs @@ -17,13 +17,16 @@ public void FieldRoundtrip_Works() AfterID = "after_id", BeforeID = "before_id", Limit = 1, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; string expectedAfterID = "after_id"; string expectedBeforeID = "before_id"; long expectedLimit = 1; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedAfterID, parameters.AfterID); Assert.Equal(expectedBeforeID, parameters.BeforeID); @@ -97,11 +100,14 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - ModelListParams parameters = new() { Betas = ["string"] }; + ModelListParams parameters = new() { Betas = [AnthropicBeta.MessageBatches2024_09_24] }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); - Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); + Assert.Equal( + ["message-batches-2024-09-24"], + requestMessage.Headers.GetValues("anthropic-beta") + ); } [Fact] @@ -112,7 +118,7 @@ public void CopyConstructor_Works() AfterID = "after_id", BeforeID = "before_id", Limit = 1, - Betas = ["string"], + Betas = [AnthropicBeta.MessageBatches2024_09_24], }; ModelListParams copied = new(parameters); diff --git a/src/Anthropic.Tests/Models/Models/ModelRetrieveParamsTest.cs b/src/Anthropic.Tests/Models/Models/ModelRetrieveParamsTest.cs index 1b5a45a14..75c9be566 100644 --- a/src/Anthropic.Tests/Models/Models/ModelRetrieveParamsTest.cs +++ b/src/Anthropic.Tests/Models/Models/ModelRetrieveParamsTest.cs @@ -12,10 +12,17 @@ public class ModelRetrieveParamsTest : TestBase [Fact] public void FieldRoundtrip_Works() { - var parameters = new ModelRetrieveParams { ModelID = "model_id", Betas = ["string"] }; + var parameters = new ModelRetrieveParams + { + ModelID = "model_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; string expectedModelID = "model_id"; - List> expectedBetas = ["string"]; + List> expectedBetas = + [ + AnthropicBeta.MessageBatches2024_09_24, + ]; Assert.Equal(expectedModelID, parameters.ModelID); Assert.NotNull(parameters.Betas); @@ -64,17 +71,28 @@ public void Url_Works() public void AddHeadersToRequest_Works() { HttpRequestMessage requestMessage = new(); - ModelRetrieveParams parameters = new() { ModelID = "model_id", Betas = ["string"] }; + ModelRetrieveParams parameters = new() + { + ModelID = "model_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; parameters.AddHeadersToRequest(requestMessage, new() { ApiKey = "my-anthropic-api-key" }); - Assert.Equal(["string"], requestMessage.Headers.GetValues("anthropic-beta")); + Assert.Equal( + ["message-batches-2024-09-24"], + requestMessage.Headers.GetValues("anthropic-beta") + ); } [Fact] public void CopyConstructor_Works() { - var parameters = new ModelRetrieveParams { ModelID = "model_id", Betas = ["string"] }; + var parameters = new ModelRetrieveParams + { + ModelID = "model_id", + Betas = [AnthropicBeta.MessageBatches2024_09_24], + }; ModelRetrieveParams copied = new(parameters); From 7a15cb84611ea466f9b95b9fb22f0a713ebdb292 Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> Date: Thu, 29 Jan 2026 15:39:31 +0000 Subject: [PATCH 21/41] Update Anthropic Foundry Identity Token Credential (#55) * Changes from PR 55 * Lint fix * fix: replace deprecated Assert.IsAssignableFrom with Assert.IsType --- ...s => AnthropicFoundryApiKeyCredentials.cs} | 0 .../AnthropicFoundryBearerTokenCredentials.cs | 27 -- ...nthropicFoundryIdentityTokenCredentials.cs | 42 +- .../IAnthropicFoundryCredentials.cs | 18 +- ...picFoundryIdentityTokenCredentialsTests.cs | 383 ++++++++++++++++++ 5 files changed, 411 insertions(+), 59 deletions(-) rename src/Anthropic.Foundry/{AnthropicFoundryTokenCredentials.cs => AnthropicFoundryApiKeyCredentials.cs} (100%) delete mode 100644 src/Anthropic.Foundry/AnthropicFoundryBearerTokenCredentials.cs create mode 100644 src/Anthropic.Tests/Foundry/AnthropicFoundryIdentityTokenCredentialsTests.cs diff --git a/src/Anthropic.Foundry/AnthropicFoundryTokenCredentials.cs b/src/Anthropic.Foundry/AnthropicFoundryApiKeyCredentials.cs similarity index 100% rename from src/Anthropic.Foundry/AnthropicFoundryTokenCredentials.cs rename to src/Anthropic.Foundry/AnthropicFoundryApiKeyCredentials.cs diff --git a/src/Anthropic.Foundry/AnthropicFoundryBearerTokenCredentials.cs b/src/Anthropic.Foundry/AnthropicFoundryBearerTokenCredentials.cs deleted file mode 100644 index 049777528..000000000 --- a/src/Anthropic.Foundry/AnthropicFoundryBearerTokenCredentials.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Anthropic.Foundry; - -///

-/// Defines a new credential set using an Authorization: bearer token. -/// -public class AnthropicFoundryBearerTokenCredentials : IAnthropicFoundryCredentials -{ - private readonly string _apiKey; - - /// - /// Creates a new instance of the class. - /// - /// The bearer token. - public AnthropicFoundryBearerTokenCredentials(string apiKey, string resourceName) - { - _apiKey = apiKey ?? throw new ArgumentNullException(nameof(apiKey)); - ResourceName = resourceName ?? throw new ArgumentNullException(nameof(resourceName)); - } - - public string ResourceName { get; } - - public void Apply(HttpRequestMessage requestMessage) - { - requestMessage.Headers.Authorization = - new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", _apiKey); - } -} diff --git a/src/Anthropic.Foundry/AnthropicFoundryIdentityTokenCredentials.cs b/src/Anthropic.Foundry/AnthropicFoundryIdentityTokenCredentials.cs index ec17080f8..7a690408e 100644 --- a/src/Anthropic.Foundry/AnthropicFoundryIdentityTokenCredentials.cs +++ b/src/Anthropic.Foundry/AnthropicFoundryIdentityTokenCredentials.cs @@ -1,3 +1,4 @@ +using System.Net.Http.Headers; using Azure.Core; namespace Anthropic.Foundry; @@ -7,32 +8,37 @@ namespace Anthropic.Foundry; ///
public class AnthropicFoundryIdentityTokenCredentials : IAnthropicFoundryCredentials { - private readonly AccessToken _apiKey; + private readonly TokenCredential _tokenCredential; + private readonly string[] _scopes = ["https://ai.azure.com/.default"]; + + public string ResourceName { get; } /// - /// Creates a new instance of the class. + /// Creates a new instance of the . /// - /// The access token generated by the method. - /// The resource name as part of the base url for the api. - public AnthropicFoundryIdentityTokenCredentials(AccessToken apiKey, string resourceName) + /// The credential provider. Use any specialization of to get your access token in supported environments. + /// The service resource subdomain name to use in the anthropic azure endpoint + /// The scopes to use when requesting the token. If null, defaults to "https://ai.azure.com/.default" + public AnthropicFoundryIdentityTokenCredentials( + TokenCredential tokenCredential, + string resourceName, + string[]? scopes = null + ) { - if (apiKey.Equals(default) || string.IsNullOrWhiteSpace(apiKey.Token)) - { - throw new ArgumentNullException( - nameof(apiKey), - "Invalid/Empty api key struct is not valid" - ); - } - _apiKey = apiKey; ResourceName = resourceName ?? throw new ArgumentNullException(nameof(resourceName)); + _tokenCredential = + tokenCredential ?? throw new ArgumentNullException(nameof(tokenCredential)); + _scopes = scopes ?? _scopes; } - public string ResourceName { get; } - public void Apply(HttpRequestMessage requestMessage) { - //TODO implement token refresh - requestMessage.Headers.Authorization = - new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", _apiKey.Token); + requestMessage.Headers.Authorization = new AuthenticationHeaderValue( + "bearer", + this._tokenCredential.GetToken( + new TokenRequestContext(this._scopes), + CancellationToken.None + ).Token + ); } } diff --git a/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs b/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs index 763eb7e48..3431ebad8 100644 --- a/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs +++ b/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs @@ -57,19 +57,9 @@ is not string envResourceName return new AnthropicFoundryApiKeyCredentials(apiKey, resourceName ?? envResourceName); } - var defaultCredentialsProvider = new DefaultAzureCredential(); - - var azureToken = await defaultCredentialsProvider - .GetTokenAsync(new() { }) - .ConfigureAwait(false); - if (!azureToken.Equals(default)) - { - return new AnthropicFoundryIdentityTokenCredentials( - azureToken, - resourceName ?? envResourceName - ); - } - - return null; + return new AnthropicFoundryIdentityTokenCredentials( + new DefaultAzureCredential(), + resourceName ?? envResourceName + ); } } diff --git a/src/Anthropic.Tests/Foundry/AnthropicFoundryIdentityTokenCredentialsTests.cs b/src/Anthropic.Tests/Foundry/AnthropicFoundryIdentityTokenCredentialsTests.cs new file mode 100644 index 000000000..7b1abc439 --- /dev/null +++ b/src/Anthropic.Tests/Foundry/AnthropicFoundryIdentityTokenCredentialsTests.cs @@ -0,0 +1,383 @@ +using System; +using System.Net.Http; +using Anthropic.Foundry; +using Azure.Core; + +namespace Anthropic.Tests.Foundry; + +public class AnthropicFoundryIdentityTokenCredentialsTests +{ + private const string TestResourceName = "test-resource"; + private static readonly string[] DefaultScopes = ["https://ai.azure.com/.default"]; + + #region Constructor Validation Tests + + [Fact] + public void Constructor_WithNullTokenCredential_ThrowsArgumentNullException() + { + // Arrange + TokenCredential? nullCredential = null; + + // Act & Assert + var exception = Assert.Throws(() => + new AnthropicFoundryIdentityTokenCredentials(nullCredential!, TestResourceName) + ); + + Assert.Equal("tokenCredential", exception.ParamName); + } + + [Fact] + public void Constructor_WithNullResourceName_ThrowsArgumentNullException() + { + // Arrange + var credential = CreateFakeTokenCredential("test-token"); + + // Act & Assert + var exception = Assert.Throws(() => + new AnthropicFoundryIdentityTokenCredentials(credential, null!) + ); + + Assert.Equal("resourceName", exception.ParamName); + } + + [Fact] + public void Constructor_WithValidParameters_CreatesInstance() + { + // Arrange + var credential = CreateFakeTokenCredential("test-token"); + + // Act + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, TestResourceName); + + // Assert + Assert.NotNull(instance); + Assert.Equal(TestResourceName, instance.ResourceName); + } + + [Fact] + public void Constructor_WithCustomScopes_UsesProvidedScopes() + { + // Arrange + var credential = CreateFakeTokenCredential("test-token"); + string[]? receivedScopes = null; + var trackingCredential = CreateTrackingTokenCredential( + "test-token", + ctx => + { + receivedScopes = ctx.Scopes; + } + ); + var customScopes = new[] { "https://custom.scope/.default" }; + + // Act + var instance = new AnthropicFoundryIdentityTokenCredentials( + trackingCredential, + TestResourceName, + customScopes + ); + var request = new HttpRequestMessage(); + instance.Apply(request); + + // Assert + Assert.NotNull(receivedScopes); + Assert.Equal(customScopes, receivedScopes); + } + + [Fact] + public void Constructor_WithNullScopes_UsesDefaultScopes() + { + // Arrange + var credential = CreateFakeTokenCredential("test-token"); + string[]? receivedScopes = null; + var trackingCredential = CreateTrackingTokenCredential( + "test-token", + ctx => + { + receivedScopes = ctx.Scopes; + } + ); + + // Act + var instance = new AnthropicFoundryIdentityTokenCredentials( + trackingCredential, + TestResourceName, + null + ); + var request = new HttpRequestMessage(); + instance.Apply(request); + + // Assert + Assert.NotNull(receivedScopes); + Assert.Equal(DefaultScopes, receivedScopes); + } + + #endregion + + #region Apply Method Tests + + [Fact] + public void Apply_SetsAuthorizationHeaderWithBearerScheme() + { + // Arrange + const string testToken = "my-test-token"; + var credential = CreateFakeTokenCredential(testToken); + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, TestResourceName); + var request = new HttpRequestMessage(); + + // Act + instance.Apply(request); + + // Assert + Assert.NotNull(request.Headers.Authorization); + Assert.Equal("bearer", request.Headers.Authorization.Scheme); + Assert.Equal(testToken, request.Headers.Authorization.Parameter); + } + + [Fact] + public void Apply_WithEmptyToken_SetsEmptyAuthorizationParameter() + { + // Arrange + const string emptyToken = ""; + var credential = CreateFakeTokenCredential(emptyToken); + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, TestResourceName); + var request = new HttpRequestMessage(); + + // Act + instance.Apply(request); + + // Assert + Assert.NotNull(request.Headers.Authorization); + Assert.Equal("bearer", request.Headers.Authorization.Scheme); + Assert.Equal(emptyToken, request.Headers.Authorization.Parameter); + } + + [Theory] + [InlineData(" ")] + [InlineData(" ")] + [InlineData("\t")] + public void Apply_WithWhitespaceToken_SetsWhitespaceAuthorizationParameter( + string whitespaceToken + ) + { + // Arrange + var credential = CreateFakeTokenCredential(whitespaceToken); + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, TestResourceName); + var request = new HttpRequestMessage(); + + // Act + instance.Apply(request); + + // Assert + Assert.NotNull(request.Headers.Authorization); + Assert.Equal("bearer", request.Headers.Authorization.Scheme); + Assert.Equal(whitespaceToken, request.Headers.Authorization.Parameter); + } + + [Theory] + [InlineData("token-with-special-chars!@#$%^&*()")] + [InlineData("token.with.dots")] + [InlineData("token/with/slashes")] + [InlineData("token=with=equals")] + [InlineData( + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U" + )] + public void Apply_WithSpecialCharacterTokens_SetsAuthorizationParameter(string specialToken) + { + // Arrange + var credential = CreateFakeTokenCredential(specialToken); + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, TestResourceName); + var request = new HttpRequestMessage(); + + // Act + instance.Apply(request); + + // Assert + Assert.NotNull(request.Headers.Authorization); + Assert.Equal("bearer", request.Headers.Authorization.Scheme); + Assert.Equal(specialToken, request.Headers.Authorization.Parameter); + } + + [Fact] + public void Apply_CalledMultipleTimes_UpdatesAuthorizationHeader() + { + // Arrange + const string token = "test-token"; + var credential = CreateFakeTokenCredential(token); + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, TestResourceName); + var request1 = new HttpRequestMessage(); + var request2 = new HttpRequestMessage(); + + // Act + instance.Apply(request1); + instance.Apply(request2); + + // Assert + Assert.Equal(token, request1.Headers.Authorization?.Parameter); + Assert.Equal(token, request2.Headers.Authorization?.Parameter); + } + + #endregion + + #region Token Retrieval Tests + + [Fact] + public void Apply_InvokesTokenCredentialGetToken_WithCorrectContext() + { + // Arrange + TokenRequestContext? capturedContext = null; + var credential = CreateTrackingTokenCredential("test-token", ctx => capturedContext = ctx); + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, TestResourceName); + var request = new HttpRequestMessage(); + + // Act + instance.Apply(request); + + // Assert + Assert.NotNull(capturedContext); + Assert.Equal(DefaultScopes, capturedContext.Value.Scopes); + } + + [Fact] + public void Apply_WithCustomScopes_PassesCustomScopesToGetToken() + { + // Arrange + var customScopes = new[] + { + "https://custom.api.com/.default", + "https://another.api.com/.default", + }; + TokenRequestContext? capturedContext = null; + var credential = CreateTrackingTokenCredential("test-token", ctx => capturedContext = ctx); + var instance = new AnthropicFoundryIdentityTokenCredentials( + credential, + TestResourceName, + customScopes + ); + var request = new HttpRequestMessage(); + + // Act + instance.Apply(request); + + // Assert + Assert.NotNull(capturedContext); + Assert.Equal(customScopes, capturedContext.Value.Scopes); + } + + #endregion + + #region Error Handling Tests + + [Fact] + public void Apply_WhenTokenCredentialThrowsException_PropagatesException() + { + // Arrange + var expectedException = new InvalidOperationException("Token retrieval failed"); + var credential = CreateThrowingTokenCredential(expectedException); + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, TestResourceName); + var request = new HttpRequestMessage(); + + // Act & Assert + var thrownException = Assert.Throws(() => + instance.Apply(request) + ); + Assert.Same(expectedException, thrownException); + } + + [Fact] + public void Apply_WhenTokenCredentialThrowsAuthenticationException_PropagatesException() + { + // Arrange + var expectedException = new Azure.Identity.AuthenticationFailedException( + "Authentication failed" + ); + var credential = CreateThrowingTokenCredential(expectedException); + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, TestResourceName); + var request = new HttpRequestMessage(); + + // Act & Assert + var thrownException = Assert.Throws(() => + instance.Apply(request) + ); + Assert.Same(expectedException, thrownException); + } + + #endregion + + #region IAnthropicFoundryCredentials Interface Tests + + [Fact] + public void Instance_ImplementsIAnthropicFoundryCredentials() + { + // Arrange + var credential = CreateFakeTokenCredential("test-token"); + + // Act + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, TestResourceName); + + // Assert + Assert.IsType(instance, exactMatch: false); + } + + [Fact] + public void ResourceName_ReturnsConstructorValue() + { + // Arrange + const string resourceName = "my-custom-resource"; + var credential = CreateFakeTokenCredential("test-token"); + + // Act + var instance = new AnthropicFoundryIdentityTokenCredentials(credential, resourceName); + + // Assert + Assert.Equal(resourceName, instance.ResourceName); + } + + #endregion + + #region Helper Methods + + private static TokenCredential CreateFakeTokenCredential(string token) + { + return DelegatedTokenCredential.Create( + (context, cancellationToken) => + new AccessToken(token, DateTimeOffset.UtcNow.AddHours(1)) + ); + } + + private static TokenCredential CreateTrackingTokenCredential( + string token, + Action onGetToken + ) + { + return DelegatedTokenCredential.Create( + (context, cancellationToken) => + { + onGetToken(context); + return new AccessToken(token, DateTimeOffset.UtcNow.AddHours(1)); + } + ); + } + + private static TokenCredential CreateCountingTokenCredential(string token, Action onGetToken) + { + return DelegatedTokenCredential.Create( + (context, cancellationToken) => + { + onGetToken(); + return new AccessToken(token, DateTimeOffset.UtcNow.AddHours(1)); + } + ); + } + + private static TokenCredential CreateThrowingTokenCredential(Exception exception) + { + return DelegatedTokenCredential.Create( + (context, cancellationToken) => + { + throw exception; + } + ); + } + + #endregion +} From 6d3d655e52c43c91e8837dda186e04984d5dcf62 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 17:01:52 +0000 Subject: [PATCH 22/41] feat(api): add support for Structured Outputs in the Messages API --- .stats.yml | 6 +- .../Messages/Batches/BatchCreateParamsTest.cs | 206 +++++++++++ .../Models/Messages/JsonOutputFormatTest.cs | 120 +++++++ .../Messages/MessageCountTokensParamsTest.cs | 39 +++ .../Messages/MessageCountTokensToolTest.cs | 12 + .../Messages/MessageCreateParamsTest.cs | 39 +++ .../Models/Messages/OutputConfigTest.cs | 159 +++++++++ .../Models/Messages/ToolBash20250124Test.cs | 96 +++++- .../Models/Messages/ToolTest.cs | 19 ++ .../Messages/ToolTextEditor20250124Test.cs | 96 +++++- .../Messages/ToolTextEditor20250429Test.cs | 96 +++++- .../Messages/ToolTextEditor20250728Test.cs | 85 ++++- .../Models/Messages/ToolUnionTest.cs | 42 ++- .../Messages/WebSearchTool20250305Test.cs | 109 +++++- .../Services/Messages/BatchServiceTest.cs | 323 +++++++++--------- .../Messages/Batches/BatchCreateParams.cs | 3 +- .../Messages/BetaCodeExecutionTool20250522.cs | 3 + .../Messages/BetaCodeExecutionTool20250825.cs | 3 + .../Beta/Messages/BetaMemoryTool20250818.cs | 3 + .../Models/Beta/Messages/BetaOutputConfig.cs | 13 +- .../Models/Beta/Messages/BetaTool.cs | 3 + .../Beta/Messages/BetaToolBash20241022.cs | 3 + .../Beta/Messages/BetaToolBash20250124.cs | 3 + .../Messages/BetaToolComputerUse20241022.cs | 3 + .../Messages/BetaToolComputerUse20250124.cs | 3 + .../Messages/BetaToolComputerUse20251124.cs | 3 + .../BetaToolSearchToolBm25_20251119.cs | 3 + .../BetaToolSearchToolRegex20251119.cs | 3 + .../Messages/BetaToolTextEditor20241022.cs | 3 + .../Messages/BetaToolTextEditor20250124.cs | 3 + .../Messages/BetaToolTextEditor20250429.cs | 3 + .../Messages/BetaToolTextEditor20250728.cs | 3 + .../Beta/Messages/BetaWebFetchTool20250910.cs | 3 + .../Messages/BetaWebSearchTool20250305.cs | 3 + .../Beta/Messages/MessageCountTokensParams.cs | 3 +- .../Beta/Messages/MessageCreateParams.cs | 3 +- .../Messages/Batches/BatchCreateParams.cs | 22 ++ .../Models/Messages/JsonOutputFormat.cs | 93 +++++ .../Messages/MessageCountTokensParams.cs | 21 ++ .../Models/Messages/MessageCountTokensTool.cs | 15 + .../Models/Messages/MessageCreateParams.cs | 21 ++ src/Anthropic/Models/Messages/OutputConfig.cs | 65 ++++ src/Anthropic/Models/Messages/Tool.cs | 22 ++ .../Models/Messages/ToolBash20250124.cs | 22 ++ .../Models/Messages/ToolTextEditor20250124.cs | 22 ++ .../Models/Messages/ToolTextEditor20250429.cs | 22 ++ .../Models/Messages/ToolTextEditor20250728.cs | 22 ++ src/Anthropic/Models/Messages/ToolUnion.cs | 15 + .../Models/Messages/WebSearchTool20250305.cs | 22 ++ 49 files changed, 1699 insertions(+), 205 deletions(-) create mode 100644 src/Anthropic.Tests/Models/Messages/JsonOutputFormatTest.cs create mode 100644 src/Anthropic.Tests/Models/Messages/OutputConfigTest.cs create mode 100644 src/Anthropic/Models/Messages/JsonOutputFormat.cs create mode 100644 src/Anthropic/Models/Messages/OutputConfig.cs diff --git a/.stats.yml b/.stats.yml index b0058c14f..d2d2d8dfa 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 32 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-f7bcdc13402c6129b30be620021a724945de44cffc6add091798f9cce33a1e32.yml -openapi_spec_hash: e78807e31b9233abc50ccc00304bfa4d -config_hash: 712e84f0cacb3436913f57da3d959b5c +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-4526612d12e919de063708c05d15b78902b5a52d33a6e3eb45708c562d338b18.yml +openapi_spec_hash: 346bef71688ca79b107cf84bc09249ac +config_hash: 0b96ef87fc0758bbc543ffa8435baa2a diff --git a/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs index 0fbe78e9e..004d6a8bb 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs @@ -26,6 +26,16 @@ public void FieldRoundtrip_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -71,6 +81,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -92,6 +103,16 @@ public void FieldRoundtrip_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -134,6 +155,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -166,6 +188,16 @@ public void Url_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -211,6 +243,7 @@ public void Url_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -242,6 +275,16 @@ public void CopyConstructor_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -287,6 +330,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -317,6 +361,16 @@ public void FieldRoundtrip_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -359,6 +413,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -374,6 +429,16 @@ public void FieldRoundtrip_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -416,6 +481,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -439,6 +505,16 @@ public void SerializationRoundtrip_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -481,6 +557,7 @@ public void SerializationRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -507,6 +584,16 @@ public void FieldRoundtripThroughSerialization_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -549,6 +636,7 @@ public void FieldRoundtripThroughSerialization_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -571,6 +659,16 @@ public void FieldRoundtripThroughSerialization_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -613,6 +711,7 @@ public void FieldRoundtripThroughSerialization_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -636,6 +735,16 @@ public void Validation_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -678,6 +787,7 @@ public void Validation_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -701,6 +811,16 @@ public void CopyConstructor_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -743,6 +863,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -768,6 +889,16 @@ public void FieldRoundtrip_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -810,6 +941,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -827,6 +959,16 @@ public void FieldRoundtrip_Works() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b", }; + Messages::OutputConfig expectedOutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; ApiEnum expectedServiceTier = ServiceTier.Auto; List expectedStopSequences = ["string"]; bool expectedStream = true; @@ -872,6 +1014,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ]; @@ -886,6 +1029,7 @@ public void FieldRoundtrip_Works() } Assert.Equal(expectedModel, model.Model); Assert.Equal(expectedMetadata, model.Metadata); + Assert.Equal(expectedOutputConfig, model.OutputConfig); Assert.Equal(expectedServiceTier, model.ServiceTier); Assert.NotNull(model.StopSequences); Assert.Equal(expectedStopSequences.Count, model.StopSequences.Count); @@ -917,6 +1061,16 @@ public void SerializationRoundtrip_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -959,6 +1113,7 @@ public void SerializationRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -981,6 +1136,16 @@ public void FieldRoundtripThroughSerialization_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -1023,6 +1188,7 @@ public void FieldRoundtripThroughSerialization_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -1044,6 +1210,16 @@ public void FieldRoundtripThroughSerialization_Works() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b", }; + Messages::OutputConfig expectedOutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; ApiEnum expectedServiceTier = ServiceTier.Auto; List expectedStopSequences = ["string"]; bool expectedStream = true; @@ -1089,6 +1265,7 @@ public void FieldRoundtripThroughSerialization_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ]; @@ -1103,6 +1280,7 @@ public void FieldRoundtripThroughSerialization_Works() } Assert.Equal(expectedModel, deserialized.Model); Assert.Equal(expectedMetadata, deserialized.Metadata); + Assert.Equal(expectedOutputConfig, deserialized.OutputConfig); Assert.Equal(expectedServiceTier, deserialized.ServiceTier); Assert.NotNull(deserialized.StopSequences); Assert.Equal(expectedStopSequences.Count, deserialized.StopSequences.Count); @@ -1134,6 +1312,16 @@ public void Validation_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -1176,6 +1364,7 @@ public void Validation_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -1198,6 +1387,8 @@ public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() Assert.Null(model.Metadata); Assert.False(model.RawData.ContainsKey("metadata")); + Assert.Null(model.OutputConfig); + Assert.False(model.RawData.ContainsKey("output_config")); Assert.Null(model.ServiceTier); Assert.False(model.RawData.ContainsKey("service_tier")); Assert.Null(model.StopSequences); @@ -1244,6 +1435,7 @@ public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() // Null should be interpreted as omitted for these properties Metadata = null, + OutputConfig = null, ServiceTier = null, StopSequences = null, Stream = null, @@ -1258,6 +1450,8 @@ public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() Assert.Null(model.Metadata); Assert.False(model.RawData.ContainsKey("metadata")); + Assert.Null(model.OutputConfig); + Assert.False(model.RawData.ContainsKey("output_config")); Assert.Null(model.ServiceTier); Assert.False(model.RawData.ContainsKey("service_tier")); Assert.Null(model.StopSequences); @@ -1291,6 +1485,7 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() // Null should be interpreted as omitted for these properties Metadata = null, + OutputConfig = null, ServiceTier = null, StopSequences = null, Stream = null, @@ -1315,6 +1510,16 @@ public void CopyConstructor_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = ServiceTier.Auto, StopSequences = ["string"], Stream = true, @@ -1357,6 +1562,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], diff --git a/src/Anthropic.Tests/Models/Messages/JsonOutputFormatTest.cs b/src/Anthropic.Tests/Models/Messages/JsonOutputFormatTest.cs new file mode 100644 index 000000000..b9284e7be --- /dev/null +++ b/src/Anthropic.Tests/Models/Messages/JsonOutputFormatTest.cs @@ -0,0 +1,120 @@ +using System.Collections.Generic; +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Messages; + +namespace Anthropic.Tests.Models.Messages; + +public class JsonOutputFormatTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new JsonOutputFormat + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; + + Dictionary expectedSchema = new() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }; + JsonElement expectedType = JsonSerializer.SerializeToElement("json_schema"); + + Assert.Equal(expectedSchema.Count, model.Schema.Count); + foreach (var item in expectedSchema) + { + Assert.True(model.Schema.TryGetValue(item.Key, out var value)); + + Assert.True(JsonElement.DeepEquals(value, model.Schema[item.Key])); + } + Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new JsonOutputFormat + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new JsonOutputFormat + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + Dictionary expectedSchema = new() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }; + JsonElement expectedType = JsonSerializer.SerializeToElement("json_schema"); + + Assert.Equal(expectedSchema.Count, deserialized.Schema.Count); + foreach (var item in expectedSchema) + { + Assert.True(deserialized.Schema.TryGetValue(item.Key, out var value)); + + Assert.True(JsonElement.DeepEquals(value, deserialized.Schema[item.Key])); + } + Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); + } + + [Fact] + public void Validation_Works() + { + var model = new JsonOutputFormat + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new JsonOutputFormat + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; + + JsonOutputFormat copied = new(model); + + Assert.Equal(model, copied); + } +} diff --git a/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs b/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs index b7717ccb7..a50be909f 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs @@ -15,6 +15,16 @@ public void FieldRoundtrip_Works() { Messages = [new() { Content = "string", Role = Messages::Role.User }], Model = Messages::Model.ClaudeOpus4_5_20251101, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, System = new( [ new Messages::TextBlockParam() @@ -53,6 +63,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -63,6 +74,16 @@ public void FieldRoundtrip_Works() new() { Content = "string", Role = Messages::Role.User }, ]; ApiEnum expectedModel = Messages::Model.ClaudeOpus4_5_20251101; + Messages::OutputConfig expectedOutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; Messages::MessageCountTokensParamsSystem expectedSystem = new( [ new Messages::TextBlockParam() @@ -104,6 +125,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ]; @@ -114,6 +136,7 @@ public void FieldRoundtrip_Works() Assert.Equal(expectedMessages[i], parameters.Messages[i]); } Assert.Equal(expectedModel, parameters.Model); + Assert.Equal(expectedOutputConfig, parameters.OutputConfig); Assert.Equal(expectedSystem, parameters.System); Assert.Equal(expectedThinking, parameters.Thinking); Assert.Equal(expectedToolChoice, parameters.ToolChoice); @@ -134,6 +157,8 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() Model = Messages::Model.ClaudeOpus4_5_20251101, }; + Assert.Null(parameters.OutputConfig); + Assert.False(parameters.RawBodyData.ContainsKey("output_config")); Assert.Null(parameters.System); Assert.False(parameters.RawBodyData.ContainsKey("system")); Assert.Null(parameters.Thinking); @@ -153,12 +178,15 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() Model = Messages::Model.ClaudeOpus4_5_20251101, // Null should be interpreted as omitted for these properties + OutputConfig = null, System = null, Thinking = null, ToolChoice = null, Tools = null, }; + Assert.Null(parameters.OutputConfig); + Assert.False(parameters.RawBodyData.ContainsKey("output_config")); Assert.Null(parameters.System); Assert.False(parameters.RawBodyData.ContainsKey("system")); Assert.Null(parameters.Thinking); @@ -190,6 +218,16 @@ public void CopyConstructor_Works() { Messages = [new() { Content = "string", Role = Messages::Role.User }], Model = Messages::Model.ClaudeOpus4_5_20251101, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, System = new( [ new Messages::TextBlockParam() @@ -228,6 +266,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], diff --git a/src/Anthropic.Tests/Models/Messages/MessageCountTokensToolTest.cs b/src/Anthropic.Tests/Models/Messages/MessageCountTokensToolTest.cs index abd472199..4d4d3f07a 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageCountTokensToolTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageCountTokensToolTest.cs @@ -24,6 +24,7 @@ public void ToolValidationWorks() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Type.Custom, }; value.Validate(); @@ -35,6 +36,7 @@ public void ToolBash20250124ValidationWorks() MessageCountTokensTool value = new ToolBash20250124() { CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, }; value.Validate(); } @@ -45,6 +47,7 @@ public void ToolTextEditor20250124ValidationWorks() MessageCountTokensTool value = new ToolTextEditor20250124() { CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, }; value.Validate(); } @@ -55,6 +58,7 @@ public void ToolTextEditor20250429ValidationWorks() MessageCountTokensTool value = new ToolTextEditor20250429() { CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, }; value.Validate(); } @@ -66,6 +70,7 @@ public void ToolTextEditor20250728ValidationWorks() { CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxCharacters = 1, + Strict = true, }; value.Validate(); } @@ -79,6 +84,7 @@ public void WebSearchTool20250305ValidationWorks() BlockedDomains = ["string"], CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxUses = 1, + Strict = true, UserLocation = new() { City = "New York", @@ -107,6 +113,7 @@ public void ToolSerializationRoundtripWorks() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Type.Custom, }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); @@ -124,6 +131,7 @@ public void ToolBash20250124SerializationRoundtripWorks() MessageCountTokensTool value = new ToolBash20250124() { CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -140,6 +148,7 @@ public void ToolTextEditor20250124SerializationRoundtripWorks() MessageCountTokensTool value = new ToolTextEditor20250124() { CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -156,6 +165,7 @@ public void ToolTextEditor20250429SerializationRoundtripWorks() MessageCountTokensTool value = new ToolTextEditor20250429() { CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -173,6 +183,7 @@ public void ToolTextEditor20250728SerializationRoundtripWorks() { CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxCharacters = 1, + Strict = true, }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -192,6 +203,7 @@ public void WebSearchTool20250305SerializationRoundtripWorks() BlockedDomains = ["string"], CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxUses = 1, + Strict = true, UserLocation = new() { City = "New York", diff --git a/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs b/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs index fc3f39cae..0885b5a35 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs @@ -18,6 +18,16 @@ public void FieldRoundtrip_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = Messages::ServiceTier.Auto, StopSequences = ["string"], System = new( @@ -59,6 +69,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], @@ -76,6 +87,16 @@ public void FieldRoundtrip_Works() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b", }; + Messages::OutputConfig expectedOutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; ApiEnum expectedServiceTier = Messages::ServiceTier.Auto; List expectedStopSequences = ["string"]; Messages::MessageCreateParamsSystem expectedSystem = new( @@ -120,6 +141,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ]; @@ -134,6 +156,7 @@ public void FieldRoundtrip_Works() } Assert.Equal(expectedModel, parameters.Model); Assert.Equal(expectedMetadata, parameters.Metadata); + Assert.Equal(expectedOutputConfig, parameters.OutputConfig); Assert.Equal(expectedServiceTier, parameters.ServiceTier); Assert.NotNull(parameters.StopSequences); Assert.Equal(expectedStopSequences.Count, parameters.StopSequences.Count); @@ -167,6 +190,8 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() Assert.Null(parameters.Metadata); Assert.False(parameters.RawBodyData.ContainsKey("metadata")); + Assert.Null(parameters.OutputConfig); + Assert.False(parameters.RawBodyData.ContainsKey("output_config")); Assert.Null(parameters.ServiceTier); Assert.False(parameters.RawBodyData.ContainsKey("service_tier")); Assert.Null(parameters.StopSequences); @@ -198,6 +223,7 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() // Null should be interpreted as omitted for these properties Metadata = null, + OutputConfig = null, ServiceTier = null, StopSequences = null, System = null, @@ -211,6 +237,8 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() Assert.Null(parameters.Metadata); Assert.False(parameters.RawBodyData.ContainsKey("metadata")); + Assert.Null(parameters.OutputConfig); + Assert.False(parameters.RawBodyData.ContainsKey("output_config")); Assert.Null(parameters.ServiceTier); Assert.False(parameters.RawBodyData.ContainsKey("service_tier")); Assert.Null(parameters.StopSequences); @@ -255,6 +283,16 @@ public void CopyConstructor_Works() Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], Model = Messages::Model.ClaudeSonnet4_5_20250929, Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, ServiceTier = Messages::ServiceTier.Auto, StopSequences = ["string"], System = new( @@ -296,6 +334,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Messages::Type.Custom, }, ], diff --git a/src/Anthropic.Tests/Models/Messages/OutputConfigTest.cs b/src/Anthropic.Tests/Models/Messages/OutputConfigTest.cs new file mode 100644 index 000000000..c5fb5c7d8 --- /dev/null +++ b/src/Anthropic.Tests/Models/Messages/OutputConfigTest.cs @@ -0,0 +1,159 @@ +using System.Collections.Generic; +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Messages; + +namespace Anthropic.Tests.Models.Messages; + +public class OutputConfigTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new OutputConfig + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; + + JsonOutputFormat expectedFormat = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; + + Assert.Equal(expectedFormat, model.Format); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new OutputConfig + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new OutputConfig + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + JsonOutputFormat expectedFormat = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }; + + Assert.Equal(expectedFormat, deserialized.Format); + } + + [Fact] + public void Validation_Works() + { + var model = new OutputConfig + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; + + model.Validate(); + } + + [Fact] + public void OptionalNullablePropertiesUnsetAreNotSet_Works() + { + var model = new OutputConfig { }; + + Assert.Null(model.Format); + Assert.False(model.RawData.ContainsKey("format")); + } + + [Fact] + public void OptionalNullablePropertiesUnsetValidation_Works() + { + var model = new OutputConfig { }; + + model.Validate(); + } + + [Fact] + public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() + { + var model = new OutputConfig { Format = null }; + + Assert.Null(model.Format); + Assert.True(model.RawData.ContainsKey("format")); + } + + [Fact] + public void OptionalNullablePropertiesSetToNullValidation_Works() + { + var model = new OutputConfig { Format = null }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new OutputConfig + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }; + + OutputConfig copied = new(model); + + Assert.Equal(model, copied); + } +} diff --git a/src/Anthropic.Tests/Models/Messages/ToolBash20250124Test.cs b/src/Anthropic.Tests/Models/Messages/ToolBash20250124Test.cs index 803d2fc36..c9afec36e 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolBash20250124Test.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolBash20250124Test.cs @@ -9,21 +9,31 @@ public class ToolBash20250124Test : TestBase [Fact] public void FieldRoundtrip_Works() { - var model = new ToolBash20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolBash20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; JsonElement expectedName = JsonSerializer.SerializeToElement("bash"); JsonElement expectedType = JsonSerializer.SerializeToElement("bash_20250124"); CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; + bool expectedStrict = true; Assert.True(JsonElement.DeepEquals(expectedName, model.Name)); Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); Assert.Equal(expectedCacheControl, model.CacheControl); + Assert.Equal(expectedStrict, model.Strict); } [Fact] public void SerializationRoundtrip_Works() { - var model = new ToolBash20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolBash20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -37,7 +47,11 @@ public void SerializationRoundtrip_Works() [Fact] public void FieldRoundtripThroughSerialization_Works() { - var model = new ToolBash20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolBash20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -49,24 +63,76 @@ public void FieldRoundtripThroughSerialization_Works() JsonElement expectedName = JsonSerializer.SerializeToElement("bash"); JsonElement expectedType = JsonSerializer.SerializeToElement("bash_20250124"); CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; + bool expectedStrict = true; Assert.True(JsonElement.DeepEquals(expectedName, deserialized.Name)); Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); Assert.Equal(expectedCacheControl, deserialized.CacheControl); + Assert.Equal(expectedStrict, deserialized.Strict); } [Fact] public void Validation_Works() + { + var model = new ToolBash20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; + + model.Validate(); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() + { + var model = new ToolBash20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetValidation_Works() { var model = new ToolBash20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; model.Validate(); } + [Fact] + public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() + { + var model = new ToolBash20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + + // Null should be interpreted as omitted for these properties + Strict = null, + }; + + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); + } + + [Fact] + public void OptionalNonNullablePropertiesSetToNullValidation_Works() + { + var model = new ToolBash20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + + // Null should be interpreted as omitted for these properties + Strict = null, + }; + + model.Validate(); + } + [Fact] public void OptionalNullablePropertiesUnsetAreNotSet_Works() { - var model = new ToolBash20250124 { }; + var model = new ToolBash20250124 { Strict = true }; Assert.Null(model.CacheControl); Assert.False(model.RawData.ContainsKey("cache_control")); @@ -75,7 +141,7 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() [Fact] public void OptionalNullablePropertiesUnsetValidation_Works() { - var model = new ToolBash20250124 { }; + var model = new ToolBash20250124 { Strict = true }; model.Validate(); } @@ -83,7 +149,12 @@ public void OptionalNullablePropertiesUnsetValidation_Works() [Fact] public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() { - var model = new ToolBash20250124 { CacheControl = null }; + var model = new ToolBash20250124 + { + Strict = true, + + CacheControl = null, + }; Assert.Null(model.CacheControl); Assert.True(model.RawData.ContainsKey("cache_control")); @@ -92,7 +163,12 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() [Fact] public void OptionalNullablePropertiesSetToNullValidation_Works() { - var model = new ToolBash20250124 { CacheControl = null }; + var model = new ToolBash20250124 + { + Strict = true, + + CacheControl = null, + }; model.Validate(); } @@ -100,7 +176,11 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() [Fact] public void CopyConstructor_Works() { - var model = new ToolBash20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolBash20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; ToolBash20250124 copied = new(model); diff --git a/src/Anthropic.Tests/Models/Messages/ToolTest.cs b/src/Anthropic.Tests/Models/Messages/ToolTest.cs index 407d0e317..f48303ff8 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolTest.cs @@ -25,6 +25,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Type.Custom, }; @@ -40,12 +41,14 @@ public void FieldRoundtrip_Works() string expectedName = "name"; CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; string expectedDescription = "Get the current weather in a given location"; + bool expectedStrict = true; ApiEnum expectedType = Type.Custom; Assert.Equal(expectedInputSchema, model.InputSchema); Assert.Equal(expectedName, model.Name); Assert.Equal(expectedCacheControl, model.CacheControl); Assert.Equal(expectedDescription, model.Description); + Assert.Equal(expectedStrict, model.Strict); Assert.Equal(expectedType, model.Type); } @@ -66,6 +69,7 @@ public void SerializationRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Type.Custom, }; @@ -92,6 +96,7 @@ public void FieldRoundtripThroughSerialization_Works() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Type.Custom, }; @@ -111,12 +116,14 @@ public void FieldRoundtripThroughSerialization_Works() string expectedName = "name"; CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; string expectedDescription = "Get the current weather in a given location"; + bool expectedStrict = true; ApiEnum expectedType = Type.Custom; Assert.Equal(expectedInputSchema, deserialized.InputSchema); Assert.Equal(expectedName, deserialized.Name); Assert.Equal(expectedCacheControl, deserialized.CacheControl); Assert.Equal(expectedDescription, deserialized.Description); + Assert.Equal(expectedStrict, deserialized.Strict); Assert.Equal(expectedType, deserialized.Type); } @@ -137,6 +144,7 @@ public void Validation_Works() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Type.Custom, }; @@ -164,6 +172,8 @@ public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() Assert.Null(model.Description); Assert.False(model.RawData.ContainsKey("description")); + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); } [Fact] @@ -208,10 +218,13 @@ public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() // Null should be interpreted as omitted for these properties Description = null, + Strict = null, }; Assert.Null(model.Description); Assert.False(model.RawData.ContainsKey("description")); + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); } [Fact] @@ -234,6 +247,7 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() // Null should be interpreted as omitted for these properties Description = null, + Strict = null, }; model.Validate(); @@ -255,6 +269,7 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() }, Name = "name", Description = "Get the current weather in a given location", + Strict = true, }; Assert.Null(model.CacheControl); @@ -279,6 +294,7 @@ public void OptionalNullablePropertiesUnsetValidation_Works() }, Name = "name", Description = "Get the current weather in a given location", + Strict = true, }; model.Validate(); @@ -300,6 +316,7 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() }, Name = "name", Description = "Get the current weather in a given location", + Strict = true, CacheControl = null, Type = null, @@ -327,6 +344,7 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() }, Name = "name", Description = "Get the current weather in a given location", + Strict = true, CacheControl = null, Type = null, @@ -352,6 +370,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Type.Custom, }; diff --git a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250124Test.cs b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250124Test.cs index c74a4f224..cf811412e 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250124Test.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250124Test.cs @@ -9,21 +9,31 @@ public class ToolTextEditor20250124Test : TestBase [Fact] public void FieldRoundtrip_Works() { - var model = new ToolTextEditor20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolTextEditor20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; JsonElement expectedName = JsonSerializer.SerializeToElement("str_replace_editor"); JsonElement expectedType = JsonSerializer.SerializeToElement("text_editor_20250124"); CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; + bool expectedStrict = true; Assert.True(JsonElement.DeepEquals(expectedName, model.Name)); Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); Assert.Equal(expectedCacheControl, model.CacheControl); + Assert.Equal(expectedStrict, model.Strict); } [Fact] public void SerializationRoundtrip_Works() { - var model = new ToolTextEditor20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolTextEditor20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -37,7 +47,11 @@ public void SerializationRoundtrip_Works() [Fact] public void FieldRoundtripThroughSerialization_Works() { - var model = new ToolTextEditor20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolTextEditor20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -49,24 +63,76 @@ public void FieldRoundtripThroughSerialization_Works() JsonElement expectedName = JsonSerializer.SerializeToElement("str_replace_editor"); JsonElement expectedType = JsonSerializer.SerializeToElement("text_editor_20250124"); CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; + bool expectedStrict = true; Assert.True(JsonElement.DeepEquals(expectedName, deserialized.Name)); Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); Assert.Equal(expectedCacheControl, deserialized.CacheControl); + Assert.Equal(expectedStrict, deserialized.Strict); } [Fact] public void Validation_Works() + { + var model = new ToolTextEditor20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; + + model.Validate(); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() + { + var model = new ToolTextEditor20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetValidation_Works() { var model = new ToolTextEditor20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; model.Validate(); } + [Fact] + public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() + { + var model = new ToolTextEditor20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + + // Null should be interpreted as omitted for these properties + Strict = null, + }; + + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); + } + + [Fact] + public void OptionalNonNullablePropertiesSetToNullValidation_Works() + { + var model = new ToolTextEditor20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + + // Null should be interpreted as omitted for these properties + Strict = null, + }; + + model.Validate(); + } + [Fact] public void OptionalNullablePropertiesUnsetAreNotSet_Works() { - var model = new ToolTextEditor20250124 { }; + var model = new ToolTextEditor20250124 { Strict = true }; Assert.Null(model.CacheControl); Assert.False(model.RawData.ContainsKey("cache_control")); @@ -75,7 +141,7 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() [Fact] public void OptionalNullablePropertiesUnsetValidation_Works() { - var model = new ToolTextEditor20250124 { }; + var model = new ToolTextEditor20250124 { Strict = true }; model.Validate(); } @@ -83,7 +149,12 @@ public void OptionalNullablePropertiesUnsetValidation_Works() [Fact] public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() { - var model = new ToolTextEditor20250124 { CacheControl = null }; + var model = new ToolTextEditor20250124 + { + Strict = true, + + CacheControl = null, + }; Assert.Null(model.CacheControl); Assert.True(model.RawData.ContainsKey("cache_control")); @@ -92,7 +163,12 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() [Fact] public void OptionalNullablePropertiesSetToNullValidation_Works() { - var model = new ToolTextEditor20250124 { CacheControl = null }; + var model = new ToolTextEditor20250124 + { + Strict = true, + + CacheControl = null, + }; model.Validate(); } @@ -100,7 +176,11 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() [Fact] public void CopyConstructor_Works() { - var model = new ToolTextEditor20250124 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolTextEditor20250124 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; ToolTextEditor20250124 copied = new(model); diff --git a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250429Test.cs b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250429Test.cs index e3d62512a..0d013fa86 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250429Test.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250429Test.cs @@ -9,21 +9,31 @@ public class ToolTextEditor20250429Test : TestBase [Fact] public void FieldRoundtrip_Works() { - var model = new ToolTextEditor20250429 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolTextEditor20250429 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; JsonElement expectedName = JsonSerializer.SerializeToElement("str_replace_based_edit_tool"); JsonElement expectedType = JsonSerializer.SerializeToElement("text_editor_20250429"); CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; + bool expectedStrict = true; Assert.True(JsonElement.DeepEquals(expectedName, model.Name)); Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); Assert.Equal(expectedCacheControl, model.CacheControl); + Assert.Equal(expectedStrict, model.Strict); } [Fact] public void SerializationRoundtrip_Works() { - var model = new ToolTextEditor20250429 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolTextEditor20250429 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -37,7 +47,11 @@ public void SerializationRoundtrip_Works() [Fact] public void FieldRoundtripThroughSerialization_Works() { - var model = new ToolTextEditor20250429 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolTextEditor20250429 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -49,24 +63,76 @@ public void FieldRoundtripThroughSerialization_Works() JsonElement expectedName = JsonSerializer.SerializeToElement("str_replace_based_edit_tool"); JsonElement expectedType = JsonSerializer.SerializeToElement("text_editor_20250429"); CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; + bool expectedStrict = true; Assert.True(JsonElement.DeepEquals(expectedName, deserialized.Name)); Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); Assert.Equal(expectedCacheControl, deserialized.CacheControl); + Assert.Equal(expectedStrict, deserialized.Strict); } [Fact] public void Validation_Works() + { + var model = new ToolTextEditor20250429 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; + + model.Validate(); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() + { + var model = new ToolTextEditor20250429 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetValidation_Works() { var model = new ToolTextEditor20250429 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; model.Validate(); } + [Fact] + public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() + { + var model = new ToolTextEditor20250429 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + + // Null should be interpreted as omitted for these properties + Strict = null, + }; + + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); + } + + [Fact] + public void OptionalNonNullablePropertiesSetToNullValidation_Works() + { + var model = new ToolTextEditor20250429 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + + // Null should be interpreted as omitted for these properties + Strict = null, + }; + + model.Validate(); + } + [Fact] public void OptionalNullablePropertiesUnsetAreNotSet_Works() { - var model = new ToolTextEditor20250429 { }; + var model = new ToolTextEditor20250429 { Strict = true }; Assert.Null(model.CacheControl); Assert.False(model.RawData.ContainsKey("cache_control")); @@ -75,7 +141,7 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() [Fact] public void OptionalNullablePropertiesUnsetValidation_Works() { - var model = new ToolTextEditor20250429 { }; + var model = new ToolTextEditor20250429 { Strict = true }; model.Validate(); } @@ -83,7 +149,12 @@ public void OptionalNullablePropertiesUnsetValidation_Works() [Fact] public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() { - var model = new ToolTextEditor20250429 { CacheControl = null }; + var model = new ToolTextEditor20250429 + { + Strict = true, + + CacheControl = null, + }; Assert.Null(model.CacheControl); Assert.True(model.RawData.ContainsKey("cache_control")); @@ -92,7 +163,12 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() [Fact] public void OptionalNullablePropertiesSetToNullValidation_Works() { - var model = new ToolTextEditor20250429 { CacheControl = null }; + var model = new ToolTextEditor20250429 + { + Strict = true, + + CacheControl = null, + }; model.Validate(); } @@ -100,7 +176,11 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() [Fact] public void CopyConstructor_Works() { - var model = new ToolTextEditor20250429 { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + var model = new ToolTextEditor20250429 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; ToolTextEditor20250429 copied = new(model); diff --git a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250728Test.cs b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250728Test.cs index 2f9745510..c0afc6bfc 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250728Test.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolTextEditor20250728Test.cs @@ -13,17 +13,20 @@ public void FieldRoundtrip_Works() { CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxCharacters = 1, + Strict = true, }; JsonElement expectedName = JsonSerializer.SerializeToElement("str_replace_based_edit_tool"); JsonElement expectedType = JsonSerializer.SerializeToElement("text_editor_20250728"); CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; long expectedMaxCharacters = 1; + bool expectedStrict = true; Assert.True(JsonElement.DeepEquals(expectedName, model.Name)); Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); Assert.Equal(expectedCacheControl, model.CacheControl); Assert.Equal(expectedMaxCharacters, model.MaxCharacters); + Assert.Equal(expectedStrict, model.Strict); } [Fact] @@ -33,6 +36,7 @@ public void SerializationRoundtrip_Works() { CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxCharacters = 1, + Strict = true, }; string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); @@ -51,6 +55,7 @@ public void FieldRoundtripThroughSerialization_Works() { CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxCharacters = 1, + Strict = true, }; string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); @@ -64,11 +69,13 @@ public void FieldRoundtripThroughSerialization_Works() JsonElement expectedType = JsonSerializer.SerializeToElement("text_editor_20250728"); CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; long expectedMaxCharacters = 1; + bool expectedStrict = true; Assert.True(JsonElement.DeepEquals(expectedName, deserialized.Name)); Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); Assert.Equal(expectedCacheControl, deserialized.CacheControl); Assert.Equal(expectedMaxCharacters, deserialized.MaxCharacters); + Assert.Equal(expectedStrict, deserialized.Strict); } [Fact] @@ -78,6 +85,63 @@ public void Validation_Works() { CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxCharacters = 1, + Strict = true, + }; + + model.Validate(); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() + { + var model = new ToolTextEditor20250728 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + MaxCharacters = 1, + }; + + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetValidation_Works() + { + var model = new ToolTextEditor20250728 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + MaxCharacters = 1, + }; + + model.Validate(); + } + + [Fact] + public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() + { + var model = new ToolTextEditor20250728 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + MaxCharacters = 1, + + // Null should be interpreted as omitted for these properties + Strict = null, + }; + + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); + } + + [Fact] + public void OptionalNonNullablePropertiesSetToNullValidation_Works() + { + var model = new ToolTextEditor20250728 + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + MaxCharacters = 1, + + // Null should be interpreted as omitted for these properties + Strict = null, }; model.Validate(); @@ -86,7 +150,7 @@ public void Validation_Works() [Fact] public void OptionalNullablePropertiesUnsetAreNotSet_Works() { - var model = new ToolTextEditor20250728 { }; + var model = new ToolTextEditor20250728 { Strict = true }; Assert.Null(model.CacheControl); Assert.False(model.RawData.ContainsKey("cache_control")); @@ -97,7 +161,7 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() [Fact] public void OptionalNullablePropertiesUnsetValidation_Works() { - var model = new ToolTextEditor20250728 { }; + var model = new ToolTextEditor20250728 { Strict = true }; model.Validate(); } @@ -105,7 +169,13 @@ public void OptionalNullablePropertiesUnsetValidation_Works() [Fact] public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() { - var model = new ToolTextEditor20250728 { CacheControl = null, MaxCharacters = null }; + var model = new ToolTextEditor20250728 + { + Strict = true, + + CacheControl = null, + MaxCharacters = null, + }; Assert.Null(model.CacheControl); Assert.True(model.RawData.ContainsKey("cache_control")); @@ -116,7 +186,13 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() [Fact] public void OptionalNullablePropertiesSetToNullValidation_Works() { - var model = new ToolTextEditor20250728 { CacheControl = null, MaxCharacters = null }; + var model = new ToolTextEditor20250728 + { + Strict = true, + + CacheControl = null, + MaxCharacters = null, + }; model.Validate(); } @@ -128,6 +204,7 @@ public void CopyConstructor_Works() { CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxCharacters = 1, + Strict = true, }; ToolTextEditor20250728 copied = new(model); diff --git a/src/Anthropic.Tests/Models/Messages/ToolUnionTest.cs b/src/Anthropic.Tests/Models/Messages/ToolUnionTest.cs index 1da778381..4e1ac88f0 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolUnionTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolUnionTest.cs @@ -24,6 +24,7 @@ public void ToolValidationWorks() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Type.Custom, }; value.Validate(); @@ -32,21 +33,33 @@ public void ToolValidationWorks() [Fact] public void Bash20250124ValidationWorks() { - ToolUnion value = new ToolBash20250124() { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + ToolUnion value = new ToolBash20250124() + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; value.Validate(); } [Fact] public void TextEditor20250124ValidationWorks() { - ToolUnion value = new ToolTextEditor20250124() { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + ToolUnion value = new ToolTextEditor20250124() + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; value.Validate(); } [Fact] public void TextEditor20250429ValidationWorks() { - ToolUnion value = new ToolTextEditor20250429() { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + ToolUnion value = new ToolTextEditor20250429() + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; value.Validate(); } @@ -57,6 +70,7 @@ public void TextEditor20250728ValidationWorks() { CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxCharacters = 1, + Strict = true, }; value.Validate(); } @@ -70,6 +84,7 @@ public void WebSearchTool20250305ValidationWorks() BlockedDomains = ["string"], CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxUses = 1, + Strict = true, UserLocation = new() { City = "New York", @@ -98,6 +113,7 @@ public void ToolSerializationRoundtripWorks() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + Strict = true, Type = Type.Custom, }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); @@ -112,7 +128,11 @@ public void ToolSerializationRoundtripWorks() [Fact] public void Bash20250124SerializationRoundtripWorks() { - ToolUnion value = new ToolBash20250124() { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + ToolUnion value = new ToolBash20250124() + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( element, @@ -125,7 +145,11 @@ public void Bash20250124SerializationRoundtripWorks() [Fact] public void TextEditor20250124SerializationRoundtripWorks() { - ToolUnion value = new ToolTextEditor20250124() { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + ToolUnion value = new ToolTextEditor20250124() + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( element, @@ -138,7 +162,11 @@ public void TextEditor20250124SerializationRoundtripWorks() [Fact] public void TextEditor20250429SerializationRoundtripWorks() { - ToolUnion value = new ToolTextEditor20250429() { CacheControl = new() { Ttl = Ttl.Ttl5m } }; + ToolUnion value = new ToolTextEditor20250429() + { + CacheControl = new() { Ttl = Ttl.Ttl5m }, + Strict = true, + }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( element, @@ -155,6 +183,7 @@ public void TextEditor20250728SerializationRoundtripWorks() { CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxCharacters = 1, + Strict = true, }; string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -174,6 +203,7 @@ public void WebSearchTool20250305SerializationRoundtripWorks() BlockedDomains = ["string"], CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxUses = 1, + Strict = true, UserLocation = new() { City = "New York", diff --git a/src/Anthropic.Tests/Models/Messages/WebSearchTool20250305Test.cs b/src/Anthropic.Tests/Models/Messages/WebSearchTool20250305Test.cs index eadca1851..972f6aaed 100644 --- a/src/Anthropic.Tests/Models/Messages/WebSearchTool20250305Test.cs +++ b/src/Anthropic.Tests/Models/Messages/WebSearchTool20250305Test.cs @@ -16,6 +16,7 @@ public void FieldRoundtrip_Works() BlockedDomains = ["string"], CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxUses = 1, + Strict = true, UserLocation = new() { City = "New York", @@ -31,6 +32,7 @@ public void FieldRoundtrip_Works() List expectedBlockedDomains = ["string"]; CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; long expectedMaxUses = 1; + bool expectedStrict = true; UserLocation expectedUserLocation = new() { City = "New York", @@ -55,6 +57,7 @@ public void FieldRoundtrip_Works() } Assert.Equal(expectedCacheControl, model.CacheControl); Assert.Equal(expectedMaxUses, model.MaxUses); + Assert.Equal(expectedStrict, model.Strict); Assert.Equal(expectedUserLocation, model.UserLocation); } @@ -67,6 +70,7 @@ public void SerializationRoundtrip_Works() BlockedDomains = ["string"], CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxUses = 1, + Strict = true, UserLocation = new() { City = "New York", @@ -94,6 +98,7 @@ public void FieldRoundtripThroughSerialization_Works() BlockedDomains = ["string"], CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxUses = 1, + Strict = true, UserLocation = new() { City = "New York", @@ -116,6 +121,7 @@ public void FieldRoundtripThroughSerialization_Works() List expectedBlockedDomains = ["string"]; CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; long expectedMaxUses = 1; + bool expectedStrict = true; UserLocation expectedUserLocation = new() { City = "New York", @@ -140,6 +146,7 @@ public void FieldRoundtripThroughSerialization_Works() } Assert.Equal(expectedCacheControl, deserialized.CacheControl); Assert.Equal(expectedMaxUses, deserialized.MaxUses); + Assert.Equal(expectedStrict, deserialized.Strict); Assert.Equal(expectedUserLocation, deserialized.UserLocation); } @@ -152,6 +159,7 @@ public void Validation_Works() BlockedDomains = ["string"], CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxUses = 1, + Strict = true, UserLocation = new() { City = "New York", @@ -164,10 +172,102 @@ public void Validation_Works() model.Validate(); } + [Fact] + public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() + { + var model = new WebSearchTool20250305 + { + AllowedDomains = ["string"], + BlockedDomains = ["string"], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + MaxUses = 1, + UserLocation = new() + { + City = "New York", + Country = "US", + Region = "California", + Timezone = "America/New_York", + }, + }; + + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetValidation_Works() + { + var model = new WebSearchTool20250305 + { + AllowedDomains = ["string"], + BlockedDomains = ["string"], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + MaxUses = 1, + UserLocation = new() + { + City = "New York", + Country = "US", + Region = "California", + Timezone = "America/New_York", + }, + }; + + model.Validate(); + } + + [Fact] + public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() + { + var model = new WebSearchTool20250305 + { + AllowedDomains = ["string"], + BlockedDomains = ["string"], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + MaxUses = 1, + UserLocation = new() + { + City = "New York", + Country = "US", + Region = "California", + Timezone = "America/New_York", + }, + + // Null should be interpreted as omitted for these properties + Strict = null, + }; + + Assert.Null(model.Strict); + Assert.False(model.RawData.ContainsKey("strict")); + } + + [Fact] + public void OptionalNonNullablePropertiesSetToNullValidation_Works() + { + var model = new WebSearchTool20250305 + { + AllowedDomains = ["string"], + BlockedDomains = ["string"], + CacheControl = new() { Ttl = Ttl.Ttl5m }, + MaxUses = 1, + UserLocation = new() + { + City = "New York", + Country = "US", + Region = "California", + Timezone = "America/New_York", + }, + + // Null should be interpreted as omitted for these properties + Strict = null, + }; + + model.Validate(); + } + [Fact] public void OptionalNullablePropertiesUnsetAreNotSet_Works() { - var model = new WebSearchTool20250305 { }; + var model = new WebSearchTool20250305 { Strict = true }; Assert.Null(model.AllowedDomains); Assert.False(model.RawData.ContainsKey("allowed_domains")); @@ -184,7 +284,7 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() [Fact] public void OptionalNullablePropertiesUnsetValidation_Works() { - var model = new WebSearchTool20250305 { }; + var model = new WebSearchTool20250305 { Strict = true }; model.Validate(); } @@ -194,6 +294,8 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() { var model = new WebSearchTool20250305 { + Strict = true, + AllowedDomains = null, BlockedDomains = null, CacheControl = null, @@ -218,6 +320,8 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() { var model = new WebSearchTool20250305 { + Strict = true, + AllowedDomains = null, BlockedDomains = null, CacheControl = null, @@ -237,6 +341,7 @@ public void CopyConstructor_Works() BlockedDomains = ["string"], CacheControl = new() { Ttl = Ttl.Ttl5m }, MaxUses = 1, + Strict = true, UserLocation = new() { City = "New York", diff --git a/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs b/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs index 132f5ec00..fd59c99b3 100644 --- a/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs +++ b/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs @@ -1,156 +1,167 @@ -using System.Collections.Generic; -using System.Text.Json; -using System.Threading.Tasks; -using Anthropic.Models.Messages.Batches; -using Anthropic.Tests; -using Messages = Anthropic.Models.Messages; - -namespace Anthropic.Tests.Services.Messages; - -public class BatchServiceTest -{ - [Theory] - [AnthropicTestClients] - [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] - [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] - public async Task Create_Works(IAnthropicClient client, string modelName) - { - var messageBatch = await client.Messages.Batches.Create( - new() - { - Requests = - [ - new() - { - CustomID = "my-custom-id-1", - Params = new() - { - MaxTokens = 1024, - Messages = - [ - new() { Content = "Hello, world", Role = Messages::Role.User }, - ], - Model = modelName, - Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - ServiceTier = ServiceTier.Auto, - StopSequences = ["string"], - Stream = true, - System = new( - [ - new Messages::TextBlockParam() - { - Text = "Today's date is 2024-06-01.", - CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, - Citations = - [ - new Messages::CitationCharLocationParam() - { - CitedText = "cited_text", - DocumentIndex = 0, - DocumentTitle = "x", - EndCharIndex = 0, - StartCharIndex = 0, - }, - ], - }, - ] - ), - Temperature = 1, - Thinking = new Messages::ThinkingConfigEnabled(1024), - ToolChoice = new Messages::ToolChoiceAuto() - { - DisableParallelToolUse = true, - }, - Tools = - [ - new Messages::Tool() - { - InputSchema = new() - { - Properties = new Dictionary() - { - { - "location", - JsonSerializer.SerializeToElement("bar") - }, - { "unit", JsonSerializer.SerializeToElement("bar") }, - }, - Required = ["location"], - }, - Name = "name", - CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, - Description = "Get the current weather in a given location", - Type = Messages::Type.Custom, - }, - ], - TopK = 5, - TopP = 0.7, - }, - }, - ], - }, - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients] - public async Task Retrieve_Works(IAnthropicClient client) - { - var messageBatch = await client.Messages.Batches.Retrieve( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients] - public async Task List_Works(IAnthropicClient client) - { - var page = await client.Messages.Batches.List(new(), TestContext.Current.CancellationToken); - page.Validate(); - } - - [Theory] - [AnthropicTestClients] - public async Task Delete_Works(IAnthropicClient client) - { - var deletedMessageBatch = await client.Messages.Batches.Delete( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - deletedMessageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients] - public async Task Cancel_Works(IAnthropicClient client) - { - var messageBatch = await client.Messages.Batches.Cancel( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory(Skip = "Prism doesn't support application/x-jsonl responses")] - [AnthropicTestClients] - public async Task ResultsStreaming_Works(IAnthropicClient client) - { - var stream = client.Messages.Batches.ResultsStreaming( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - - await foreach (var messageBatchIndividualResponse in stream) - { - messageBatchIndividualResponse.Validate(); - } - } -} +using System.Collections.Generic; +using System.Text.Json; +using System.Threading.Tasks; +using Anthropic.Models.Messages.Batches; +using Anthropic.Tests; +using Messages = Anthropic.Models.Messages; + +namespace Anthropic.Tests.Services.Messages; + +public class BatchServiceTest +{ + [Theory] + [AnthropicTestClients] + [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] + [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + public async Task Create_Works(IAnthropicClient client, string modelName) + { + var messageBatch = await client.Messages.Batches.Create( + new() + { + Requests = + [ + new() + { + CustomID = "my-custom-id-1", + Params = new() + { + MaxTokens = 1024, + Messages = + [ + new() { Content = "Hello, world", Role = Messages::Role.User }, + ], + Model = modelName, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() + { + DisableParallelToolUse = true, + }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { + "location", + JsonSerializer.SerializeToElement("bar") + }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + Strict = true, + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }, + }, + ], + }, + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients] + public async Task Retrieve_Works(IAnthropicClient client) + { + var messageBatch = await client.Messages.Batches.Retrieve( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients] + public async Task List_Works(IAnthropicClient client) + { + var page = await client.Messages.Batches.List(new(), TestContext.Current.CancellationToken); + page.Validate(); + } + + [Theory] + [AnthropicTestClients] + public async Task Delete_Works(IAnthropicClient client) + { + var deletedMessageBatch = await client.Messages.Batches.Delete( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + deletedMessageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients] + public async Task Cancel_Works(IAnthropicClient client) + { + var messageBatch = await client.Messages.Batches.Cancel( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory(Skip = "Prism doesn't support application/x-jsonl responses")] + [AnthropicTestClients] + public async Task ResultsStreaming_Works(IAnthropicClient client) + { + var stream = client.Messages.Batches.ResultsStreaming( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + + await foreach (var messageBatchIndividualResponse in stream) + { + messageBatchIndividualResponse.Validate(); + } + } +} diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs index d859b2c7c..1d4ad1571 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs @@ -453,8 +453,7 @@ public BetaMetadata? Metadata } /// - /// Configuration options for the model's output. Controls aspects like output - /// format or how much effort the model puts into its response. + /// Configuration options for the model's output, such as the output format. /// public BetaOutputConfig? OutputConfig { diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250522.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250522.cs index 084656ff4..94ac3965a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250522.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250522.cs @@ -98,6 +98,9 @@ public bool? DeferLoading } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250825.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250825.cs index 0ca6103ea..95fdca49d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250825.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionTool20250825.cs @@ -99,6 +99,9 @@ public bool? DeferLoading } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818.cs b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818.cs index b7e5f5ea2..9c98fe07d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818.cs @@ -126,6 +126,9 @@ public IReadOnlyList>? InputExamples } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs b/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs index 89bbc8dc8..ecf02a5a7 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs @@ -13,7 +13,10 @@ namespace Anthropic.Models.Beta.Messages; public sealed record class BetaOutputConfig : JsonModel { /// - /// All possible effort levels. + /// How much effort the model should put into its response. Higher effort levels + /// may result in more thorough analysis but take longer. + /// + /// Valid values are `low`, `medium`, or `high`. /// public ApiEnum? Effort { @@ -26,8 +29,7 @@ public ApiEnum? Effort } /// - /// A schema to specify Claude's output format in responses. See [structured - /// outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + /// A schema to specify Claude's output format in responses. See [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) /// public BetaJsonOutputFormat? Format { @@ -84,7 +86,10 @@ public BetaOutputConfig FromRawUnchecked(IReadOnlyDictionary -/// All possible effort levels. +/// How much effort the model should put into its response. Higher effort levels may +/// result in more thorough analysis but take longer. +/// +/// Valid values are `low`, `medium`, or `high`. /// [JsonConverter(typeof(EffortConverter))] public enum Effort diff --git a/src/Anthropic/Models/Beta/Messages/BetaTool.cs b/src/Anthropic/Models/Beta/Messages/BetaTool.cs index a43ce5d16..306c8a518 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTool.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTool.cs @@ -159,6 +159,9 @@ public IReadOnlyList>? InputExamples } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolBash20241022.cs b/src/Anthropic/Models/Beta/Messages/BetaToolBash20241022.cs index 63d1b2bac..9a7025127 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolBash20241022.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolBash20241022.cs @@ -127,6 +127,9 @@ public IReadOnlyList>? InputExamples } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolBash20250124.cs b/src/Anthropic/Models/Beta/Messages/BetaToolBash20250124.cs index 4590d653f..77d405d22 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolBash20250124.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolBash20250124.cs @@ -127,6 +127,9 @@ public IReadOnlyList>? InputExamples } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20241022.cs b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20241022.cs index d1b097236..00ca12cfd 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20241022.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20241022.cs @@ -167,6 +167,9 @@ public IReadOnlyList>? InputExamples } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20250124.cs b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20250124.cs index 80713407f..1aee3622e 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20250124.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20250124.cs @@ -167,6 +167,9 @@ public IReadOnlyList>? InputExamples } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20251124.cs b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20251124.cs index f4d7eaff5..873938f99 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20251124.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolComputerUse20251124.cs @@ -188,6 +188,9 @@ public IReadOnlyList>? InputExamples } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolBm25_20251119.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolBm25_20251119.cs index fae3dc3cc..d457f51e7 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolBm25_20251119.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolBm25_20251119.cs @@ -104,6 +104,9 @@ public bool? DeferLoading } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolRegex20251119.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolRegex20251119.cs index cef63a353..05413957a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolRegex20251119.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolRegex20251119.cs @@ -104,6 +104,9 @@ public bool? DeferLoading } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20241022.cs b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20241022.cs index d985480b1..94e8a324e 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20241022.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20241022.cs @@ -128,6 +128,9 @@ public IReadOnlyList>? InputExamples } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250124.cs b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250124.cs index 25d1c127a..913505a5b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250124.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250124.cs @@ -128,6 +128,9 @@ public IReadOnlyList>? InputExamples } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250429.cs b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250429.cs index 9e05b75fa..902e70059 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250429.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250429.cs @@ -128,6 +128,9 @@ public IReadOnlyList>? InputExamples } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250728.cs b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250728.cs index 90df6396d..16ce63d56 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250728.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolTextEditor20250728.cs @@ -142,6 +142,9 @@ public long? MaxCharacters init { this._rawData.Set("max_characters", value); } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebFetchTool20250910.cs b/src/Anthropic/Models/Beta/Messages/BetaWebFetchTool20250910.cs index 58ea64050..36bb63308 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebFetchTool20250910.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebFetchTool20250910.cs @@ -175,6 +175,9 @@ public long? MaxUses init { this._rawData.Set("max_uses", value); } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchTool20250305.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchTool20250305.cs index 79c6c5089..f785b5367 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchTool20250305.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchTool20250305.cs @@ -149,6 +149,9 @@ public long? MaxUses init { this._rawData.Set("max_uses", value); } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// public bool? Strict { get diff --git a/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs b/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs index f45fbeef4..25f935b49 100644 --- a/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs +++ b/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs @@ -159,8 +159,7 @@ public IReadOnlyList? McpServers } /// - /// Configuration options for the model's output. Controls aspects like output - /// format or how much effort the model puts into its response. + /// Configuration options for the model's output, such as the output format. /// public BetaOutputConfig? OutputConfig { diff --git a/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs b/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs index 7529e94b9..035ea81a6 100644 --- a/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs @@ -212,8 +212,7 @@ public BetaMetadata? Metadata } /// - /// Configuration options for the model's output. Controls aspects like output - /// format or how much effort the model puts into its response. + /// Configuration options for the model's output, such as the output format. /// public BetaOutputConfig? OutputConfig { diff --git a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs index bb208d796..6fc0d0532 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs @@ -366,6 +366,27 @@ public Metadata? Metadata } } + /// + /// Configuration options for the model's output, such as the output format. + /// + public OutputConfig? OutputConfig + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("output_config"); + } + init + { + if (value == null) + { + return; + } + + this._rawData.Set("output_config", value); + } + } + /// /// Determines whether to use priority capacity (if available) or standard capacity /// for this request. @@ -682,6 +703,7 @@ public override void Validate() } this.Model.Validate(); this.Metadata?.Validate(); + this.OutputConfig?.Validate(); this.ServiceTier?.Validate(); _ = this.StopSequences; _ = this.Stream; diff --git a/src/Anthropic/Models/Messages/JsonOutputFormat.cs b/src/Anthropic/Models/Messages/JsonOutputFormat.cs new file mode 100644 index 000000000..b96b119ec --- /dev/null +++ b/src/Anthropic/Models/Messages/JsonOutputFormat.cs @@ -0,0 +1,93 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Models.Messages; + +[JsonConverter(typeof(JsonModelConverter))] +public sealed record class JsonOutputFormat : JsonModel +{ + /// + /// The JSON schema of the format + /// + public required IReadOnlyDictionary Schema + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullClass>("schema"); + } + init + { + this._rawData.Set>( + "schema", + FrozenDictionary.ToFrozenDictionary(value) + ); + } + } + + public JsonElement Type + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("type"); + } + init { this._rawData.Set("type", value); } + } + + /// + public override void Validate() + { + _ = this.Schema; + if (!JsonElement.DeepEquals(this.Type, JsonSerializer.SerializeToElement("json_schema"))) + { + throw new AnthropicInvalidDataException("Invalid value given for constant"); + } + } + + public JsonOutputFormat() + { + this.Type = JsonSerializer.SerializeToElement("json_schema"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + public JsonOutputFormat(JsonOutputFormat jsonOutputFormat) + : base(jsonOutputFormat) { } +#pragma warning restore CS8618 + + public JsonOutputFormat(IReadOnlyDictionary rawData) + { + this._rawData = new(rawData); + + this.Type = JsonSerializer.SerializeToElement("json_schema"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + JsonOutputFormat(FrozenDictionary rawData) + { + this._rawData = new(rawData); + } +#pragma warning restore CS8618 + + /// + public static JsonOutputFormat FromRawUnchecked( + IReadOnlyDictionary rawData + ) + { + return new(FrozenDictionary.ToFrozenDictionary(rawData)); + } +} + +class JsonOutputFormatFromRaw : IFromRawJson +{ + /// + public JsonOutputFormat FromRawUnchecked(IReadOnlyDictionary rawData) => + JsonOutputFormat.FromRawUnchecked(rawData); +} diff --git a/src/Anthropic/Models/Messages/MessageCountTokensParams.cs b/src/Anthropic/Models/Messages/MessageCountTokensParams.cs index 0edf1ec5e..d2786ab62 100644 --- a/src/Anthropic/Models/Messages/MessageCountTokensParams.cs +++ b/src/Anthropic/Models/Messages/MessageCountTokensParams.cs @@ -113,6 +113,27 @@ public required ApiEnum Model init { this._rawBodyData.Set("model", value); } } + /// + /// Configuration options for the model's output, such as the output format. + /// + public OutputConfig? OutputConfig + { + get + { + this._rawBodyData.Freeze(); + return this._rawBodyData.GetNullableClass("output_config"); + } + init + { + if (value == null) + { + return; + } + + this._rawBodyData.Set("output_config", value); + } + } + /// /// System prompt. /// diff --git a/src/Anthropic/Models/Messages/MessageCountTokensTool.cs b/src/Anthropic/Models/Messages/MessageCountTokensTool.cs index 9a1bd69a3..5153bf77a 100644 --- a/src/Anthropic/Models/Messages/MessageCountTokensTool.cs +++ b/src/Anthropic/Models/Messages/MessageCountTokensTool.cs @@ -40,6 +40,21 @@ public CacheControlEphemeral? CacheControl } } + public bool? Strict + { + get + { + return Match( + tool: (x) => x.Strict, + toolBash20250124: (x) => x.Strict, + toolTextEditor20250124: (x) => x.Strict, + toolTextEditor20250429: (x) => x.Strict, + toolTextEditor20250728: (x) => x.Strict, + webSearchTool20250305: (x) => x.Strict + ); + } + } + public MessageCountTokensTool(Tool value, JsonElement? element = null) { this.Value = value; diff --git a/src/Anthropic/Models/Messages/MessageCreateParams.cs b/src/Anthropic/Models/Messages/MessageCreateParams.cs index bb2e34dba..7340235c7 100644 --- a/src/Anthropic/Models/Messages/MessageCreateParams.cs +++ b/src/Anthropic/Models/Messages/MessageCreateParams.cs @@ -153,6 +153,27 @@ public Metadata? Metadata } } + /// + /// Configuration options for the model's output, such as the output format. + /// + public OutputConfig? OutputConfig + { + get + { + this._rawBodyData.Freeze(); + return this._rawBodyData.GetNullableClass("output_config"); + } + init + { + if (value == null) + { + return; + } + + this._rawBodyData.Set("output_config", value); + } + } + /// /// Determines whether to use priority capacity (if available) or standard capacity /// for this request. diff --git a/src/Anthropic/Models/Messages/OutputConfig.cs b/src/Anthropic/Models/Messages/OutputConfig.cs new file mode 100644 index 000000000..18aa4a66c --- /dev/null +++ b/src/Anthropic/Models/Messages/OutputConfig.cs @@ -0,0 +1,65 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; + +namespace Anthropic.Models.Messages; + +[JsonConverter(typeof(JsonModelConverter))] +public sealed record class OutputConfig : JsonModel +{ + /// + /// A schema to specify Claude's output format in responses. See [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) + /// + public JsonOutputFormat? Format + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("format"); + } + init { this._rawData.Set("format", value); } + } + + /// + public override void Validate() + { + this.Format?.Validate(); + } + + public OutputConfig() { } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + public OutputConfig(OutputConfig outputConfig) + : base(outputConfig) { } +#pragma warning restore CS8618 + + public OutputConfig(IReadOnlyDictionary rawData) + { + this._rawData = new(rawData); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + OutputConfig(FrozenDictionary rawData) + { + this._rawData = new(rawData); + } +#pragma warning restore CS8618 + + /// + public static OutputConfig FromRawUnchecked(IReadOnlyDictionary rawData) + { + return new(FrozenDictionary.ToFrozenDictionary(rawData)); + } +} + +class OutputConfigFromRaw : IFromRawJson +{ + /// + public OutputConfig FromRawUnchecked(IReadOnlyDictionary rawData) => + OutputConfig.FromRawUnchecked(rawData); +} diff --git a/src/Anthropic/Models/Messages/Tool.cs b/src/Anthropic/Models/Messages/Tool.cs index e6fb70f8b..38f9ab905 100644 --- a/src/Anthropic/Models/Messages/Tool.cs +++ b/src/Anthropic/Models/Messages/Tool.cs @@ -83,6 +83,27 @@ public string? Description } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// + public bool? Strict + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct("strict"); + } + init + { + if (value == null) + { + return; + } + + this._rawData.Set("strict", value); + } + } + public ApiEnum? Type { get @@ -102,6 +123,7 @@ public override void Validate() _ = this.Name; this.CacheControl?.Validate(); _ = this.Description; + _ = this.Strict; this.Type?.Validate(); } diff --git a/src/Anthropic/Models/Messages/ToolBash20250124.cs b/src/Anthropic/Models/Messages/ToolBash20250124.cs index 07a6d5602..c27435d60 100644 --- a/src/Anthropic/Models/Messages/ToolBash20250124.cs +++ b/src/Anthropic/Models/Messages/ToolBash20250124.cs @@ -49,6 +49,27 @@ public CacheControlEphemeral? CacheControl init { this._rawData.Set("cache_control", value); } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// + public bool? Strict + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct("strict"); + } + init + { + if (value == null) + { + return; + } + + this._rawData.Set("strict", value); + } + } + /// public override void Validate() { @@ -61,6 +82,7 @@ public override void Validate() throw new AnthropicInvalidDataException("Invalid value given for constant"); } this.CacheControl?.Validate(); + _ = this.Strict; } public ToolBash20250124() diff --git a/src/Anthropic/Models/Messages/ToolTextEditor20250124.cs b/src/Anthropic/Models/Messages/ToolTextEditor20250124.cs index 69ad41726..de5d0a941 100644 --- a/src/Anthropic/Models/Messages/ToolTextEditor20250124.cs +++ b/src/Anthropic/Models/Messages/ToolTextEditor20250124.cs @@ -49,6 +49,27 @@ public CacheControlEphemeral? CacheControl init { this._rawData.Set("cache_control", value); } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// + public bool? Strict + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct("strict"); + } + init + { + if (value == null) + { + return; + } + + this._rawData.Set("strict", value); + } + } + /// public override void Validate() { @@ -71,6 +92,7 @@ public override void Validate() throw new AnthropicInvalidDataException("Invalid value given for constant"); } this.CacheControl?.Validate(); + _ = this.Strict; } public ToolTextEditor20250124() diff --git a/src/Anthropic/Models/Messages/ToolTextEditor20250429.cs b/src/Anthropic/Models/Messages/ToolTextEditor20250429.cs index c34690d2b..8c50523d8 100644 --- a/src/Anthropic/Models/Messages/ToolTextEditor20250429.cs +++ b/src/Anthropic/Models/Messages/ToolTextEditor20250429.cs @@ -49,6 +49,27 @@ public CacheControlEphemeral? CacheControl init { this._rawData.Set("cache_control", value); } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// + public bool? Strict + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct("strict"); + } + init + { + if (value == null) + { + return; + } + + this._rawData.Set("strict", value); + } + } + /// public override void Validate() { @@ -71,6 +92,7 @@ public override void Validate() throw new AnthropicInvalidDataException("Invalid value given for constant"); } this.CacheControl?.Validate(); + _ = this.Strict; } public ToolTextEditor20250429() diff --git a/src/Anthropic/Models/Messages/ToolTextEditor20250728.cs b/src/Anthropic/Models/Messages/ToolTextEditor20250728.cs index cc347102d..72644ee34 100644 --- a/src/Anthropic/Models/Messages/ToolTextEditor20250728.cs +++ b/src/Anthropic/Models/Messages/ToolTextEditor20250728.cs @@ -63,6 +63,27 @@ public long? MaxCharacters init { this._rawData.Set("max_characters", value); } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// + public bool? Strict + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct("strict"); + } + init + { + if (value == null) + { + return; + } + + this._rawData.Set("strict", value); + } + } + /// public override void Validate() { @@ -86,6 +107,7 @@ public override void Validate() } this.CacheControl?.Validate(); _ = this.MaxCharacters; + _ = this.Strict; } public ToolTextEditor20250728() diff --git a/src/Anthropic/Models/Messages/ToolUnion.cs b/src/Anthropic/Models/Messages/ToolUnion.cs index 88b810e53..47f71a892 100644 --- a/src/Anthropic/Models/Messages/ToolUnion.cs +++ b/src/Anthropic/Models/Messages/ToolUnion.cs @@ -40,6 +40,21 @@ public CacheControlEphemeral? CacheControl } } + public bool? Strict + { + get + { + return Match( + tool: (x) => x.Strict, + bash20250124: (x) => x.Strict, + textEditor20250124: (x) => x.Strict, + textEditor20250429: (x) => x.Strict, + textEditor20250728: (x) => x.Strict, + webSearchTool20250305: (x) => x.Strict + ); + } + } + public ToolUnion(Tool value, JsonElement? element = null) { this.Value = value; diff --git a/src/Anthropic/Models/Messages/WebSearchTool20250305.cs b/src/Anthropic/Models/Messages/WebSearchTool20250305.cs index 7b8350baa..bf140e36b 100644 --- a/src/Anthropic/Models/Messages/WebSearchTool20250305.cs +++ b/src/Anthropic/Models/Messages/WebSearchTool20250305.cs @@ -102,6 +102,27 @@ public long? MaxUses init { this._rawData.Set("max_uses", value); } } + /// + /// When true, guarantees schema validation on tool names and inputs + /// + public bool? Strict + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct("strict"); + } + init + { + if (value == null) + { + return; + } + + this._rawData.Set("strict", value); + } + } + /// /// Parameters for the user's location. Used to provide more relevant search results. /// @@ -135,6 +156,7 @@ public override void Validate() _ = this.BlockedDomains; this.CacheControl?.Validate(); _ = this.MaxUses; + _ = this.Strict; this.UserLocation?.Validate(); } From 7cd6228283959922903cff5b5554d44c761217eb Mon Sep 17 00:00:00 2001 From: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> Date: Thu, 29 Jan 2026 17:03:18 +0000 Subject: [PATCH 23/41] Allow MEAI User Agent tracking for IChatClient (#91) * fix: use Properties initializer for InputSchema in IChatClient extensions (#83) * chore(ci): Add Claude Code GitHub Workflow (#273) * "Claude PR Assistant workflow" * "Claude Code Review workflow" * fix: use Properties initializer for InputSchema in IChatClient extensions The InputSchema constructor was being passed properties as rawData, which caused them to be serialized at the top level of the JSON object instead of under a "properties" key. This resulted in invalid JSON Schema that failed Anthropic API validation with error: "tools.0.custom.input_schema: JSON schema is invalid" The fix uses property initializer syntax to correctly populate the Properties property, ensuring the schema is valid JSON Schema draft 2020-12. Also updates tests to expect the corrected schema format. Fixes #82 * Remove added workflows --------- Co-authored-by: dtmeadows * Add MEAI User-Agent for IChatClient implementation * Fix failing UT for new schema properties pattern * Add MEAI user agent + UT for betaservice * Address PR comments * Use FrozenDictionary for MEAI headers and fix User-Agent test assertions * Add missing System.Linq using for ToArray extension method * Fix User-Agent tests to verify single header with multiple values * Fix lint issues: use collection expressions and simplify regex --------- Co-authored-by: Matt Brailsford Co-authored-by: dtmeadows --- .editorconfig | 1 + .../AnthropicClientBetaExtensionsTests.cs | 269 +++++++++++++++++ .../AnthropicClientExtensionsTests.cs | 272 +++++++++++++++++- src/Anthropic/AnthropicClientExtensions.cs | 56 +++- .../Messages/AnthropicBetaClientExtensions.cs | 56 +++- 5 files changed, 651 insertions(+), 3 deletions(-) diff --git a/.editorconfig b/.editorconfig index f36eb4b59..7cc868e7a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -22,6 +22,7 @@ end_of_line = crlf insert_final_newline = true dotnet_diagnostic.CA1510.severity = none # Use ArgumentNullException throw helper +dotnet_diagnostic.IDE0009.severity = none # Add this or Me qualification dotnet_diagnostic.IDE0060.severity = none # Caused by resource with no methods and no subresources dotnet_diagnostic.IDE1006.severity = none # Some names may not match up with C# conventions dotnet_diagnostic.IDE0290.severity = none # Don't prefer primary constructors diff --git a/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs b/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs index 71199e7fe..3fb641f5b 100644 --- a/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs +++ b/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs @@ -2218,4 +2218,273 @@ public async Task GetResponseAsync_WithHostedToolsAndExistingBetas_PreservesAndD Assert.Contains("code-execution-2025-08-25", capturedBetaHeaders); Assert.Contains("mcp-client-2025-11-20", capturedBetaHeaders); } + + [Fact] + public async Task GetResponseAsync_IncludesMeaiUserAgentHeader() + { + string[]? capturedUserAgentValues = null; + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "Test" + }] + }] + } + """, + actualResponse: """ + { + "id": "msg_meai_header_01", + "type": "message", + "role": "assistant", + "model": "claude-haiku-4-5", + "content": [{ + "type": "text", + "text": "Response" + }], + "stop_reason": "end_turn", + "usage": { + "input_tokens": 10, + "output_tokens": 5 + } + } + """ + ) + { + OnRequestHeaders = headers => + { + // Verify there's exactly one User-Agent header entry + Assert.Single(headers, h => h.Key == "User-Agent"); + if (headers.TryGetValues("User-Agent", out var values)) + { + capturedUserAgentValues = [.. values]; + } + }, + }; + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + ChatResponse response = await chatClient.GetResponseAsync( + "Test", + new(), + TestContext.Current.CancellationToken + ); + + Assert.NotNull(response); + Assert.NotNull(capturedUserAgentValues); + Assert.Contains(capturedUserAgentValues, v => v.Contains("MEAI")); + Assert.Contains(capturedUserAgentValues, v => v.Contains("AnthropicClient")); + } + + [Fact] + public async Task GetStreamingResponseAsync_IncludesMeaiUserAgentHeader() + { + string[]? capturedUserAgentValues = null; + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "Test streaming" + }] + }], + "stream": true + } + """, + actualResponse: """ + event: message_start + data: {"type":"message_start","message":{"id":"msg_stream_meai_01","type":"message","role":"assistant","model":"claude-haiku-4-5","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":10,"output_tokens":0}}} + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Response"}} + + event: content_block_stop + data: {"type":"content_block_stop","index":0} + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":5}} + + event: message_stop + data: {"type":"message_stop"} + + """ + ) + { + OnRequestHeaders = headers => + { + // Verify there's exactly one User-Agent header entry + Assert.Single(headers, h => h.Key == "User-Agent"); + if (headers.TryGetValues("User-Agent", out var values)) + { + capturedUserAgentValues = [.. values]; + } + }, + }; + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + await foreach ( + var update in chatClient.GetStreamingResponseAsync( + "Test streaming", + new(), + TestContext.Current.CancellationToken + ) + ) + { + // Consume the stream + } + + Assert.NotNull(capturedUserAgentValues); + Assert.Contains(capturedUserAgentValues, v => v.Contains("MEAI")); + Assert.Contains(capturedUserAgentValues, v => v.Contains("AnthropicClient")); + } + + [Fact] + public async Task GetResponseAsync_MeaiUserAgentHeader_HasCorrectFormat() + { + string[]? capturedUserAgentValues = null; + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "Test" + }] + }] + } + """, + actualResponse: """ + { + "id": "msg_meai_format_01", + "type": "message", + "role": "assistant", + "model": "claude-haiku-4-5", + "content": [{ + "type": "text", + "text": "Response" + }], + "stop_reason": "end_turn", + "usage": { + "input_tokens": 10, + "output_tokens": 5 + } + } + """ + ) + { + OnRequestHeaders = headers => + { + // Verify there's exactly one User-Agent header entry + Assert.Single(headers, h => h.Key == "User-Agent"); + if (headers.TryGetValues("User-Agent", out var values)) + { + capturedUserAgentValues = [.. values]; + } + }, + }; + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + ChatResponse response = await chatClient.GetResponseAsync( + "Test", + new(), + TestContext.Current.CancellationToken + ); + + Assert.NotNull(response); + Assert.NotNull(capturedUserAgentValues); + // Verify the MEAI user-agent is present and has correct format (MEAI or MEAI/version) + Assert.Contains( + capturedUserAgentValues, + v => v.StartsWith("MEAI", StringComparison.Ordinal) + ); + Assert.Contains(capturedUserAgentValues, v => v.Contains("AnthropicClient")); + } + + [Fact] + public async Task GetResponseAsync_MeaiUserAgentHeader_PresentAlongsideDefaultHeaders() + { + bool hasAnthropicVersion = false; + bool hasMeaiUserAgent = false; + bool hasDefaultUserAgent = false; + + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "Test" + }] + }] + } + """, + actualResponse: """ + { + "id": "msg_headers_01", + "type": "message", + "role": "assistant", + "model": "claude-haiku-4-5", + "content": [{ + "type": "text", + "text": "Response" + }], + "stop_reason": "end_turn", + "usage": { + "input_tokens": 10, + "output_tokens": 5 + } + } + """ + ) + { + OnRequestHeaders = headers => + { + // Verify there's exactly one User-Agent header entry + Assert.Single(headers, h => h.Key == "User-Agent"); + hasAnthropicVersion = headers.Contains("anthropic-version"); + if (headers.TryGetValues("User-Agent", out var values)) + { + var valuesArray = values.ToArray(); + hasMeaiUserAgent = valuesArray.Any(v => v.Contains("MEAI")); + hasDefaultUserAgent = valuesArray.Any(v => v.Contains("AnthropicClient")); + } + }, + }; + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + ChatResponse response = await chatClient.GetResponseAsync( + "Test", + new(), + TestContext.Current.CancellationToken + ); + + Assert.NotNull(response); + Assert.True(hasAnthropicVersion, "anthropic-version header should be present"); + Assert.True(hasMeaiUserAgent, "MEAI user-agent header should be present"); + Assert.True( + hasDefaultUserAgent, + "Default AnthropicClient user-agent header should be present" + ); + } } diff --git a/src/Anthropic.Tests/AnthropicClientExtensionsTests.cs b/src/Anthropic.Tests/AnthropicClientExtensionsTests.cs index 0d5a17652..7d41d8327 100644 --- a/src/Anthropic.Tests/AnthropicClientExtensionsTests.cs +++ b/src/Anthropic.Tests/AnthropicClientExtensionsTests.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading.Tasks; using Anthropic; using Anthropic.Models.Messages; @@ -480,4 +479,275 @@ public async Task GetResponseAsync_WithRawRepresentationFactory_SystemMessagesLi ); Assert.NotNull(response); } + + [Fact] + public async Task GetResponseAsync_IncludesMeaiUserAgentHeader() + { + string[]? capturedUserAgentValues = null; + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "Test" + }] + }] + } + """, + actualResponse: """ + { + "id": "msg_meai_header_01", + "type": "message", + "role": "assistant", + "model": "claude-haiku-4-5", + "content": [{ + "type": "text", + "text": "Response" + }], + "stop_reason": "end_turn", + "usage": { + "input_tokens": 10, + "output_tokens": 5 + } + } + """ + ) + { + OnRequestHeaders = headers => + { + // Verify there's exactly one User-Agent header entry + Assert.Single(headers, h => h.Key == "User-Agent"); + if (headers.TryGetValues("User-Agent", out var values)) + { + capturedUserAgentValues = [.. values]; + } + }, + }; + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + ChatResponse response = await chatClient.GetResponseAsync( + "Test", + new(), + TestContext.Current.CancellationToken + ); + + Assert.NotNull(response); + Assert.NotNull(capturedUserAgentValues); + Assert.Contains(capturedUserAgentValues, v => v.Contains("MEAI")); + Assert.Contains(capturedUserAgentValues, v => v.Contains("AnthropicClient")); + } + + [Fact] + public async Task GetStreamingResponseAsync_IncludesMeaiUserAgentHeader() + { + string[]? capturedUserAgentValues = null; + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "Test streaming" + }] + }], + "stream": true + } + """, + actualResponse: """ + event: message_start + data: {"type":"message_start","message":{"id":"msg_stream_meai_01","type":"message","role":"assistant","model":"claude-haiku-4-5","content":[],"stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":10,"output_tokens":0}}} + + event: content_block_start + data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}} + + event: content_block_delta + data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Response"}} + + event: content_block_stop + data: {"type":"content_block_stop","index":0} + + event: message_delta + data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":5}} + + event: message_stop + data: {"type":"message_stop"} + + """ + ) + { + OnRequestHeaders = headers => + { + // Verify there's exactly one User-Agent header entry + Assert.Single(headers, h => h.Key == "User-Agent"); + if (headers.TryGetValues("User-Agent", out var values)) + { + capturedUserAgentValues = [.. values]; + } + }, + }; + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + List updates = []; + await foreach ( + var update in chatClient.GetStreamingResponseAsync( + "Test streaming", + new(), + TestContext.Current.CancellationToken + ) + ) + { + updates.Add(update); + } + + Assert.NotEmpty(updates); + Assert.NotNull(capturedUserAgentValues); + Assert.Contains(capturedUserAgentValues, v => v.Contains("MEAI")); + Assert.Contains(capturedUserAgentValues, v => v.Contains("AnthropicClient")); + } + + [Fact] + public async Task GetResponseAsync_MeaiUserAgentHeader_HasCorrectFormat() + { + string[]? capturedUserAgentValues = null; + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "Test" + }] + }] + } + """, + actualResponse: """ + { + "id": "msg_meai_format_01", + "type": "message", + "role": "assistant", + "model": "claude-haiku-4-5", + "content": [{ + "type": "text", + "text": "Response" + }], + "stop_reason": "end_turn", + "usage": { + "input_tokens": 10, + "output_tokens": 5 + } + } + """ + ) + { + OnRequestHeaders = headers => + { + // Verify there's exactly one User-Agent header entry + Assert.Single(headers, h => h.Key == "User-Agent"); + if (headers.TryGetValues("User-Agent", out var values)) + { + capturedUserAgentValues = [.. values]; + } + }, + }; + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + ChatResponse response = await chatClient.GetResponseAsync( + "Test", + new(), + TestContext.Current.CancellationToken + ); + + Assert.NotNull(response); + Assert.NotNull(capturedUserAgentValues); + // Verify the MEAI user-agent is present and has correct format (MEAI or MEAI/version) + Assert.Contains( + capturedUserAgentValues, + v => v.StartsWith("MEAI", StringComparison.Ordinal) + ); + Assert.Contains(capturedUserAgentValues, v => v.Contains("AnthropicClient")); + } + + [Fact] + public async Task GetResponseAsync_MeaiUserAgentHeader_PresentAlongsideDefaultHeaders() + { + bool hasAnthropicVersion = false; + bool hasMeaiUserAgent = false; + bool hasDefaultUserAgent = false; + + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "Test" + }] + }] + } + """, + actualResponse: """ + { + "id": "msg_headers_01", + "type": "message", + "role": "assistant", + "model": "claude-haiku-4-5", + "content": [{ + "type": "text", + "text": "Response" + }], + "stop_reason": "end_turn", + "usage": { + "input_tokens": 10, + "output_tokens": 5 + } + } + """ + ) + { + OnRequestHeaders = headers => + { + // Verify there's exactly one User-Agent header entry + Assert.Single(headers, h => h.Key == "User-Agent"); + hasAnthropicVersion = headers.Contains("anthropic-version"); + if (headers.TryGetValues("User-Agent", out var values)) + { + var valuesArray = values.ToArray(); + hasMeaiUserAgent = valuesArray.Any(v => v.Contains("MEAI")); + hasDefaultUserAgent = valuesArray.Any(v => v.Contains("AnthropicClient")); + } + }, + }; + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + ChatResponse response = await chatClient.GetResponseAsync( + "Test", + new(), + TestContext.Current.CancellationToken + ); + + Assert.NotNull(response); + Assert.True(hasAnthropicVersion, "anthropic-version header should be present"); + Assert.True(hasMeaiUserAgent, "MEAI user-agent header should be present"); + Assert.True( + hasDefaultUserAgent, + "Default AnthropicClient user-agent header should be present" + ); + } } diff --git a/src/Anthropic/AnthropicClientExtensions.cs b/src/Anthropic/AnthropicClientExtensions.cs index 2aa20fa17..a5f96ccec 100644 --- a/src/Anthropic/AnthropicClientExtensions.cs +++ b/src/Anthropic/AnthropicClientExtensions.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Text.Json; @@ -87,12 +89,47 @@ private sealed class AnthropicChatClient( ) : IChatClient { private const int DefaultMaxTokens = 1024; + private const string MeaiUserAgentHeaderKey = "User-Agent"; + + private static readonly FrozenDictionary s_meaiHeaderData = + new Dictionary + { + [MeaiUserAgentHeaderKey] = JsonSerializer.SerializeToElement( + CreateMeaiUserAgentValue() + ), + }.ToFrozenDictionary(); private readonly IAnthropicClient _anthropicClient = anthropicClient; private readonly string? _defaultModelId = defaultModelId; private readonly int _defaultMaxTokens = defaultMaxTokens ?? DefaultMaxTokens; private ChatClientMetadata? _metadata; + private static string CreateMeaiUserAgentValue() + { + const string Name = "MEAI"; + + if ( + typeof(IChatClient) + .Assembly.GetCustomAttribute() + ?.InformationalVersion + is string version + ) + { + int pos = version.IndexOf('+'); + if (pos >= 0) + { + version = version.Substring(0, pos); + } + + if (version.Length > 0) + { + return $"{Name}/{version}"; + } + } + + return Name; + } + /// void IDisposable.Dispose() { } @@ -899,7 +936,24 @@ toolMode is AutoChatToolMode createParams = createParams with { System = systemMessages }; } - return createParams; + // Merge the MEAI user-agent header with existing headers + return AddMeaiHeaders(createParams); + } + + private static MessageCreateParams AddMeaiHeaders(MessageCreateParams createParams) + { + Dictionary mergedHeaders = new(s_meaiHeaderData); + + foreach (var header in createParams.RawHeaderData) + { + mergedHeaders[header.Key] = header.Value; + } + + return MessageCreateParams.FromRawUnchecked( + mergedHeaders, + createParams.RawQueryData, + createParams.RawBodyData + ); } private static UsageDetails ToUsageDetails(Usage usage) => diff --git a/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs b/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs index 2dd0c2eb5..0f569308c 100644 --- a/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs +++ b/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs @@ -1,7 +1,9 @@ using System; +using System.Collections.Frozen; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Text.Json; @@ -137,6 +139,41 @@ private sealed class AnthropicChatClient( ) : IChatClient { private const int DefaultMaxTokens = 1024; + private const string MeaiUserAgentHeaderKey = "User-Agent"; + + private static readonly FrozenDictionary s_meaiHeaderData = + new Dictionary + { + [MeaiUserAgentHeaderKey] = JsonSerializer.SerializeToElement( + CreateMeaiUserAgentValue() + ), + }.ToFrozenDictionary(); + + private static string CreateMeaiUserAgentValue() + { + const string Name = "MEAI"; + + if ( + typeof(IChatClient) + .Assembly.GetCustomAttribute() + ?.InformationalVersion + is string version + ) + { + int pos = version.IndexOf('+'); + if (pos >= 0) + { + version = version.Substring(0, pos); + } + + if (version.Length > 0) + { + return $"{Name}/{version}"; + } + } + + return Name; + } private static readonly AIJsonSchemaTransformCache s_transformCache = new( new AIJsonSchemaTransformOptions @@ -1143,7 +1180,24 @@ existingSystem.Value is IReadOnlyList existingMessages createParams = createParams with { Betas = [.. betaHeaders] }; } - return createParams; + // Merge the MEAI user-agent header with existing headers + return AddMeaiHeaders(createParams); + } + + private static MessageCreateParams AddMeaiHeaders(MessageCreateParams createParams) + { + Dictionary mergedHeaders = new(s_meaiHeaderData); + + foreach (var header in createParams.RawHeaderData) + { + mergedHeaders[header.Key] = header.Value; + } + + return MessageCreateParams.FromRawUnchecked( + mergedHeaders, + createParams.RawQueryData, + createParams.RawBodyData + ); } private static UsageDetails ToUsageDetails(BetaUsage usage) => From 3733fea562b0af7010a73f1e5c631c81d2db8323 Mon Sep 17 00:00:00 2001 From: Stephen Date: Thu, 29 Jan 2026 12:21:45 -0500 Subject: [PATCH 24/41] fix formatting (#101) --- .../Services/Messages/BatchServiceTest.cs | 334 +++++++++--------- 1 file changed, 167 insertions(+), 167 deletions(-) diff --git a/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs b/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs index fd59c99b3..5f41456ea 100644 --- a/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs +++ b/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs @@ -1,167 +1,167 @@ -using System.Collections.Generic; -using System.Text.Json; -using System.Threading.Tasks; -using Anthropic.Models.Messages.Batches; -using Anthropic.Tests; -using Messages = Anthropic.Models.Messages; - -namespace Anthropic.Tests.Services.Messages; - -public class BatchServiceTest -{ - [Theory] - [AnthropicTestClients] - [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] - [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] - public async Task Create_Works(IAnthropicClient client, string modelName) - { - var messageBatch = await client.Messages.Batches.Create( - new() - { - Requests = - [ - new() - { - CustomID = "my-custom-id-1", - Params = new() - { - MaxTokens = 1024, - Messages = - [ - new() { Content = "Hello, world", Role = Messages::Role.User }, - ], - Model = modelName, - Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() - { - Format = new() - { - Schema = new Dictionary() - { - { "foo", JsonSerializer.SerializeToElement("bar") }, - }, - }, - }, - ServiceTier = ServiceTier.Auto, - StopSequences = ["string"], - Stream = true, - System = new( - [ - new Messages::TextBlockParam() - { - Text = "Today's date is 2024-06-01.", - CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, - Citations = - [ - new Messages::CitationCharLocationParam() - { - CitedText = "cited_text", - DocumentIndex = 0, - DocumentTitle = "x", - EndCharIndex = 0, - StartCharIndex = 0, - }, - ], - }, - ] - ), - Temperature = 1, - Thinking = new Messages::ThinkingConfigEnabled(1024), - ToolChoice = new Messages::ToolChoiceAuto() - { - DisableParallelToolUse = true, - }, - Tools = - [ - new Messages::Tool() - { - InputSchema = new() - { - Properties = new Dictionary() - { - { - "location", - JsonSerializer.SerializeToElement("bar") - }, - { "unit", JsonSerializer.SerializeToElement("bar") }, - }, - Required = ["location"], - }, - Name = "name", - CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, - Description = "Get the current weather in a given location", - Strict = true, - Type = Messages::Type.Custom, - }, - ], - TopK = 5, - TopP = 0.7, - }, - }, - ], - }, - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients] - public async Task Retrieve_Works(IAnthropicClient client) - { - var messageBatch = await client.Messages.Batches.Retrieve( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients] - public async Task List_Works(IAnthropicClient client) - { - var page = await client.Messages.Batches.List(new(), TestContext.Current.CancellationToken); - page.Validate(); - } - - [Theory] - [AnthropicTestClients] - public async Task Delete_Works(IAnthropicClient client) - { - var deletedMessageBatch = await client.Messages.Batches.Delete( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - deletedMessageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients] - public async Task Cancel_Works(IAnthropicClient client) - { - var messageBatch = await client.Messages.Batches.Cancel( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory(Skip = "Prism doesn't support application/x-jsonl responses")] - [AnthropicTestClients] - public async Task ResultsStreaming_Works(IAnthropicClient client) - { - var stream = client.Messages.Batches.ResultsStreaming( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - - await foreach (var messageBatchIndividualResponse in stream) - { - messageBatchIndividualResponse.Validate(); - } - } -} +using System.Collections.Generic; +using System.Text.Json; +using System.Threading.Tasks; +using Anthropic.Models.Messages.Batches; +using Anthropic.Tests; +using Messages = Anthropic.Models.Messages; + +namespace Anthropic.Tests.Services.Messages; + +public class BatchServiceTest +{ + [Theory] + [AnthropicTestClients] + [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] + [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + public async Task Create_Works(IAnthropicClient client, string modelName) + { + var messageBatch = await client.Messages.Batches.Create( + new() + { + Requests = + [ + new() + { + CustomID = "my-custom-id-1", + Params = new() + { + MaxTokens = 1024, + Messages = + [ + new() { Content = "Hello, world", Role = Messages::Role.User }, + ], + Model = modelName, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() + { + DisableParallelToolUse = true, + }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { + "location", + JsonSerializer.SerializeToElement("bar") + }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + Strict = true, + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }, + }, + ], + }, + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients] + public async Task Retrieve_Works(IAnthropicClient client) + { + var messageBatch = await client.Messages.Batches.Retrieve( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients] + public async Task List_Works(IAnthropicClient client) + { + var page = await client.Messages.Batches.List(new(), TestContext.Current.CancellationToken); + page.Validate(); + } + + [Theory] + [AnthropicTestClients] + public async Task Delete_Works(IAnthropicClient client) + { + var deletedMessageBatch = await client.Messages.Batches.Delete( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + deletedMessageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients] + public async Task Cancel_Works(IAnthropicClient client) + { + var messageBatch = await client.Messages.Batches.Cancel( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory(Skip = "Prism doesn't support application/x-jsonl responses")] + [AnthropicTestClients] + public async Task ResultsStreaming_Works(IAnthropicClient client) + { + var stream = client.Messages.Batches.ResultsStreaming( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + + await foreach (var messageBatchIndividualResponse in stream) + { + messageBatchIndividualResponse.Validate(); + } + } +} From f48824bb0b48083ec83a0927943108208f66831c Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 19:23:59 +0000 Subject: [PATCH 25/41] chore(internal): ignore stainless-internal artifacts --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 08a6d8081..cb0f7844e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ bin/ obj/ .vs/ .idea/ + +# do not edit! excludes generated files used internally +.artifacts/ From b5730e50a8aa90ec2051ac86a746cd7245fb845f Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 18:27:35 +0000 Subject: [PATCH 26/41] chore(internal): add sse tests --- src/Anthropic.Tests/SseTest.cs | 112 +++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/Anthropic.Tests/SseTest.cs diff --git a/src/Anthropic.Tests/SseTest.cs b/src/Anthropic.Tests/SseTest.cs new file mode 100644 index 000000000..e9e90fde5 --- /dev/null +++ b/src/Anthropic.Tests/SseTest.cs @@ -0,0 +1,112 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Tests; + +public class SseTest : TestBase +{ + public static TheoryData Data() => + new() + { + // event and data + { "event: completion\n" + "data: {\"foo\":true}\n\n", ["{\"foo\": true}"] }, + // event missing data + { "event: completion\n" + "\n", [] }, + // multiple events and data + { + "event: completion\n" + + "data: {\"foo\":true}\n\n" + + "event: message_start\n" + + "data: {\"bar\": false}\n\n", + ["{\"foo\": true}", "{\"bar\": false}"] + }, + // multiple events missing data + { "event: completion\n" + "\n" + "event: message_start\n" + "\n", [] }, + // json-escaped double newline + { + "event: completion\n" + "data: {\ndata: \"foo\":\ndata: true }\n\n\n", + ["{ \"foo\":\ntrue }"] + }, + // multiple data lines + { + "event: completion\n" + "data: { \ndata: \"foo\":\ndata: true }\n\n\n", + ["{ \"foo\":\ntrue }"] + }, + // special newline character + { + "event: completion\n" + + "data: {\"content\": \" culpa\"}\n\n" + + "event: message_start\n" + + "data: {\"content\": \" \u2028\"}\n\n" + + "event: completion\n" + + "data: {\"content\": \"foo\"}\n\n", + [ + "{\"content\": \" culpa\"}", + "{\"content\": \" \u2028\"}", + "{\"content\": \"foo\"}", + ] + }, + // multi-byte character + { + "event: completion\n" + + "data: {\"content\": " + + "\"\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0438\"}\n\n}", + ["{\"content\":\"известни\"}"] + }, + }; + + [Theory] + [MemberData(nameof(Data))] + public async Task Sse_Works( + string events, + string[] expectedMessageStrings, + CancellationToken cancellationToken = default + ) + { + var expectedMessages = new List(); + foreach (var message in expectedMessageStrings) + { + expectedMessages.Add(JsonSerializer.Deserialize(message)); + } + + var resp = new HttpResponseMessage() { Content = new StringContent(events) }; + + var actualMessages = new List(); + await foreach (var message in Sse.Enumerate(resp, cancellationToken)) + { + actualMessages.Add(message); + } + + Assert.Equal(expectedMessages.Count, actualMessages.Count); + for (int i = 0; i < expectedMessages.Count; i++) + { + Assert.True(JsonElement.DeepEquals(expectedMessages[i], actualMessages[i])); + } + } + + [Fact] + public async Task SseEventError_Works() + { + var resp = new HttpResponseMessage() + { + Content = new StringContent("event: error\ndata: unspecified error\n\n"), + }; + + var exception = await Assert.ThrowsAsync(async () => + { + await foreach ( + var message in Sse.Enumerate( + resp, + TestContext.Current.CancellationToken + ) + ) { } + }); + + Assert.Equal("SSE error returned from server: 'unspecified error'", exception.Message); + } +} From 98349082a391234569be16049f1a6a1f24c20100 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 19:27:08 +0000 Subject: [PATCH 27/41] feat(client): add common response headers to `HttpResponse` --- src/Anthropic/Core/HttpResponse.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Anthropic/Core/HttpResponse.cs b/src/Anthropic/Core/HttpResponse.cs index 1f54bd0b8..366c954ce 100644 --- a/src/Anthropic/Core/HttpResponse.cs +++ b/src/Anthropic/Core/HttpResponse.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Linq; using System.Net; using System.Net.Http; using System.Text.Json; @@ -32,6 +33,20 @@ public HttpStatusCode StatusCode public Threading::CancellationToken CancellationToken { get; init; } = default; + /// + /// Returns the value of the request-id header, or null if there's no + /// such header in the response. + /// + public string? RequestID + { + get + { + return RawMessage.Headers.TryGetValues("request-id", out var value) + ? Enumerable.FirstOrDefault(value) + : null; + } + } + public IEnumerable GetHeaderValues(string name) => RawMessage.Headers.GetValues(name); public bool TryGetHeaderValues( From 2f857bbad40967cb13f689dd773a59d2ef55614d Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 22:01:53 +0000 Subject: [PATCH 28/41] fix(client): improve union equality method --- src/Anthropic/Models/Beta/BetaError.cs | 25 +++++++-- .../Messages/Batches/BatchCreateParams.cs | 36 ++++++++++--- .../Batches/BetaMessageBatchResult.cs | 20 +++++-- .../BetaBashCodeExecutionToolResultBlock.cs | 18 +++++-- ...taBashCodeExecutionToolResultBlockParam.cs | 18 +++++-- .../Beta/Messages/BetaCitationsDelta.cs | 21 ++++++-- .../Messages/BetaClearThinking20251015Edit.cs | 19 +++++-- .../Messages/BetaClearToolUses20250919Edit.cs | 36 ++++++++++--- ...BetaCodeExecutionToolResultBlockContent.cs | 18 +++++-- ...odeExecutionToolResultBlockParamContent.cs | 18 +++++-- .../Models/Beta/Messages/BetaContentBlock.cs | 30 +++++++++-- .../Beta/Messages/BetaContentBlockParam.cs | 34 ++++++++++-- .../Beta/Messages/BetaContentBlockSource.cs | 18 +++++-- .../Messages/BetaContextManagementConfig.cs | 18 +++++-- .../Messages/BetaContextManagementResponse.cs | 18 +++++-- .../Models/Beta/Messages/BetaDocumentBlock.cs | 18 +++++-- .../Beta/Messages/BetaImageBlockParam.cs | 19 +++++-- .../Beta/Messages/BetaMcpToolResultBlock.cs | 18 +++++-- .../Messages/BetaMemoryTool20250818Command.cs | 22 ++++++-- .../Models/Beta/Messages/BetaMessageParam.cs | 18 +++++-- .../Beta/Messages/BetaRawContentBlockDelta.cs | 21 ++++++-- .../Messages/BetaRawContentBlockStartEvent.cs | 30 +++++++++-- .../Messages/BetaRawMessageStreamEvent.cs | 22 ++++++-- .../Beta/Messages/BetaRequestDocumentBlock.cs | 21 ++++++-- .../BetaRequestMcpToolResultBlockParam.cs | 18 +++++-- .../Beta/Messages/BetaServerToolUseBlock.cs | 18 +++++-- .../Messages/BetaServerToolUseBlockParam.cs | 18 +++++-- .../Models/Beta/Messages/BetaTextCitation.cs | 21 ++++++-- .../Beta/Messages/BetaTextCitationParam.cs | 21 ++++++-- ...aTextEditorCodeExecutionToolResultBlock.cs | 20 +++++-- ...EditorCodeExecutionToolResultBlockParam.cs | 20 +++++-- .../Beta/Messages/BetaThinkingConfigParam.cs | 18 +++++-- .../Models/Beta/Messages/BetaToolChoice.cs | 20 +++++-- .../Beta/Messages/BetaToolResultBlockParam.cs | 39 +++++++++++--- .../Messages/BetaToolSearchToolResultBlock.cs | 18 +++++-- .../BetaToolSearchToolResultBlockParam.cs | 18 +++++-- .../Models/Beta/Messages/BetaToolUnion.cs | 34 ++++++++++-- .../Models/Beta/Messages/BetaToolUseBlock.cs | 18 +++++-- .../Beta/Messages/BetaToolUseBlockParam.cs | 18 +++++-- .../Messages/BetaWebFetchToolResultBlock.cs | 18 +++++-- .../BetaWebFetchToolResultBlockParam.cs | 18 +++++-- .../BetaWebSearchToolResultBlockContent.cs | 18 +++++-- ...etaWebSearchToolResultBlockParamContent.cs | 18 +++++-- .../MessageBetaContentBlockSourceContent.cs | 18 +++++-- .../Beta/Messages/MessageCountTokensParams.cs | 52 ++++++++++++++++--- .../Beta/Messages/MessageCreateParams.cs | 36 ++++++++++--- src/Anthropic/Models/ErrorObject.cs | 25 +++++++-- .../Messages/Batches/BatchCreateParams.cs | 18 +++++-- .../Messages/Batches/MessageBatchResult.cs | 20 +++++-- .../Models/Messages/CitationsDelta.cs | 21 ++++++-- src/Anthropic/Models/Messages/ContentBlock.cs | 22 ++++++-- .../Models/Messages/ContentBlockParam.cs | 26 ++++++++-- .../Models/Messages/ContentBlockSource.cs | 18 +++++-- .../Messages/ContentBlockSourceContent.cs | 18 +++++-- .../Models/Messages/DocumentBlockParam.cs | 20 +++++-- .../Models/Messages/ImageBlockParam.cs | 18 +++++-- .../Messages/MessageCountTokensParams.cs | 18 +++++-- .../Models/Messages/MessageCountTokensTool.cs | 22 ++++++-- .../Models/Messages/MessageCreateParams.cs | 18 +++++-- src/Anthropic/Models/Messages/MessageParam.cs | 18 +++++-- .../Models/Messages/RawContentBlockDelta.cs | 21 ++++++-- .../Messages/RawContentBlockStartEvent.cs | 22 ++++++-- .../Models/Messages/RawMessageStreamEvent.cs | 22 ++++++-- src/Anthropic/Models/Messages/TextCitation.cs | 21 ++++++-- .../Models/Messages/TextCitationParam.cs | 21 ++++++-- .../Models/Messages/ThinkingConfigParam.cs | 18 +++++-- src/Anthropic/Models/Messages/ToolChoice.cs | 20 +++++-- .../Models/Messages/ToolResultBlockParam.cs | 38 +++++++++++--- src/Anthropic/Models/Messages/ToolUnion.cs | 22 ++++++-- .../WebSearchToolResultBlockContent.cs | 18 +++++-- .../WebSearchToolResultBlockParamContent.cs | 18 +++++-- 71 files changed, 1248 insertions(+), 308 deletions(-) diff --git a/src/Anthropic/Models/Beta/BetaError.cs b/src/Anthropic/Models/Beta/BetaError.cs index 35546d118..ccd5d31ef 100644 --- a/src/Anthropic/Models/Beta/BetaError.cs +++ b/src/Anthropic/Models/Beta/BetaError.cs @@ -488,10 +488,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaError? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaError? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -500,6 +500,23 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaInvalidRequestError _ => 0, + BetaAuthenticationError _ => 1, + BetaBillingError _ => 2, + BetaPermissionError _ => 3, + BetaNotFoundError _ => 4, + BetaRateLimitError _ => 5, + BetaGatewayTimeoutError _ => 6, + BetaApiError _ => 7, + BetaOverloadedError _ => 8, + _ => -1, + }; + } } sealed class BetaErrorConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs index 1d4ad1571..0a5095193 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs @@ -1045,10 +1045,10 @@ public override void Validate() this.Switch((betaContainerParams) => betaContainerParams.Validate(), (_) => { }); } - public virtual bool Equals(Container? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Container? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -1057,6 +1057,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaContainerParams _ => 0, + string _ => 1, + _ => -1, + }; + } } sealed class ContainerConverter : JsonConverter @@ -1353,10 +1363,10 @@ public override void Validate() } } - public virtual bool Equals(ParamsSystem? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ParamsSystem? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -1365,6 +1375,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class ParamsSystemConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchResult.cs b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchResult.cs index 688d6805a..b7d891c5b 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchResult.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BetaMessageBatchResult.cs @@ -291,10 +291,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaMessageBatchResult? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaMessageBatchResult? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -303,6 +303,18 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaMessageBatchSucceededResult _ => 0, + BetaMessageBatchErroredResult _ => 1, + BetaMessageBatchCanceledResult _ => 2, + BetaMessageBatchExpiredResult _ => 3, + _ => -1, + }; + } } sealed class BetaMessageBatchResultConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlock.cs index edd962864..d2bb4108b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlock.cs @@ -307,10 +307,10 @@ public override void Validate() ); } - public virtual bool Equals(Content? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Content? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -319,6 +319,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaBashCodeExecutionToolResultError _ => 0, + BetaBashCodeExecutionResultBlock _ => 1, + _ => -1, + }; + } } sealed class ContentConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParam.cs index 36fc1ac9a..3eae802d5 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaBashCodeExecutionToolResultBlockParam.cs @@ -341,10 +341,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaBashCodeExecutionToolResultBlockParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaBashCodeExecutionToolResultBlockParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -353,6 +353,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaBashCodeExecutionToolResultErrorParam _ => 0, + BetaBashCodeExecutionResultBlockParam _ => 1, + _ => -1, + }; + } } sealed class BetaBashCodeExecutionToolResultBlockParamContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaCitationsDelta.cs b/src/Anthropic/Models/Beta/Messages/BetaCitationsDelta.cs index 9ca66d69e..efe20e800 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCitationsDelta.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCitationsDelta.cs @@ -512,10 +512,10 @@ public override void Validate() ); } - public virtual bool Equals(Citation? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Citation? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -524,6 +524,19 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaCitationCharLocation _ => 0, + BetaCitationPageLocation _ => 1, + BetaCitationContentBlockLocation _ => 2, + BetaCitationsWebSearchResultLocation _ => 3, + BetaCitationSearchResultLocation _ => 4, + _ => -1, + }; + } } sealed class CitationConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015Edit.cs b/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015Edit.cs index e0ed8a9b3..684197cba 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015Edit.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaClearThinking20251015Edit.cs @@ -335,10 +335,10 @@ public override void Validate() ); } - public virtual bool Equals(Keep? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Keep? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -347,6 +347,17 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaThinkingTurns _ => 0, + BetaAllThinkingTurns _ => 1, + UnionMember2 _ => 2, + _ => -1, + }; + } } sealed class KeepConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs b/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs index b4a368db1..cac1b5050 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs @@ -352,10 +352,10 @@ public override void Validate() } } - public virtual bool Equals(ClearToolInputs? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ClearToolInputs? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -364,6 +364,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + bool _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class ClearToolInputsConverter : JsonConverter @@ -602,10 +612,10 @@ public override void Validate() ); } - public virtual bool Equals(Trigger? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Trigger? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -614,6 +624,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaInputTokensTrigger _ => 0, + BetaToolUsesTrigger _ => 1, + _ => -1, + }; + } } sealed class TriggerConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockContent.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockContent.cs index 8a1fd4b18..be04dfcb9 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockContent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockContent.cs @@ -200,10 +200,10 @@ public override void Validate() this.Switch((error) => error.Validate(), (resultBlock) => resultBlock.Validate()); } - public virtual bool Equals(BetaCodeExecutionToolResultBlockContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaCodeExecutionToolResultBlockContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -212,6 +212,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaCodeExecutionToolResultError _ => 0, + BetaCodeExecutionResultBlock _ => 1, + _ => -1, + }; + } } sealed class BetaCodeExecutionToolResultBlockContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParamContent.cs b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParamContent.cs index b1547239d..058dc570b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParamContent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaCodeExecutionToolResultBlockParamContent.cs @@ -207,10 +207,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaCodeExecutionToolResultBlockParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaCodeExecutionToolResultBlockParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -219,6 +219,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaCodeExecutionToolResultErrorParam _ => 0, + BetaCodeExecutionResultBlockParam _ => 1, + _ => -1, + }; + } } sealed class BetaCodeExecutionToolResultBlockParamContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaContentBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaContentBlock.cs index 93ad46fa5..673a75333 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContentBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContentBlock.cs @@ -743,10 +743,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaContentBlock? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaContentBlock? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -755,6 +755,28 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaTextBlock _ => 0, + BetaThinkingBlock _ => 1, + BetaRedactedThinkingBlock _ => 2, + BetaToolUseBlock _ => 3, + BetaServerToolUseBlock _ => 4, + BetaWebSearchToolResultBlock _ => 5, + BetaWebFetchToolResultBlock _ => 6, + BetaCodeExecutionToolResultBlock _ => 7, + BetaBashCodeExecutionToolResultBlock _ => 8, + BetaTextEditorCodeExecutionToolResultBlock _ => 9, + BetaToolSearchToolResultBlock _ => 10, + BetaMcpToolUseBlock _ => 11, + BetaMcpToolResultBlock _ => 12, + BetaContainerUploadBlock _ => 13, + _ => -1, + }; + } } sealed class BetaContentBlockConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaContentBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaContentBlockParam.cs index b29d88fba..334e7f380 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContentBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContentBlockParam.cs @@ -1024,10 +1024,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaContentBlockParam? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaContentBlockParam? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -1036,6 +1036,32 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaTextBlockParam _ => 0, + BetaImageBlockParam _ => 1, + BetaRequestDocumentBlock _ => 2, + BetaSearchResultBlockParam _ => 3, + BetaThinkingBlockParam _ => 4, + BetaRedactedThinkingBlockParam _ => 5, + BetaToolUseBlockParam _ => 6, + BetaToolResultBlockParam _ => 7, + BetaServerToolUseBlockParam _ => 8, + BetaWebSearchToolResultBlockParam _ => 9, + BetaWebFetchToolResultBlockParam _ => 10, + BetaCodeExecutionToolResultBlockParam _ => 11, + BetaBashCodeExecutionToolResultBlockParam _ => 12, + BetaTextEditorCodeExecutionToolResultBlockParam _ => 13, + BetaToolSearchToolResultBlockParam _ => 14, + BetaMcpToolUseBlockParam _ => 15, + BetaRequestMcpToolResultBlockParam _ => 16, + BetaContainerUploadBlockParam _ => 17, + _ => -1, + }; + } } sealed class BetaContentBlockParamConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaContentBlockSource.cs b/src/Anthropic/Models/Beta/Messages/BetaContentBlockSource.cs index 0d2667dc0..772b3ac16 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContentBlockSource.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContentBlockSource.cs @@ -283,10 +283,10 @@ public override void Validate() } } - public virtual bool Equals(BetaContentBlockSourceContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaContentBlockSourceContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -295,6 +295,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class BetaContentBlockSourceContentConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs b/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs index 5536cadd5..4b17e6d9c 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs @@ -276,10 +276,10 @@ public override void Validate() ); } - public virtual bool Equals(Edit? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Edit? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -288,6 +288,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaClearToolUses20250919Edit _ => 0, + BetaClearThinking20251015Edit _ => 1, + _ => -1, + }; + } } sealed class EditConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaContextManagementResponse.cs b/src/Anthropic/Models/Beta/Messages/BetaContextManagementResponse.cs index eeab4d2f2..f99164a8e 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContextManagementResponse.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContextManagementResponse.cs @@ -308,10 +308,10 @@ public override void Validate() ); } - public virtual bool Equals(AppliedEdit? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(AppliedEdit? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -320,6 +320,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaClearToolUses20250919EditResponse _ => 0, + BetaClearThinking20251015EditResponse _ => 1, + _ => -1, + }; + } } sealed class AppliedEditConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaDocumentBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaDocumentBlock.cs index be32d89aa..3ba372e73 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaDocumentBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaDocumentBlock.cs @@ -304,10 +304,10 @@ public override void Validate() ); } - public virtual bool Equals(Source? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Source? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -316,6 +316,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaBase64PdfSource _ => 0, + BetaPlainTextSource _ => 1, + _ => -1, + }; + } } sealed class SourceConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaImageBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaImageBlockParam.cs index fabc95264..002c41fd0 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaImageBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaImageBlockParam.cs @@ -339,10 +339,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaImageBlockParamSource? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaImageBlockParamSource? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -351,6 +351,17 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaBase64ImageSource _ => 0, + BetaUrlImageSource _ => 1, + BetaFileImageSource _ => 2, + _ => -1, + }; + } } sealed class BetaImageBlockParamSourceConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaMcpToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaMcpToolResultBlock.cs index 1765bd426..dd8096f8f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMcpToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMcpToolResultBlock.cs @@ -293,10 +293,10 @@ public override void Validate() } } - public virtual bool Equals(BetaMcpToolResultBlockContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaMcpToolResultBlockContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -305,6 +305,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class BetaMcpToolResultBlockContentConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818Command.cs b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818Command.cs index eb6849729..ea2a7a96f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818Command.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMemoryTool20250818Command.cs @@ -412,10 +412,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaMemoryTool20250818Command? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaMemoryTool20250818Command? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -424,6 +424,20 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaMemoryTool20250818ViewCommand _ => 0, + BetaMemoryTool20250818CreateCommand _ => 1, + BetaMemoryTool20250818StrReplaceCommand _ => 2, + BetaMemoryTool20250818InsertCommand _ => 3, + BetaMemoryTool20250818DeleteCommand _ => 4, + BetaMemoryTool20250818RenameCommand _ => 5, + _ => -1, + }; + } } sealed class BetaMemoryTool20250818CommandConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaMessageParam.cs b/src/Anthropic/Models/Beta/Messages/BetaMessageParam.cs index 5297e35ae..bc32255dc 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMessageParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMessageParam.cs @@ -260,10 +260,10 @@ public override void Validate() } } - public virtual bool Equals(BetaMessageParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaMessageParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -272,6 +272,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class BetaMessageParamContentConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDelta.cs b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDelta.cs index ab4c8ddb5..862b80ec8 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDelta.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDelta.cs @@ -319,10 +319,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaRawContentBlockDelta? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaRawContentBlockDelta? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -331,6 +331,19 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaTextDelta _ => 0, + BetaInputJsonDelta _ => 1, + BetaCitationsDelta _ => 2, + BetaThinkingDelta _ => 3, + BetaSignatureDelta _ => 4, + _ => -1, + }; + } } sealed class BetaRawContentBlockDeltaConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs index d190603d7..560c17d85 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs @@ -843,10 +843,10 @@ public override void Validate() ); } - public virtual bool Equals(ContentBlock? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ContentBlock? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -855,6 +855,28 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaTextBlock _ => 0, + BetaThinkingBlock _ => 1, + BetaRedactedThinkingBlock _ => 2, + BetaToolUseBlock _ => 3, + BetaServerToolUseBlock _ => 4, + BetaWebSearchToolResultBlock _ => 5, + BetaWebFetchToolResultBlock _ => 6, + BetaCodeExecutionToolResultBlock _ => 7, + BetaBashCodeExecutionToolResultBlock _ => 8, + BetaTextEditorCodeExecutionToolResultBlock _ => 9, + BetaToolSearchToolResultBlock _ => 10, + BetaMcpToolUseBlock _ => 11, + BetaMcpToolResultBlock _ => 12, + BetaContainerUploadBlock _ => 13, + _ => -1, + }; + } } sealed class ContentBlockConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawMessageStreamEvent.cs b/src/Anthropic/Models/Beta/Messages/BetaRawMessageStreamEvent.cs index a05459572..18517a251 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawMessageStreamEvent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawMessageStreamEvent.cs @@ -391,10 +391,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaRawMessageStreamEvent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaRawMessageStreamEvent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -403,6 +403,20 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaRawMessageStartEvent _ => 0, + BetaRawMessageDeltaEvent _ => 1, + BetaRawMessageStopEvent _ => 2, + BetaRawContentBlockStartEvent _ => 3, + BetaRawContentBlockDeltaEvent _ => 4, + BetaRawContentBlockStopEvent _ => 5, + _ => -1, + }; + } } sealed class BetaRawMessageStreamEventConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaRequestDocumentBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaRequestDocumentBlock.cs index abf2e2053..7583358f7 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRequestDocumentBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRequestDocumentBlock.cs @@ -483,10 +483,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaRequestDocumentBlockSource? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaRequestDocumentBlockSource? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -495,6 +495,19 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaBase64PdfSource _ => 0, + BetaPlainTextSource _ => 1, + BetaContentBlockSource _ => 2, + BetaUrlPdfSource _ => 3, + BetaFileDocumentSource _ => 4, + _ => -1, + }; + } } sealed class BetaRequestDocumentBlockSourceConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaRequestMcpToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaRequestMcpToolResultBlockParam.cs index 30940989e..a22c59ee3 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRequestMcpToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRequestMcpToolResultBlockParam.cs @@ -341,10 +341,10 @@ public override void Validate() } } - public virtual bool Equals(BetaRequestMcpToolResultBlockParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaRequestMcpToolResultBlockParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -353,6 +353,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class BetaRequestMcpToolResultBlockParamContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs index 32215d57c..ed6e2705b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlock.cs @@ -377,10 +377,10 @@ public override void Validate() ); } - public virtual bool Equals(Caller? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Caller? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -389,6 +389,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaDirectCaller _ => 0, + BetaServerToolCaller _ => 1, + _ => -1, + }; + } } sealed class CallerConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlockParam.cs index eb79f4015..7ef5d095d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaServerToolUseBlockParam.cs @@ -410,10 +410,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaServerToolUseBlockParamCaller? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaServerToolUseBlockParamCaller? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -422,6 +422,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaDirectCaller _ => 0, + BetaServerToolCaller _ => 1, + _ => -1, + }; + } } sealed class BetaServerToolUseBlockParamCallerConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextCitation.cs b/src/Anthropic/Models/Beta/Messages/BetaTextCitation.cs index 516b939e1..2a739d572 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextCitation.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextCitation.cs @@ -423,10 +423,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaTextCitation? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaTextCitation? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -435,6 +435,19 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaCitationCharLocation _ => 0, + BetaCitationPageLocation _ => 1, + BetaCitationContentBlockLocation _ => 2, + BetaCitationsWebSearchResultLocation _ => 3, + BetaCitationSearchResultLocation _ => 4, + _ => -1, + }; + } } sealed class BetaTextCitationConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextCitationParam.cs b/src/Anthropic/Models/Beta/Messages/BetaTextCitationParam.cs index 9c8916134..478345adc 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextCitationParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextCitationParam.cs @@ -429,10 +429,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaTextCitationParam? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaTextCitationParam? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -441,6 +441,19 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaCitationCharLocationParam _ => 0, + BetaCitationPageLocationParam _ => 1, + BetaCitationContentBlockLocationParam _ => 2, + BetaCitationWebSearchResultLocationParam _ => 3, + BetaCitationSearchResultLocationParam _ => 4, + _ => -1, + }; + } } sealed class BetaTextCitationParamConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlock.cs index 080252174..f163cae46 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlock.cs @@ -431,10 +431,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaTextEditorCodeExecutionToolResultBlockContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaTextEditorCodeExecutionToolResultBlockContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -443,6 +443,18 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaTextEditorCodeExecutionToolResultError _ => 0, + BetaTextEditorCodeExecutionViewResultBlock _ => 1, + BetaTextEditorCodeExecutionCreateResultBlock _ => 2, + BetaTextEditorCodeExecutionStrReplaceResultBlock _ => 3, + _ => -1, + }; + } } sealed class BetaTextEditorCodeExecutionToolResultBlockContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParam.cs index 81218b81b..0c96037f7 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTextEditorCodeExecutionToolResultBlockParam.cs @@ -445,10 +445,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaTextEditorCodeExecutionToolResultBlockParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaTextEditorCodeExecutionToolResultBlockParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -457,6 +457,18 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaTextEditorCodeExecutionToolResultErrorParam _ => 0, + BetaTextEditorCodeExecutionViewResultBlockParam _ => 1, + BetaTextEditorCodeExecutionCreateResultBlockParam _ => 2, + BetaTextEditorCodeExecutionStrReplaceResultBlockParam _ => 3, + _ => -1, + }; + } } sealed class BetaTextEditorCodeExecutionToolResultBlockParamContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigParam.cs b/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigParam.cs index b2bf44736..bd3eebd2a 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigParam.cs @@ -202,10 +202,10 @@ public override void Validate() this.Switch((enabled) => enabled.Validate(), (disabled) => disabled.Validate()); } - public virtual bool Equals(BetaThinkingConfigParam? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaThinkingConfigParam? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -214,6 +214,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaThinkingConfigEnabled _ => 0, + BetaThinkingConfigDisabled _ => 1, + _ => -1, + }; + } } sealed class BetaThinkingConfigParamConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolChoice.cs b/src/Anthropic/Models/Beta/Messages/BetaToolChoice.cs index 1e899c081..8030598fb 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolChoice.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolChoice.cs @@ -294,10 +294,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaToolChoice? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaToolChoice? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -306,6 +306,18 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaToolChoiceAuto _ => 0, + BetaToolChoiceAny _ => 1, + BetaToolChoiceTool _ => 2, + BetaToolChoiceNone _ => 3, + _ => -1, + }; + } } sealed class BetaToolChoiceConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaToolResultBlockParam.cs index 71d892b23..4eed61496 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolResultBlockParam.cs @@ -319,10 +319,10 @@ public override void Validate() } } - public virtual bool Equals(BetaToolResultBlockParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaToolResultBlockParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -331,6 +331,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class BetaToolResultBlockParamContentConverter @@ -720,10 +730,10 @@ public override void Validate() ); } - public virtual bool Equals(Block? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Block? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -732,6 +742,19 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaTextBlockParam _ => 0, + BetaImageBlockParam _ => 1, + BetaSearchResultBlockParam _ => 2, + BetaRequestDocumentBlock _ => 3, + BetaToolReferenceBlockParam _ => 4, + _ => -1, + }; + } } sealed class BlockConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlock.cs index 0f67f217f..711932322 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlock.cs @@ -311,10 +311,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaToolSearchToolResultBlockContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaToolSearchToolResultBlockContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -323,6 +323,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaToolSearchToolResultError _ => 0, + BetaToolSearchToolSearchResultBlock _ => 1, + _ => -1, + }; + } } sealed class BetaToolSearchToolResultBlockContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlockParam.cs index 163cec93d..f8d37d53e 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolSearchToolResultBlockParam.cs @@ -335,10 +335,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaToolSearchToolResultBlockParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaToolSearchToolResultBlockParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -347,6 +347,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaToolSearchToolResultErrorParam _ => 0, + BetaToolSearchToolSearchResultBlockParam _ => 1, + _ => -1, + }; + } } sealed class BetaToolSearchToolResultBlockParamContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolUnion.cs b/src/Anthropic/Models/Beta/Messages/BetaToolUnion.cs index 7fbf09172..54baa484b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolUnion.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolUnion.cs @@ -1011,10 +1011,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaToolUnion? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaToolUnion? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -1023,6 +1023,32 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaTool _ => 0, + BetaToolBash20241022 _ => 1, + BetaToolBash20250124 _ => 2, + BetaCodeExecutionTool20250522 _ => 3, + BetaCodeExecutionTool20250825 _ => 4, + BetaToolComputerUse20241022 _ => 5, + BetaMemoryTool20250818 _ => 6, + BetaToolComputerUse20250124 _ => 7, + BetaToolTextEditor20241022 _ => 8, + BetaToolComputerUse20251124 _ => 9, + BetaToolTextEditor20250124 _ => 10, + BetaToolTextEditor20250429 _ => 11, + BetaToolTextEditor20250728 _ => 12, + BetaWebSearchTool20250305 _ => 13, + BetaWebFetchTool20250910 _ => 14, + BetaToolSearchToolBm25_20251119 _ => 15, + BetaToolSearchToolRegex20251119 _ => 16, + BetaMcpToolset _ => 17, + _ => -1, + }; + } } sealed class BetaToolUnionConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolUseBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaToolUseBlock.cs index 8f476ae17..96014ef0f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolUseBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolUseBlock.cs @@ -324,10 +324,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaToolUseBlockCaller? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaToolUseBlockCaller? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -336,6 +336,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaDirectCaller _ => 0, + BetaServerToolCaller _ => 1, + _ => -1, + }; + } } sealed class BetaToolUseBlockCallerConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaToolUseBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaToolUseBlockParam.cs index 7062988a5..ceef1a724 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaToolUseBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaToolUseBlockParam.cs @@ -340,10 +340,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaToolUseBlockParamCaller? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaToolUseBlockParamCaller? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -352,6 +352,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaDirectCaller _ => 0, + BetaServerToolCaller _ => 1, + _ => -1, + }; + } } sealed class BetaToolUseBlockParamCallerConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlock.cs index 79c5f1c34..5d1f4f151 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlock.cs @@ -303,10 +303,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaWebFetchToolResultBlockContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaWebFetchToolResultBlockContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -315,6 +315,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaWebFetchToolResultErrorBlock _ => 0, + BetaWebFetchBlock _ => 1, + _ => -1, + }; + } } sealed class BetaWebFetchToolResultBlockContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlockParam.cs index 521020d80..1be24120d 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebFetchToolResultBlockParam.cs @@ -334,10 +334,10 @@ public override void Validate() ); } - public virtual bool Equals(BetaWebFetchToolResultBlockParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaWebFetchToolResultBlockParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -346,6 +346,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaWebFetchToolResultErrorBlockParam _ => 0, + BetaWebFetchBlockParam _ => 1, + _ => -1, + }; + } } sealed class BetaWebFetchToolResultBlockParamContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockContent.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockContent.cs index a49bab73a..fbad6425f 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockContent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockContent.cs @@ -199,10 +199,10 @@ public override void Validate() this.Switch((error) => error.Validate(), (_) => { }); } - public virtual bool Equals(BetaWebSearchToolResultBlockContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaWebSearchToolResultBlockContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -211,6 +211,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaWebSearchToolResultError _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class BetaWebSearchToolResultBlockContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockParamContent.cs b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockParamContent.cs index 2b23ffbd9..a170679ea 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockParamContent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaWebSearchToolResultBlockParamContent.cs @@ -199,10 +199,10 @@ public override void Validate() this.Switch((_) => { }, (requestError) => requestError.Validate()); } - public virtual bool Equals(BetaWebSearchToolResultBlockParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(BetaWebSearchToolResultBlockParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -211,6 +211,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + IReadOnlyList _ => 0, + BetaWebSearchToolRequestError _ => 1, + _ => -1, + }; + } } sealed class BetaWebSearchToolResultBlockParamContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/MessageBetaContentBlockSourceContent.cs b/src/Anthropic/Models/Beta/Messages/MessageBetaContentBlockSourceContent.cs index bd9334675..d0e679fb4 100644 --- a/src/Anthropic/Models/Beta/Messages/MessageBetaContentBlockSourceContent.cs +++ b/src/Anthropic/Models/Beta/Messages/MessageBetaContentBlockSourceContent.cs @@ -214,10 +214,10 @@ public override void Validate() ); } - public virtual bool Equals(MessageBetaContentBlockSourceContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(MessageBetaContentBlockSourceContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -226,6 +226,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaTextBlockParam _ => 0, + BetaImageBlockParam _ => 1, + _ => -1, + }; + } } sealed class MessageBetaContentBlockSourceContentConverter diff --git a/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs b/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs index 25f935b49..6352d9382 100644 --- a/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs +++ b/src/Anthropic/Models/Beta/Messages/MessageCountTokensParams.cs @@ -660,10 +660,10 @@ public override void Validate() } } - public virtual bool Equals(MessageCountTokensParamsSystem? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(MessageCountTokensParamsSystem? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -672,6 +672,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class MessageCountTokensParamsSystemConverter : JsonConverter @@ -1729,10 +1739,10 @@ public override void Validate() ); } - public virtual bool Equals(Tool? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Tool? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -1741,6 +1751,32 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaTool _ => 0, + BetaToolBash20241022 _ => 1, + BetaToolBash20250124 _ => 2, + BetaCodeExecutionTool20250522 _ => 3, + BetaCodeExecutionTool20250825 _ => 4, + BetaToolComputerUse20241022 _ => 5, + BetaMemoryTool20250818 _ => 6, + BetaToolComputerUse20250124 _ => 7, + BetaToolTextEditor20241022 _ => 8, + BetaToolComputerUse20251124 _ => 9, + BetaToolTextEditor20250124 _ => 10, + BetaToolTextEditor20250429 _ => 11, + BetaToolTextEditor20250728 _ => 12, + BetaWebSearchTool20250305 _ => 13, + BetaWebFetchTool20250910 _ => 14, + BetaToolSearchToolBm25_20251119 _ => 15, + BetaToolSearchToolRegex20251119 _ => 16, + BetaMcpToolset _ => 17, + _ => -1, + }; + } } sealed class ToolConverter : JsonConverter diff --git a/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs b/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs index 035ea81a6..7acf20104 100644 --- a/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs @@ -842,10 +842,10 @@ public override void Validate() this.Switch((betaContainerParams) => betaContainerParams.Validate(), (_) => { }); } - public virtual bool Equals(Container? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Container? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -854,6 +854,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaContainerParams _ => 0, + string _ => 1, + _ => -1, + }; + } } sealed class ContainerConverter : JsonConverter @@ -1145,10 +1155,10 @@ public override void Validate() } } - public virtual bool Equals(MessageCreateParamsSystem? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(MessageCreateParamsSystem? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -1157,6 +1167,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class MessageCreateParamsSystemConverter : JsonConverter diff --git a/src/Anthropic/Models/ErrorObject.cs b/src/Anthropic/Models/ErrorObject.cs index 7512a03de..8ac6bc2f9 100644 --- a/src/Anthropic/Models/ErrorObject.cs +++ b/src/Anthropic/Models/ErrorObject.cs @@ -490,10 +490,10 @@ public override void Validate() ); } - public virtual bool Equals(ErrorObject? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ErrorObject? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -502,6 +502,23 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + InvalidRequestError _ => 0, + AuthenticationError _ => 1, + BillingError _ => 2, + PermissionError _ => 3, + NotFoundError _ => 4, + RateLimitError _ => 5, + GatewayTimeoutError _ => 6, + ApiErrorObject _ => 7, + OverloadedError _ => 8, + _ => -1, + }; + } } sealed class ErrorObjectConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs index 6fc0d0532..b68471b2a 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs @@ -989,10 +989,10 @@ public override void Validate() } } - public virtual bool Equals(ParamsSystem? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ParamsSystem? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -1001,6 +1001,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class ParamsSystemConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/Batches/MessageBatchResult.cs b/src/Anthropic/Models/Messages/Batches/MessageBatchResult.cs index c2d13fd11..1512ce724 100644 --- a/src/Anthropic/Models/Messages/Batches/MessageBatchResult.cs +++ b/src/Anthropic/Models/Messages/Batches/MessageBatchResult.cs @@ -288,10 +288,10 @@ public override void Validate() ); } - public virtual bool Equals(MessageBatchResult? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(MessageBatchResult? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -300,6 +300,18 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + MessageBatchSucceededResult _ => 0, + MessageBatchErroredResult _ => 1, + MessageBatchCanceledResult _ => 2, + MessageBatchExpiredResult _ => 3, + _ => -1, + }; + } } sealed class MessageBatchResultConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/CitationsDelta.cs b/src/Anthropic/Models/Messages/CitationsDelta.cs index 399257ad5..a3f0a4620 100644 --- a/src/Anthropic/Models/Messages/CitationsDelta.cs +++ b/src/Anthropic/Models/Messages/CitationsDelta.cs @@ -502,10 +502,10 @@ public override void Validate() ); } - public virtual bool Equals(Citation? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Citation? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -514,6 +514,19 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + CitationCharLocation _ => 0, + CitationPageLocation _ => 1, + CitationContentBlockLocation _ => 2, + CitationsWebSearchResultLocation _ => 3, + CitationsSearchResultLocation _ => 4, + _ => -1, + }; + } } sealed class CitationConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/ContentBlock.cs b/src/Anthropic/Models/Messages/ContentBlock.cs index 6768b11d7..b456ed146 100644 --- a/src/Anthropic/Models/Messages/ContentBlock.cs +++ b/src/Anthropic/Models/Messages/ContentBlock.cs @@ -370,10 +370,10 @@ public override void Validate() ); } - public virtual bool Equals(ContentBlock? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ContentBlock? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -382,6 +382,20 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + TextBlock _ => 0, + ThinkingBlock _ => 1, + RedactedThinkingBlock _ => 2, + ToolUseBlock _ => 3, + ServerToolUseBlock _ => 4, + WebSearchToolResultBlock _ => 5, + _ => -1, + }; + } } sealed class ContentBlockConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/ContentBlockParam.cs b/src/Anthropic/Models/Messages/ContentBlockParam.cs index 3664b2144..0f7f7defa 100644 --- a/src/Anthropic/Models/Messages/ContentBlockParam.cs +++ b/src/Anthropic/Models/Messages/ContentBlockParam.cs @@ -594,10 +594,10 @@ public override void Validate() ); } - public virtual bool Equals(ContentBlockParam? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ContentBlockParam? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -606,6 +606,24 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + TextBlockParam _ => 0, + ImageBlockParam _ => 1, + DocumentBlockParam _ => 2, + SearchResultBlockParam _ => 3, + ThinkingBlockParam _ => 4, + RedactedThinkingBlockParam _ => 5, + ToolUseBlockParam _ => 6, + ToolResultBlockParam _ => 7, + ServerToolUseBlockParam _ => 8, + WebSearchToolResultBlockParam _ => 9, + _ => -1, + }; + } } sealed class ContentBlockParamConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/ContentBlockSource.cs b/src/Anthropic/Models/Messages/ContentBlockSource.cs index 4e0f8e333..65d7a209f 100644 --- a/src/Anthropic/Models/Messages/ContentBlockSource.cs +++ b/src/Anthropic/Models/Messages/ContentBlockSource.cs @@ -270,10 +270,10 @@ public override void Validate() } } - public virtual bool Equals(Content? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Content? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -282,6 +282,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class ContentConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/ContentBlockSourceContent.cs b/src/Anthropic/Models/Messages/ContentBlockSourceContent.cs index dd502b11e..7c0bc3ac7 100644 --- a/src/Anthropic/Models/Messages/ContentBlockSourceContent.cs +++ b/src/Anthropic/Models/Messages/ContentBlockSourceContent.cs @@ -204,10 +204,10 @@ public override void Validate() ); } - public virtual bool Equals(ContentBlockSourceContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ContentBlockSourceContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -216,6 +216,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + TextBlockParam _ => 0, + ImageBlockParam _ => 1, + _ => -1, + }; + } } sealed class ContentBlockSourceContentConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/DocumentBlockParam.cs b/src/Anthropic/Models/Messages/DocumentBlockParam.cs index 89ee7c9e4..311f10561 100644 --- a/src/Anthropic/Models/Messages/DocumentBlockParam.cs +++ b/src/Anthropic/Models/Messages/DocumentBlockParam.cs @@ -430,10 +430,10 @@ public override void Validate() ); } - public virtual bool Equals(Source? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Source? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -442,6 +442,18 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + Base64PdfSource _ => 0, + PlainTextSource _ => 1, + ContentBlockSource _ => 2, + UrlPdfSource _ => 3, + _ => -1, + }; + } } sealed class SourceConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/ImageBlockParam.cs b/src/Anthropic/Models/Messages/ImageBlockParam.cs index df49d2a21..febb6097f 100644 --- a/src/Anthropic/Models/Messages/ImageBlockParam.cs +++ b/src/Anthropic/Models/Messages/ImageBlockParam.cs @@ -286,10 +286,10 @@ public override void Validate() this.Switch((base64Image) => base64Image.Validate(), (urlImage) => urlImage.Validate()); } - public virtual bool Equals(ImageBlockParamSource? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ImageBlockParamSource? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -298,6 +298,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + Base64ImageSource _ => 0, + UrlImageSource _ => 1, + _ => -1, + }; + } } sealed class ImageBlockParamSourceConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/MessageCountTokensParams.cs b/src/Anthropic/Models/Messages/MessageCountTokensParams.cs index d2786ab62..951e04bbb 100644 --- a/src/Anthropic/Models/Messages/MessageCountTokensParams.cs +++ b/src/Anthropic/Models/Messages/MessageCountTokensParams.cs @@ -571,10 +571,10 @@ public override void Validate() } } - public virtual bool Equals(MessageCountTokensParamsSystem? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(MessageCountTokensParamsSystem? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -583,6 +583,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class MessageCountTokensParamsSystemConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/MessageCountTokensTool.cs b/src/Anthropic/Models/Messages/MessageCountTokensTool.cs index 5153bf77a..c306c41b5 100644 --- a/src/Anthropic/Models/Messages/MessageCountTokensTool.cs +++ b/src/Anthropic/Models/Messages/MessageCountTokensTool.cs @@ -374,10 +374,10 @@ public override void Validate() ); } - public virtual bool Equals(MessageCountTokensTool? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(MessageCountTokensTool? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -386,6 +386,20 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + Tool _ => 0, + ToolBash20250124 _ => 1, + ToolTextEditor20250124 _ => 2, + ToolTextEditor20250429 _ => 3, + ToolTextEditor20250728 _ => 4, + WebSearchTool20250305 _ => 5, + _ => -1, + }; + } } sealed class MessageCountTokensToolConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/MessageCreateParams.cs b/src/Anthropic/Models/Messages/MessageCreateParams.cs index 7340235c7..c9077850a 100644 --- a/src/Anthropic/Models/Messages/MessageCreateParams.cs +++ b/src/Anthropic/Models/Messages/MessageCreateParams.cs @@ -798,10 +798,10 @@ public override void Validate() } } - public virtual bool Equals(MessageCreateParamsSystem? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(MessageCreateParamsSystem? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -810,6 +810,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class MessageCreateParamsSystemConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/MessageParam.cs b/src/Anthropic/Models/Messages/MessageParam.cs index 3f30813c0..6bee6f0ec 100644 --- a/src/Anthropic/Models/Messages/MessageParam.cs +++ b/src/Anthropic/Models/Messages/MessageParam.cs @@ -255,10 +255,10 @@ public override void Validate() } } - public virtual bool Equals(MessageParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(MessageParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -267,6 +267,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class MessageParamContentConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/RawContentBlockDelta.cs b/src/Anthropic/Models/Messages/RawContentBlockDelta.cs index b98aaf887..b5e733e72 100644 --- a/src/Anthropic/Models/Messages/RawContentBlockDelta.cs +++ b/src/Anthropic/Models/Messages/RawContentBlockDelta.cs @@ -316,10 +316,10 @@ public override void Validate() ); } - public virtual bool Equals(RawContentBlockDelta? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(RawContentBlockDelta? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -328,6 +328,19 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + TextDelta _ => 0, + InputJsonDelta _ => 1, + CitationsDelta _ => 2, + ThinkingDelta _ => 3, + SignatureDelta _ => 4, + _ => -1, + }; + } } sealed class RawContentBlockDeltaConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/RawContentBlockStartEvent.cs b/src/Anthropic/Models/Messages/RawContentBlockStartEvent.cs index a17da2850..adcb637d1 100644 --- a/src/Anthropic/Models/Messages/RawContentBlockStartEvent.cs +++ b/src/Anthropic/Models/Messages/RawContentBlockStartEvent.cs @@ -486,10 +486,10 @@ public override void Validate() ); } - public virtual bool Equals(RawContentBlockStartEventContentBlock? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(RawContentBlockStartEventContentBlock? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -498,6 +498,20 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + TextBlock _ => 0, + ThinkingBlock _ => 1, + RedactedThinkingBlock _ => 2, + ToolUseBlock _ => 3, + ServerToolUseBlock _ => 4, + WebSearchToolResultBlock _ => 5, + _ => -1, + }; + } } sealed class RawContentBlockStartEventContentBlockConverter diff --git a/src/Anthropic/Models/Messages/RawMessageStreamEvent.cs b/src/Anthropic/Models/Messages/RawMessageStreamEvent.cs index f063cf83a..203eb03f2 100644 --- a/src/Anthropic/Models/Messages/RawMessageStreamEvent.cs +++ b/src/Anthropic/Models/Messages/RawMessageStreamEvent.cs @@ -373,10 +373,10 @@ public override void Validate() ); } - public virtual bool Equals(RawMessageStreamEvent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(RawMessageStreamEvent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -385,6 +385,20 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + RawMessageStartEvent _ => 0, + RawMessageDeltaEvent _ => 1, + RawMessageStopEvent _ => 2, + RawContentBlockStartEvent _ => 3, + RawContentBlockDeltaEvent _ => 4, + RawContentBlockStopEvent _ => 5, + _ => -1, + }; + } } sealed class RawMessageStreamEventConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/TextCitation.cs b/src/Anthropic/Models/Messages/TextCitation.cs index b044ac093..464956f42 100644 --- a/src/Anthropic/Models/Messages/TextCitation.cs +++ b/src/Anthropic/Models/Messages/TextCitation.cs @@ -421,10 +421,10 @@ public override void Validate() ); } - public virtual bool Equals(TextCitation? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(TextCitation? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -433,6 +433,19 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + CitationCharLocation _ => 0, + CitationPageLocation _ => 1, + CitationContentBlockLocation _ => 2, + CitationsWebSearchResultLocation _ => 3, + CitationsSearchResultLocation _ => 4, + _ => -1, + }; + } } sealed class TextCitationConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/TextCitationParam.cs b/src/Anthropic/Models/Messages/TextCitationParam.cs index e70886567..995844b80 100644 --- a/src/Anthropic/Models/Messages/TextCitationParam.cs +++ b/src/Anthropic/Models/Messages/TextCitationParam.cs @@ -418,10 +418,10 @@ public override void Validate() ); } - public virtual bool Equals(TextCitationParam? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(TextCitationParam? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -430,6 +430,19 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + CitationCharLocationParam _ => 0, + CitationPageLocationParam _ => 1, + CitationContentBlockLocationParam _ => 2, + CitationWebSearchResultLocationParam _ => 3, + CitationSearchResultLocationParam _ => 4, + _ => -1, + }; + } } sealed class TextCitationParamConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/ThinkingConfigParam.cs b/src/Anthropic/Models/Messages/ThinkingConfigParam.cs index e08c81c89..c80b05f07 100644 --- a/src/Anthropic/Models/Messages/ThinkingConfigParam.cs +++ b/src/Anthropic/Models/Messages/ThinkingConfigParam.cs @@ -200,10 +200,10 @@ public override void Validate() this.Switch((enabled) => enabled.Validate(), (disabled) => disabled.Validate()); } - public virtual bool Equals(ThinkingConfigParam? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ThinkingConfigParam? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -212,6 +212,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + ThinkingConfigEnabled _ => 0, + ThinkingConfigDisabled _ => 1, + _ => -1, + }; + } } sealed class ThinkingConfigParamConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/ToolChoice.cs b/src/Anthropic/Models/Messages/ToolChoice.cs index 0b5beee80..c62b5c819 100644 --- a/src/Anthropic/Models/Messages/ToolChoice.cs +++ b/src/Anthropic/Models/Messages/ToolChoice.cs @@ -292,10 +292,10 @@ public override void Validate() ); } - public virtual bool Equals(ToolChoice? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ToolChoice? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -304,6 +304,18 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + ToolChoiceAuto _ => 0, + ToolChoiceAny _ => 1, + ToolChoiceTool _ => 2, + ToolChoiceNone _ => 3, + _ => -1, + }; + } } sealed class ToolChoiceConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/ToolResultBlockParam.cs b/src/Anthropic/Models/Messages/ToolResultBlockParam.cs index 514a22bde..4f068cca6 100644 --- a/src/Anthropic/Models/Messages/ToolResultBlockParam.cs +++ b/src/Anthropic/Models/Messages/ToolResultBlockParam.cs @@ -317,10 +317,10 @@ public override void Validate() } } - public virtual bool Equals(ToolResultBlockParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ToolResultBlockParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -329,6 +329,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + string _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class ToolResultBlockParamContentConverter : JsonConverter @@ -669,10 +679,10 @@ public override void Validate() ); } - public virtual bool Equals(Block? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(Block? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -681,6 +691,18 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + TextBlockParam _ => 0, + ImageBlockParam _ => 1, + SearchResultBlockParam _ => 2, + DocumentBlockParam _ => 3, + _ => -1, + }; + } } sealed class BlockConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/ToolUnion.cs b/src/Anthropic/Models/Messages/ToolUnion.cs index 47f71a892..e6f717ea1 100644 --- a/src/Anthropic/Models/Messages/ToolUnion.cs +++ b/src/Anthropic/Models/Messages/ToolUnion.cs @@ -368,10 +368,10 @@ public override void Validate() ); } - public virtual bool Equals(ToolUnion? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(ToolUnion? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -380,6 +380,20 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + Tool _ => 0, + ToolBash20250124 _ => 1, + ToolTextEditor20250124 _ => 2, + ToolTextEditor20250429 _ => 3, + ToolTextEditor20250728 _ => 4, + WebSearchTool20250305 _ => 5, + _ => -1, + }; + } } sealed class ToolUnionConverter : JsonConverter diff --git a/src/Anthropic/Models/Messages/WebSearchToolResultBlockContent.cs b/src/Anthropic/Models/Messages/WebSearchToolResultBlockContent.cs index 721525c3f..3d93f86ca 100644 --- a/src/Anthropic/Models/Messages/WebSearchToolResultBlockContent.cs +++ b/src/Anthropic/Models/Messages/WebSearchToolResultBlockContent.cs @@ -199,10 +199,10 @@ public override void Validate() this.Switch((error) => error.Validate(), (_) => { }); } - public virtual bool Equals(WebSearchToolResultBlockContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(WebSearchToolResultBlockContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -211,6 +211,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + WebSearchToolResultError _ => 0, + IReadOnlyList _ => 1, + _ => -1, + }; + } } sealed class WebSearchToolResultBlockContentConverter diff --git a/src/Anthropic/Models/Messages/WebSearchToolResultBlockParamContent.cs b/src/Anthropic/Models/Messages/WebSearchToolResultBlockParamContent.cs index 6188dadaa..732cf4667 100644 --- a/src/Anthropic/Models/Messages/WebSearchToolResultBlockParamContent.cs +++ b/src/Anthropic/Models/Messages/WebSearchToolResultBlockParamContent.cs @@ -197,10 +197,10 @@ public override void Validate() this.Switch((_) => { }, (requestError) => requestError.Validate()); } - public virtual bool Equals(WebSearchToolResultBlockParamContent? other) - { - return other != null && JsonElement.DeepEquals(this.Json, other.Json); - } + public virtual bool Equals(WebSearchToolResultBlockParamContent? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); public override int GetHashCode() { @@ -209,6 +209,16 @@ public override int GetHashCode() public override string ToString() => JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + IReadOnlyList _ => 0, + WebSearchToolRequestError _ => 1, + _ => -1, + }; + } } sealed class WebSearchToolResultBlockParamContentConverter From 40c5d160061025fc92112e92cb71af85a5f4ac9c Mon Sep 17 00:00:00 2001 From: dtmeadows Date: Tue, 3 Feb 2026 09:38:28 -0500 Subject: [PATCH 29/41] chore(ci): remove claude-code-review workflow Co-authored-by: Claude Code (/Users/davidmeadows/stainless/stainless) --- .github/workflows/claude-code-review.yml | 57 ------------------------ 1 file changed, 57 deletions(-) delete mode 100644 .github/workflows/claude-code-review.yml diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml deleted file mode 100644 index a4c8f6a89..000000000 --- a/.github/workflows/claude-code-review.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Claude Code Review - -on: - pull_request: - types: [opened, synchronize] - # Optional: Only run on specific file changes - # paths: - # - "src/**/*.ts" - # - "src/**/*.tsx" - # - "src/**/*.js" - # - "src/**/*.jsx" - -jobs: - claude-review: - # Optional: Filter by PR author - # if: | - # github.event.pull_request.user.login == 'external-contributor' || - # github.event.pull_request.user.login == 'new-developer' || - # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' - - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: read - issues: read - id-token: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 1 - - - name: Run Claude Code Review - id: claude-review - uses: anthropics/claude-code-action@v1 - with: - anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} - prompt: | - REPO: ${{ github.repository }} - PR NUMBER: ${{ github.event.pull_request.number }} - - Please review this pull request and provide feedback on: - - Code quality and best practices - - Potential bugs or issues - - Performance considerations - - Security concerns - - Test coverage - - Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback. - - Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR. - - # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md - # or https://code.claude.com/docs/en/cli-reference for available options - claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"' - From a8dfc47ba5056aef142e3fca42d4a0c2c228748e Mon Sep 17 00:00:00 2001 From: Stephen Date: Tue, 3 Feb 2026 10:19:05 -0500 Subject: [PATCH 30/41] fix the build (#106) --- examples/MessagesExample/Program.cs | 4 ++-- src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/MessagesExample/Program.cs b/examples/MessagesExample/Program.cs index 00bd14f20..80aa0ee10 100644 --- a/examples/MessagesExample/Program.cs +++ b/examples/MessagesExample/Program.cs @@ -22,8 +22,8 @@ var message = string.Join( "", response - .Content.Where(message => message.Value is TextBlock) - .Select(message => message.Value as TextBlock) + .Content.Select(message => message.Value) + .OfType() .Select((textBlock) => textBlock.Text) ); diff --git a/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs b/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs index 3431ebad8..a8501efe0 100644 --- a/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs +++ b/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs @@ -8,9 +8,9 @@ public interface IAnthropicFoundryCredentials void Apply(HttpRequestMessage requestMessage); #if NET8_0_OR_GREATER - public static async ValueTask FromEnv() + public static IAnthropicFoundryCredentials? FromEnv() { - return await DefaultAnthropicFoundryCredentials.FromEnv().ConfigureAwait(false); + return DefaultAnthropicFoundryCredentials.FromEnv(); } #endif } @@ -33,7 +33,7 @@ public class DefaultAnthropicFoundryCredentials /// /// The resource name or if null loaded from the environment variable ANTHROPIC_FOUNDRY_RESOURCE /// - public static async ValueTask FromEnv( + public static IAnthropicFoundryCredentials? FromEnv( string? resourceName = null ) { From b24775028a0f3bb0423078b58c176c6df9648e7f Mon Sep 17 00:00:00 2001 From: Stephen Date: Tue, 3 Feb 2026 10:56:33 -0500 Subject: [PATCH 31/41] lint fix (#107) --- src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs b/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs index a8501efe0..553bd4cfb 100644 --- a/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs +++ b/src/Anthropic.Foundry/IAnthropicFoundryCredentials.cs @@ -33,9 +33,7 @@ public class DefaultAnthropicFoundryCredentials /// /// The resource name or if null loaded from the environment variable ANTHROPIC_FOUNDRY_RESOURCE /// - public static IAnthropicFoundryCredentials? FromEnv( - string? resourceName = null - ) + public static IAnthropicFoundryCredentials? FromEnv(string? resourceName = null) { if ( Environment.GetEnvironmentVariable("ANTHROPIC_FOUNDRY_RESOURCE") From c54884b15e2fc3216a803adbc8914aa41d8b8e89 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Wed, 4 Feb 2026 19:24:13 +0100 Subject: [PATCH 32/41] Add Bedrock as provider for SDK (#77) * SSE implementation * Add aws cred store * Adapt AWS authentication * Fix Streaming for bedrock * Add nuget stubs * Lint files * Update code comments * Add support for netstandard to bedrock Removed Async streaming implementation * Format code * Cleanup code * make mr linter happy * Fix net9 specific optimizations * Apply review comments * Fix linting issues * applied review comments * Remove argument check * Remove unused code * Adapt method header NetStandard switch * lint code * Fix merge conflicts from source * Apply review comments * Removed unused method * Apply code review changes * Add bedrock example * rename event stream helper * linting * remove incorrectly added example project * fix build * Fix tests * fix build and lint * apply review comments * revert merge conflict issue * lint * Split examples into multiple projects for bedrock, anthropic and foundry * apply review comments * Remove bedrock from general testing loop as currently unsupported by test tool * Update Examples * lint * Cleanup examples * update comment * update exception * Update src/Anthropic.Bedrock/LocalShims.cs * combine if statements * fix lint? --------- Co-authored-by: Stephen --- Anthropic.sln | 15 + examples/Anthropic.Examples.sln | 28 ++ .../MessagesExample.Bedrock.csproj | 16 + examples/MessagesExample.Bedrock/Program.cs | 40 +++ .../MessagesExample.Foundry.csproj | 15 + examples/MessagesExample.Foundry/Program.cs | 34 +++ .../MessagesExample/MessagesExample.csproj | 1 - examples/MessagesExample/Program.cs | 3 - .../Anthropic.Bedrock.csproj | 26 ++ .../AnthropicBedrockApiTokenCredentials.cs | 33 ++ .../AnthropicBedrockClient.cs | 281 ++++++++++++++++++ .../AnthropicBedrockCredentialsHelper.cs | 87 ++++++ .../AnthropicBedrockPrivateKeyCredentials.cs | 59 ++++ .../AwsEventStreamHelpers.cs | 166 +++++++++++ src/Anthropic.Bedrock/AwsSigner.cs | 174 +++++++++++ .../IAnthropicBedrockCredentials.cs | 26 ++ src/Anthropic.Bedrock/LocalShims.cs | 104 +++++++ .../SseEventContentWrapper.cs | 132 ++++++++ src/Anthropic.Tests/Anthropic.Tests.csproj | 4 +- src/Anthropic.Tests/AnthropicTestClients.cs | 33 +- .../Services/Beta/FileServiceTest.cs | 6 +- .../Beta/Messages/BatchServiceTest.cs | 12 +- .../Services/MessageServiceTest.cs | 7 +- .../Services/Messages/BatchServiceTest.cs | 12 +- src/Anthropic/Shims.cs | 2 - 25 files changed, 1287 insertions(+), 29 deletions(-) create mode 100644 examples/MessagesExample.Bedrock/MessagesExample.Bedrock.csproj create mode 100644 examples/MessagesExample.Bedrock/Program.cs create mode 100644 examples/MessagesExample.Foundry/MessagesExample.Foundry.csproj create mode 100644 examples/MessagesExample.Foundry/Program.cs create mode 100644 src/Anthropic.Bedrock/Anthropic.Bedrock.csproj create mode 100644 src/Anthropic.Bedrock/AnthropicBedrockApiTokenCredentials.cs create mode 100644 src/Anthropic.Bedrock/AnthropicBedrockClient.cs create mode 100644 src/Anthropic.Bedrock/AnthropicBedrockCredentialsHelper.cs create mode 100644 src/Anthropic.Bedrock/AnthropicBedrockPrivateKeyCredentials.cs create mode 100644 src/Anthropic.Bedrock/AwsEventStreamHelpers.cs create mode 100644 src/Anthropic.Bedrock/AwsSigner.cs create mode 100644 src/Anthropic.Bedrock/IAnthropicBedrockCredentials.cs create mode 100644 src/Anthropic.Bedrock/LocalShims.cs create mode 100644 src/Anthropic.Bedrock/SseEventContentWrapper.cs diff --git a/Anthropic.sln b/Anthropic.sln index 4fbe89c82..15013d25c 100644 --- a/Anthropic.sln +++ b/Anthropic.sln @@ -11,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Anthropic.Foundry", "src\Anthropic.Foundry\Anthropic.Foundry.csproj", "{DD0E539D-6D5F-45EB-A807-01BE0A443604}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Anthropic.Bedrock", "src\Anthropic.Bedrock\Anthropic.Bedrock.csproj", "{72FC9906-07F4-4911-8D6B-F9814974BB37}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{93E58BA5-CEFE-447E-AC0C-F2C5BC4C411D}" ProjectSection(SolutionItems) = preProject CHANGELOG.md @@ -68,6 +70,18 @@ Global {DD0E539D-6D5F-45EB-A807-01BE0A443604}.Release|x64.Build.0 = Release|Any CPU {DD0E539D-6D5F-45EB-A807-01BE0A443604}.Release|x86.ActiveCfg = Release|Any CPU {DD0E539D-6D5F-45EB-A807-01BE0A443604}.Release|x86.Build.0 = Release|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Debug|x64.ActiveCfg = Debug|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Debug|x64.Build.0 = Debug|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Debug|x86.ActiveCfg = Debug|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Debug|x86.Build.0 = Debug|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|Any CPU.Build.0 = Release|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|x64.ActiveCfg = Release|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|x64.Build.0 = Release|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|x86.ActiveCfg = Release|Any CPU + {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -76,5 +90,6 @@ Global {5816A0C1-3BA1-454E-8D08-85B23DEF309D} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {0732C8A6-7313-4C33-AE2E-FFAA82EFB481} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {DD0E539D-6D5F-45EB-A807-01BE0A443604} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} + {72FC9906-07F4-4911-8D6B-F9814974BB37} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} EndGlobalSection EndGlobal diff --git a/examples/Anthropic.Examples.sln b/examples/Anthropic.Examples.sln index c5f116adf..933d318b9 100644 --- a/examples/Anthropic.Examples.sln +++ b/examples/Anthropic.Examples.sln @@ -13,6 +13,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagesStreamingExample", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatClientExample", "ChatClientExample\ChatClientExample.csproj", "{AA6ED2E6-A693-4FD8-AF20-1D339FBFBF96}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagesExample.Foundry", "MessagesExample.Foundry\MessagesExample.Foundry.csproj", "{5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagesExample.Bedrock", "MessagesExample.Bedrock\MessagesExample.Bedrock.csproj", "{7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -83,6 +87,30 @@ Global {AA6ED2E6-A693-4FD8-AF20-1D339FBFBF96}.Release|x64.Build.0 = Release|Any CPU {AA6ED2E6-A693-4FD8-AF20-1D339FBFBF96}.Release|x86.ActiveCfg = Release|Any CPU {AA6ED2E6-A693-4FD8-AF20-1D339FBFBF96}.Release|x86.Build.0 = Release|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Debug|x64.ActiveCfg = Debug|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Debug|x64.Build.0 = Debug|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Debug|x86.ActiveCfg = Debug|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Debug|x86.Build.0 = Debug|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Release|Any CPU.Build.0 = Release|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Release|x64.ActiveCfg = Release|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Release|x64.Build.0 = Release|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Release|x86.ActiveCfg = Release|Any CPU + {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Release|x86.Build.0 = Release|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Debug|x64.ActiveCfg = Debug|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Debug|x64.Build.0 = Debug|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Debug|x86.ActiveCfg = Debug|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Debug|x86.Build.0 = Debug|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Release|Any CPU.Build.0 = Release|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Release|x64.ActiveCfg = Release|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Release|x64.Build.0 = Release|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Release|x86.ActiveCfg = Release|Any CPU + {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/examples/MessagesExample.Bedrock/MessagesExample.Bedrock.csproj b/examples/MessagesExample.Bedrock/MessagesExample.Bedrock.csproj new file mode 100644 index 000000000..85699315d --- /dev/null +++ b/examples/MessagesExample.Bedrock/MessagesExample.Bedrock.csproj @@ -0,0 +1,16 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + diff --git a/examples/MessagesExample.Bedrock/Program.cs b/examples/MessagesExample.Bedrock/Program.cs new file mode 100644 index 000000000..2908304bd --- /dev/null +++ b/examples/MessagesExample.Bedrock/Program.cs @@ -0,0 +1,40 @@ +using Amazon.Runtime.Credentials.Internal; +using Anthropic.Bedrock; +using Anthropic.Models.Messages; + +// Create a new AnthropicBedrockClient +// Options for the AnthropicBedrockClient constructor parameter (implements IAnthropicBedrockCredentials): + +// - AnthropicBedrockApiTokenCredentials — bearer-token auth (sets Authorization: bearer ) plus Region. +// - AnthropicBedrockPrivateKeyCredentials — access-key/secret-key auth (for AWS-signed requests) plus Region. +// - AnthropicBedrockCredentialsHelper.FromEnv() — helper that returns either of the above by reading AWS env vars / default credential chain. +// The CredentialsHelper tries to get the region and token from two enviorment variables: +// - "AWS_BEARER_TOKEN_BEDROCK" +// - "AWS_REGION" +// if both of those are not set, it uses the Azure SDK to load system configuration as described here: https://learn.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet +// - Any custom type that implements IAnthropicBedrockCredentials — implement Region and Apply(HttpRequestMessage) for custom auth. +AnthropicBedrockClient client = new( + await AnthropicBedrockCredentialsHelper.FromEnv().ConfigureAwait(false) + ?? throw new InvalidOperationException("Your system is not properly configured.") +); +MessageCreateParams parameters = new() +{ + MaxTokens = 2048, + Messages = + [ + new() { Content = "Tell me a story about building the best SDK!", Role = Role.User }, + ], + Model = "global.anthropic.claude-haiku-4-5-20251001-v1:0", +}; + +var response = await client.Messages.Create(parameters); + +var message = string.Join( + "", + response + .Content.Where(message => message.Value is TextBlock) + .Select(message => message.Value as TextBlock) + .Select((textBlock) => textBlock.Text) +); + +Console.WriteLine(message); diff --git a/examples/MessagesExample.Foundry/MessagesExample.Foundry.csproj b/examples/MessagesExample.Foundry/MessagesExample.Foundry.csproj new file mode 100644 index 000000000..33113c3fb --- /dev/null +++ b/examples/MessagesExample.Foundry/MessagesExample.Foundry.csproj @@ -0,0 +1,15 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + diff --git a/examples/MessagesExample.Foundry/Program.cs b/examples/MessagesExample.Foundry/Program.cs new file mode 100644 index 000000000..f6ed87259 --- /dev/null +++ b/examples/MessagesExample.Foundry/Program.cs @@ -0,0 +1,34 @@ +using Anthropic.Foundry; +using Anthropic.Models.Messages; + +// Create a new AnthropicFoundryClient. +// The constructor accepts any IAnthropicFoundryCredentials implementation: +// - AnthropicFoundryApiKeyCredentials(apiKey, resourceName): adds an x-api-key header. +// - AnthropicFoundryBearerTokenCredentials(token, resourceName): sets Authorization: bearer token. +// - AnthropicFoundryIdentityTokenCredentials(AccessToken, resourceName): uses an Azure Identity access token. +// You can also obtain credentials from environment/Azure via DefaultAnthropicFoundryCredentials.FromEnv(). +AnthropicFoundryClient client = new( + new AnthropicFoundryApiKeyCredentials("API-TOKEN", "RESOURCE-NAME") +); + +MessageCreateParams parameters = new() +{ + MaxTokens = 2048, + Messages = + [ + new() { Content = "Tell me a story about building the best SDK!", Role = Role.User }, + ], + Model = "claude-sonnet-4-5", +}; + +var response = await client.Messages.Create(parameters); + +var message = string.Join( + "", + response + .Content.Where(message => message.Value is TextBlock) + .Select(message => message.Value as TextBlock) + .Select((textBlock) => textBlock.Text) +); + +Console.WriteLine(message); diff --git a/examples/MessagesExample/MessagesExample.csproj b/examples/MessagesExample/MessagesExample.csproj index 53318fa98..2875a6802 100644 --- a/examples/MessagesExample/MessagesExample.csproj +++ b/examples/MessagesExample/MessagesExample.csproj @@ -7,6 +7,5 @@ - diff --git a/examples/MessagesExample/Program.cs b/examples/MessagesExample/Program.cs index 80aa0ee10..a81cd60c0 100644 --- a/examples/MessagesExample/Program.cs +++ b/examples/MessagesExample/Program.cs @@ -4,9 +4,6 @@ // Configured using the ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN and ANTHROPIC_BASE_URL environment variables var client = new AnthropicClient(); -// For using the Foundry client, use this instead -// AnthropicFoundryClient client = new(new AnthropicFoundryApiKeyCredentials("API-TOKEN", "RESOURCE-NAME")); - MessageCreateParams parameters = new() { MaxTokens = 2048, diff --git a/src/Anthropic.Bedrock/Anthropic.Bedrock.csproj b/src/Anthropic.Bedrock/Anthropic.Bedrock.csproj new file mode 100644 index 000000000..4c993ab5e --- /dev/null +++ b/src/Anthropic.Bedrock/Anthropic.Bedrock.csproj @@ -0,0 +1,26 @@ + + + + net9.0;net8.0;netstandard2.0 + enable + enable + 13.0 + + Anthropic.Bedrock + 0.1.0 + + + + + + + + + + + + + + + + diff --git a/src/Anthropic.Bedrock/AnthropicBedrockApiTokenCredentials.cs b/src/Anthropic.Bedrock/AnthropicBedrockApiTokenCredentials.cs new file mode 100644 index 000000000..e473d6a5d --- /dev/null +++ b/src/Anthropic.Bedrock/AnthropicBedrockApiTokenCredentials.cs @@ -0,0 +1,33 @@ +namespace Anthropic.Bedrock; + +/// +/// Provides bearer token-based authentication credentials for accessing Amazon Bedrock Anthropic API. +/// +/// +/// This class implements the interface to support +/// authentication using a bearer token and AWS region for Anthropic API requests through Amazon Bedrock. +/// The bearer token is applied to the Authorization header of HTTP requests. +/// +public sealed class AnthropicBedrockApiTokenCredentials : IAnthropicBedrockCredentials +{ + /// + /// Gets the bearer token used for authentication with the Anthropic Bedrock API. + /// + /// + /// A string representing the bearer token. This value is set privately and can only be modified within the class. + /// + public required string BearerToken { get; init; } + + /// + /// Gets the AWS region. + /// + public required string Region { get; init; } + + /// + public Task Apply(HttpRequestMessage requestMessage) + { + requestMessage.Headers.Authorization = + new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", BearerToken); + return Task.CompletedTask; + } +} diff --git a/src/Anthropic.Bedrock/AnthropicBedrockClient.cs b/src/Anthropic.Bedrock/AnthropicBedrockClient.cs new file mode 100644 index 000000000..2dfbc2009 --- /dev/null +++ b/src/Anthropic.Bedrock/AnthropicBedrockClient.cs @@ -0,0 +1,281 @@ +using System.Buffers; +using System.Text.Json; +using System.Text.Json.Nodes; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Bedrock; + +/// +/// Provides an Anthropic client implementation for AWS Bedrock integration. +/// +public sealed class AnthropicBedrockClient : AnthropicClient +{ + private const string ServiceName = "bedrock-runtime"; + + private readonly IAnthropicBedrockCredentials _bedrockCredentials; + private readonly Lazy _withRawResponse; + + /// + /// Creates a new Instance of the . + /// + /// The credential Provider used to authenticate with the AWS Bedrock service. + public AnthropicBedrockClient(IAnthropicBedrockCredentials bedrockCredentials) + : base() + { + _bedrockCredentials = bedrockCredentials; + BaseUrl = $"https://{ServiceName}.{_bedrockCredentials.Region}.amazonaws.com"; + _withRawResponse = new(() => + new AnthropicBedrockClientWithRawResponse(_bedrockCredentials, _options) + ); + } + + private AnthropicBedrockClient( + IAnthropicBedrockCredentials bedrockCredentials, + ClientOptions clientOptions + ) + : base(clientOptions) + { + _bedrockCredentials = bedrockCredentials; + _withRawResponse = new(() => + new AnthropicBedrockClientWithRawResponse(_bedrockCredentials, _options) + ); + } + + /// + public override IAnthropicClient WithOptions(Func modifier) + { + return new AnthropicBedrockClient(_bedrockCredentials, modifier(this._options)); + } + + public override IAnthropicClientWithRawResponse WithRawResponse => _withRawResponse.Value; +} + +internal class AnthropicBedrockClientWithRawResponse : AnthropicClientWithRawResponse +{ + private readonly IAnthropicBedrockCredentials _credentials; + private const string AnthropicVersion = "bedrock-2023-05-31"; + private const string HeaderAnthropicBeta = "anthropic-beta"; + + /// + /// The name of the header that identifies the content type for the "payloads" of AWS + /// EventStream messages in streaming responses from Bedrock. + /// + private const string HeaderPayloadContentType = "x-amzn-bedrock-content-type"; + + /// + /// The content type for Bedrock responses containing data in the AWS EventStream format. + /// The value of the Content-Type header identifies the content type of the + /// "payloads" in this stream. + /// + private const string ContentTypeAwsEventStream = "application/vnd.amazon.eventstream"; + + /// + /// The content type for Anthropic responses containing Bedrock data after it has been + /// translated into the Server-Sent Events (SSE) stream format. + /// + private const string ContentTypeSseStreamMediaType = "text/event-stream"; + + public AnthropicBedrockClientWithRawResponse( + IAnthropicBedrockCredentials credentials, + ClientOptions clientOptions + ) + : base(clientOptions) + { + _credentials = credentials; + } + + /// + public override IAnthropicClientWithRawResponse WithOptions( + Func modifier + ) + { + return new AnthropicBedrockClientWithRawResponse(_credentials, modifier(this._options)); + } + + /// + protected override async ValueTask BeforeSend( + HttpRequest request, + HttpRequestMessage requestMessage, + CancellationToken cancellationToken + ) + { + ValidateRequest(requestMessage); + + if (requestMessage.Content is not null) + { + var bodyContent = JsonNode.Parse( + await requestMessage.Content!.ReadAsStringAsync( +#if NET + cancellationToken +#endif + ).ConfigureAwait(false) + )!; + + var betaVersions = requestMessage.Headers.Contains(HeaderAnthropicBeta) + ? requestMessage.Headers.GetValues(HeaderAnthropicBeta).Distinct().ToArray() + : []; + if (betaVersions is not { Length: 0 }) + { + bodyContent["anthropic_beta"] = new JsonArray( + [.. betaVersions.Select(v => JsonValue.Create(v))] + ); + } + + bodyContent["anthropic_version"] = JsonValue.Create(AnthropicVersion); + + var modelValue = bodyContent["model"]!; + bodyContent.Root.AsObject().Remove("model"); + var parsedStreamValue = ((bool?)bodyContent["stream"]?.AsValue()) ?? false; + bodyContent.Root.AsObject().Remove("stream"); + + var contentStream = new MemoryStream(); + requestMessage.Content = new StreamContent(contentStream); + using var writer = new Utf8JsonWriter(contentStream); + { + bodyContent.WriteTo(writer); + await writer.FlushAsync(cancellationToken).ConfigureAwait(false); + } + contentStream.Seek(0, SeekOrigin.Begin); + requestMessage.Headers.TryAddWithoutValidation( + "content-length", + contentStream.Length.ToString() + ); + var strUri = + $"{requestMessage.RequestUri!.Scheme}://{requestMessage.RequestUri.Host}/model/{modelValue}/{(parsedStreamValue ? "invoke-with-response-stream" : "invoke")}"; + +#if NET6_0_OR_GREATER + // The UriCreationOptions and DangerousDisablePathAndQueryCanonicalization were added in .NET 6 and allows + // us to turn off the Uri behavior of canonicalizing Uri. For example if the resource path was "foo/../bar.txt" + // the URI class will change the canonicalize path to bar.txt. This behavior of changing the Uri after the + // request has been signed will trigger a signature mismatch error. It is valid especially for S3 for the resource + // path to contain ".." segments. + + // as this is only available in net8 or greater we can only enable it there. NetStandard may not support those paths + var uriCreationOptions = new UriCreationOptions() + { + DangerousDisablePathAndQueryCanonicalization = true, + }; + + requestMessage.RequestUri = new Uri(strUri, uriCreationOptions); +#else + requestMessage.RequestUri = new Uri(strUri); +#endif + + requestMessage.Headers.TryAddWithoutValidation("Host", requestMessage.RequestUri.Host); + requestMessage.Headers.TryAddWithoutValidation( + "X-Amzn-Bedrock-Accept", + "application/json" + ); + requestMessage.Headers.TryAddWithoutValidation("content-type", "application/json"); + if (parsedStreamValue) + { + requestMessage.Headers.TryAddWithoutValidation("Accept-Encoding", "gzip"); + } + } + + await _credentials.Apply(requestMessage).ConfigureAwait(false); + } + + private static void ValidateRequest(HttpRequestMessage requestMessage) + { + if (requestMessage.RequestUri is null || requestMessage.RequestUri.Segments.Length < 1) + { + throw new AnthropicInvalidDataException( + "Request is missing required path segments. Expected > 1 segments, found none." + ); + } + + if (requestMessage.RequestUri.Segments[1].Trim('/') != "v1") + { + throw new AnthropicInvalidDataException( + $"Request is missing required path segments. Expected [0] segment to be 'v1', found {requestMessage.RequestUri.Segments[0]}." + ); + } + + if ( + requestMessage.RequestUri.Segments.Length >= 4 + && requestMessage.RequestUri.Segments[2].Trim('/') is "messages" + && requestMessage.RequestUri.Segments[3].Trim('/') is "batches" or "count_tokens" + ) + { + throw new AnthropicInvalidDataException( + $"The requested endpoint '{requestMessage.RequestUri.Segments[3].Trim('/')}' is not yet supported." + ); + } + } + + /// + protected override async ValueTask AfterSend( + HttpRequest request, + HttpResponseMessage httpResponseMessage, + CancellationToken cancellationToken + ) + { + if (!httpResponseMessage.IsSuccessStatusCode) + { + return; + } + + if ( + !string.Equals( + httpResponseMessage.Content.Headers.ContentType?.MediaType, + ContentTypeAwsEventStream, + StringComparison.CurrentCultureIgnoreCase + ) + ) + { + return; + } + + var headerPayloads = httpResponseMessage.Headers.GetValues(HeaderPayloadContentType); + + if ( + !headerPayloads.Any(f => + f.Equals("application/json", StringComparison.OrdinalIgnoreCase) + ) + ) + { + throw new AnthropicInvalidDataException( + $"Expected streaming bedrock events to have content type of application/json but found {string.Join(", ", headerPayloads)}" + ); + } + + // A decoded AWS EventStream message's payload is JSON. It might look like this (abridged): + // + // {"bytes":"eyJ0eXBlIjoi...ZXJlIn19","p":"abcdefghijkl"} + // + // The value of the "bytes" field is a base-64 encoded JSON string (UTF-8). When decoded, it + // might look like this: + // + // {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}} + // + // Parse the "type" field to allow the construction of a server-sent event (SSE) that might + // look like this: + // + // event: content_block_delta + // data: + // {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}} + // + // Print the SSE (with a blank line after) to the piped output stream to complete the + // translation process. + + var originalStream = await httpResponseMessage + .Content.ReadAsStreamAsync( +#if NET + cancellationToken +#endif + ) + .ConfigureAwait(false); + httpResponseMessage.Content = new SseEventContentWrapper(originalStream); + + httpResponseMessage.Content.Headers.ContentType = new( +#if NET + ContentTypeSseStreamMediaType, + "utf-8" +#else + $"{ContentTypeSseStreamMediaType}; charset=utf-8" +#endif + ); + } +} diff --git a/src/Anthropic.Bedrock/AnthropicBedrockCredentialsHelper.cs b/src/Anthropic.Bedrock/AnthropicBedrockCredentialsHelper.cs new file mode 100644 index 000000000..e0a2434db --- /dev/null +++ b/src/Anthropic.Bedrock/AnthropicBedrockCredentialsHelper.cs @@ -0,0 +1,87 @@ +using Amazon.Runtime; +using Amazon.Runtime.Credentials; + +namespace Anthropic.Bedrock; + +//// +/// Asynchronously creates an IAnthropicBedrockCredentials instance by inspecting environment variables +/// and falling back to the AWS default credential resolution chain. +/// +/// +/// A that resolves to an IAnthropicBedrockCredentials when credentials +/// are successfully discovered; otherwise null. +/// +/// +/// Behavior details: +/// - Environment variables: +/// - AWS_BEARER_TOKEN_BEDROCK: when present and non-empty, used to construct AnthropicBedrockApiTokenCredentials. +/// - AWS_REGION: used as the Bedrock region. If not set, this method consults FallbackRegionFactory. +/// - If no bearer token is found, the method queries DefaultAWSCredentialsIdentityResolver for credentials. +/// - If the returned credentials indicate UseToken, the session token is used to create +/// AnthropicBedrockApiTokenCredentials. +/// - Otherwise the access key and secret key are used to create AnthropicBedrockPrivateKeyCredentials. +/// - The method returns null in scenarios where the region cannot be determined or no credentials are available. +/// - The method performs asynchronous credential resolution and should be awaited. +/// +/// +/// // Example usage: +/// // var creds = await AnthropicBedrockCredentialsHelper.FromEnv(); +/// // if (creds == null) { /* handle missing credentials */ } +/// +public static class AnthropicBedrockCredentialsHelper +{ + public static async ValueTask FromEnv() + { + const string ENV_API_KEY = "AWS_BEARER_TOKEN_BEDROCK"; + const string ENV_REGION = "AWS_REGION"; + + var region = Environment.GetEnvironmentVariable(ENV_REGION); + if (region is null) + { + var defaultRegion = FallbackRegionFactory.GetRegionEndpoint(false); + if (defaultRegion is null) + { + return null; + } + region = defaultRegion.HostnameTemplate; + } + + var token = Environment.GetEnvironmentVariable(ENV_API_KEY); + if (!string.IsNullOrWhiteSpace(token)) + { + return new AnthropicBedrockApiTokenCredentials() + { + BearerToken = token, + Region = region, + }; + } + + var defaultIdentity = DefaultAWSCredentialsIdentityResolver.GetCredentials(); + if (defaultIdentity is null) + { + return null; + } + + var defaultCreds = await defaultIdentity.GetCredentialsAsync().ConfigureAwait(false); + if (defaultCreds is null) + { + return null; + } + + if (defaultCreds.UseToken) + { + return new AnthropicBedrockApiTokenCredentials() + { + BearerToken = defaultCreds.Token, + Region = region, + }; + } + + return new AnthropicBedrockPrivateKeyCredentials + { + ApiAccessKey = defaultCreds.AccessKey, + ApiSecret = defaultCreds.SecretKey, + Region = region, + }; + } +} diff --git a/src/Anthropic.Bedrock/AnthropicBedrockPrivateKeyCredentials.cs b/src/Anthropic.Bedrock/AnthropicBedrockPrivateKeyCredentials.cs new file mode 100644 index 000000000..34accc554 --- /dev/null +++ b/src/Anthropic.Bedrock/AnthropicBedrockPrivateKeyCredentials.cs @@ -0,0 +1,59 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Anthropic.Bedrock; + +/// +/// Provides AWS private key-based credentials for authenticating requests to Amazon Bedrock's Anthropic models. +/// +/// +/// This class implements the AWS Signature Version 4 signing process to authenticate HTTP requests +/// to Amazon Bedrock using AWS access key and secret key credentials. The credentials are applied +/// to each request by adding the necessary AWS authentication headers including the authorization +/// signature, date, and content hash. +/// +public sealed class AnthropicBedrockPrivateKeyCredentials : IAnthropicBedrockCredentials +{ + /// + /// Gets the Aws Region. + /// + public required string Region { get; init; } + + /// + /// Gets the ApiSecret. + /// + public required string ApiSecret { get; init; } + + /// + /// Gets the ApiKey. + /// + public required string ApiAccessKey { get; init; } + + /// + public async Task Apply(HttpRequestMessage requestMessage) + { + var now = DateTime.UtcNow; + var amzDate = AWSSigner.ToAmzDate(now); + requestMessage.Headers.TryAddWithoutValidation("x-amz-date", amzDate); + var content = await requestMessage.Content!.ReadAsStringAsync().ConfigureAwait(false); + var payloadHash = AWSSigner.CalculateHash(content); + requestMessage.Headers.TryAddWithoutValidation("x-amz-content-sha256", payloadHash); + + var authorizationHeader = AWSSigner.GetAuthorizationHeader( + "bedrock", + Region, + requestMessage.Method.ToString(), + requestMessage.RequestUri!, + now, + requestMessage.Headers.ToDictionary( + e => e.Key, + e => string.Join(" ", e.Value), + StringComparer.InvariantCultureIgnoreCase + ), + payloadHash, + ApiAccessKey, + ApiSecret + ); + + requestMessage.Headers.TryAddWithoutValidation("Authorization", authorizationHeader); + } +} diff --git a/src/Anthropic.Bedrock/AwsEventStreamHelpers.cs b/src/Anthropic.Bedrock/AwsEventStreamHelpers.cs new file mode 100644 index 000000000..7546269c0 --- /dev/null +++ b/src/Anthropic.Bedrock/AwsEventStreamHelpers.cs @@ -0,0 +1,166 @@ +using System.Buffers; +using System.Buffers.Binary; +using System.IO.Pipelines; +using System.Text.Json; +using System.Text.Json.Nodes; + +namespace Anthropic.Bedrock; + +/// +/// Provides helper methods for processing Server-Sent Events (SSE) from AWS Bedrock event streams. +/// Handles parsing, validation, and synchronization of event stream messages encoded according to +/// the AWS event stream encoding specification. +/// +/// +/// Reference: https://docs.aws.amazon.com/lexv2/latest/dg/event-stream-encoding.html +/// +internal static class AwsEventStreamHelpers +{ + private static readonly JsonSerializerOptions? _jsonOptions = new() { WriteIndented = false }; + + public static async Task<(string? Data, bool readData)> ReadStreamMessage( + Stream source, + CancellationToken cancellationToken + ) + { + /* + events come in the form of the event stream. + https://docs.aws.amazon.com/lexv2/latest/dg/event-stream-encoding.html + | Prelude | | Data | + | Total Byte Length | Headers Byte Length | Prelude CRC | Headers | Payload | Message CRC | + | 4 byte | 4byte | 4byte | | + */ + + Memory preamble = new byte[12]; + try + { + await source.ReadExactlyAsync(preamble, cancellationToken).ConfigureAwait(false); + } + // only catch exceptions here as at every other occasion it's not expected. + catch (EndOfStreamException) + { + return (null, false); + } + + if (!Crc32ChecksumValidation(preamble[..8].Span, preamble[8..].Span)) + { + throw new InvalidDataException( + $"The preamble at position {source.Position} is invalid" + ); + } + + if ( + !BinaryPrimitives.TryReadInt32BigEndian(preamble[0..4].Span, out var totalLength) + || !BinaryPrimitives.TryReadInt32BigEndian(preamble[4..8].Span, out var headerLength) + || totalLength <= 0 + || headerLength <= 0 + ) + { + throw new InvalidDataException($"The preamble lengths are invalid"); + } + + // we don't care about headers so skip them + Memory header = new byte[headerLength]; + await source.ReadExactlyAsync(header, cancellationToken).ConfigureAwait(false); + + // total length is without the preamble (8bytes) + preamble crc (4bytes) + headers but do not take the message crc (4 bytes) + var messageLength = totalLength - 12 - headerLength - 4; + using var bodyData = MemoryPool.Shared.Rent(messageLength); + Memory messageSpan = bodyData.Memory[0..messageLength]; + await source.ReadExactlyAsync(messageSpan, cancellationToken).ConfigureAwait(false); // read the message part + + Memory messageCrc = new byte[4]; + await source.ReadExactlyAsync(messageCrc, cancellationToken).ConfigureAwait(false); // advance 4 bytes for EOM crc sum + if ( + !Crc32ChecksumValidation( + [.. preamble.Span, .. header.Span, .. messageSpan.Span], + messageCrc.Span + ) + ) + { + throw new InvalidDataException( + "The calculated crc checksum for the message content does not match the provided value from the server." + ); + } + var result = await Parse(new ReadOnlySequence(messageSpan), cancellationToken) + .ConfigureAwait(false); + return (result, true); + } + + private static async Task Parse( + ReadOnlySequence bodyData, + CancellationToken cancellationToken + ) + { + var eventLine = await JsonSerializer + .DeserializeAsync( + PipeReader.Create(bodyData), + _jsonOptions, + cancellationToken + ) + .ConfigureAwait(false); + var eventContents = eventLine?["bytes"]?.AsValue().GetValue(); + if (string.IsNullOrWhiteSpace(eventContents)) + { + return null; + } + + var parsedEvent = await JsonSerializer + .DeserializeAsync( + PipeReader.Create( + new ReadOnlySequence(Convert.FromBase64String(eventContents)) + ), + _jsonOptions, + cancellationToken + ) + .ConfigureAwait(false); + if (parsedEvent is null) + { + return null; + } + + // add double linebreaks at the end to force the StreamReader to emit an empty line for parsing. + return $"event:{parsedEvent["type"]}\ndata:{parsedEvent.ToJsonString(_jsonOptions)}\n\n"; + } + + private static bool Crc32ChecksumValidation( + ReadOnlySpan data, + ReadOnlySpan checksum + ) + { + var dataChecksum = CRC32.ComputeChecksum(data); + var reference = BinaryPrimitives.ReadUInt32BigEndian(checksum); + return dataChecksum == reference; + } + + public class CRC32 + { + private static readonly uint[] CrcTable; + + static CRC32() + { + const uint polynomial = 0xedb88320; + CrcTable = new uint[256]; + for (uint i = 0; i < 256; i++) + { + uint crc = i; + for (uint j = 8; j > 0; j--) + { + crc = (crc & 1) == 1 ? (crc >> 1) ^ polynomial : crc >> 1; + } + CrcTable[i] = crc; + } + } + + public static uint ComputeChecksum(ReadOnlySpan bytes) + { + uint crc = 0xffffffff; + foreach (byte b in bytes) + { + byte tableIndex = (byte)((crc ^ b) & 0xff); + crc = (crc >> 8) ^ CrcTable[tableIndex]; + } + return ~crc; + } + } +} diff --git a/src/Anthropic.Bedrock/AwsSigner.cs b/src/Anthropic.Bedrock/AwsSigner.cs new file mode 100644 index 000000000..9df8a36c2 --- /dev/null +++ b/src/Anthropic.Bedrock/AwsSigner.cs @@ -0,0 +1,174 @@ +using System.Net; +using System.Security.Cryptography; +using System.Text; + +namespace Anthropic.Bedrock; + +/// +/// AWS Signing helper +/// +/// +/// Taken from: https://github.com/aws-samples/sigv4-signing-examples/blob/main/no-sdk/dotnet/AWSSigner.cs +/// +public static class AWSSigner +{ + public static string GetAuthorizationHeader( + string service, + string region, + string httpMethod, + Uri uri, + DateTime now, + string awsAccessKey, + string awsSecretKey, + string? awsSessionToken = null + ) + { + return GetAuthorizationHeader( + service, + region, + httpMethod, + uri, + now, + new Dictionary(), + CalculateHash(""), + awsAccessKey, + awsSecretKey, + awsSessionToken + ); + } + + public static string GetAuthorizationHeader( + string service, + string region, + string httpMethod, + Uri uri, + DateTime now, + IDictionary headers, + string payloadHash, + string awsAccessKey, + string awsSecretKey, + string? awsSessionToken = null + ) + { + var ALGORITHM = "AWS4-HMAC-SHA256"; + + var amzDate = ToAmzDate(now); + var datestamp = now.ToString("yyyyMMdd"); + headers["host"] = uri.Host; + headers["x-amz-date"] = amzDate; + if (!string.IsNullOrWhiteSpace(awsSessionToken)) + { + headers["x-amz-security-token"] = awsSessionToken!; + } + + // Create the canonical request + var canonicalQuerystring = ""; + var canonicalHeaders = CanonicalizeHeaders(headers); + var signedHeaders = CanonicalizeHeaderNames(headers); + var canonicalRequest = + $"{httpMethod}\n{string.Join("/", uri.AbsolutePath.Split('/').Select(WebUtility.UrlEncode))}\n{canonicalQuerystring}\n{canonicalHeaders}\n{signedHeaders}\n{payloadHash}"; + + // Create the string to sign + var credentialScope = $"{datestamp}/{region}/{service}/aws4_request"; + var hashedCanonicalRequest = CalculateHash(canonicalRequest); + var stringToSign = $"{ALGORITHM}\n{amzDate}\n{credentialScope}\n{hashedCanonicalRequest}"; + + // Sign the string + var signingKey = GetSignatureKey(awsSecretKey, datestamp, region, service); + var signature = CalculateHmacHex(signingKey, stringToSign); + + // return signing information + return $"{ALGORITHM} Credential={awsAccessKey}/{credentialScope}, SignedHeaders={signedHeaders}, Signature={signature}"; + } + + public static string ToAmzDate(DateTime date) + { + return date.ToString("yyyyMMddTHHmmssZ"); + } + + static string CanonicalizeHeaderNames(IDictionary headers) + { + var headersToSign = new List(headers.Keys); + headersToSign.Sort(StringComparer.OrdinalIgnoreCase); + + var sb = new StringBuilder(); + foreach (var header in headersToSign) + { + if (sb.Length > 0) + sb.Append(';'); + sb.Append(header.ToLower()); + } + return sb.ToString(); + } + + static string CanonicalizeHeaders(IDictionary headers) + { + var canonicalHeaders = new StringBuilder(); + var sortedHeaders = new SortedDictionary( + headers, + StringComparer.OrdinalIgnoreCase + ); + foreach (var header in sortedHeaders) + { + canonicalHeaders.Append($"{header.Key.ToLowerInvariant()}:{header.Value.Trim()}\n"); + } + return canonicalHeaders.ToString(); + } + + static byte[] GetSignatureKey( + string key, + string dateStamp, + string regionName, + string serviceName + ) + { + var kSecret = Encoding.UTF8.GetBytes($"AWS4{key}"); + var kDate = HmacSha256(kSecret, dateStamp); + var kRegion = HmacSha256(kDate, regionName); + var kService = HmacSha256(kRegion, serviceName); + return HmacSha256(kService, "aws4_request"); + } + + static string CalculateHmacHex(byte[] key, string data) + { + var hash = HmacSha256(key, data); +#if NET9_0_OR_GREATER + return System.Convert.ToHexStringLower(hash).Replace("-", ""); +#else + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); +#endif + } + + static byte[] HmacSha256(byte[] key, string data) + { + using HMACSHA256 hmac = new(key); + return hmac.ComputeHash(Encoding.UTF8.GetBytes(data)); + } + + public static string CalculateHash(string data) + { +#if NET9_0_OR_GREATER + return Convert + .ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(data))) + .Replace("-", ""); +#else +#if NET + var hash = SHA256.HashData(Encoding.UTF8.GetBytes(data)); +#else + using SHA256 sha256 = SHA256.Create(); + var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(data)); +#endif + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); +#endif + } + + public static string ToHexString(byte[] data, bool lowercase) + { + var sb = new StringBuilder(); + for (var i = 0; i < data.Length; i++) + { + sb.Append(data[i].ToString(lowercase ? "x2" : "X2")); + } + return sb.ToString(); + } +} diff --git a/src/Anthropic.Bedrock/IAnthropicBedrockCredentials.cs b/src/Anthropic.Bedrock/IAnthropicBedrockCredentials.cs new file mode 100644 index 000000000..e4b712e46 --- /dev/null +++ b/src/Anthropic.Bedrock/IAnthropicBedrockCredentials.cs @@ -0,0 +1,26 @@ +namespace Anthropic.Bedrock; + +/// +/// Provides methods for authenticating a request for the AWS servers. +/// +public interface IAnthropicBedrockCredentials +{ + /// + /// Gets the Region a request should target. + /// + public string Region { get; } + + /// + /// Modifies a to contain authentication necessary. + /// + /// The to authenticate. + /// A task that resolves once the request has been modified. + public Task Apply(HttpRequestMessage requestMessage); + +#if NET + public static async ValueTask FromEnv() + { + return await AnthropicBedrockCredentialsHelper.FromEnv().ConfigureAwait(false); + } +#endif +} diff --git a/src/Anthropic.Bedrock/LocalShims.cs b/src/Anthropic.Bedrock/LocalShims.cs new file mode 100644 index 000000000..ea733c1fd --- /dev/null +++ b/src/Anthropic.Bedrock/LocalShims.cs @@ -0,0 +1,104 @@ +#if !NET +using System.Buffers; +using System.Runtime.InteropServices; + +/// +/// Contains Shims for .NET 8 available methods to compile on a NetStandard2.0 target. +/// +internal static class StreamExtensions +{ + public static ValueTask WriteAsync( + this Stream stream, + Span bytes, + CancellationToken cancellationToken + ) + { + return new ValueTask( + stream.WriteAsync(bytes.ToArray(), 0, bytes.Length, cancellationToken) + ); + } + + public static ValueTask ReadExactlyAsync( + this Stream stream, + Memory buffer, + CancellationToken cancellationToken = default + ) => + stream.ReadAtLeastAsyncCore( + buffer, + buffer.Length, + throwOnEndOfStream: true, + cancellationToken + ); + + private static async ValueTask ReadAtLeastAsyncCore( + this Stream stream, + Memory buffer, + int minimumBytes, + bool throwOnEndOfStream, + CancellationToken cancellationToken + ) + { + int totalRead = 0; + while (totalRead < minimumBytes) + { + int read = await stream + .ReadAsync(buffer.Slice(totalRead), cancellationToken) + .ConfigureAwait(false); + if (read == 0) + { + if (throwOnEndOfStream) + { + throw new EndOfStreamException(); + } + + return totalRead; + } + + totalRead += read; + } + + return totalRead; + } + + public static ValueTask ReadAsync( + this Stream stream, + Memory buffer, + CancellationToken cancellationToken = default + ) + { + if (MemoryMarshal.TryGetArray(buffer, out ArraySegment array)) + { + return new ValueTask( + stream.ReadAsync(array.Array!, array.Offset, array.Count, cancellationToken) + ); + } + + byte[] sharedBuffer = ArrayPool.Shared.Rent(buffer.Length); + return FinishReadAsync( + stream.ReadAsync(sharedBuffer, 0, buffer.Length, cancellationToken), + sharedBuffer, + buffer + ); + + static async ValueTask FinishReadAsync( + Task readTask, + byte[] localBuffer, + Memory localDestination + ) + { + try + { + int result = await readTask.ConfigureAwait(false); + new ReadOnlySpan(localBuffer, 0, result).CopyTo(localDestination.Span); + return result; + } + finally + { + ArrayPool.Shared.Return(localBuffer); + } + } + } +} + + +#endif diff --git a/src/Anthropic.Bedrock/SseEventContentWrapper.cs b/src/Anthropic.Bedrock/SseEventContentWrapper.cs new file mode 100644 index 000000000..0ee5df4c7 --- /dev/null +++ b/src/Anthropic.Bedrock/SseEventContentWrapper.cs @@ -0,0 +1,132 @@ +using System.Net; +using System.Text; + +namespace Anthropic.Bedrock; + +/// +/// Wraps an HTTP content stream to provide on demand reading of Server-Sent Events (SSE) data. +/// This class transforms the underlying stream into an SSE-compatible format by reading +/// events on-demand and encoding them as UTF-8 data chunks. +/// +/// +/// This wrapper is used internally to adapt AWS Bedrock streaming responses into a format +/// that can be consumed as SSE events. The content is read on demand of the caller, meaning events are only +/// processed when the stream is read from, not when the wrapper is created. +/// +internal class SseEventContentWrapper : HttpContent +{ + private readonly Stream _originalStream; + + public SseEventContentWrapper(Stream originalStream) + { + _originalStream = originalStream; + } + + protected override Task CreateContentReadStreamAsync( +#if NET + CancellationToken cancellationToken +#endif + ) + { + return Task.FromResult(new SseLazyEventStream(_originalStream)); + } + + protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) + { + throw new NotImplementedException(); + } + + protected override bool TryComputeLength(out long length) + { + length = -1; + return false; + } + + private class SseLazyEventStream : Stream + { + private readonly Stream _sourceStream; + + public SseLazyEventStream(Stream source) + { + _sourceStream = source; + } + + public override bool CanRead => true; + + public override bool CanSeek => false; + + public override bool CanWrite => false; + + public override long Length => -1; + + public override long Position { get; set; } + + public override void Flush() { } + +#if NET + public override async ValueTask ReadAsync( + Memory buffer, + CancellationToken cancellationToken = default + ) + { + var (data, success) = await AwsEventStreamHelpers + .ReadStreamMessage(_sourceStream, cancellationToken) + .ConfigureAwait(false); + if (!success) + { + return 0; + } + + var encodedData = Encoding.UTF8.GetBytes(data!); + encodedData.CopyTo(buffer); + return encodedData.Length; + } +#else + public override async Task ReadAsync( + byte[] buffer, + int offset, + int count, + CancellationToken cancellationToken + ) + { + var (data, success) = await AwsEventStreamHelpers + .ReadStreamMessage(_sourceStream, cancellationToken) + .ConfigureAwait(false); + if (!success) + { + return 0; + } + + var encodedData = Encoding.UTF8.GetBytes(data!); + encodedData.CopyTo(buffer, offset); + return encodedData.Length; + } +#endif + + public override int Read(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + _sourceStream.Dispose(); + } + } +} diff --git a/src/Anthropic.Tests/Anthropic.Tests.csproj b/src/Anthropic.Tests/Anthropic.Tests.csproj index 124d191f2..b5c6a9083 100644 --- a/src/Anthropic.Tests/Anthropic.Tests.csproj +++ b/src/Anthropic.Tests/Anthropic.Tests.csproj @@ -21,6 +21,8 @@ + + - \ No newline at end of file + diff --git a/src/Anthropic.Tests/AnthropicTestClients.cs b/src/Anthropic.Tests/AnthropicTestClients.cs index d58c706b8..30c26cc5e 100644 --- a/src/Anthropic.Tests/AnthropicTestClients.cs +++ b/src/Anthropic.Tests/AnthropicTestClients.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Reflection; using System.Threading.Tasks; +using Anthropic.Bedrock; using Anthropic.Foundry; using Xunit.Sdk; using Xunit.v3; @@ -42,7 +43,7 @@ DisposalTracker disposalTracker new AnthropicClient() { BaseUrl = DataServiceUrl, ApiKey = ApiKey }, .. testData .Where(e => e.TestSupport.HasFlag(TestSupportTypes.Anthropic)) - .Select(f => f.TestData) + .SelectMany(f => f.TestData) .ToArray(), ] ) @@ -61,7 +62,30 @@ .. testData }, .. testData .Where(e => e.TestSupport.HasFlag(TestSupportTypes.Foundry)) - .Select(f => f.TestData) + .SelectMany(f => f.TestData) + .ToArray(), + ] + ) + ); + } + if (TestSupportTypes.HasFlag(TestSupportTypes.Bedrock)) + { + rows.Add( + new TheoryDataRow( + [ + new AnthropicBedrockClient( + new AnthropicBedrockApiTokenCredentials() + { + BearerToken = ApiKey, + Region = Resource, + } + ) + { + BaseUrl = DataServiceUrl, + }, + .. testData + .Where(e => e.TestSupport.HasFlag(TestSupportTypes.Bedrock)) + .SelectMany(f => f.TestData) .ToArray(), ] ) @@ -75,14 +99,14 @@ .. testData [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)] sealed class AnthropicTestDataAttribute : Attribute { - public AnthropicTestDataAttribute(TestSupportTypes testSupport, object testData) + public AnthropicTestDataAttribute(TestSupportTypes testSupport, params object[] testData) { TestSupport = testSupport; TestData = testData; } public TestSupportTypes TestSupport { get; } - public object TestData { get; } + public object[] TestData { get; } } [Flags] @@ -91,4 +115,5 @@ public enum TestSupportTypes All = Anthropic | Foundry, Anthropic = 1 << 1, Foundry = 1 << 2, + Bedrock = 1 << 3, } diff --git a/src/Anthropic.Tests/Services/Beta/FileServiceTest.cs b/src/Anthropic.Tests/Services/Beta/FileServiceTest.cs index b06c59f39..67a66797a 100644 --- a/src/Anthropic.Tests/Services/Beta/FileServiceTest.cs +++ b/src/Anthropic.Tests/Services/Beta/FileServiceTest.cs @@ -6,7 +6,7 @@ namespace Anthropic.Tests.Services.Beta; public class FileServiceTest { [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task List_Works(IAnthropicClient client) { var page = await client.Beta.Files.List(new(), TestContext.Current.CancellationToken); @@ -14,7 +14,7 @@ public async Task List_Works(IAnthropicClient client) } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task Delete_Works(IAnthropicClient client) { var deletedFile = await client.Beta.Files.Delete( @@ -33,7 +33,7 @@ public async Task Download_Works(IAnthropicClient client) } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task RetrieveMetadata_Works(IAnthropicClient client) { var fileMetadata = await client.Beta.Files.RetrieveMetadata( diff --git a/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs b/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs index 143eee26a..376f3588b 100644 --- a/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs +++ b/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs @@ -10,7 +10,7 @@ namespace Anthropic.Tests.Services.Beta.Messages; public class BatchServiceTest { [Theory(Skip = "prism validates based on the non-beta endpoint")] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task Create_Works(IAnthropicClient client) { var betaMessageBatch = await client.Beta.Messages.Batches.Create( @@ -156,7 +156,7 @@ public async Task Create_Works(IAnthropicClient client) } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task Retrieve_Works(IAnthropicClient client) { var betaMessageBatch = await client.Beta.Messages.Batches.Retrieve( @@ -168,7 +168,7 @@ public async Task Retrieve_Works(IAnthropicClient client) } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task List_Works(IAnthropicClient client) { var page = await client.Beta.Messages.Batches.List( @@ -179,7 +179,7 @@ public async Task List_Works(IAnthropicClient client) } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task Delete_Works(IAnthropicClient client) { var betaDeletedMessageBatch = await client.Beta.Messages.Batches.Delete( @@ -191,7 +191,7 @@ public async Task Delete_Works(IAnthropicClient client) } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task Cancel_Works(IAnthropicClient client) { var betaMessageBatch = await client.Beta.Messages.Batches.Cancel( @@ -203,7 +203,7 @@ public async Task Cancel_Works(IAnthropicClient client) } [Theory(Skip = "Prism doesn't support application/x-jsonl responses")] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task ResultsStreaming_Works(IAnthropicClient client) { var stream = client.Beta.Messages.Batches.ResultsStreaming( diff --git a/src/Anthropic.Tests/Services/MessageServiceTest.cs b/src/Anthropic.Tests/Services/MessageServiceTest.cs index 5c724e59b..1ba047f21 100644 --- a/src/Anthropic.Tests/Services/MessageServiceTest.cs +++ b/src/Anthropic.Tests/Services/MessageServiceTest.cs @@ -1,7 +1,6 @@ -using System.Linq; using System.Threading.Tasks; +using Anthropic.Bedrock; using Anthropic.Models.Messages; -using Anthropic.Tests; namespace Anthropic.Tests.Services; @@ -11,6 +10,7 @@ public class MessageServiceTest [AnthropicTestClients] [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] public async Task Create_Works(IAnthropicClient client, string modelName) { var message = await client.Messages.Create( @@ -29,6 +29,7 @@ public async Task Create_Works(IAnthropicClient client, string modelName) [AnthropicTestClients] [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] public async Task CreateStreaming_Works(IAnthropicClient client, string modelName) { var stream = client.Messages.CreateStreaming( @@ -48,7 +49,7 @@ public async Task CreateStreaming_Works(IAnthropicClient client, string modelNam } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] public async Task CountTokens_Works(IAnthropicClient client, string modelName) diff --git a/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs b/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs index 5f41456ea..a2c5642df 100644 --- a/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs +++ b/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs @@ -10,7 +10,7 @@ namespace Anthropic.Tests.Services.Messages; public class BatchServiceTest { [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] public async Task Create_Works(IAnthropicClient client, string modelName) @@ -106,7 +106,7 @@ public async Task Create_Works(IAnthropicClient client, string modelName) } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task Retrieve_Works(IAnthropicClient client) { var messageBatch = await client.Messages.Batches.Retrieve( @@ -118,7 +118,7 @@ public async Task Retrieve_Works(IAnthropicClient client) } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task List_Works(IAnthropicClient client) { var page = await client.Messages.Batches.List(new(), TestContext.Current.CancellationToken); @@ -126,7 +126,7 @@ public async Task List_Works(IAnthropicClient client) } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task Delete_Works(IAnthropicClient client) { var deletedMessageBatch = await client.Messages.Batches.Delete( @@ -138,7 +138,7 @@ public async Task Delete_Works(IAnthropicClient client) } [Theory] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task Cancel_Works(IAnthropicClient client) { var messageBatch = await client.Messages.Batches.Cancel( @@ -150,7 +150,7 @@ public async Task Cancel_Works(IAnthropicClient client) } [Theory(Skip = "Prism doesn't support application/x-jsonl responses")] - [AnthropicTestClients] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] public async Task ResultsStreaming_Works(IAnthropicClient client) { var stream = client.Messages.Batches.ResultsStreaming( diff --git a/src/Anthropic/Shims.cs b/src/Anthropic/Shims.cs index afd5582f1..e8afceffe 100644 --- a/src/Anthropic/Shims.cs +++ b/src/Anthropic/Shims.cs @@ -1,5 +1,3 @@ -using System; - #if !NET #pragma warning disable IDE0130 // Namespace does not match folder structure #pragma warning disable CS9113 // Unused parameters From f40db86a00ff6136e26f04204c42c39da5f02d43 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 17:38:36 +0000 Subject: [PATCH 33/41] feat(api): manual updates --- .stats.yml | 6 +- .../Messages/Batches/BatchCreateParamsTest.cs | 118 +++-- .../BetaMessageBatchIndividualResponseTest.cs | 126 +++++- .../Batches/BetaMessageBatchResultTest.cs | 36 +- .../BetaMessageBatchSucceededResultTest.cs | 126 +++++- .../Messages/BetaCompact20260112EditTest.cs | 202 +++++++++ .../Messages/BetaCompactionBlockParamTest.cs | 139 ++++++ .../Beta/Messages/BetaCompactionBlockTest.cs | 71 +++ .../BetaCompactionContentBlockDeltaTest.cs | 71 +++ .../BetaCompactionIterationUsageTest.cs | 130 ++++++ .../Messages/BetaContentBlockParamTest.cs | 28 ++ .../Beta/Messages/BetaContentBlockTest.cs | 20 + .../BetaContextManagementConfigTest.cs | 27 ++ .../Messages/BetaMessageDeltaUsageTest.cs | 110 +++++ .../Messages/BetaMessageIterationUsageTest.cs | 130 ++++++ .../Models/Beta/Messages/BetaMessageTest.cs | 126 +++++- .../Beta/Messages/BetaOutputConfigTest.cs | 2 + .../Messages/BetaRawContentBlockDeltaTest.cs | 20 + .../BetaRawContentBlockStartEventTest.cs | 20 + .../Messages/BetaRawMessageDeltaEventTest.cs | 105 +++++ .../Messages/BetaRawMessageStartEventTest.cs | 126 +++++- .../Messages/BetaRawMessageStreamEventTest.cs | 66 ++- .../Beta/Messages/BetaStopReasonTest.cs | 2 + .../BetaThinkingConfigAdaptiveTest.cs | 67 +++ .../Messages/BetaThinkingConfigParamTest.cs | 20 + .../Models/Beta/Messages/BetaToolTest.cs | 19 + .../Models/Beta/Messages/BetaToolUnionTest.cs | 2 + .../Models/Beta/Messages/BetaUsageTest.cs | 119 +++++ .../Messages/MessageCountTokensParamsTest.cs | 25 +- .../Beta/Messages/MessageCreateParamsTest.cs | 34 +- .../UnnamedSchemaWithArrayParent0Test.cs | 76 ++++ .../Models/Beta/Models/BetaModelInfoTest.cs | 42 +- .../Beta/Models/ModelListPageResponseTest.cs | 42 +- .../Messages/Batches/BatchCreateParamsTest.cs | 406 +++++++++++++++++- .../MessageBatchIndividualResponseTest.cs | 21 +- .../Batches/MessageBatchResultTest.cs | 6 +- .../MessageBatchSucceededResultTest.cs | 21 +- .../Messages/MessageCountTokensParamsTest.cs | 18 +- .../Messages/MessageCountTokensToolTest.cs | 2 + .../Messages/MessageCreateParamsTest.cs | 174 +++++++- .../Models/Messages/MessageTest.cs | 21 +- .../Models/Messages/ModelTest.cs | 2 + .../Models/Messages/OutputConfigTest.cs | 80 +++- .../Messages/RawMessageStartEventTest.cs | 21 +- .../Messages/RawMessageStreamEventTest.cs | 6 +- .../Messages/ThinkingConfigAdaptiveTest.cs | 67 +++ .../Messages/ThinkingConfigParamTest.cs | 20 + .../Models/Messages/ToolTest.cs | 19 + .../Models/Messages/ToolUnionTest.cs | 2 + .../Models/Messages/UsageTest.cs | 9 + .../Models/Models/ModelInfoTest.cs | 42 +- .../Models/ModelListPageResponseTest.cs | 42 +- .../Services/Beta/MessageServiceTest.cs | 6 +- .../Beta/Messages/BatchServiceTest.cs | 4 +- .../Services/MessageServiceTest.cs | 134 +++--- .../Services/Messages/BatchServiceTest.cs | 334 +++++++------- src/Anthropic/Core/ModelBase.cs | 1 + .../Messages/Batches/BatchCreateParams.cs | 15 + .../Beta/Messages/BetaCompact20260112Edit.cs | 132 ++++++ .../Beta/Messages/BetaCompactionBlock.cs | 101 +++++ .../Beta/Messages/BetaCompactionBlockParam.cs | 120 ++++++ .../BetaCompactionContentBlockDelta.cs | 104 +++++ .../Messages/BetaCompactionIterationUsage.cs | 152 +++++++ .../Models/Beta/Messages/BetaContentBlock.cs | 80 +++- .../Beta/Messages/BetaContentBlockParam.cs | 90 +++- .../Messages/BetaContextManagementConfig.cs | 77 +++- .../Beta/Messages/BetaMessageDeltaUsage.cs | 32 ++ .../Messages/BetaMessageIterationUsage.cs | 152 +++++++ .../Models/Beta/Messages/BetaOutputConfig.cs | 13 +- .../Beta/Messages/BetaRawContentBlockDelta.cs | 79 +++- .../Messages/BetaRawContentBlockStartEvent.cs | 80 +++- .../Models/Beta/Messages/BetaStopReason.cs | 3 + .../Messages/BetaThinkingConfigAdaptive.cs | 76 ++++ .../Beta/Messages/BetaThinkingConfigParam.cs | 80 +++- .../Models/Beta/Messages/BetaTool.cs | 18 + .../Models/Beta/Messages/BetaUsage.cs | 46 ++ .../Beta/Messages/MessageCreateParams.cs | 14 + .../Messages/UnnamedSchemaWithArrayParent0.cs | 352 +++++++++++++++ .../Messages/Batches/BatchCreateParams.cs | 15 + .../Models/Messages/MessageCreateParams.cs | 14 + src/Anthropic/Models/Messages/Model.cs | 7 + src/Anthropic/Models/Messages/OutputConfig.cs | 65 +++ .../Models/Messages/ThinkingConfigAdaptive.cs | 74 ++++ .../Models/Messages/ThinkingConfigParam.cs | 79 +++- src/Anthropic/Models/Messages/Tool.cs | 18 + src/Anthropic/Models/Messages/Usage.cs | 14 + 86 files changed, 5280 insertions(+), 533 deletions(-) create mode 100644 src/Anthropic.Tests/Models/Beta/Messages/BetaCompact20260112EditTest.cs create mode 100644 src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionBlockParamTest.cs create mode 100644 src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionBlockTest.cs create mode 100644 src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionContentBlockDeltaTest.cs create mode 100644 src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionIterationUsageTest.cs create mode 100644 src/Anthropic.Tests/Models/Beta/Messages/BetaMessageIterationUsageTest.cs create mode 100644 src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigAdaptiveTest.cs create mode 100644 src/Anthropic.Tests/Models/Beta/Messages/UnnamedSchemaWithArrayParent0Test.cs create mode 100644 src/Anthropic.Tests/Models/Messages/ThinkingConfigAdaptiveTest.cs create mode 100644 src/Anthropic/Models/Beta/Messages/BetaCompact20260112Edit.cs create mode 100644 src/Anthropic/Models/Beta/Messages/BetaCompactionBlock.cs create mode 100644 src/Anthropic/Models/Beta/Messages/BetaCompactionBlockParam.cs create mode 100644 src/Anthropic/Models/Beta/Messages/BetaCompactionContentBlockDelta.cs create mode 100644 src/Anthropic/Models/Beta/Messages/BetaCompactionIterationUsage.cs create mode 100644 src/Anthropic/Models/Beta/Messages/BetaMessageIterationUsage.cs create mode 100644 src/Anthropic/Models/Beta/Messages/BetaThinkingConfigAdaptive.cs create mode 100644 src/Anthropic/Models/Beta/Messages/UnnamedSchemaWithArrayParent0.cs create mode 100644 src/Anthropic/Models/Messages/ThinkingConfigAdaptive.cs diff --git a/.stats.yml b/.stats.yml index d2d2d8dfa..e3f4c0ff5 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 32 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-4526612d12e919de063708c05d15b78902b5a52d33a6e3eb45708c562d338b18.yml -openapi_spec_hash: 346bef71688ca79b107cf84bc09249ac -config_hash: 0b96ef87fc0758bbc543ffa8435baa2a +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/anthropic%2Fanthropic-267f913f89364cb8df3a758335a974b43eb98019a8ceef0a9b0a94ef34c2a3b5.yml +openapi_spec_hash: aa708f3d3bc54992526cbf5894427446 +config_hash: d56fbaeeb3934b1a3b374590c9837ddd diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs index 4909605ee..511defa69 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BatchCreateParamsTest.cs @@ -27,7 +27,7 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -55,6 +55,7 @@ public void FieldRoundtrip_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -135,6 +136,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -163,7 +165,7 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -191,6 +193,7 @@ public void FieldRoundtrip_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -267,6 +270,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -315,7 +319,7 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -343,6 +347,7 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -423,6 +428,7 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -459,7 +465,7 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -487,6 +493,7 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -567,6 +574,7 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -606,7 +614,7 @@ public void Url_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -634,6 +642,7 @@ public void Url_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -714,6 +723,7 @@ public void Url_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -752,7 +762,7 @@ public void AddHeadersToRequest_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -780,6 +790,7 @@ public void AddHeadersToRequest_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -860,6 +871,7 @@ public void AddHeadersToRequest_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -901,7 +913,7 @@ public void CopyConstructor_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -929,6 +941,7 @@ public void CopyConstructor_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -1009,6 +1022,7 @@ public void CopyConstructor_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -1046,7 +1060,7 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -1074,6 +1088,7 @@ public void FieldRoundtrip_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -1147,6 +1162,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -1168,7 +1184,7 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -1196,6 +1212,7 @@ public void FieldRoundtrip_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -1269,6 +1286,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -1298,7 +1316,7 @@ public void SerializationRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -1326,6 +1344,7 @@ public void SerializationRoundtrip_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -1399,6 +1418,7 @@ public void SerializationRoundtrip_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -1431,7 +1451,7 @@ public void FieldRoundtripThroughSerialization_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -1459,6 +1479,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -1532,6 +1553,7 @@ public void FieldRoundtripThroughSerialization_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -1560,7 +1582,7 @@ public void FieldRoundtripThroughSerialization_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -1588,6 +1610,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -1661,6 +1684,7 @@ public void FieldRoundtripThroughSerialization_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -1690,7 +1714,7 @@ public void Validation_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -1718,6 +1742,7 @@ public void Validation_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -1791,6 +1816,7 @@ public void Validation_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -1820,7 +1846,7 @@ public void CopyConstructor_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -1848,6 +1874,7 @@ public void CopyConstructor_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -1921,6 +1948,7 @@ public void CopyConstructor_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -1952,7 +1980,7 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -1980,6 +2008,7 @@ public void FieldRoundtrip_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -2053,6 +2082,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -2073,8 +2103,7 @@ public void FieldRoundtrip_Works() [ new() { Content = "Hello, world", Role = Messages::Role.User }, ]; - ApiEnum expectedModel = - ModelsMessages::Model.ClaudeSonnet4_5_20250929; + ApiEnum expectedModel = ModelsMessages::Model.ClaudeOpus4_6; Container expectedContainer = new Messages::BetaContainerParams() { ID = "id", @@ -2102,6 +2131,7 @@ public void FieldRoundtrip_Works() }, ], }; + string expectedInferenceGeo = "inference_geo"; List expectedMcpServers = [ new() @@ -2182,6 +2212,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -2205,6 +2236,7 @@ public void FieldRoundtrip_Works() Assert.Equal(expectedModel, model.Model); Assert.Equal(expectedContainer, model.Container); Assert.Equal(expectedContextManagement, model.ContextManagement); + Assert.Equal(expectedInferenceGeo, model.InferenceGeo); Assert.NotNull(model.McpServers); Assert.Equal(expectedMcpServers.Count, model.McpServers.Count); for (int i = 0; i < expectedMcpServers.Count; i++) @@ -2243,7 +2275,7 @@ public void SerializationRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -2271,6 +2303,7 @@ public void SerializationRoundtrip_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -2344,6 +2377,7 @@ public void SerializationRoundtrip_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -2372,7 +2406,7 @@ public void FieldRoundtripThroughSerialization_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -2400,6 +2434,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -2473,6 +2508,7 @@ public void FieldRoundtripThroughSerialization_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -2497,8 +2533,7 @@ public void FieldRoundtripThroughSerialization_Works() [ new() { Content = "Hello, world", Role = Messages::Role.User }, ]; - ApiEnum expectedModel = - ModelsMessages::Model.ClaudeSonnet4_5_20250929; + ApiEnum expectedModel = ModelsMessages::Model.ClaudeOpus4_6; Container expectedContainer = new Messages::BetaContainerParams() { ID = "id", @@ -2526,6 +2561,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ], }; + string expectedInferenceGeo = "inference_geo"; List expectedMcpServers = [ new() @@ -2606,6 +2642,7 @@ public void FieldRoundtripThroughSerialization_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -2629,6 +2666,7 @@ public void FieldRoundtripThroughSerialization_Works() Assert.Equal(expectedModel, deserialized.Model); Assert.Equal(expectedContainer, deserialized.Container); Assert.Equal(expectedContextManagement, deserialized.ContextManagement); + Assert.Equal(expectedInferenceGeo, deserialized.InferenceGeo); Assert.NotNull(deserialized.McpServers); Assert.Equal(expectedMcpServers.Count, deserialized.McpServers.Count); for (int i = 0; i < expectedMcpServers.Count; i++) @@ -2667,7 +2705,7 @@ public void Validation_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -2695,6 +2733,7 @@ public void Validation_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -2768,6 +2807,7 @@ public void Validation_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -2793,7 +2833,7 @@ public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -2821,6 +2861,7 @@ public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() }, ], }, + InferenceGeo = "inference_geo", OutputFormat = new() { Schema = new Dictionary() @@ -2865,7 +2906,7 @@ public void OptionalNonNullablePropertiesUnsetValidation_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -2893,6 +2934,7 @@ public void OptionalNonNullablePropertiesUnsetValidation_Works() }, ], }, + InferenceGeo = "inference_geo", OutputFormat = new() { Schema = new Dictionary() @@ -2912,7 +2954,7 @@ public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -2940,6 +2982,7 @@ public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() }, ], }, + InferenceGeo = "inference_geo", OutputFormat = new() { Schema = new Dictionary() @@ -2999,7 +3042,7 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -3027,6 +3070,7 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() }, ], }, + InferenceGeo = "inference_geo", OutputFormat = new() { Schema = new Dictionary() @@ -3061,7 +3105,7 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, McpServers = [ new() @@ -3128,6 +3172,7 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -3147,6 +3192,8 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() Assert.False(model.RawData.ContainsKey("container")); Assert.Null(model.ContextManagement); Assert.False(model.RawData.ContainsKey("context_management")); + Assert.Null(model.InferenceGeo); + Assert.False(model.RawData.ContainsKey("inference_geo")); Assert.Null(model.OutputFormat); Assert.False(model.RawData.ContainsKey("output_format")); } @@ -3158,7 +3205,7 @@ public void OptionalNullablePropertiesUnsetValidation_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, McpServers = [ new() @@ -3225,6 +3272,7 @@ public void OptionalNullablePropertiesUnsetValidation_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -3250,7 +3298,7 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, McpServers = [ new() @@ -3317,6 +3365,7 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -3333,6 +3382,7 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() Container = null, ContextManagement = null, + InferenceGeo = null, OutputFormat = null, }; @@ -3340,6 +3390,8 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() Assert.True(model.RawData.ContainsKey("container")); Assert.Null(model.ContextManagement); Assert.True(model.RawData.ContainsKey("context_management")); + Assert.Null(model.InferenceGeo); + Assert.True(model.RawData.ContainsKey("inference_geo")); Assert.Null(model.OutputFormat); Assert.True(model.RawData.ContainsKey("output_format")); } @@ -3351,7 +3403,7 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, McpServers = [ new() @@ -3418,6 +3470,7 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -3434,6 +3487,7 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() Container = null, ContextManagement = null, + InferenceGeo = null, OutputFormat = null, }; @@ -3447,7 +3501,7 @@ public void CopyConstructor_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = ModelsMessages::Model.ClaudeSonnet4_5_20250929, + Model = ModelsMessages::Model.ClaudeOpus4_6, Container = new Messages::BetaContainerParams() { ID = "id", @@ -3475,6 +3529,7 @@ public void CopyConstructor_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -3548,6 +3603,7 @@ public void CopyConstructor_Works() CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponseTest.cs index 5e7c59107..492a8f8a5 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchIndividualResponseTest.cs @@ -61,7 +61,7 @@ public void FieldRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -73,7 +73,23 @@ public void FieldRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -129,7 +145,7 @@ public void FieldRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -141,7 +157,23 @@ public void FieldRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -205,7 +237,7 @@ public void SerializationRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -217,7 +249,23 @@ public void SerializationRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -287,7 +335,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -299,7 +347,23 @@ public void FieldRoundtripThroughSerialization_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -362,7 +426,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -374,7 +438,23 @@ public void FieldRoundtripThroughSerialization_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -438,7 +518,7 @@ public void Validation_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -450,7 +530,23 @@ public void Validation_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -514,7 +610,7 @@ public void CopyConstructor_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -526,7 +622,23 @@ public void CopyConstructor_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchResultTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchResultTest.cs index d6ce7a210..0de2528b4 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchResultTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchResultTest.cs @@ -59,7 +59,7 @@ public void SucceededValidationWorks() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -71,7 +71,23 @@ public void SucceededValidationWorks() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -157,7 +173,7 @@ public void SucceededSerializationRoundtripWorks() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -169,7 +185,23 @@ public void SucceededSerializationRoundtripWorks() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, diff --git a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResultTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResultTest.cs index da86ab802..068894185 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResultTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/Batches/BetaMessageBatchSucceededResultTest.cs @@ -59,7 +59,7 @@ public void FieldRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -71,7 +71,23 @@ public void FieldRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -124,7 +140,7 @@ public void FieldRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -132,7 +148,23 @@ public void FieldRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -194,7 +226,7 @@ public void SerializationRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -206,7 +238,23 @@ public void SerializationRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -273,7 +321,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -285,7 +333,23 @@ public void FieldRoundtripThroughSerialization_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -345,7 +409,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -353,7 +417,23 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -415,7 +495,7 @@ public void Validation_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -427,7 +507,23 @@ public void Validation_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -488,7 +584,7 @@ public void CopyConstructor_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -500,7 +596,23 @@ public void CopyConstructor_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCompact20260112EditTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCompact20260112EditTest.cs new file mode 100644 index 000000000..11d93882c --- /dev/null +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCompact20260112EditTest.cs @@ -0,0 +1,202 @@ +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Beta.Messages; + +namespace Anthropic.Tests.Models.Beta.Messages; + +public class BetaCompact20260112EditTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new BetaCompact20260112Edit + { + Instructions = "instructions", + PauseAfterCompaction = true, + Trigger = new(1), + }; + + JsonElement expectedType = JsonSerializer.SerializeToElement("compact_20260112"); + string expectedInstructions = "instructions"; + bool expectedPauseAfterCompaction = true; + BetaInputTokensTrigger expectedTrigger = new(1); + + Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); + Assert.Equal(expectedInstructions, model.Instructions); + Assert.Equal(expectedPauseAfterCompaction, model.PauseAfterCompaction); + Assert.Equal(expectedTrigger, model.Trigger); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new BetaCompact20260112Edit + { + Instructions = "instructions", + PauseAfterCompaction = true, + Trigger = new(1), + }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new BetaCompact20260112Edit + { + Instructions = "instructions", + PauseAfterCompaction = true, + Trigger = new(1), + }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + JsonElement expectedType = JsonSerializer.SerializeToElement("compact_20260112"); + string expectedInstructions = "instructions"; + bool expectedPauseAfterCompaction = true; + BetaInputTokensTrigger expectedTrigger = new(1); + + Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); + Assert.Equal(expectedInstructions, deserialized.Instructions); + Assert.Equal(expectedPauseAfterCompaction, deserialized.PauseAfterCompaction); + Assert.Equal(expectedTrigger, deserialized.Trigger); + } + + [Fact] + public void Validation_Works() + { + var model = new BetaCompact20260112Edit + { + Instructions = "instructions", + PauseAfterCompaction = true, + Trigger = new(1), + }; + + model.Validate(); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() + { + var model = new BetaCompact20260112Edit { Instructions = "instructions", Trigger = new(1) }; + + Assert.Null(model.PauseAfterCompaction); + Assert.False(model.RawData.ContainsKey("pause_after_compaction")); + } + + [Fact] + public void OptionalNonNullablePropertiesUnsetValidation_Works() + { + var model = new BetaCompact20260112Edit { Instructions = "instructions", Trigger = new(1) }; + + model.Validate(); + } + + [Fact] + public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() + { + var model = new BetaCompact20260112Edit + { + Instructions = "instructions", + Trigger = new(1), + + // Null should be interpreted as omitted for these properties + PauseAfterCompaction = null, + }; + + Assert.Null(model.PauseAfterCompaction); + Assert.False(model.RawData.ContainsKey("pause_after_compaction")); + } + + [Fact] + public void OptionalNonNullablePropertiesSetToNullValidation_Works() + { + var model = new BetaCompact20260112Edit + { + Instructions = "instructions", + Trigger = new(1), + + // Null should be interpreted as omitted for these properties + PauseAfterCompaction = null, + }; + + model.Validate(); + } + + [Fact] + public void OptionalNullablePropertiesUnsetAreNotSet_Works() + { + var model = new BetaCompact20260112Edit { PauseAfterCompaction = true }; + + Assert.Null(model.Instructions); + Assert.False(model.RawData.ContainsKey("instructions")); + Assert.Null(model.Trigger); + Assert.False(model.RawData.ContainsKey("trigger")); + } + + [Fact] + public void OptionalNullablePropertiesUnsetValidation_Works() + { + var model = new BetaCompact20260112Edit { PauseAfterCompaction = true }; + + model.Validate(); + } + + [Fact] + public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() + { + var model = new BetaCompact20260112Edit + { + PauseAfterCompaction = true, + + Instructions = null, + Trigger = null, + }; + + Assert.Null(model.Instructions); + Assert.True(model.RawData.ContainsKey("instructions")); + Assert.Null(model.Trigger); + Assert.True(model.RawData.ContainsKey("trigger")); + } + + [Fact] + public void OptionalNullablePropertiesSetToNullValidation_Works() + { + var model = new BetaCompact20260112Edit + { + PauseAfterCompaction = true, + + Instructions = null, + Trigger = null, + }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCompact20260112Edit + { + Instructions = "instructions", + PauseAfterCompaction = true, + Trigger = new(1), + }; + + BetaCompact20260112Edit copied = new(model); + + Assert.Equal(model, copied); + } +} diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionBlockParamTest.cs new file mode 100644 index 000000000..0936c25a5 --- /dev/null +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionBlockParamTest.cs @@ -0,0 +1,139 @@ +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Beta.Messages; + +namespace Anthropic.Tests.Models.Beta.Messages; + +public class BetaCompactionBlockParamTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new BetaCompactionBlockParam + { + Content = "content", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + string expectedContent = "content"; + JsonElement expectedType = JsonSerializer.SerializeToElement("compaction"); + BetaCacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; + + Assert.Equal(expectedContent, model.Content); + Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); + Assert.Equal(expectedCacheControl, model.CacheControl); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new BetaCompactionBlockParam + { + Content = "content", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new BetaCompactionBlockParam + { + Content = "content", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + string expectedContent = "content"; + JsonElement expectedType = JsonSerializer.SerializeToElement("compaction"); + BetaCacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; + + Assert.Equal(expectedContent, deserialized.Content); + Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); + Assert.Equal(expectedCacheControl, deserialized.CacheControl); + } + + [Fact] + public void Validation_Works() + { + var model = new BetaCompactionBlockParam + { + Content = "content", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + model.Validate(); + } + + [Fact] + public void OptionalNullablePropertiesUnsetAreNotSet_Works() + { + var model = new BetaCompactionBlockParam { Content = "content" }; + + Assert.Null(model.CacheControl); + Assert.False(model.RawData.ContainsKey("cache_control")); + } + + [Fact] + public void OptionalNullablePropertiesUnsetValidation_Works() + { + var model = new BetaCompactionBlockParam { Content = "content" }; + + model.Validate(); + } + + [Fact] + public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() + { + var model = new BetaCompactionBlockParam + { + Content = "content", + + CacheControl = null, + }; + + Assert.Null(model.CacheControl); + Assert.True(model.RawData.ContainsKey("cache_control")); + } + + [Fact] + public void OptionalNullablePropertiesSetToNullValidation_Works() + { + var model = new BetaCompactionBlockParam + { + Content = "content", + + CacheControl = null, + }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCompactionBlockParam + { + Content = "content", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + + BetaCompactionBlockParam copied = new(model); + + Assert.Equal(model, copied); + } +} diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionBlockTest.cs new file mode 100644 index 000000000..0126fcba3 --- /dev/null +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionBlockTest.cs @@ -0,0 +1,71 @@ +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Beta.Messages; + +namespace Anthropic.Tests.Models.Beta.Messages; + +public class BetaCompactionBlockTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new BetaCompactionBlock { Content = "content" }; + + string expectedContent = "content"; + JsonElement expectedType = JsonSerializer.SerializeToElement("compaction"); + + Assert.Equal(expectedContent, model.Content); + Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new BetaCompactionBlock { Content = "content" }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new BetaCompactionBlock { Content = "content" }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + string expectedContent = "content"; + JsonElement expectedType = JsonSerializer.SerializeToElement("compaction"); + + Assert.Equal(expectedContent, deserialized.Content); + Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); + } + + [Fact] + public void Validation_Works() + { + var model = new BetaCompactionBlock { Content = "content" }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCompactionBlock { Content = "content" }; + + BetaCompactionBlock copied = new(model); + + Assert.Equal(model, copied); + } +} diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionContentBlockDeltaTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionContentBlockDeltaTest.cs new file mode 100644 index 000000000..6d736ad34 --- /dev/null +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionContentBlockDeltaTest.cs @@ -0,0 +1,71 @@ +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Beta.Messages; + +namespace Anthropic.Tests.Models.Beta.Messages; + +public class BetaCompactionContentBlockDeltaTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new BetaCompactionContentBlockDelta { Content = "content" }; + + string expectedContent = "content"; + JsonElement expectedType = JsonSerializer.SerializeToElement("compaction_delta"); + + Assert.Equal(expectedContent, model.Content); + Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new BetaCompactionContentBlockDelta { Content = "content" }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new BetaCompactionContentBlockDelta { Content = "content" }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + string expectedContent = "content"; + JsonElement expectedType = JsonSerializer.SerializeToElement("compaction_delta"); + + Assert.Equal(expectedContent, deserialized.Content); + Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); + } + + [Fact] + public void Validation_Works() + { + var model = new BetaCompactionContentBlockDelta { Content = "content" }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCompactionContentBlockDelta { Content = "content" }; + + BetaCompactionContentBlockDelta copied = new(model); + + Assert.Equal(model, copied); + } +} diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionIterationUsageTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionIterationUsageTest.cs new file mode 100644 index 000000000..8fd2a61b5 --- /dev/null +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaCompactionIterationUsageTest.cs @@ -0,0 +1,130 @@ +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Beta.Messages; + +namespace Anthropic.Tests.Models.Beta.Messages; + +public class BetaCompactionIterationUsageTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new BetaCompactionIterationUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + + BetaCacheCreation expectedCacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }; + long expectedCacheCreationInputTokens = 0; + long expectedCacheReadInputTokens = 0; + long expectedInputTokens = 0; + long expectedOutputTokens = 0; + JsonElement expectedType = JsonSerializer.SerializeToElement("compaction"); + + Assert.Equal(expectedCacheCreation, model.CacheCreation); + Assert.Equal(expectedCacheCreationInputTokens, model.CacheCreationInputTokens); + Assert.Equal(expectedCacheReadInputTokens, model.CacheReadInputTokens); + Assert.Equal(expectedInputTokens, model.InputTokens); + Assert.Equal(expectedOutputTokens, model.OutputTokens); + Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new BetaCompactionIterationUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new BetaCompactionIterationUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + BetaCacheCreation expectedCacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }; + long expectedCacheCreationInputTokens = 0; + long expectedCacheReadInputTokens = 0; + long expectedInputTokens = 0; + long expectedOutputTokens = 0; + JsonElement expectedType = JsonSerializer.SerializeToElement("compaction"); + + Assert.Equal(expectedCacheCreation, deserialized.CacheCreation); + Assert.Equal(expectedCacheCreationInputTokens, deserialized.CacheCreationInputTokens); + Assert.Equal(expectedCacheReadInputTokens, deserialized.CacheReadInputTokens); + Assert.Equal(expectedInputTokens, deserialized.InputTokens); + Assert.Equal(expectedOutputTokens, deserialized.OutputTokens); + Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); + } + + [Fact] + public void Validation_Works() + { + var model = new BetaCompactionIterationUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaCompactionIterationUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + + BetaCompactionIterationUsage copied = new(model); + + Assert.Equal(model, copied); + } +} diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockParamTest.cs index dd21f80f9..5c945b119 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockParamTest.cs @@ -291,6 +291,17 @@ public void ContainerUploadValidationWorks() value.Validate(); } + [Fact] + public void CompactionValidationWorks() + { + BetaContentBlockParam value = new BetaCompactionBlockParam() + { + Content = "content", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + value.Validate(); + } + [Fact] public void TextSerializationRoundtripWorks() { @@ -682,4 +693,21 @@ public void ContainerUploadSerializationRoundtripWorks() Assert.Equal(value, deserialized); } + + [Fact] + public void CompactionSerializationRoundtripWorks() + { + BetaContentBlockParam value = new BetaCompactionBlockParam() + { + Content = "content", + CacheControl = new() { Ttl = Ttl.Ttl5m }, + }; + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockTest.cs index 142fb8539..22c3f9226 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContentBlockTest.cs @@ -194,6 +194,13 @@ public void ContainerUploadValidationWorks() value.Validate(); } + [Fact] + public void CompactionValidationWorks() + { + BetaContentBlock value = new BetaCompactionBlock("content"); + value.Validate(); + } + [Fact] public void TextSerializationRoundtripWorks() { @@ -464,4 +471,17 @@ public void ContainerUploadSerializationRoundtripWorks() Assert.Equal(value, deserialized); } + + [Fact] + public void CompactionSerializationRoundtripWorks() + { + BetaContentBlock value = new BetaCompactionBlock("content"); + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementConfigTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementConfigTest.cs index 9112053a9..1854b80b9 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementConfigTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaContextManagementConfigTest.cs @@ -227,6 +227,18 @@ public void BetaClearThinking20251015ValidationWorks() value.Validate(); } + [Fact] + public void BetaCompact20260112ValidationWorks() + { + Edit value = new BetaCompact20260112Edit() + { + Instructions = "instructions", + PauseAfterCompaction = true, + Trigger = new(1), + }; + value.Validate(); + } + [Fact] public void BetaClearToolUses20250919SerializationRoundtripWorks() { @@ -253,4 +265,19 @@ public void BetaClearThinking20251015SerializationRoundtripWorks() Assert.Equal(value, deserialized); } + + [Fact] + public void BetaCompact20260112SerializationRoundtripWorks() + { + Edit value = new BetaCompact20260112Edit() + { + Instructions = "instructions", + PauseAfterCompaction = true, + Trigger = new(1), + }; + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize(element, ModelBase.SerializerOptions); + + Assert.Equal(value, deserialized); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageDeltaUsageTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageDeltaUsageTest.cs index b8f21407d..e88103335 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageDeltaUsageTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageDeltaUsageTest.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Text.Json; using Anthropic.Core; using Anthropic.Models.Beta.Messages; @@ -14,6 +15,21 @@ public void FieldRoundtrip_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }; @@ -21,6 +37,17 @@ public void FieldRoundtrip_Works() long expectedCacheCreationInputTokens = 2051; long expectedCacheReadInputTokens = 2051; long expectedInputTokens = 2095; + List expectedIterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ]; long expectedOutputTokens = 503; BetaServerToolUsage expectedServerToolUse = new() { @@ -31,6 +58,12 @@ public void FieldRoundtrip_Works() Assert.Equal(expectedCacheCreationInputTokens, model.CacheCreationInputTokens); Assert.Equal(expectedCacheReadInputTokens, model.CacheReadInputTokens); Assert.Equal(expectedInputTokens, model.InputTokens); + Assert.NotNull(model.Iterations); + Assert.Equal(expectedIterations.Count, model.Iterations.Count); + for (int i = 0; i < expectedIterations.Count; i++) + { + Assert.Equal(expectedIterations[i], model.Iterations[i]); + } Assert.Equal(expectedOutputTokens, model.OutputTokens); Assert.Equal(expectedServerToolUse, model.ServerToolUse); } @@ -43,6 +76,21 @@ public void SerializationRoundtrip_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }; @@ -64,6 +112,21 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }; @@ -78,6 +141,17 @@ public void FieldRoundtripThroughSerialization_Works() long expectedCacheCreationInputTokens = 2051; long expectedCacheReadInputTokens = 2051; long expectedInputTokens = 2095; + List expectedIterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ]; long expectedOutputTokens = 503; BetaServerToolUsage expectedServerToolUse = new() { @@ -88,6 +162,12 @@ public void FieldRoundtripThroughSerialization_Works() Assert.Equal(expectedCacheCreationInputTokens, deserialized.CacheCreationInputTokens); Assert.Equal(expectedCacheReadInputTokens, deserialized.CacheReadInputTokens); Assert.Equal(expectedInputTokens, deserialized.InputTokens); + Assert.NotNull(deserialized.Iterations); + Assert.Equal(expectedIterations.Count, deserialized.Iterations.Count); + for (int i = 0; i < expectedIterations.Count; i++) + { + Assert.Equal(expectedIterations[i], deserialized.Iterations[i]); + } Assert.Equal(expectedOutputTokens, deserialized.OutputTokens); Assert.Equal(expectedServerToolUse, deserialized.ServerToolUse); } @@ -100,6 +180,21 @@ public void Validation_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }; @@ -115,6 +210,21 @@ public void CopyConstructor_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }; diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageIterationUsageTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageIterationUsageTest.cs new file mode 100644 index 000000000..de69720c8 --- /dev/null +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageIterationUsageTest.cs @@ -0,0 +1,130 @@ +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Beta.Messages; + +namespace Anthropic.Tests.Models.Beta.Messages; + +public class BetaMessageIterationUsageTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new BetaMessageIterationUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + + BetaCacheCreation expectedCacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }; + long expectedCacheCreationInputTokens = 0; + long expectedCacheReadInputTokens = 0; + long expectedInputTokens = 0; + long expectedOutputTokens = 0; + JsonElement expectedType = JsonSerializer.SerializeToElement("message"); + + Assert.Equal(expectedCacheCreation, model.CacheCreation); + Assert.Equal(expectedCacheCreationInputTokens, model.CacheCreationInputTokens); + Assert.Equal(expectedCacheReadInputTokens, model.CacheReadInputTokens); + Assert.Equal(expectedInputTokens, model.InputTokens); + Assert.Equal(expectedOutputTokens, model.OutputTokens); + Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new BetaMessageIterationUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new BetaMessageIterationUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + BetaCacheCreation expectedCacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }; + long expectedCacheCreationInputTokens = 0; + long expectedCacheReadInputTokens = 0; + long expectedInputTokens = 0; + long expectedOutputTokens = 0; + JsonElement expectedType = JsonSerializer.SerializeToElement("message"); + + Assert.Equal(expectedCacheCreation, deserialized.CacheCreation); + Assert.Equal(expectedCacheCreationInputTokens, deserialized.CacheCreationInputTokens); + Assert.Equal(expectedCacheReadInputTokens, deserialized.CacheReadInputTokens); + Assert.Equal(expectedInputTokens, deserialized.InputTokens); + Assert.Equal(expectedOutputTokens, deserialized.OutputTokens); + Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); + } + + [Fact] + public void Validation_Works() + { + var model = new BetaMessageIterationUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaMessageIterationUsage + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + + BetaMessageIterationUsage copied = new(model); + + Assert.Equal(model, copied); + } +} diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTest.cs index 21a175920..7d294ad5d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaMessageTest.cs @@ -57,7 +57,7 @@ public void FieldRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -65,7 +65,23 @@ public void FieldRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -115,7 +131,7 @@ public void FieldRoundtrip_Works() }, ] ); - ApiEnum expectedModel = Model.ClaudeSonnet4_5_20250929; + ApiEnum expectedModel = Model.ClaudeOpus4_6; JsonElement expectedRole = JsonSerializer.SerializeToElement("assistant"); ApiEnum expectedStopReason = Messages::BetaStopReason.EndTurn; @@ -125,7 +141,23 @@ public void FieldRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -195,7 +227,7 @@ public void SerializationRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -203,7 +235,23 @@ public void SerializationRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -267,7 +315,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -275,7 +323,23 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -332,7 +396,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ] ); - ApiEnum expectedModel = Model.ClaudeSonnet4_5_20250929; + ApiEnum expectedModel = Model.ClaudeOpus4_6; JsonElement expectedRole = JsonSerializer.SerializeToElement("assistant"); ApiEnum expectedStopReason = Messages::BetaStopReason.EndTurn; @@ -342,7 +406,23 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -412,7 +492,7 @@ public void Validation_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -420,7 +500,23 @@ public void Validation_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -478,7 +574,7 @@ public void CopyConstructor_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -486,7 +582,23 @@ public void CopyConstructor_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs index 800c50feb..1847f940c 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaOutputConfigTest.cs @@ -178,6 +178,7 @@ public class EffortTest : TestBase [InlineData(Effort.Low)] [InlineData(Effort.Medium)] [InlineData(Effort.High)] + [InlineData(Effort.Max)] public void Validation_Works(Effort rawValue) { // force implicit conversion because Theory can't do that for us @@ -201,6 +202,7 @@ public void InvalidEnumValidationThrows_Works() [InlineData(Effort.Low)] [InlineData(Effort.Medium)] [InlineData(Effort.High)] + [InlineData(Effort.Max)] public void SerializationRoundtrip_Works(Effort rawValue) { // force implicit conversion because Theory can't do that for us diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockDeltaTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockDeltaTest.cs index f46f6817b..f7c2ad7a6 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockDeltaTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockDeltaTest.cs @@ -53,6 +53,13 @@ public void SignatureValidationWorks() value.Validate(); } + [Fact] + public void CompactionValidationWorks() + { + BetaRawContentBlockDelta value = new BetaCompactionContentBlockDelta("content"); + value.Validate(); + } + [Fact] public void TextSerializationRoundtripWorks() { @@ -129,4 +136,17 @@ public void SignatureSerializationRoundtripWorks() Assert.Equal(value, deserialized); } + + [Fact] + public void CompactionSerializationRoundtripWorks() + { + BetaRawContentBlockDelta value = new BetaCompactionContentBlockDelta("content"); + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs index b02880e1a..92bde5b54 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawContentBlockStartEventTest.cs @@ -389,6 +389,13 @@ public void BetaContainerUploadValidationWorks() value.Validate(); } + [Fact] + public void BetaCompactionValidationWorks() + { + ContentBlock value = new BetaCompactionBlock("content"); + value.Validate(); + } + [Fact] public void BetaTextSerializationRoundtripWorks() { @@ -659,4 +666,17 @@ public void BetaContainerUploadSerializationRoundtripWorks() Assert.Equal(value, deserialized); } + + [Fact] + public void BetaCompactionSerializationRoundtripWorks() + { + ContentBlock value = new BetaCompactionBlock("content"); + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageDeltaEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageDeltaEventTest.cs index 970a01f0c..9df0f297d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageDeltaEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageDeltaEventTest.cs @@ -45,6 +45,21 @@ public void FieldRoundtrip_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }, @@ -84,6 +99,21 @@ public void FieldRoundtrip_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }; @@ -132,6 +162,21 @@ public void SerializationRoundtrip_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }, @@ -184,6 +229,21 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }, @@ -230,6 +290,21 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }; @@ -278,6 +353,21 @@ public void Validation_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }, @@ -324,6 +414,21 @@ public void CopyConstructor_Works() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }, diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStartEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStartEventTest.cs index d163ee474..516b20108 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStartEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStartEventTest.cs @@ -58,7 +58,7 @@ public void FieldRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -70,7 +70,23 @@ public void FieldRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -123,7 +139,7 @@ public void FieldRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -131,7 +147,23 @@ public void FieldRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -193,7 +225,7 @@ public void SerializationRoundtrip_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -205,7 +237,23 @@ public void SerializationRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -272,7 +320,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -284,7 +332,23 @@ public void FieldRoundtripThroughSerialization_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -344,7 +408,7 @@ public void FieldRoundtripThroughSerialization_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -352,7 +416,23 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -414,7 +494,7 @@ public void Validation_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -426,7 +506,23 @@ public void Validation_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -487,7 +583,7 @@ public void CopyConstructor_Works() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -499,7 +595,23 @@ public void CopyConstructor_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStreamEventTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStreamEventTest.cs index 030802461..4c664a747 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStreamEventTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaRawMessageStreamEventTest.cs @@ -57,7 +57,7 @@ public void StartValidationWorks() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -69,7 +69,23 @@ public void StartValidationWorks() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -117,6 +133,21 @@ public void DeltaValidationWorks() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }, @@ -224,7 +255,7 @@ public void StartSerializationRoundtripWorks() }, ] ), - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = Messages::BetaStopReason.EndTurn, StopSequence = null, Usage = new() @@ -236,7 +267,23 @@ public void StartSerializationRoundtripWorks() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = Messages::BetaUsageServiceTier.Standard, @@ -290,6 +337,21 @@ public void DeltaSerializationRoundtripWorks() CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, InputTokens = 2095, + Iterations = + [ + new Messages::BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, }, diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaStopReasonTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaStopReasonTest.cs index 98f27d0c0..11a197320 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaStopReasonTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaStopReasonTest.cs @@ -13,6 +13,7 @@ public class BetaStopReasonTest : TestBase [InlineData(BetaStopReason.StopSequence)] [InlineData(BetaStopReason.ToolUse)] [InlineData(BetaStopReason.PauseTurn)] + [InlineData(BetaStopReason.Compaction)] [InlineData(BetaStopReason.Refusal)] [InlineData(BetaStopReason.ModelContextWindowExceeded)] public void Validation_Works(BetaStopReason rawValue) @@ -40,6 +41,7 @@ public void InvalidEnumValidationThrows_Works() [InlineData(BetaStopReason.StopSequence)] [InlineData(BetaStopReason.ToolUse)] [InlineData(BetaStopReason.PauseTurn)] + [InlineData(BetaStopReason.Compaction)] [InlineData(BetaStopReason.Refusal)] [InlineData(BetaStopReason.ModelContextWindowExceeded)] public void SerializationRoundtrip_Works(BetaStopReason rawValue) diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigAdaptiveTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigAdaptiveTest.cs new file mode 100644 index 000000000..999c6f693 --- /dev/null +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigAdaptiveTest.cs @@ -0,0 +1,67 @@ +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Beta.Messages; + +namespace Anthropic.Tests.Models.Beta.Messages; + +public class BetaThinkingConfigAdaptiveTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new BetaThinkingConfigAdaptive { }; + + JsonElement expectedType = JsonSerializer.SerializeToElement("adaptive"); + + Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new BetaThinkingConfigAdaptive { }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new BetaThinkingConfigAdaptive { }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + JsonElement expectedType = JsonSerializer.SerializeToElement("adaptive"); + + Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); + } + + [Fact] + public void Validation_Works() + { + var model = new BetaThinkingConfigAdaptive { }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new BetaThinkingConfigAdaptive { }; + + BetaThinkingConfigAdaptive copied = new(model); + + Assert.Equal(model, copied); + } +} diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigParamTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigParamTest.cs index 1e8f6cb98..1730ccf05 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigParamTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaThinkingConfigParamTest.cs @@ -20,6 +20,13 @@ public void DisabledValidationWorks() value.Validate(); } + [Fact] + public void AdaptiveValidationWorks() + { + BetaThinkingConfigParam value = new BetaThinkingConfigAdaptive(); + value.Validate(); + } + [Fact] public void EnabledSerializationRoundtripWorks() { @@ -45,4 +52,17 @@ public void DisabledSerializationRoundtripWorks() Assert.Equal(value, deserialized); } + + [Fact] + public void AdaptiveSerializationRoundtripWorks() + { + BetaThinkingConfigParam value = new BetaThinkingConfigAdaptive(); + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } } diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTest.cs index 5384a8809..a143d3ffb 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolTest.cs @@ -27,6 +27,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -55,6 +56,7 @@ public void FieldRoundtrip_Works() BetaCacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; bool expectedDeferLoading = true; string expectedDescription = "Get the current weather in a given location"; + bool expectedEagerInputStreaming = true; List> expectedInputExamples = [ new Dictionary() @@ -76,6 +78,7 @@ public void FieldRoundtrip_Works() Assert.Equal(expectedCacheControl, model.CacheControl); Assert.Equal(expectedDeferLoading, model.DeferLoading); Assert.Equal(expectedDescription, model.Description); + Assert.Equal(expectedEagerInputStreaming, model.EagerInputStreaming); Assert.NotNull(model.InputExamples); Assert.Equal(expectedInputExamples.Count, model.InputExamples.Count); for (int i = 0; i < expectedInputExamples.Count; i++) @@ -111,6 +114,7 @@ public void SerializationRoundtrip_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -147,6 +151,7 @@ public void FieldRoundtripThroughSerialization_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -182,6 +187,7 @@ public void FieldRoundtripThroughSerialization_Works() BetaCacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; bool expectedDeferLoading = true; string expectedDescription = "Get the current weather in a given location"; + bool expectedEagerInputStreaming = true; List> expectedInputExamples = [ new Dictionary() @@ -203,6 +209,7 @@ public void FieldRoundtripThroughSerialization_Works() Assert.Equal(expectedCacheControl, deserialized.CacheControl); Assert.Equal(expectedDeferLoading, deserialized.DeferLoading); Assert.Equal(expectedDescription, deserialized.Description); + Assert.Equal(expectedEagerInputStreaming, deserialized.EagerInputStreaming); Assert.NotNull(deserialized.InputExamples); Assert.Equal(expectedInputExamples.Count, deserialized.InputExamples.Count); for (int i = 0; i < expectedInputExamples.Count; i++) @@ -238,6 +245,7 @@ public void Validation_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -268,6 +276,7 @@ public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() }, Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, + EagerInputStreaming = true, Type = BetaToolType.Custom, }; @@ -299,6 +308,7 @@ public void OptionalNonNullablePropertiesUnsetValidation_Works() }, Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, + EagerInputStreaming = true, Type = BetaToolType.Custom, }; @@ -321,6 +331,7 @@ public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() }, Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, + EagerInputStreaming = true, Type = BetaToolType.Custom, // Null should be interpreted as omitted for these properties @@ -359,6 +370,7 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() }, Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, + EagerInputStreaming = true, Type = BetaToolType.Custom, // Null should be interpreted as omitted for these properties @@ -402,6 +414,8 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() Assert.Null(model.CacheControl); Assert.False(model.RawData.ContainsKey("cache_control")); + Assert.Null(model.EagerInputStreaming); + Assert.False(model.RawData.ContainsKey("eager_input_streaming")); Assert.Null(model.Type); Assert.False(model.RawData.ContainsKey("type")); } @@ -465,11 +479,14 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() Strict = true, CacheControl = null, + EagerInputStreaming = null, Type = null, }; Assert.Null(model.CacheControl); Assert.True(model.RawData.ContainsKey("cache_control")); + Assert.Null(model.EagerInputStreaming); + Assert.True(model.RawData.ContainsKey("eager_input_streaming")); Assert.Null(model.Type); Assert.True(model.RawData.ContainsKey("type")); } @@ -502,6 +519,7 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() Strict = true, CacheControl = null, + EagerInputStreaming = null, Type = null, }; @@ -527,6 +545,7 @@ public void CopyConstructor_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUnionTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUnionTest.cs index c2b4a083e..b28921892 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUnionTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaToolUnionTest.cs @@ -26,6 +26,7 @@ public void BetaToolValidationWorks() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -383,6 +384,7 @@ public void BetaToolSerializationRoundtripWorks() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaUsageTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaUsageTest.cs index 8d2bc85ce..e4b86b4f4 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaUsageTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaUsageTest.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Text.Json; using Anthropic.Core; using Anthropic.Exceptions; @@ -15,7 +16,23 @@ public void FieldRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = BetaUsageServiceTier.Standard, @@ -28,7 +45,19 @@ public void FieldRoundtrip_Works() }; long expectedCacheCreationInputTokens = 2051; long expectedCacheReadInputTokens = 2051; + string expectedInferenceGeo = "inference_geo"; long expectedInputTokens = 2095; + List expectedIterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ]; long expectedOutputTokens = 503; BetaServerToolUsage expectedServerToolUse = new() { @@ -40,7 +69,14 @@ public void FieldRoundtrip_Works() Assert.Equal(expectedCacheCreation, model.CacheCreation); Assert.Equal(expectedCacheCreationInputTokens, model.CacheCreationInputTokens); Assert.Equal(expectedCacheReadInputTokens, model.CacheReadInputTokens); + Assert.Equal(expectedInferenceGeo, model.InferenceGeo); Assert.Equal(expectedInputTokens, model.InputTokens); + Assert.NotNull(model.Iterations); + Assert.Equal(expectedIterations.Count, model.Iterations.Count); + for (int i = 0; i < expectedIterations.Count; i++) + { + Assert.Equal(expectedIterations[i], model.Iterations[i]); + } Assert.Equal(expectedOutputTokens, model.OutputTokens); Assert.Equal(expectedServerToolUse, model.ServerToolUse); Assert.Equal(expectedServiceTier, model.ServiceTier); @@ -54,7 +90,23 @@ public void SerializationRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = BetaUsageServiceTier.Standard, @@ -74,7 +126,23 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = BetaUsageServiceTier.Standard, @@ -94,7 +162,19 @@ public void FieldRoundtripThroughSerialization_Works() }; long expectedCacheCreationInputTokens = 2051; long expectedCacheReadInputTokens = 2051; + string expectedInferenceGeo = "inference_geo"; long expectedInputTokens = 2095; + List expectedIterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ]; long expectedOutputTokens = 503; BetaServerToolUsage expectedServerToolUse = new() { @@ -106,7 +186,14 @@ public void FieldRoundtripThroughSerialization_Works() Assert.Equal(expectedCacheCreation, deserialized.CacheCreation); Assert.Equal(expectedCacheCreationInputTokens, deserialized.CacheCreationInputTokens); Assert.Equal(expectedCacheReadInputTokens, deserialized.CacheReadInputTokens); + Assert.Equal(expectedInferenceGeo, deserialized.InferenceGeo); Assert.Equal(expectedInputTokens, deserialized.InputTokens); + Assert.NotNull(deserialized.Iterations); + Assert.Equal(expectedIterations.Count, deserialized.Iterations.Count); + for (int i = 0; i < expectedIterations.Count; i++) + { + Assert.Equal(expectedIterations[i], deserialized.Iterations[i]); + } Assert.Equal(expectedOutputTokens, deserialized.OutputTokens); Assert.Equal(expectedServerToolUse, deserialized.ServerToolUse); Assert.Equal(expectedServiceTier, deserialized.ServiceTier); @@ -120,7 +207,23 @@ public void Validation_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = BetaUsageServiceTier.Standard, @@ -137,7 +240,23 @@ public void CopyConstructor_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], OutputTokens = 503, ServerToolUse = new() { WebFetchRequests = 2, WebSearchRequests = 0 }, ServiceTier = BetaUsageServiceTier.Standard, diff --git a/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs index 95b00c0fb..370919e3d 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/MessageCountTokensParamsTest.cs @@ -17,7 +17,7 @@ public void FieldRoundtrip_Works() var parameters = new MessageCountTokensParams { Messages = [new() { Content = "string", Role = Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, ContextManagement = new() { Edits = @@ -100,6 +100,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -115,7 +116,7 @@ public void FieldRoundtrip_Works() }; List expectedMessages = [new() { Content = "string", Role = Role.User }]; - ApiEnum expectedModel = Messages::Model.ClaudeOpus4_5_20251101; + ApiEnum expectedModel = Messages::Model.ClaudeOpus4_6; BetaContextManagementConfig expectedContextManagement = new() { Edits = @@ -201,6 +202,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -255,7 +257,7 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() var parameters = new MessageCountTokensParams { Messages = [new() { Content = "string", Role = Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, ContextManagement = new() { Edits = @@ -301,7 +303,7 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() var parameters = new MessageCountTokensParams { Messages = [new() { Content = "string", Role = Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, ContextManagement = new() { Edits = @@ -356,7 +358,7 @@ public void OptionalNullableParamsUnsetAreNotSet_Works() var parameters = new MessageCountTokensParams { Messages = [new() { Content = "string", Role = Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, McpServers = [ new() @@ -418,6 +420,7 @@ public void OptionalNullableParamsUnsetAreNotSet_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -444,7 +447,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() var parameters = new MessageCountTokensParams { Messages = [new() { Content = "string", Role = Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, McpServers = [ new() @@ -506,6 +509,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -535,7 +539,7 @@ public void Url_Works() MessageCountTokensParams parameters = new() { Messages = [new() { Content = "string", Role = Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, }; var url = parameters.Url(new() { ApiKey = "my-anthropic-api-key" }); @@ -550,7 +554,7 @@ public void AddHeadersToRequest_Works() MessageCountTokensParams parameters = new() { Messages = [new() { Content = "string", Role = Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, Betas = [AnthropicBeta.MessageBatches2024_09_24], }; @@ -568,7 +572,7 @@ public void CopyConstructor_Works() var parameters = new MessageCountTokensParams { Messages = [new() { Content = "string", Role = Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, ContextManagement = new() { Edits = @@ -651,6 +655,7 @@ public void CopyConstructor_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -773,6 +778,7 @@ public void BetaValidationWorks() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -1130,6 +1136,7 @@ public void BetaSerializationRoundtripWorks() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() diff --git a/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs index dc3e72ab1..4d6849beb 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/MessageCreateParamsTest.cs @@ -19,7 +19,7 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, Container = new BetaContainerParams() { ID = "id", @@ -47,6 +47,7 @@ public void FieldRoundtrip_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -119,6 +120,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -140,7 +142,7 @@ public void FieldRoundtrip_Works() [ new() { Content = "Hello, world", Role = Role.User }, ]; - ApiEnum expectedModel = Messages::Model.ClaudeSonnet4_5_20250929; + ApiEnum expectedModel = Messages::Model.ClaudeOpus4_6; Container expectedContainer = new BetaContainerParams() { ID = "id", @@ -168,6 +170,7 @@ public void FieldRoundtrip_Works() }, ], }; + string expectedInferenceGeo = "inference_geo"; List expectedMcpServers = [ new() @@ -243,6 +246,7 @@ public void FieldRoundtrip_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -270,6 +274,7 @@ public void FieldRoundtrip_Works() Assert.Equal(expectedModel, parameters.Model); Assert.Equal(expectedContainer, parameters.Container); Assert.Equal(expectedContextManagement, parameters.ContextManagement); + Assert.Equal(expectedInferenceGeo, parameters.InferenceGeo); Assert.NotNull(parameters.McpServers); Assert.Equal(expectedMcpServers.Count, parameters.McpServers.Count); for (int i = 0; i < expectedMcpServers.Count; i++) @@ -313,7 +318,7 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, Container = new BetaContainerParams() { ID = "id", @@ -341,6 +346,7 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() }, ], }, + InferenceGeo = "inference_geo", OutputFormat = new() { Schema = new Dictionary() @@ -385,7 +391,7 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, Container = new BetaContainerParams() { ID = "id", @@ -413,6 +419,7 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() }, ], }, + InferenceGeo = "inference_geo", OutputFormat = new() { Schema = new Dictionary() @@ -472,7 +479,7 @@ public void OptionalNullableParamsUnsetAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, McpServers = [ new() @@ -538,6 +545,7 @@ public void OptionalNullableParamsUnsetAreNotSet_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -558,6 +566,8 @@ public void OptionalNullableParamsUnsetAreNotSet_Works() Assert.False(parameters.RawBodyData.ContainsKey("container")); Assert.Null(parameters.ContextManagement); Assert.False(parameters.RawBodyData.ContainsKey("context_management")); + Assert.Null(parameters.InferenceGeo); + Assert.False(parameters.RawBodyData.ContainsKey("inference_geo")); Assert.Null(parameters.OutputFormat); Assert.False(parameters.RawBodyData.ContainsKey("output_format")); } @@ -569,7 +579,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, McpServers = [ new() @@ -635,6 +645,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() @@ -652,6 +663,7 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() Container = null, ContextManagement = null, + InferenceGeo = null, OutputFormat = null, }; @@ -659,6 +671,8 @@ public void OptionalNullableParamsSetToNullAreSetToNull_Works() Assert.True(parameters.RawBodyData.ContainsKey("container")); Assert.Null(parameters.ContextManagement); Assert.True(parameters.RawBodyData.ContainsKey("context_management")); + Assert.Null(parameters.InferenceGeo); + Assert.True(parameters.RawBodyData.ContainsKey("inference_geo")); Assert.Null(parameters.OutputFormat); Assert.True(parameters.RawBodyData.ContainsKey("output_format")); } @@ -670,7 +684,7 @@ public void Url_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, }; var url = parameters.Url(new() { ApiKey = "my-anthropic-api-key" }); @@ -686,7 +700,7 @@ public void AddHeadersToRequest_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, Betas = [AnthropicBeta.MessageBatches2024_09_24], }; @@ -705,7 +719,7 @@ public void CopyConstructor_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, Container = new BetaContainerParams() { ID = "id", @@ -733,6 +747,7 @@ public void CopyConstructor_Works() }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -805,6 +820,7 @@ public void CopyConstructor_Works() CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() diff --git a/src/Anthropic.Tests/Models/Beta/Messages/UnnamedSchemaWithArrayParent0Test.cs b/src/Anthropic.Tests/Models/Beta/Messages/UnnamedSchemaWithArrayParent0Test.cs new file mode 100644 index 000000000..37fdb6134 --- /dev/null +++ b/src/Anthropic.Tests/Models/Beta/Messages/UnnamedSchemaWithArrayParent0Test.cs @@ -0,0 +1,76 @@ +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Beta.Messages; + +namespace Anthropic.Tests.Models.Beta.Messages; + +public class UnnamedSchemaWithArrayParent0Test : TestBase +{ + [Fact] + public void BetaMessageIterationUsageValidationWorks() + { + UnnamedSchemaWithArrayParent0 value = new BetaMessageIterationUsage() + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + value.Validate(); + } + + [Fact] + public void BetaCompactionIterationUsageValidationWorks() + { + UnnamedSchemaWithArrayParent0 value = new BetaCompactionIterationUsage() + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + value.Validate(); + } + + [Fact] + public void BetaMessageIterationUsageSerializationRoundtripWorks() + { + UnnamedSchemaWithArrayParent0 value = new BetaMessageIterationUsage() + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } + + [Fact] + public void BetaCompactionIterationUsageSerializationRoundtripWorks() + { + UnnamedSchemaWithArrayParent0 value = new BetaCompactionIterationUsage() + { + CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }; + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } +} diff --git a/src/Anthropic.Tests/Models/Beta/Models/BetaModelInfoTest.cs b/src/Anthropic.Tests/Models/Beta/Models/BetaModelInfoTest.cs index 409a057a8..e623ae2af 100644 --- a/src/Anthropic.Tests/Models/Beta/Models/BetaModelInfoTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Models/BetaModelInfoTest.cs @@ -12,14 +12,14 @@ public void FieldRoundtrip_Works() { var model = new BetaModelInfo { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }; - string expectedID = "claude-sonnet-4-20250514"; - DateTimeOffset expectedCreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"); - string expectedDisplayName = "Claude Sonnet 4"; + string expectedID = "claude-opus-4-6"; + DateTimeOffset expectedCreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"); + string expectedDisplayName = "Claude Opus 4.6"; JsonElement expectedType = JsonSerializer.SerializeToElement("model"); Assert.Equal(expectedID, model.ID); @@ -33,9 +33,9 @@ public void SerializationRoundtrip_Works() { var model = new BetaModelInfo { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }; string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); @@ -52,9 +52,9 @@ public void FieldRoundtripThroughSerialization_Works() { var model = new BetaModelInfo { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }; string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); @@ -64,9 +64,9 @@ public void FieldRoundtripThroughSerialization_Works() ); Assert.NotNull(deserialized); - string expectedID = "claude-sonnet-4-20250514"; - DateTimeOffset expectedCreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"); - string expectedDisplayName = "Claude Sonnet 4"; + string expectedID = "claude-opus-4-6"; + DateTimeOffset expectedCreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"); + string expectedDisplayName = "Claude Opus 4.6"; JsonElement expectedType = JsonSerializer.SerializeToElement("model"); Assert.Equal(expectedID, deserialized.ID); @@ -80,9 +80,9 @@ public void Validation_Works() { var model = new BetaModelInfo { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }; model.Validate(); @@ -93,9 +93,9 @@ public void CopyConstructor_Works() { var model = new BetaModelInfo { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }; BetaModelInfo copied = new(model); diff --git a/src/Anthropic.Tests/Models/Beta/Models/ModelListPageResponseTest.cs b/src/Anthropic.Tests/Models/Beta/Models/ModelListPageResponseTest.cs index 08dfc014d..23a840926 100644 --- a/src/Anthropic.Tests/Models/Beta/Models/ModelListPageResponseTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Models/ModelListPageResponseTest.cs @@ -17,9 +17,9 @@ public void FieldRoundtrip_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ], FirstID = "first_id", @@ -31,9 +31,9 @@ public void FieldRoundtrip_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ]; string expectedFirstID = "first_id"; @@ -59,9 +59,9 @@ public void SerializationRoundtrip_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ], FirstID = "first_id", @@ -87,9 +87,9 @@ public void FieldRoundtripThroughSerialization_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ], FirstID = "first_id", @@ -108,9 +108,9 @@ public void FieldRoundtripThroughSerialization_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ]; string expectedFirstID = "first_id"; @@ -136,9 +136,9 @@ public void Validation_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ], FirstID = "first_id", @@ -158,9 +158,9 @@ public void CopyConstructor_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ], FirstID = "first_id", diff --git a/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs index 004d6a8bb..da56451c3 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/BatchCreateParamsTest.cs @@ -24,10 +24,12 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -81,6 +83,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -101,10 +104,12 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -155,6 +160,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -186,10 +192,12 @@ public void Url_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -243,6 +251,7 @@ public void Url_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -273,10 +282,12 @@ public void CopyConstructor_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -330,6 +341,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -359,10 +371,12 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -413,6 +427,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -427,10 +442,12 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -481,6 +498,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -503,10 +521,12 @@ public void SerializationRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -557,6 +577,7 @@ public void SerializationRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -582,10 +603,12 @@ public void FieldRoundtripThroughSerialization_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -636,6 +659,7 @@ public void FieldRoundtripThroughSerialization_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -657,10 +681,12 @@ public void FieldRoundtripThroughSerialization_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -711,6 +737,7 @@ public void FieldRoundtripThroughSerialization_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -733,10 +760,12 @@ public void Validation_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -787,6 +816,7 @@ public void Validation_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -809,10 +839,12 @@ public void CopyConstructor_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -863,6 +895,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -887,10 +920,12 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -941,6 +976,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -954,13 +990,15 @@ public void FieldRoundtrip_Works() [ new() { Content = "Hello, world", Role = Messages::Role.User }, ]; - ApiEnum expectedModel = Messages::Model.ClaudeSonnet4_5_20250929; + ApiEnum expectedModel = Messages::Model.ClaudeOpus4_6; + string expectedInferenceGeo = "inference_geo"; Messages::Metadata expectedMetadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b", }; Messages::OutputConfig expectedOutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -1014,6 +1052,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -1028,6 +1067,7 @@ public void FieldRoundtrip_Works() Assert.Equal(expectedMessages[i], model.Messages[i]); } Assert.Equal(expectedModel, model.Model); + Assert.Equal(expectedInferenceGeo, model.InferenceGeo); Assert.Equal(expectedMetadata, model.Metadata); Assert.Equal(expectedOutputConfig, model.OutputConfig); Assert.Equal(expectedServiceTier, model.ServiceTier); @@ -1059,10 +1099,12 @@ public void SerializationRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -1113,6 +1155,7 @@ public void SerializationRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -1134,10 +1177,12 @@ public void FieldRoundtripThroughSerialization_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -1188,6 +1233,7 @@ public void FieldRoundtripThroughSerialization_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -1205,13 +1251,15 @@ public void FieldRoundtripThroughSerialization_Works() [ new() { Content = "Hello, world", Role = Messages::Role.User }, ]; - ApiEnum expectedModel = Messages::Model.ClaudeSonnet4_5_20250929; + ApiEnum expectedModel = Messages::Model.ClaudeOpus4_6; + string expectedInferenceGeo = "inference_geo"; Messages::Metadata expectedMetadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b", }; Messages::OutputConfig expectedOutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -1265,6 +1313,7 @@ public void FieldRoundtripThroughSerialization_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -1279,6 +1328,7 @@ public void FieldRoundtripThroughSerialization_Works() Assert.Equal(expectedMessages[i], deserialized.Messages[i]); } Assert.Equal(expectedModel, deserialized.Model); + Assert.Equal(expectedInferenceGeo, deserialized.InferenceGeo); Assert.Equal(expectedMetadata, deserialized.Metadata); Assert.Equal(expectedOutputConfig, deserialized.OutputConfig); Assert.Equal(expectedServiceTier, deserialized.ServiceTier); @@ -1310,10 +1360,12 @@ public void Validation_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -1364,6 +1416,7 @@ public void Validation_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -1382,7 +1435,8 @@ public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", }; Assert.Null(model.Metadata); @@ -1418,7 +1472,8 @@ public void OptionalNonNullablePropertiesUnsetValidation_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", }; model.Validate(); @@ -1431,7 +1486,8 @@ public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", // Null should be interpreted as omitted for these properties Metadata = null, @@ -1481,7 +1537,8 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", // Null should be interpreted as omitted for these properties Metadata = null, @@ -1501,6 +1558,308 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() model.Validate(); } + [Fact] + public void OptionalNullablePropertiesUnsetAreNotSet_Works() + { + var model = new Params + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeOpus4_6, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + EagerInputStreaming = true, + Strict = true, + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }; + + Assert.Null(model.InferenceGeo); + Assert.False(model.RawData.ContainsKey("inference_geo")); + } + + [Fact] + public void OptionalNullablePropertiesUnsetValidation_Works() + { + var model = new Params + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeOpus4_6, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + EagerInputStreaming = true, + Strict = true, + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }; + + model.Validate(); + } + + [Fact] + public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() + { + var model = new Params + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeOpus4_6, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + EagerInputStreaming = true, + Strict = true, + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + + InferenceGeo = null, + }; + + Assert.Null(model.InferenceGeo); + Assert.True(model.RawData.ContainsKey("inference_geo")); + } + + [Fact] + public void OptionalNullablePropertiesSetToNullValidation_Works() + { + var model = new Params + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeOpus4_6, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + EagerInputStreaming = true, + Strict = true, + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + + InferenceGeo = null, + }; + + model.Validate(); + } + [Fact] public void CopyConstructor_Works() { @@ -1508,10 +1867,12 @@ public void CopyConstructor_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -1562,6 +1923,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, diff --git a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchIndividualResponseTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchIndividualResponseTest.cs index 1023651ce..ece1097e3 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchIndividualResponseTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchIndividualResponseTest.cs @@ -36,7 +36,7 @@ public void FieldRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -48,6 +48,7 @@ public void FieldRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -81,7 +82,7 @@ public void FieldRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -93,6 +94,7 @@ public void FieldRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -134,7 +136,7 @@ public void SerializationRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -146,6 +148,7 @@ public void SerializationRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -193,7 +196,7 @@ public void FieldRoundtripThroughSerialization_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -205,6 +208,7 @@ public void FieldRoundtripThroughSerialization_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -245,7 +249,7 @@ public void FieldRoundtripThroughSerialization_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -257,6 +261,7 @@ public void FieldRoundtripThroughSerialization_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -298,7 +303,7 @@ public void Validation_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -310,6 +315,7 @@ public void Validation_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -351,7 +357,7 @@ public void CopyConstructor_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -363,6 +369,7 @@ public void CopyConstructor_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), diff --git a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchResultTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchResultTest.cs index 46eba2da5..affd11d07 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchResultTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchResultTest.cs @@ -34,7 +34,7 @@ public void SucceededValidationWorks() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -46,6 +46,7 @@ public void SucceededValidationWorks() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -109,7 +110,7 @@ public void SucceededSerializationRoundtripWorks() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -121,6 +122,7 @@ public void SucceededSerializationRoundtripWorks() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), diff --git a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchSucceededResultTest.cs b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchSucceededResultTest.cs index d73d1361d..7f5a2844a 100644 --- a/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchSucceededResultTest.cs +++ b/src/Anthropic.Tests/Models/Messages/Batches/MessageBatchSucceededResultTest.cs @@ -34,7 +34,7 @@ public void FieldRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -46,6 +46,7 @@ public void FieldRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -76,7 +77,7 @@ public void FieldRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -84,6 +85,7 @@ public void FieldRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -123,7 +125,7 @@ public void SerializationRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -135,6 +137,7 @@ public void SerializationRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -179,7 +182,7 @@ public void FieldRoundtripThroughSerialization_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -191,6 +194,7 @@ public void FieldRoundtripThroughSerialization_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -228,7 +232,7 @@ public void FieldRoundtripThroughSerialization_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -236,6 +240,7 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -275,7 +280,7 @@ public void Validation_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -287,6 +292,7 @@ public void Validation_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -325,7 +331,7 @@ public void CopyConstructor_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -337,6 +343,7 @@ public void CopyConstructor_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), diff --git a/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs b/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs index a50be909f..d3471f915 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageCountTokensParamsTest.cs @@ -14,9 +14,10 @@ public void FieldRoundtrip_Works() var parameters = new Messages::MessageCountTokensParams { Messages = [new() { Content = "string", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -63,6 +64,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -73,9 +75,10 @@ public void FieldRoundtrip_Works() [ new() { Content = "string", Role = Messages::Role.User }, ]; - ApiEnum expectedModel = Messages::Model.ClaudeOpus4_5_20251101; + ApiEnum expectedModel = Messages::Model.ClaudeOpus4_6; Messages::OutputConfig expectedOutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -125,6 +128,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -154,7 +158,7 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() var parameters = new Messages::MessageCountTokensParams { Messages = [new() { Content = "string", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, }; Assert.Null(parameters.OutputConfig); @@ -175,7 +179,7 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() var parameters = new Messages::MessageCountTokensParams { Messages = [new() { Content = "string", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, // Null should be interpreted as omitted for these properties OutputConfig = null, @@ -203,7 +207,7 @@ public void Url_Works() Messages::MessageCountTokensParams parameters = new() { Messages = [new() { Content = "string", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, }; var url = parameters.Url(new() { ApiKey = "my-anthropic-api-key" }); @@ -217,9 +221,10 @@ public void CopyConstructor_Works() var parameters = new Messages::MessageCountTokensParams { Messages = [new() { Content = "string", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -266,6 +271,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, diff --git a/src/Anthropic.Tests/Models/Messages/MessageCountTokensToolTest.cs b/src/Anthropic.Tests/Models/Messages/MessageCountTokensToolTest.cs index 4d4d3f07a..9aac03115 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageCountTokensToolTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageCountTokensToolTest.cs @@ -24,6 +24,7 @@ public void ToolValidationWorks() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Type.Custom, }; @@ -113,6 +114,7 @@ public void ToolSerializationRoundtripWorks() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Type.Custom, }; diff --git a/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs b/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs index 0885b5a35..3b740cf28 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageCreateParamsTest.cs @@ -16,10 +16,12 @@ public void FieldRoundtrip_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -69,6 +71,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -82,13 +85,15 @@ public void FieldRoundtrip_Works() [ new() { Content = "Hello, world", Role = Messages::Role.User }, ]; - ApiEnum expectedModel = Messages::Model.ClaudeSonnet4_5_20250929; + ApiEnum expectedModel = Messages::Model.ClaudeOpus4_6; + string expectedInferenceGeo = "inference_geo"; Messages::Metadata expectedMetadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b", }; Messages::OutputConfig expectedOutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -141,6 +146,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, @@ -155,6 +161,7 @@ public void FieldRoundtrip_Works() Assert.Equal(expectedMessages[i], parameters.Messages[i]); } Assert.Equal(expectedModel, parameters.Model); + Assert.Equal(expectedInferenceGeo, parameters.InferenceGeo); Assert.Equal(expectedMetadata, parameters.Metadata); Assert.Equal(expectedOutputConfig, parameters.OutputConfig); Assert.Equal(expectedServiceTier, parameters.ServiceTier); @@ -185,7 +192,8 @@ public void OptionalNonNullableParamsUnsetAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", }; Assert.Null(parameters.Metadata); @@ -219,7 +227,8 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", // Null should be interpreted as omitted for these properties Metadata = null, @@ -259,6 +268,156 @@ public void OptionalNonNullableParamsSetToNullAreNotSet_Works() Assert.False(parameters.RawBodyData.ContainsKey("top_p")); } + [Fact] + public void OptionalNullableParamsUnsetAreNotSet_Works() + { + var parameters = new Messages::MessageCreateParams + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeOpus4_6, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + ServiceTier = Messages::ServiceTier.Auto, + StopSequences = ["string"], + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + EagerInputStreaming = true, + Strict = true, + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }; + + Assert.Null(parameters.InferenceGeo); + Assert.False(parameters.RawBodyData.ContainsKey("inference_geo")); + } + + [Fact] + public void OptionalNullableParamsSetToNullAreSetToNull_Works() + { + var parameters = new Messages::MessageCreateParams + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], + Model = Messages::Model.ClaudeOpus4_6, + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + ServiceTier = Messages::ServiceTier.Auto, + StopSequences = ["string"], + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() { DisableParallelToolUse = true }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { "location", JsonSerializer.SerializeToElement("bar") }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + EagerInputStreaming = true, + Strict = true, + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + + InferenceGeo = null, + }; + + Assert.Null(parameters.InferenceGeo); + Assert.True(parameters.RawBodyData.ContainsKey("inference_geo")); + } + [Fact] public void Url_Works() { @@ -266,7 +425,7 @@ public void Url_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, }; var url = parameters.Url(new() { ApiKey = "my-anthropic-api-key" }); @@ -281,10 +440,12 @@ public void CopyConstructor_Works() { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Messages::Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, + InferenceGeo = "inference_geo", Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, OutputConfig = new() { + Effort = Messages::Effort.Low, Format = new() { Schema = new Dictionary() @@ -334,6 +495,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Messages::Type.Custom, }, diff --git a/src/Anthropic.Tests/Models/Messages/MessageTest.cs b/src/Anthropic.Tests/Models/Messages/MessageTest.cs index 51e428f12..4b0bfb88b 100644 --- a/src/Anthropic.Tests/Models/Messages/MessageTest.cs +++ b/src/Anthropic.Tests/Models/Messages/MessageTest.cs @@ -32,7 +32,7 @@ public void FieldRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -40,6 +40,7 @@ public void FieldRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -67,7 +68,7 @@ public void FieldRoundtrip_Works() Text = "Hi! My name is Claude.", }, ]; - ApiEnum expectedModel = Model.ClaudeSonnet4_5_20250929; + ApiEnum expectedModel = Model.ClaudeOpus4_6; JsonElement expectedRole = JsonSerializer.SerializeToElement("assistant"); ApiEnum expectedStopReason = StopReason.EndTurn; JsonElement expectedType = JsonSerializer.SerializeToElement("message"); @@ -76,6 +77,7 @@ public void FieldRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -121,7 +123,7 @@ public void SerializationRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -129,6 +131,7 @@ public void SerializationRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -167,7 +170,7 @@ public void FieldRoundtripThroughSerialization_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -175,6 +178,7 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -209,7 +213,7 @@ public void FieldRoundtripThroughSerialization_Works() Text = "Hi! My name is Claude.", }, ]; - ApiEnum expectedModel = Model.ClaudeSonnet4_5_20250929; + ApiEnum expectedModel = Model.ClaudeOpus4_6; JsonElement expectedRole = JsonSerializer.SerializeToElement("assistant"); ApiEnum expectedStopReason = StopReason.EndTurn; JsonElement expectedType = JsonSerializer.SerializeToElement("message"); @@ -218,6 +222,7 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -263,7 +268,7 @@ public void Validation_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -271,6 +276,7 @@ public void Validation_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -306,7 +312,7 @@ public void CopyConstructor_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -314,6 +320,7 @@ public void CopyConstructor_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), diff --git a/src/Anthropic.Tests/Models/Messages/ModelTest.cs b/src/Anthropic.Tests/Models/Messages/ModelTest.cs index e8cc0a3d8..09f9c07df 100644 --- a/src/Anthropic.Tests/Models/Messages/ModelTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ModelTest.cs @@ -8,6 +8,7 @@ namespace Anthropic.Tests.Models.Messages; public class ModelTest : TestBase { [Theory] + [InlineData(Model.ClaudeOpus4_6)] [InlineData(Model.ClaudeOpus4_5_20251101)] [InlineData(Model.ClaudeOpus4_5)] [InlineData(Model.Claude3_7SonnetLatest)] @@ -48,6 +49,7 @@ public void InvalidEnumValidationThrows_Works() } [Theory] + [InlineData(Model.ClaudeOpus4_6)] [InlineData(Model.ClaudeOpus4_5_20251101)] [InlineData(Model.ClaudeOpus4_5)] [InlineData(Model.Claude3_7SonnetLatest)] diff --git a/src/Anthropic.Tests/Models/Messages/OutputConfigTest.cs b/src/Anthropic.Tests/Models/Messages/OutputConfigTest.cs index c5fb5c7d8..27f7c1284 100644 --- a/src/Anthropic.Tests/Models/Messages/OutputConfigTest.cs +++ b/src/Anthropic.Tests/Models/Messages/OutputConfigTest.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Text.Json; using Anthropic.Core; +using Anthropic.Exceptions; using Anthropic.Models.Messages; namespace Anthropic.Tests.Models.Messages; @@ -12,6 +13,7 @@ public void FieldRoundtrip_Works() { var model = new OutputConfig { + Effort = Effort.Low, Format = new() { Schema = new Dictionary() @@ -21,6 +23,7 @@ public void FieldRoundtrip_Works() }, }; + ApiEnum expectedEffort = Effort.Low; JsonOutputFormat expectedFormat = new() { Schema = new Dictionary() @@ -29,6 +32,7 @@ public void FieldRoundtrip_Works() }, }; + Assert.Equal(expectedEffort, model.Effort); Assert.Equal(expectedFormat, model.Format); } @@ -37,6 +41,7 @@ public void SerializationRoundtrip_Works() { var model = new OutputConfig { + Effort = Effort.Low, Format = new() { Schema = new Dictionary() @@ -60,6 +65,7 @@ public void FieldRoundtripThroughSerialization_Works() { var model = new OutputConfig { + Effort = Effort.Low, Format = new() { Schema = new Dictionary() @@ -76,6 +82,7 @@ public void FieldRoundtripThroughSerialization_Works() ); Assert.NotNull(deserialized); + ApiEnum expectedEffort = Effort.Low; JsonOutputFormat expectedFormat = new() { Schema = new Dictionary() @@ -84,6 +91,7 @@ public void FieldRoundtripThroughSerialization_Works() }, }; + Assert.Equal(expectedEffort, deserialized.Effort); Assert.Equal(expectedFormat, deserialized.Format); } @@ -92,6 +100,7 @@ public void Validation_Works() { var model = new OutputConfig { + Effort = Effort.Low, Format = new() { Schema = new Dictionary() @@ -109,6 +118,8 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() { var model = new OutputConfig { }; + Assert.Null(model.Effort); + Assert.False(model.RawData.ContainsKey("effort")); Assert.Null(model.Format); Assert.False(model.RawData.ContainsKey("format")); } @@ -124,8 +135,10 @@ public void OptionalNullablePropertiesUnsetValidation_Works() [Fact] public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() { - var model = new OutputConfig { Format = null }; + var model = new OutputConfig { Effort = null, Format = null }; + Assert.Null(model.Effort); + Assert.True(model.RawData.ContainsKey("effort")); Assert.Null(model.Format); Assert.True(model.RawData.ContainsKey("format")); } @@ -133,7 +146,7 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() [Fact] public void OptionalNullablePropertiesSetToNullValidation_Works() { - var model = new OutputConfig { Format = null }; + var model = new OutputConfig { Effort = null, Format = null }; model.Validate(); } @@ -143,6 +156,7 @@ public void CopyConstructor_Works() { var model = new OutputConfig { + Effort = Effort.Low, Format = new() { Schema = new Dictionary() @@ -157,3 +171,65 @@ public void CopyConstructor_Works() Assert.Equal(model, copied); } } + +public class EffortTest : TestBase +{ + [Theory] + [InlineData(Effort.Low)] + [InlineData(Effort.Medium)] + [InlineData(Effort.High)] + [InlineData(Effort.Max)] + public void Validation_Works(Effort rawValue) + { + // force implicit conversion because Theory can't do that for us + ApiEnum value = rawValue; + value.Validate(); + } + + [Fact] + public void InvalidEnumValidationThrows_Works() + { + var value = JsonSerializer.Deserialize>( + JsonSerializer.SerializeToElement("invalid value"), + ModelBase.SerializerOptions + ); + + Assert.NotNull(value); + Assert.Throws(() => value.Validate()); + } + + [Theory] + [InlineData(Effort.Low)] + [InlineData(Effort.Medium)] + [InlineData(Effort.High)] + [InlineData(Effort.Max)] + public void SerializationRoundtrip_Works(Effort rawValue) + { + // force implicit conversion because Theory can't do that for us + ApiEnum value = rawValue; + + string json = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize>( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } + + [Fact] + public void InvalidEnumSerializationRoundtrip_Works() + { + var value = JsonSerializer.Deserialize>( + JsonSerializer.SerializeToElement("invalid value"), + ModelBase.SerializerOptions + ); + string json = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize>( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } +} diff --git a/src/Anthropic.Tests/Models/Messages/RawMessageStartEventTest.cs b/src/Anthropic.Tests/Models/Messages/RawMessageStartEventTest.cs index 13ead7f43..5111252b2 100644 --- a/src/Anthropic.Tests/Models/Messages/RawMessageStartEventTest.cs +++ b/src/Anthropic.Tests/Models/Messages/RawMessageStartEventTest.cs @@ -33,7 +33,7 @@ public void FieldRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -45,6 +45,7 @@ public void FieldRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -75,7 +76,7 @@ public void FieldRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -83,6 +84,7 @@ public void FieldRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -122,7 +124,7 @@ public void SerializationRoundtrip_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -134,6 +136,7 @@ public void SerializationRoundtrip_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -178,7 +181,7 @@ public void FieldRoundtripThroughSerialization_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -190,6 +193,7 @@ public void FieldRoundtripThroughSerialization_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -227,7 +231,7 @@ public void FieldRoundtripThroughSerialization_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -235,6 +239,7 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -274,7 +279,7 @@ public void Validation_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -286,6 +291,7 @@ public void Validation_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -324,7 +330,7 @@ public void CopyConstructor_Works() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -336,6 +342,7 @@ public void CopyConstructor_Works() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), diff --git a/src/Anthropic.Tests/Models/Messages/RawMessageStreamEventTest.cs b/src/Anthropic.Tests/Models/Messages/RawMessageStreamEventTest.cs index aeb9ae198..0441c4814 100644 --- a/src/Anthropic.Tests/Models/Messages/RawMessageStreamEventTest.cs +++ b/src/Anthropic.Tests/Models/Messages/RawMessageStreamEventTest.cs @@ -32,7 +32,7 @@ public void StartValidationWorks() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -44,6 +44,7 @@ public void StartValidationWorks() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -149,7 +150,7 @@ public void StartSerializationRoundtripWorks() Text = "Hi! My name is Claude.", }, ], - Model = Model.ClaudeSonnet4_5_20250929, + Model = Model.ClaudeOpus4_6, StopReason = StopReason.EndTurn, StopSequence = null, Usage = new() @@ -161,6 +162,7 @@ public void StartSerializationRoundtripWorks() }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), diff --git a/src/Anthropic.Tests/Models/Messages/ThinkingConfigAdaptiveTest.cs b/src/Anthropic.Tests/Models/Messages/ThinkingConfigAdaptiveTest.cs new file mode 100644 index 000000000..88196c75c --- /dev/null +++ b/src/Anthropic.Tests/Models/Messages/ThinkingConfigAdaptiveTest.cs @@ -0,0 +1,67 @@ +using System.Text.Json; +using Anthropic.Core; +using Anthropic.Models.Messages; + +namespace Anthropic.Tests.Models.Messages; + +public class ThinkingConfigAdaptiveTest : TestBase +{ + [Fact] + public void FieldRoundtrip_Works() + { + var model = new ThinkingConfigAdaptive { }; + + JsonElement expectedType = JsonSerializer.SerializeToElement("adaptive"); + + Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); + } + + [Fact] + public void SerializationRoundtrip_Works() + { + var model = new ThinkingConfigAdaptive { }; + + string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + json, + ModelBase.SerializerOptions + ); + + Assert.Equal(model, deserialized); + } + + [Fact] + public void FieldRoundtripThroughSerialization_Works() + { + var model = new ThinkingConfigAdaptive { }; + + string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + Assert.NotNull(deserialized); + + JsonElement expectedType = JsonSerializer.SerializeToElement("adaptive"); + + Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); + } + + [Fact] + public void Validation_Works() + { + var model = new ThinkingConfigAdaptive { }; + + model.Validate(); + } + + [Fact] + public void CopyConstructor_Works() + { + var model = new ThinkingConfigAdaptive { }; + + ThinkingConfigAdaptive copied = new(model); + + Assert.Equal(model, copied); + } +} diff --git a/src/Anthropic.Tests/Models/Messages/ThinkingConfigParamTest.cs b/src/Anthropic.Tests/Models/Messages/ThinkingConfigParamTest.cs index 893f3f120..ee58083af 100644 --- a/src/Anthropic.Tests/Models/Messages/ThinkingConfigParamTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ThinkingConfigParamTest.cs @@ -20,6 +20,13 @@ public void DisabledValidationWorks() value.Validate(); } + [Fact] + public void AdaptiveValidationWorks() + { + ThinkingConfigParam value = new ThinkingConfigAdaptive(); + value.Validate(); + } + [Fact] public void EnabledSerializationRoundtripWorks() { @@ -45,4 +52,17 @@ public void DisabledSerializationRoundtripWorks() Assert.Equal(value, deserialized); } + + [Fact] + public void AdaptiveSerializationRoundtripWorks() + { + ThinkingConfigParam value = new ThinkingConfigAdaptive(); + string element = JsonSerializer.Serialize(value, ModelBase.SerializerOptions); + var deserialized = JsonSerializer.Deserialize( + element, + ModelBase.SerializerOptions + ); + + Assert.Equal(value, deserialized); + } } diff --git a/src/Anthropic.Tests/Models/Messages/ToolTest.cs b/src/Anthropic.Tests/Models/Messages/ToolTest.cs index f48303ff8..ebb42a45a 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolTest.cs @@ -25,6 +25,7 @@ public void FieldRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Type.Custom, }; @@ -41,6 +42,7 @@ public void FieldRoundtrip_Works() string expectedName = "name"; CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; string expectedDescription = "Get the current weather in a given location"; + bool expectedEagerInputStreaming = true; bool expectedStrict = true; ApiEnum expectedType = Type.Custom; @@ -48,6 +50,7 @@ public void FieldRoundtrip_Works() Assert.Equal(expectedName, model.Name); Assert.Equal(expectedCacheControl, model.CacheControl); Assert.Equal(expectedDescription, model.Description); + Assert.Equal(expectedEagerInputStreaming, model.EagerInputStreaming); Assert.Equal(expectedStrict, model.Strict); Assert.Equal(expectedType, model.Type); } @@ -69,6 +72,7 @@ public void SerializationRoundtrip_Works() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Type.Custom, }; @@ -96,6 +100,7 @@ public void FieldRoundtripThroughSerialization_Works() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Type.Custom, }; @@ -116,6 +121,7 @@ public void FieldRoundtripThroughSerialization_Works() string expectedName = "name"; CacheControlEphemeral expectedCacheControl = new() { Ttl = Ttl.Ttl5m }; string expectedDescription = "Get the current weather in a given location"; + bool expectedEagerInputStreaming = true; bool expectedStrict = true; ApiEnum expectedType = Type.Custom; @@ -123,6 +129,7 @@ public void FieldRoundtripThroughSerialization_Works() Assert.Equal(expectedName, deserialized.Name); Assert.Equal(expectedCacheControl, deserialized.CacheControl); Assert.Equal(expectedDescription, deserialized.Description); + Assert.Equal(expectedEagerInputStreaming, deserialized.EagerInputStreaming); Assert.Equal(expectedStrict, deserialized.Strict); Assert.Equal(expectedType, deserialized.Type); } @@ -144,6 +151,7 @@ public void Validation_Works() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Type.Custom, }; @@ -167,6 +175,7 @@ public void OptionalNonNullablePropertiesUnsetAreNotSet_Works() }, Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, + EagerInputStreaming = true, Type = Type.Custom, }; @@ -192,6 +201,7 @@ public void OptionalNonNullablePropertiesUnsetValidation_Works() }, Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, + EagerInputStreaming = true, Type = Type.Custom, }; @@ -214,6 +224,7 @@ public void OptionalNonNullablePropertiesSetToNullAreNotSet_Works() }, Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, + EagerInputStreaming = true, Type = Type.Custom, // Null should be interpreted as omitted for these properties @@ -243,6 +254,7 @@ public void OptionalNonNullablePropertiesSetToNullValidation_Works() }, Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, + EagerInputStreaming = true, Type = Type.Custom, // Null should be interpreted as omitted for these properties @@ -274,6 +286,8 @@ public void OptionalNullablePropertiesUnsetAreNotSet_Works() Assert.Null(model.CacheControl); Assert.False(model.RawData.ContainsKey("cache_control")); + Assert.Null(model.EagerInputStreaming); + Assert.False(model.RawData.ContainsKey("eager_input_streaming")); Assert.Null(model.Type); Assert.False(model.RawData.ContainsKey("type")); } @@ -319,11 +333,14 @@ public void OptionalNullablePropertiesSetToNullAreSetToNull_Works() Strict = true, CacheControl = null, + EagerInputStreaming = null, Type = null, }; Assert.Null(model.CacheControl); Assert.True(model.RawData.ContainsKey("cache_control")); + Assert.Null(model.EagerInputStreaming); + Assert.True(model.RawData.ContainsKey("eager_input_streaming")); Assert.Null(model.Type); Assert.True(model.RawData.ContainsKey("type")); } @@ -347,6 +364,7 @@ public void OptionalNullablePropertiesSetToNullValidation_Works() Strict = true, CacheControl = null, + EagerInputStreaming = null, Type = null, }; @@ -370,6 +388,7 @@ public void CopyConstructor_Works() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Type.Custom, }; diff --git a/src/Anthropic.Tests/Models/Messages/ToolUnionTest.cs b/src/Anthropic.Tests/Models/Messages/ToolUnionTest.cs index 4e1ac88f0..08915b966 100644 --- a/src/Anthropic.Tests/Models/Messages/ToolUnionTest.cs +++ b/src/Anthropic.Tests/Models/Messages/ToolUnionTest.cs @@ -24,6 +24,7 @@ public void ToolValidationWorks() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Type.Custom, }; @@ -113,6 +114,7 @@ public void ToolSerializationRoundtripWorks() Name = "name", CacheControl = new() { Ttl = Ttl.Ttl5m }, Description = "Get the current weather in a given location", + EagerInputStreaming = true, Strict = true, Type = Type.Custom, }; diff --git a/src/Anthropic.Tests/Models/Messages/UsageTest.cs b/src/Anthropic.Tests/Models/Messages/UsageTest.cs index b23f80561..4c2acfa7f 100644 --- a/src/Anthropic.Tests/Models/Messages/UsageTest.cs +++ b/src/Anthropic.Tests/Models/Messages/UsageTest.cs @@ -15,6 +15,7 @@ public void FieldRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -28,6 +29,7 @@ public void FieldRoundtrip_Works() }; long expectedCacheCreationInputTokens = 2051; long expectedCacheReadInputTokens = 2051; + string expectedInferenceGeo = "inference_geo"; long expectedInputTokens = 2095; long expectedOutputTokens = 503; ServerToolUsage expectedServerToolUse = new(0); @@ -36,6 +38,7 @@ public void FieldRoundtrip_Works() Assert.Equal(expectedCacheCreation, model.CacheCreation); Assert.Equal(expectedCacheCreationInputTokens, model.CacheCreationInputTokens); Assert.Equal(expectedCacheReadInputTokens, model.CacheReadInputTokens); + Assert.Equal(expectedInferenceGeo, model.InferenceGeo); Assert.Equal(expectedInputTokens, model.InputTokens); Assert.Equal(expectedOutputTokens, model.OutputTokens); Assert.Equal(expectedServerToolUse, model.ServerToolUse); @@ -50,6 +53,7 @@ public void SerializationRoundtrip_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -70,6 +74,7 @@ public void FieldRoundtripThroughSerialization_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -87,6 +92,7 @@ public void FieldRoundtripThroughSerialization_Works() }; long expectedCacheCreationInputTokens = 2051; long expectedCacheReadInputTokens = 2051; + string expectedInferenceGeo = "inference_geo"; long expectedInputTokens = 2095; long expectedOutputTokens = 503; ServerToolUsage expectedServerToolUse = new(0); @@ -95,6 +101,7 @@ public void FieldRoundtripThroughSerialization_Works() Assert.Equal(expectedCacheCreation, deserialized.CacheCreation); Assert.Equal(expectedCacheCreationInputTokens, deserialized.CacheCreationInputTokens); Assert.Equal(expectedCacheReadInputTokens, deserialized.CacheReadInputTokens); + Assert.Equal(expectedInferenceGeo, deserialized.InferenceGeo); Assert.Equal(expectedInputTokens, deserialized.InputTokens); Assert.Equal(expectedOutputTokens, deserialized.OutputTokens); Assert.Equal(expectedServerToolUse, deserialized.ServerToolUse); @@ -109,6 +116,7 @@ public void Validation_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), @@ -126,6 +134,7 @@ public void CopyConstructor_Works() CacheCreation = new() { Ephemeral1hInputTokens = 0, Ephemeral5mInputTokens = 0 }, CacheCreationInputTokens = 2051, CacheReadInputTokens = 2051, + InferenceGeo = "inference_geo", InputTokens = 2095, OutputTokens = 503, ServerToolUse = new(0), diff --git a/src/Anthropic.Tests/Models/Models/ModelInfoTest.cs b/src/Anthropic.Tests/Models/Models/ModelInfoTest.cs index 906ddb457..a8c6df7c2 100644 --- a/src/Anthropic.Tests/Models/Models/ModelInfoTest.cs +++ b/src/Anthropic.Tests/Models/Models/ModelInfoTest.cs @@ -12,14 +12,14 @@ public void FieldRoundtrip_Works() { var model = new ModelInfo { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }; - string expectedID = "claude-sonnet-4-20250514"; - DateTimeOffset expectedCreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"); - string expectedDisplayName = "Claude Sonnet 4"; + string expectedID = "claude-opus-4-6"; + DateTimeOffset expectedCreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"); + string expectedDisplayName = "Claude Opus 4.6"; JsonElement expectedType = JsonSerializer.SerializeToElement("model"); Assert.Equal(expectedID, model.ID); @@ -33,9 +33,9 @@ public void SerializationRoundtrip_Works() { var model = new ModelInfo { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }; string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); @@ -49,9 +49,9 @@ public void FieldRoundtripThroughSerialization_Works() { var model = new ModelInfo { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }; string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); @@ -61,9 +61,9 @@ public void FieldRoundtripThroughSerialization_Works() ); Assert.NotNull(deserialized); - string expectedID = "claude-sonnet-4-20250514"; - DateTimeOffset expectedCreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"); - string expectedDisplayName = "Claude Sonnet 4"; + string expectedID = "claude-opus-4-6"; + DateTimeOffset expectedCreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"); + string expectedDisplayName = "Claude Opus 4.6"; JsonElement expectedType = JsonSerializer.SerializeToElement("model"); Assert.Equal(expectedID, deserialized.ID); @@ -77,9 +77,9 @@ public void Validation_Works() { var model = new ModelInfo { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }; model.Validate(); @@ -90,9 +90,9 @@ public void CopyConstructor_Works() { var model = new ModelInfo { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }; ModelInfo copied = new(model); diff --git a/src/Anthropic.Tests/Models/Models/ModelListPageResponseTest.cs b/src/Anthropic.Tests/Models/Models/ModelListPageResponseTest.cs index 2cdb37e2d..7094a0475 100644 --- a/src/Anthropic.Tests/Models/Models/ModelListPageResponseTest.cs +++ b/src/Anthropic.Tests/Models/Models/ModelListPageResponseTest.cs @@ -17,9 +17,9 @@ public void FieldRoundtrip_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ], FirstID = "first_id", @@ -31,9 +31,9 @@ public void FieldRoundtrip_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ]; string expectedFirstID = "first_id"; @@ -59,9 +59,9 @@ public void SerializationRoundtrip_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ], FirstID = "first_id", @@ -87,9 +87,9 @@ public void FieldRoundtripThroughSerialization_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ], FirstID = "first_id", @@ -108,9 +108,9 @@ public void FieldRoundtripThroughSerialization_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ]; string expectedFirstID = "first_id"; @@ -136,9 +136,9 @@ public void Validation_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ], FirstID = "first_id", @@ -158,9 +158,9 @@ public void CopyConstructor_Works() [ new() { - ID = "claude-sonnet-4-20250514", - CreatedAt = DateTimeOffset.Parse("2025-02-19T00:00:00Z"), - DisplayName = "Claude Sonnet 4", + ID = "claude-opus-4-6", + CreatedAt = DateTimeOffset.Parse("2026-02-04T00:00:00Z"), + DisplayName = "Claude Opus 4.6", }, ], FirstID = "first_id", diff --git a/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs b/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs index 4d7a00cd2..56181335b 100644 --- a/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs +++ b/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs @@ -16,7 +16,7 @@ public async Task Create_Works(IAnthropicClient client) { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, }, TestContext.Current.CancellationToken ); @@ -32,7 +32,7 @@ public async Task CreateStreaming_Works(IAnthropicClient client) { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, }, TestContext.Current.CancellationToken ); @@ -51,7 +51,7 @@ public async Task CountTokens_Works(IAnthropicClient client) new() { Messages = [new() { Content = "string", Role = Role.User }], - Model = Messages::Model.ClaudeOpus4_5_20251101, + Model = Messages::Model.ClaudeOpus4_6, }, TestContext.Current.CancellationToken ); diff --git a/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs b/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs index 376f3588b..20fb2f5e6 100644 --- a/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs +++ b/src/Anthropic.Tests/Services/Beta/Messages/BatchServiceTest.cs @@ -25,7 +25,7 @@ public async Task Create_Works(IAnthropicClient client) { MaxTokens = 1024, Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = Messages::Model.ClaudeSonnet4_5_20250929, + Model = Messages::Model.ClaudeOpus4_6, Container = new BetaContainerParams() { ID = "id", @@ -53,6 +53,7 @@ public async Task Create_Works(IAnthropicClient client) }, ], }, + InferenceGeo = "inference_geo", McpServers = [ new() @@ -133,6 +134,7 @@ public async Task Create_Works(IAnthropicClient client) CacheControl = new() { Ttl = Ttl.Ttl5m }, DeferLoading = true, Description = "Get the current weather in a given location", + EagerInputStreaming = true, InputExamples = [ new Dictionary() diff --git a/src/Anthropic.Tests/Services/MessageServiceTest.cs b/src/Anthropic.Tests/Services/MessageServiceTest.cs index 1ba047f21..5cf967098 100644 --- a/src/Anthropic.Tests/Services/MessageServiceTest.cs +++ b/src/Anthropic.Tests/Services/MessageServiceTest.cs @@ -1,67 +1,67 @@ -using System.Threading.Tasks; -using Anthropic.Bedrock; -using Anthropic.Models.Messages; - -namespace Anthropic.Tests.Services; - -public class MessageServiceTest -{ - [Theory] - [AnthropicTestClients] - [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] - [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] - [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] - public async Task Create_Works(IAnthropicClient client, string modelName) - { - var message = await client.Messages.Create( - new MessageCreateParams() - { - MaxTokens = 1024, - Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = modelName, - }, - TestContext.Current.CancellationToken - ); - message.Validate(); - } - - [Theory] - [AnthropicTestClients] - [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] - [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] - [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] - public async Task CreateStreaming_Works(IAnthropicClient client, string modelName) - { - var stream = client.Messages.CreateStreaming( - new() - { - MaxTokens = 1024, - Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = modelName, - }, - TestContext.Current.CancellationToken - ); - - await foreach (var message in stream) - { - message.Validate(); - } - } - - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] - [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] - public async Task CountTokens_Works(IAnthropicClient client, string modelName) - { - var messageTokensCount = await client.Messages.CountTokens( - new() - { - Messages = [new() { Content = "string", Role = Role.User }], - Model = modelName, - }, - TestContext.Current.CancellationToken - ); - messageTokensCount.Validate(); - } -} +using System.Threading.Tasks; +using Anthropic.Bedrock; +using Anthropic.Models.Messages; + +namespace Anthropic.Tests.Services; + +public class MessageServiceTest +{ + [Theory] + [AnthropicTestClients] + [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] + [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] + public async Task Create_Works(IAnthropicClient client, string modelName) + { + var message = await client.Messages.Create( + new MessageCreateParams() + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Role.User }], + Model = modelName, + }, + TestContext.Current.CancellationToken + ); + message.Validate(); + } + + [Theory] + [AnthropicTestClients] + [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] + [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] + public async Task CreateStreaming_Works(IAnthropicClient client, string modelName) + { + var stream = client.Messages.CreateStreaming( + new() + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Role.User }], + Model = modelName, + }, + TestContext.Current.CancellationToken + ); + + await foreach (var message in stream) + { + message.Validate(); + } + } + + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] + [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + public async Task CountTokens_Works(IAnthropicClient client, string modelName) + { + var messageTokensCount = await client.Messages.CountTokens( + new() + { + Messages = [new() { Content = "string", Role = Role.User }], + Model = modelName, + }, + TestContext.Current.CancellationToken + ); + messageTokensCount.Validate(); + } +} diff --git a/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs b/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs index a2c5642df..ce8171834 100644 --- a/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs +++ b/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs @@ -1,167 +1,167 @@ -using System.Collections.Generic; -using System.Text.Json; -using System.Threading.Tasks; -using Anthropic.Models.Messages.Batches; -using Anthropic.Tests; -using Messages = Anthropic.Models.Messages; - -namespace Anthropic.Tests.Services.Messages; - -public class BatchServiceTest -{ - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] - [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] - public async Task Create_Works(IAnthropicClient client, string modelName) - { - var messageBatch = await client.Messages.Batches.Create( - new() - { - Requests = - [ - new() - { - CustomID = "my-custom-id-1", - Params = new() - { - MaxTokens = 1024, - Messages = - [ - new() { Content = "Hello, world", Role = Messages::Role.User }, - ], - Model = modelName, - Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() - { - Format = new() - { - Schema = new Dictionary() - { - { "foo", JsonSerializer.SerializeToElement("bar") }, - }, - }, - }, - ServiceTier = ServiceTier.Auto, - StopSequences = ["string"], - Stream = true, - System = new( - [ - new Messages::TextBlockParam() - { - Text = "Today's date is 2024-06-01.", - CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, - Citations = - [ - new Messages::CitationCharLocationParam() - { - CitedText = "cited_text", - DocumentIndex = 0, - DocumentTitle = "x", - EndCharIndex = 0, - StartCharIndex = 0, - }, - ], - }, - ] - ), - Temperature = 1, - Thinking = new Messages::ThinkingConfigEnabled(1024), - ToolChoice = new Messages::ToolChoiceAuto() - { - DisableParallelToolUse = true, - }, - Tools = - [ - new Messages::Tool() - { - InputSchema = new() - { - Properties = new Dictionary() - { - { - "location", - JsonSerializer.SerializeToElement("bar") - }, - { "unit", JsonSerializer.SerializeToElement("bar") }, - }, - Required = ["location"], - }, - Name = "name", - CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, - Description = "Get the current weather in a given location", - Strict = true, - Type = Messages::Type.Custom, - }, - ], - TopK = 5, - TopP = 0.7, - }, - }, - ], - }, - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - public async Task Retrieve_Works(IAnthropicClient client) - { - var messageBatch = await client.Messages.Batches.Retrieve( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - public async Task List_Works(IAnthropicClient client) - { - var page = await client.Messages.Batches.List(new(), TestContext.Current.CancellationToken); - page.Validate(); - } - - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - public async Task Delete_Works(IAnthropicClient client) - { - var deletedMessageBatch = await client.Messages.Batches.Delete( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - deletedMessageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - public async Task Cancel_Works(IAnthropicClient client) - { - var messageBatch = await client.Messages.Batches.Cancel( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory(Skip = "Prism doesn't support application/x-jsonl responses")] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - public async Task ResultsStreaming_Works(IAnthropicClient client) - { - var stream = client.Messages.Batches.ResultsStreaming( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - - await foreach (var messageBatchIndividualResponse in stream) - { - messageBatchIndividualResponse.Validate(); - } - } -} +using System.Collections.Generic; +using System.Text.Json; +using System.Threading.Tasks; +using Anthropic.Models.Messages.Batches; +using Anthropic.Tests; +using Messages = Anthropic.Models.Messages; + +namespace Anthropic.Tests.Services.Messages; + +public class BatchServiceTest +{ + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] + [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + public async Task Create_Works(IAnthropicClient client, string modelName) + { + var messageBatch = await client.Messages.Batches.Create( + new() + { + Requests = + [ + new() + { + CustomID = "my-custom-id-1", + Params = new() + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Role.User }], + Model = modelName, + InferenceGeo = "inference_geo", + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() + { + DisableParallelToolUse = true, + }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { + "location", + JsonSerializer.SerializeToElement("bar") + }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + EagerInputStreaming = true, + Strict = true, + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }, + }, + ], + }, + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + public async Task Retrieve_Works(IAnthropicClient client) + { + var messageBatch = await client.Messages.Batches.Retrieve( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + public async Task List_Works(IAnthropicClient client) + { + var page = await client.Messages.Batches.List(new(), TestContext.Current.CancellationToken); + page.Validate(); + } + + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + public async Task Delete_Works(IAnthropicClient client) + { + var deletedMessageBatch = await client.Messages.Batches.Delete( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + deletedMessageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + public async Task Cancel_Works(IAnthropicClient client) + { + var messageBatch = await client.Messages.Batches.Cancel( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory(Skip = "Prism doesn't support application/x-jsonl responses")] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + public async Task ResultsStreaming_Works(IAnthropicClient client) + { + var stream = client.Messages.Batches.ResultsStreaming( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + + await foreach (var messageBatchIndividualResponse in stream) + { + messageBatchIndividualResponse.Validate(); + } + } +} diff --git a/src/Anthropic/Core/ModelBase.cs b/src/Anthropic/Core/ModelBase.cs index 861864129..754478e4e 100644 --- a/src/Anthropic/Core/ModelBase.cs +++ b/src/Anthropic/Core/ModelBase.cs @@ -30,6 +30,7 @@ protected ModelBase(ModelBase modelBase) new ApiEnumConverter(), new ApiEnumConverter(), new ApiEnumConverter(), + new ApiEnumConverter(), new ApiEnumConverter(), new ApiEnumConverter(), new ApiEnumConverter(), diff --git a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs index 0a5095193..1558fde23 100644 --- a/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/Batches/BatchCreateParams.cs @@ -405,6 +405,20 @@ public BetaContextManagementConfig? ContextManagement init { this._rawData.Set("context_management", value); } } + /// + /// Specifies the geographic region for inference processing. If not specified, + /// the workspace's `default_inference_geo` is used. + /// + public string? InferenceGeo + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("inference_geo"); + } + init { this._rawData.Set("inference_geo", value); } + } + /// /// MCP servers to be utilized in this request /// @@ -809,6 +823,7 @@ public override void Validate() this.Model.Validate(); this.Container?.Validate(); this.ContextManagement?.Validate(); + _ = this.InferenceGeo; foreach (var item in this.McpServers ?? []) { item.Validate(); diff --git a/src/Anthropic/Models/Beta/Messages/BetaCompact20260112Edit.cs b/src/Anthropic/Models/Beta/Messages/BetaCompact20260112Edit.cs new file mode 100644 index 000000000..1d415afba --- /dev/null +++ b/src/Anthropic/Models/Beta/Messages/BetaCompact20260112Edit.cs @@ -0,0 +1,132 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Models.Beta.Messages; + +/// +/// Automatically compact older context when reaching the configured trigger threshold. +/// +[JsonConverter(typeof(JsonModelConverter))] +public sealed record class BetaCompact20260112Edit : JsonModel +{ + public JsonElement Type + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("type"); + } + init { this._rawData.Set("type", value); } + } + + /// + /// Additional instructions for summarization. + /// + public string? Instructions + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("instructions"); + } + init { this._rawData.Set("instructions", value); } + } + + /// + /// Whether to pause after compaction and return the compaction block to the user. + /// + public bool? PauseAfterCompaction + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct("pause_after_compaction"); + } + init + { + if (value == null) + { + return; + } + + this._rawData.Set("pause_after_compaction", value); + } + } + + /// + /// When to trigger compaction. Defaults to 150000 input tokens. + /// + public BetaInputTokensTrigger? Trigger + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("trigger"); + } + init { this._rawData.Set("trigger", value); } + } + + /// + public override void Validate() + { + if ( + !JsonElement.DeepEquals( + this.Type, + JsonSerializer.SerializeToElement("compact_20260112") + ) + ) + { + throw new AnthropicInvalidDataException("Invalid value given for constant"); + } + _ = this.Instructions; + _ = this.PauseAfterCompaction; + this.Trigger?.Validate(); + } + + public BetaCompact20260112Edit() + { + this.Type = JsonSerializer.SerializeToElement("compact_20260112"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + public BetaCompact20260112Edit(BetaCompact20260112Edit betaCompact20260112Edit) + : base(betaCompact20260112Edit) { } +#pragma warning restore CS8618 + + public BetaCompact20260112Edit(IReadOnlyDictionary rawData) + { + this._rawData = new(rawData); + + this.Type = JsonSerializer.SerializeToElement("compact_20260112"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + BetaCompact20260112Edit(FrozenDictionary rawData) + { + this._rawData = new(rawData); + } +#pragma warning restore CS8618 + + /// + public static BetaCompact20260112Edit FromRawUnchecked( + IReadOnlyDictionary rawData + ) + { + return new(FrozenDictionary.ToFrozenDictionary(rawData)); + } +} + +class BetaCompact20260112EditFromRaw : IFromRawJson +{ + /// + public BetaCompact20260112Edit FromRawUnchecked( + IReadOnlyDictionary rawData + ) => BetaCompact20260112Edit.FromRawUnchecked(rawData); +} diff --git a/src/Anthropic/Models/Beta/Messages/BetaCompactionBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaCompactionBlock.cs new file mode 100644 index 000000000..eb8d6e201 --- /dev/null +++ b/src/Anthropic/Models/Beta/Messages/BetaCompactionBlock.cs @@ -0,0 +1,101 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Models.Beta.Messages; + +/// +/// A compaction block returned when autocompact is triggered. +/// +/// When content is None, it indicates the compaction failed to produce a valid +/// summary (e.g., malformed output from the model). Clients may round-trip compaction +/// blocks with null content; the server treats them as no-ops. +/// +[JsonConverter(typeof(JsonModelConverter))] +public sealed record class BetaCompactionBlock : JsonModel +{ + /// + /// Summary of compacted content, or null if compaction failed + /// + public required string? Content + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("content"); + } + init { this._rawData.Set("content", value); } + } + + public JsonElement Type + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("type"); + } + init { this._rawData.Set("type", value); } + } + + /// + public override void Validate() + { + _ = this.Content; + if (!JsonElement.DeepEquals(this.Type, JsonSerializer.SerializeToElement("compaction"))) + { + throw new AnthropicInvalidDataException("Invalid value given for constant"); + } + } + + public BetaCompactionBlock() + { + this.Type = JsonSerializer.SerializeToElement("compaction"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + public BetaCompactionBlock(BetaCompactionBlock betaCompactionBlock) + : base(betaCompactionBlock) { } +#pragma warning restore CS8618 + + public BetaCompactionBlock(IReadOnlyDictionary rawData) + { + this._rawData = new(rawData); + + this.Type = JsonSerializer.SerializeToElement("compaction"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + BetaCompactionBlock(FrozenDictionary rawData) + { + this._rawData = new(rawData); + } +#pragma warning restore CS8618 + + /// + public static BetaCompactionBlock FromRawUnchecked( + IReadOnlyDictionary rawData + ) + { + return new(FrozenDictionary.ToFrozenDictionary(rawData)); + } + + [SetsRequiredMembers] + public BetaCompactionBlock(string? content) + : this() + { + this.Content = content; + } +} + +class BetaCompactionBlockFromRaw : IFromRawJson +{ + /// + public BetaCompactionBlock FromRawUnchecked(IReadOnlyDictionary rawData) => + BetaCompactionBlock.FromRawUnchecked(rawData); +} diff --git a/src/Anthropic/Models/Beta/Messages/BetaCompactionBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaCompactionBlockParam.cs new file mode 100644 index 000000000..3fc3e9260 --- /dev/null +++ b/src/Anthropic/Models/Beta/Messages/BetaCompactionBlockParam.cs @@ -0,0 +1,120 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Models.Beta.Messages; + +/// +/// A compaction block containing summary of previous context. +/// +/// Users should round-trip these blocks from responses to subsequent requests +/// to maintain context across compaction boundaries. +/// +/// When content is None, the block represents a failed compaction. The server +/// treats these as no-ops. Empty string content is not allowed. +/// +[JsonConverter( + typeof(JsonModelConverter) +)] +public sealed record class BetaCompactionBlockParam : JsonModel +{ + /// + /// Summary of previously compacted content, or null if compaction failed + /// + public required string? Content + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("content"); + } + init { this._rawData.Set("content", value); } + } + + public JsonElement Type + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("type"); + } + init { this._rawData.Set("type", value); } + } + + /// + /// Create a cache control breakpoint at this content block. + /// + public BetaCacheControlEphemeral? CacheControl + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("cache_control"); + } + init { this._rawData.Set("cache_control", value); } + } + + /// + public override void Validate() + { + _ = this.Content; + if (!JsonElement.DeepEquals(this.Type, JsonSerializer.SerializeToElement("compaction"))) + { + throw new AnthropicInvalidDataException("Invalid value given for constant"); + } + this.CacheControl?.Validate(); + } + + public BetaCompactionBlockParam() + { + this.Type = JsonSerializer.SerializeToElement("compaction"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + public BetaCompactionBlockParam(BetaCompactionBlockParam betaCompactionBlockParam) + : base(betaCompactionBlockParam) { } +#pragma warning restore CS8618 + + public BetaCompactionBlockParam(IReadOnlyDictionary rawData) + { + this._rawData = new(rawData); + + this.Type = JsonSerializer.SerializeToElement("compaction"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + BetaCompactionBlockParam(FrozenDictionary rawData) + { + this._rawData = new(rawData); + } +#pragma warning restore CS8618 + + /// + public static BetaCompactionBlockParam FromRawUnchecked( + IReadOnlyDictionary rawData + ) + { + return new(FrozenDictionary.ToFrozenDictionary(rawData)); + } + + [SetsRequiredMembers] + public BetaCompactionBlockParam(string? content) + : this() + { + this.Content = content; + } +} + +class BetaCompactionBlockParamFromRaw : IFromRawJson +{ + /// + public BetaCompactionBlockParam FromRawUnchecked( + IReadOnlyDictionary rawData + ) => BetaCompactionBlockParam.FromRawUnchecked(rawData); +} diff --git a/src/Anthropic/Models/Beta/Messages/BetaCompactionContentBlockDelta.cs b/src/Anthropic/Models/Beta/Messages/BetaCompactionContentBlockDelta.cs new file mode 100644 index 000000000..cdbbf4a3b --- /dev/null +++ b/src/Anthropic/Models/Beta/Messages/BetaCompactionContentBlockDelta.cs @@ -0,0 +1,104 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Models.Beta.Messages; + +[JsonConverter( + typeof(JsonModelConverter< + BetaCompactionContentBlockDelta, + BetaCompactionContentBlockDeltaFromRaw + >) +)] +public sealed record class BetaCompactionContentBlockDelta : JsonModel +{ + public required string? Content + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("content"); + } + init { this._rawData.Set("content", value); } + } + + public JsonElement Type + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("type"); + } + init { this._rawData.Set("type", value); } + } + + /// + public override void Validate() + { + _ = this.Content; + if ( + !JsonElement.DeepEquals( + this.Type, + JsonSerializer.SerializeToElement("compaction_delta") + ) + ) + { + throw new AnthropicInvalidDataException("Invalid value given for constant"); + } + } + + public BetaCompactionContentBlockDelta() + { + this.Type = JsonSerializer.SerializeToElement("compaction_delta"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + public BetaCompactionContentBlockDelta( + BetaCompactionContentBlockDelta betaCompactionContentBlockDelta + ) + : base(betaCompactionContentBlockDelta) { } +#pragma warning restore CS8618 + + public BetaCompactionContentBlockDelta(IReadOnlyDictionary rawData) + { + this._rawData = new(rawData); + + this.Type = JsonSerializer.SerializeToElement("compaction_delta"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + BetaCompactionContentBlockDelta(FrozenDictionary rawData) + { + this._rawData = new(rawData); + } +#pragma warning restore CS8618 + + /// + public static BetaCompactionContentBlockDelta FromRawUnchecked( + IReadOnlyDictionary rawData + ) + { + return new(FrozenDictionary.ToFrozenDictionary(rawData)); + } + + [SetsRequiredMembers] + public BetaCompactionContentBlockDelta(string? content) + : this() + { + this.Content = content; + } +} + +class BetaCompactionContentBlockDeltaFromRaw : IFromRawJson +{ + /// + public BetaCompactionContentBlockDelta FromRawUnchecked( + IReadOnlyDictionary rawData + ) => BetaCompactionContentBlockDelta.FromRawUnchecked(rawData); +} diff --git a/src/Anthropic/Models/Beta/Messages/BetaCompactionIterationUsage.cs b/src/Anthropic/Models/Beta/Messages/BetaCompactionIterationUsage.cs new file mode 100644 index 000000000..dc8c98beb --- /dev/null +++ b/src/Anthropic/Models/Beta/Messages/BetaCompactionIterationUsage.cs @@ -0,0 +1,152 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Models.Beta.Messages; + +/// +/// Token usage for a compaction iteration. +/// +[JsonConverter( + typeof(JsonModelConverter) +)] +public sealed record class BetaCompactionIterationUsage : JsonModel +{ + /// + /// Breakdown of cached tokens by TTL + /// + public required BetaCacheCreation? CacheCreation + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("cache_creation"); + } + init { this._rawData.Set("cache_creation", value); } + } + + /// + /// The number of input tokens used to create the cache entry. + /// + public required long CacheCreationInputTokens + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("cache_creation_input_tokens"); + } + init { this._rawData.Set("cache_creation_input_tokens", value); } + } + + /// + /// The number of input tokens read from the cache. + /// + public required long CacheReadInputTokens + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("cache_read_input_tokens"); + } + init { this._rawData.Set("cache_read_input_tokens", value); } + } + + /// + /// The number of input tokens which were used. + /// + public required long InputTokens + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("input_tokens"); + } + init { this._rawData.Set("input_tokens", value); } + } + + /// + /// The number of output tokens which were used. + /// + public required long OutputTokens + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("output_tokens"); + } + init { this._rawData.Set("output_tokens", value); } + } + + /// + /// Usage for a compaction iteration + /// + public JsonElement Type + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("type"); + } + init { this._rawData.Set("type", value); } + } + + /// + public override void Validate() + { + this.CacheCreation?.Validate(); + _ = this.CacheCreationInputTokens; + _ = this.CacheReadInputTokens; + _ = this.InputTokens; + _ = this.OutputTokens; + if (!JsonElement.DeepEquals(this.Type, JsonSerializer.SerializeToElement("compaction"))) + { + throw new AnthropicInvalidDataException("Invalid value given for constant"); + } + } + + public BetaCompactionIterationUsage() + { + this.Type = JsonSerializer.SerializeToElement("compaction"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + public BetaCompactionIterationUsage(BetaCompactionIterationUsage betaCompactionIterationUsage) + : base(betaCompactionIterationUsage) { } +#pragma warning restore CS8618 + + public BetaCompactionIterationUsage(IReadOnlyDictionary rawData) + { + this._rawData = new(rawData); + + this.Type = JsonSerializer.SerializeToElement("compaction"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + BetaCompactionIterationUsage(FrozenDictionary rawData) + { + this._rawData = new(rawData); + } +#pragma warning restore CS8618 + + /// + public static BetaCompactionIterationUsage FromRawUnchecked( + IReadOnlyDictionary rawData + ) + { + return new(FrozenDictionary.ToFrozenDictionary(rawData)); + } +} + +class BetaCompactionIterationUsageFromRaw : IFromRawJson +{ + /// + public BetaCompactionIterationUsage FromRawUnchecked( + IReadOnlyDictionary rawData + ) => BetaCompactionIterationUsage.FromRawUnchecked(rawData); +} diff --git a/src/Anthropic/Models/Beta/Messages/BetaContentBlock.cs b/src/Anthropic/Models/Beta/Messages/BetaContentBlock.cs index 673a75333..1a233f70b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContentBlock.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContentBlock.cs @@ -46,7 +46,8 @@ public JsonElement Type toolSearchToolResult: (x) => x.Type, mcpToolUse: (x) => x.Type, mcpToolResult: (x) => x.Type, - containerUpload: (x) => x.Type + containerUpload: (x) => x.Type, + compaction: (x) => x.Type ); } } @@ -69,7 +70,8 @@ public string? ID toolSearchToolResult: (_) => null, mcpToolUse: (x) => x.ID, mcpToolResult: (_) => null, - containerUpload: (_) => null + containerUpload: (_) => null, + compaction: (_) => null ); } } @@ -92,7 +94,8 @@ public string? ToolUseID toolSearchToolResult: (x) => x.ToolUseID, mcpToolUse: (_) => null, mcpToolResult: (x) => x.ToolUseID, - containerUpload: (_) => null + containerUpload: (_) => null, + compaction: (_) => null ); } } @@ -184,6 +187,12 @@ public BetaContentBlock(BetaContainerUploadBlock value, JsonElement? element = n this._element = element; } + public BetaContentBlock(BetaCompactionBlock value, JsonElement? element = null) + { + this.Value = value; + this._element = element; + } + public BetaContentBlock(JsonElement element) { this._element = element; @@ -495,6 +504,27 @@ public bool TryPickContainerUpload([NotNullWhen(true)] out BetaContainerUploadBl return value != null; } + /// + /// Returns true and sets the out parameter if the instance was constructed with a variant of + /// type . + /// + /// Consider using or if you need to handle every variant. + /// + /// + /// + /// if (instance.TryPickCompaction(out var value)) { + /// // `value` is of type `BetaCompactionBlock` + /// Console.WriteLine(value); + /// } + /// + /// + /// + public bool TryPickCompaction([NotNullWhen(true)] out BetaCompactionBlock? value) + { + value = this.Value as BetaCompactionBlock; + return value != null; + } + /// /// Calls the function parameter corresponding to the variant the instance was constructed with. /// @@ -522,7 +552,8 @@ public bool TryPickContainerUpload([NotNullWhen(true)] out BetaContainerUploadBl /// (BetaToolSearchToolResultBlock value) => {...}, /// (BetaMcpToolUseBlock value) => {...}, /// (BetaMcpToolResultBlock value) => {...}, - /// (BetaContainerUploadBlock value) => {...} + /// (BetaContainerUploadBlock value) => {...}, + /// (BetaCompactionBlock value) => {...} /// ); /// /// @@ -541,7 +572,8 @@ public void Switch( System::Action toolSearchToolResult, System::Action mcpToolUse, System::Action mcpToolResult, - System::Action containerUpload + System::Action containerUpload, + System::Action compaction ) { switch (this.Value) @@ -588,6 +620,9 @@ public void Switch( case BetaContainerUploadBlock value: containerUpload(value); break; + case BetaCompactionBlock value: + compaction(value); + break; default: throw new AnthropicInvalidDataException( "Data did not match any variant of BetaContentBlock" @@ -623,7 +658,8 @@ public void Switch( /// (BetaToolSearchToolResultBlock value) => {...}, /// (BetaMcpToolUseBlock value) => {...}, /// (BetaMcpToolResultBlock value) => {...}, - /// (BetaContainerUploadBlock value) => {...} + /// (BetaContainerUploadBlock value) => {...}, + /// (BetaCompactionBlock value) => {...} /// ); /// /// @@ -645,7 +681,8 @@ public T Match( System::Func toolSearchToolResult, System::Func mcpToolUse, System::Func mcpToolResult, - System::Func containerUpload + System::Func containerUpload, + System::Func compaction ) { return this.Value switch @@ -666,6 +703,7 @@ public T Match( BetaMcpToolUseBlock value => mcpToolUse(value), BetaMcpToolResultBlock value => mcpToolResult(value), BetaContainerUploadBlock value => containerUpload(value), + BetaCompactionBlock value => compaction(value), _ => throw new AnthropicInvalidDataException( "Data did not match any variant of BetaContentBlock" ), @@ -707,6 +745,8 @@ public static implicit operator BetaContentBlock(BetaToolSearchToolResultBlock v public static implicit operator BetaContentBlock(BetaContainerUploadBlock value) => new(value); + public static implicit operator BetaContentBlock(BetaCompactionBlock value) => new(value); + /// /// Validates that the instance was constructed with a known variant and that this variant is valid /// (based on its own Validate method). @@ -739,7 +779,8 @@ public override void Validate() (toolSearchToolResult) => toolSearchToolResult.Validate(), (mcpToolUse) => mcpToolUse.Validate(), (mcpToolResult) => mcpToolResult.Validate(), - (containerUpload) => containerUpload.Validate() + (containerUpload) => containerUpload.Validate(), + (compaction) => compaction.Validate() ); } @@ -774,6 +815,7 @@ int VariantIndex() BetaMcpToolUseBlock _ => 11, BetaMcpToolResultBlock _ => 12, BetaContainerUploadBlock _ => 13, + BetaCompactionBlock _ => 14, _ => -1, }; } @@ -1107,6 +1149,28 @@ JsonSerializerOptions options return new(element); } + case "compaction": + { + try + { + var deserialized = JsonSerializer.Deserialize( + element, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new(deserialized, element); + } + } + catch (System::Exception e) + when (e is JsonException || e is AnthropicInvalidDataException) + { + // ignore + } + + return new(element); + } default: { return new BetaContentBlock(element); diff --git a/src/Anthropic/Models/Beta/Messages/BetaContentBlockParam.cs b/src/Anthropic/Models/Beta/Messages/BetaContentBlockParam.cs index 334e7f380..af08e0ee7 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContentBlockParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContentBlockParam.cs @@ -50,7 +50,8 @@ public JsonElement Type toolSearchToolResult: (x) => x.Type, mcpToolUse: (x) => x.Type, requestMcpToolResult: (x) => x.Type, - containerUpload: (x) => x.Type + containerUpload: (x) => x.Type, + compaction: (x) => x.Type ); } } @@ -77,7 +78,8 @@ public BetaCacheControlEphemeral? CacheControl toolSearchToolResult: (x) => x.CacheControl, mcpToolUse: (x) => x.CacheControl, requestMcpToolResult: (x) => x.CacheControl, - containerUpload: (x) => x.CacheControl + containerUpload: (x) => x.CacheControl, + compaction: (x) => x.CacheControl ); } } @@ -104,7 +106,8 @@ public string? Title toolSearchToolResult: (_) => null, mcpToolUse: (_) => null, requestMcpToolResult: (_) => null, - containerUpload: (_) => null + containerUpload: (_) => null, + compaction: (_) => null ); } } @@ -131,7 +134,8 @@ public string? ID toolSearchToolResult: (_) => null, mcpToolUse: (x) => x.ID, requestMcpToolResult: (_) => null, - containerUpload: (_) => null + containerUpload: (_) => null, + compaction: (_) => null ); } } @@ -158,7 +162,8 @@ public string? ToolUseID toolSearchToolResult: (x) => x.ToolUseID, mcpToolUse: (_) => null, requestMcpToolResult: (x) => x.ToolUseID, - containerUpload: (_) => null + containerUpload: (_) => null, + compaction: (_) => null ); } } @@ -185,7 +190,8 @@ public bool? IsError toolSearchToolResult: (_) => null, mcpToolUse: (_) => null, requestMcpToolResult: (x) => x.IsError, - containerUpload: (_) => null + containerUpload: (_) => null, + compaction: (_) => null ); } } @@ -319,6 +325,12 @@ public BetaContentBlockParam(BetaContainerUploadBlockParam value, JsonElement? e this._element = element; } + public BetaContentBlockParam(BetaCompactionBlockParam value, JsonElement? element = null) + { + this.Value = value; + this._element = element; + } + public BetaContentBlockParam(JsonElement element) { this._element = element; @@ -718,6 +730,27 @@ public bool TryPickContainerUpload([NotNullWhen(true)] out BetaContainerUploadBl return value != null; } + /// + /// Returns true and sets the out parameter if the instance was constructed with a variant of + /// type . + /// + /// Consider using or if you need to handle every variant. + /// + /// + /// + /// if (instance.TryPickCompaction(out var value)) { + /// // `value` is of type `BetaCompactionBlockParam` + /// Console.WriteLine(value); + /// } + /// + /// + /// + public bool TryPickCompaction([NotNullWhen(true)] out BetaCompactionBlockParam? value) + { + value = this.Value as BetaCompactionBlockParam; + return value != null; + } + /// /// Calls the function parameter corresponding to the variant the instance was constructed with. /// @@ -749,7 +782,8 @@ public bool TryPickContainerUpload([NotNullWhen(true)] out BetaContainerUploadBl /// (BetaToolSearchToolResultBlockParam value) => {...}, /// (BetaMcpToolUseBlockParam value) => {...}, /// (BetaRequestMcpToolResultBlockParam value) => {...}, - /// (BetaContainerUploadBlockParam value) => {...} + /// (BetaContainerUploadBlockParam value) => {...}, + /// (BetaCompactionBlockParam value) => {...} /// ); /// /// @@ -772,7 +806,8 @@ public void Switch( System::Action toolSearchToolResult, System::Action mcpToolUse, System::Action requestMcpToolResult, - System::Action containerUpload + System::Action containerUpload, + System::Action compaction ) { switch (this.Value) @@ -831,6 +866,9 @@ public void Switch( case BetaContainerUploadBlockParam value: containerUpload(value); break; + case BetaCompactionBlockParam value: + compaction(value); + break; default: throw new AnthropicInvalidDataException( "Data did not match any variant of BetaContentBlockParam" @@ -870,7 +908,8 @@ public void Switch( /// (BetaToolSearchToolResultBlockParam value) => {...}, /// (BetaMcpToolUseBlockParam value) => {...}, /// (BetaRequestMcpToolResultBlockParam value) => {...}, - /// (BetaContainerUploadBlockParam value) => {...} + /// (BetaContainerUploadBlockParam value) => {...}, + /// (BetaCompactionBlockParam value) => {...} /// ); /// /// @@ -896,7 +935,8 @@ public T Match( System::Func toolSearchToolResult, System::Func mcpToolUse, System::Func requestMcpToolResult, - System::Func containerUpload + System::Func containerUpload, + System::Func compaction ) { return this.Value switch @@ -920,6 +960,7 @@ public T Match( BetaMcpToolUseBlockParam value => mcpToolUse(value), BetaRequestMcpToolResultBlockParam value => requestMcpToolResult(value), BetaContainerUploadBlockParam value => containerUpload(value), + BetaCompactionBlockParam value => compaction(value), _ => throw new AnthropicInvalidDataException( "Data did not match any variant of BetaContentBlockParam" ), @@ -984,6 +1025,9 @@ BetaRequestMcpToolResultBlockParam value public static implicit operator BetaContentBlockParam(BetaContainerUploadBlockParam value) => new(value); + public static implicit operator BetaContentBlockParam(BetaCompactionBlockParam value) => + new(value); + /// /// Validates that the instance was constructed with a known variant and that this variant is valid /// (based on its own Validate method). @@ -1020,7 +1064,8 @@ public override void Validate() (toolSearchToolResult) => toolSearchToolResult.Validate(), (mcpToolUse) => mcpToolUse.Validate(), (requestMcpToolResult) => requestMcpToolResult.Validate(), - (containerUpload) => containerUpload.Validate() + (containerUpload) => containerUpload.Validate(), + (compaction) => compaction.Validate() ); } @@ -1059,6 +1104,7 @@ int VariantIndex() BetaMcpToolUseBlockParam _ => 15, BetaRequestMcpToolResultBlockParam _ => 16, BetaContainerUploadBlockParam _ => 17, + BetaCompactionBlockParam _ => 18, _ => -1, }; } @@ -1487,6 +1533,28 @@ JsonSerializerOptions options return new(element); } + case "compaction": + { + try + { + var deserialized = JsonSerializer.Deserialize( + element, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new(deserialized, element); + } + } + catch (System::Exception e) + when (e is JsonException || e is AnthropicInvalidDataException) + { + // ignore + } + + return new(element); + } default: { return new BetaContentBlockParam(element); diff --git a/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs b/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs index 4b17e6d9c..cf175b884 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaContextManagementConfig.cs @@ -86,6 +86,9 @@ IReadOnlyDictionary rawData ) => BetaContextManagementConfig.FromRawUnchecked(rawData); } +/// +/// Automatically compact older context when reaching the configured trigger threshold. +/// [JsonConverter(typeof(EditConverter))] public record class Edit : ModelBase { @@ -110,7 +113,8 @@ public JsonElement Type { return Match( betaClearToolUses20250919: (x) => x.Type, - betaClearThinking20251015: (x) => x.Type + betaClearThinking20251015: (x) => x.Type, + betaCompact20260112: (x) => x.Type ); } } @@ -127,6 +131,12 @@ public Edit(BetaClearThinking20251015Edit value, JsonElement? element = null) this._element = element; } + public Edit(BetaCompact20260112Edit value, JsonElement? element = null) + { + this.Value = value; + this._element = element; + } + public Edit(JsonElement element) { this._element = element; @@ -178,6 +188,27 @@ public bool TryPickBetaClearThinking20251015( return value != null; } + /// + /// Returns true and sets the out parameter if the instance was constructed with a variant of + /// type . + /// + /// Consider using or if you need to handle every variant. + /// + /// + /// + /// if (instance.TryPickBetaCompact20260112(out var value)) { + /// // `value` is of type `BetaCompact20260112Edit` + /// Console.WriteLine(value); + /// } + /// + /// + /// + public bool TryPickBetaCompact20260112([NotNullWhen(true)] out BetaCompact20260112Edit? value) + { + value = this.Value as BetaCompact20260112Edit; + return value != null; + } + /// /// Calls the function parameter corresponding to the variant the instance was constructed with. /// @@ -193,14 +224,16 @@ public bool TryPickBetaClearThinking20251015( /// /// instance.Switch( /// (BetaClearToolUses20250919Edit value) => {...}, - /// (BetaClearThinking20251015Edit value) => {...} + /// (BetaClearThinking20251015Edit value) => {...}, + /// (BetaCompact20260112Edit value) => {...} /// ); /// /// /// public void Switch( System::Action betaClearToolUses20250919, - System::Action betaClearThinking20251015 + System::Action betaClearThinking20251015, + System::Action betaCompact20260112 ) { switch (this.Value) @@ -211,6 +244,9 @@ public void Switch( case BetaClearThinking20251015Edit value: betaClearThinking20251015(value); break; + case BetaCompact20260112Edit value: + betaCompact20260112(value); + break; default: throw new AnthropicInvalidDataException("Data did not match any variant of Edit"); } @@ -232,20 +268,23 @@ public void Switch( /// /// var result = instance.Match( /// (BetaClearToolUses20250919Edit value) => {...}, - /// (BetaClearThinking20251015Edit value) => {...} + /// (BetaClearThinking20251015Edit value) => {...}, + /// (BetaCompact20260112Edit value) => {...} /// ); /// /// /// public T Match( System::Func betaClearToolUses20250919, - System::Func betaClearThinking20251015 + System::Func betaClearThinking20251015, + System::Func betaCompact20260112 ) { return this.Value switch { BetaClearToolUses20250919Edit value => betaClearToolUses20250919(value), BetaClearThinking20251015Edit value => betaClearThinking20251015(value), + BetaCompact20260112Edit value => betaCompact20260112(value), _ => throw new AnthropicInvalidDataException("Data did not match any variant of Edit"), }; } @@ -254,6 +293,8 @@ public T Match( public static implicit operator Edit(BetaClearThinking20251015Edit value) => new(value); + public static implicit operator Edit(BetaCompact20260112Edit value) => new(value); + /// /// Validates that the instance was constructed with a known variant and that this variant is valid /// (based on its own Validate method). @@ -272,7 +313,8 @@ public override void Validate() } this.Switch( (betaClearToolUses20250919) => betaClearToolUses20250919.Validate(), - (betaClearThinking20251015) => betaClearThinking20251015.Validate() + (betaClearThinking20251015) => betaClearThinking20251015.Validate(), + (betaCompact20260112) => betaCompact20260112.Validate() ); } @@ -295,6 +337,7 @@ int VariantIndex() { BetaClearToolUses20250919Edit _ => 0, BetaClearThinking20251015Edit _ => 1, + BetaCompact20260112Edit _ => 2, _ => -1, }; } @@ -365,6 +408,28 @@ JsonSerializerOptions options return new(element); } + case "compact_20260112": + { + try + { + var deserialized = JsonSerializer.Deserialize( + element, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new(deserialized, element); + } + } + catch (System::Exception e) + when (e is JsonException || e is AnthropicInvalidDataException) + { + // ignore + } + + return new(element); + } default: { return new Edit(element); diff --git a/src/Anthropic/Models/Beta/Messages/BetaMessageDeltaUsage.cs b/src/Anthropic/Models/Beta/Messages/BetaMessageDeltaUsage.cs index 7e60296de..4284da09b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaMessageDeltaUsage.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaMessageDeltaUsage.cs @@ -1,5 +1,6 @@ using System.Collections.Frozen; using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; @@ -49,6 +50,33 @@ public required long? InputTokens init { this._rawData.Set("input_tokens", value); } } + /// + /// Per-iteration token usage breakdown. + /// + /// Each entry represents one sampling iteration, with its own input/output + /// token counts and cache statistics. This allows you to: - Determine which + /// iterations exceeded long context thresholds (>=200k tokens) - Calculate the + /// true context window size from the last iteration - Understand token accumulation + /// across server-side tool use loops + /// + public required IReadOnlyList? Iterations + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct>( + "iterations" + ); + } + init + { + this._rawData.Set?>( + "iterations", + value == null ? null : ImmutableArray.ToImmutableArray(value) + ); + } + } + /// /// The cumulative number of output tokens which were used. /// @@ -81,6 +109,10 @@ public override void Validate() _ = this.CacheCreationInputTokens; _ = this.CacheReadInputTokens; _ = this.InputTokens; + foreach (var item in this.Iterations ?? []) + { + item.Validate(); + } _ = this.OutputTokens; this.ServerToolUse?.Validate(); } diff --git a/src/Anthropic/Models/Beta/Messages/BetaMessageIterationUsage.cs b/src/Anthropic/Models/Beta/Messages/BetaMessageIterationUsage.cs new file mode 100644 index 000000000..3429f5567 --- /dev/null +++ b/src/Anthropic/Models/Beta/Messages/BetaMessageIterationUsage.cs @@ -0,0 +1,152 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Models.Beta.Messages; + +/// +/// Token usage for a sampling iteration. +/// +[JsonConverter( + typeof(JsonModelConverter) +)] +public sealed record class BetaMessageIterationUsage : JsonModel +{ + /// + /// Breakdown of cached tokens by TTL + /// + public required BetaCacheCreation? CacheCreation + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("cache_creation"); + } + init { this._rawData.Set("cache_creation", value); } + } + + /// + /// The number of input tokens used to create the cache entry. + /// + public required long CacheCreationInputTokens + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("cache_creation_input_tokens"); + } + init { this._rawData.Set("cache_creation_input_tokens", value); } + } + + /// + /// The number of input tokens read from the cache. + /// + public required long CacheReadInputTokens + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("cache_read_input_tokens"); + } + init { this._rawData.Set("cache_read_input_tokens", value); } + } + + /// + /// The number of input tokens which were used. + /// + public required long InputTokens + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("input_tokens"); + } + init { this._rawData.Set("input_tokens", value); } + } + + /// + /// The number of output tokens which were used. + /// + public required long OutputTokens + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("output_tokens"); + } + init { this._rawData.Set("output_tokens", value); } + } + + /// + /// Usage for a sampling iteration + /// + public JsonElement Type + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("type"); + } + init { this._rawData.Set("type", value); } + } + + /// + public override void Validate() + { + this.CacheCreation?.Validate(); + _ = this.CacheCreationInputTokens; + _ = this.CacheReadInputTokens; + _ = this.InputTokens; + _ = this.OutputTokens; + if (!JsonElement.DeepEquals(this.Type, JsonSerializer.SerializeToElement("message"))) + { + throw new AnthropicInvalidDataException("Invalid value given for constant"); + } + } + + public BetaMessageIterationUsage() + { + this.Type = JsonSerializer.SerializeToElement("message"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + public BetaMessageIterationUsage(BetaMessageIterationUsage betaMessageIterationUsage) + : base(betaMessageIterationUsage) { } +#pragma warning restore CS8618 + + public BetaMessageIterationUsage(IReadOnlyDictionary rawData) + { + this._rawData = new(rawData); + + this.Type = JsonSerializer.SerializeToElement("message"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + BetaMessageIterationUsage(FrozenDictionary rawData) + { + this._rawData = new(rawData); + } +#pragma warning restore CS8618 + + /// + public static BetaMessageIterationUsage FromRawUnchecked( + IReadOnlyDictionary rawData + ) + { + return new(FrozenDictionary.ToFrozenDictionary(rawData)); + } +} + +class BetaMessageIterationUsageFromRaw : IFromRawJson +{ + /// + public BetaMessageIterationUsage FromRawUnchecked( + IReadOnlyDictionary rawData + ) => BetaMessageIterationUsage.FromRawUnchecked(rawData); +} diff --git a/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs b/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs index ecf02a5a7..784c987a7 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaOutputConfig.cs @@ -13,10 +13,7 @@ namespace Anthropic.Models.Beta.Messages; public sealed record class BetaOutputConfig : JsonModel { /// - /// How much effort the model should put into its response. Higher effort levels - /// may result in more thorough analysis but take longer. - /// - /// Valid values are `low`, `medium`, or `high`. + /// All possible effort levels. /// public ApiEnum? Effort { @@ -86,10 +83,7 @@ public BetaOutputConfig FromRawUnchecked(IReadOnlyDictionary -/// How much effort the model should put into its response. Higher effort levels may -/// result in more thorough analysis but take longer. -/// -/// Valid values are `low`, `medium`, or `high`. +/// All possible effort levels. /// [JsonConverter(typeof(EffortConverter))] public enum Effort @@ -97,6 +91,7 @@ public enum Effort Low, Medium, High, + Max, } sealed class EffortConverter : JsonConverter @@ -112,6 +107,7 @@ JsonSerializerOptions options "low" => Effort.Low, "medium" => Effort.Medium, "high" => Effort.High, + "max" => Effort.Max, _ => (Effort)(-1), }; } @@ -125,6 +121,7 @@ public override void Write(Utf8JsonWriter writer, Effort value, JsonSerializerOp Effort.Low => "low", Effort.Medium => "medium", Effort.High => "high", + Effort.Max => "max", _ => throw new AnthropicInvalidDataException( string.Format("Invalid value '{0}' in {1}", value, nameof(value)) ), diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDelta.cs b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDelta.cs index 862b80ec8..7a4bf8a25 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDelta.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockDelta.cs @@ -34,7 +34,8 @@ public JsonElement Type inputJson: (x) => x.Type, citations: (x) => x.Type, thinking: (x) => x.Type, - signature: (x) => x.Type + signature: (x) => x.Type, + compaction: (x) => x.Type ); } } @@ -69,6 +70,15 @@ public BetaRawContentBlockDelta(BetaSignatureDelta value, JsonElement? element = this._element = element; } + public BetaRawContentBlockDelta( + BetaCompactionContentBlockDelta value, + JsonElement? element = null + ) + { + this.Value = value; + this._element = element; + } + public BetaRawContentBlockDelta(JsonElement element) { this._element = element; @@ -179,6 +189,27 @@ public bool TryPickSignature([NotNullWhen(true)] out BetaSignatureDelta? value) return value != null; } + /// + /// Returns true and sets the out parameter if the instance was constructed with a variant of + /// type . + /// + /// Consider using or if you need to handle every variant. + /// + /// + /// + /// if (instance.TryPickCompaction(out var value)) { + /// // `value` is of type `BetaCompactionContentBlockDelta` + /// Console.WriteLine(value); + /// } + /// + /// + /// + public bool TryPickCompaction([NotNullWhen(true)] out BetaCompactionContentBlockDelta? value) + { + value = this.Value as BetaCompactionContentBlockDelta; + return value != null; + } + /// /// Calls the function parameter corresponding to the variant the instance was constructed with. /// @@ -197,7 +228,8 @@ public bool TryPickSignature([NotNullWhen(true)] out BetaSignatureDelta? value) /// (BetaInputJsonDelta value) => {...}, /// (BetaCitationsDelta value) => {...}, /// (BetaThinkingDelta value) => {...}, - /// (BetaSignatureDelta value) => {...} + /// (BetaSignatureDelta value) => {...}, + /// (BetaCompactionContentBlockDelta value) => {...} /// ); /// /// @@ -207,7 +239,8 @@ public void Switch( System::Action inputJson, System::Action citations, System::Action thinking, - System::Action signature + System::Action signature, + System::Action compaction ) { switch (this.Value) @@ -227,6 +260,9 @@ public void Switch( case BetaSignatureDelta value: signature(value); break; + case BetaCompactionContentBlockDelta value: + compaction(value); + break; default: throw new AnthropicInvalidDataException( "Data did not match any variant of BetaRawContentBlockDelta" @@ -253,7 +289,8 @@ public void Switch( /// (BetaInputJsonDelta value) => {...}, /// (BetaCitationsDelta value) => {...}, /// (BetaThinkingDelta value) => {...}, - /// (BetaSignatureDelta value) => {...} + /// (BetaSignatureDelta value) => {...}, + /// (BetaCompactionContentBlockDelta value) => {...} /// ); /// /// @@ -263,7 +300,8 @@ public T Match( System::Func inputJson, System::Func citations, System::Func thinking, - System::Func signature + System::Func signature, + System::Func compaction ) { return this.Value switch @@ -273,6 +311,7 @@ public T Match( BetaCitationsDelta value => citations(value), BetaThinkingDelta value => thinking(value), BetaSignatureDelta value => signature(value), + BetaCompactionContentBlockDelta value => compaction(value), _ => throw new AnthropicInvalidDataException( "Data did not match any variant of BetaRawContentBlockDelta" ), @@ -292,6 +331,10 @@ public static implicit operator BetaRawContentBlockDelta(BetaCitationsDelta valu public static implicit operator BetaRawContentBlockDelta(BetaSignatureDelta value) => new(value); + public static implicit operator BetaRawContentBlockDelta( + BetaCompactionContentBlockDelta value + ) => new(value); + /// /// Validates that the instance was constructed with a known variant and that this variant is valid /// (based on its own Validate method). @@ -315,7 +358,8 @@ public override void Validate() (inputJson) => inputJson.Validate(), (citations) => citations.Validate(), (thinking) => thinking.Validate(), - (signature) => signature.Validate() + (signature) => signature.Validate(), + (compaction) => compaction.Validate() ); } @@ -341,6 +385,7 @@ int VariantIndex() BetaCitationsDelta _ => 2, BetaThinkingDelta _ => 3, BetaSignatureDelta _ => 4, + BetaCompactionContentBlockDelta _ => 5, _ => -1, }; } @@ -474,6 +519,28 @@ JsonSerializerOptions options return new(element); } + case "compaction_delta": + { + try + { + var deserialized = JsonSerializer.Deserialize( + element, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new(deserialized, element); + } + } + catch (System::Exception e) + when (e is JsonException || e is AnthropicInvalidDataException) + { + // ignore + } + + return new(element); + } default: { return new BetaRawContentBlockDelta(element); diff --git a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs index 560c17d85..89fcc67df 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaRawContentBlockStartEvent.cs @@ -147,7 +147,8 @@ public JsonElement Type betaToolSearchToolResult: (x) => x.Type, betaMcpToolUse: (x) => x.Type, betaMcpToolResult: (x) => x.Type, - betaContainerUpload: (x) => x.Type + betaContainerUpload: (x) => x.Type, + betaCompaction: (x) => x.Type ); } } @@ -170,7 +171,8 @@ public string? ID betaToolSearchToolResult: (_) => null, betaMcpToolUse: (x) => x.ID, betaMcpToolResult: (_) => null, - betaContainerUpload: (_) => null + betaContainerUpload: (_) => null, + betaCompaction: (_) => null ); } } @@ -193,7 +195,8 @@ public string? ToolUseID betaToolSearchToolResult: (x) => x.ToolUseID, betaMcpToolUse: (_) => null, betaMcpToolResult: (x) => x.ToolUseID, - betaContainerUpload: (_) => null + betaContainerUpload: (_) => null, + betaCompaction: (_) => null ); } } @@ -285,6 +288,12 @@ public ContentBlock(BetaContainerUploadBlock value, JsonElement? element = null) this._element = element; } + public ContentBlock(BetaCompactionBlock value, JsonElement? element = null) + { + this.Value = value; + this._element = element; + } + public ContentBlock(JsonElement element) { this._element = element; @@ -598,6 +607,27 @@ public bool TryPickBetaContainerUpload([NotNullWhen(true)] out BetaContainerUplo return value != null; } + /// + /// Returns true and sets the out parameter if the instance was constructed with a variant of + /// type . + /// + /// Consider using or if you need to handle every variant. + /// + /// + /// + /// if (instance.TryPickBetaCompaction(out var value)) { + /// // `value` is of type `BetaCompactionBlock` + /// Console.WriteLine(value); + /// } + /// + /// + /// + public bool TryPickBetaCompaction([NotNullWhen(true)] out BetaCompactionBlock? value) + { + value = this.Value as BetaCompactionBlock; + return value != null; + } + /// /// Calls the function parameter corresponding to the variant the instance was constructed with. /// @@ -625,7 +655,8 @@ public bool TryPickBetaContainerUpload([NotNullWhen(true)] out BetaContainerUplo /// (BetaToolSearchToolResultBlock value) => {...}, /// (BetaMcpToolUseBlock value) => {...}, /// (BetaMcpToolResultBlock value) => {...}, - /// (BetaContainerUploadBlock value) => {...} + /// (BetaContainerUploadBlock value) => {...}, + /// (BetaCompactionBlock value) => {...} /// ); /// /// @@ -644,7 +675,8 @@ public void Switch( System::Action betaToolSearchToolResult, System::Action betaMcpToolUse, System::Action betaMcpToolResult, - System::Action betaContainerUpload + System::Action betaContainerUpload, + System::Action betaCompaction ) { switch (this.Value) @@ -691,6 +723,9 @@ public void Switch( case BetaContainerUploadBlock value: betaContainerUpload(value); break; + case BetaCompactionBlock value: + betaCompaction(value); + break; default: throw new AnthropicInvalidDataException( "Data did not match any variant of ContentBlock" @@ -726,7 +761,8 @@ public void Switch( /// (BetaToolSearchToolResultBlock value) => {...}, /// (BetaMcpToolUseBlock value) => {...}, /// (BetaMcpToolResultBlock value) => {...}, - /// (BetaContainerUploadBlock value) => {...} + /// (BetaContainerUploadBlock value) => {...}, + /// (BetaCompactionBlock value) => {...} /// ); /// /// @@ -748,7 +784,8 @@ public T Match( System::Func betaToolSearchToolResult, System::Func betaMcpToolUse, System::Func betaMcpToolResult, - System::Func betaContainerUpload + System::Func betaContainerUpload, + System::Func betaCompaction ) { return this.Value switch @@ -768,6 +805,7 @@ public T Match( BetaMcpToolUseBlock value => betaMcpToolUse(value), BetaMcpToolResultBlock value => betaMcpToolResult(value), BetaContainerUploadBlock value => betaContainerUpload(value), + BetaCompactionBlock value => betaCompaction(value), _ => throw new AnthropicInvalidDataException( "Data did not match any variant of ContentBlock" ), @@ -806,6 +844,8 @@ BetaTextEditorCodeExecutionToolResultBlock value public static implicit operator ContentBlock(BetaContainerUploadBlock value) => new(value); + public static implicit operator ContentBlock(BetaCompactionBlock value) => new(value); + /// /// Validates that the instance was constructed with a known variant and that this variant is valid /// (based on its own Validate method). @@ -839,7 +879,8 @@ public override void Validate() (betaToolSearchToolResult) => betaToolSearchToolResult.Validate(), (betaMcpToolUse) => betaMcpToolUse.Validate(), (betaMcpToolResult) => betaMcpToolResult.Validate(), - (betaContainerUpload) => betaContainerUpload.Validate() + (betaContainerUpload) => betaContainerUpload.Validate(), + (betaCompaction) => betaCompaction.Validate() ); } @@ -874,6 +915,7 @@ int VariantIndex() BetaMcpToolUseBlock _ => 11, BetaMcpToolResultBlock _ => 12, BetaContainerUploadBlock _ => 13, + BetaCompactionBlock _ => 14, _ => -1, }; } @@ -1207,6 +1249,28 @@ JsonSerializerOptions options return new(element); } + case "compaction": + { + try + { + var deserialized = JsonSerializer.Deserialize( + element, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new(deserialized, element); + } + } + catch (System::Exception e) + when (e is JsonException || e is AnthropicInvalidDataException) + { + // ignore + } + + return new(element); + } default: { return new ContentBlock(element); diff --git a/src/Anthropic/Models/Beta/Messages/BetaStopReason.cs b/src/Anthropic/Models/Beta/Messages/BetaStopReason.cs index 0890b0b2a..ff331386b 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaStopReason.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaStopReason.cs @@ -13,6 +13,7 @@ public enum BetaStopReason StopSequence, ToolUse, PauseTurn, + Compaction, Refusal, ModelContextWindowExceeded, } @@ -32,6 +33,7 @@ JsonSerializerOptions options "stop_sequence" => BetaStopReason.StopSequence, "tool_use" => BetaStopReason.ToolUse, "pause_turn" => BetaStopReason.PauseTurn, + "compaction" => BetaStopReason.Compaction, "refusal" => BetaStopReason.Refusal, "model_context_window_exceeded" => BetaStopReason.ModelContextWindowExceeded, _ => (BetaStopReason)(-1), @@ -53,6 +55,7 @@ JsonSerializerOptions options BetaStopReason.StopSequence => "stop_sequence", BetaStopReason.ToolUse => "tool_use", BetaStopReason.PauseTurn => "pause_turn", + BetaStopReason.Compaction => "compaction", BetaStopReason.Refusal => "refusal", BetaStopReason.ModelContextWindowExceeded => "model_context_window_exceeded", _ => throw new AnthropicInvalidDataException( diff --git a/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigAdaptive.cs b/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigAdaptive.cs new file mode 100644 index 000000000..caea663f4 --- /dev/null +++ b/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigAdaptive.cs @@ -0,0 +1,76 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Models.Beta.Messages; + +[JsonConverter( + typeof(JsonModelConverter) +)] +public sealed record class BetaThinkingConfigAdaptive : JsonModel +{ + public JsonElement Type + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("type"); + } + init { this._rawData.Set("type", value); } + } + + /// + public override void Validate() + { + if (!JsonElement.DeepEquals(this.Type, JsonSerializer.SerializeToElement("adaptive"))) + { + throw new AnthropicInvalidDataException("Invalid value given for constant"); + } + } + + public BetaThinkingConfigAdaptive() + { + this.Type = JsonSerializer.SerializeToElement("adaptive"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + public BetaThinkingConfigAdaptive(BetaThinkingConfigAdaptive betaThinkingConfigAdaptive) + : base(betaThinkingConfigAdaptive) { } +#pragma warning restore CS8618 + + public BetaThinkingConfigAdaptive(IReadOnlyDictionary rawData) + { + this._rawData = new(rawData); + + this.Type = JsonSerializer.SerializeToElement("adaptive"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + BetaThinkingConfigAdaptive(FrozenDictionary rawData) + { + this._rawData = new(rawData); + } +#pragma warning restore CS8618 + + /// + public static BetaThinkingConfigAdaptive FromRawUnchecked( + IReadOnlyDictionary rawData + ) + { + return new(FrozenDictionary.ToFrozenDictionary(rawData)); + } +} + +class BetaThinkingConfigAdaptiveFromRaw : IFromRawJson +{ + /// + public BetaThinkingConfigAdaptive FromRawUnchecked( + IReadOnlyDictionary rawData + ) => BetaThinkingConfigAdaptive.FromRawUnchecked(rawData); +} diff --git a/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigParam.cs b/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigParam.cs index bd3eebd2a..1a28ddc94 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigParam.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaThinkingConfigParam.cs @@ -37,7 +37,10 @@ public JsonElement Json public JsonElement Type { - get { return Match(enabled: (x) => x.Type, disabled: (x) => x.Type); } + get + { + return Match(enabled: (x) => x.Type, disabled: (x) => x.Type, adaptive: (x) => x.Type); + } } public BetaThinkingConfigParam(BetaThinkingConfigEnabled value, JsonElement? element = null) @@ -52,6 +55,12 @@ public BetaThinkingConfigParam(BetaThinkingConfigDisabled value, JsonElement? el this._element = element; } + public BetaThinkingConfigParam(BetaThinkingConfigAdaptive value, JsonElement? element = null) + { + this.Value = value; + this._element = element; + } + public BetaThinkingConfigParam(JsonElement element) { this._element = element; @@ -99,6 +108,27 @@ public bool TryPickDisabled([NotNullWhen(true)] out BetaThinkingConfigDisabled? return value != null; } + /// + /// Returns true and sets the out parameter if the instance was constructed with a variant of + /// type . + /// + /// Consider using or if you need to handle every variant. + /// + /// + /// + /// if (instance.TryPickAdaptive(out var value)) { + /// // `value` is of type `BetaThinkingConfigAdaptive` + /// Console.WriteLine(value); + /// } + /// + /// + /// + public bool TryPickAdaptive([NotNullWhen(true)] out BetaThinkingConfigAdaptive? value) + { + value = this.Value as BetaThinkingConfigAdaptive; + return value != null; + } + /// /// Calls the function parameter corresponding to the variant the instance was constructed with. /// @@ -114,14 +144,16 @@ public bool TryPickDisabled([NotNullWhen(true)] out BetaThinkingConfigDisabled? /// /// instance.Switch( /// (BetaThinkingConfigEnabled value) => {...}, - /// (BetaThinkingConfigDisabled value) => {...} + /// (BetaThinkingConfigDisabled value) => {...}, + /// (BetaThinkingConfigAdaptive value) => {...} /// ); /// /// /// public void Switch( System::Action enabled, - System::Action disabled + System::Action disabled, + System::Action adaptive ) { switch (this.Value) @@ -132,6 +164,9 @@ public void Switch( case BetaThinkingConfigDisabled value: disabled(value); break; + case BetaThinkingConfigAdaptive value: + adaptive(value); + break; default: throw new AnthropicInvalidDataException( "Data did not match any variant of BetaThinkingConfigParam" @@ -155,20 +190,23 @@ public void Switch( /// /// var result = instance.Match( /// (BetaThinkingConfigEnabled value) => {...}, - /// (BetaThinkingConfigDisabled value) => {...} + /// (BetaThinkingConfigDisabled value) => {...}, + /// (BetaThinkingConfigAdaptive value) => {...} /// ); /// /// /// public T Match( System::Func enabled, - System::Func disabled + System::Func disabled, + System::Func adaptive ) { return this.Value switch { BetaThinkingConfigEnabled value => enabled(value), BetaThinkingConfigDisabled value => disabled(value), + BetaThinkingConfigAdaptive value => adaptive(value), _ => throw new AnthropicInvalidDataException( "Data did not match any variant of BetaThinkingConfigParam" ), @@ -181,6 +219,9 @@ public static implicit operator BetaThinkingConfigParam(BetaThinkingConfigEnable public static implicit operator BetaThinkingConfigParam(BetaThinkingConfigDisabled value) => new(value); + public static implicit operator BetaThinkingConfigParam(BetaThinkingConfigAdaptive value) => + new(value); + /// /// Validates that the instance was constructed with a known variant and that this variant is valid /// (based on its own Validate method). @@ -199,7 +240,11 @@ public override void Validate() "Data did not match any variant of BetaThinkingConfigParam" ); } - this.Switch((enabled) => enabled.Validate(), (disabled) => disabled.Validate()); + this.Switch( + (enabled) => enabled.Validate(), + (disabled) => disabled.Validate(), + (adaptive) => adaptive.Validate() + ); } public virtual bool Equals(BetaThinkingConfigParam? other) => @@ -221,6 +266,7 @@ int VariantIndex() { BetaThinkingConfigEnabled _ => 0, BetaThinkingConfigDisabled _ => 1, + BetaThinkingConfigAdaptive _ => 2, _ => -1, }; } @@ -291,6 +337,28 @@ JsonSerializerOptions options return new(element); } + case "adaptive": + { + try + { + var deserialized = JsonSerializer.Deserialize( + element, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new(deserialized, element); + } + } + catch (System::Exception e) + when (e is JsonException || e is AnthropicInvalidDataException) + { + // ignore + } + + return new(element); + } default: { return new BetaThinkingConfigParam(element); diff --git a/src/Anthropic/Models/Beta/Messages/BetaTool.cs b/src/Anthropic/Models/Beta/Messages/BetaTool.cs index 306c8a518..d5e85f5e5 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaTool.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaTool.cs @@ -129,6 +129,23 @@ public string? Description } } + /// + /// Enable eager input streaming for this tool. When true, tool input parameters + /// will be streamed incrementally as they are generated, and types will be inferred + /// on-the-fly rather than buffering the full JSON output. When false, streaming + /// is disabled for this tool even if the fine-grained-tool-streaming beta is + /// active. When null (default), uses the default behavior based on beta headers. + /// + public bool? EagerInputStreaming + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct("eager_input_streaming"); + } + init { this._rawData.Set("eager_input_streaming", value); } + } + public IReadOnlyList>? InputExamples { get @@ -202,6 +219,7 @@ public override void Validate() this.CacheControl?.Validate(); _ = this.DeferLoading; _ = this.Description; + _ = this.EagerInputStreaming; _ = this.InputExamples; _ = this.Strict; this.Type?.Validate(); diff --git a/src/Anthropic/Models/Beta/Messages/BetaUsage.cs b/src/Anthropic/Models/Beta/Messages/BetaUsage.cs index 743aa9a5f..0cf51ecb8 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaUsage.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaUsage.cs @@ -1,5 +1,6 @@ using System.Collections.Frozen; using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; @@ -51,6 +52,19 @@ public required long? CacheReadInputTokens init { this._rawData.Set("cache_read_input_tokens", value); } } + /// + /// The geographic region where inference was performed for this request. + /// + public required string? InferenceGeo + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("inference_geo"); + } + init { this._rawData.Set("inference_geo", value); } + } + /// /// The number of input tokens which were used. /// @@ -64,6 +78,33 @@ public required long InputTokens init { this._rawData.Set("input_tokens", value); } } + /// + /// Per-iteration token usage breakdown. + /// + /// Each entry represents one sampling iteration, with its own input/output + /// token counts and cache statistics. This allows you to: - Determine which + /// iterations exceeded long context thresholds (>=200k tokens) - Calculate the + /// true context window size from the last iteration - Understand token accumulation + /// across server-side tool use loops + /// + public required IReadOnlyList? Iterations + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct>( + "iterations" + ); + } + init + { + this._rawData.Set?>( + "iterations", + value == null ? null : ImmutableArray.ToImmutableArray(value) + ); + } + } + /// /// The number of output tokens which were used. /// @@ -111,7 +152,12 @@ public override void Validate() this.CacheCreation?.Validate(); _ = this.CacheCreationInputTokens; _ = this.CacheReadInputTokens; + _ = this.InferenceGeo; _ = this.InputTokens; + foreach (var item in this.Iterations ?? []) + { + item.Validate(); + } _ = this.OutputTokens; this.ServerToolUse?.Validate(); this.ServiceTier?.Validate(); diff --git a/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs b/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs index 7acf20104..02eaa26e4 100644 --- a/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs +++ b/src/Anthropic/Models/Beta/Messages/MessageCreateParams.cs @@ -164,6 +164,20 @@ public BetaContextManagementConfig? ContextManagement init { this._rawBodyData.Set("context_management", value); } } + /// + /// Specifies the geographic region for inference processing. If not specified, + /// the workspace's `default_inference_geo` is used. + /// + public string? InferenceGeo + { + get + { + this._rawBodyData.Freeze(); + return this._rawBodyData.GetNullableClass("inference_geo"); + } + init { this._rawBodyData.Set("inference_geo", value); } + } + /// /// MCP servers to be utilized in this request /// diff --git a/src/Anthropic/Models/Beta/Messages/UnnamedSchemaWithArrayParent0.cs b/src/Anthropic/Models/Beta/Messages/UnnamedSchemaWithArrayParent0.cs new file mode 100644 index 000000000..dc260c9db --- /dev/null +++ b/src/Anthropic/Models/Beta/Messages/UnnamedSchemaWithArrayParent0.cs @@ -0,0 +1,352 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; +using Anthropic.Exceptions; +using System = System; + +namespace Anthropic.Models.Beta.Messages; + +/// +/// Token usage for a sampling iteration. +/// +[JsonConverter(typeof(UnnamedSchemaWithArrayParent0Converter))] +public record class UnnamedSchemaWithArrayParent0 : ModelBase +{ + public object? Value { get; } = null; + + JsonElement? _element = null; + + public JsonElement Json + { + get + { + return this._element ??= JsonSerializer.SerializeToElement( + this.Value, + ModelBase.SerializerOptions + ); + } + } + + public BetaCacheCreation? CacheCreation + { + get + { + return Match( + betaMessageIterationUsage: (x) => x.CacheCreation, + betaCompactionIterationUsage: (x) => x.CacheCreation + ); + } + } + + public long CacheCreationInputTokens + { + get + { + return Match( + betaMessageIterationUsage: (x) => x.CacheCreationInputTokens, + betaCompactionIterationUsage: (x) => x.CacheCreationInputTokens + ); + } + } + + public long CacheReadInputTokens + { + get + { + return Match( + betaMessageIterationUsage: (x) => x.CacheReadInputTokens, + betaCompactionIterationUsage: (x) => x.CacheReadInputTokens + ); + } + } + + public long InputTokens + { + get + { + return Match( + betaMessageIterationUsage: (x) => x.InputTokens, + betaCompactionIterationUsage: (x) => x.InputTokens + ); + } + } + + public long OutputTokens + { + get + { + return Match( + betaMessageIterationUsage: (x) => x.OutputTokens, + betaCompactionIterationUsage: (x) => x.OutputTokens + ); + } + } + + public JsonElement Type + { + get + { + return Match( + betaMessageIterationUsage: (x) => x.Type, + betaCompactionIterationUsage: (x) => x.Type + ); + } + } + + public UnnamedSchemaWithArrayParent0( + BetaMessageIterationUsage value, + JsonElement? element = null + ) + { + this.Value = value; + this._element = element; + } + + public UnnamedSchemaWithArrayParent0( + BetaCompactionIterationUsage value, + JsonElement? element = null + ) + { + this.Value = value; + this._element = element; + } + + public UnnamedSchemaWithArrayParent0(JsonElement element) + { + this._element = element; + } + + /// + /// Returns true and sets the out parameter if the instance was constructed with a variant of + /// type . + /// + /// Consider using or if you need to handle every variant. + /// + /// + /// + /// if (instance.TryPickBetaMessageIterationUsage(out var value)) { + /// // `value` is of type `BetaMessageIterationUsage` + /// Console.WriteLine(value); + /// } + /// + /// + /// + public bool TryPickBetaMessageIterationUsage( + [NotNullWhen(true)] out BetaMessageIterationUsage? value + ) + { + value = this.Value as BetaMessageIterationUsage; + return value != null; + } + + /// + /// Returns true and sets the out parameter if the instance was constructed with a variant of + /// type . + /// + /// Consider using or if you need to handle every variant. + /// + /// + /// + /// if (instance.TryPickBetaCompactionIterationUsage(out var value)) { + /// // `value` is of type `BetaCompactionIterationUsage` + /// Console.WriteLine(value); + /// } + /// + /// + /// + public bool TryPickBetaCompactionIterationUsage( + [NotNullWhen(true)] out BetaCompactionIterationUsage? value + ) + { + value = this.Value as BetaCompactionIterationUsage; + return value != null; + } + + /// + /// Calls the function parameter corresponding to the variant the instance was constructed with. + /// + /// Use the TryPick method(s) if you don't need to handle every variant, or + /// if you need your function parameters to return something. + /// + /// + /// Thrown when the instance was constructed with an unknown variant (e.g. deserialized from raw data + /// that doesn't match any variant's expected shape). + /// + /// + /// + /// + /// instance.Switch( + /// (BetaMessageIterationUsage value) => {...}, + /// (BetaCompactionIterationUsage value) => {...} + /// ); + /// + /// + /// + public void Switch( + System::Action betaMessageIterationUsage, + System::Action betaCompactionIterationUsage + ) + { + switch (this.Value) + { + case BetaMessageIterationUsage value: + betaMessageIterationUsage(value); + break; + case BetaCompactionIterationUsage value: + betaCompactionIterationUsage(value); + break; + default: + throw new AnthropicInvalidDataException( + "Data did not match any variant of UnnamedSchemaWithArrayParent0" + ); + } + } + + /// + /// Calls the function parameter corresponding to the variant the instance was constructed with and + /// returns its result. + /// + /// Use the TryPick method(s) if you don't need to handle every variant, or + /// if you don't need your function parameters to return a value. + /// + /// + /// Thrown when the instance was constructed with an unknown variant (e.g. deserialized from raw data + /// that doesn't match any variant's expected shape). + /// + /// + /// + /// + /// var result = instance.Match( + /// (BetaMessageIterationUsage value) => {...}, + /// (BetaCompactionIterationUsage value) => {...} + /// ); + /// + /// + /// + public T Match( + System::Func betaMessageIterationUsage, + System::Func betaCompactionIterationUsage + ) + { + return this.Value switch + { + BetaMessageIterationUsage value => betaMessageIterationUsage(value), + BetaCompactionIterationUsage value => betaCompactionIterationUsage(value), + _ => throw new AnthropicInvalidDataException( + "Data did not match any variant of UnnamedSchemaWithArrayParent0" + ), + }; + } + + public static implicit operator UnnamedSchemaWithArrayParent0( + BetaMessageIterationUsage value + ) => new(value); + + public static implicit operator UnnamedSchemaWithArrayParent0( + BetaCompactionIterationUsage value + ) => new(value); + + /// + /// Validates that the instance was constructed with a known variant and that this variant is valid + /// (based on its own Validate method). + /// + /// This is useful for instances constructed from raw JSON data (e.g. deserialized from an API response). + /// + /// + /// Thrown when the instance does not pass validation. + /// + /// + public override void Validate() + { + if (this.Value == null) + { + throw new AnthropicInvalidDataException( + "Data did not match any variant of UnnamedSchemaWithArrayParent0" + ); + } + this.Switch( + (betaMessageIterationUsage) => betaMessageIterationUsage.Validate(), + (betaCompactionIterationUsage) => betaCompactionIterationUsage.Validate() + ); + } + + public virtual bool Equals(UnnamedSchemaWithArrayParent0? other) => + other != null + && this.VariantIndex() == other.VariantIndex() + && JsonElement.DeepEquals(this.Json, other.Json); + + public override int GetHashCode() + { + return 0; + } + + public override string ToString() => + JsonSerializer.Serialize(this._element, ModelBase.ToStringSerializerOptions); + + int VariantIndex() + { + return this.Value switch + { + BetaMessageIterationUsage _ => 0, + BetaCompactionIterationUsage _ => 1, + _ => -1, + }; + } +} + +sealed class UnnamedSchemaWithArrayParent0Converter : JsonConverter +{ + public override UnnamedSchemaWithArrayParent0? Read( + ref Utf8JsonReader reader, + System::Type typeToConvert, + JsonSerializerOptions options + ) + { + var element = JsonSerializer.Deserialize(ref reader, options); + try + { + var deserialized = JsonSerializer.Deserialize( + element, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new(deserialized, element); + } + } + catch (System::Exception e) when (e is JsonException || e is AnthropicInvalidDataException) + { + // ignore + } + + try + { + var deserialized = JsonSerializer.Deserialize( + element, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new(deserialized, element); + } + } + catch (System::Exception e) when (e is JsonException || e is AnthropicInvalidDataException) + { + // ignore + } + + return new(element); + } + + public override void Write( + Utf8JsonWriter writer, + UnnamedSchemaWithArrayParent0 value, + JsonSerializerOptions options + ) + { + JsonSerializer.Serialize(writer, value.Json, options); + } +} diff --git a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs index b68471b2a..42b819d03 100644 --- a/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs +++ b/src/Anthropic/Models/Messages/Batches/BatchCreateParams.cs @@ -345,6 +345,20 @@ public required ApiEnum Model init { this._rawData.Set("model", value); } } + /// + /// Specifies the geographic region for inference processing. If not specified, + /// the workspace's `default_inference_geo` is used. + /// + public string? InferenceGeo + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("inference_geo"); + } + init { this._rawData.Set("inference_geo", value); } + } + /// /// An object describing metadata about the request. /// @@ -702,6 +716,7 @@ public override void Validate() item.Validate(); } this.Model.Validate(); + _ = this.InferenceGeo; this.Metadata?.Validate(); this.OutputConfig?.Validate(); this.ServiceTier?.Validate(); diff --git a/src/Anthropic/Models/Messages/MessageCreateParams.cs b/src/Anthropic/Models/Messages/MessageCreateParams.cs index c9077850a..0c1db46e5 100644 --- a/src/Anthropic/Models/Messages/MessageCreateParams.cs +++ b/src/Anthropic/Models/Messages/MessageCreateParams.cs @@ -132,6 +132,20 @@ public required ApiEnum Model init { this._rawBodyData.Set("model", value); } } + /// + /// Specifies the geographic region for inference processing. If not specified, + /// the workspace's `default_inference_geo` is used. + /// + public string? InferenceGeo + { + get + { + this._rawBodyData.Freeze(); + return this._rawBodyData.GetNullableClass("inference_geo"); + } + init { this._rawBodyData.Set("inference_geo", value); } + } + /// /// An object describing metadata about the request. /// diff --git a/src/Anthropic/Models/Messages/Model.cs b/src/Anthropic/Models/Messages/Model.cs index 516788f59..3972d768a 100644 --- a/src/Anthropic/Models/Messages/Model.cs +++ b/src/Anthropic/Models/Messages/Model.cs @@ -12,6 +12,11 @@ namespace Anthropic.Models.Messages; [JsonConverter(typeof(ModelConverter))] public enum Model { + /// + /// Most intelligent model for building agents and coding + /// + ClaudeOpus4_6, + /// /// Premium model combining maximum intelligence with practical performance /// @@ -141,6 +146,7 @@ JsonSerializerOptions options { return JsonSerializer.Deserialize(ref reader, options) switch { + "claude-opus-4-6" => Model.ClaudeOpus4_6, "claude-opus-4-5-20251101" => Model.ClaudeOpus4_5_20251101, "claude-opus-4-5" => Model.ClaudeOpus4_5, "claude-3-7-sonnet-latest" => Model.Claude3_7SonnetLatest, @@ -171,6 +177,7 @@ public override void Write(Utf8JsonWriter writer, Model value, JsonSerializerOpt writer, value switch { + Model.ClaudeOpus4_6 => "claude-opus-4-6", Model.ClaudeOpus4_5_20251101 => "claude-opus-4-5-20251101", Model.ClaudeOpus4_5 => "claude-opus-4-5", Model.Claude3_7SonnetLatest => "claude-3-7-sonnet-latest", diff --git a/src/Anthropic/Models/Messages/OutputConfig.cs b/src/Anthropic/Models/Messages/OutputConfig.cs index 18aa4a66c..20fd8a0f5 100644 --- a/src/Anthropic/Models/Messages/OutputConfig.cs +++ b/src/Anthropic/Models/Messages/OutputConfig.cs @@ -4,12 +4,27 @@ using System.Text.Json; using System.Text.Json.Serialization; using Anthropic.Core; +using Anthropic.Exceptions; +using System = System; namespace Anthropic.Models.Messages; [JsonConverter(typeof(JsonModelConverter))] public sealed record class OutputConfig : JsonModel { + /// + /// All possible effort levels. + /// + public ApiEnum? Effort + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass>("effort"); + } + init { this._rawData.Set("effort", value); } + } + /// /// A schema to specify Claude's output format in responses. See [structured outputs](https://platform.claude.com/docs/en/build-with-claude/structured-outputs) /// @@ -26,6 +41,7 @@ public JsonOutputFormat? Format /// public override void Validate() { + this.Effort?.Validate(); this.Format?.Validate(); } @@ -63,3 +79,52 @@ class OutputConfigFromRaw : IFromRawJson public OutputConfig FromRawUnchecked(IReadOnlyDictionary rawData) => OutputConfig.FromRawUnchecked(rawData); } + +/// +/// All possible effort levels. +/// +[JsonConverter(typeof(EffortConverter))] +public enum Effort +{ + Low, + Medium, + High, + Max, +} + +sealed class EffortConverter : JsonConverter +{ + public override Effort Read( + ref Utf8JsonReader reader, + System::Type typeToConvert, + JsonSerializerOptions options + ) + { + return JsonSerializer.Deserialize(ref reader, options) switch + { + "low" => Effort.Low, + "medium" => Effort.Medium, + "high" => Effort.High, + "max" => Effort.Max, + _ => (Effort)(-1), + }; + } + + public override void Write(Utf8JsonWriter writer, Effort value, JsonSerializerOptions options) + { + JsonSerializer.Serialize( + writer, + value switch + { + Effort.Low => "low", + Effort.Medium => "medium", + Effort.High => "high", + Effort.Max => "max", + _ => throw new AnthropicInvalidDataException( + string.Format("Invalid value '{0}' in {1}", value, nameof(value)) + ), + }, + options + ); + } +} diff --git a/src/Anthropic/Models/Messages/ThinkingConfigAdaptive.cs b/src/Anthropic/Models/Messages/ThinkingConfigAdaptive.cs new file mode 100644 index 000000000..56fe6f47a --- /dev/null +++ b/src/Anthropic/Models/Messages/ThinkingConfigAdaptive.cs @@ -0,0 +1,74 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Models.Messages; + +[JsonConverter(typeof(JsonModelConverter))] +public sealed record class ThinkingConfigAdaptive : JsonModel +{ + public JsonElement Type + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNotNullStruct("type"); + } + init { this._rawData.Set("type", value); } + } + + /// + public override void Validate() + { + if (!JsonElement.DeepEquals(this.Type, JsonSerializer.SerializeToElement("adaptive"))) + { + throw new AnthropicInvalidDataException("Invalid value given for constant"); + } + } + + public ThinkingConfigAdaptive() + { + this.Type = JsonSerializer.SerializeToElement("adaptive"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + public ThinkingConfigAdaptive(ThinkingConfigAdaptive thinkingConfigAdaptive) + : base(thinkingConfigAdaptive) { } +#pragma warning restore CS8618 + + public ThinkingConfigAdaptive(IReadOnlyDictionary rawData) + { + this._rawData = new(rawData); + + this.Type = JsonSerializer.SerializeToElement("adaptive"); + } + +#pragma warning disable CS8618 + [SetsRequiredMembers] + ThinkingConfigAdaptive(FrozenDictionary rawData) + { + this._rawData = new(rawData); + } +#pragma warning restore CS8618 + + /// + public static ThinkingConfigAdaptive FromRawUnchecked( + IReadOnlyDictionary rawData + ) + { + return new(FrozenDictionary.ToFrozenDictionary(rawData)); + } +} + +class ThinkingConfigAdaptiveFromRaw : IFromRawJson +{ + /// + public ThinkingConfigAdaptive FromRawUnchecked( + IReadOnlyDictionary rawData + ) => ThinkingConfigAdaptive.FromRawUnchecked(rawData); +} diff --git a/src/Anthropic/Models/Messages/ThinkingConfigParam.cs b/src/Anthropic/Models/Messages/ThinkingConfigParam.cs index c80b05f07..d567e9b1a 100644 --- a/src/Anthropic/Models/Messages/ThinkingConfigParam.cs +++ b/src/Anthropic/Models/Messages/ThinkingConfigParam.cs @@ -37,7 +37,10 @@ public JsonElement Json public JsonElement Type { - get { return Match(enabled: (x) => x.Type, disabled: (x) => x.Type); } + get + { + return Match(enabled: (x) => x.Type, disabled: (x) => x.Type, adaptive: (x) => x.Type); + } } public ThinkingConfigParam(ThinkingConfigEnabled value, JsonElement? element = null) @@ -52,6 +55,12 @@ public ThinkingConfigParam(ThinkingConfigDisabled value, JsonElement? element = this._element = element; } + public ThinkingConfigParam(ThinkingConfigAdaptive value, JsonElement? element = null) + { + this.Value = value; + this._element = element; + } + public ThinkingConfigParam(JsonElement element) { this._element = element; @@ -99,6 +108,27 @@ public bool TryPickDisabled([NotNullWhen(true)] out ThinkingConfigDisabled? valu return value != null; } + /// + /// Returns true and sets the out parameter if the instance was constructed with a variant of + /// type . + /// + /// Consider using or if you need to handle every variant. + /// + /// + /// + /// if (instance.TryPickAdaptive(out var value)) { + /// // `value` is of type `ThinkingConfigAdaptive` + /// Console.WriteLine(value); + /// } + /// + /// + /// + public bool TryPickAdaptive([NotNullWhen(true)] out ThinkingConfigAdaptive? value) + { + value = this.Value as ThinkingConfigAdaptive; + return value != null; + } + /// /// Calls the function parameter corresponding to the variant the instance was constructed with. /// @@ -114,14 +144,16 @@ public bool TryPickDisabled([NotNullWhen(true)] out ThinkingConfigDisabled? valu /// /// instance.Switch( /// (ThinkingConfigEnabled value) => {...}, - /// (ThinkingConfigDisabled value) => {...} + /// (ThinkingConfigDisabled value) => {...}, + /// (ThinkingConfigAdaptive value) => {...} /// ); /// /// /// public void Switch( System::Action enabled, - System::Action disabled + System::Action disabled, + System::Action adaptive ) { switch (this.Value) @@ -132,6 +164,9 @@ public void Switch( case ThinkingConfigDisabled value: disabled(value); break; + case ThinkingConfigAdaptive value: + adaptive(value); + break; default: throw new AnthropicInvalidDataException( "Data did not match any variant of ThinkingConfigParam" @@ -155,20 +190,23 @@ public void Switch( /// /// var result = instance.Match( /// (ThinkingConfigEnabled value) => {...}, - /// (ThinkingConfigDisabled value) => {...} + /// (ThinkingConfigDisabled value) => {...}, + /// (ThinkingConfigAdaptive value) => {...} /// ); /// /// /// public T Match( System::Func enabled, - System::Func disabled + System::Func disabled, + System::Func adaptive ) { return this.Value switch { ThinkingConfigEnabled value => enabled(value), ThinkingConfigDisabled value => disabled(value), + ThinkingConfigAdaptive value => adaptive(value), _ => throw new AnthropicInvalidDataException( "Data did not match any variant of ThinkingConfigParam" ), @@ -179,6 +217,8 @@ public T Match( public static implicit operator ThinkingConfigParam(ThinkingConfigDisabled value) => new(value); + public static implicit operator ThinkingConfigParam(ThinkingConfigAdaptive value) => new(value); + /// /// Validates that the instance was constructed with a known variant and that this variant is valid /// (based on its own Validate method). @@ -197,7 +237,11 @@ public override void Validate() "Data did not match any variant of ThinkingConfigParam" ); } - this.Switch((enabled) => enabled.Validate(), (disabled) => disabled.Validate()); + this.Switch( + (enabled) => enabled.Validate(), + (disabled) => disabled.Validate(), + (adaptive) => adaptive.Validate() + ); } public virtual bool Equals(ThinkingConfigParam? other) => @@ -219,6 +263,7 @@ int VariantIndex() { ThinkingConfigEnabled _ => 0, ThinkingConfigDisabled _ => 1, + ThinkingConfigAdaptive _ => 2, _ => -1, }; } @@ -289,6 +334,28 @@ JsonSerializerOptions options return new(element); } + case "adaptive": + { + try + { + var deserialized = JsonSerializer.Deserialize( + element, + options + ); + if (deserialized != null) + { + deserialized.Validate(); + return new(deserialized, element); + } + } + catch (System::Exception e) + when (e is JsonException || e is AnthropicInvalidDataException) + { + // ignore + } + + return new(element); + } default: { return new ThinkingConfigParam(element); diff --git a/src/Anthropic/Models/Messages/Tool.cs b/src/Anthropic/Models/Messages/Tool.cs index 38f9ab905..c5a62fb8d 100644 --- a/src/Anthropic/Models/Messages/Tool.cs +++ b/src/Anthropic/Models/Messages/Tool.cs @@ -83,6 +83,23 @@ public string? Description } } + /// + /// Enable eager input streaming for this tool. When true, tool input parameters + /// will be streamed incrementally as they are generated, and types will be inferred + /// on-the-fly rather than buffering the full JSON output. When false, streaming + /// is disabled for this tool even if the fine-grained-tool-streaming beta is + /// active. When null (default), uses the default behavior based on beta headers. + /// + public bool? EagerInputStreaming + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableStruct("eager_input_streaming"); + } + init { this._rawData.Set("eager_input_streaming", value); } + } + /// /// When true, guarantees schema validation on tool names and inputs /// @@ -123,6 +140,7 @@ public override void Validate() _ = this.Name; this.CacheControl?.Validate(); _ = this.Description; + _ = this.EagerInputStreaming; _ = this.Strict; this.Type?.Validate(); } diff --git a/src/Anthropic/Models/Messages/Usage.cs b/src/Anthropic/Models/Messages/Usage.cs index 6cc1b50b9..4e767c35c 100644 --- a/src/Anthropic/Models/Messages/Usage.cs +++ b/src/Anthropic/Models/Messages/Usage.cs @@ -51,6 +51,19 @@ public required long? CacheReadInputTokens init { this._rawData.Set("cache_read_input_tokens", value); } } + /// + /// The geographic region where inference was performed for this request. + /// + public required string? InferenceGeo + { + get + { + this._rawData.Freeze(); + return this._rawData.GetNullableClass("inference_geo"); + } + init { this._rawData.Set("inference_geo", value); } + } + /// /// The number of input tokens which were used. /// @@ -111,6 +124,7 @@ public override void Validate() this.CacheCreation?.Validate(); _ = this.CacheCreationInputTokens; _ = this.CacheReadInputTokens; + _ = this.InferenceGeo; _ = this.InputTokens; _ = this.OutputTokens; this.ServerToolUse?.Validate(); From 5d1eb0a84492af9fd4be666c6b8c34b03982699d Mon Sep 17 00:00:00 2001 From: Andrea Sciutto Date: Fri, 6 Feb 2026 06:51:24 +1300 Subject: [PATCH 34/41] fix: update beta service to use output_config.format (#110) output_format is depracated in favour of output_config.format. Update api call configuration to reflect this change update test to reflect this change --- .../AnthropicClientBetaExtensionsTests.cs | 104 +++++++++--------- .../Messages/AnthropicBetaClientExtensions.cs | 17 ++- 2 files changed, 66 insertions(+), 55 deletions(-) diff --git a/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs b/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs index 3fb641f5b..836718105 100644 --- a/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs +++ b/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs @@ -532,16 +532,18 @@ public async Task GetResponseAsync_WithSimpleResponseFormat_ReturnsStructuredJSO "text": "Tell me about Albert Einstein. Respond with his name and age at death." }] }], - "output_format": { - "type": "json_schema", - "schema": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "age": { "type": "integer" } - }, - "required": ["name", "age"], - "additionalProperties": false + "output_config": { + "format": { + "type": "json_schema", + "schema": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "age": { "type": "integer" } + }, + "required": ["name", "age"], + "additionalProperties": false + } } } } @@ -613,27 +615,29 @@ public async Task GetResponseAsync_WithNestedObjectSchema_ReturnsStructuredJSON( "text": "Tell me about the book '1984' by George Orwell." }] }], - "output_format": { - "type": "json_schema", - "schema": { - "type": "object", - "properties": { - "title": { "type": "string" }, - "author": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "birth_year": { "type": "integer" } + "output_config": { + "format": { + "type": "json_schema", + "schema": { + "type": "object", + "properties": { + "title": { "type": "string" }, + "author": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "birth_year": { "type": "integer" } + }, + "required": ["name", "birth_year"], + "additionalProperties": false }, - "required": ["name", "birth_year"], - "additionalProperties": false + "published_year": { + "type": "integer" + } }, - "published_year": { - "type": "integer" - } - }, - "required": ["title", "author", "published_year"], - "additionalProperties": false + "required": ["title", "author", "published_year"], + "additionalProperties": false + } } } } @@ -715,27 +719,29 @@ public async Task GetResponseAsync_WithArraySchema_ReturnsStructuredJSON() "text": "List 3 common fruits: apple, orange, and banana." }] }], - "output_format": { - "type": "json_schema", - "schema": { - "type": "object", - "properties": { - "fruits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { "type": "string" }, - "color": { "type": "string" }, - "is_citrus": { "type": "boolean" } - }, - "required": ["name", "color", "is_citrus"], - "additionalProperties": false + "output_config": { + "format": { + "type": "json_schema", + "schema": { + "type": "object", + "properties": { + "fruits": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "color": { "type": "string" }, + "is_citrus": { "type": "boolean" } + }, + "required": ["name", "color", "is_citrus"], + "additionalProperties": false + } } - } - }, - "required": ["fruits"], - "additionalProperties": false + }, + "required": ["fruits"], + "additionalProperties": false + } } } } diff --git a/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs b/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs index 0f569308c..1736674e3 100644 --- a/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs +++ b/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs @@ -922,14 +922,19 @@ createParams.OutputFormat is null { createParams = createParams with { - OutputFormat = new BetaJsonOutputFormat() + OutputConfig = new BetaOutputConfig() { - Schema = new Dictionary + Format = new BetaJsonOutputFormat() { - ["type"] = JsonElement.Parse("\"object\""), - ["properties"] = properties, - ["required"] = required, - ["additionalProperties"] = JsonElement.Parse("false"), + Schema = new Dictionary + { + ["type"] = JsonElement.Parse("\"object\""), + ["properties"] = properties, + ["required"] = required, + ["additionalProperties"] = JsonElement.Parse( + "false" + ), + }, }, }, }; From 310b769ec87f4b6f519890ee9babae035120e477 Mon Sep 17 00:00:00 2001 From: Stephen Date: Thu, 5 Feb 2026 10:30:43 -0800 Subject: [PATCH 35/41] fix build (#111) --- .../Services/MessageServiceTest.cs | 134 +++---- .../Services/Messages/BatchServiceTest.cs | 337 +++++++++--------- 2 files changed, 237 insertions(+), 234 deletions(-) diff --git a/src/Anthropic.Tests/Services/MessageServiceTest.cs b/src/Anthropic.Tests/Services/MessageServiceTest.cs index 5cf967098..1ba047f21 100644 --- a/src/Anthropic.Tests/Services/MessageServiceTest.cs +++ b/src/Anthropic.Tests/Services/MessageServiceTest.cs @@ -1,67 +1,67 @@ -using System.Threading.Tasks; -using Anthropic.Bedrock; -using Anthropic.Models.Messages; - -namespace Anthropic.Tests.Services; - -public class MessageServiceTest -{ - [Theory] - [AnthropicTestClients] - [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] - [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] - [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] - public async Task Create_Works(IAnthropicClient client, string modelName) - { - var message = await client.Messages.Create( - new MessageCreateParams() - { - MaxTokens = 1024, - Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = modelName, - }, - TestContext.Current.CancellationToken - ); - message.Validate(); - } - - [Theory] - [AnthropicTestClients] - [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] - [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] - [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] - public async Task CreateStreaming_Works(IAnthropicClient client, string modelName) - { - var stream = client.Messages.CreateStreaming( - new() - { - MaxTokens = 1024, - Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = modelName, - }, - TestContext.Current.CancellationToken - ); - - await foreach (var message in stream) - { - message.Validate(); - } - } - - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] - [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] - public async Task CountTokens_Works(IAnthropicClient client, string modelName) - { - var messageTokensCount = await client.Messages.CountTokens( - new() - { - Messages = [new() { Content = "string", Role = Role.User }], - Model = modelName, - }, - TestContext.Current.CancellationToken - ); - messageTokensCount.Validate(); - } -} +using System.Threading.Tasks; +using Anthropic.Bedrock; +using Anthropic.Models.Messages; + +namespace Anthropic.Tests.Services; + +public class MessageServiceTest +{ + [Theory] + [AnthropicTestClients] + [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] + [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] + public async Task Create_Works(IAnthropicClient client, string modelName) + { + var message = await client.Messages.Create( + new MessageCreateParams() + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Role.User }], + Model = modelName, + }, + TestContext.Current.CancellationToken + ); + message.Validate(); + } + + [Theory] + [AnthropicTestClients] + [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] + [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] + public async Task CreateStreaming_Works(IAnthropicClient client, string modelName) + { + var stream = client.Messages.CreateStreaming( + new() + { + MaxTokens = 1024, + Messages = [new() { Content = "Hello, world", Role = Role.User }], + Model = modelName, + }, + TestContext.Current.CancellationToken + ); + + await foreach (var message in stream) + { + message.Validate(); + } + } + + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] + [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + public async Task CountTokens_Works(IAnthropicClient client, string modelName) + { + var messageTokensCount = await client.Messages.CountTokens( + new() + { + Messages = [new() { Content = "string", Role = Role.User }], + Model = modelName, + }, + TestContext.Current.CancellationToken + ); + messageTokensCount.Validate(); + } +} diff --git a/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs b/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs index ce8171834..9e8344be3 100644 --- a/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs +++ b/src/Anthropic.Tests/Services/Messages/BatchServiceTest.cs @@ -1,167 +1,170 @@ -using System.Collections.Generic; -using System.Text.Json; -using System.Threading.Tasks; -using Anthropic.Models.Messages.Batches; -using Anthropic.Tests; -using Messages = Anthropic.Models.Messages; - -namespace Anthropic.Tests.Services.Messages; - -public class BatchServiceTest -{ - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] - [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] - public async Task Create_Works(IAnthropicClient client, string modelName) - { - var messageBatch = await client.Messages.Batches.Create( - new() - { - Requests = - [ - new() - { - CustomID = "my-custom-id-1", - Params = new() - { - MaxTokens = 1024, - Messages = [new() { Content = "Hello, world", Role = Role.User }], - Model = modelName, - InferenceGeo = "inference_geo", - Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, - OutputConfig = new() - { - Effort = Effort.Low, - Format = new() - { - Schema = new Dictionary() - { - { "foo", JsonSerializer.SerializeToElement("bar") }, - }, - }, - }, - ServiceTier = ServiceTier.Auto, - StopSequences = ["string"], - Stream = true, - System = new( - [ - new Messages::TextBlockParam() - { - Text = "Today's date is 2024-06-01.", - CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, - Citations = - [ - new Messages::CitationCharLocationParam() - { - CitedText = "cited_text", - DocumentIndex = 0, - DocumentTitle = "x", - EndCharIndex = 0, - StartCharIndex = 0, - }, - ], - }, - ] - ), - Temperature = 1, - Thinking = new Messages::ThinkingConfigEnabled(1024), - ToolChoice = new Messages::ToolChoiceAuto() - { - DisableParallelToolUse = true, - }, - Tools = - [ - new Messages::Tool() - { - InputSchema = new() - { - Properties = new Dictionary() - { - { - "location", - JsonSerializer.SerializeToElement("bar") - }, - { "unit", JsonSerializer.SerializeToElement("bar") }, - }, - Required = ["location"], - }, - Name = "name", - CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, - Description = "Get the current weather in a given location", - EagerInputStreaming = true, - Strict = true, - Type = Messages::Type.Custom, - }, - ], - TopK = 5, - TopP = 0.7, - }, - }, - ], - }, - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - public async Task Retrieve_Works(IAnthropicClient client) - { - var messageBatch = await client.Messages.Batches.Retrieve( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - public async Task List_Works(IAnthropicClient client) - { - var page = await client.Messages.Batches.List(new(), TestContext.Current.CancellationToken); - page.Validate(); - } - - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - public async Task Delete_Works(IAnthropicClient client) - { - var deletedMessageBatch = await client.Messages.Batches.Delete( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - deletedMessageBatch.Validate(); - } - - [Theory] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - public async Task Cancel_Works(IAnthropicClient client) - { - var messageBatch = await client.Messages.Batches.Cancel( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - messageBatch.Validate(); - } - - [Theory(Skip = "Prism doesn't support application/x-jsonl responses")] - [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] - public async Task ResultsStreaming_Works(IAnthropicClient client) - { - var stream = client.Messages.Batches.ResultsStreaming( - "message_batch_id", - new(), - TestContext.Current.CancellationToken - ); - - await foreach (var messageBatchIndividualResponse in stream) - { - messageBatchIndividualResponse.Validate(); - } - } -} +using System.Collections.Generic; +using System.Text.Json; +using System.Threading.Tasks; +using Anthropic.Models.Messages.Batches; +using Anthropic.Tests; +using Messages = Anthropic.Models.Messages; + +namespace Anthropic.Tests.Services.Messages; + +public class BatchServiceTest +{ + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] + [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] + public async Task Create_Works(IAnthropicClient client, string modelName) + { + var messageBatch = await client.Messages.Batches.Create( + new() + { + Requests = + [ + new() + { + CustomID = "my-custom-id-1", + Params = new() + { + MaxTokens = 1024, + Messages = + [ + new() { Content = "Hello, world", Role = Messages::Role.User }, + ], + Model = modelName, + InferenceGeo = "inference_geo", + Metadata = new() { UserID = "13803d75-b4b5-4c3e-b2a2-6f21399b021b" }, + OutputConfig = new() + { + Effort = Messages::Effort.Low, + Format = new() + { + Schema = new Dictionary() + { + { "foo", JsonSerializer.SerializeToElement("bar") }, + }, + }, + }, + ServiceTier = ServiceTier.Auto, + StopSequences = ["string"], + Stream = true, + System = new( + [ + new Messages::TextBlockParam() + { + Text = "Today's date is 2024-06-01.", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Citations = + [ + new Messages::CitationCharLocationParam() + { + CitedText = "cited_text", + DocumentIndex = 0, + DocumentTitle = "x", + EndCharIndex = 0, + StartCharIndex = 0, + }, + ], + }, + ] + ), + Temperature = 1, + Thinking = new Messages::ThinkingConfigEnabled(1024), + ToolChoice = new Messages::ToolChoiceAuto() + { + DisableParallelToolUse = true, + }, + Tools = + [ + new Messages::Tool() + { + InputSchema = new() + { + Properties = new Dictionary() + { + { + "location", + JsonSerializer.SerializeToElement("bar") + }, + { "unit", JsonSerializer.SerializeToElement("bar") }, + }, + Required = ["location"], + }, + Name = "name", + CacheControl = new() { Ttl = Messages::Ttl.Ttl5m }, + Description = "Get the current weather in a given location", + EagerInputStreaming = true, + Strict = true, + Type = Messages::Type.Custom, + }, + ], + TopK = 5, + TopP = 0.7, + }, + }, + ], + }, + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + public async Task Retrieve_Works(IAnthropicClient client) + { + var messageBatch = await client.Messages.Batches.Retrieve( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + public async Task List_Works(IAnthropicClient client) + { + var page = await client.Messages.Batches.List(new(), TestContext.Current.CancellationToken); + page.Validate(); + } + + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + public async Task Delete_Works(IAnthropicClient client) + { + var deletedMessageBatch = await client.Messages.Batches.Delete( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + deletedMessageBatch.Validate(); + } + + [Theory] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + public async Task Cancel_Works(IAnthropicClient client) + { + var messageBatch = await client.Messages.Batches.Cancel( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + messageBatch.Validate(); + } + + [Theory(Skip = "Prism doesn't support application/x-jsonl responses")] + [AnthropicTestClients(TestSupportTypes.All & ~TestSupportTypes.Bedrock)] + public async Task ResultsStreaming_Works(IAnthropicClient client) + { + var stream = client.Messages.Batches.ResultsStreaming( + "message_batch_id", + new(), + TestContext.Current.CancellationToken + ); + + await foreach (var messageBatchIndividualResponse in stream) + { + messageBatchIndividualResponse.Validate(); + } + } +} From 2f17663e760c8cc450b138447b22cc4a1ea6861f Mon Sep 17 00:00:00 2001 From: Stephen Date: Thu, 5 Feb 2026 12:40:32 -0800 Subject: [PATCH 36/41] feat(client): streaming aggregators (#105) * chore: add release notes * Implement message Aggregator * Add prism log to gitignore * Fix test script * Add streaming aggregators * Refactored aggregator for v0.1.0 * Fixed copypaste SignatureDelta issue * WIP Aggregator refactor * applied review comments * Fix merge conflict Format code * apply review comments * Lint code * Apply code review * fix test results * apply review comments * properly await Aggregate function * lint files * Refactor code to provide in-place aggregation * Add example * Fix examples and lint code * Update readme and example * Fix tests * apply review sugestions * fix tests * fix tests * Apply suggestions from code review Co-authored-by: Stephen * typo * remove obsolete gitignore entry * typo * lint * fix linter? * fix lint * fixes * example working * done? * fix formatting * fixes * add exception when computed timeout is too high * update readme * address feedback * formatting --------- Co-authored-by: meorphis Co-authored-by: JPVenson Co-authored-by: JPVenson --- Anthropic.sln | 36 +- README.md | 44 +++ examples/Anthropic.Examples.sln | 13 + .../Program.cs | 48 +++ .../StreamingAggregationExample.csproj | 11 + .../StreamingAggregationExample/Program.cs | 50 +++ .../StreamingAggregationExample.csproj | 11 + src/Anthropic.Tests/Anthropic.Tests.csproj | 1 + .../Services/Beta/MessageServiceTest.cs | 353 ++++++++++++++++- .../Services/MessageServiceTest.cs | 356 ++++++++++++++++++ src/Anthropic/Core/ClientOptions.cs | 60 +++ .../Helpers/BetaMessageContentAggregator.cs | 198 ++++++++++ .../Helpers/MessageContentAggregator.cs | 183 +++++++++ src/Anthropic/Helpers/SseAggregator.cs | 119 ++++++ src/Anthropic/Services/Beta/MessageService.cs | 16 +- src/Anthropic/Services/MessageService.cs | 16 +- src/Anthropic/SseAggregatorExtensions.cs | 68 ++++ 17 files changed, 1570 insertions(+), 13 deletions(-) create mode 100644 examples/StreamingAggregationBetaExample/Program.cs create mode 100644 examples/StreamingAggregationBetaExample/StreamingAggregationExample.csproj create mode 100644 examples/StreamingAggregationExample/Program.cs create mode 100644 examples/StreamingAggregationExample/StreamingAggregationExample.csproj create mode 100644 src/Anthropic/Helpers/BetaMessageContentAggregator.cs create mode 100644 src/Anthropic/Helpers/MessageContentAggregator.cs create mode 100644 src/Anthropic/Helpers/SseAggregator.cs create mode 100644 src/Anthropic/SseAggregatorExtensions.cs diff --git a/Anthropic.sln b/Anthropic.sln index 15013d25c..fc3fd450c 100644 --- a/Anthropic.sln +++ b/Anthropic.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 18 -VisualStudioVersion = 18.0.11205.157 d18.0 +VisualStudioVersion = 18.0.11205.157 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Anthropic", "src\Anthropic\Anthropic.csproj", "{5816A0C1-3BA1-454E-8D08-85B23DEF309D}" EndProject @@ -15,15 +15,21 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Anthropic.Bedrock", "src\An EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{93E58BA5-CEFE-447E-AC0C-F2C5BC4C411D}" ProjectSection(SolutionItems) = preProject - CHANGELOG.md - .csharpierignore - .editorconfig - .gitignore - LICENSE - README.md - SECURITY.md + CHANGELOG.md = CHANGELOG.md + .csharpierignore = .csharpierignore + .editorconfig = .editorconfig + .gitignore = .gitignore + LICENSE = LICENSE + README.md = README.md + SECURITY.md = SECURITY.md EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StreamingAggregationBetaExample", "StreamingAggregationBetaExample", "{6D5DEC39-3673-615E-54FA-C74C69400686}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StreamingAggregationExample", "examples\StreamingAggregationBetaExample\StreamingAggregationExample.csproj", "{0E525CB1-B565-4ABE-B477-48C53F9BB258}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -82,6 +88,18 @@ Global {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|x64.Build.0 = Release|Any CPU {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|x86.ActiveCfg = Release|Any CPU {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|x86.Build.0 = Release|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Debug|x64.ActiveCfg = Debug|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Debug|x64.Build.0 = Debug|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Debug|x86.ActiveCfg = Debug|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Debug|x86.Build.0 = Debug|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Release|Any CPU.Build.0 = Release|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Release|x64.ActiveCfg = Release|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Release|x64.Build.0 = Release|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Release|x86.ActiveCfg = Release|Any CPU + {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -91,5 +109,7 @@ Global {0732C8A6-7313-4C33-AE2E-FFAA82EFB481} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {DD0E539D-6D5F-45EB-A807-01BE0A443604} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {72FC9906-07F4-4911-8D6B-F9814974BB37} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} + {6D5DEC39-3673-615E-54FA-C74C69400686} = {B36A84DF-456D-A817-6EDD-3EC3E7F6E11F} + {0E525CB1-B565-4ABE-B477-48C53F9BB258} = {6D5DEC39-3673-615E-54FA-C74C69400686} EndGlobalSection EndGlobal diff --git a/README.md b/README.md index 86f899687..0e9c8f83f 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,13 @@ To send a request to the Anthropic API, build an instance of some `Params` class For example, `client.Messages.Create` should be called with an instance of `MessageCreateParams`, and it will return an instance of `Task`. +> [!IMPORTANT] +> We highly encourage you to use [streaming](#streaming) for longer running requests. + +We do not recommend setting a large `MaxTokens` value without using streaming. Some networks may drop idle connections after a certain period of time, which can cause the request to fail or [timeout](#timeouts) without receiving a response from Anthropic. We periodically ping the API to keep the connection alive and reduce the impact of these networks. + +The SDK throws an error if a non-streaming request is expected to take longer than 10 minutes. Using a [streaming method](#streaming) or [overriding the timeout](#timeouts) at the client or request level disables the error. + ## Streaming The SDK defines methods that return response "chunk" streams, where each chunk can be individually processed as soon as it arrives instead of waiting on the full response. Streaming methods generally correspond to [SSE](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) or [JSONL](https://jsonlines.org) responses. @@ -155,6 +162,43 @@ await foreach (var message in client.Messages.CreateStreaming(parameters)) } ``` +### Aggregators + +Both the [Messages](src/Anthropic/Models/Messages/Message.cs) and [BetaMessages](src/Anthropic/Models/Beta/Messages/BetaMessage.cs) streaming endpoints have built-in aggregators that can produce the same object as its non-streaming counterparts. + +It is possible to either only get the full result object via the `.Aggregate()` extension on the `IAsyncEnumerable` returned by the `CreateStreaming` method or insert an external aggregator into a LINQ tree: + +```csharp +IAsyncEnumerable responseUpdates = client.Messages.CreateStreaming( + parameters +); + +// This produces a single object based on the streaming output. +var message = await responseUpdates.Aggregate().ConfigureAwait(false); + +// You can also add an aggregator as part of your LINQ chain to get realtime streaming and aggregation + +var aggregator = new MessageContentAggregator(); +await foreach (RawMessageStreamEvent rawEvent in responseUpdates.CollectAsync(aggregator)) +{ + // Do something with the stream events + if (rawEvent.TryPickContentBlockDelta(out var delta)) + { + if (delta.Delta.TryPickThinking(out var thinkingDelta)) + { + Console.Write(thinkingDelta.Thinking); + } + else if (delta.Delta.TryPickText(out var textDelta)) + { + Console.Write(textDelta.Text); + } + } +} + +// And then get the full aggregated message. +var fullMessage = await aggregator.Message(); +``` + ## `IChatClient` The SDK provides an implementation of the `IChatClient` interface from the `Microsoft.Extensions.AI.Abstractions` library. diff --git a/examples/Anthropic.Examples.sln b/examples/Anthropic.Examples.sln index 933d318b9..eea860c9b 100644 --- a/examples/Anthropic.Examples.sln +++ b/examples/Anthropic.Examples.sln @@ -13,6 +13,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagesStreamingExample", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatClientExample", "ChatClientExample\ChatClientExample.csproj", "{AA6ED2E6-A693-4FD8-AF20-1D339FBFBF96}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StreamingAggregationExample", "StreamingAggregationExample\StreamingAggregationExample.csproj", "{8E03AF57-D948-47B7-9038-D6F1468B6BCC}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagesExample.Foundry", "MessagesExample.Foundry\MessagesExample.Foundry.csproj", "{5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagesExample.Bedrock", "MessagesExample.Bedrock\MessagesExample.Bedrock.csproj", "{7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}" @@ -87,6 +88,18 @@ Global {AA6ED2E6-A693-4FD8-AF20-1D339FBFBF96}.Release|x64.Build.0 = Release|Any CPU {AA6ED2E6-A693-4FD8-AF20-1D339FBFBF96}.Release|x86.ActiveCfg = Release|Any CPU {AA6ED2E6-A693-4FD8-AF20-1D339FBFBF96}.Release|x86.Build.0 = Release|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Debug|x64.ActiveCfg = Debug|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Debug|x64.Build.0 = Debug|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Debug|x86.ActiveCfg = Debug|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Debug|x86.Build.0 = Debug|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Release|Any CPU.Build.0 = Release|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Release|x64.ActiveCfg = Release|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Release|x64.Build.0 = Release|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Release|x86.ActiveCfg = Release|Any CPU + {8E03AF57-D948-47B7-9038-D6F1468B6BCC}.Release|x86.Build.0 = Release|Any CPU {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Debug|Any CPU.Build.0 = Debug|Any CPU {5AD47EFB-4DE0-4F91-A6CB-C1DE6EFD5BD2}.Debug|x64.ActiveCfg = Debug|Any CPU diff --git a/examples/StreamingAggregationBetaExample/Program.cs b/examples/StreamingAggregationBetaExample/Program.cs new file mode 100644 index 000000000..667e8209c --- /dev/null +++ b/examples/StreamingAggregationBetaExample/Program.cs @@ -0,0 +1,48 @@ +using Anthropic; +using Anthropic.Helpers; +using Anthropic.Models.Beta.Messages; +using Anthropic.Services.Beta.Messages; +using Messages = Anthropic.Models.Messages; + +// Configured using the ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN and ANTHROPIC_BASE_URL environment variables +AnthropicClient client = new(); + +var responseUpdates = client.Beta.Messages.CreateStreaming( + new() + { + MaxTokens = 2048, + Messages = + [ + new() { Content = "Tell me a story about building the best SDK!", Role = Role.User }, + ], + Model = Messages::Model.Claude4Sonnet20250514, + } +); + +// some streaming endpoints have built-in aggregators that create logically aggregated objects. +// these represent the full stream as a single object. +var message = await responseUpdates.Aggregate().ConfigureAwait(false); +Console.WriteLine(message); + +// you can also add an aggregator as part of your LINQ chain to get real-time streaming and aggregation + +var aggregator = new BetaMessageContentAggregator(); +await foreach (BetaRawMessageStreamEvent rawEvent in responseUpdates.CollectAsync(aggregator)) +{ + // do something with the stream events + if (rawEvent.TryPickContentBlockDelta(out var delta)) + { + if (delta.Delta.TryPickThinking(out var thinkingDelta)) + { + Console.Write(thinkingDelta.Thinking); + } + else if (delta.Delta.TryPickText(out var textDelta)) + { + Console.Write(textDelta.Text); + } + } +} + +// and then get the full aggregated message +var message2 = aggregator.Message(); +Console.WriteLine(message2); diff --git a/examples/StreamingAggregationBetaExample/StreamingAggregationExample.csproj b/examples/StreamingAggregationBetaExample/StreamingAggregationExample.csproj new file mode 100644 index 000000000..37dbf3370 --- /dev/null +++ b/examples/StreamingAggregationBetaExample/StreamingAggregationExample.csproj @@ -0,0 +1,11 @@ + + + + + + Exe + net8.0 + enable + enable + + diff --git a/examples/StreamingAggregationExample/Program.cs b/examples/StreamingAggregationExample/Program.cs new file mode 100644 index 000000000..03aa82e79 --- /dev/null +++ b/examples/StreamingAggregationExample/Program.cs @@ -0,0 +1,50 @@ +using Anthropic; +using Anthropic.Helpers; +using Anthropic.Models.Messages; +using Anthropic.Services.Messages; + +// Configured using the ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN and ANTHROPIC_BASE_URL environment variables +AnthropicClient client = new(); + +MessageCreateParams parameters = new() +{ + MaxTokens = 2048, + Messages = + [ + new() { Content = "Tell me a story about building the best SDK!", Role = Role.User }, + ], + Model = Model.Claude4Sonnet20250514, + Thinking = new ThinkingConfigEnabled() { BudgetTokens = 1024 }, +}; + +IAsyncEnumerable responseUpdates = client.Messages.CreateStreaming( + parameters +); + +// some streaming endpoints have built-in aggregators that create logically aggregated objects. +// these represent the full stream as a single object. +var message = await responseUpdates.Aggregate().ConfigureAwait(false); +Console.WriteLine(message); + +// you can also add an aggregator as part of your LINQ chain to get real-time streaming and aggregation + +var aggregator = new MessageContentAggregator(); +await foreach (RawMessageStreamEvent rawEvent in responseUpdates.CollectAsync(aggregator)) +{ + // do something with the stream events + if (rawEvent.TryPickContentBlockDelta(out var delta)) + { + if (delta.Delta.TryPickThinking(out var thinkingDelta)) + { + Console.Write(thinkingDelta.Thinking); + } + else if (delta.Delta.TryPickText(out var textDelta)) + { + Console.Write(textDelta.Text); + } + } +} + +// and then get the full aggregated message +var message2 = aggregator.Message(); +Console.WriteLine(message2); diff --git a/examples/StreamingAggregationExample/StreamingAggregationExample.csproj b/examples/StreamingAggregationExample/StreamingAggregationExample.csproj new file mode 100644 index 000000000..37dbf3370 --- /dev/null +++ b/examples/StreamingAggregationExample/StreamingAggregationExample.csproj @@ -0,0 +1,11 @@ + + + + + + Exe + net8.0 + enable + enable + + diff --git a/src/Anthropic.Tests/Anthropic.Tests.csproj b/src/Anthropic.Tests/Anthropic.Tests.csproj index b5c6a9083..8fb3cca27 100644 --- a/src/Anthropic.Tests/Anthropic.Tests.csproj +++ b/src/Anthropic.Tests/Anthropic.Tests.csproj @@ -14,6 +14,7 @@ + diff --git a/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs b/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs index 56181335b..626940959 100644 --- a/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs +++ b/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs @@ -1,12 +1,46 @@ +using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; +using Anthropic.Helpers; using Anthropic.Models.Beta.Messages; -using Anthropic.Tests; +using Anthropic.Services.Beta; +using Moq; using Messages = Anthropic.Models.Messages; namespace Anthropic.Tests.Services.Beta; public class MessageServiceTest { + private static BetaMessage GenerateStartMessage => + new() + { + ID = "Test", + Content = [], + Model = Messages::Model.Claude3OpusLatest, + StopReason = BetaStopReason.ToolUse, + StopSequence = "", + Usage = new() + { + CacheCreation = null, + CacheCreationInputTokens = null, + CacheReadInputTokens = null, + InputTokens = 25, + OutputTokens = 25, + ServerToolUse = null, + ServiceTier = BetaUsageServiceTier.Standard, + }, + Container = null, + ContextManagement = null, + }; + + private static MessageCreateParams StreamingParam => + new() + { + MaxTokens = 1024, + Messages = [new() { Content = new(""), Role = Role.User }], + Model = Messages::Model.Claude3OpusLatest, + }; + [Theory(Skip = "prism validates based on the non-beta endpoint")] [AnthropicTestClients] public async Task Create_Works(IAnthropicClient client) @@ -57,4 +91,321 @@ public async Task CountTokens_Works(IAnthropicClient client) ); betaMessageTokensCount.Validate(); } + + [Fact] + public async Task CreateStreamingAggregation_WorksNoContent_RawMessageStartEvent() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new BetaRawMessageStartEvent(GenerateStartMessage)); + yield return new(new BetaRawMessageStopEvent()); + await Task.CompletedTask; + } + messagesServiceMock + .Setup(e => + e.CreateStreaming(It.IsAny(), It.IsAny()) + ) + .Returns(GetTestValues); + + // act + + var stream = await messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .Aggregate(); + + // assert + + Assert.NotNull(stream); + Assert.Empty(stream.Content); + stream.Validate(); + } + + [Fact] + public async Task CreateStreamingAggregation_HandlesNoEndMessageInterrupt() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new BetaRawMessageStartEvent(GenerateStartMessage)); + await Task.CompletedTask; + } + messagesServiceMock + .Setup(e => + e.CreateStreaming(It.IsAny(), It.IsAny()) + ) + .Returns(GetTestValues); + + // act + + // assert + + await Assert.ThrowsAsync(async () => + await messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .Aggregate() + ); + } + + [Fact] + public async Task CreateStreamingAggregation_WorksNoContent_RawContentBlockStartEvent() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new BetaRawMessageStartEvent(GenerateStartMessage)); + yield return new( + new BetaRawContentBlockStartEvent() + { + Index = 0, + ContentBlock = new( + new BetaTextBlock() { Citations = [], Text = "Test Output" } + ), + } + ); + yield return new(new BetaRawContentBlockStopEvent() { Index = 0 }); + yield return new(new BetaRawMessageStopEvent()); + await Task.CompletedTask; + } + + messagesServiceMock + .Setup(e => + e.CreateStreaming(It.IsAny(), It.IsAny()) + ) + .Returns(GetTestValues); + + // act + + var stream = await messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .Aggregate(); + + // assert + + Assert.NotNull(stream); + stream.Validate(); + Assert.NotEmpty(stream.Content); + Assert.Single(stream.Content); + Assert.IsType(stream.Content[0].Value); + Assert.Equal("Test Output", ((BetaTextBlock)stream.Content[0].Value!).Text); + } + + [Fact] + public async Task CreateStreamingAggregation_WorksStopEndEvent() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new BetaRawMessageStartEvent(GenerateStartMessage)); + yield return new( + new BetaRawContentBlockStartEvent() + { + Index = 0, + ContentBlock = new BetaTextBlock() { Citations = [], Text = "this is a " }, + } + ); + yield return new(new BetaRawContentBlockStopEvent() { Index = 0 }); + yield return new( + new BetaRawContentBlockDeltaEvent() + { + Index = 0, + Delta = new(new BetaTextDelta("Test")), + } + ); + yield return new(new BetaRawMessageStopEvent()); + await Task.CompletedTask; + } + messagesServiceMock + .Setup(e => + e.CreateStreaming(It.IsAny(), It.IsAny()) + ) + .Returns(GetTestValues); + + // act + + var stream = await messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .Aggregate(); + + // assert + + Assert.NotNull(stream); + stream.Validate(); + Assert.NotEmpty(stream.Content); + Assert.Single(stream.Content); + Assert.IsType(stream.Content[0].Value); + Assert.Equal("this is a Test", ((BetaTextBlock)stream.Content[0].Value!).Text); + } + + [Fact] + public async Task CreateStreamingAggregationPartialAggregation_Throws() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new BetaRawMessageStartEvent(GenerateStartMessage)); + yield return new( + new BetaRawContentBlockStartEvent() + { + Index = 0, + ContentBlock = new(new BetaTextBlock() { Citations = [], Text = "This is a " }), + } + ); + yield return new( + new BetaRawContentBlockDeltaEvent() + { + Index = 0, + Delta = new(new BetaTextDelta("Test")), + } + ); + yield return new( + new BetaRawContentBlockDeltaEvent() + { + Index = 0, + Delta = new( + new BetaCitationsDelta( + new Citation( + new BetaCitationsWebSearchResultLocation() + { + CitedText = "Somewhere", + EncryptedIndex = "0", + Title = "Over", + Url = "the://rainbow", + } + ) + ) + ), + } + ); + yield return new(new BetaRawContentBlockStopEvent() { Index = 0 }); + yield return new( + new BetaRawContentBlockStartEvent() + { + Index = 1, + ContentBlock = new( + new BetaThinkingBlock() { Signature = "", Thinking = "Other Test" } + ), + } + ); + yield return new(new BetaRawContentBlockStopEvent() { Index = 1 }); + yield return new(new BetaRawMessageStopEvent()); + await Task.CompletedTask; + } + messagesServiceMock + .Setup(e => + e.CreateStreaming(It.IsAny(), It.IsAny()) + ) + .Returns(GetTestValues); + + // act + + var aggregator = new BetaMessageContentAggregator(); + var stream = messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .CollectAsync(aggregator); + await foreach (var _ in stream) + { + // don't iterate entirely + break; + } + + // assert + + var exception = Assert.Throws(() => + aggregator.Message() + ); + Assert.Equal("stop message not yet received", exception.Message); + } + + [Fact] + public async Task CreateStreamingAggregation_Works() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new BetaRawMessageStartEvent(GenerateStartMessage)); + yield return new( + new BetaRawContentBlockStartEvent() + { + Index = 0, + ContentBlock = new(new BetaTextBlock() { Citations = [], Text = "This is a " }), + } + ); + yield return new( + new BetaRawContentBlockDeltaEvent() + { + Index = 0, + Delta = new(new BetaTextDelta("Test")), + } + ); + yield return new( + new BetaRawContentBlockDeltaEvent() + { + Index = 0, + Delta = new( + new BetaCitationsDelta( + new Citation( + new BetaCitationsWebSearchResultLocation() + { + CitedText = "Somewhere", + EncryptedIndex = "0", + Title = "Over", + Url = "the://rainbow", + } + ) + ) + ), + } + ); + yield return new(new BetaRawContentBlockStopEvent() { Index = 0 }); + yield return new( + new BetaRawContentBlockStartEvent() + { + Index = 1, + ContentBlock = new( + new BetaThinkingBlock() { Signature = "", Thinking = "Other Test" } + ), + } + ); + yield return new(new BetaRawContentBlockStopEvent() { Index = 1 }); + yield return new(new BetaRawMessageStopEvent()); + await Task.CompletedTask; + } + messagesServiceMock + .Setup(e => + e.CreateStreaming(It.IsAny(), It.IsAny()) + ) + .Returns(GetTestValues); + + // act + + var stream = await messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .Aggregate(); + + // assert + + Assert.NotNull(stream); + stream.Validate(); + Assert.NotEmpty(stream.Content); + Assert.Equal(2, stream.Content.Count); + Assert.IsType(stream.Content[0].Value); + Assert.IsType(stream.Content[1].Value); + Assert.Equal("This is a Test", ((BetaTextBlock)stream.Content[0].Value!).Text); + Assert.NotNull(((BetaTextBlock)stream.Content[0].Value!).Citations); + Assert.NotEmpty(((BetaTextBlock)stream.Content[0].Value!).Citations!); + Assert.Equal("Other Test", ((BetaThinkingBlock)stream.Content[1].Value!).Thinking); + } } diff --git a/src/Anthropic.Tests/Services/MessageServiceTest.cs b/src/Anthropic.Tests/Services/MessageServiceTest.cs index 1ba047f21..492fe3b03 100644 --- a/src/Anthropic.Tests/Services/MessageServiceTest.cs +++ b/src/Anthropic.Tests/Services/MessageServiceTest.cs @@ -1,11 +1,46 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; using System.Threading.Tasks; using Anthropic.Bedrock; +using Anthropic.Helpers; using Anthropic.Models.Messages; +using Anthropic.Services; +using Anthropic.Tests; +using Moq; namespace Anthropic.Tests.Services; public class MessageServiceTest { + private static Message GenerateStartMessage => + new() + { + ID = "Test", + Content = [], + Model = Model.Claude3OpusLatest, + StopReason = StopReason.ToolUse, + StopSequence = "", + Usage = new() + { + CacheCreation = null, + CacheCreationInputTokens = null, + CacheReadInputTokens = null, + InputTokens = 25, + OutputTokens = 25, + ServerToolUse = null, + ServiceTier = UsageServiceTier.Standard, + }, + }; + + private static Anthropic.Models.Messages.MessageCreateParams StreamingParam => + new() + { + MaxTokens = 1024, + Messages = [new() { Content = new(""), Role = Anthropic.Models.Messages.Role.User }], + Model = Model.Claude3_7SonnetLatest, + }; + [Theory] [AnthropicTestClients] [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] @@ -64,4 +99,325 @@ public async Task CountTokens_Works(IAnthropicClient client, string modelName) ); messageTokensCount.Validate(); } + + [Fact] + public async Task CreateStreamingAggregation_WorksNoContent_RawMessageStartEvent() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new RawMessageStartEvent(GenerateStartMessage)); + yield return new(new RawMessageStopEvent()); + await Task.CompletedTask; + } + messagesServiceMock + .Setup(e => + e.CreateStreaming( + It.IsAny(), + It.IsAny() + ) + ) + .Returns(GetTestValues); + + // act + + var stream = await messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .Aggregate(); + + // assert + + Assert.NotNull(stream); + Assert.Empty(stream.Content); + stream.Validate(); + } + + [Fact] + public async Task CreateStreamingAggregation_HandlesNoEndMessageInterrupt() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new RawMessageStartEvent(GenerateStartMessage)); + await Task.CompletedTask; + } + messagesServiceMock + .Setup(e => + e.CreateStreaming( + It.IsAny(), + It.IsAny() + ) + ) + .Returns(GetTestValues); + + // act + + // assert + + await Assert.ThrowsAsync(async () => + await messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .Aggregate() + ); + } + + [Fact] + public async Task CreateStreamingAggregation_WorksNoContent_RawContentBlockStartEvent() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new RawMessageStartEvent(GenerateStartMessage)); + yield return new( + new RawContentBlockStartEvent() + { + Index = 0, + ContentBlock = new(new TextBlock() { Citations = [], Text = "Test Output" }), + } + ); + yield return new(new RawContentBlockStopEvent() { Index = 0 }); + yield return new(new RawMessageStopEvent()); + await Task.CompletedTask; + } + + messagesServiceMock + .Setup(e => + e.CreateStreaming( + It.IsAny(), + It.IsAny() + ) + ) + .Returns(GetTestValues); + + // act + + var stream = await messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .Aggregate(); + + // assert + + Assert.NotNull(stream); + stream.Validate(); + Assert.NotEmpty(stream.Content); + Assert.Single(stream.Content); + Assert.IsType(stream.Content[0].Value); + Assert.Equal("Test Output", ((TextBlock)stream.Content[0].Value!).Text); + } + + [Fact] + public async Task CreateStreamingAggregation_WorksStopEndEvent() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new RawMessageStartEvent(GenerateStartMessage)); + yield return new( + new RawContentBlockStartEvent() + { + Index = 0, + ContentBlock = new TextBlock() { Citations = [], Text = "this is a " }, + } + ); + yield return new(new RawContentBlockStopEvent() { Index = 0 }); + yield return new( + new RawContentBlockDeltaEvent() { Index = 0, Delta = new(new TextDelta("Test")) } + ); + yield return new(new RawMessageStopEvent()); + await Task.CompletedTask; + } + messagesServiceMock + .Setup(e => + e.CreateStreaming( + It.IsAny(), + It.IsAny() + ) + ) + .Returns(GetTestValues); + + // act + + var stream = await messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .Aggregate(); + + // assert + + Assert.NotNull(stream); + stream.Validate(); + Assert.NotEmpty(stream.Content); + Assert.Single(stream.Content); + Assert.IsType(stream.Content[0].Value); + Assert.Equal("this is a Test", ((TextBlock)stream.Content[0].Value!).Text); + } + + [Fact] + public async Task CreateStreamingAggregationPartialAggregation_Throws() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new RawMessageStartEvent(GenerateStartMessage)); + yield return new( + new RawContentBlockStartEvent() + { + Index = 0, + ContentBlock = new(new TextBlock() { Citations = [], Text = "This is a " }), + } + ); + yield return new( + new RawContentBlockDeltaEvent() { Index = 0, Delta = new(new TextDelta("Test")) } + ); + yield return new( + new RawContentBlockDeltaEvent() + { + Index = 0, + Delta = new( + new CitationsDelta( + new Anthropic.Models.Messages.Citation( + new CitationsWebSearchResultLocation() + { + CitedText = "Somewhere", + EncryptedIndex = "0", + Title = "Over", + Url = "the://rainbow", + } + ) + ) + ), + } + ); + yield return new(new RawContentBlockStopEvent() { Index = 0 }); + yield return new( + new RawContentBlockStartEvent() + { + Index = 1, + ContentBlock = new( + new ThinkingBlock() { Signature = "", Thinking = "Other Test" } + ), + } + ); + yield return new(new RawContentBlockStopEvent() { Index = 1 }); + yield return new(new RawMessageStopEvent()); + await Task.CompletedTask; + } + messagesServiceMock + .Setup(e => + e.CreateStreaming( + It.IsAny(), + It.IsAny() + ) + ) + .Returns(GetTestValues); + + // act + + var aggregator = new MessageContentAggregator(); + var stream = messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .CollectAsync(aggregator); + await foreach (var _ in stream) + { + // don't iterate entirely + break; + } + + // assert + + var exception = Assert.Throws(() => + aggregator.Message() + ); + Assert.Equal("stop message not yet received", exception.Message); + } + + [Fact] + public async Task CreateStreamingAggregation_Works() + { + // arrange + + var messagesServiceMock = new Mock(); + static async IAsyncEnumerable GetTestValues() + { + yield return new(new RawMessageStartEvent(GenerateStartMessage)); + yield return new( + new RawContentBlockStartEvent() + { + Index = 0, + ContentBlock = new(new TextBlock() { Citations = [], Text = "This is a " }), + } + ); + yield return new( + new RawContentBlockDeltaEvent() { Index = 0, Delta = new(new TextDelta("Test")) } + ); + yield return new( + new RawContentBlockDeltaEvent() + { + Index = 0, + Delta = new( + new CitationsDelta( + new Anthropic.Models.Messages.Citation( + new CitationsWebSearchResultLocation() + { + CitedText = "Somewhere", + EncryptedIndex = "0", + Title = "Over", + Url = "the://rainbow", + } + ) + ) + ), + } + ); + yield return new(new RawContentBlockStopEvent() { Index = 0 }); + yield return new( + new RawContentBlockStartEvent() + { + Index = 1, + ContentBlock = new( + new ThinkingBlock() { Signature = "", Thinking = "Other Test" } + ), + } + ); + yield return new(new RawContentBlockStopEvent() { Index = 1 }); + yield return new(new RawMessageStopEvent()); + await Task.CompletedTask; + } + messagesServiceMock + .Setup(e => + e.CreateStreaming( + It.IsAny(), + It.IsAny() + ) + ) + .Returns(GetTestValues); + + // act + + var stream = await messagesServiceMock + .Object.CreateStreaming(StreamingParam, TestContext.Current.CancellationToken) + .Aggregate(); + + // assert + + Assert.NotNull(stream); + stream.Validate(); + Assert.NotEmpty(stream.Content); + Assert.Equal(2, stream.Content.Count); + Assert.IsType(stream.Content[0].Value); + Assert.IsType(stream.Content[1].Value); + Assert.Equal("This is a Test", ((TextBlock)stream.Content[0].Value!).Text); + Assert.NotNull(((TextBlock)stream.Content[0].Value!).Citations); + Assert.NotEmpty(((TextBlock)stream.Content[0].Value!).Citations!); + Assert.Equal("Other Test", ((ThinkingBlock)stream.Content[1].Value!).Thinking); + } } diff --git a/src/Anthropic/Core/ClientOptions.cs b/src/Anthropic/Core/ClientOptions.cs index a409b297f..c8785733d 100644 --- a/src/Anthropic/Core/ClientOptions.cs +++ b/src/Anthropic/Core/ClientOptions.cs @@ -97,4 +97,64 @@ public string? AuthToken readonly get { return _authToken.Value; } set { _authToken = new(() => value); } } + + internal static TimeSpan TimeoutFromMaxTokens( + long maxTokens, + bool isStreaming, + string? model = null + ) + { + // Check model-specific token limits for non-streaming requests + long? maxNonStreamingTokens = null; + + if (model != null) + { + maxNonStreamingTokens = model switch + { + "claude-opus-4-20250514" => 8_192, + "claude-4-opus-20250514" => 8_192, + "claude-opus-4-0" => 8_192, + "anthropic.claude-opus-4-20250514-v1:0" => 8_192, + "claude-opus-4@20250514" => 8_192, + "claude-opus-4-1-20250805" => 8_192, + "anthropic.claude-opus-4-1-20250805-v1:0" => 8_192, + "claude-opus-4-1@20250805" => 8_192, + _ => null, + }; + } + var exceedsModelLimit = maxNonStreamingTokens != null && maxTokens > maxNonStreamingTokens; + + long timeoutSeconds; + if (isStreaming) + { + timeoutSeconds = Math.Min( + 60 * 60, // 1 hour maximum + Math.Max( + 10 * 60, // 10 minute minimum + 60 * 60 * maxTokens / 128_000 + ) + ); + } + else + { + timeoutSeconds = Math.Min( + 10 * 60, // 10 minute maximum + Math.Max( + 30, // 30 second minimum + 30 * maxTokens / 1000 + ) + ); + } + + if (!isStreaming && (exceedsModelLimit || timeoutSeconds > 10 * 60)) // 10 minutes + { + throw new ArgumentOutOfRangeException( + nameof(maxTokens), + "Streaming is required for operations that may take longer than 10 minutes. " + + "For more information, see https://github.com/anthropics/anthropic-sdk-csharp#streaming" + ); + } + + return TimeSpan.FromSeconds(timeoutSeconds); + } } diff --git a/src/Anthropic/Helpers/BetaMessageContentAggregator.cs b/src/Anthropic/Helpers/BetaMessageContentAggregator.cs new file mode 100644 index 000000000..205955c8e --- /dev/null +++ b/src/Anthropic/Helpers/BetaMessageContentAggregator.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Anthropic.Exceptions; +using Anthropic.Models.Beta.Messages; + +namespace Anthropic.Helpers; + +/// +/// The aggregation model for a stream of +/// +public sealed class BetaMessageContentAggregator + : SseAggregator +{ + protected override BetaMessage GetResult( + IReadOnlyDictionary> messages + ) + { + var content = messages[FilterResult.Content].GroupBy(e => e.Index); + + var startMessage = + messages[FilterResult.StartMessage] + .Select(e => e.Value) + .OfType() + .FirstOrDefault() + ?? throw new AnthropicInvalidDataException("start message not yet received"); + var endMessage = + messages[FilterResult.EndMessage] + .Select(e => e.Value) + .OfType() + .FirstOrDefault() + ?? throw new AnthropicInvalidDataException("stop message not yet received"); + + var contentBlocks = new List(); + foreach (var item in content) + { + var startContent = + item.Select(e => e.Value).OfType().FirstOrDefault() + ?? throw new AnthropicInvalidDataException( + "start content message not yet received" + ); + var blockContent = item.Select(e => e.Value) + .OfType() + .ToArray(); + + var contentBlock = startContent.ContentBlock; + contentBlocks.Add(MergeBlock(contentBlock, blockContent.Select(e => e.Delta))); + } + + var stopSequence = startMessage.Message.StopSequence; + var stopReason = startMessage.Message.StopReason; + var container = startMessage.Message.Container; + var usage = startMessage.Message.Usage; + + if (messages.TryGetValue(FilterResult.Delta, out var deltaEvents)) + { + var deltas = deltaEvents.Select(e => e.Value).OfType(); + + foreach (var delta in deltas ?? []) + { + stopReason = delta.Delta.StopReason; + stopSequence = delta.Delta.StopSequence; + + if (delta.Delta.Container != null) + { + container = delta.Delta.Container; + } + + usage = usage with { OutputTokens = delta.Usage.OutputTokens }; + if (delta.Usage.InputTokens != null) + { + usage = usage with { InputTokens = delta.Usage.InputTokens.Value }; + } + if (delta.Usage.CacheCreationInputTokens != null) + { + usage = usage with + { + CacheCreationInputTokens = delta.Usage.CacheCreationInputTokens, + }; + } + if (delta.Usage.CacheReadInputTokens != null) + { + usage = usage with { CacheReadInputTokens = delta.Usage.CacheReadInputTokens }; + } + if (delta.Usage.ServerToolUse != null) + { + usage = usage with { ServerToolUse = delta.Usage.ServerToolUse }; + } + } + } + + return new() + { + Content = [.. contentBlocks], + Container = container, + ContextManagement = startMessage.Message.ContextManagement, + ID = startMessage.Message.ID, + Model = startMessage.Message.Model, + StopReason = stopReason, + StopSequence = stopSequence, + Usage = usage, + }; + } + + private static BetaContentBlock MergeBlock( + ContentBlock contentBlock, + IEnumerable blockContents + ) + { + BetaContentBlock? resultBlock = null; + + string StringJoinHelper( + string source, + IEnumerable sources, + Func expression + ) + { + return string.Join(null, (string[])[source, .. sources.Select(expression)]); + } + + void As(Func, BetaContentBlock> factory) + { + // those blocks are delta variants not the source block + // e.g TextBlock and TextDelta + resultBlock = factory([.. blockContents.Select(e => e.Value).OfType()]); + } + + IEnumerable Of() + { + return blockContents.Select(e => e.Value).OfType(); + } + + void Single(T item) + { + resultBlock = ( + blockContents.Select(e => e.Value).OfType().Single() as BetaContentBlock + ); + } + + contentBlock.Switch( + textBlock => + As(blocks => new BetaTextBlock() + { + Text = StringJoinHelper(textBlock.Text, blocks, e => e.Text), + Citations = + [ + .. (textBlock.Citations ?? []), + .. Of() + .Select(e => + e.Citation.Match( + f => f, + f => f, + f => f, + f => f, + f => f + ) + ), + ], + }), + thinkingBlock => + As(blocks => new BetaThinkingBlock() + { + Signature = StringJoinHelper( + thinkingBlock.Signature, + Of(), + e => e.Signature + ), + Thinking = StringJoinHelper(thinkingBlock.Thinking, blocks, e => e.Thinking), + }), + e => Single(e), + e => Single(e), + e => Single(e), + e => Single(e), + e => Single(e), + e => Single(e), + e => Single(e), + e => Single(e), + e => Single(e), + e => Single(e), + e => Single(e), + e => Single(e) + ); + + return resultBlock ?? throw new AnthropicInvalidDataException("Missing result block"); + } + + protected override FilterResult Filter(BetaRawMessageStreamEvent message) => + message.Value switch + { + BetaRawContentBlockStartEvent _ => FilterResult.Content, + BetaRawContentBlockStopEvent _ => FilterResult.Content, + BetaRawContentBlockDeltaEvent _ => FilterResult.Content, + BetaRawMessageDeltaEvent => FilterResult.Delta, + BetaRawMessageStartEvent => FilterResult.StartMessage, + BetaRawMessageStopEvent _ => FilterResult.EndMessage, + _ => FilterResult.Ignore, + }; +} diff --git a/src/Anthropic/Helpers/MessageContentAggregator.cs b/src/Anthropic/Helpers/MessageContentAggregator.cs new file mode 100644 index 000000000..173a62d3f --- /dev/null +++ b/src/Anthropic/Helpers/MessageContentAggregator.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Anthropic.Exceptions; +using Anthropic.Models.Messages; +using Anthropic.Services; + +namespace Anthropic.Helpers; + +/// +/// An implementation of the for aggregating BlockDeltaEvents from the method. +/// +public sealed class MessageContentAggregator : SseAggregator +{ + protected override Message GetResult( + IReadOnlyDictionary> messages + ) + { + var content = messages[FilterResult.Content].GroupBy(e => e.Index); + + var startMessage = + messages[FilterResult.StartMessage] + .Select(e => e.Value) + .OfType() + .FirstOrDefault() + ?? throw new AnthropicInvalidDataException("start message not yet received"); + + var endMessageCount = messages[FilterResult.EndMessage].Count; + if (endMessageCount == 0) + { + throw new AnthropicInvalidDataException("stop message not yet received"); + } + + var contentBlocks = new List(); + foreach (var item in content) + { + var startContent = + item.Select(e => e.Value).OfType().FirstOrDefault() + ?? throw new AnthropicInvalidDataException( + "start content message not yet received" + ); + var blockContent = item.Select(e => e.Value) + .OfType() + .ToArray(); + + var contentBlock = startContent.ContentBlock; + contentBlocks.Add(MergeBlock(contentBlock, [.. blockContent.Select(e => e.Delta)])); + } + + var stopSequence = startMessage.Message.StopSequence; + var stopReason = startMessage.Message.StopReason; + var usage = startMessage.Message.Usage; + + if (messages.TryGetValue(FilterResult.Delta, out var deltaEvents)) + { + var deltas = deltaEvents.Select(e => e.Value).OfType(); + foreach (var delta in deltas) + { + stopReason = delta.Delta.StopReason; + stopSequence = delta.Delta.StopSequence; + + usage = usage with { OutputTokens = delta.Usage.OutputTokens }; + if (delta.Usage.InputTokens != null) + { + usage = usage with { InputTokens = delta.Usage.InputTokens.Value }; + } + if (delta.Usage.CacheCreationInputTokens != null) + { + usage = usage with + { + CacheCreationInputTokens = delta.Usage.CacheCreationInputTokens, + }; + } + if (delta.Usage.CacheReadInputTokens != null) + { + usage = usage with { CacheReadInputTokens = delta.Usage.CacheReadInputTokens }; + } + if (delta.Usage.ServerToolUse != null) + { + usage = usage with { ServerToolUse = delta.Usage.ServerToolUse }; + } + } + } + + return new() + { + Content = [.. contentBlocks], + ID = startMessage.Message.ID, + Model = startMessage.Message.Model, + StopReason = stopReason, + StopSequence = stopSequence, + Usage = usage, + }; + } + + private static ContentBlock MergeBlock( + RawContentBlockStartEventContentBlock contentBlock, + IEnumerable blockContents + ) + { + ContentBlock? resultBlock = null; + + string StringJoinHelper( + string source, + IEnumerable sources, + Func expression + ) + { + return string.Join(null, (string[])[source, .. sources.Select(expression)]); + } + + void As(Func, ContentBlock> factory) + { + // those blocks are delta variants not the source block + // e.g TextBlock and TextDelta + resultBlock = factory([.. blockContents.Select(e => e.Value).OfType()]); + } + + IEnumerable Of() + { + return blockContents.Select(e => e.Value).OfType(); + } + + void Single(T item) + { + resultBlock = + (blockContents.Select(e => e.Value).OfType().Single() as ContentBlock) + ?? throw new AnthropicInvalidDataException( + "Could not convert block to content block" + ); + } + + contentBlock.Switch( + textBlock => + As(blocks => new TextBlock() + { + Text = StringJoinHelper(textBlock.Text, blocks, e => e.Text), + Citations = + [ + .. (textBlock.Citations ?? []), + .. Of() + .Select(e => + e.Citation.Match( + f => f, + f => f, + f => f, + f => f, + f => f + ) + ), + ], + }), + thinkingBlock => + As(blocks => new ThinkingBlock() + { + Signature = StringJoinHelper( + thinkingBlock.Signature, + Of(), + e => e.Signature + ), + Thinking = StringJoinHelper(thinkingBlock.Thinking, blocks, e => e.Thinking), + }), + e => Single(e), + e => Single(e), + e => Single(e), + e => Single(e) + ); + + return resultBlock ?? throw new AnthropicInvalidDataException("Missing result block"); + } + + protected override FilterResult Filter(RawMessageStreamEvent message) => + message.Value switch + { + RawContentBlockStartEvent _ => FilterResult.Content, + RawContentBlockStopEvent _ => FilterResult.Content, + RawContentBlockDeltaEvent _ => FilterResult.Content, + RawMessageDeltaEvent => FilterResult.Delta, + RawMessageStartEvent => FilterResult.StartMessage, + RawMessageStopEvent _ => FilterResult.EndMessage, + _ => FilterResult.Ignore, + }; +} diff --git a/src/Anthropic/Helpers/SseAggregator.cs b/src/Anthropic/Helpers/SseAggregator.cs new file mode 100644 index 000000000..b972f7d3b --- /dev/null +++ b/src/Anthropic/Helpers/SseAggregator.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using Anthropic.Exceptions; + +namespace Anthropic.Helpers; + +/// +/// Defines the base for all Aggregators using ServerSideStreaming events. +/// +/// The raw message base element type. +/// The element type that defines an aggregated +public abstract class SseAggregator +{ + private Dictionary>? _messages; + private bool _streamEnded; + private TResult? _message; + + /// + /// Collects and filters the provided for aggregation with the method. + /// + /// An containing the messages to aggregate. + /// An of all content messages used to build the aggregation result. + /// Will be thrown if the aggregator is in an invalid state. + /// Will be thrown if the aggregator encounters an invalid state of the source message stream. + public virtual async IAsyncEnumerable CollectAsync( + IAsyncEnumerable messageStream + ) + { + if (_messages is not null) + { + throw new InvalidOperationException( + "Cannot collect multiple streams into same aggregator." + ); + } + + _messages = []; + + foreach (FilterResult item in Enum.GetValues(typeof(FilterResult))) + { + _messages[item] = []; + } + + var startMessageReceived = false; + FilterResult filterResult = FilterResult.Ignore; + await foreach (var message in messageStream) + { + Console.WriteLine(message); + if (!_streamEnded) + { + if (!startMessageReceived && Filter(message) != FilterResult.StartMessage) + { + _messages[FilterResult.StartMessage].Add(message); + continue; + } + + startMessageReceived = true; + filterResult = Filter(message); + _messages[filterResult].Add(message); + if (filterResult == FilterResult.EndMessage) + { + break; + } + } + + yield return message; + } + + if (filterResult != FilterResult.EndMessage) + { + throw new AnthropicInvalidDataException( + $"Expected last message to be the End message but found: {filterResult}" + ); + } + + _streamEnded = true; + } + + /// + /// Aggregates all items based on the Anthropic streaming protocol present in the provided on initialization. + /// + /// The result of the aggregation. + public virtual TResult Message() + { + if (_messages == null) + { + throw new AnthropicInvalidDataException("Stream was not passed to aggregator"); + } + + return _message ??= GetResult( + new ReadOnlyDictionary>(_messages) + ); + } + + /// + /// Applies a filter to each individual message. + /// + /// The message to filter. + /// [True] if the message should be included in the aggregation result, otherwise [False] + protected abstract FilterResult Filter(TMessage message); + + /// + /// Gets an aggregation result of the collected list of messages. + /// + /// The read only list of messages. + /// The aggregation result. + protected abstract TResult GetResult( + IReadOnlyDictionary> messages + ); + + protected enum FilterResult + { + Ignore = 0, + StartMessage = 1, + Delta = 2, + Content = 3, + EndMessage = 4, + } +} diff --git a/src/Anthropic/Services/Beta/MessageService.cs b/src/Anthropic/Services/Beta/MessageService.cs index 47a99b953..b804354a8 100644 --- a/src/Anthropic/Services/Beta/MessageService.cs +++ b/src/Anthropic/Services/Beta/MessageService.cs @@ -124,7 +124,13 @@ public async Task> Create( ._client.WithOptions(options => options with { - Timeout = options.Timeout ?? TimeSpan.FromMinutes(10), + Timeout = + options.Timeout + ?? ClientOptions.TimeoutFromMaxTokens( + parameters.MaxTokens, + isStreaming: false, + parameters.Model + ), } ) .Execute(request, cancellationToken) @@ -172,7 +178,13 @@ public async Task> CreateStream ._client.WithOptions(options => options with { - Timeout = options.Timeout ?? TimeSpan.FromMinutes(10), + Timeout = + options.Timeout + ?? ClientOptions.TimeoutFromMaxTokens( + parameters.MaxTokens, + isStreaming: true, + parameters.Model + ), } ) .Execute(request, cancellationToken) diff --git a/src/Anthropic/Services/MessageService.cs b/src/Anthropic/Services/MessageService.cs index f90f19e6c..425385afe 100644 --- a/src/Anthropic/Services/MessageService.cs +++ b/src/Anthropic/Services/MessageService.cs @@ -124,7 +124,13 @@ public async Task> Create( ._client.WithOptions(options => options with { - Timeout = options.Timeout ?? TimeSpan.FromMinutes(10), + Timeout = + options.Timeout + ?? ClientOptions.TimeoutFromMaxTokens( + parameters.MaxTokens, + isStreaming: false, + parameters.Model + ), } ) .Execute(request, cancellationToken) @@ -170,7 +176,13 @@ public async Task> CreateStreaming( ._client.WithOptions(options => options with { - Timeout = options.Timeout ?? TimeSpan.FromMinutes(10), + Timeout = + options.Timeout + ?? ClientOptions.TimeoutFromMaxTokens( + parameters.MaxTokens, + isStreaming: true, + parameters.Model + ), } ) .Execute(request, cancellationToken) diff --git a/src/Anthropic/SseAggregatorExtensions.cs b/src/Anthropic/SseAggregatorExtensions.cs new file mode 100644 index 000000000..82a35701e --- /dev/null +++ b/src/Anthropic/SseAggregatorExtensions.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Anthropic.Helpers; +using Anthropic.Models.Beta.Messages; +using Anthropic.Models.Messages; + +namespace Anthropic; + +/// +/// Extension methods for providing easy access to Aggregators +/// +public static class SseAggregatorExtensions +{ + /// + /// Aggregates all messages received by the streaming event and aggregates them into a single object once the sender indicates a fully delivered stream. + /// + /// A enumerable as provided by the + /// A task that completes once all messages have been received or in the event of improper streaming and exception. + public static async Task Aggregate(this IAsyncEnumerable source) + { + return await new MessageContentAggregator().Aggregate(source).ConfigureAwait(false); + } + + /// + /// Aggregates all messages received by the streaming event and aggregates them into a single object once the sender indicates a fully delivered stream. + /// + /// A enumerable as provided by the + /// A task that completes once all messages have been received or in the event of improper streaming and exception. + public static async Task Aggregate( + this IAsyncEnumerable source + ) + { + return await new BetaMessageContentAggregator().Aggregate(source).ConfigureAwait(false); + } + + /// + /// Aggregates all messages received by the streaming event and aggregates them into a single object once the sender indicates a fully delivered stream. + /// + /// The type of message as provided by the Api. + /// The Result object that the aggregator should build. + /// The aggregator instance that will collect messages and build the result object. + /// The source stream of messages. + /// A task that completes after all messages from the source have been consumed. + public static async Task Aggregate( + this SseAggregator aggregator, + IAsyncEnumerable source + ) + { + await foreach (var _ in aggregator.CollectAsync(source)) { } + return aggregator.Message(); + } + + /// + /// Aggregates all messages received by the streaming event and collects them in the provided aggregator. + /// + /// The type of message as provided by the Api. + /// The Result object that the aggregator should build. + /// The source stream of messages. + /// The aggregator instance that will collect messages and build the result object. + /// An filtered by the aggregator. + public static IAsyncEnumerable CollectAsync( + this IAsyncEnumerable source, + SseAggregator aggregator + ) + { + return aggregator.CollectAsync(source); + } +} From 46db22fc1bcd049f84ce62137f6e57d23eb19a4d Mon Sep 17 00:00:00 2001 From: Stephen Date: Thu, 5 Feb 2026 13:10:42 -0800 Subject: [PATCH 37/41] fix build (#113) --- .../Services/Beta/MessageServiceTest.cs | 16 ++++++++++++++++ .../Services/MessageServiceTest.cs | 1 + .../Helpers/BetaMessageContentAggregator.cs | 1 + 3 files changed, 18 insertions(+) diff --git a/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs b/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs index 626940959..a56b9b209 100644 --- a/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs +++ b/src/Anthropic.Tests/Services/Beta/MessageServiceTest.cs @@ -28,6 +28,22 @@ public class MessageServiceTest OutputTokens = 25, ServerToolUse = null, ServiceTier = BetaUsageServiceTier.Standard, + InferenceGeo = "inference_geo", + Iterations = + [ + new BetaMessageIterationUsage() + { + CacheCreation = new() + { + Ephemeral1hInputTokens = 0, + Ephemeral5mInputTokens = 0, + }, + CacheCreationInputTokens = 0, + CacheReadInputTokens = 0, + InputTokens = 0, + OutputTokens = 0, + }, + ], }, Container = null, ContextManagement = null, diff --git a/src/Anthropic.Tests/Services/MessageServiceTest.cs b/src/Anthropic.Tests/Services/MessageServiceTest.cs index 492fe3b03..64701316b 100644 --- a/src/Anthropic.Tests/Services/MessageServiceTest.cs +++ b/src/Anthropic.Tests/Services/MessageServiceTest.cs @@ -30,6 +30,7 @@ public class MessageServiceTest OutputTokens = 25, ServerToolUse = null, ServiceTier = UsageServiceTier.Standard, + InferenceGeo = "inference_geo", }, }; diff --git a/src/Anthropic/Helpers/BetaMessageContentAggregator.cs b/src/Anthropic/Helpers/BetaMessageContentAggregator.cs index 205955c8e..795ba2bef 100644 --- a/src/Anthropic/Helpers/BetaMessageContentAggregator.cs +++ b/src/Anthropic/Helpers/BetaMessageContentAggregator.cs @@ -178,6 +178,7 @@ .. Of() e => Single(e), e => Single(e), e => Single(e), + e => Single(e), e => Single(e) ); From ec8b153d9c59728bdc247909ba73c1196f9c351b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 22:11:19 +0000 Subject: [PATCH 38/41] fix(client): handle edge case with renamed variable --- .../Messages/BetaInputTokensTriggerTest.cs | 18 +++++++++--------- .../Messages/BetaClearToolUses20250919Edit.cs | 4 ++-- .../Beta/Messages/BetaInputTokensTrigger.cs | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensTriggerTest.cs b/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensTriggerTest.cs index aafcbe4e5..e98997037 100644 --- a/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensTriggerTest.cs +++ b/src/Anthropic.Tests/Models/Beta/Messages/BetaInputTokensTriggerTest.cs @@ -9,19 +9,19 @@ public class BetaInputTokensTriggerTest : TestBase [Fact] public void FieldRoundtrip_Works() { - var model = new BetaInputTokensTrigger { Value = 1 }; + var model = new BetaInputTokensTrigger { ValueValue = 1 }; JsonElement expectedType = JsonSerializer.SerializeToElement("input_tokens"); - long expectedValue = 1; + long expectedValueValue = 1; Assert.True(JsonElement.DeepEquals(expectedType, model.Type)); - Assert.Equal(expectedValue, model.Value); + Assert.Equal(expectedValueValue, model.ValueValue); } [Fact] public void SerializationRoundtrip_Works() { - var model = new BetaInputTokensTrigger { Value = 1 }; + var model = new BetaInputTokensTrigger { ValueValue = 1 }; string json = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -35,7 +35,7 @@ public void SerializationRoundtrip_Works() [Fact] public void FieldRoundtripThroughSerialization_Works() { - var model = new BetaInputTokensTrigger { Value = 1 }; + var model = new BetaInputTokensTrigger { ValueValue = 1 }; string element = JsonSerializer.Serialize(model, ModelBase.SerializerOptions); var deserialized = JsonSerializer.Deserialize( @@ -45,16 +45,16 @@ public void FieldRoundtripThroughSerialization_Works() Assert.NotNull(deserialized); JsonElement expectedType = JsonSerializer.SerializeToElement("input_tokens"); - long expectedValue = 1; + long expectedValueValue = 1; Assert.True(JsonElement.DeepEquals(expectedType, deserialized.Type)); - Assert.Equal(expectedValue, deserialized.Value); + Assert.Equal(expectedValueValue, deserialized.ValueValue); } [Fact] public void Validation_Works() { - var model = new BetaInputTokensTrigger { Value = 1 }; + var model = new BetaInputTokensTrigger { ValueValue = 1 }; model.Validate(); } @@ -62,7 +62,7 @@ public void Validation_Works() [Fact] public void CopyConstructor_Works() { - var model = new BetaInputTokensTrigger { Value = 1 }; + var model = new BetaInputTokensTrigger { ValueValue = 1 }; BetaInputTokensTrigger copied = new(model); diff --git a/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs b/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs index cac1b5050..d2ce73ffc 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaClearToolUses20250919Edit.cs @@ -446,9 +446,9 @@ public JsonElement Type get { return Match(betaInputTokens: (x) => x.Type, betaToolUses: (x) => x.Type); } } - public long Value1 + public long ValueValue { - get { return Match(betaInputTokens: (x) => x.Value, betaToolUses: (x) => x.Value); } + get { return Match(betaInputTokens: (x) => x.ValueValue, betaToolUses: (x) => x.Value); } } public Trigger(BetaInputTokensTrigger value, JsonElement? element = null) diff --git a/src/Anthropic/Models/Beta/Messages/BetaInputTokensTrigger.cs b/src/Anthropic/Models/Beta/Messages/BetaInputTokensTrigger.cs index f1f75820a..2c298d3ac 100644 --- a/src/Anthropic/Models/Beta/Messages/BetaInputTokensTrigger.cs +++ b/src/Anthropic/Models/Beta/Messages/BetaInputTokensTrigger.cs @@ -21,7 +21,7 @@ public JsonElement Type init { this._rawData.Set("type", value); } } - public required long Value + public required long ValueValue { get { @@ -38,7 +38,7 @@ public override void Validate() { throw new AnthropicInvalidDataException("Invalid value given for constant"); } - _ = this.Value; + _ = this.ValueValue; } public BetaInputTokensTrigger() @@ -76,10 +76,10 @@ IReadOnlyDictionary rawData } [SetsRequiredMembers] - public BetaInputTokensTrigger(long value) + public BetaInputTokensTrigger(long valueValue) : this() { - this.Value = value; + this.ValueValue = valueValue; } } From 51f66c313a2d412c4b477963cc3bc024940aed79 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Sat, 7 Feb 2026 00:31:15 +0100 Subject: [PATCH 39/41] (feat) Add vertex provider (#108) * Add vertex provider Add vertex example Add explicit body check for vertex Readd explicit check for model value in bedrock client lint reintroduce null forgiving operator as required by build * apply review suggestions * Update examples/MessagesExample.Vertex/Program.cs * Apply suggestion from @sd-st --------- Co-authored-by: Stephen --- Anthropic.sln | 15 ++ examples/Anthropic.Examples.sln | 14 ++ .../MessagesExample.Vertex.csproj | 14 ++ examples/MessagesExample.Vertex/Program.cs | 51 +++++++ .../AnthropicBedrockClient.cs | 6 +- src/Anthropic.Tests/Anthropic.Tests.csproj | 2 +- src/Anthropic.Tests/AnthropicTestClients.cs | 21 +++ .../Services/MessageServiceTest.cs | 1 + src/Anthropic.Vertex/Anthropic.Vertex.csproj | 27 ++++ src/Anthropic.Vertex/AnthropicVertexClient.cs | 51 +++++++ .../AnthropicVertexClientWithRawResponse.cs | 133 ++++++++++++++++++ .../AnthropicVertexCredentials.cs | 52 +++++++ .../IAnthropicVertexCredentials.cs | 75 ++++++++++ 13 files changed, 460 insertions(+), 2 deletions(-) create mode 100644 examples/MessagesExample.Vertex/MessagesExample.Vertex.csproj create mode 100644 examples/MessagesExample.Vertex/Program.cs create mode 100644 src/Anthropic.Vertex/Anthropic.Vertex.csproj create mode 100644 src/Anthropic.Vertex/AnthropicVertexClient.cs create mode 100644 src/Anthropic.Vertex/AnthropicVertexClientWithRawResponse.cs create mode 100644 src/Anthropic.Vertex/AnthropicVertexCredentials.cs create mode 100644 src/Anthropic.Vertex/IAnthropicVertexCredentials.cs diff --git a/Anthropic.sln b/Anthropic.sln index fc3fd450c..ac27bfc73 100644 --- a/Anthropic.sln +++ b/Anthropic.sln @@ -24,6 +24,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution SECURITY.md = SECURITY.md EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Anthropic.Vertex", "src\Anthropic.Vertex\Anthropic.Vertex.csproj", "{A316C280-3880-4674-9B0C-2F6FE77B8B49}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StreamingAggregationBetaExample", "StreamingAggregationBetaExample", "{6D5DEC39-3673-615E-54FA-C74C69400686}" @@ -88,6 +90,18 @@ Global {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|x64.Build.0 = Release|Any CPU {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|x86.ActiveCfg = Release|Any CPU {72FC9906-07F4-4911-8D6B-F9814974BB37}.Release|x86.Build.0 = Release|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Debug|x64.ActiveCfg = Debug|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Debug|x64.Build.0 = Debug|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Debug|x86.ActiveCfg = Debug|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Debug|x86.Build.0 = Debug|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Release|Any CPU.Build.0 = Release|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Release|x64.ActiveCfg = Release|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Release|x64.Build.0 = Release|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Release|x86.ActiveCfg = Release|Any CPU + {A316C280-3880-4674-9B0C-2F6FE77B8B49}.Release|x86.Build.0 = Release|Any CPU {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Debug|Any CPU.Build.0 = Debug|Any CPU {0E525CB1-B565-4ABE-B477-48C53F9BB258}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -109,6 +123,7 @@ Global {0732C8A6-7313-4C33-AE2E-FFAA82EFB481} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {DD0E539D-6D5F-45EB-A807-01BE0A443604} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {72FC9906-07F4-4911-8D6B-F9814974BB37} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} + {A316C280-3880-4674-9B0C-2F6FE77B8B49} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B} {6D5DEC39-3673-615E-54FA-C74C69400686} = {B36A84DF-456D-A817-6EDD-3EC3E7F6E11F} {0E525CB1-B565-4ABE-B477-48C53F9BB258} = {6D5DEC39-3673-615E-54FA-C74C69400686} EndGlobalSection diff --git a/examples/Anthropic.Examples.sln b/examples/Anthropic.Examples.sln index eea860c9b..8be1c01b7 100644 --- a/examples/Anthropic.Examples.sln +++ b/examples/Anthropic.Examples.sln @@ -18,6 +18,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagesExample.Foundry", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagesExample.Bedrock", "MessagesExample.Bedrock\MessagesExample.Bedrock.csproj", "{7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessagesExample.Vertex", "MessagesExample.Vertex\MessagesExample.Vertex.csproj", "{E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -124,6 +126,18 @@ Global {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Release|x64.Build.0 = Release|Any CPU {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Release|x86.ActiveCfg = Release|Any CPU {7AD57F3D-FF5A-472B-ABEF-FC381D5CCC0C}.Release|x86.Build.0 = Release|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Debug|x64.ActiveCfg = Debug|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Debug|x64.Build.0 = Debug|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Debug|x86.ActiveCfg = Debug|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Debug|x86.Build.0 = Debug|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Release|Any CPU.Build.0 = Release|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Release|x64.ActiveCfg = Release|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Release|x64.Build.0 = Release|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Release|x86.ActiveCfg = Release|Any CPU + {E2B0C44D-3B9C-4ACD-BA53-2E27F4111004}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/examples/MessagesExample.Vertex/MessagesExample.Vertex.csproj b/examples/MessagesExample.Vertex/MessagesExample.Vertex.csproj new file mode 100644 index 000000000..7aa8b9465 --- /dev/null +++ b/examples/MessagesExample.Vertex/MessagesExample.Vertex.csproj @@ -0,0 +1,14 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + diff --git a/examples/MessagesExample.Vertex/Program.cs b/examples/MessagesExample.Vertex/Program.cs new file mode 100644 index 000000000..1ddc17dd2 --- /dev/null +++ b/examples/MessagesExample.Vertex/Program.cs @@ -0,0 +1,51 @@ +using Anthropic.Models.Messages; +using Anthropic.Vertex; +using Google.Apis.Auth.OAuth2; + +// The google vertex client needs a Project ID, use the ID from the google cloud dashboard. +// The region parameter is optional. + +// By default the Vertex Credential provider tries to load system wide credentials generated via the "gcloud" tool. +// For application wide credentials we recommend using service accounts instead and providing your own GoogleCredentials. Example: +/* +var client = new AnthropicVertexClient(new AnthropicVertexCredentials(null, "YourProjectId", GoogleCredential.FromJson( +""" +{ + ServiceAccount JSON +} +""").CreateScoped("https://www.googleapis.com/auth/cloud-platform"))); +*/ + +// or you can load the credentials from your system after you set it with the necessary environment variables by calling +// var client = new AnthropicVertexClient(await DefaultAnthropicVertexCredentials.FromEnvAsync()); + +// The main variables you can set are below. There are more options available; consult the method's documentation for more info. +// +// ANTHROPIC_VERTEX_PROJECT_ID=your_project_id +// CLOUD_ML_REGION=region_name +// VERTEX_ACCESS_TOKEN=vertex_access_token +// + +var client = new AnthropicVertexClient(new AnthropicVertexCredentials(null, "YourProjectId")); + +MessageCreateParams parameters = new() +{ + MaxTokens = 2048, + Messages = + [ + new() { Content = "Tell me a story about building the best SDK!", Role = Role.User }, + ], + Model = "claude-3-7-sonnet@20250219", +}; + +var response = await client.Messages.Create(parameters); + +var message = string.Join( + "", + response + .Content.Where(message => message.Value is TextBlock) + .Select(message => message.Value as TextBlock) + .Select((textBlock) => textBlock.Text) +); + +Console.WriteLine(message); diff --git a/src/Anthropic.Bedrock/AnthropicBedrockClient.cs b/src/Anthropic.Bedrock/AnthropicBedrockClient.cs index 2dfbc2009..77b42d515 100644 --- a/src/Anthropic.Bedrock/AnthropicBedrockClient.cs +++ b/src/Anthropic.Bedrock/AnthropicBedrockClient.cs @@ -124,7 +124,11 @@ [.. betaVersions.Select(v => JsonValue.Create(v))] bodyContent["anthropic_version"] = JsonValue.Create(AnthropicVersion); - var modelValue = bodyContent["model"]!; + var modelValue = + bodyContent["model"] + ?? throw new AnthropicInvalidDataException( + "Expected to find property model in request json but found none." + ); bodyContent.Root.AsObject().Remove("model"); var parsedStreamValue = ((bool?)bodyContent["stream"]?.AsValue()) ?? false; bodyContent.Root.AsObject().Remove("stream"); diff --git a/src/Anthropic.Tests/Anthropic.Tests.csproj b/src/Anthropic.Tests/Anthropic.Tests.csproj index 8fb3cca27..73f63fb5d 100644 --- a/src/Anthropic.Tests/Anthropic.Tests.csproj +++ b/src/Anthropic.Tests/Anthropic.Tests.csproj @@ -23,7 +23,7 @@ - + diff --git a/src/Anthropic.Tests/AnthropicTestClients.cs b/src/Anthropic.Tests/AnthropicTestClients.cs index 30c26cc5e..02ba4e80c 100644 --- a/src/Anthropic.Tests/AnthropicTestClients.cs +++ b/src/Anthropic.Tests/AnthropicTestClients.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Anthropic.Bedrock; using Anthropic.Foundry; +using Anthropic.Vertex; using Xunit.Sdk; using Xunit.v3; @@ -91,6 +92,25 @@ .. testData ) ); } + if (TestSupportTypes.HasFlag(TestSupportTypes.Vertex)) + { + rows.Add( + new TheoryDataRow( + [ + new AnthropicVertexClient( + new AnthropicVertexCredentials(Resource, "VertexProject") + ) + { + BaseUrl = DataServiceUrl, + }, + .. testData + .Where(e => e.TestSupport.HasFlag(TestSupportTypes.Vertex)) + .SelectMany(f => f.TestData) + .ToArray(), + ] + ) + ); + } return new ValueTask>(rows); } @@ -116,4 +136,5 @@ public enum TestSupportTypes Anthropic = 1 << 1, Foundry = 1 << 2, Bedrock = 1 << 3, + Vertex = 1 << 4, } diff --git a/src/Anthropic.Tests/Services/MessageServiceTest.cs b/src/Anthropic.Tests/Services/MessageServiceTest.cs index 64701316b..6cf57182c 100644 --- a/src/Anthropic.Tests/Services/MessageServiceTest.cs +++ b/src/Anthropic.Tests/Services/MessageServiceTest.cs @@ -47,6 +47,7 @@ public class MessageServiceTest [AnthropicTestData(TestSupportTypes.Anthropic, "Claude3_7SonnetLatest")] [AnthropicTestData(TestSupportTypes.Foundry, "claude-sonnet-4-5")] [AnthropicTestData(TestSupportTypes.Bedrock, "global.anthropic.claude-haiku-4-5-20251001-v1:0")] + [AnthropicTestData(TestSupportTypes.Vertex, "claude-3-7-sonnet@20250219")] public async Task Create_Works(IAnthropicClient client, string modelName) { var message = await client.Messages.Create( diff --git a/src/Anthropic.Vertex/Anthropic.Vertex.csproj b/src/Anthropic.Vertex/Anthropic.Vertex.csproj new file mode 100644 index 000000000..416858993 --- /dev/null +++ b/src/Anthropic.Vertex/Anthropic.Vertex.csproj @@ -0,0 +1,27 @@ + + + + enable + enable + + Anthropic.Vertex + 0.1.0 + + + + + + + + + + + + + + + + + + + diff --git a/src/Anthropic.Vertex/AnthropicVertexClient.cs b/src/Anthropic.Vertex/AnthropicVertexClient.cs new file mode 100644 index 000000000..603bc285f --- /dev/null +++ b/src/Anthropic.Vertex/AnthropicVertexClient.cs @@ -0,0 +1,51 @@ +using Anthropic.Core; + +namespace Anthropic.Vertex; + +/// +/// Provides methods for invoking the vertex hosted Anthropic api. +/// +public class AnthropicVertexClient : AnthropicClient +{ + private readonly IAnthropicVertexCredentials _vertexCredentials; + + private readonly Lazy _withRawResponse; + + /// + /// Creates a new Instance of the . + /// + /// The credential Provider used to authenticate with the AWS Bedrock service. + public AnthropicVertexClient(IAnthropicVertexCredentials vertexCredentials) + : base() + { + _vertexCredentials = vertexCredentials; + BaseUrl = + $"https://{(_vertexCredentials.Region is "global" or null ? "" : _vertexCredentials.Region + "-")}aiplatform.googleapis.com"; + _withRawResponse = new(() => + new AnthropicVertexClientWithRawResponse(_vertexCredentials, _options) + ); + } + + private AnthropicVertexClient( + IAnthropicVertexCredentials vertexCredentials, + ClientOptions clientOptions + ) + : base(clientOptions) + { + _vertexCredentials = vertexCredentials; + BaseUrl = + $"https://{(_vertexCredentials.Region is "global" or null ? "" : _vertexCredentials.Region + "-")}aiplatform.googleapis.com"; + _withRawResponse = new(() => + new AnthropicVertexClientWithRawResponse(_vertexCredentials, _options) + ); + } + + /// + public override IAnthropicClient WithOptions(Func modifier) + { + return new AnthropicVertexClient(_vertexCredentials, modifier(this._options)); + } + + /// + public override IAnthropicClientWithRawResponse WithRawResponse => _withRawResponse.Value; +} diff --git a/src/Anthropic.Vertex/AnthropicVertexClientWithRawResponse.cs b/src/Anthropic.Vertex/AnthropicVertexClientWithRawResponse.cs new file mode 100644 index 000000000..c681fbf89 --- /dev/null +++ b/src/Anthropic.Vertex/AnthropicVertexClientWithRawResponse.cs @@ -0,0 +1,133 @@ +using System.Text; +using System.Text.Json; +using System.Text.Json.Nodes; +using Anthropic.Core; +using Anthropic.Exceptions; + +namespace Anthropic.Vertex; + +internal class AnthropicVertexClientWithRawResponse : AnthropicClientWithRawResponse +{ + private const string ANTHROPIC_VERSION = "vertex-2023-10-16"; + + private readonly IAnthropicVertexCredentials _vertexCredentials; + + /// + /// Creates a new Instance of the . + /// + /// The credential Provider used to authenticate with the AWS Bedrock service. + public AnthropicVertexClientWithRawResponse( + IAnthropicVertexCredentials vertexCredentials, + ClientOptions options + ) + : base(options) + { + _vertexCredentials = vertexCredentials; + } + + public override IAnthropicClientWithRawResponse WithOptions( + Func modifier + ) + { + return new AnthropicVertexClientWithRawResponse(_vertexCredentials, modifier(_options)); + } + + protected override async ValueTask BeforeSend( + HttpRequest request, + HttpRequestMessage requestMessage, + CancellationToken cancellationToken + ) + { + ValidateRequest(requestMessage, out var isCountEndpoint); + + var bodyContent = JsonNode.Parse( + await requestMessage.Content!.ReadAsStringAsync( +#if NET + cancellationToken +#endif + ).ConfigureAwait(false) + )!; + + bodyContent["anthropic_version"] = JsonValue.Create(ANTHROPIC_VERSION); + + var modelValue = + bodyContent["model"] + ?? throw new AnthropicInvalidDataException( + "Expected to find property model in request json but found none." + ); + + bodyContent.Root.AsObject().Remove("model"); + var parsedStreamValue = ((bool?)bodyContent["stream"]?.AsValue()) ?? false; + + var contentStream = new MemoryStream(); + requestMessage.Content = new StreamContent(contentStream); + using var writer = new Utf8JsonWriter(contentStream); + { + bodyContent.WriteTo(writer); + await writer.FlushAsync(cancellationToken).ConfigureAwait(false); + } + contentStream.Seek(0, SeekOrigin.Begin); + requestMessage.Headers.TryAddWithoutValidation( + "content-length", + contentStream.Length.ToString() + ); + + var requestBuilder = new StringBuilder( + $"{requestMessage.RequestUri!.Scheme}://{requestMessage.RequestUri.Host}/v1/projects/{_vertexCredentials.Project}/locations/{_vertexCredentials.Region}/publishers/anthropic/models/" + ); + if (isCountEndpoint) + { + requestBuilder.Append("count-tokens:rawPredict"); + } + else + { + requestBuilder.Append( + $"{modelValue.AsValue()}:{(parsedStreamValue ? "streamRawPredict" : "rawPredict")}" + ); + } + + requestMessage.RequestUri = new Uri(requestBuilder.ToString()); + + await _vertexCredentials.ApplyAsync(requestMessage).ConfigureAwait(false); + } + + private static void ValidateRequest(HttpRequestMessage requestMessage, out bool isCountEndpoint) + { + if (requestMessage.RequestUri is null) + { + throw new AnthropicInvalidDataException( + "Request is missing required path segments. Expected > 1 segments, found none." + ); + } + + if (requestMessage.RequestUri.Segments.Length < 1) + { + throw new AnthropicInvalidDataException( + "Request is missing required path segments. Expected > 1 segments, found none." + ); + } + + if (requestMessage.RequestUri.Segments[1].Trim('/') != "v1") + { + throw new AnthropicInvalidDataException( + $"Request is missing required path segments. Expected [0] segment to be 'v1', found {requestMessage.RequestUri.Segments[0]}." + ); + } + + if ( + requestMessage.RequestUri.Segments.Length >= 4 + && requestMessage.RequestUri.Segments[2].Trim('/') is "messages" + && requestMessage.RequestUri.Segments[3].Trim('/') is "batches" or "count_tokens" + ) + { + throw new AnthropicInvalidDataException( + $"The requested endpoint '{requestMessage.RequestUri.Segments.Last().Trim('/')}' is not yet supported." + ); + } + + isCountEndpoint = + requestMessage.RequestUri.Segments.Length >= 4 + && requestMessage.RequestUri.Segments[2].Trim('/') is "messages" + && requestMessage.RequestUri.Segments[3].Trim('/') is "count_tokens"; + } +} diff --git a/src/Anthropic.Vertex/AnthropicVertexCredentials.cs b/src/Anthropic.Vertex/AnthropicVertexCredentials.cs new file mode 100644 index 000000000..5664360f8 --- /dev/null +++ b/src/Anthropic.Vertex/AnthropicVertexCredentials.cs @@ -0,0 +1,52 @@ +using Google.Apis.Auth.OAuth2; + +namespace Anthropic.Vertex; + +/// +/// Defines methods to authenticate with vertex services using the api. +/// +public class AnthropicVertexCredentials : IAnthropicVertexCredentials +{ + private readonly GoogleCredential _googleCredentials; + + /// + /// Creates a new instance of the using the environment provided google authentication methods. + /// + /// The region string for the project or null for global. + /// The project string. + public AnthropicVertexCredentials(string? region, string project) + : this(region, project, GoogleCredential.GetApplicationDefault()) { } + + /// + /// Creates a new instance of the . + /// + /// The region string for the project or null for global. + /// The project string. + /// The authentication method. + public AnthropicVertexCredentials( + string? region, + string project, + GoogleCredential googleCredential + ) + { + Region = region ?? "global"; + Project = project; + _googleCredentials = googleCredential; + } + + /// + public string Region { get; } + + /// + public string Project { get; } + + /// + public async ValueTask ApplyAsync(HttpRequestMessage requestMessage) + { + var token = await _googleCredentials + .UnderlyingCredential.GetAccessTokenForRequestAsync() + .ConfigureAwait(false); + requestMessage.Headers.Authorization = + new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + } +} diff --git a/src/Anthropic.Vertex/IAnthropicVertexCredentials.cs b/src/Anthropic.Vertex/IAnthropicVertexCredentials.cs new file mode 100644 index 000000000..f2123ebcc --- /dev/null +++ b/src/Anthropic.Vertex/IAnthropicVertexCredentials.cs @@ -0,0 +1,75 @@ +using Google.Apis.Auth.OAuth2; + +namespace Anthropic.Vertex; + +/// +/// Defines methods for authenticating requests to the vertex api. +/// +public interface IAnthropicVertexCredentials +{ + /// + /// Gets the Region on the Project. + /// + string Region { get; } + + /// + /// Gets the Project name. + /// + string Project { get; } + + /// + /// Applies the authentication method to the request. + /// + /// The http Request message object. + /// A value task that is resolved when the authentication has been applied to the request message. + ValueTask ApplyAsync(HttpRequestMessage requestMessage); + +#if NET8_0_OR_GREATER + public static async Task FromEnvAsync() + { + return await DefaultAnthropicVertexCredentials.FromEnvAsync().ConfigureAwait(false); + } +#endif +} + +public static class DefaultAnthropicVertexCredentials +{ + /// + /// Creates a new instance of from environment variables. + /// + /// + /// Set the following environment variables: + /// + /// ANTHROPIC_VERTEX_PROJECT_ID=your_project_id + /// CLOUD_ML_REGION=region_name + /// VERTEX_ACCESS_TOKEN=vertex_access_token + /// + /// The CLOUD_ML_REGION environment variable is optional and if not set will fallback to global. + /// The VERTEX_ACCESS_TOKEN environment variable is optional and if unset the google system checks will be performed to obtain a valid set of credentials. See: https://docs.cloud.google.com/docs/authentication/application-default-credentials + /// + /// A new instance of an or null if it cannot be loaded from environment variables + public static async ValueTask FromEnvAsync() + { + var projId = Environment.GetEnvironmentVariable("ANTHROPIC_VERTEX_PROJECT_ID"); + var region = Environment.GetEnvironmentVariable("CLOUD_ML_REGION"); + var accessToken = Environment.GetEnvironmentVariable("VERTEX_ACCESS_TOKEN"); + + if (projId is null) + { + return null; + } + + region ??= "global"; + + var credentials = accessToken is null + ? GoogleCredential.FromAccessToken(accessToken) + : await GoogleCredential.GetApplicationDefaultAsync().ConfigureAwait(false); + + if (credentials.UnderlyingCredential is null) + { + return null; + } + + return new AnthropicVertexCredentials(region, projId, credentials); + } +} From 63f412a8ec932d544ee2d1bf36d3f2919d7af07e Mon Sep 17 00:00:00 2001 From: Stephen Date: Fri, 6 Feb 2026 15:45:37 -0800 Subject: [PATCH 40/41] chore(examples): fix warnings (#116) --- examples/MessagesExample.Bedrock/Program.cs | 4 ++-- examples/MessagesExample.Vertex/Program.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/MessagesExample.Bedrock/Program.cs b/examples/MessagesExample.Bedrock/Program.cs index 2908304bd..527c0b201 100644 --- a/examples/MessagesExample.Bedrock/Program.cs +++ b/examples/MessagesExample.Bedrock/Program.cs @@ -32,8 +32,8 @@ await AnthropicBedrockCredentialsHelper.FromEnv().ConfigureAwait(false) var message = string.Join( "", response - .Content.Where(message => message.Value is TextBlock) - .Select(message => message.Value as TextBlock) + .Content.Select(message => message.Value) + .OfType() .Select((textBlock) => textBlock.Text) ); diff --git a/examples/MessagesExample.Vertex/Program.cs b/examples/MessagesExample.Vertex/Program.cs index 1ddc17dd2..fc7435bf6 100644 --- a/examples/MessagesExample.Vertex/Program.cs +++ b/examples/MessagesExample.Vertex/Program.cs @@ -43,8 +43,8 @@ ServiceAccount JSON var message = string.Join( "", response - .Content.Where(message => message.Value is TextBlock) - .Select(message => message.Value as TextBlock) + .Content.Select(message => message.Value) + .OfType() .Select((textBlock) => textBlock.Text) ); From 7cd5a46ab2b5037a94446a385a666ab64f908d60 Mon Sep 17 00:00:00 2001 From: Peder Date: Sat, 7 Feb 2026 13:13:33 +0100 Subject: [PATCH 41/41] Normalize nullable union tool types Add handling for nullable union types (e.g., "type": ["integer", "null"]) generated by the C# MCP SDK for optional nullable parameters. Transforms them to simple types for non-required properties since structured outputs doesn't support union types. Changes: - Add nullable union type normalization in schema transform - Add TransformNullableUnionType helper for tool property processing - Reorder required/properties parsing to support transformation - Add tests for nullable union type transformation --- .../AnthropicClientBetaExtensionsTests.cs | 168 ++++++++++++++++ .../Messages/AnthropicBetaClientExtensions.cs | 183 ++++++++++++++++-- 2 files changed, 337 insertions(+), 14 deletions(-) diff --git a/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs b/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs index 836718105..df71cabcf 100644 --- a/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs +++ b/src/Anthropic.Tests/AnthropicClientBetaExtensionsTests.cs @@ -2493,4 +2493,172 @@ public async Task GetResponseAsync_MeaiUserAgentHeader_PresentAlongsideDefaultHe "Default AnthropicClient user-agent header should be present" ); } + + [Fact] + public async Task GetResponseAsync_WithNullableUnionType_TransformsToSimpleType() + { + // The C# MCP SDK generates schemas with "type": ["integer", "null"], "default": null + // for optional nullable parameters. This test verifies the transformation removes + // the null from the union type and the default: null for non-required properties. + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "Call tool with optional param" + }] + }], + "tools": [{ + "name": "tool_with_optional", + "description": "A tool with an optional nullable parameter", + "input_schema": { + "type": "object", + "properties": { + "required_param": { + "type": "string" + }, + "optional_number": { + "type": "integer" + } + }, + "required": ["required_param"] + } + }] + } + """, + actualResponse: """ + { + "id": "msg_nullable_01", + "type": "message", + "role": "assistant", + "model": "claude-haiku-4-5", + "content": [{ + "type": "text", + "text": "Tool ready" + }], + "stop_reason": "end_turn", + "usage": { + "input_tokens": 30, + "output_tokens": 5 + } + } + """ + ); + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + // Create a function with an optional nullable parameter - the schema will have + // "type": ["integer", "null"], "default": null which should be transformed + var functionWithOptional = AIFunctionFactory.Create( + (string required_param, int? optional_number = null) => "result", + new AIFunctionFactoryOptions + { + Name = "tool_with_optional", + Description = "A tool with an optional nullable parameter", + } + ); + + ChatOptions options = new() { Tools = [functionWithOptional] }; + + ChatResponse response = await chatClient.GetResponseAsync( + "Call tool with optional param", + options, + TestContext.Current.CancellationToken + ); + Assert.NotNull(response); + } + + [Fact] + public async Task GetResponseAsync_WithRequiredNullableUnionType_PreservesUnionType() + { + // When a property IS in the required array but has a nullable union type, + // we should NOT transform it - let the API fail with a meaningful error + // rather than silently misrepresenting the schema. + // Using BetaTool.AsAITool() bypasses the schema transformation, so this test + // verifies the raw tool passes through unchanged. + VerbatimHttpHandler handler = new( + expectedRequest: """ + { + "max_tokens": 1024, + "model": "claude-haiku-4-5", + "messages": [{ + "role": "user", + "content": [{ + "type": "text", + "text": "Call tool with required nullable" + }] + }], + "tools": [{ + "name": "tool_with_required_nullable", + "description": "A tool with a required nullable parameter", + "input_schema": { + "nullable_number": { + "type": ["integer", "null"], + "description": "A required but nullable number" + }, + "type": "object", + "required": ["nullable_number"] + } + }] + } + """, + actualResponse: """ + { + "id": "msg_required_nullable_01", + "type": "message", + "role": "assistant", + "model": "claude-haiku-4-5", + "content": [{ + "type": "text", + "text": "Tool ready" + }], + "stop_reason": "end_turn", + "usage": { + "input_tokens": 30, + "output_tokens": 5 + } + } + """ + ); + + IChatClient chatClient = CreateChatClient(handler, "claude-haiku-4-5"); + + // Create a BetaTool with a required nullable parameter using raw schema + // This simulates a schema that came from elsewhere (not C# MCP SDK pattern) +#pragma warning disable CA1861 // Prefer 'static readonly' fields over constant array arguments - test method only runs once + BetaToolUnion rawTool = new BetaTool + { + Name = "tool_with_required_nullable", + Description = "A tool with a required nullable parameter", + InputSchema = new InputSchema( + new Dictionary + { + ["nullable_number"] = JsonSerializer.SerializeToElement( + new + { + type = new[] { "integer", "null" }, + description = "A required but nullable number", + } + ), + } + ) + { + Required = ["nullable_number"], + }, + }; +#pragma warning restore CA1861 + + ChatOptions options = new() { Tools = [rawTool.AsAITool()] }; + + ChatResponse response = await chatClient.GetResponseAsync( + "Call tool with required nullable", + options, + TestContext.Current.CancellationToken + ); + Assert.NotNull(response); + } } diff --git a/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs b/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs index 1736674e3..45e8fd6ab 100644 --- a/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs +++ b/src/Anthropic/Services/Beta/Messages/AnthropicBetaClientExtensions.cs @@ -197,6 +197,87 @@ is string version { _ = schemaObj.Remove(propName); } + + // Handle nullable union types (e.g., "type": ["integer", "null"]) for + // non-required properties. The C# MCP SDK generates these for optional + // parameters, but structured outputs doesn't support union types. + // Only transform non-required properties; required + nullable is an + // incompatible schema that should fail at the API level. + if ( + schemaObj.TryGetPropertyValue("properties", out JsonNode? propsNode) + && propsNode is JsonObject propsObj + ) + { + HashSet requiredProps = []; + if ( + schemaObj.TryGetPropertyValue("required", out JsonNode? reqNode) + && reqNode is JsonArray reqArray + ) + { + foreach (JsonNode? req in reqArray) + { + if (req?.GetValue() is string reqName) + { + requiredProps.Add(reqName); + } + } + } + + foreach (var prop in propsObj) + { + if (requiredProps.Contains(prop.Key)) + { + continue; + } + + if (prop.Value is not JsonObject propSchema) + { + continue; + } + + if ( + !propSchema.TryGetPropertyValue("type", out JsonNode? typeNode) + || typeNode is not JsonArray typeArray + ) + { + continue; + } + + int nullIndex = -1; + for (int i = 0; i < typeArray.Count; i++) + { + if (typeArray[i]?.GetValue() == "null") + { + nullIndex = i; + break; + } + } + + if (nullIndex < 0) + { + continue; + } + + typeArray.RemoveAt(nullIndex); + + if (typeArray.Count == 1) + { + propSchema["type"] = typeArray[0]?.DeepClone(); + } + + if ( + propSchema.TryGetPropertyValue( + "default", + out JsonNode? defaultNode + ) + && defaultNode is JsonValue defaultValue + && defaultValue.GetValueKind() == JsonValueKind.Null + ) + { + propSchema.Remove("default"); + } + } + } } return schemaNode; @@ -998,20 +1079,6 @@ createParams.OutputFormat is null JsonElement inputSchema = af.JsonSchema; if (inputSchema.ValueKind is JsonValueKind.Object) { - if ( - inputSchema.TryGetProperty( - "properties", - out JsonElement propsElement - ) - && propsElement.ValueKind is JsonValueKind.Object - ) - { - foreach (JsonProperty p in propsElement.EnumerateObject()) - { - properties[p.Name] = p.Value; - } - } - if ( inputSchema.TryGetProperty( "required", @@ -1032,6 +1099,23 @@ r.ValueKind is JsonValueKind.String } } } + + if ( + inputSchema.TryGetProperty( + "properties", + out JsonElement propsElement + ) + && propsElement.ValueKind is JsonValueKind.Object + ) + { + foreach (JsonProperty p in propsElement.EnumerateObject()) + { + // Transform nullable union types for non-required properties + properties[p.Name] = required.Contains(p.Name) + ? p.Value + : TransformNullableUnionType(p.Value); + } + } } (createdTools ??= []).Add( @@ -1515,6 +1599,77 @@ out Uri? url return annotation; } + /// + /// Transforms a property schema with nullable union type (e.g., "type": ["integer", "null"]) + /// to a simple type (e.g., "type": "integer") and removes "default": null. + /// This handles schemas generated by the C# MCP SDK for optional nullable parameters. + /// + private static JsonElement TransformNullableUnionType(JsonElement propertySchema) + { + if (propertySchema.ValueKind is not JsonValueKind.Object) + { + return propertySchema; + } + + if ( + !propertySchema.TryGetProperty("type", out JsonElement typeElement) + || typeElement.ValueKind is not JsonValueKind.Array + ) + { + return propertySchema; + } + + List nonNullTypes = []; + bool hasNull = false; + foreach (JsonElement t in typeElement.EnumerateArray()) + { + if (t.ValueKind is JsonValueKind.String && t.GetString() == "null") + { + hasNull = true; + } + else + { + nonNullTypes.Add(t); + } + } + + if (!hasNull || nonNullTypes.Count == 0) + { + return propertySchema; + } + + var transformed = new Dictionary(); + foreach (JsonProperty prop in propertySchema.EnumerateObject()) + { + if (prop.Name == "type") + { + if (nonNullTypes.Count == 1) + { + transformed["type"] = nonNullTypes[0]; + } + else + { + transformed["type"] = JsonSerializer.SerializeToElement( + nonNullTypes.Select(t => t.GetString()) + ); + } + } + else if (prop.Name == "default") + { + if (prop.Value.ValueKind is not JsonValueKind.Null) + { + transformed[prop.Name] = prop.Value; + } + } + else + { + transformed[prop.Name] = prop.Value; + } + } + + return JsonSerializer.SerializeToElement(transformed); + } + private sealed class StreamingFunctionData { public string CallId { get; set; } = "";