Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Feb 1, 2026

  • Create ReasoningEffort enum with None, Low, Medium, High, ExtraHigh values
  • Create ReasoningOutput enum with None, Summary, Full values (renamed Detailed → Full)
  • Create ReasoningOptions class with Effort and Output properties
  • Add Reasoning property to ChatOptions class
  • Update ChatOptions copy constructor to clone Reasoning
  • Update OpenAI Chat implementation to map ReasoningOptions
  • Update OpenAI Responses implementation to map ReasoningOptions
  • Update tests for ChatOptions
  • Address PR feedback:
    • Remove [Experimental] attribute and add to stable JSON file
    • Remove ExtraHigh-specific remarks
    • Make Clone() method internal
    • Simplify ToOpenAIChatReasoningEffortLevel method
    • Revert DiagnosticIds.cs changes
    • Remove remarks from ChatOptions.Reasoning property
    • Update ReasoningEffort documentation with suggested text
    • Simplify "No reasoning effort" comment
    • Update ReasoningOptions documentation with suggested text
    • Remove explicit enum numbering from both enums
    • Add dedicated ReasoningOptionsTests for serialization/roundtripping
    • Add OpenAI unit tests for ReasoningOptions producing expected JSON
    • Rename ReasoningOutput.DetailedReasoningOutput.Full for clarity
Original prompt

This section details on the original issue you should resolve

<issue_title>[API Proposal]: ChatOptions Reasoning</issue_title>
<issue_description>### Background and motivation

While we can use ChatOptions.RawRepresentationFactory to set the reasoning configuration of a request, things get complicated when different providers are supported by the IChatClient. Reasoning seems to be supported by most providers so we should start thinking about how to expose it in ChatOptions.

Here is a summary of how it works for different providers:

Provider Reasoning Comment
Claude output_config={ "effort": "medium" } "thinking": { "type": "enabled", "budget_tokens": 10000 } Enum: low, medium, high. Also supports thinking budget. Effort seems to be the new thing. Default is high
Gemini thinking_config=types.ThinkingConfig(thinking_level="low") thinking_config=types.ThinkingConfig(thinking_budget=1024) Enum: low, high. Also supports budget but the level is "recommended for Gemini 3 models and onwards". Default is dynamic.
Mistral "prompt_mode": "reasoning" reasoning is the default value. Can be set to null to disable it.
OpenAI reasoning={"effort": "medium"} Enum: none, minimal, low, medium, high, xhigh
xAI reasoning_effort="high" Enum: low, high
Amazon ??

API Proposal

public class Reasoning
{
    public static Reasoning None { get; }
    public static Reasoning Low { get; }
    public static Reasoning Medium { get; }
    public static Reasoning High { get; }
}

public class ChatOptions
{
    public Reasoning? Reasoning { get; set; }
}

Low/Medium/High with bool-based providers (Mistral)

None => disable
Low/Medium/High => enable

Default Value

If ChatOptions.Reasoning is null, the provider's default is used:

  • Claude: high
  • Gemini: dynamic thinking
  • Mistral: true
  • OpenAI: medium

API Usage

ChatResponse response = await chatClient.GetResponseAsync("Hi", new ChatOptions
{
    Reasoning = Reasoning.Medium,
});

Alternative Designs

Reasoning.FromBudget(int budget)

Mapping a budget to an enum (for OpenAI) is tricky. With Claude and Gemini moving to enums, I don't think we need to deal with budgets. This greatly simplify things.

Additional Property

Use an additional property. Though, my goal is to be able to use reasoning with all providers so I would rather add it to ChatOptions.

Risks

No response</issue_description>

<agent_instructions>Create a design something like this:

public sealed class ReasoningOptions
{
public ReasoningEffort? Effort { get; set; }
public ReasoningOutput? Output { get; set; }
}

public enum ReasoningEffort
{
    None = 0,
    Low = 1,
    Medium = 2,
    High = 3,
    ExtraHigh = 4,
}

public enum ReasoningOutput
{
    None = 0,
    Summary = 1,
    Detailed = 2,
}

public sealed partial class ChatOptions
{
    public ReasoningOptions? Reasoning { get; set; }
}

