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