// Copyright (c) Microsoft. All rights reserved.
using System;
using System.Text.Json;
namespace Microsoft.Agents.AI;
///
/// Provides strongly-typed state management for providers, enabling reading and writing of provider-specific state
/// to and from an 's .
///
/// The type of the state to be maintained. Must be a reference type.
///
///
/// This class encapsulates the logic for initializing, retrieving, and persisting provider state in the session's StateBag
/// using a configurable key and JSON serialization options. It is intended to be used as a composed field within provider
/// implementations (e.g., or subclasses) to avoid
/// duplicating state management logic across provider type hierarchies.
///
///
/// State is stored in the using the property as the key,
/// enabling multiple providers to maintain independent state within the same session.
///
///
public class ProviderSessionState
where TState : class
{
private readonly Func _stateInitializer;
private readonly JsonSerializerOptions _jsonSerializerOptions;
///
/// Initializes a new instance of the class.
///
/// A function to initialize the state when it is not yet present in the session's StateBag.
/// The key used to store the state in the session's StateBag.
/// Options for JSON serialization and deserialization of the state.
public ProviderSessionState(
Func stateInitializer,
string stateKey,
JsonSerializerOptions? jsonSerializerOptions = null)
{
this._stateInitializer = stateInitializer;
this.StateKey = stateKey;
this._jsonSerializerOptions = jsonSerializerOptions ?? AgentAbstractionsJsonUtilities.DefaultOptions;
}
///
/// Gets the key used to store the provider state in the .
///
public string StateKey { get; }
///
/// Gets the state from the session's StateBag, or initializes it using the state initializer if not present.
///
/// The agent session containing the StateBag.
/// The provider state.
public TState GetOrInitializeState(AgentSession? session)
{
if (session?.StateBag.TryGetValue(this.StateKey, out var state, this._jsonSerializerOptions) is true && state is not null)
{
return state;
}
state = this._stateInitializer(session);
if (session is not null)
{
session.StateBag.SetValue(this.StateKey, state, this._jsonSerializerOptions);
}
return state;
}
///
/// Saves the specified state to the session's StateBag using the configured state key and JSON serializer options.
/// If the session is null, this method does nothing.
///
/// The agent session containing the StateBag.
/// The state to be saved.
public void SaveState(AgentSession? session, TState state)
{
if (session is not null)
{
session.StateBag.SetValue(this.StateKey, state, this._jsonSerializerOptions);
}
}
}