diff --git a/Anthropic.SDK.Tests/Anthropic.SDK.Tests.csproj b/Anthropic.SDK.Tests/Anthropic.SDK.Tests.csproj
index c53b35c..3920640 100644
--- a/Anthropic.SDK.Tests/Anthropic.SDK.Tests.csproj
+++ b/Anthropic.SDK.Tests/Anthropic.SDK.Tests.csproj
@@ -33,18 +33,18 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
diff --git a/Anthropic.SDK.Tests/ChatOptionsExtensionsTests.cs b/Anthropic.SDK.Tests/ChatOptionsExtensionsTests.cs
index 8fc537c..eff3ebe 100644
--- a/Anthropic.SDK.Tests/ChatOptionsExtensionsTests.cs
+++ b/Anthropic.SDK.Tests/ChatOptionsExtensionsTests.cs
@@ -26,7 +26,7 @@ public void WithThinking_SetsThinkingParameters()
var thinkingParams = options.GetThinkingParameters();
Assert.IsNotNull(thinkingParams);
Assert.AreEqual(budgetTokens, thinkingParams.BudgetTokens);
- Assert.AreEqual("enabled", thinkingParams.Type);
+ Assert.AreEqual(ThinkingType.enabled, thinkingParams.Type);
Assert.IsFalse(thinkingParams.UseInterleavedThinking);
}
@@ -63,7 +63,7 @@ public void WithInterleavedThinking_SetsInterleavedThinkingParameters()
var thinkingParams = options.GetThinkingParameters();
Assert.IsNotNull(thinkingParams);
Assert.AreEqual(budgetTokens, thinkingParams.BudgetTokens);
- Assert.AreEqual("enabled", thinkingParams.Type);
+ Assert.AreEqual(ThinkingType.enabled, thinkingParams.Type);
Assert.IsTrue(thinkingParams.UseInterleavedThinking);
}
@@ -291,7 +291,7 @@ public void ChatClientHelper_MapsThinkingParametersCorrectly()
// Assert
Assert.IsNotNull(messageParams.Thinking);
Assert.AreEqual(3000, messageParams.Thinking.BudgetTokens);
- Assert.AreEqual("enabled", messageParams.Thinking.Type);
+ Assert.AreEqual(ThinkingType.enabled, messageParams.Thinking.Type);
Assert.IsFalse(messageParams.Thinking.UseInterleavedThinking);
Assert.AreEqual(AnthropicModels.Claude37Sonnet, messageParams.Model);
Assert.AreEqual(4096, messageParams.MaxTokens);
@@ -319,10 +319,254 @@ public void ChatClientHelper_MapsInterleavedThinkingParametersCorrectly()
// Assert
Assert.IsNotNull(messageParams.Thinking);
Assert.AreEqual(8000, messageParams.Thinking.BudgetTokens);
- Assert.AreEqual("enabled", messageParams.Thinking.Type);
+ Assert.AreEqual(ThinkingType.enabled, messageParams.Thinking.Type);
Assert.IsTrue(messageParams.Thinking.UseInterleavedThinking);
Assert.AreEqual(AnthropicModels.Claude37Sonnet, messageParams.Model);
Assert.AreEqual(4096, messageParams.MaxTokens);
}
+
+ [TestMethod]
+ public void WithAdaptiveThinking_SetsAdaptiveType()
+ {
+ // Arrange
+ var options = new ChatOptions();
+
+ // Act
+ var result = options.WithAdaptiveThinking();
+
+ // Assert
+ Assert.AreSame(options, result);
+ var thinkingParams = options.GetThinkingParameters();
+ Assert.IsNotNull(thinkingParams);
+ Assert.AreEqual(ThinkingType.adaptive, thinkingParams.Type);
+ Assert.IsNull(thinkingParams.BudgetTokens);
+ Assert.IsNull(thinkingParams.Effort);
+ }
+
+ [TestMethod]
+ public void WithAdaptiveThinking_WithEffort_SetsEffortAndAdaptiveType()
+ {
+ // Arrange
+ var options = new ChatOptions();
+
+ // Act
+ var result = options.WithAdaptiveThinking(ThinkingEffort.medium);
+
+ // Assert
+ Assert.AreSame(options, result);
+ var thinkingParams = options.GetThinkingParameters();
+ Assert.IsNotNull(thinkingParams);
+ Assert.AreEqual(ThinkingType.adaptive, thinkingParams.Type);
+ Assert.AreEqual(ThinkingEffort.medium, thinkingParams.Effort);
+ Assert.IsNull(thinkingParams.BudgetTokens);
+ }
+
+ [TestMethod]
+ public void WithAdaptiveThinking_NullOptions_ThrowsArgumentNullException()
+ {
+ // Arrange
+ ChatOptions options = null;
+
+ // Act & Assert
+ Assert.Throws(() => options.WithAdaptiveThinking());
+ Assert.Throws(() => options.WithAdaptiveThinking(ThinkingEffort.high));
+ }
+
+ [TestMethod]
+ public void WithAdaptiveThinking_FluentChaining_Works()
+ {
+ // Arrange & Act
+ var options = new ChatOptions
+ {
+ ModelId = AnthropicModels.Claude46Sonnet,
+ MaxOutputTokens = 16000,
+ Temperature = 1.0f
+ }.WithAdaptiveThinking(ThinkingEffort.high);
+
+ // Assert
+ Assert.AreEqual(AnthropicModels.Claude46Sonnet, options.ModelId);
+ Assert.AreEqual(16000, options.MaxOutputTokens);
+ Assert.AreEqual(1.0f, options.Temperature);
+
+ var thinkingParams = options.GetThinkingParameters();
+ Assert.IsNotNull(thinkingParams);
+ Assert.AreEqual(ThinkingType.adaptive, thinkingParams.Type);
+ Assert.AreEqual(ThinkingEffort.high, thinkingParams.Effort);
+ }
+
+ [TestMethod]
+ public void WithAdaptiveThinking_OverwritesPreviousThinkingParameters()
+ {
+ // Arrange
+ var options = new ChatOptions();
+ options.WithThinking(3000);
+
+ // Act
+ options.WithAdaptiveThinking(ThinkingEffort.medium);
+
+ // Assert
+ var thinkingParams = options.GetThinkingParameters();
+ Assert.IsNotNull(thinkingParams);
+ Assert.AreEqual(ThinkingType.adaptive, thinkingParams.Type);
+ Assert.AreEqual(ThinkingEffort.medium, thinkingParams.Effort);
+ Assert.IsNull(thinkingParams.BudgetTokens);
+ }
+
+ [TestMethod]
+ public void ChatClientHelper_MapsAdaptiveThinkingCorrectly()
+ {
+ // Arrange
+ var client = new AnthropicClient().Messages;
+ var messages = new List
+ {
+ new ChatMessage(ChatRole.User, "Test message")
+ };
+ var options = new ChatOptions
+ {
+ ModelId = AnthropicModels.Claude46Sonnet,
+ MaxOutputTokens = 16000,
+ }.WithAdaptiveThinking(ThinkingEffort.medium);
+
+ // Act
+ var messageParams = ChatClientHelper.CreateMessageParameters(client, messages, options);
+
+ // Assert
+ Assert.IsNotNull(messageParams.Thinking);
+ Assert.AreEqual(ThinkingType.adaptive, messageParams.Thinking.Type);
+ Assert.IsNull(messageParams.Thinking.BudgetTokens);
+ Assert.IsNotNull(messageParams.OutputConfig);
+ Assert.AreEqual(ThinkingEffort.medium, messageParams.OutputConfig.Effort);
+ }
+
+ [TestMethod]
+ public void ChatClientHelper_MapsAdaptiveThinkingWithoutEffort()
+ {
+ // Arrange
+ var client = new AnthropicClient().Messages;
+ var messages = new List
+ {
+ new ChatMessage(ChatRole.User, "Test message")
+ };
+ var options = new ChatOptions
+ {
+ ModelId = AnthropicModels.Claude46Sonnet,
+ MaxOutputTokens = 16000,
+ }.WithAdaptiveThinking();
+
+ // Act
+ var messageParams = ChatClientHelper.CreateMessageParameters(client, messages, options);
+
+ // Assert
+ Assert.IsNotNull(messageParams.Thinking);
+ Assert.AreEqual(ThinkingType.adaptive, messageParams.Thinking.Type);
+ Assert.IsNull(messageParams.Thinking.BudgetTokens);
+ Assert.IsNull(messageParams.OutputConfig);
+ }
+
+ [TestMethod]
+ public void ChatClientHelper_MapsReasoningOptionsToAdaptiveThinking()
+ {
+ // Arrange
+ var client = new AnthropicClient().Messages;
+ var messages = new List
+ {
+ new ChatMessage(ChatRole.User, "Test message")
+ };
+ var options = new ChatOptions
+ {
+ ModelId = AnthropicModels.Claude46Sonnet,
+ MaxOutputTokens = 16000,
+ Reasoning = new ReasoningOptions { Effort = ReasoningEffort.Medium }
+ };
+
+ // Act
+ var messageParams = ChatClientHelper.CreateMessageParameters(client, messages, options);
+
+ // Assert
+ Assert.IsNotNull(messageParams.Thinking);
+ Assert.AreEqual(ThinkingType.adaptive, messageParams.Thinking.Type);
+ Assert.IsNull(messageParams.Thinking.BudgetTokens);
+ Assert.IsNotNull(messageParams.OutputConfig);
+ Assert.AreEqual(ThinkingEffort.medium, messageParams.OutputConfig.Effort);
+ }
+
+ [TestMethod]
+ [DataRow(ReasoningEffort.Low, ThinkingEffort.low)]
+ [DataRow(ReasoningEffort.Medium, ThinkingEffort.medium)]
+ [DataRow(ReasoningEffort.High, ThinkingEffort.high)]
+ [DataRow(ReasoningEffort.ExtraHigh, ThinkingEffort.max)]
+ public void ChatClientHelper_MapsAllReasoningEffortLevels(ReasoningEffort reasoningEffort, ThinkingEffort expectedEffort)
+ {
+ // Arrange
+ var client = new AnthropicClient().Messages;
+ var messages = new List
+ {
+ new ChatMessage(ChatRole.User, "Test message")
+ };
+ var options = new ChatOptions
+ {
+ ModelId = AnthropicModels.Claude46Sonnet,
+ MaxOutputTokens = 16000,
+ Reasoning = new ReasoningOptions { Effort = reasoningEffort }
+ };
+
+ // Act
+ var messageParams = ChatClientHelper.CreateMessageParameters(client, messages, options);
+
+ // Assert
+ Assert.IsNotNull(messageParams.Thinking);
+ Assert.AreEqual(ThinkingType.adaptive, messageParams.Thinking.Type);
+ Assert.IsNotNull(messageParams.OutputConfig);
+ Assert.AreEqual(expectedEffort, messageParams.OutputConfig.Effort);
+ }
+
+ [TestMethod]
+ public void ChatClientHelper_ReasoningOptionsNone_ClearsThinking()
+ {
+ // Arrange
+ var client = new AnthropicClient().Messages;
+ var messages = new List
+ {
+ new ChatMessage(ChatRole.User, "Test message")
+ };
+ var options = new ChatOptions
+ {
+ ModelId = AnthropicModels.Claude46Sonnet,
+ MaxOutputTokens = 16000,
+ Reasoning = new ReasoningOptions { Effort = ReasoningEffort.None }
+ };
+
+ // Act
+ var messageParams = ChatClientHelper.CreateMessageParameters(client, messages, options);
+
+ // Assert
+ Assert.IsNull(messageParams.Thinking);
+ }
+
+ [TestMethod]
+ public void ChatClientHelper_ExplicitThinkingTakesPrecedenceOverReasoningOptions()
+ {
+ // Arrange
+ var client = new AnthropicClient().Messages;
+ var messages = new List
+ {
+ new ChatMessage(ChatRole.User, "Test message")
+ };
+ var options = new ChatOptions
+ {
+ ModelId = AnthropicModels.Claude46Sonnet,
+ MaxOutputTokens = 16000,
+ Reasoning = new ReasoningOptions { Effort = ReasoningEffort.Low }
+ }.WithAdaptiveThinking(ThinkingEffort.max);
+
+ // Act
+ var messageParams = ChatClientHelper.CreateMessageParameters(client, messages, options);
+
+ // Assert - WithAdaptiveThinking should win over ReasoningOptions
+ Assert.IsNotNull(messageParams.Thinking);
+ Assert.AreEqual(ThinkingType.adaptive, messageParams.Thinking.Type);
+ Assert.IsNotNull(messageParams.OutputConfig);
+ Assert.AreEqual(ThinkingEffort.max, messageParams.OutputConfig.Effort);
+ }
}
}
\ No newline at end of file
diff --git a/Anthropic.SDK.Tests/Messages.ChatClient.cs b/Anthropic.SDK.Tests/Messages.ChatClient.cs
index 90ac50c..1f124fb 100644
--- a/Anthropic.SDK.Tests/Messages.ChatClient.cs
+++ b/Anthropic.SDK.Tests/Messages.ChatClient.cs
@@ -104,6 +104,56 @@ public async Task TestNonStreamingThinkingWithExtensionMethods()
Assert.IsTrue(res.Text?.Contains("10") is true, res.Text);
}
+ [TestMethod]
+ public async Task TestNonStreamingThinkingAdaptiveWithExtensionMethods()
+ {
+ IChatClient client = new AnthropicClient().Messages;
+
+ List messages = new()
+ {
+ new ChatMessage(ChatRole.User, "How many r's are in the word strawberry?")
+ };
+
+ ChatOptions options = new ChatOptions()
+ {
+ ModelId = AnthropicModels.Claude46Sonnet,
+ MaxOutputTokens = 20000,
+ Temperature = 1.0f,
+ }.WithAdaptiveThinking(ThinkingEffort.high);
+
+ var res = await client.GetResponseAsync(messages, options);
+ Assert.IsTrue(res.Text.Contains("3") is true, res.Text);
+ messages.AddMessages(res);
+ messages.Add(new ChatMessage(ChatRole.User, "and how many letters total?"));
+ res = await client.GetResponseAsync(messages, options);
+ Assert.IsTrue(res.Text?.Contains("10") is true, res.Text);
+ }
+
+ [TestMethod]
+ public async Task TestNonStreamingThinkingAdaptive()
+ {
+ IChatClient client = new AnthropicClient().Messages;
+
+ List messages = new()
+ {
+ new ChatMessage(ChatRole.User, "How many r's are in the word strawberry?")
+ };
+
+ ChatOptions options = new ChatOptions()
+ {
+ ModelId = AnthropicModels.Claude46Sonnet,
+ MaxOutputTokens = 20000,
+ Temperature = 1.0f,
+ Reasoning = new ReasoningOptions()
+ {
+ Effort = ReasoningEffort.High,
+ }
+ };
+
+ var res = await client.GetResponseAsync(messages, options);
+ Assert.IsTrue(res.Text.Contains("3") is true, res.Text);
+ }
+
[TestMethod]
public async Task TestThinkingStreamingWithExtensionMethods()
{
diff --git a/Anthropic.SDK.Tests/ThinkingModeTests.cs b/Anthropic.SDK.Tests/ThinkingModeTests.cs
index 5cbfbf3..81429ab 100644
--- a/Anthropic.SDK.Tests/ThinkingModeTests.cs
+++ b/Anthropic.SDK.Tests/ThinkingModeTests.cs
@@ -43,6 +43,34 @@ public async Task TestBasicClaude37ThinkingMessage()
Assert.IsNotNull(response);
}
+ [TestMethod]
+ public async Task TestBasicClaude46ThinkingMessage()
+ {
+ var client = new AnthropicClient();
+ var messages = new List();
+ messages.Add(new Message(RoleType.User, "How many r's are in the word strawberry?"));
+ var parameters = new MessageParameters()
+ {
+ Messages = messages,
+ MaxTokens = 20000,
+ Model = AnthropicModels.Claude46Sonnet,
+ Stream = false,
+ Temperature = 1.0m,
+ Thinking = new ThinkingParameters()
+ {
+ UseInterleavedThinking = true,
+ Type = ThinkingType.adaptive,
+ Effort = ThinkingEffort.high,
+ }
+ };
+ var res = await client.Messages.GetClaudeMessageAsync(parameters);
+ Assert.IsTrue(res.Content.OfType().Any());
+ var response = res.Message.ToString();
+ var thoughts = res.Message.ThinkingContent;
+ Assert.IsNotNull(thoughts);
+ Assert.IsNotNull(response);
+ }
+
[TestMethod]
public async Task TestRedactedClaude37ThinkingMessage()
{
diff --git a/Anthropic.SDK/Anthropic.SDK.csproj b/Anthropic.SDK/Anthropic.SDK.csproj
index bbdd8e0..57d22c9 100644
--- a/Anthropic.SDK/Anthropic.SDK.csproj
+++ b/Anthropic.SDK/Anthropic.SDK.csproj
@@ -36,13 +36,13 @@
-
-
+
+
-
+
diff --git a/Anthropic.SDK/BaseEndpoint.cs b/Anthropic.SDK/BaseEndpoint.cs
index d291283..1ae4068 100644
--- a/Anthropic.SDK/BaseEndpoint.cs
+++ b/Anthropic.SDK/BaseEndpoint.cs
@@ -184,7 +184,10 @@ protected async Task HttpRequestRaw(string url = null, Http
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters = { ContentConverter.Instance },
// Ensure proper Unicode handling for all characters
- Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
+ Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
+#if DEBUG
+ WriteIndented = true,
+#endif
};
string jsonContent = JsonSerializer.Serialize(postData, options);
req.Content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
diff --git a/Anthropic.SDK/Constants/AnthropicModels.cs b/Anthropic.SDK/Constants/AnthropicModels.cs
index d104565..f3ae820 100644
--- a/Anthropic.SDK/Constants/AnthropicModels.cs
+++ b/Anthropic.SDK/Constants/AnthropicModels.cs
@@ -9,6 +9,16 @@ namespace Anthropic.SDK.Constants
///
public static class AnthropicModels
{
+ ///
+ /// Claude 4.6 Opus
+ ///
+ public const string Claude46Opus = "claude-opus-4-6";
+
+ ///
+ /// Claude 4.6 Opus
+ ///
+ public const string Claude46Sonnet = "claude-sonnet-4-6";
+
///
/// Claude 4.5 Opus
///
diff --git a/Anthropic.SDK/Constants/VertexAIModels.cs b/Anthropic.SDK/Constants/VertexAIModels.cs
index 51ebcbc..a79bd61 100644
--- a/Anthropic.SDK/Constants/VertexAIModels.cs
+++ b/Anthropic.SDK/Constants/VertexAIModels.cs
@@ -46,5 +46,15 @@ public static class VertexAIModels
/// Claude 4.5 Opus on Vertex AI
///
public const string Claude45Opus = "claude-opus-4-5@20251101";
+
+ ///
+ /// Claude 4.6 Sonnet on Vertex AI
+ ///
+ public const string Claude46Sonnet = "claude-sonnet-4-6";
+
+ ///
+ /// Claude 4.6 Opus on Vertex AI
+ ///
+ public const string Claude46Opus = "claude-opus-4-6";
}
}
diff --git a/Anthropic.SDK/Extensions/ChatOptionsExtensions.cs b/Anthropic.SDK/Extensions/ChatOptionsExtensions.cs
index 8f2849c..f0dd699 100644
--- a/Anthropic.SDK/Extensions/ChatOptionsExtensions.cs
+++ b/Anthropic.SDK/Extensions/ChatOptionsExtensions.cs
@@ -100,6 +100,46 @@ public static ChatOptions WithInterleavedThinking(this ChatOptions options, Thin
return options;
}
+ ///
+ /// Sets adaptive thinking mode, which lets Claude dynamically determine when and how much to use extended thinking.
+ /// Recommended for Claude Opus 4.6 and Sonnet 4.6. Interleaved thinking is automatically enabled.
+ ///
+ /// The ChatOptions instance
+ /// The ChatOptions instance for fluent chaining
+ public static ChatOptions WithAdaptiveThinking(this ChatOptions options)
+ {
+ if (options == null)
+ throw new ArgumentNullException(nameof(options));
+
+ (options.AdditionalProperties ??= new())[ThinkingParametersKey] = new ThinkingParameters
+ {
+ Type = ThinkingType.adaptive
+ };
+
+ return options;
+ }
+
+ ///
+ /// Sets adaptive thinking mode with a specific effort level. The effort level is mapped to output_config.effort
+ /// to guide how much thinking Claude does. Recommended for Claude Opus 4.6 and Sonnet 4.6.
+ ///
+ /// The ChatOptions instance
+ /// The effort level (low, medium, high, or max) to guide thinking allocation
+ /// The ChatOptions instance for fluent chaining
+ public static ChatOptions WithAdaptiveThinking(this ChatOptions options, ThinkingEffort effort)
+ {
+ if (options == null)
+ throw new ArgumentNullException(nameof(options));
+
+ (options.AdditionalProperties ??= new())[ThinkingParametersKey] = new ThinkingParameters
+ {
+ Type = ThinkingType.adaptive,
+ Effort = effort
+ };
+
+ return options;
+ }
+
///
/// Gets the thinking parameters from ChatOptions
///
diff --git a/Anthropic.SDK/Messaging/ChatClientHelper.cs b/Anthropic.SDK/Messaging/ChatClientHelper.cs
index ed6bab9..09f980f 100644
--- a/Anthropic.SDK/Messaging/ChatClientHelper.cs
+++ b/Anthropic.SDK/Messaging/ChatClientHelper.cs
@@ -143,6 +143,37 @@ public static MessageParameters CreateMessageParameters(IChatClient client, IEnu
if (thinkingParameters != null)
{
parameters.Thinking = thinkingParameters;
+
+ if (thinkingParameters.Effort is { } effort)
+ {
+ (parameters.OutputConfig ??= new OutputConfig()).Effort = effort;
+ }
+ }
+
+ // Map MEAI ReasoningOptions when the Anthropic-specific extension wasn't used
+ if (options.Reasoning is { } reasoning && thinkingParameters == null)
+ {
+ if (reasoning.Effort is { } reasoningEffort && reasoningEffort != ReasoningEffort.None)
+ {
+ parameters.Thinking = new ThinkingParameters
+ {
+ Type = ThinkingType.adaptive
+ };
+
+ var mapped = reasoningEffort switch
+ {
+ ReasoningEffort.Low => ThinkingEffort.low,
+ ReasoningEffort.Medium => ThinkingEffort.medium,
+ ReasoningEffort.High => ThinkingEffort.high,
+ ReasoningEffort.ExtraHigh => ThinkingEffort.max,
+ _ => (ThinkingEffort?)null
+ };
+
+ if (mapped is not null)
+ {
+ (parameters.OutputConfig ??= new OutputConfig()).Effort = mapped;
+ }
+ }
}
// Map response format from ChatOptions for structured JSON output
diff --git a/Anthropic.SDK/Messaging/MessageParameters.cs b/Anthropic.SDK/Messaging/MessageParameters.cs
index 76e3108..e22c72d 100644
--- a/Anthropic.SDK/Messaging/MessageParameters.cs
+++ b/Anthropic.SDK/Messaging/MessageParameters.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
@@ -45,10 +46,27 @@ public class MessageParameters : MessageCountTokenParameters
///
/// Output format configuration for structured JSON output.
- /// Requires the structured-outputs-2025-11-13 beta header.
+ /// Obsolete and will be removed in the future.
///
- [JsonPropertyName("output_format")]
- public OutputFormat OutputFormat { get; set; }
+ [Obsolete]
+ [JsonIgnore]
+ public OutputFormat OutputFormat
+ {
+ get
+ {
+ return OutputConfig?.OutputFormat;
+ }
+ set
+ {
+ if (OutputConfig == null)
+ OutputConfig = new OutputConfig();
+
+ OutputConfig.OutputFormat = value;
+ }
+ }
+
+ [JsonPropertyName("output_config")]
+ public OutputConfig OutputConfig { get; set; }
[JsonPropertyName("mcp_servers")]
public List MCPServers { get; set; }
diff --git a/Anthropic.SDK/Messaging/OutputConfig.cs b/Anthropic.SDK/Messaging/OutputConfig.cs
new file mode 100644
index 0000000..e372e06
--- /dev/null
+++ b/Anthropic.SDK/Messaging/OutputConfig.cs
@@ -0,0 +1,13 @@
+using System.Text.Json.Serialization;
+
+namespace Anthropic.SDK.Messaging
+{
+ public class OutputConfig
+ {
+ [JsonPropertyName("effort")]
+ public ThinkingEffort? Effort { get; set; }
+
+ [JsonPropertyName("format")]
+ public OutputFormat OutputFormat { get; set; }
+ }
+}
diff --git a/Anthropic.SDK/Messaging/ThinkingEffort.cs b/Anthropic.SDK/Messaging/ThinkingEffort.cs
new file mode 100644
index 0000000..1e7c157
--- /dev/null
+++ b/Anthropic.SDK/Messaging/ThinkingEffort.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Text.Json.Serialization;
+
+namespace Anthropic.SDK.Messaging;
+
+[JsonConverter(typeof(JsonStringEnumConverter))]
+public enum ThinkingEffort
+{
+ low,
+ medium,
+ high,
+ max
+}
\ No newline at end of file
diff --git a/Anthropic.SDK/Messaging/ThinkingParameters.cs b/Anthropic.SDK/Messaging/ThinkingParameters.cs
index da334ab..f246832 100644
--- a/Anthropic.SDK/Messaging/ThinkingParameters.cs
+++ b/Anthropic.SDK/Messaging/ThinkingParameters.cs
@@ -1,22 +1,30 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;
namespace Anthropic.SDK.Messaging
{
-
+
public class ThinkingParameters
{
[JsonPropertyName("type")]
- public string Type => "enabled";
+ public ThinkingType Type { get; set; } = ThinkingType.enabled;
+
[JsonPropertyName("budget_tokens")]
- public int BudgetTokens { get; set; }
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ public int? BudgetTokens { get; set; }
///
/// Indicates whether to use interleaved thinking mode which allows thinking tokens to exceed max_tokens
///
[JsonIgnore]
public bool UseInterleavedThinking { get; set; }
+
+ ///
+ /// The effort level to map to output_config.effort when using adaptive thinking
+ ///
+ [JsonIgnore]
+ public ThinkingEffort? Effort { get; set; }
}
}
diff --git a/Anthropic.SDK/Messaging/ThinkingType.cs b/Anthropic.SDK/Messaging/ThinkingType.cs
new file mode 100644
index 0000000..2e49569
--- /dev/null
+++ b/Anthropic.SDK/Messaging/ThinkingType.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Text.Json.Serialization;
+
+namespace Anthropic.SDK.Messaging;
+
+[JsonConverter(typeof(JsonStringEnumConverter))]
+public enum ThinkingType
+{
+ enabled,
+
+ adaptive
+}
\ No newline at end of file
diff --git a/Anthropic.SDK/Messaging/VertexAIMessagesEndpoint.cs b/Anthropic.SDK/Messaging/VertexAIMessagesEndpoint.cs
index fc12afe..3a34bfb 100644
--- a/Anthropic.SDK/Messaging/VertexAIMessagesEndpoint.cs
+++ b/Anthropic.SDK/Messaging/VertexAIMessagesEndpoint.cs
@@ -325,7 +325,8 @@ private object CreateVertexAIRequest(MessageParameters parameters)
stream = parameters.Stream,
tools = parameters.Tools?.Select(t => t.Function).ToList(),
tool_choice = parameters.ToolChoice,
- thinking = parameters.Thinking
+ thinking = parameters.Thinking,
+ output_config = parameters.OutputConfig
// Note: We don't need to include model here as it's part of the URL for Vertex AI
};