.NET: Simplify store=false scenario for responses (#4124)

* Simplify store=false scenario for responses

* Mark AsIChatClientWithStoredOutputDisabled as Experimental
This commit is contained in:
westey
2026-02-23 12:24:32 +00:00
committed by GitHub
Unverified
parent d8b9409e96
commit 060d8fcadd
5 changed files with 67 additions and 1 deletions
+1
View File
@@ -7,6 +7,7 @@
<IsAotCompatible>false</IsAotCompatible>
<TargetFrameworks>net10.0;net472</TargetFrameworks>
<UserSecretsId>5ee045b0-aea3-4f08-8d31-32d1a6f8fed0</UserSecretsId>
<NoWarn>$(NoWarn);MAAI001</NoWarn>
</PropertyGroup>
<ItemGroup>
@@ -5,6 +5,7 @@
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI.Responses;
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
@@ -21,3 +22,16 @@ AIAgent agent = new AzureOpenAIClient(
// Invoke the agent and output the text result.
Console.WriteLine(await agent.RunAsync("Tell me a joke about a pirate."));
// Create a responses based agent with "store"=false.
// This means that chat history is managed locally by Agent Framework
// instead of being stored in the service (default).
AIAgent agentStoreFalse = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetResponsesClient(deploymentName)
.AsIChatClientWithStoredOutputDisabled()
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Invoke the agent and output the text result.
Console.WriteLine(await agentStoreFalse.RunAsync("Tell me a joke about a pirate."));
@@ -92,4 +92,23 @@ public static class OpenAIResponseClientExtensions
return new ChatClientAgent(chatClient, options, loggerFactory, services);
}
/// <summary>
/// Gets an <see cref="IChatClient"/> for use with this <see cref="ResponsesClient"/> that does not store responses for later retrieval.
/// </summary>
/// <remarks>
/// This corresponds to setting the "store" property in the JSON representation to false.
/// </remarks>
/// <param name="responseClient">The client.</param>
/// <returns>An <see cref="IChatClient"/> that can be used to converse via the <see cref="ResponsesClient"/> that does not store responses for later retrieval.</returns>
/// <exception cref="ArgumentNullException"><paramref name="responseClient"/> is <see langword="null"/>.</exception>
[Experimental(DiagnosticIds.Experiments.AgentsAIExperiments)]
public static IChatClient AsIChatClientWithStoredOutputDisabled(this ResponsesClient responseClient)
{
return Throw.IfNull(responseClient)
.AsIChatClient()
.AsBuilder()
.ConfigureOptions(x => x.RawRepresentationFactory = _ => new CreateResponseOptions() { StoredOutputEnabled = false })
.Build();
}
}
+1 -1
View File
@@ -8,7 +8,7 @@
<IsAotCompatible>false</IsAotCompatible>
<TargetFrameworks>net10.0;net472</TargetFrameworks>
<UserSecretsId>b7762d10-e29b-4bb1-8b74-b6d69a667dd4</UserSecretsId>
<NoWarn>$(NoWarn);Moq1410;xUnit2023</NoWarn>
<NoWarn>$(NoWarn);Moq1410;xUnit2023;MAAI001</NoWarn>
</PropertyGroup>
<ItemGroup>
@@ -259,6 +259,38 @@ public sealed class OpenAIResponseClientExtensionsTests
Assert.Same(serviceProvider, GetFunctionInvocationServices(functionInvokingClient));
}
/// <summary>
/// Verify that AsIChatClientWithStoredOutputDisabled throws ArgumentNullException when client is null.
/// </summary>
[Fact]
public void AsIChatClientWithStoredOutputDisabled_WithNullClient_ThrowsArgumentNullException()
{
// Act & Assert
var exception = Assert.Throws<ArgumentNullException>(() =>
((ResponsesClient)null!).AsIChatClientWithStoredOutputDisabled());
Assert.Equal("responseClient", exception.ParamName);
}
/// <summary>
/// Verify that AsIChatClientWithStoredOutputDisabled wraps the original ResponsesClient,
/// which remains accessible via the service chain.
/// </summary>
[Fact]
public void AsIChatClientWithStoredOutputDisabled_InnerResponsesClientIsAccessible()
{
// Arrange
var responseClient = new TestOpenAIResponseClient();
// Act
var chatClient = responseClient.AsIChatClientWithStoredOutputDisabled();
// Assert - the inner ResponsesClient should be accessible via GetService
var innerClient = chatClient.GetService<ResponsesClient>();
Assert.NotNull(innerClient);
Assert.Same(responseClient, innerClient);
}
/// <summary>
/// A simple test IServiceProvider implementation for testing.
/// </summary>