// Copyright (c) Microsoft. All rights reserved.
using System.Diagnostics.CodeAnalysis;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;
using Microsoft.Shared.DiagnosticIds;
using Microsoft.Shared.Diagnostics;
namespace OpenAI.Responses;
///
/// Provides extension methods for
/// to simplify the creation of AI agents that work with OpenAI services.
///
///
/// These extensions bridge the gap between OpenAI SDK client objects and the Microsoft Agent Framework,
/// allowing developers to easily create AI agents that leverage OpenAI's chat completion and response services.
/// The methods handle the conversion from OpenAI clients to instances and then wrap them
/// in objects that implement the interface.
///
[Experimental(DiagnosticIds.Experiments.AIOpenAIResponses)]
public static class OpenAIResponseClientExtensions
{
///
/// Creates an AI agent from an using the OpenAI Response API.
///
/// The to use for the agent.
/// Optional default model ID to use for requests. Required when using a plain (not via Azure OpenAI).
/// Optional system instructions that define the agent's behavior and personality.
/// Optional name for the agent for identification purposes.
/// Optional description of the agent's capabilities and purpose.
/// Optional collection of AI tools that the agent can use during conversations.
/// Provides a way to customize the creation of the underlying used by the agent.
/// Optional logger factory for enabling logging within the agent.
/// An optional to use for resolving services required by the instances being invoked.
/// An instance backed by the OpenAI Response service.
/// Thrown when is .
public static ChatClientAgent AsAIAgent(
this ResponsesClient client,
string? model = null,
string? instructions = null,
string? name = null,
string? description = null,
IList? tools = null,
Func? clientFactory = null,
ILoggerFactory? loggerFactory = null,
IServiceProvider? services = null)
{
Throw.IfNull(client);
return client.AsAIAgent(
new ChatClientAgentOptions()
{
Name = name,
Description = description,
ChatOptions = tools is null && string.IsNullOrWhiteSpace(instructions) ? null : new ChatOptions()
{
Instructions = instructions,
Tools = tools,
}
},
model,
clientFactory,
loggerFactory,
services);
}
///
/// Creates an AI agent from an using the OpenAI Response API.
///
/// The to use for the agent.
/// Full set of options to configure the agent.
/// Optional default model ID to use for requests. Required when using a plain (not via Azure OpenAI).
/// Provides a way to customize the creation of the underlying used by the agent.
/// Optional logger factory for enabling logging within the agent.
/// An optional to use for resolving services required by the instances being invoked.
/// An instance backed by the OpenAI Response service.
/// Thrown when or is .
public static ChatClientAgent AsAIAgent(
this ResponsesClient client,
ChatClientAgentOptions options,
string? model = null,
Func? clientFactory = null,
ILoggerFactory? loggerFactory = null,
IServiceProvider? services = null)
{
Throw.IfNull(client);
Throw.IfNull(options);
var chatClient = client.AsIChatClient(model);
if (clientFactory is not null)
{
chatClient = clientFactory(chatClient);
}
return new ChatClientAgent(chatClient, options, loggerFactory, services);
}
///
/// Gets an for use with this that does not store responses for later retrieval.
///
///
/// This corresponds to setting the "store" property in the JSON representation to false.
///
/// The client.
/// Optional default model ID to use for requests. Required when using a plain (not via Azure OpenAI).
///
/// Includes an encrypted version of reasoning tokens in reasoning item outputs.
/// This enables reasoning items to be used in multi-turn conversations when using the Responses API statelessly
/// (like when the store parameter is set to false, or when an organization is enrolled in the zero data retention program).
/// Defaults to .
///
/// An that can be used to converse via the that does not store responses for later retrieval.
/// is .
[Experimental(DiagnosticIds.Experiments.AgentsAIExperiments)]
public static IChatClient AsIChatClientWithStoredOutputDisabled(this ResponsesClient responseClient, string? model = null, bool includeReasoningEncryptedContent = true)
{
return Throw.IfNull(responseClient)
.AsIChatClient(model)
.AsBuilder()
.ConfigureOptions(x => x.RawRepresentationFactory = _ => includeReasoningEncryptedContent
? new CreateResponseOptions() { StoredOutputEnabled = false, IncludedProperties = { IncludedResponseProperty.ReasoningEncryptedContent } }
: new CreateResponseOptions() { StoredOutputEnabled = false })
.Build();
}
}