// Copyright (c) Microsoft. All rights reserved. using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; using System.Threading.Tasks; namespace Microsoft.Agents.AI.Workflows.Checkpointing; /// /// An in-memory implementation of that stores checkpoints in a dictionary. /// internal sealed class InMemoryCheckpointManager : ICheckpointManager { [JsonInclude] internal Dictionary> Store { get; } = []; public InMemoryCheckpointManager() { } [JsonConstructor] internal InMemoryCheckpointManager(Dictionary> store) { this.Store = store; } private SessionCheckpointCache GetSessionStore(string sessionId) { if (!this.Store.TryGetValue(sessionId, out SessionCheckpointCache? sessionStore)) { sessionStore = this.Store[sessionId] = new(); } return sessionStore; } public ValueTask CommitCheckpointAsync(string sessionId, Checkpoint checkpoint) { SessionCheckpointCache sessionStore = this.GetSessionStore(sessionId); CheckpointInfo key; do { key = new(sessionId); } while (!sessionStore.Add(key, checkpoint)); return new(key); } public ValueTask LookupCheckpointAsync(string sessionId, CheckpointInfo checkpointInfo) { if (!this.GetSessionStore(sessionId).TryGet(checkpointInfo, out Checkpoint? value)) { throw new KeyNotFoundException($"Could not retrieve checkpoint with id {checkpointInfo.CheckpointId} for session {sessionId}"); } return new(value); } internal bool HasCheckpoints(string sessionId) => this.GetSessionStore(sessionId).HasCheckpoints; public bool TryGetLastCheckpoint(string sessionId, [NotNullWhen(true)] out CheckpointInfo? checkpoint) => this.GetSessionStore(sessionId).TryGetLastCheckpointInfo(out checkpoint); public ValueTask> RetrieveIndexAsync(string sessionId, CheckpointInfo? withParent = null) => new(this.GetSessionStore(sessionId).CheckpointIndex.AsReadOnly()); }