Update the abstractions and tests and ensure it's fully implemted as much as possible in the openai implementations, ignoring anything that can't be mapped (it's best effort) </agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Microsoft Reviewers: Open in CodeFlow

Copilot AI changed the title [WIP] Add reasoning configuration to ChatOptions Add ReasoningOptions to ChatOptions Feb 2, 2026
Copilot AI requested a review from stephentoub February 2, 2026 00:12
@stephentoub
Copy link
Member

@copilot

…nal, simplify ToOpenAIChatReasoningEffortLevel

Co-authored-by: stephentoub <[email protected]>
Copilot AI requested a review from stephentoub February 2, 2026 13:58
@stephentoub stephentoub marked this pull request as ready for review February 2, 2026 14:03
@stephentoub stephentoub requested a review from a team as a code owner February 2, 2026 14:03
@stephentoub
Copy link
Member

cc: @PederHP

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds reasoning configuration options to the ChatOptions class, enabling developers to control how much computational effort AI models should apply when generating responses and how reasoning content should be included.

Changes:

  • Introduced ReasoningEffort enum (None, Low, Medium, High, ExtraHigh) and ReasoningOutput enum (None, Summary, Detailed) to the abstractions layer
  • Added ReasoningOptions class with Effort and Output properties, plus internal Clone() method for copy semantics
  • Integrated reasoning options into ChatOptions with proper cloning support in the copy constructor
  • Implemented OpenAI-specific mappings in both OpenAIChatClient (reasoning effort only) and OpenAIResponsesChatClient (both effort and output)
  • Added comprehensive test coverage including unit tests, JSON serialization tests, and integration tests that verify expected JSON output

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ReasoningEffort.cs New enum defining reasoning effort levels (None, Low, Medium, High, ExtraHigh)
src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ReasoningOutput.cs New enum defining reasoning output modes (None, Summary, Detailed)
src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ReasoningOptions.cs New sealed class containing reasoning configuration with internal Clone() method
src/Libraries/Microsoft.Extensions.AI.Abstractions/ChatCompletion/ChatOptions.cs Added Reasoning property and clone logic in copy constructor
src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIChatClient.cs Maps ReasoningEffort to OpenAI ChatReasoningEffortLevel (ExtraHigh maps to High)
src/Libraries/Microsoft.Extensions.AI.OpenAI/OpenAIResponsesChatClient.cs Maps both ReasoningEffort and ReasoningOutput to OpenAI Response API types
src/Libraries/Microsoft.Extensions.AI.Abstractions/Microsoft.Extensions.AI.Abstractions.json API baseline manifest updated with new stable APIs
test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ReasoningOptionsTests.cs Comprehensive unit tests for ReasoningOptions including JSON serialization
test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/ChatCompletion/ChatOptionsTests.cs Updated tests to verify Reasoning property and cloning behavior
test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIChatClientTests.cs Tests verifying correct JSON generation for reasoning effort in Chat API
test/Libraries/Microsoft.Extensions.AI.OpenAI.Tests/OpenAIResponseClientTests.cs Tests verifying correct JSON generation for reasoning effort and output in Response API
test/Libraries/Microsoft.Extensions.AI.Abstractions.Tests/TestJsonSerializerContext.cs Added JSON serialization support for new types

ptr727 added a commit to ptr727/LanguageTags that referenced this pull request Feb 12, 2026
Updated [csharpier](https://github.com/belav/csharpier) from 1.2.5 to
1.2.6.

<details>
<summary>Release notes</summary>

_Sourced from [csharpier's
releases](https://github.com/belav/csharpier/releases)._

## 1.2.6

## What's Changed
### [Bug]: XML with DOCTYPE results in "invalid xml" warning
[#​1809](belav/csharpier#1809)
CSharpier was not formatting xml that included a doctype and instead
reporting that it was invalid xml.
```xml
<?xml version="1.0"?>
<!DOCTYPE staff SYSTEM "staff.dtd"[
    <!ENTITY ent1 "es">
]>
<staff></staff>
```
### [Bug]: Initializing a span using `stackalloc` leads to different
formatting compared to `new`
[#​1808](belav/csharpier#1808)
When initializing a spacn using stackalloc, it was not being formatting
consistently with other code
```c#
// input & expected output
Span<int> metatable = new int[]
{
    00000000000000000000000001,
    00000000000000000000000002,
    00000000000000000000000003,
};

Span<int> metatable = stackalloc int[]
{
    00000000000000000000000001,
    00000000000000000000000002,
    00000000000000000000000003,
};

// 1.2.5
Span<int> metatable = new int[]
{
    00000000000000000000000001,
    00000000000000000000000002,
    00000000000000000000000003,
};

Span<int> metatable =
    stackalloc int[] {
        00000000000000000000000001,
        00000000000000000000000002,
        00000000000000000000000003,
    };

```
### [Bug]: Comments in otherwise empty object pattern disappear when
formatting [#​1804](belav/csharpier#1804)
CSharpier was removing comments if they were the only content of an
object pattern.
```c#
// input & expected output
var match = obj is {
    //Property: 123
 ... (truncated)

Commits viewable in [compare view](belav/csharpier@1.2.5...1.2.6).
</details>

Updated [Microsoft.Extensions.Http.Resilience](https://github.com/dotnet/extensions) from 10.2.0 to 10.3.0.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.Extensions.Http.Resilience's releases](https://github.com/dotnet/extensions/releases)._

## 10.3.0

## What's Changed
* Bump version to 10.3.0 for next development cycle by @​Copilot in dotnet/extensions#7197
* Fix race condition in UnreliableL2Tests.WriteFailureInvisible by @​Copilot in dotnet/extensions#7075
* Set Microsoft.McpServer.ProjectTemplates version to align with MCP packages by @​jeffhandley in dotnet/extensions#7170
* ToChatResponse: Merge AdditionalProperties into ChatMessage instead of ChatResponse by @​Copilot in dotnet/extensions#7194
* Fix NRT resolution for AIFunction parameters. by @​eiriktsarpalis in dotnet/extensions#7200
* Bump mdast-util-to-hast from 13.2.0 to 13.2.1 in /src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript by @​dependabot[bot] in dotnet/extensions#7198
* Add .npmrc next to package.json and add lockfile for PublishAIEvaluationReport by @​akoeplinger in dotnet/extensions#7108
* Bump qs from 6.14.0 to 6.14.1 in /src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript by @​dependabot[bot] in dotnet/extensions#7189
* Bump js-yaml from 4.1.0 to 4.1.1 in /src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript by @​dependabot[bot] in dotnet/extensions#7054
* Bump validator from 13.15.20 to 13.15.23 in /src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript by @​dependabot[bot] in dotnet/extensions#7103
* Update AI changelogs by @​stephentoub in dotnet/extensions#7206
* Merge changes from internal after 10.2 release by @​joperezr in dotnet/extensions#7205
* Merge changes from release/10.2 to main by @​joperezr in dotnet/extensions#7209
* Categorize MEAI001 experimental APIs by @​Copilot in dotnet/extensions#7116
* [main] Update dependencies from dotnet/arcade by @​dotnet-maestro[bot] in dotnet/extensions#7212
* Update Package Validation Baseline to 10.2.0 by @​Copilot in dotnet/extensions#7208
* Enable package validation for M.E.AmbientMetadata.Build by @​evgenyfedorov2 in dotnet/extensions#7213
* [5752] FakeLogCollector waiting capabilities by @​Demo30 in dotnet/extensions#6228
* Set network isolation policy for extensions-ci by @​wtgodbe in dotnet/extensions#7221
* Fix FunctionInvokingChatClient invoke_agent span detection with exact match or space delimiter by @​Copilot in dotnet/extensions#7224
* Add Ordinal into ordering by @​cincuranet in dotnet/extensions#7225
* Remove AIFunctionDeclaration tools on last iteration in FunctionInvokingChatClient by @​Copilot in dotnet/extensions#7207
* Remove unnecessary description tags by @​gewarren in dotnet/extensions#7226
* Fix FunctionInvokingChatClient to respect ChatOptions.Tools modifications by function tools by @​Copilot in dotnet/extensions#7218
* Add LoadFromAsync and SaveToAsync helper methods to DataContent by @​Copilot in dotnet/extensions#7159
* Bump lodash from 4.17.21 to 4.17.23 in /src/Libraries/Microsoft.Extensions.AI.Evaluation.Reporting/TypeScript by @​dependabot[bot] in dotnet/extensions#7227
* Add logging to FunctionInvokingChatClient for approval flow, error handling, and loop control by @​Copilot in dotnet/extensions#7228
* [main] Update dependencies from dotnet/arcade by @​dotnet-maestro[bot] in dotnet/extensions#7230
* Allow FunctionResultContent pass-through when CallId matches by @​Copilot in dotnet/extensions#7229
* Propagate CachedInputTokenCount in OpenTelemetry telemetry by @​Copilot in dotnet/extensions#7234
* Add InvocationRequired property to FunctionCallContent by @​Copilot in dotnet/extensions#7126
* Escape the JSON data before embedding in Evaluation reports by @​peterwald in dotnet/extensions#7238
* Update mcpserver template to ModelContextProtocol 0.7.0-preview.1 by @​Copilot in dotnet/extensions#7236
* Update aiagent-webapi template to Agent Framework 1.0.0-preview.260127.1 by @​Copilot in dotnet/extensions#7237
* Fix token metric unit to use UCUM format {token} by @​stephentoub in dotnet/extensions#7241
* Add server tool call support to OpenTelemetryChatClient per semantic conventions by @​Copilot in dotnet/extensions#7240
* Preserve extra JSON schema properties in ToolJson serialization by @​Copilot in dotnet/extensions#7250
* Bring new cpu.requests formula from Kubernetes by @​amadeuszl in dotnet/extensions#7239
* Update M.E.AI changelogs with recent changes by @​stephentoub in dotnet/extensions#7242
* Fix DataUriParser to default to text/plain;charset=US-ASCII per RFC 2397 by @​Copilot in dotnet/extensions#7247
* Fix deadlock in ServiceEndpointWatcher when disposing change token registration by @​ReubenBond in dotnet/extensions#7255
* Rename FunctionCallContent.InvocationRequired to InformationalOnly with inverted polarity by @​Copilot in dotnet/extensions#7262
* Fix approval request/response correlation in FunctionInvokingChatClient by @​Copilot in dotnet/extensions#7261
* Add ReasoningOptions to ChatOptions by @​Copilot in dotnet/extensions#7252

## New Contributors
* @​cincuranet made their first contribution in dotnet/extensions#7225
* @​ReubenBond made their first contribution in dotnet/extensions#7255

 ... (truncated)

Commits viewable in [compare view](dotnet/extensions@v10.2.0...v10.3.0).
</details>

Updated [Microsoft.Extensions.Logging.Abstractions](https://github.com/dotnet/dotnet) from 10.0.2 to 10.0.3.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.Extensions.Logging.Abstractions's releases](https://github.com/dotnet/dotnet/releases)._

## 10.0.3

[Release](https://github.com/dotnet/core/releases/tag/v10.0.3)

Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits/v10.0.3).
</details>

Updated [Microsoft.SourceLink.GitHub](https://github.com/dotnet/dotnet) from 10.0.102 to 10.0.103.

<details>
<summary>Release notes</summary>

_Sourced from [Microsoft.SourceLink.GitHub's releases](https://github.com/dotnet/dotnet/releases)._

## 10.0.103

You can build .NET 10.0 from the repository by cloning the release tag `v10.0.103` and following the build instructions in the [main README.md](https://github.com/dotnet/dotnet/blob/v10.0.103/README.md#building).

Alternatively, you can build from the sources attached to this release directly.
More information on this process can be found in the [dotnet/dotnet repository](https://github.com/dotnet/dotnet/blob/v10.0.103/README.md#building-from-released-sources).

Attached is the PGP signature for the GitHub generated tarball. You can find the public key at https://dot.net/release-key-2023

Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits/v10.0.103).
</details>

Updated [Serilog](https://github.com/serilog/serilog) from 4.3.0 to 4.3.1.

<details>
<summary>Release notes</summary>

_Sourced from [Serilog's releases](https://github.com/serilog/serilog/releases)._

## 4.3.1

## What's Changed
* Remove SourceLink by @​SimonCropp in serilog/serilog#2183
* Handle Exception.ToString failures in text formatter by @​krisbiradar in serilog/serilog#2197
* Remove char[] allocation by @​karpinsn in serilog/serilog#2198
* Remove backpressure from XMLDoc by @​timothycoleman in serilog/serilog#2203
* Don't enable XDOC for tests by @​nblumhardt in serilog/serilog#2205
* Target and test on net10 by @​SimonCropp in serilog/serilog#2206
* Fix trimming error when Serilog is a transitive dependency by @​Numpsy in serilog/serilog#2214
* Inline TraceId and SpanId JSON string formatting by @​SimonCropp in serilog/serilog#2215

## New Contributors
* @​krisbiradar made their first contribution in serilog/serilog#2197
* @​karpinsn made their first contribution in serilog/serilog#2198
* @​timothycoleman made their first contribution in serilog/serilog#2203
* @​Numpsy made their first contribution in serilog/serilog#2214

**Full Changelog**: serilog/serilog@v4.3.0...v4.3.1

Commits viewable in [compare view](serilog/serilog@v4.3.0...v4.3.1).
</details>

Updated [System.CommandLine](https://github.com/dotnet/dotnet) from 2.0.2 to 2.0.3.

<details>
<summary>Release notes</summary>

_Sourced from [System.CommandLine's releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare view](https://github.com/dotnet/dotnet/commits).
</details>

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions


</details>

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Pieter Viljoen <[email protected]>
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.

[API Proposal]: ChatOptions Reasoning

3 participants