// Copyright (c) Microsoft. All rights reserved. using System; using System.Diagnostics; using System.Text.Json; using Microsoft.Shared.Diagnostics; namespace Microsoft.Agents.AI; /// /// Provides a base class for agent sessions that store conversation state remotely in a service and maintain only an identifier reference locally. /// /// /// This class is designed for scenarios where conversation state is managed by an external service (such as a cloud-based AI service) /// rather than being stored locally. The session maintains only the service identifier needed to reference the remote conversation state. /// [DebuggerDisplay("ServiceSessionId = {ServiceSessionId}")] public abstract class ServiceIdAgentSession : AgentSession { /// /// Initializes a new instance of the class without a service session identifier. /// /// /// When using this constructor, the will be initially /// and should be set by derived classes when the remote conversation is created. /// protected ServiceIdAgentSession() { } /// /// Initializes a new instance of the class with the specified service session identifier. /// /// The unique identifier that references the conversation state stored in the remote service. /// is . /// is empty or contains only whitespace. protected ServiceIdAgentSession(string serviceSessionId) { this.ServiceSessionId = Throw.IfNullOrEmpty(serviceSessionId); } /// /// Initializes a new instance of the class from previously serialized state. /// /// A representing the serialized state of the session. /// Optional settings for customizing the JSON deserialization process. /// The is not a JSON object. /// The is invalid or cannot be deserialized to the expected type. /// /// This constructor enables restoration of a service-backed session from serialized state, typically used /// when deserializing session information that was previously saved or transmitted across application boundaries. /// protected ServiceIdAgentSession( JsonElement serializedState, JsonSerializerOptions? jsonSerializerOptions = null) { if (serializedState.ValueKind != JsonValueKind.Object) { throw new ArgumentException("The serialized session state must be a JSON object.", nameof(serializedState)); } var state = serializedState.Deserialize( AgentAbstractionsJsonUtilities.DefaultOptions.GetTypeInfo(typeof(ServiceIdAgentSessionState))) as ServiceIdAgentSessionState; if (state?.ServiceSessionId is string serviceSessionId) { this.ServiceSessionId = serviceSessionId; } } /// /// Gets or sets the unique identifier that references the conversation state stored in the remote service. /// /// /// A string identifier that uniquely identifies the conversation within the remote service, /// or if no remote conversation has been established yet. /// /// /// This identifier is used by derived classes to reference the remote conversation state when making /// API calls to the backing service. The exact format and meaning of this identifier depends on the /// specific service implementation. /// protected string? ServiceSessionId { get; set; } /// /// 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. protected internal virtual JsonElement Serialize(JsonSerializerOptions? jsonSerializerOptions = null) { var state = new ServiceIdAgentSessionState { ServiceSessionId = this.ServiceSessionId, }; return JsonSerializer.SerializeToElement(state, AgentAbstractionsJsonUtilities.DefaultOptions.GetTypeInfo(typeof(ServiceIdAgentSessionState))); } internal sealed class ServiceIdAgentSessionState { public string? ServiceSessionId { get; set; } } }