// Copyright (c) Microsoft. All rights reserved. using System; using System.Diagnostics; using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Shared.Diagnostics; namespace Microsoft.Agents.AI; /// /// Base abstraction for all agent threads. /// /// /// /// An contains the state of a specific conversation with an agent which may include: /// /// Conversation history or a reference to externally stored conversation history. /// Memories or a reference to externally stored memories. /// Any other state that the agent needs to persist across runs for a conversation. /// /// /// /// An may also have behaviors attached to it that may include: /// /// Customized storage of state. /// Data extraction from and injection into a conversation. /// Chat history reduction, e.g. where messages needs to be summarized or truncated to reduce the size. /// /// An is always constructed by an so that the /// can attach any necessary behaviors to the . See the /// and methods for more information. /// /// /// Because of these behaviors, an may not be reusable across different agents, since each agent /// may add different behaviors to the it creates. /// /// /// To support conversations that may need to survive application restarts or separate service requests, an can be serialized /// and deserialized, so that it can be saved in a persistent store. /// The provides the method to serialize the session to a /// and the method /// can be used to deserialize the session. /// /// /// /// /// [DebuggerDisplay("{DebuggerDisplay,nq}")] public abstract class AgentSession { /// /// Initializes a new instance of the class. /// protected AgentSession() { } /// /// Initializes a new instance of the class. /// protected AgentSession(AgentSessionStateBag stateBag) { this.StateBag = Throw.IfNull(stateBag); } /// /// Gets any arbitrary state associated with this session. /// [JsonPropertyName("stateBag")] public AgentSessionStateBag StateBag { get; protected set; } = new(); /// 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. For example, to access a if available for the instance, /// may be used to request it. /// 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; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay => $"StateBag Count = {this.StateBag.Count}"; }