// Copyright (c) Microsoft. All rights reserved.

using System;
using System.Threading.Tasks;

namespace Microsoft.SemanticKernel.Agents;

/// <summary>
/// Optional parameters for agent invocation.
/// </summary>
public class AgentInvokeOptions
{
    /// <summary>
    /// Initializes a new instance of the <see cref="AgentInvokeOptions"/> class.
    /// </summary>
    public AgentInvokeOptions()
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="AgentInvokeOptions"/> class by cloning the provided options.
    /// </summary>
    /// <param name="options">The options to clone.</param>
    public AgentInvokeOptions(AgentInvokeOptions options)
    {
        Verify.NotNull(options);

        this.KernelArguments = options.KernelArguments;
        this.Kernel = options.Kernel;
        this.AdditionalInstructions = options.AdditionalInstructions;
        this.OnIntermediateMessage = options.OnIntermediateMessage;
    }

    /// <summary>
    /// Gets or sets optional arguments to pass to the agent's invocation, including any <see cref="PromptExecutionSettings"/>
    /// </summary>
    public KernelArguments? KernelArguments { get; init; } = null;

    /// <summary>
    /// Gets or sets the <see cref="Kernel"/> containing services, plugins, and other state for use by the agent
    /// </summary>
    public Kernel? Kernel { get; init; } = null;

    /// <summary>
    /// Gets or sets any instructions, in addition to those that were provided to the agent
    /// initially, that need to be added to the prompt for this invocation only.
    /// </summary>
    public string AdditionalInstructions { get; init; } = string.Empty;

    /// <summary>
    /// Gets or sets a function to be called when a complete new message is generated by the agent.
    /// </summary>
    /// <remarks>
    /// <para>
    /// This callback is particularly useful in cases where the caller wants to receive complete messages
    /// when invoking the agent with streaming.
    /// </para>
    /// </remarks>
    public Func<ChatMessageContent, Task>? OnIntermediateMessage { get; init; } = null;
}
