Skip to content

Conversation

Copy link

Copilot AI commented Sep 14, 2025

Summary

This PR adds native support for ThinkingParameters and advanced Interleaved Thinking capabilities in the Microsoft.Extensions.AI (MEAI) compatible API through clean extension methods. Previously, users had to use the verbose RawRepresentationFactory workaround to enable extended thinking functionality with Claude 3.7 Sonnet and newer models.

Problem

The ThinkingParameters feature was fully supported in the basic Anthropic.SDK API but only accessible in MEAI through a cumbersome workaround:

// Old approach - verbose and unintuitive
ChatOptions options = new()
{
    ModelId = AnthropicModels.Claude37Sonnet,
    MaxOutputTokens = 4096,
    RawRepresentationFactory = static _ => new MessageParameters()
    {
        Thinking = new() { BudgetTokens = 4000 },
    },
};

Solution

Added fluent extension methods that provide a clean, intuitive API with support for both regular and interleaved thinking:

// Regular thinking (budget ≤ max_tokens)
ChatOptions options = new()
{
    ModelId = AnthropicModels.Claude37Sonnet,
    MaxOutputTokens = 4096,
    Temperature = 1.0f,
}.WithThinking(4000);

// Interleaved thinking (budget can exceed max_tokens with beta header)
ChatOptions options = new()
{
    ModelId = AnthropicModels.Claude37Sonnet,
    MaxOutputTokens = 4096,
    Temperature = 1.0f,
}.WithInterleavedThinking(8000);

Key Features

  • Fluent API: Clean, chainable extension methods following .NET conventions
  • Type Safety: Proper validation with meaningful error messages
  • Automatic Mapping: Seamless integration with existing ChatClientHelper
  • Backward Compatible: Old RawRepresentationFactory approach still works
  • Full Support: Works with both streaming and non-streaming scenarios
  • Interleaved Thinking: Advanced mode allowing thinking tokens to exceed max_tokens
  • Dynamic Headers: Automatically adds interleaved-thinking-2025-05-14 beta header when needed
  • Platform Compatibility: Documented limitations for 3rd-party platforms (Bedrock, Vertex AI)
  • Rich Documentation: Comprehensive README examples and XML documentation

Implementation Details

Core Components

  1. ChatOptionsExtensions.cs - Extension methods for ChatOptions:

    • WithThinking(int budgetTokens) - Simple fluent method for regular thinking
    • WithThinking(ThinkingParameters) - Advanced method with custom parameters
    • WithInterleavedThinking(int budgetTokens) - Enables interleaved thinking mode
    • WithInterleavedThinking(ThinkingParameters) - Advanced interleaved thinking
    • GetThinkingParameters() - Retrieval method
  2. Enhanced ThinkingParameters.cs - Added support for interleaved thinking:

    • New UseInterleavedThinking property to track mode
    • Maintains backward compatibility
  3. Updated HTTP Infrastructure - Dynamic header support:

    • Enhanced BaseEndpoint.HttpRequestRaw() to accept additional headers
    • Modified MessagesEndpoint to detect interleaved thinking and add beta header
    • Works for both streaming and non-streaming requests
  4. Updated ChatClientHelper.cs - Automatic parameter mapping:

    • Checks for thinking parameters in ChatOptions.AdditionalProperties
    • Maps to MessageParameters.Thinking automatically
  5. Comprehensive Testing - Full test coverage:

    • 20 unit tests covering all extension methods and scenarios
    • Integration tests with ChatClientHelper
    • Error handling validation
    • Tests for both regular and interleaved thinking modes

Usage Examples

Basic Usage

using Anthropic.SDK.Extensions;

IChatClient client = new AnthropicClient().Messages;

ChatOptions options = new()
{
    ModelId = AnthropicModels.Claude37Sonnet,
    MaxOutputTokens = 4096,
    Temperature = 1.0f,
}.WithThinking(4000); // Enable thinking with 4,000 budget tokens

var response = await client.GetResponseAsync("How many r's are in strawberry?", options);

// Access thinking content if available
var thinkingContent = response.Message.Contents
    .OfType<TextReasoningContent>()
    .FirstOrDefault();

Advanced Usage with Interleaved Thinking

// Enable interleaved thinking with budget tokens exceeding max_tokens
ChatOptions options = new()
{
    ModelId = AnthropicModels.Claude37Sonnet,
    MaxOutputTokens = 4096,
    Temperature = 1.0f,
}.WithInterleavedThinking(8000); // 8,000 thinking tokens with 4,096 max output tokens

var response = await client.GetResponseAsync("Complex reasoning task", options);

Custom ThinkingParameters

var thinkingParams = new ThinkingParameters { BudgetTokens = 3000 };
var options = new ChatOptions()
{
    ModelId = AnthropicModels.Claude37Sonnet,
    MaxOutputTokens = 4096,
}.WithThinking(thinkingParams);

