mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
.NET: Update M.A.AI.OpenAI implementations (#1018)
* Update M.A.AI.OpenAI implementations
- There was only a ChatClient-based agent. Add a Responses one, too.
- Fix the public extension methods to create OpenAI types even when not backed by the right OpenAI client.
- Add reusable AgentRunResponse{Update} to ChatResponse{Update} conversion routines that are then used by the OpenAI agents and elsewhere
* Address feedback
This commit is contained in:
committed by
GitHub
Unverified
parent
8dad045c9d
commit
2d20e644df
@@ -2,7 +2,7 @@
|
||||
|
||||
using System.ClientModel;
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Agents.AI.OpenAI.ChatClient;
|
||||
using Microsoft.Agents.AI.OpenAI;
|
||||
using Microsoft.Shared.Diagnostics;
|
||||
using OpenAI.Chat;
|
||||
|
||||
@@ -34,7 +34,7 @@ public static class AIAgentWithOpenAIExtensions
|
||||
/// <exception cref="NotSupportedException">Thrown when any message in <paramref name="messages"/> has a type that is not supported by the message conversion method.</exception>
|
||||
/// <remarks>
|
||||
/// This method converts the OpenAI chat messages to the Microsoft Extensions AI format using the appropriate conversion method,
|
||||
/// runs the agent with the converted message collection, and then extracts the native OpenAI <see cref="ChatCompletion"/> from the response using <see cref="AgentRunResponseExtensions.AsChatCompletion"/>.
|
||||
/// runs the agent with the converted message collection, and then extracts the native OpenAI <see cref="ChatCompletion"/> from the response using <see cref="AgentRunResponseExtensions.AsOpenAIChatCompletion"/>.
|
||||
/// </remarks>
|
||||
public static async Task<ChatCompletion> RunAsync(this AIAgent agent, IEnumerable<ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -43,7 +43,7 @@ public static class AIAgentWithOpenAIExtensions
|
||||
|
||||
var response = await agent.RunAsync([.. messages.AsChatMessages()], thread, options, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return response.AsChatCompletion();
|
||||
return response.AsOpenAIChatCompletion();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -60,7 +60,7 @@ public static class AIAgentWithOpenAIExtensions
|
||||
/// <exception cref="NotSupportedException">Thrown when the <paramref name="messages"/> type is not supported by the message conversion method.</exception>
|
||||
/// <remarks>
|
||||
/// This method converts the OpenAI chat messages to the Microsoft Extensions AI format using the appropriate conversion method,
|
||||
/// runs the agent, and then extracts the native OpenAI <see cref="ChatCompletion"/> from the response using <see cref="AgentRunResponseExtensions.AsChatCompletion"/>.
|
||||
/// runs the agent, and then extracts the native OpenAI <see cref="ChatCompletion"/> from the response using <see cref="AgentRunResponseExtensions.AsOpenAIChatCompletion"/>.
|
||||
/// </remarks>
|
||||
public static AsyncCollectionResult<StreamingChatCompletionUpdate> RunStreamingAsync(this AIAgent agent, IEnumerable<ChatMessage> messages, AgentThread? thread = null, AgentRunOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
||||
@@ -1,52 +1,45 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Microsoft.Agents.AI;
|
||||
using Microsoft.Extensions.AI;
|
||||
using Microsoft.Shared.Diagnostics;
|
||||
using OpenAI.Chat;
|
||||
using OpenAI.Responses;
|
||||
|
||||
namespace OpenAI;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for <see cref="AgentRunResponse"/> to extract native OpenAI response objects
|
||||
/// from the Microsoft Agent Framework responses.
|
||||
/// Provides extension methods for <see cref="AgentRunResponse"/> and <see cref="AgentRunResponseUpdate"/> instances to
|
||||
/// create or extract native OpenAI response objects from the Microsoft Agent Framework responses.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These extensions enable developers to access the underlying OpenAI SDK objects when working with
|
||||
/// AI agents that are backed by OpenAI services. The methods extract strongly-typed OpenAI responses
|
||||
/// from the <see cref="AgentRunResponse.RawRepresentation"/> property, providing a bridge between
|
||||
/// the Microsoft Extensions AI framework and the native OpenAI SDK types.
|
||||
/// </remarks>
|
||||
public static class AgentRunResponseExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Extracts a native OpenAI <see cref="ChatCompletion"/> object from an <see cref="AgentRunResponse"/>.
|
||||
/// Creates or extracts a native OpenAI <see cref="ChatCompletion"/> object from an <see cref="AgentRunResponse"/>.
|
||||
/// </summary>
|
||||
/// <param name="agentResponse">The agent response containing the raw OpenAI representation.</param>
|
||||
/// <returns>The native OpenAI <see cref="ChatCompletion"/> object.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentResponse"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown when the <see cref="AgentRunResponse.RawRepresentation"/> is not a <see cref="ChatCompletion"/> object.
|
||||
/// This typically occurs when the agent response was not generated by an OpenAI chat completion service
|
||||
/// or when the underlying representation has been modified or corrupted.
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This method provides access to the native OpenAI <see cref="ChatCompletion"/> object that was used
|
||||
/// to generate the agent response. This is useful when you need to access OpenAI-specific properties
|
||||
/// or metadata that are not exposed through the Microsoft Extensions AI abstractions.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static ChatCompletion AsChatCompletion(this AgentRunResponse agentResponse)
|
||||
/// <param name="response">The agent response.</param>
|
||||
/// <returns>The OpenAI <see cref="ChatCompletion"/> object.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="response"/> is <see langword="null"/>.</exception>
|
||||
public static ChatCompletion AsOpenAIChatCompletion(this AgentRunResponse response)
|
||||
{
|
||||
Throw.IfNull(agentResponse);
|
||||
Throw.IfNull(response);
|
||||
|
||||
if (agentResponse.RawRepresentation is ChatResponse chatResponse)
|
||||
{
|
||||
return chatResponse.RawRepresentation is ChatCompletion chatCompletion
|
||||
? chatCompletion
|
||||
: throw new ArgumentException("ChatResponse.RawRepresentation must be a ChatCompletion");
|
||||
}
|
||||
throw new ArgumentException("AgentRunResponse.RawRepresentation must be a ChatResponse");
|
||||
return
|
||||
response.RawRepresentation as ChatCompletion ??
|
||||
response.AsChatResponse().AsOpenAIChatCompletion();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates or extracts a native OpenAI <see cref="OpenAIResponse"/> object from an <see cref="AgentRunResponse"/>.
|
||||
/// </summary>
|
||||
/// <param name="response">The agent response.</param>
|
||||
/// <returns>The OpenAI <see cref="OpenAIResponse"/> object.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="response"/> is <see langword="null"/>.</exception>
|
||||
public static OpenAIResponse AsOpenAIResponse(this AgentRunResponse response)
|
||||
{
|
||||
Throw.IfNull(response);
|
||||
|
||||
return
|
||||
response.RawRepresentation as OpenAIResponse ??
|
||||
response.AsChatResponse().AsOpenAIResponse();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
using Microsoft.Extensions.AI;
|
||||
using Microsoft.Shared.Diagnostics;
|
||||
using OpenAI.Chat;
|
||||
|
||||
namespace Microsoft.Agents.AI;
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for <see cref="AgentRunResponseUpdate"/> to extract native OpenAI response objects
|
||||
/// from the Microsoft Agent Framework responses.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// These extensions enable developers to access the underlying OpenAI SDK objects when working with
|
||||
/// AI agents that are backed by OpenAI services. The methods extract strongly-typed OpenAI responses
|
||||
/// from the <see cref="AgentRunResponseUpdate.RawRepresentation"/> property, providing a bridge between
|
||||
/// the Microsoft Extensions AI framework and the native OpenAI SDK types.
|
||||
/// </remarks>
|
||||
public static class AgentRunResponseUpdateExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Extracts a native OpenAI <see cref="StreamingChatCompletionUpdate"/> object from an <see cref="AgentRunResponseUpdate"/>.
|
||||
/// </summary>
|
||||
/// <param name="agentResponseUpdate">The agent response containing the raw OpenAI representation.</param>
|
||||
/// <returns>The native OpenAI <see cref="StreamingChatCompletionUpdate"/> object.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="agentResponseUpdate"/> is <see langword="null"/>.</exception>
|
||||
/// <exception cref="ArgumentException">
|
||||
/// Thrown when the <see cref="AgentRunResponseUpdate.RawRepresentation"/> is not a <see cref="ChatResponseUpdate"/> object,
|
||||
/// or when the nested <see cref="ChatResponseUpdate.RawRepresentation"/> is not a <see cref="StreamingChatCompletionUpdate"/> object.
|
||||
/// This typically occurs when the agent response was not generated by an OpenAI streaming chat completion service
|
||||
/// or when the underlying representation has been modified or corrupted.
|
||||
/// </exception>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This method provides access to the native OpenAI <see cref="StreamingChatCompletionUpdate"/> object that was used
|
||||
/// to generate the agent response. This is useful when you need to access OpenAI-specific properties
|
||||
/// or metadata that are not exposed through the Microsoft Extensions AI abstractions.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static StreamingChatCompletionUpdate AsStreamingChatCompletionUpdate(this AgentRunResponseUpdate agentResponseUpdate)
|
||||
{
|
||||
Throw.IfNull(agentResponseUpdate);
|
||||
|
||||
if (agentResponseUpdate.RawRepresentation is ChatResponseUpdate chatResponseUpdate)
|
||||
{
|
||||
return chatResponseUpdate.RawRepresentation is StreamingChatCompletionUpdate streamingChatCompletionUpdate
|
||||
? streamingChatCompletionUpdate
|
||||
: throw new ArgumentException("ChatResponseUpdate.RawRepresentation must be a StreamingChatCompletionUpdate");
|
||||
}
|
||||
throw new ArgumentException("AgentRunResponseUpdate.RawRepresentation must be a ChatResponseUpdate");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user