// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.AI;
using Microsoft.Shared.Diagnostics;
namespace Microsoft.Agents.AI;
///
/// Provides structured output methods for that enable requesting responses in a specific type format.
///
public abstract partial class AIAgent
{
///
/// Run the agent with no message assuming that all required instructions are already provided to the agent or on the session, and requesting a response of the specified type .
///
/// The type of structured output to request.
///
/// The conversation session to use for this invocation. If , a new session will be created.
/// The session will be updated with any response messages generated during invocation.
///
/// Optional JSON serializer options to use for deserializing the response.
/// Optional configuration parameters for controlling the agent's invocation behavior.
/// The to monitor for cancellation requests. The default is .
/// A task that represents the asynchronous operation. The task result contains an with the agent's output.
///
/// This overload is useful when the agent has sufficient context from previous messages in the session
/// or from its initial configuration to generate a meaningful response without additional input.
///
public Task> RunAsync(
AgentSession? session = null,
JsonSerializerOptions? serializerOptions = null,
AgentRunOptions? options = null,
CancellationToken cancellationToken = default) =>
this.RunAsync([], session, serializerOptions, options, cancellationToken);
///
/// Runs the agent with a text message from the user, requesting a response of the specified type .
///
/// The type of structured output to request.
/// The user message to send to the agent.
///
/// The conversation session to use for this invocation. If , a new session will be created.
/// The session will be updated with the input message and any response messages generated during invocation.
///
/// Optional JSON serializer options to use for deserializing the response.
/// Optional configuration parameters for controlling the agent's invocation behavior.
/// The to monitor for cancellation requests. The default is .
/// A task that represents the asynchronous operation. The task result contains an with the agent's output.
/// is , empty, or contains only whitespace.
///
/// The provided text will be wrapped in a with the role
/// before being sent to the agent. This is a convenience method for simple text-based interactions.
///
public Task> RunAsync(
string message,
AgentSession? session = null,
JsonSerializerOptions? serializerOptions = null,
AgentRunOptions? options = null,
CancellationToken cancellationToken = default)
{
_ = Throw.IfNullOrWhitespace(message);
return this.RunAsync(new ChatMessage(ChatRole.User, message), session, serializerOptions, options, cancellationToken);
}
///
/// Runs the agent with a single chat message, requesting a response of the specified type .
///
/// The type of structured output to request.
/// The chat message to send to the agent.
///
/// The conversation session to use for this invocation. If , a new session will be created.
/// The session will be updated with the input message and any response messages generated during invocation.
///
/// Optional JSON serializer options to use for deserializing the response.
/// Optional configuration parameters for controlling the agent's invocation behavior.
/// The to monitor for cancellation requests. The default is .
/// A task that represents the asynchronous operation. The task result contains an with the agent's output.
/// is .
public Task> RunAsync(
ChatMessage message,
AgentSession? session = null,
JsonSerializerOptions? serializerOptions = null,
AgentRunOptions? options = null,
CancellationToken cancellationToken = default)
{
_ = Throw.IfNull(message);
return this.RunAsync([message], session, serializerOptions, options, cancellationToken);
}
///
/// Runs the agent with a collection of chat messages, requesting a response of the specified type .
///
/// The type of structured output to request.
/// The collection of messages to send to the agent for processing.
///
/// The conversation session to use for this invocation. If , a new session will be created.
/// The session will be updated with the input messages and any response messages generated during invocation.
///
/// Optional JSON serializer options to use for deserializing the response.
/// Optional configuration parameters for controlling the agent's invocation behavior.
/// The to monitor for cancellation requests. The default is .
/// A task that represents the asynchronous operation. The task result contains an with the agent's output.
///
///
/// This method handles collections of messages, allowing for complex conversational scenarios including
/// multi-turn interactions, function calls, and context-rich conversations.
///
///
/// The messages are processed in the order provided and become part of the conversation history.
/// The agent's response will also be added to if one is provided.
///
///
public async Task> RunAsync(
IEnumerable messages,
AgentSession? session = null,
JsonSerializerOptions? serializerOptions = null,
AgentRunOptions? options = null,
CancellationToken cancellationToken = default)
{
serializerOptions ??= AgentAbstractionsJsonUtilities.DefaultOptions;
var responseFormat = ChatResponseFormat.ForJsonSchema(serializerOptions);
(responseFormat, bool isWrappedInObject) = StructuredOutputSchemaUtilities.WrapNonObjectSchema(responseFormat);
options = options?.Clone() ?? new AgentRunOptions();
options.ResponseFormat = responseFormat;
AgentResponse response = await this.RunAsync(messages, session, options, cancellationToken).ConfigureAwait(false);
return new AgentResponse(response, serializerOptions) { IsWrappedInObject = isWrappedInObject };
}
}