MICROSOFT AGENT FRAMEWORK · 0.16.0-rc.1
Historique et persistance de session
Séparer contexte SQLite, historique en mémoire et session MAF sérialisée.
Objectifs
- Historique natif et identité
- Persistance et reprise de conversation
- Isolation et redémarrage
Que doit retrouver une nouvelle exécution ?
Une demande de support porte sur Reporting. Fermer la console puis la rouvrir permet de poser une question précise : le programme retrouve-t-il le contexte produit, les anciens messages ou seulement ses instructions ? J2 introduisait ces mécanismes ensemble. Les programmes actuels les séparent pour que chaque promesse de reprise ait un support identifiable.
| État | Durée et responsabilité |
|---|---|
| Historique | Messages conservés par la session active ; disparaissent avec le processus sans sauvegarde. |
| Session native | Conteneur MAF sérialisé par Demo140 dans session/session.json. |
| Contexte métier | Valeur explicite AgentState en SQLite dans context/state.db pour Demo130. |
| Faits partagés | WorkingMemory de Demo150/160, en processus avec provenance. |
| Contexte injecté | Vue fabriquée pour un appel ; ne garantit aucune persistance. |
Un contexte durable ciblé
Demo130 initialise AgentState sans supprimer les lignes. setctx TEXT remplace la valeur context puis crée une session vide. showctx relit SQLite. Chaque question reçoit la valeur courante comme donnée utilisateur non vérifiée. Le dialogue précédent reste dans la session du processus, sans être enregistré en base. Après redémarrage, le contexte subsiste et le dialogue repart à zéro.
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;");
Sauver et restaurer la session native
Demo140 appelle SerializeSessionAsync et DeserializeSessionAsync. Une enveloppe associe version de format 1 et version d’instructions memory-1.1 au snapshot. Le chargement est automatique au démarrage ; chaque réponse réussie est suivie d’une sauvegarde. save et load permettent une manipulation explicite. Le fichier temporaire voisin est renommé après écriture ; ce mécanisme ne transforme pas une conversation en transaction métier ou checkpoint de workflow.
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);
Code source · Maf.Memory · Dossier
Un JSON corrompu ou une version incompatible provoque une erreur visible. Ne pas ignorer cette erreur pour démarrer silencieusement une conversation neuve. Examiner la cause ; --reset-state=true est une destruction volontaire du snapshot de cette démo, à réserver à un état de travail choisi.
Reprise, remplacement et isolation
- Démarrage → charger le snapshot ou créer une session si absent
- Réponse réussie → sérialiser → remplacer le snapshot
- forget → supprimer le snapshot + remplacer la session active
- Redémarrage → une session vide si aucun nouveau snapshot
Dans Demo140, newsession, reset, deletesession et forget suppriment tous le snapshot et remplacent l’historique actif. L’ancien scénario J2 « newsession puis load pour retrouver la sauvegarde » ne correspond plus au contrat actuel. Utiliser deux racines MAF_STATE_ROOT absolues distinctes pour isoler deux essais. Deux processus dans la même racine ne sont pas une isolation multi-utilisateur et peuvent se concurrencer.
Vérifier avant et après redémarrage
$env:MAF_STATE_ROOT = Join-Path $env:TEMP ('maf-memory-' + [guid]::NewGuid().ToString('N'))Garder cette variable dans le même terminal pendant les relances. Avec Demo130 : setctx module=Reporting, showctx, quit ; relancer et exécuter showctx. Puis reset, quit, relancer et showctx : la valeur doit être vide. Avec Demo140, dans cette racine de travail : envoyer module=Reporting, attendre une réponse réussie, quit, relancer et demander Which module did we discuss? Inspecter aussi le snapshot. Ensuite forget, quit, relancer et load : le snapshot absent ne peut restaurer l’ancien échange.
dotnet test tests/Maf.Memory.Tests/Maf.Memory.Tests.csproj -m:1 -c Release --no-build --no-restorePortée de l’oubli
Effacer l’historique ne supprime pas AgentState, un autre store, un journal, une sauvegarde ni les données éventuellement conservées par un fournisseur. DELETE de lignes SQLite ne prouve pas un effacement sécurisé des pages sur disque. Ces exemples sont locaux, séquentiels, sans chiffrement ni contrôle d’accès multiprocessus. Les manipulations avec réponses sont des essais guidés à exécuter avec un chat qualifié ; les tests déterministes vérifient séparément SQLite et la sérialisation avec un client scripté.
Passer aux faits partagés
Prérequis
Pour poursuivre
Précédent
Suivant
