.Net: Update Microsoft.Extensions.AI dependencies to 10.3.0 and OpenAI SDK to 2.8.0 (#13544)

### Motivation and Context

Updates Microsoft.Extensions.AI packages to latest stable releases
(10.3.0) and OpenAI SDK to 2.8.0. The new versions require transitive
dependency updates and fixing breaking type renames in the OpenAI
Responses API. Additionally, the new `ChatOptions.Reasoning` property is
now mapped from `PromptExecutionSettings` and used in samples instead of
`RawRepresentationFactory`.

### Description

**Package Updates:**
- `Microsoft.Extensions.AI` and `Microsoft.Extensions.AI.Abstractions`:
10.2.0 → 10.3.0
- `Microsoft.Extensions.AI.OpenAI`: 10.0.1-preview → 10.3.0 (stable)
- `OpenAI`: 2.7.0 → 2.8.0
- `Azure.AI.OpenAI`: 2.7.0-beta.2 → 2.8.0-beta.1
- Transitive dependencies → 10.0.3:
  - `System.Text.Json`
  - `System.Numerics.Tensors`
  - `Microsoft.Extensions.Logging.Abstractions`
  - `Microsoft.Bcl.AsyncInterfaces`
  - `System.Threading.Channels`

**OpenAI 2.8.0 Breaking Changes Fixed (~23 files):**
- `OpenAIResponseClient` → `ResponsesClient`
- `ResponseCreationOptions` → `CreateResponseOptions`
- `OpenAIResponse` → `ResponseResult`
- `GetOpenAIResponseClient()` → `GetResponsesClient()`
- API: Input items now passed via `CreateResponseOptions.InputItems`
instead of separate parameter
- API: `StreamingEnabled = true` required for streaming calls
- `OpenAIResponsesModelFactory` removed → using public constructors in
tests

**ChatOptions.Reasoning Mapping:**
- Added `reasoning_effort` → `ChatOptions.Reasoning.Effort` mapping in
`PromptExecutionSettingsExtensions.ToChatOptions`, supporting `low`,
`medium`, `high`, and `xhigh` (→ ExtraHigh) effort levels per OpenAI API
documentation
- Replaced `RawRepresentationFactory` with `ChatOptions.Reasoning` in
the OpenAI and AzureOpenAI Step02_ReasoningModel sample files
- Updated migration documentation in
`.github/upgrades/prompts/SemanticKernelToAgentFramework.md` to use
`TruncationMode` as the provider-specific options example (since
reasoning now has a direct `ChatOptions` equivalent)

### Contribution Checklist

- [x] The code builds clean without any errors or warnings
- [x] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [x] All unit tests pass, and I have added new tests where possible
- [x] I didn't break anyone 😄

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: stephentoub <[email protected]>
Co-authored-by: Roger Barreto <[email protected]>
Co-authored-by: Copilot <[email protected]>
This commit is contained in:
Copilot
2026-02-25 12:10:01 +00:00
committed by GitHub
co-authored by stephentoub Roger Barreto Copilot
parent c086d09442
commit 889807dfda
27 changed files with 160 additions and 160 deletions
@@ -870,20 +870,16 @@ var agentOptions = new ChatClientAgentRunOptions(new ChatOptions
{
MaxOutputTokens = 8000,
// Breaking glass to access provider-specific options
RawRepresentationFactory = (_) => new OpenAI.Responses.ResponseCreationOptions()
RawRepresentationFactory = (_) => new OpenAI.Responses.CreateResponseOptions()
{
ReasoningOptions = new()
{
ReasoningEffortLevel = OpenAI.Responses.ResponseReasoningEffortLevel.High,
ReasoningSummaryVerbosity = OpenAI.Responses.ResponseReasoningSummaryVerbosity.Detailed
}
TruncationMode = OpenAI.Responses.ResponseTruncationMode.Auto,
}
});
```
**Use this pattern when:**
1. Standard `ChatOptions` properties don't cover required model settings
2. Provider-specific configuration is needed (e.g., reasoning effort level)
2. Provider-specific configuration is needed (e.g., truncation mode)
3. Advanced SDK features need to be accessed
</configuration_changes>
+11 -11
View File
@@ -22,7 +22,7 @@
<PackageVersion Include="AWSSDK.SecurityToken" Version="4.0.5.6" />
<PackageVersion Include="Azure.AI.Agents.Persistent" Version="1.1.0" />
<PackageVersion Include="Azure.AI.ContentSafety" Version="1.0.0" />
<PackageVersion Include="Azure.AI.OpenAI" Version="2.7.0-beta.2" />
<PackageVersion Include="Azure.AI.OpenAI" Version="2.8.0-beta.1" />
<PackageVersion Include="Azure.AI.Projects" Version="1.1.0" />
<PackageVersion Include="Azure.Identity" Version="1.17.1" />
<PackageVersion Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.5.0" />
@@ -65,7 +65,7 @@
<PackageVersion Include="Microsoft.Azure.Kusto.Data" Version="12.2.8" />
<PackageVersion Include="Microsoft.Azure.WebJobs.Extensions.OpenApi" Version="1.5.1" />
<PackageVersion Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="5.3.2" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.2" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.3" />
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
<PackageVersion Include="Microsoft.Bcl.Memory" Version="10.0.2" />
<PackageVersion Include="Microsoft.Bcl.Numerics" Version="10.0.2" />
@@ -92,7 +92,7 @@
<PackageVersion Include="Npgsql" Version="8.0.7" />
<PackageVersion Include="OData2Linq" Version="2.2.0" />
<PackageVersion Include="OllamaSharp" Version="5.4.12" />
<PackageVersion Include="OpenAI" Version="2.7.0" />
<PackageVersion Include="OpenAI" Version="2.8.0" />
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.14.0" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.14.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.14.0" />
@@ -109,8 +109,8 @@
<PackageVersion Include="System.Linq.AsyncEnumerable" Version="10.0.2" />
<PackageVersion Include="System.Memory.Data" Version="10.0.2" />
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
<PackageVersion Include="System.Numerics.Tensors" Version="10.0.2" />
<PackageVersion Include="System.Text.Json" Version="10.0.2" />
<PackageVersion Include="System.Numerics.Tensors" Version="10.0.3" />
<PackageVersion Include="System.Text.Json" Version="10.0.3" />
<PackageVersion Include="System.ValueTuple" Version="4.6.1" />
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.6.3" />
<PackageVersion Include="A2A" Version="0.3.1-preview" />
@@ -119,10 +119,10 @@
<!-- Tokenizers -->
<PackageVersion Include="Microsoft.ML.Tokenizers" Version="2.0.0" />
<!-- Microsoft.Extensions.* -->
<PackageVersion Include="Microsoft.Extensions.AI" Version="10.2.0" />
<PackageVersion Include="Microsoft.Extensions.AI.Abstractions" Version="10.2.0" />
<PackageVersion Include="Microsoft.Extensions.AI" Version="10.3.0" />
<PackageVersion Include="Microsoft.Extensions.AI.Abstractions" Version="10.3.0" />
<PackageVersion Include="Microsoft.Extensions.AI.AzureAIInference" Version="10.0.0-preview.1.25559.3" />
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="10.0.1-preview.1.25571.5" />
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="10.3.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.2" />
@@ -131,14 +131,14 @@
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.Testing" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="10.2.0" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="10.2.0" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Logging.Debug" Version="10.0.2" />
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="10.0.2" />
@@ -151,7 +151,7 @@
<PackageVersion Include="Moq" Version="[4.18.4]" />
<PackageVersion Include="FluentAssertions" Version="8.2.0" />
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageVersion Include="System.Threading.Channels" Version="10.0.2" />
<PackageVersion Include="System.Threading.Channels" Version="10.0.3" />
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="10.0.2" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.abstractions" Version="2.0.3" />
@@ -24,7 +24,7 @@ async Task SKAgentAsync()
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName);
.GetResponsesClient(deploymentName);
OpenAIResponseAgent agent = new(responseClient)
{
Name = "Joker",
@@ -54,7 +54,7 @@ async Task SKAgent_As_AFAgentAsync()
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var responseClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName);
.GetResponsesClient(deploymentName);
OpenAIResponseAgent skAgent = new(responseClient)
{
@@ -83,7 +83,7 @@ async Task AFAgentAsync()
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.GetResponsesClient(deploymentName)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes.");
var thread = agent.GetNewThread();
@@ -51,7 +51,7 @@ async Task SKAgentAsync()
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName);
.GetResponsesClient(deploymentName);
OpenAIResponseAgent agent = new(responseClient)
{
Name = "Thinker",
@@ -119,7 +119,7 @@ async Task SKAgent_As_AFAgentAsync()
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var responseClient = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName);
.GetResponsesClient(deploymentName);
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
@@ -138,15 +138,10 @@ async Task SKAgent_As_AFAgentAsync()
var agentOptions = new ChatClientAgentRunOptions(new()
{
MaxOutputTokens = 8000,
// Microsoft.Extensions.AI currently does not have an abstraction for reasoning-effort,
// we need to break glass using the RawRepresentationFactory.
RawRepresentationFactory = (_) => new OpenAI.Responses.ResponseCreationOptions()
Reasoning = new()
{
ReasoningOptions = new()
{
ReasoningEffortLevel = OpenAI.Responses.ResponseReasoningEffortLevel.High,
ReasoningSummaryVerbosity = OpenAI.Responses.ResponseReasoningSummaryVerbosity.Detailed
}
Effort = ReasoningEffort.High,
Output = ReasoningOutput.Full
}
});
@@ -185,22 +180,17 @@ async Task AFAgentAsync()
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.GetResponsesClient(deploymentName)
.CreateAIAgent(name: "Thinker", instructions: "You are good at thinking hard before answering.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new()
{
MaxOutputTokens = 8000,
// Microsoft.Extensions.AI currently does not have an abstraction for reasoning-effort,
// we need to break glass using the RawRepresentationFactory.
RawRepresentationFactory = (_) => new OpenAI.Responses.ResponseCreationOptions()
Reasoning = new()
{
ReasoningOptions = new()
{
ReasoningEffortLevel = OpenAI.Responses.ResponseReasoningEffortLevel.High,
ReasoningSummaryVerbosity = OpenAI.Responses.ResponseReasoningSummaryVerbosity.Detailed
}
Effort = ReasoningEffort.High,
Output = ReasoningOutput.Full
}
});
@@ -29,7 +29,7 @@ await AFAgentAsync();
async Task SKAgentAsync()
{
OpenAIResponseAgent agent = new(new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName))
.GetResponsesClient(deploymentName))
{ StoreEnabled = true };
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
@@ -49,7 +49,7 @@ async Task SKAgentAsync()
async Task SKAgent_As_AFAgentAsync()
{
OpenAIResponseAgent skAgent = new(new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName))
.GetResponsesClient(deploymentName))
{ StoreEnabled = true };
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
@@ -66,7 +66,7 @@ async Task SKAgent_As_AFAgentAsync()
async Task AFAgentAsync()
{
var agent = new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.GetResponsesClient(deploymentName)
.CreateAIAgent(instructions: "You are a helpful assistant", tools: [AIFunctionFactory.Create(GetWeather)]);
Console.WriteLine("\n=== AF Agent Response ===\n");
@@ -28,7 +28,7 @@ async Task SKAgentAsync()
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<Microsoft.SemanticKernel.Agents.Agent>((sp)
=> new OpenAIResponseAgent(new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName))
.GetResponsesClient(deploymentName))
{
Name = "Joker",
Instructions = "You are good at telling jokes.",
@@ -49,7 +49,7 @@ async Task SKAgent_As_AFAgentAsync()
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<Microsoft.SemanticKernel.Agents.Agent>((sp)
=> new OpenAIResponseAgent(new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName))
.GetResponsesClient(deploymentName))
{
Name = "Joker",
Instructions = "You are good at telling jokes.",
@@ -71,7 +71,7 @@ async Task AFAgentAsync()
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<AIAgent>((sp) => new AzureOpenAIClient(new Uri(endpoint), new AzureCliCredential())
.GetOpenAIResponseClient(deploymentName)
.GetResponsesClient(deploymentName)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes."));
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
@@ -21,7 +21,7 @@ async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new OpenAIClient(apiKey).GetOpenAIResponseClient(model);
var responseClient = new OpenAIClient(apiKey).GetResponsesClient(model);
OpenAIResponseAgent agent = new(responseClient)
{
Name = "Joker",
@@ -51,7 +51,7 @@ async Task SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var responseClient = new OpenAIClient(apiKey).GetOpenAIResponseClient(model);
var responseClient = new OpenAIClient(apiKey).GetResponsesClient(model);
OpenAIResponseAgent skAgent = new(responseClient)
{
@@ -79,7 +79,7 @@ async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new OpenAIClient(apiKey).GetOpenAIResponseClient(model)
var agent = new OpenAIClient(apiKey).GetResponsesClient(model)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes.");
var thread = agent.GetNewThread();
@@ -48,7 +48,7 @@ async Task SKAgentAsync()
{
Console.WriteLine("\n=== SK Agent ===\n");
var responseClient = new OpenAIClient(apiKey).GetOpenAIResponseClient(model);
var responseClient = new OpenAIClient(apiKey).GetResponsesClient(model);
OpenAIResponseAgent agent = new(responseClient)
{
Name = "Thinker",
@@ -116,7 +116,7 @@ async Task SKAgent_As_AFAgentAsync()
{
Console.WriteLine("\n=== SK Agent Converted as an AF Agent ===\n");
var responseClient = new OpenAIClient(apiKey).GetOpenAIResponseClient(model);
var responseClient = new OpenAIClient(apiKey).GetResponsesClient(model);
#pragma warning disable SKEXP0110 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
@@ -135,15 +135,10 @@ async Task SKAgent_As_AFAgentAsync()
var agentOptions = new ChatClientAgentRunOptions(new()
{
MaxOutputTokens = 8000,
// Microsoft.Extensions.AI currently does not have an abstraction for reasoning-effort,
// we need to break glass using the RawRepresentationFactory.
RawRepresentationFactory = (_) => new OpenAI.Responses.ResponseCreationOptions()
Reasoning = new()
{
ReasoningOptions = new()
{
ReasoningEffortLevel = OpenAI.Responses.ResponseReasoningEffortLevel.High,
ReasoningSummaryVerbosity = OpenAI.Responses.ResponseReasoningSummaryVerbosity.Detailed
}
Effort = ReasoningEffort.High,
Output = ReasoningOutput.Full
}
});
@@ -181,22 +176,17 @@ async Task AFAgentAsync()
{
Console.WriteLine("\n=== AF Agent ===\n");
var agent = new OpenAIClient(apiKey).GetOpenAIResponseClient(model)
var agent = new OpenAIClient(apiKey).GetResponsesClient(model)
.CreateAIAgent(name: "Thinker", instructions: "You are at thinking hard before answering.");
var thread = agent.GetNewThread();
var agentOptions = new ChatClientAgentRunOptions(new()
{
MaxOutputTokens = 8000,
// Microsoft.Extensions.AI currently does not have an abstraction for reasoning-effort,
// we need to break glass using the RawRepresentationFactory.
RawRepresentationFactory = (_) => new OpenAI.Responses.ResponseCreationOptions()
Reasoning = new()
{
ReasoningOptions = new()
{
ReasoningEffortLevel = OpenAI.Responses.ResponseReasoningEffortLevel.High,
ReasoningSummaryVerbosity = OpenAI.Responses.ResponseReasoningSummaryVerbosity.Detailed
}
Effort = ReasoningEffort.High,
Output = ReasoningOutput.Full
}
});
@@ -28,7 +28,7 @@ async Task SKAgentAsync()
{
var builder = Kernel.CreateBuilder().AddOpenAIChatClient(model, apiKey);
OpenAIResponseAgent agent = new(new OpenAIClient(apiKey).GetOpenAIResponseClient(model)) { StoreEnabled = true };
OpenAIResponseAgent agent = new(new OpenAIClient(apiKey).GetResponsesClient(model)) { StoreEnabled = true };
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
agent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
@@ -48,7 +48,7 @@ async Task SKAgent_As_AFAgentAsync()
{
var builder = Kernel.CreateBuilder().AddOpenAIChatClient(model, apiKey);
OpenAIResponseAgent skAgent = new(new OpenAIClient(apiKey).GetOpenAIResponseClient(model)) { StoreEnabled = true };
OpenAIResponseAgent skAgent = new(new OpenAIClient(apiKey).GetResponsesClient(model)) { StoreEnabled = true };
// Initialize plugin and add to the agent's Kernel (same as direct Kernel usage).
skAgent.Kernel.Plugins.Add(KernelPluginFactory.CreateFromFunctions("KernelPluginName", [KernelFunctionFactory.CreateFromMethod(GetWeather)]));
@@ -63,7 +63,7 @@ async Task SKAgent_As_AFAgentAsync()
async Task AFAgentAsync()
{
var agent = new OpenAIClient(apiKey).GetOpenAIResponseClient(model).CreateAIAgent(
var agent = new OpenAIClient(apiKey).GetResponsesClient(model).CreateAIAgent(
instructions: "You are a helpful assistant",
tools: [AIFunctionFactory.Create(GetWeather)]);
@@ -25,7 +25,7 @@ async Task SKAgentAsync()
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<Microsoft.SemanticKernel.Agents.Agent>((sp)
=> new OpenAIResponseAgent(new OpenAIClient(apiKey).GetOpenAIResponseClient(model))
=> new OpenAIResponseAgent(new OpenAIClient(apiKey).GetResponsesClient(model))
{
Name = "Joker",
Instructions = "You are good at telling jokes."
@@ -44,7 +44,7 @@ async Task SKAgent_As_AFAgentAsync()
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<Microsoft.SemanticKernel.Agents.Agent>((sp)
=> new OpenAIResponseAgent(new OpenAIClient(apiKey).GetOpenAIResponseClient(model))
=> new OpenAIResponseAgent(new OpenAIClient(apiKey).GetResponsesClient(model))
{
Name = "Joker",
Instructions = "You are good at telling jokes."
@@ -65,7 +65,7 @@ async Task AFAgentAsync()
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient((sp) => new OpenAIClient(apiKey)
.GetOpenAIResponseClient(model)
.GetResponsesClient(model)
.CreateAIAgent(name: "Joker", instructions: "You are good at telling jokes."));
await using ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
@@ -59,7 +59,7 @@ public class Step04_OpenAIResponseAgent_Tools(ITestOutputHelper output) : BaseRe
};
// ResponseCreationOptions allows you to specify tools for the agent.
ResponseCreationOptions creationOptions = new();
CreateResponseOptions creationOptions = new();
creationOptions.Tools.Add(ResponseTool.CreateWebSearchTool());
OpenAIResponseAgentInvokeOptions invokeOptions = new()
{
@@ -95,7 +95,7 @@ public class Step04_OpenAIResponseAgent_Tools(ITestOutputHelper output) : BaseRe
};
// ResponseCreationOptions allows you to specify tools for the agent.
ResponseCreationOptions creationOptions = new();
CreateResponseOptions creationOptions = new();
creationOptions.Tools.Add(ResponseTool.CreateFileSearchTool([createStoreOp.Value.Id], null));
OpenAIResponseAgentInvokeOptions invokeOptions = new()
{
@@ -151,7 +151,7 @@ public class Step04_OpenAIResponseAgent_Tools(ITestOutputHelper output) : BaseRe
}
// ResponseCreationOptions allows you to specify tools for the agent.
ResponseCreationOptions creationOptions = new();
CreateResponseOptions creationOptions = new();
creationOptions.Tools.Add(ResponseTool.CreateWebSearchTool());
OpenAIResponseAgentInvokeOptions invokeOptions = new()
{
@@ -12,11 +12,11 @@ namespace Microsoft.SemanticKernel.Agents.OpenAI;
internal static class OpenAIResponseExtensions
{
/// <summary>
/// Converts a <see cref="OpenAIResponse"/> instance to a <see cref="ChatMessageContent"/>.
/// Converts a <see cref="ResponseResult"/> instance to a <see cref="ChatMessageContent"/>.
/// </summary>
/// <param name="response">The response to convert.</param>
/// <returns>A <see cref="ChatMessageContent"/> instance.</returns>
public static ChatMessageContent ToChatMessageContent(this OpenAIResponse response)
public static ChatMessageContent ToChatMessageContent(this ResponseResult response)
{
var messageItem = response.OutputItems
.FirstOrDefault(item => item is MessageResponseItem);
@@ -7,21 +7,21 @@ using OpenAI.Responses;
namespace Microsoft.SemanticKernel.Agents.OpenAI.Internal;
/// <summary>
/// Factory for creating instances of <see cref="ResponseCreationOptions"/>.
/// Factory for creating instances of <see cref="CreateResponseOptions"/>.
/// </summary>
internal static class ResponseCreationOptionsFactory
{
internal static ResponseCreationOptions CreateOptions(
internal static CreateResponseOptions CreateOptions(
OpenAIResponseAgent agent,
AgentThread agentThread,
AgentInvokeOptions? invokeOptions)
{
var instructions = $"{agent.Instructions}{(string.IsNullOrEmpty(agent.Instructions) || string.IsNullOrEmpty(invokeOptions?.AdditionalInstructions) ? "" : "\n")}{invokeOptions?.AdditionalInstructions}";
ResponseCreationOptions creationOptions;
CreateResponseOptions creationOptions;
if (invokeOptions is OpenAIResponseAgentInvokeOptions responseAgentInvokeOptions &&
responseAgentInvokeOptions.ResponseCreationOptions is not null)
{
creationOptions = new ResponseCreationOptions
creationOptions = new CreateResponseOptions
{
EndUserId = responseAgentInvokeOptions.ResponseCreationOptions.EndUserId ?? agent.GetDisplayName(),
Instructions = responseAgentInvokeOptions.ResponseCreationOptions.Instructions ?? instructions,
@@ -42,7 +42,7 @@ internal static class ResponseCreationOptionsFactory
}
else
{
creationOptions = new ResponseCreationOptions
creationOptions = new CreateResponseOptions
{
EndUserId = agent.GetDisplayName(),
Instructions = instructions,
@@ -45,7 +45,9 @@ internal static class ResponseThreadActions
for (int requestIndex = 0; ; requestIndex++)
{
// Create a response using the OpenAI Responses API
var clientResult = await agent.Client.CreateResponseAsync(inputItems, creationOptions, cancellationToken).ConfigureAwait(false);
creationOptions.InputItems.Clear();
foreach (var item in inputItems) { creationOptions.InputItems.Add(item); }
var clientResult = await agent.Client.CreateResponseAsync(creationOptions, cancellationToken).ConfigureAwait(false);
var response = clientResult.Value;
ThrowIfIncompleteOrFailed(agent, response);
@@ -139,7 +141,7 @@ internal static class ResponseThreadActions
ChatMessageContent? message = null;
for (int requestIndex = 0; ; requestIndex++)
{
// Make the call to the OpenAIResponseClient and process the streaming results.
// Make the call to the ResponsesClient and process the streaming results.
DateTimeOffset? createdAt = null;
string? responseId = null;
string? modelId = null;
@@ -147,8 +149,11 @@ internal static class ResponseThreadActions
Dictionary<int, MessageResponseItem> outputIndexToMessages = [];
Dictionary<int, FunctionCallInfo>? functionCallInfos = null;
StreamingFunctionCallUpdateContent? functionCallUpdateContent = null;
OpenAIResponse? response = null;
await foreach (var streamingUpdate in agent.Client.CreateResponseStreamingAsync(inputItems, creationOptions, cancellationToken).ConfigureAwait(false))
ResponseResult? response = null;
creationOptions.InputItems.Clear();
foreach (var item in inputItems) { creationOptions.InputItems.Add(item); }
creationOptions.StreamingEnabled = true;
await foreach (var streamingUpdate in agent.Client.CreateResponseStreamingAsync(creationOptions, cancellationToken).ConfigureAwait(false))
{
switch (streamingUpdate)
{
@@ -304,7 +309,7 @@ internal static class ResponseThreadActions
throw new InvalidOperationException("The agent thread is not a ChatHistoryAgentThread.");
}
private static void ThrowIfIncompleteOrFailed(OpenAIResponseAgent agent, OpenAIResponse response)
private static void ThrowIfIncompleteOrFailed(OpenAIResponseAgent agent, ResponseResult response)
{
if (response.Status is ResponseStatus.Incomplete or ResponseStatus.Failed)
{
@@ -22,7 +22,7 @@ public sealed class OpenAIResponseAgent : Agent
/// Initializes a new instance of the <see cref="OpenAIResponseAgent"/> class.
/// </summary>
/// <param name="client">The OpenAI provider for accessing the Responses API service.</param>
public OpenAIResponseAgent(OpenAIResponseClient client)
public OpenAIResponseAgent(ResponsesClient client)
{
Verify.NotNull(client);
@@ -32,7 +32,7 @@ public sealed class OpenAIResponseAgent : Agent
/// <summary>
/// Expose client for additional use.
/// </summary>
public OpenAIResponseClient Client { get; }
public ResponsesClient Client { get; }
/// <summary>
/// Storing of messages is enabled.
@@ -46,5 +46,5 @@ public sealed class OpenAIResponseAgentInvokeOptions : AgentInvokeOptions
/// <summary>
/// Gets or initializes the options used for creating a response.
/// </summary>
public ResponseCreationOptions? ResponseCreationOptions { get; set; }
public CreateResponseOptions? ResponseCreationOptions { get; set; }
}
@@ -14,14 +14,14 @@ namespace Microsoft.SemanticKernel.Agents.OpenAI;
/// </summary>
public sealed class OpenAIResponseAgentThread : AgentThread
{
private readonly OpenAIResponseClient _client;
private readonly ResponsesClient _client;
private bool _isDeleted = false;
/// <summary>
/// Initializes a new instance of the <see cref="OpenAIResponseAgentThread"/> class.
/// </summary>
/// <param name="client">The agents client to use for interacting with responses.</param>
public OpenAIResponseAgentThread(OpenAIResponseClient client)
public OpenAIResponseAgentThread(ResponsesClient client)
{
Verify.NotNull(client);
@@ -33,7 +33,7 @@ public sealed class OpenAIResponseAgentThread : AgentThread
/// </summary>
/// <param name="client">The agents client to use for interacting with responses.</param>
/// <param name="responseId">The ID of an existing response to resume.</param>
public OpenAIResponseAgentThread(OpenAIResponseClient client, string responseId)
public OpenAIResponseAgentThread(ResponsesClient client, string responseId)
{
Verify.NotNull(client);
Verify.NotNull(responseId);
@@ -108,7 +108,7 @@ public sealed class OpenAIResponseAgentThread : AgentThread
if (!string.IsNullOrEmpty(this.ResponseId))
{
var collectionResult = this._client.GetResponseInputItemsAsync(this.ResponseId, default, cancellationToken).ConfigureAwait(false);
var collectionResult = this._client.GetResponseInputItemsAsync(this.ResponseId, cancellationToken).ConfigureAwait(false);
await foreach (var responseItem in collectionResult)
{
var messageContent = responseItem.ToChatMessageContent();
@@ -10,13 +10,13 @@ using OpenAI.Responses;
namespace SemanticKernel.Agents.UnitTests.OpenAI;
/// <summary>
/// Base tests which use <see cref="OpenAIResponseClient"/>
/// Base tests which use <see cref="ResponsesClient"/>
/// </summary>
public class BaseOpenAIResponseClientTest : IDisposable
{
internal MultipleHttpMessageHandlerStub MessageHandlerStub { get; }
internal HttpClient HttpClient { get; }
internal OpenAIResponseClient Client { get; }
internal ResponsesClient Client { get; }
internal BaseOpenAIResponseClientTest()
{
@@ -27,7 +27,7 @@ public class BaseOpenAIResponseClientTest : IDisposable
{
Transport = new HttpClientPipelineTransport(this.HttpClient)
};
this.Client = new OpenAIResponseClient("model", new ApiKeyCredential("apiKey"), clientOptions);
this.Client = new ResponsesClient("model", new ApiKeyCredential("apiKey"), clientOptions);
}
/// <inheritdoc />
@@ -16,13 +16,13 @@ namespace SemanticKernel.Agents.UnitTests.OpenAI.Extensions;
public class OpenAIResponseExtensionsTests
{
/// <summary>
/// Verify conversion from <see cref="OpenAIResponse"/> to <see cref="ChatMessageContent"/>.
/// Verify conversion from <see cref="ResponseResult"/> to <see cref="ChatMessageContent"/>.
/// </summary>
[Fact]
public void VerifyToChatMessageContentWithOpenAIResponse()
{
// Arrange
OpenAIResponse mockResponse = this.CreateMockOpenAIResponse("gpt-4o-mini",
ResponseResult mockResponse = this.CreateMockOpenAIResponse("gpt-4o-mini",
[
ResponseItem.CreateUserMessageItem("This is a user message."),
]);
@@ -197,7 +197,7 @@ public class OpenAIResponseExtensionsTests
}
/// <summary>
/// Verify that OpenAIResponse with both ReasoningResponseItem and MessageResponseItem generates correct content types.
/// Verify that ResponseResult with both ReasoningResponseItem and MessageResponseItem generates correct content types.
/// </summary>
[Fact]
public void VerifyToChatMessageContentWithMixedResponseItems()
@@ -206,7 +206,7 @@ public class OpenAIResponseExtensionsTests
var reasoningResponseItem = this.CreateReasoningResponseItem("Thinking about the answer...");
var messageResponseItem = ResponseItem.CreateAssistantMessageItem("Here is my response.");
OpenAIResponse mockResponse = this.CreateMockOpenAIResponse("gpt-4o-mini",
ResponseResult mockResponse = this.CreateMockOpenAIResponse("gpt-4o-mini",
[
reasoningResponseItem,
messageResponseItem
@@ -231,30 +231,37 @@ public class OpenAIResponseExtensionsTests
}
#region private
private OpenAIResponse CreateMockOpenAIResponse(string model, IEnumerable<ResponseItem> outputItems) =>
OpenAIResponsesModelFactory.OpenAIResponse(
model: model,
outputItems: outputItems);
private ResponseResult CreateMockOpenAIResponse(string model, IEnumerable<ResponseItem> outputItems)
{
var result = new ResponseResult { Model = model };
foreach (var item in outputItems) { result.OutputItems.Add(item); }
return result;
}
private OpenAIResponse CreateMockOpenAIResponse(string id, DateTimeOffset createdAt, ResponseError error, string instructions, string model, string previousResponseId, float temperature, IEnumerable<ResponseTool> tools, float topP, IDictionary<string, string> metadata, ResponseIncompleteStatusDetails incompleteStatusDetails, IEnumerable<ResponseItem> outputItems, bool parallelToolCallsEnabled, ResponseToolChoice toolChoice) =>
OpenAIResponsesModelFactory.OpenAIResponse(
id: id,
createdAt: createdAt,
error: error,
instructions: instructions,
model: model,
previousResponseId: previousResponseId,
temperature: temperature,
tools: tools,
topP: topP,
metadata: metadata,
incompleteStatusDetails: incompleteStatusDetails,
outputItems: outputItems,
parallelToolCallsEnabled: parallelToolCallsEnabled,
toolChoice: toolChoice);
private ResponseResult CreateMockOpenAIResponse(string id, DateTimeOffset createdAt, ResponseError error, string instructions, string model, string previousResponseId, float temperature, IEnumerable<ResponseTool> tools, float topP, IDictionary<string, string> metadata, ResponseIncompleteStatusDetails incompleteStatusDetails, IEnumerable<ResponseItem> outputItems, bool parallelToolCallsEnabled, ResponseToolChoice toolChoice)
{
var result = new ResponseResult
{
Id = id,
CreatedAt = createdAt,
Error = error,
Instructions = instructions,
Model = model,
PreviousResponseId = previousResponseId,
Temperature = temperature,
TopP = topP,
IncompleteStatusDetails = incompleteStatusDetails,
ParallelToolCallsEnabled = parallelToolCallsEnabled,
ToolChoice = toolChoice,
};
foreach (var tool in tools) { result.Tools.Add(tool); }
foreach (var kvp in metadata) { result.Metadata[kvp.Key] = kvp.Value; }
foreach (var item in outputItems) { result.OutputItems.Add(item); }
return result;
}
private ReasoningResponseItem CreateReasoningResponseItem(string? reasoningText = null) =>
OpenAIResponsesModelFactory.ReasoningResponseItem(summaryText: reasoningText);
new(summaryText: reasoningText);
#endregion
}
@@ -96,7 +96,7 @@ public class ResponseCreationOptionsFactoryTests
// Arrange
var mockAgent = CreateMockAgent("Test Agent", "You are a helpful assistant.", storeEnabled: false);
var mockThread = CreateMockAgentThread(null);
var responseCreationOptions = new ResponseCreationOptions
var responseCreationOptions = new CreateResponseOptions
{
EndUserId = "custom-user",
Instructions = "Custom instructions",
@@ -142,7 +142,7 @@ public class ResponseCreationOptionsFactoryTests
// Arrange
var mockAgent = CreateMockAgent("Test Agent", "You are a helpful assistant.", storeEnabled: true);
var mockThread = CreateMockAgentThread(null);
var responseCreationOptions = new ResponseCreationOptions
var responseCreationOptions = new CreateResponseOptions
{
EndUserId = null, // Should fallback to agent display name
Instructions = null, // Should fallback to agent instructions + additional
@@ -297,7 +297,7 @@ public class ResponseCreationOptionsFactoryTests
// Custom invoke options should be respected
var invokeOptions = new OpenAIResponseAgentInvokeOptions
{
ResponseCreationOptions = new ResponseCreationOptions
ResponseCreationOptions = new CreateResponseOptions
{
ToolChoice = ResponseToolChoice.CreateNoneChoice(),
ParallelToolCallsEnabled = false
@@ -317,7 +317,7 @@ public class ResponseCreationOptionsFactoryTests
private static OpenAIResponseAgent CreateMockAgent(string? name, string? instructions, bool storeEnabled)
{
var mockClient = new Mock<OpenAIResponseClient>();
var mockClient = new Mock<ResponsesClient>();
var mockAgent = new OpenAIResponseAgent(mockClient.Object)
{
Name = name ?? "UnnamedAgent",
@@ -16,7 +16,7 @@ public sealed class OpenAIResponseAgentExtensionsTests
public void AsAIAgent_WithValidOpenAIResponseAgent_ReturnsSemanticKernelAIAgent()
{
// Arrange
var responseClient = new OpenAIResponseClient("model", "apikey");
var responseClient = new ResponsesClient("model", "apikey");
var responseAgent = new OpenAIResponseAgent(responseClient);
// Act
@@ -41,7 +41,7 @@ public sealed class OpenAIResponseAgentExtensionsTests
public void AsAIAgent_CreatesWorkingThreadFactoryStoreTrue()
{
// Arrange
var responseClient = new OpenAIResponseClient("model", "apikey");
var responseClient = new ResponsesClient("model", "apikey");
var responseAgent = new OpenAIResponseAgent(responseClient)
{
StoreEnabled = true
@@ -62,7 +62,7 @@ public sealed class OpenAIResponseAgentExtensionsTests
public void AsAIAgent_CreatesWorkingThreadFactoryStoreFalse()
{
// Arrange
var responseClient = new OpenAIResponseClient("model", "apikey");
var responseClient = new ResponsesClient("model", "apikey");
var responseAgent = new OpenAIResponseAgent(responseClient)
{
StoreEnabled = false
@@ -83,7 +83,7 @@ public sealed class OpenAIResponseAgentExtensionsTests
public void AsAIAgent_ThreadDeserializationFactory_WithNullAgentId_CreatesNewThread()
{
// Arrange
var responseClient = new OpenAIResponseClient("model", "apikey");
var responseClient = new ResponsesClient("model", "apikey");
var responseAgent = new OpenAIResponseAgent(responseClient)
{
StoreEnabled = true
@@ -105,7 +105,7 @@ public sealed class OpenAIResponseAgentExtensionsTests
public void AsAIAgent_ThreadDeserializationFactory_WithValidAgentId_CreatesThreadWithId()
{
// Arrange
var responseClient = new OpenAIResponseClient("model", "apikey");
var responseClient = new ResponsesClient("model", "apikey");
var responseAgent = new OpenAIResponseAgent(responseClient)
{
StoreEnabled = true
@@ -129,7 +129,7 @@ public sealed class OpenAIResponseAgentExtensionsTests
public void AsAIAgent_ThreadSerializer_SerializesThreadId()
{
// Arrange
var responseClient = new OpenAIResponseClient("model", "apikey");
var responseClient = new ResponsesClient("model", "apikey");
var responseAgent = new OpenAIResponseAgent(responseClient)
{
StoreEnabled = true
@@ -152,7 +152,7 @@ public sealed class OpenAIResponseAgentExtensionsTests
[Fact]
public void AsAIAgent_ThreadDeserializationFactory_WithNullJson_CreatesThreadWithEmptyChatHistory()
{
var responseClient = new OpenAIResponseClient("model", "apikey");
var responseClient = new ResponsesClient("model", "apikey");
var responseAgent = new OpenAIResponseAgent(responseClient);
var jsonElement = JsonSerializer.SerializeToElement((string?)null);
@@ -171,7 +171,7 @@ public sealed class OpenAIResponseAgentExtensionsTests
[Fact]
public void AsAIAgent_ThreadDeserializationFactory_WithChatHistory_CreatesThreadWithChatHistory()
{
var responseClient = new OpenAIResponseClient("model", "apikey");
var responseClient = new ResponsesClient("model", "apikey");
var responseAgent = new OpenAIResponseAgent(responseClient);
var expectedChatHistory = new ChatHistory("mock message", AuthorRole.User);
var jsonElement = JsonSerializer.SerializeToElement(expectedChatHistory);
@@ -195,7 +195,7 @@ public sealed class OpenAIResponseAgentExtensionsTests
public void AsAIAgent_ThreadSerializer_SerializesChatHistory()
{
// Arrange
var responseClient = new OpenAIResponseClient("model", "apikey");
var responseClient = new ResponsesClient("model", "apikey");
var responseAgent = new OpenAIResponseAgent(responseClient);
var expectedChatHistory = new ChatHistory("mock message", AuthorRole.User);
var jsonElement = JsonSerializer.SerializeToElement(expectedChatHistory);
@@ -1,6 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
using System.ClientModel;
using System.Threading.Tasks;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Xunit;
@@ -21,7 +21,7 @@ public class OpenAIResponseAgentInvokeTests() : InvokeTests(() => new OpenAIResp
[Fact]
public override Task InvokeWithoutMessageCreatesThreadAsync()
{
return Assert.ThrowsAsync<ArgumentException>(() => base.InvokeWithoutMessageCreatesThreadAsync());
return Assert.ThrowsAsync<ClientResultException>(() => base.InvokeWithoutMessageCreatesThreadAsync());
}
[Fact(Skip = $"{nameof(OpenAIResponseAgent)} fails to notify for all messages - Issue #12468")]
@@ -1,6 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
using System;
using System.ClientModel;
using System.Threading.Tasks;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Xunit;
@@ -22,6 +22,6 @@ public class OpenAIResponseAgentInvokeStreamingTests() : InvokeStreamingTests(()
[Fact]
public override Task InvokeStreamingAsyncWithoutMessageCreatesThreadAsync()
{
return Assert.ThrowsAsync<ArgumentException>(() => base.InvokeStreamingAsyncWithoutMessageCreatesThreadAsync());
return Assert.ThrowsAsync<ClientResultException>(() => base.InvokeStreamingAsyncWithoutMessageCreatesThreadAsync());
}
}
@@ -25,14 +25,14 @@ public class OpenAIResponseAgentFixture : AgentFixture
.AddUserSecrets<OpenAIResponseAgentFixture>()
.Build();
private OpenAIResponseClient? _responseClient;
private ResponsesClient? _responseClient;
private OpenAIResponseAgent? _agent;
private OpenAIResponseAgentThread? _thread;
private OpenAIResponseAgentThread? _createdThread;
private OpenAIResponseAgentThread? _serviceFailingAgentThread;
private OpenAIResponseAgentThread? _createdServiceFailingAgentThread;
public OpenAIResponseClient ResponseClient => this._responseClient!;
public ResponsesClient ResponseClient => this._responseClient!;
public override Agent Agent => this._agent!;
@@ -112,7 +112,7 @@ public class OpenAIResponseAgentFixture : AgentFixture
var response = await this._responseClient.CreateResponseAsync([ResponseItem.CreateUserMessageItem("Hello")]);
this._createdThread = new OpenAIResponseAgentThread(this._responseClient, response.Value.Id);
var serviceFailingClient = new OpenAIResponseClient(configuration.ModelId, credential: new ApiKeyCredential("FakeApiKey"), options: options);
var serviceFailingClient = new ResponsesClient(configuration.ModelId, credential: new ApiKeyCredential("FakeApiKey"), options: options);
this._serviceFailingAgentThread = new OpenAIResponseAgentThread(serviceFailingClient);
this._createdServiceFailingAgentThread = new OpenAIResponseAgentThread(this._responseClient, "FakeId");
@@ -43,7 +43,7 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
[InlineData("What is the capital of France?", "Paris", false, false)]
public async Task OpenAIResponseAgentInvokeAsync(string input, string expectedAnswerContains, bool isOpenAI, bool storeEnabled)
{
OpenAIResponseClient client = this.CreateClient(isOpenAI);
ResponsesClient client = this.CreateClient(isOpenAI);
await this.ExecuteAgentAsync(
client,
@@ -63,7 +63,7 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
public async Task OpenAIResponseAgentInvokeWithThreadAsync(string input, string expectedAnswerContains, bool isOpenAI, bool storeEnabled)
{
// Arrange
OpenAIResponseClient client = this.CreateClient(isOpenAI);
ResponsesClient client = this.CreateClient(isOpenAI);
OpenAIResponseAgent agent = new(client)
{
StoreEnabled = storeEnabled,
@@ -112,7 +112,7 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
public async Task OpenAIResponseAgentInvokeWithFunctionCallingAsync(string input, string expectedAnswerContains, bool isOpenAI, bool storeEnabled)
{
// Arrange
OpenAIResponseClient client = this.CreateClient(isOpenAI);
ResponsesClient client = this.CreateClient(isOpenAI);
KernelPlugin plugin = KernelPluginFactory.CreateFromType<MenuPlugin>();
OpenAIResponseAgent agent = new(client)
{
@@ -161,7 +161,7 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
[InlineData("What is the capital of France?", "Paris", false, false)]
public async Task OpenAIResponseAgentInvokeStreamingAsync(string input, string expectedAnswerContains, bool isOpenAI, bool storeEnabled)
{
OpenAIResponseClient client = this.CreateClient(isOpenAI);
ResponsesClient client = this.CreateClient(isOpenAI);
await this.ExecuteStreamingAgentAsync(
client,
@@ -181,7 +181,7 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
public async Task OpenAIResponseAgentInvokeStreamingWithThreadAsync(bool isOpenAI, bool storeEnabled)
{
// Arrange
OpenAIResponseClient client = this.CreateClient(isOpenAI);
ResponsesClient client = this.CreateClient(isOpenAI);
OpenAIResponseAgent agent = new(client)
{
StoreEnabled = storeEnabled,
@@ -229,7 +229,7 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
public async Task OpenAIResponseAgentInvokeStreamingWithFunctionCallingAsync(string input, string expectedAnswerContains, bool isOpenAI, bool storeEnabled)
{
// Arrange
OpenAIResponseClient client = this.CreateClient(isOpenAI);
ResponsesClient client = this.CreateClient(isOpenAI);
KernelPlugin plugin = KernelPluginFactory.CreateFromType<MenuPlugin>();
OpenAIResponseAgent agent = new(client)
{
@@ -273,7 +273,7 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
private bool EnableLogging { get; set; } = true;
private async Task ExecuteAgentAsync(
OpenAIResponseClient client,
ResponsesClient client,
bool storeEnabled,
string input,
string expected)
@@ -305,7 +305,7 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
}
private async Task ExecuteStreamingAgentAsync(
OpenAIResponseClient client,
ResponsesClient client,
bool storeEnabled,
string input,
string expected)
@@ -355,9 +355,9 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
return configuration;
}
private OpenAIResponseClient CreateClient(bool isOpenAI)
private ResponsesClient CreateClient(bool isOpenAI)
{
OpenAIResponseClient client;
ResponsesClient client;
if (isOpenAI)
{
client = this.CreateClient(this._configuration.GetSection("OpenAI").Get<OpenAIConfiguration>());
@@ -370,7 +370,7 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
return client;
}
private OpenAIResponseClient CreateClient(OpenAIConfiguration? configuration)
private ResponsesClient CreateClient(OpenAIConfiguration? configuration)
{
Assert.NotNull(configuration);
@@ -387,10 +387,10 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
};
}
return new OpenAIResponseClient(configuration.ChatModelId, new ApiKeyCredential(configuration.ApiKey), options);
return new ResponsesClient(configuration.ChatModelId, new ApiKeyCredential(configuration.ApiKey), options);
}
private OpenAIResponseClient CreateClient(AzureOpenAIConfiguration? configuration)
private ResponsesClient CreateClient(AzureOpenAIConfiguration? configuration)
{
Assert.NotNull(configuration);
@@ -408,7 +408,7 @@ public sealed class OpenAIResponseAgentTests(ITestOutputHelper output)
}
var azureClient = new AzureOpenAIClient(new Uri(configuration.Endpoint), new AzureCliCredential(), options);
return azureClient.GetOpenAIResponseClient(configuration.ChatDeploymentName);
return azureClient.GetResponsesClient(configuration.ChatDeploymentName);
}
public sealed class MenuPlugin
@@ -11,7 +11,7 @@ using OpenAI.VectorStores;
/// <summary>
/// Base class for samples that demonstrate the usage of <see cref="OpenAIResponseAgent"/>.
/// </summary>
public abstract class BaseResponsesAgentTest : BaseAgentsTest<OpenAIResponseClient>
public abstract class BaseResponsesAgentTest : BaseAgentsTest<ResponsesClient>
{
protected BaseResponsesAgentTest(ITestOutputHelper output, string? model = null) : base(output)
{
@@ -39,5 +39,5 @@ public abstract class BaseResponsesAgentTest : BaseAgentsTest<OpenAIResponseClie
protected bool EnableLogging { get; set; } = false;
/// <inheritdoc/>
protected override OpenAIResponseClient Client { get; }
protected override ResponsesClient Client { get; }
}
@@ -113,6 +113,18 @@ public static class PromptExecutionSettingsExtensions
options.ResponseFormat = responseFormat is JsonElement e ? ChatResponseFormat.ForJsonSchema(e) : null;
}
}
else if (entry.Key.Equals("reasoning_effort", StringComparison.OrdinalIgnoreCase) &&
TryConvert(entry.Value, out string? reasoningEffort))
{
(options.Reasoning ??= new()).Effort = reasoningEffort.ToUpperInvariant() switch
{
"LOW" => ReasoningEffort.Low,
"MEDIUM" => ReasoningEffort.Medium,
"HIGH" => ReasoningEffort.High,
"XHIGH" => ReasoningEffort.ExtraHigh,
_ => null,
};
}
else
{
// Roundtripping a derived PromptExecutionSettings through the base type will have put all the