// 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 }; } }