Platform Compatibility

  • Direct Anthropic API: Interleaved thinking works with all compatible models
  • 3rd-party platforms (Amazon Bedrock, Vertex AI): Interleaved thinking only works with Claude Opus 4.1, Opus 4, or Sonnet 4 models
  • Developers are responsible for ensuring compatibility with their chosen platform and model

Breaking Changes

None. This is a purely additive change that maintains full backward compatibility.

Testing

  • ✅ All existing tests continue to pass
  • ✅ New comprehensive test suite with 20 tests validates all functionality
  • ✅ Integration tests confirm proper mapping behavior
  • ✅ Error handling tests ensure robust validation
  • ✅ Tests cover both regular and interleaved thinking modes

This enhancement significantly improves the developer experience for MEAI users wanting to leverage Claude's extended thinking capabilities, including the advanced interleaved thinking mode, while maintaining the library's commitment to clean, intuitive APIs.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI changed the title [WIP] Can you figure out if ThinkingParameters is supported when using the Microsoft.Extensions.AI compatible API of this library? There's an example in the README.md of using it with the "basic" AnthropicClient via MessageParameters, but I am unsure if it's... Add direct ThinkingParameters support to Microsoft.Extensions.AI ChatOptions Sep 14, 2025
Copilot AI requested a review from PederHP September 14, 2025 17:04
Copilot finished work on behalf of PederHP September 14, 2025 17:04
@PederHP PederHP marked this pull request as ready for review September 18, 2025 14:58
Copy link
Owner

@PederHP PederHP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example token values are more than Sonnet 3.7 allows. I think we should use <= 4096 for max_tokens and then less than equal that for the thinking budget.

There's a detail where if this beta header is passed: interleaved-thinking-2025-05-14 - then thinking tokens is allowed to be higher than max tokens. But it isn't currently. Can you make that an option?

However it should be noted that:

On 3rd-party platforms (e.g., Amazon Bedrock and Vertex AI), if you pass interleaved-thinking-2025-05-14 to any model aside from Claude Opus 4.1, Opus 4, or Sonnet 4, your request will fail.

On direct Anthropic API access it's ok to pass it always, but it cannot be auto-passed for the others. Can you take a look at making it configurable, and then for now it's up to the developer to ensure it is only passed with compatible models for those providers.

I am thinking a WithInterleavedThinking() extension on ChatOptions() would be a super cool way to configure it if possible.

@PederHP
Copy link
Owner

PederHP commented Sep 18, 2025

@copilot I have some review comments

Copy link
Author

Copilot AI commented Sep 18, 2025

The example token values are more than Sonnet 3.7 allows. I think we should use <= 4096 for max_tokens and then less than equal that for the thinking budget.

There's a detail where if this beta hea...

I've implemented all the requested changes in commit 2e59561:

Fixed token values: Updated all examples to use 4096 for max_tokens and appropriate thinking budget (≤ max_tokens for regular thinking)

Added WithInterleavedThinking() extension: Created fluent extension methods that enable the interleaved-thinking-2025-05-14 beta header, allowing thinking tokens to exceed max_tokens

Dynamic header support: Automatically adds the interleaved thinking beta header only when needed, without affecting global client configuration

Platform compatibility handling: Added documentation noting that on 3rd-party platforms (Bedrock, Vertex AI), this only works with Claude Opus 4.1, Opus 4, or Sonnet 4 models

Usage examples:

// Regular thinking (budget ≤ max_tokens)
ChatOptions options = new()
{
    ModelId = AnthropicModels.Claude37Sonnet,
    MaxOutputTokens = 4096,
}.WithThinking(4000);

// Interleaved thinking (budget can exceed max_tokens)
ChatOptions options = new()
{
    ModelId = AnthropicModels.Claude37Sonnet,
    MaxOutputTokens = 4096,
}.WithInterleavedThinking(8000); // Works with beta header

All 20 tests pass, including comprehensive coverage of the new functionality.

@copilot I have some review comments

I've addressed all the review comments from your previous feedback in commit 2e59561. The implementation includes proper token values (4096 max_tokens), the requested WithInterleavedThinking() extension method, and dynamic beta header support for enhanced thinking capabilities.

Copilot AI changed the title Add direct ThinkingParameters support to Microsoft.Extensions.AI ChatOptions Add ThinkingParameters and Interleaved Thinking support to Microsoft.Extensions.AI ChatOptions Sep 18, 2025
Copilot AI requested a review from PederHP September 18, 2025 15:16
Copilot finished work on behalf of PederHP September 18, 2025 15:16
@PederHP PederHP merged commit 8de8f15 into main Sep 18, 2025
@PederHP PederHP deleted the copilot/fix-67a37551-064d-46f4-aaef-ab508ac3b957 branch October 17, 2025 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants