// 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 an abstract base class for storing and managing chat messages associated with agent conversations. /// /// /// /// defines the contract for persistent storage of chat messages in agent conversations. /// Implementations are responsible for managing message persistence, retrieval, and any necessary optimization /// strategies such as truncation, summarization, or archival. /// /// /// Key responsibilities include: /// /// Storing chat messages with proper ordering and metadata preservation /// Retrieving messages in chronological order for agent context /// Managing storage limits through truncation, summarization, or other strategies /// Supporting serialization for thread persistence and migration /// /// /// public abstract class ChatMessageStore { /// /// Asynchronously retrieves all messages from the store that should be provided as context for the next agent invocation. /// /// The to monitor for cancellation requests. The default is . /// /// A task that represents the asynchronous operation. The task result contains a collection of /// instances in ascending chronological order (oldest first). /// /// /// /// Messages are returned in chronological order to maintain proper conversation flow and context for the agent. /// The oldest messages appear first in the collection, followed by more recent messages. /// /// /// If the total message history becomes very large, implementations should apply appropriate strategies to manage /// storage constraints, such as: /// /// Truncating older messages while preserving recent context /// Summarizing message groups to maintain essential context /// Implementing sliding window approaches for message retention /// Archiving old messages while keeping active conversation context /// /// /// /// Each store instance should be associated with a single conversation thread to ensure proper message isolation /// and context management. /// /// public abstract Task> GetMessagesAsync(CancellationToken cancellationToken = default); /// /// Asynchronously adds new messages to the store. /// /// The collection of chat messages to add to the store. /// The to monitor for cancellation requests. The default is . /// A task that represents the asynchronous add operation. /// is . /// /// /// Messages should be added in the order they were generated to maintain proper chronological sequence. /// The store is responsible for preserving message ordering and ensuring that subsequent calls to /// return messages in the correct chronological order. /// /// /// Implementations may perform additional processing during message addition, such as: /// /// Validating message content and metadata /// Applying storage optimizations or compression /// Triggering background maintenance operations /// Updating indices or search capabilities /// /// /// public abstract Task AddMessagesAsync(IEnumerable messages, CancellationToken cancellationToken = default); /// /// Serializes the current object's state to a using the specified serialization options. /// /// The JSON serialization options to use. /// A representation of the object's state. public abstract JsonElement Serialize(JsonSerializerOptions? jsonSerializerOptions = null); /// Asks the for an object of the specified type . /// The type of object being requested. /// An optional key that can be used to help identify the target service. /// The found object, otherwise . /// is . /// /// The purpose of this method is to allow for the retrieval of strongly-typed services that might be provided by the , /// including itself or any services it might be wrapping. /// public virtual object? GetService(Type serviceType, object? serviceKey = null) { _ = Throw.IfNull(serviceType); return serviceKey is null && serviceType.IsInstanceOfType(this) ? this : null; } /// Asks the for an object of type . /// The type of the object to be retrieved. /// An optional key that can be used to help identify the target service. /// The found object, otherwise . /// /// The purpose of this method is to allow for the retrieval of strongly typed services that may be provided by the , /// including itself or any services it might be wrapping. /// public TService? GetService(object? serviceKey = null) => this.GetService(typeof(TService), serviceKey) is TService service ? service : default; }