Plongée approfondie dans la gestion des sessions
Gestion des sessions et compaction (Plongée approfondie)
Section intitulée « Gestion des sessions et compaction (Plongée approfondie) »Ce document explique comment OpenClaw gère les sessions de bout en bout :
- Routage des sessions (façon dont les messages entrants sont mappés à une
sessionKey) - Magasin de sessions (
sessions.json) et ce qu’il suit - Persistance des transcriptions (
*.jsonl) et sa structure - Hygiène des transcriptions (corrections spécifiques au fournisseur avant les exécutions)
- Limites de contexte (fenêtre de contexte par rapport aux jetons suivis)
- Compaction (manuelle + auto-compaction) et où accrocher le travail de pré-compaction
- Maintenance silencieuse (ex: écritures en mémoire qui ne doivent pas produire de sortie visible pour l’utilisateur)
Si vous souhaitez d’abord un aperçu de plus haut niveau, commencez par :
- /concepts/session
- /concepts/compaction
- /concepts/memory
- /concepts/memory-search
- /concepts/session-pruning
- /reference/transcript-hygiene
Source de vérité : le Gateway
Section intitulée « Source de vérité : le Gateway »OpenClaw est conçu autour d’un unique processus Gateway qui possède l’état de la session.
- Les interfaces utilisateur (application macOS, interface de contrôle Web, TUI) doivent interroger le Gateway pour obtenir les listes de sessions et les comptes de jetons.
- En mode distant, les fichiers de session se trouvent sur l’hôte distant ; “vérifier vos fichiers Mac locaux” ne reflétera pas ce que le Gateway utilise.
Deux couches de persistance
Section intitulée « Deux couches de persistance »OpenClaw conserve les sessions sur deux couches :
-
Magasin de sessions (
sessions.json)- Carte clé/valeur :
sessionKey -> SessionEntry - Petit, mutable, sûr à modifier (ou à supprimer des entrées)
- Suivi des métadonnées de session (id de session actuel, dernière activité, bascules, compteurs de jetons, etc.)
- Carte clé/valeur :
-
Transcription (
<sessionId>.jsonl)- Transcription en ajout uniquement avec une structure arborescente (les entrées ont
id+parentId) - Stocke la conversation réelle + les appels d’outils + les résumés de compactage
- Utilisé pour reconstruire le contexte du modèle pour les futurs tours
- Transcription en ajout uniquement avec une structure arborescente (les entrées ont
Emplacements sur disque
Section intitulée « Emplacements sur disque »Par agent, sur l’hôte du Gateway :
- Magasin :
~/.openclaw/agents/<agentId>/sessions/sessions.json - Transcriptions :
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl- Sessions de sujet Telegram :
.../<sessionId>-topic-<threadId>.jsonl
- Sessions de sujet Telegram :
OpenClaw les résout via src/config/sessions.ts.
Maintenance du magasin et contrôles disque
Section intitulée « Maintenance du magasin et contrôles disque »La persistance des sessions dispose de contrôles de maintenance automatique (session.maintenance) pour les artefacts sessions.json et de transcription :
mode:warn(par défaut) ouenforcepruneAfter: limite d’âge des entrées obsolètes (par défaut30d)maxEntries: plafonner les entrées danssessions.json(par défaut500)rotateBytes: faire une rotation desessions.jsonen cas de dépassement de taille (par défaut10mb)resetArchiveRetention: rétention pour les archives de transcriptions*.reset.<timestamp>(par défaut : identique àpruneAfter;falsedésactive le nettoyage)maxDiskBytes: budget optionnel pour le répertoire de sessionshighWaterBytes: cible optionnelle après nettoyage (par défaut80%demaxDiskBytes)
Ordre d’application pour le nettoyage du budget disque (mode: "enforce") :
- Supprimer d’abord les artefacts de transcription archivés ou orphelins les plus anciens.
- Si toujours au-dessus de la cible, expulser les entrées de session les plus anciennes et leurs fichiers de transcription.
- Continuer jusqu’à ce que l’utilisation soit égale ou inférieure à
highWaterBytes.
En mode: "warn", OpenClaw signale les expulsions potentielles mais ne modifie pas le magasin/les fichiers.
Exécuter la maintenance à la demande :
openclaw sessions cleanup --dry-runopenclaw sessions cleanup --enforceSessions Cron et journaux d’exécution
Section intitulée « Sessions Cron et journaux d’exécution »Les exécutions cron isolées créent également des entrées de session/transcriptions, et elles disposent de contrôles de rétention dédiés :
cron.sessionRetention(par défaut24h) élimine les anciennes sessions d’exécution cron isolées du magasin de sessions (falsedésactive).cron.runLog.maxBytes+cron.runLog.keepLineséliminent les fichiers~/.openclaw/cron/runs/<jobId>.jsonl(par défaut :2_000_000octets et2000lignes).
Clés de session (sessionKey)
Section intitulée « Clés de session (sessionKey) »Une sessionKey identifie à quel bucket de conversation vous appartenez (routage + isolation).
Modèles courants :
- Chat principal/direct (par agent) :
agent:<agentId>:<mainKey>(par défautmain) - Groupe :
agent:<agentId>:<channel>:group:<id> - Salon/canal (Discord/Slack) :
agent:<agentId>:<channel>:channel:<id>ou...:room:<id> - Cron :
cron:<job.id> - Webhook :
hook:<uuid>(sauf si remplacé)
Les règles canoniques sont documentées dans /concepts/session.
Identifiants de session (sessionId)
Section intitulée « Identifiants de session (sessionId) »Chaque sessionKey pointe vers un sessionId actuel (le fichier de transcription qui poursuit la conversation).
Règles empiriques :
- Reset (
/new,/reset) crée un nouveausessionIdpour cesessionKey. - Daily reset (par défaut 4h00 heure locale sur l’hôte de la passerelle) crée un nouveau
sessionIdsur le prochain message après la limite de réinitialisation. - Idle expiry (
session.reset.idleMinutesou l’anciensession.idleMinutes) crée un nouveausessionIdlorsqu’un message arrive après la fenêtre d’inactivité. Quand les réinitialisations quotidienne et par inactivité sont toutes deux configurées, la première qui expire l’emporte. - Thread parent fork guard (
session.parentForkMaxTokens, par défaut100000) ignore la duplication de la transcription parente lorsque la session parente est déjà trop volumineuse ; le nouveau fil démarre à l’état neuf. Définissez0pour désactiver.
Détail d’implémentation : la décision est prise dans initSessionState() dans src/auto-reply/reply/session.ts.
Schéma du magasin de sessions (sessions.json)
Section intitulée « Schéma du magasin de sessions (sessions.json) »Le type de valeur du magasin est SessionEntry dans src/config/sessions.ts.
Champs clés (liste non exhaustive) :
sessionId: id de la transcription actuelle (le nom de fichier est dérivé de celui-ci sauf sisessionFileest défini)updatedAt: horodatage de la dernière activitésessionFile: remplacement explicite optionnel du chemin de la transcriptionchatType:direct | group | room(aide les interfaces utilisateur et la stratégie d’envoi)provider,subject,room,space,displayName: métadonnées pour l’étiquetage de groupe/canal- Bascules :
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(remplacement par session)
- Sélection du modèle :
providerOverride,modelOverride,authProfileOverride
- Compteurs de jetons (best-effort / dépendant du fournisseur) :
inputTokens,outputTokens,totalTokens,contextTokens
compactionCount: fréquence à laquelle l’auto-compaction s’est terminée pour cette clé de sessionmemoryFlushAt: horodatage de la dernière vidange de mémoire pré-compactionmemoryFlushCompactionCount: compteur de compactage lors de la dernière exécution de vidange
Le magasin peut être modifié en toute sécurité, mais le Gateway fait autorité : il peut réécrire ou réhydrater les entrées au fur et à mesure que les sessions s’exécutent.
Structure de la transcription (*.jsonl)
Section intitulée « Structure de la transcription (*.jsonl) »Les transcriptions sont gérées par le SessionManager de @mariozechner/pi-coding-agent.
Le fichier est au format JSONL :
- Première ligne : en-tête de session (
type: "session", inclutid,cwd,timestamp,parentSessionen option) - Ensuite : entrées de session avec
id+parentId(arborescence)
Types d’entrées notables :
message: messages utilisateur/assistant/toolResultcustom_message: messages injectés par l’extension qui entrent dans le contexte du modèle (peuvent être masqués dans l’interface utilisateur)custom: état de l’extension qui n’entre pas dans le contexte du modèlecompaction: résumé de compactage persisté avecfirstKeptEntryIdettokensBeforebranch_summary: résumé persisté lors de la navigation dans une branche d’arborescence
OpenClaw ne “corrige” pas intentionnellement les transcriptions ; le Gateway utilise SessionManager pour les lire/écrire.
Fenêtres de contexte vs jetons suivis
Section intitulée « Fenêtres de contexte vs jetons suivis »Deux concepts différents sont importants :
- Fenêtre de contexte du modèle : limite stricte par modèle (jetons visibles par le modèle)
- Compteurs du magasin de sessions : statistiques roulantes écrites dans
sessions.json(utilisés pour /status et les tableaux de bord)
Si vous réglez les limites :
- La fenêtre de contexte provient du catalogue de modèles (et peut être remplacée via la configuration).
contextTokensdans le magasin est une valeur d’estimation/ de rapport à l’exécution ; ne la traitez pas comme une garantie stricte.
Pour plus d’informations, consultez /token-use.
Compactage : ce que c’est
Section intitulée « Compactage : ce que c’est »La compression résume l’ancienne conversation dans une entrée compaction persistée dans la transcription et conserve les messages récents intacts.
Après la compression, les futurs tours voient :
- Le résumé de la compression
- Messages après
firstKeptEntryId
La compression est persistante (contrairement à l’élagage de session). Voir /concepts/session-pruning.
Quand la compression automatique se produit (exécution Pi)
Section intitulée « Quand la compression automatique se produit (exécution Pi) »Dans l’agent Pi embarqué, la compression automatique se déclenche dans deux cas :
- Récupération de dépassement : le modèle renvoie une erreur de dépassement de contexte → compresser → réessayer.
- Maintenance de seuil : après un tour réussi, lorsque :
contextTokens > contextWindow - reserveTokens
Où :
contextWindowest la fenêtre contextuelle du modèlereserveTokensest la marge réservée pour les invites (prompts) + la prochaine sortie du modèle
Ce sont les sémantiques d’exécution de Pi (OpenClaw consomme les événements, mais Pi décide quand compresser).
Paramètres de compression (reserveTokens, keepRecentTokens)
Section intitulée « Paramètres de compression (reserveTokens, keepRecentTokens) »Les paramètres de compression de Pi résident dans les paramètres Pi :
{ compaction: { enabled: true, reserveTokens: 16384, keepRecentTokens: 20000, },}OpenClaw applique également un seuil de sécurité minimal pour les exécutions embarquées :
- Si
compaction.reserveTokens < reserveTokensFloor, OpenClaw l’augmente. - Le seuil par défaut est
20000jetons. - Définissez
agents.defaults.compaction.reserveTokensFloor: 0pour désactiver le seuil minimal. - S’il est déjà plus élevé, OpenClaw le laisse tel quel.
Pourquoi : laisser suffisamment de marge pour le « nettoyage » (housekeeping) multi-tours (comme les écritures en mémoire) avant que la compression ne devienne inévitable.
Implémentation : ensurePiCompactionReserveTokens() dans src/agents/pi-settings.ts
(appelé depuis src/agents/pi-embedded-runner.ts).
Surfaces visibles par l’utilisateur
Section intitulée « Surfaces visibles par l’utilisateur »Vous pouvez observer la compression et l’état de la session via :
/status(dans n’importe quelle session de chat)openclaw status(CLI)openclaw sessions/sessions --json- Mode détaillé :
🧹 Auto-compaction complete+ nombre de compressions
Nettoyage silencieux (NO_REPLY)
Section intitulée « Nettoyage silencieux (NO_REPLY) »OpenClaw prend en charge les tours « silencieux » pour les tâches en arrière-plan où l’utilisateur ne doit pas voir la sortie intermédiaire.
Convention :
- L’assistant commence sa sortie par
NO_REPLYpour indiquer « ne pas livrer de réponse à l’utilisateur ». - OpenClaw supprime ceci dans la couche de livraison.
Depuis 2026.1.10, OpenClaw supprime également le streaming de brouillon/frappe lorsqu’un partiel commence par NO_REPLY, afin que les opérations silencieuses ne fuient pas de sortie partielle en milieu de tour.
Pré-compaction “vidange de la mémoire” (implémenté)
Section intitulée « Pré-compaction “vidange de la mémoire” (implémenté) »Objectif : avant que l’auto-compaction ne se produise, exécuter un tour agent silencieux qui écrit un état durable sur le disque (par exemple memory/YYYY-MM-DD.md dans l’espace de travail de l’agent) afin que la compaction ne puisse pas effacer le contexte critique.
OpenClaw utilise l’approche de vidange pré-seuil :
- Surveiller l’utilisation du contexte de session.
- Lorsqu’il dépasse un “seuil souple” (en dessous du seuil de compaction de Pi), exécuter une directive silencieuse “écrire la mémoire maintenant” à l’agent.
- Utilisez
NO_REPLYpour que l’utilisateur ne voie rien.
Config (agents.defaults.compaction.memoryFlush) :
enabled(par défaut :true)softThresholdTokens(par défaut :4000)prompt(message utilisateur pour le tour de vidange)systemPrompt(invite système supplémentaire ajoutée pour le tour de vidange)
Notes :
- L’invite système par défaut inclut un indice
NO_REPLYpour supprimer la livraison. - La vidange s’exécute une fois par cycle de compaction (suivie dans
sessions.json). - La vidange ne s’exécute que pour les sessions Pi intégrées (les backends CLI l’ignorent).
- La vidange est ignorée lorsque l’espace de travail de la session est en lecture seule (
workspaceAccess: "ro"ou"none"). - Voir Mémoire pour la disposition des fichiers de l’espace de travail et les modèles d’écriture.
Pi expose également un hook session_before_compact dans l’API d’extension, mais la logique de vidange d’OpenClaw réside aujourd’hui du côté de la Gateway.
Liste de contrôle de dépannage
Section intitulée « Liste de contrôle de dépannage »- Clé de session incorrecte ? Commencez par /concepts/session et confirmez le
sessionKeydans/status. - Inadéquation entre le magasin et la transcription ? Confirmez l’hôte de la Gateway et le chemin du magasin à partir de
openclaw status. - Spam de compaction ? Vérifiez :
- fenêtre de contexte du modèle (trop petite)
- paramètres de compactage (
reserveTokenstrop élevés pour la fenêtre du model peuvent entraîner un compactage plus précoce) - bloat des résultats de tool : activez/réglez l’élagage de session
- Fuites de tours silencieux ? Confirmez que la réponse commence par
NO_REPLY(jeton exact) et que vous êtes sur une version qui inclut le correctif de suppression du streaming.