Skip to content

Commit c1c6a52

Browse files
committed
Add support for GPT-5 minimal reasoning effort
See announcement at https://cookbook.openai.com/examples/gpt-5/gpt-5_new_params_and_tools
1 parent ac09982 commit c1c6a52

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

src/AI.Tests/OpenAITests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,43 @@ public async Task OpenAIThinks()
8282
});
8383
}
8484

85+
[SecretsFact("OPENAI_API_KEY")]
86+
public async Task GPT5_ThinksFast()
87+
{
88+
var messages = new Chat()
89+
{
90+
{ "system", "You are an intelligent AI assistant that's an expert on financial matters." },
91+
{ "user", "If you have a debt of 100k and accumulate a compounding 5% debt on top of it every year, how long before you are a negative millonaire? (round up to full integer value)" },
92+
};
93+
94+
var requests = new List<JsonNode>();
95+
96+
var chat = new OpenAIChatClient(Configuration["OPENAI_API_KEY"]!, "gpt-5-nano",
97+
OpenAIClientOptions.Observable(requests.Add).WriteTo(output));
98+
99+
var options = new ChatOptions
100+
{
101+
ModelId = "gpt-5",
102+
ReasoningEffort = ReasoningEffort.Minimal
103+
};
104+
105+
var response = await chat.GetResponseAsync(messages, options);
106+
107+
var text = response.Text;
108+
109+
Assert.Contains("48 years", text);
110+
// NOTE: the chat client was requested as grok-3 but the chat options wanted a
111+
// different model and the grok client honors that choice.
112+
Assert.StartsWith("gpt-5", response.ModelId);
113+
Assert.DoesNotContain("nano", response.ModelId);
114+
115+
// Reasoning should have been set to medium
116+
Assert.All(requests, x =>
117+
{
118+
var search = Assert.IsType<JsonObject>(x["reasoning"]);
119+
Assert.Equal("minimal", search["effort"]?.GetValue<string>());
120+
});
121+
}
85122
[SecretsFact("OPENAI_API_KEY")]
86123
public async Task WebSearchCountryHighContext()
87124
{

src/AI/OpenAI/OpenAIChatClient.cs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.ClientModel;
22
using System.ClientModel.Primitives;
33
using System.Collections.Concurrent;
4+
using System.Text.Json;
45
using Microsoft.Extensions.AI;
56
using OpenAI;
67
using OpenAI.Responses;
@@ -50,15 +51,18 @@ IChatClient GetChatClient(string modelId) => clients.GetOrAdd(modelId, model
5051
{
5152
options.RawRepresentationFactory = _ => new ResponseCreationOptions
5253
{
53-
ReasoningOptions = new ResponseReasoningOptions()
54-
{
55-
ReasoningEffortLevel = effort switch
56-
{
57-
ReasoningEffort.High => ResponseReasoningEffortLevel.High,
58-
ReasoningEffort.Medium => ResponseReasoningEffortLevel.Medium,
59-
_ => ResponseReasoningEffortLevel.Low
60-
},
61-
}
54+
ReasoningOptions = new ReasoningEffortOptions(effort)
55+
//ReasoningOptions = new ResponseReasoningOptions()
56+
//{
57+
// ReasoningEffortLevel = effort switch
58+
// {
59+
// ReasoningEffort.High => ResponseReasoningEffortLevel.High,
60+
// ReasoningEffort.Medium => ResponseReasoningEffortLevel.Medium,
61+
// // TODO: not exposed yet in the OpenAI package
62+
// // ReasoningEffort.Minimal => ResponseReasoningEffortLevel.Minimal,
63+
// _ => ResponseReasoningEffortLevel.Low
64+
// },
65+
//}
6266
};
6367
}
6468

@@ -71,4 +75,14 @@ IChatClient GetChatClient(string modelId) => clients.GetOrAdd(modelId, model
7175

7276
// Allows creating the base OpenAIClient with a pre-created pipeline.
7377
class PipelineClient(ClientPipeline pipeline, OpenAIClientOptions? options) : OpenAIClient(pipeline, options) { }
78+
79+
class ReasoningEffortOptions(ReasoningEffort effort) : ResponseReasoningOptions
80+
{
81+
protected override void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
82+
{
83+
writer.WritePropertyName("effort"u8);
84+
writer.WriteStringValue(effort.ToString().ToLowerInvariant());
85+
base.JsonModelWriteCore(writer, options);
86+
}
87+
}
7488
}

src/AI/ReasoningEffort.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
/// </summary>
66
public enum ReasoningEffort
77
{
8+
/// <summary>
9+
/// Minimal reasoning effort, which may result in faster responses. Support depends on the model.
10+
/// </summary>
11+
Minimal,
812
/// <summary>
913
/// Low effort reasoning, which may result in faster responses but less detailed or accurate answers.
1014
/// </summary>

0 commit comments

Comments
 (0)