e-naxosMAF COURSE / COURS
Français

MICROSOFT AGENT FRAMEWORK · 0.16.0-rc.1

Session history and persistence

Separate SQLite context, in-memory history and serialized MAF sessions.

Objectives

What must a new execution recover?

A support request concerns Reporting. Closing and reopening the console raises a precise question: does the program recover product context, earlier messages or only its instructions? J2 introduced these mechanisms together. The current programs separate them so every recovery claim has an identifiable storage mechanism.

Five distinct states
StateLifetime and responsibility
HistoryMessages retained by the active session; lost with the process without a save.
Native sessionMAF container serialized by Demo140 into session/session.json.
Business contextExplicit AgentState value in SQLite at context/state.db for Demo130.
Shared factsDemo150/160 WorkingMemory, in-process with provenance.
Injected contextA view assembled for one call; provides no persistence guarantee.

A targeted durable context

Demo130 initializes AgentState without deleting rows. setctx TEXT replaces the context value and creates an empty session. showctx reads SQLite. Each question receives the current value as unverified user data. Earlier dialogue remains in the process session and is not written to the database. After restart the context survives and dialogue starts afresh.

public void Set(string value)
{
    ArgumentException.ThrowIfNullOrWhiteSpace(value);
    if (value.Length > 4096)
        throw new ArgumentException("Context must not exceed 4096 characters.");
    Execute("INSERT INTO AgentState(Key, Value) VALUES ('context', $value) ON CONFLICT(Key) DO UPDATE SET Value=excluded.Value;", value);
}

/// <summary>Clears rows transactionally without deleting pooled SQLite files.</summary>
public void Reset() => Execute("DELETE FROM AgentState;");

shared/Maf.Memory/StateStorage.cs · L49–L58 · 9a895c94534c

Source code · Maf.Memory · Folder

Save and restore the native session

Demo140 calls SerializeSessionAsync and DeserializeSessionAsync. An envelope associates format version 1 and instruction version memory-1.1 with the snapshot. Startup loads automatically; every successful answer is followed by a save. save and load allow explicit operations. A neighboring temporary file is renamed after writing; this does not turn a conversation into a business transaction or workflow checkpoint.

public async Task<AgentSession> LoadOrCreateAsync(AIAgent agent, CancellationToken cancellationToken = default)
{
    if (!File.Exists(path))
        return await agent.CreateSessionAsync(cancellationToken);
    var envelope = JsonSerializer.Deserialize<Envelope>(await File.ReadAllTextAsync(path, cancellationToken))
        ?? throw new InvalidDataException("Empty session envelope.");
    if (envelope.Version != 1 || envelope.InstructionVersion != instructionVersion)
        throw new InvalidDataException("Session version or instruction version mismatch. Reset explicitly.");
    return await agent.DeserializeSessionAsync(envelope.Session, cancellationToken: cancellationToken);

shared/Maf.Memory/StateStorage.cs · L79–L87 · 9a895c94534c

Source code · Maf.Memory · Folder

Corrupt JSON or an incompatible version causes a visible error. Do not suppress it by silently starting a fresh conversation. Inspect the cause; --reset-state=true deliberately destroys this demo snapshot and belongs only on a chosen working state.

Recovery, replacement and isolation

Demo140 lifecycle; every step is also described below
  1. Startup → load snapshot or create a session if absent
  2. Successful answer → serialize → replace snapshot
  3. forget → delete snapshot + replace active session
  4. Restart → empty session if no new snapshot

In Demo140, newsession, reset, deletesession and forget all delete the snapshot and replace active history. The old J2 scenario “newsession then load to recover the save” no longer matches the current contract. Use two distinct absolute MAF_STATE_ROOT directories to isolate two trials. Two processes using the same root do not provide multi-user isolation and may race.

Verify before and after restart

$env:MAF_STATE_ROOT = Join-Path $env:TEMP ('maf-memory-' + [guid]::NewGuid().ToString('N'))

Keep this variable in the same terminal across restarts. In Demo130: setctx module=Reporting, showctx, quit; restart and run showctx. Then reset, quit, restart and showctx: the value must be empty. In Demo140, using this working root: send module=Reporting, wait for a successful answer, quit, restart and ask Which module did we discuss? Also inspect the snapshot. Then forget, quit, restart and load: an absent snapshot cannot restore the earlier exchange.

dotnet test tests/Maf.Memory.Tests/Maf.Memory.Tests.csproj -m:1 -c Release --no-build --no-restore

Scope of forgetting

Deleting history does not remove AgentState, another store, a log, a backup or data a provider may retain. Deleting SQLite rows does not prove secure erasure of disk pages. These examples are local and sequential, without encryption or cross-process access control. Procedures requiring answers are guided trials with a qualified chat model; deterministic tests separately check SQLite and serialization with a scripted client.

Continue with shared facts

Prerequisites

Continue reading

Previous

Next

lot008-memory-rag-1 · 2026-10-24 · 9a895c94534cd5fc6f3da883e37e5f7856e588c1