Gestion des sessions
OpenClaw traite une session de discussion directe par agent comme principale. Les discussions directes sont réduites à agent:<agentId>:<mainKey> (par défaut main), tandis que les discussions de groupe/canal obtiennent leurs propres clés. session.mainKey est respectée. Utilisez session.dmScope pour contrôler comment les messages directs sont regroupés :
main(par défaut) : tous les DM partagent la session principale pour la continuité.per-peer: isoler par identifiant de l'expéditeur à travers les canaux.per-channel-peer: isoler par canal + expéditeur (recommandé pour les boîtes de réception multi-utilisateurs).per-account-channel-peer: isoler par compte + canal + expéditeur (recommandé pour les boîtes de réception multi-comptes). Utilisezsession.identityLinkspour mapper les identifiants de pairs préfixés par le fournisseur à une identité canonique afin que la même personne partage une session DM à travers les canaux lors de l'utilisation deper-peer,per-channel-peerouper-account-channel-peer.
Mode DM sécurisé (recommandé pour les configurations multi-utilisateurs)
Avertissement de sécurité : Si votre agent peut recevoir des DM de plusieurs personnes, vous devriez sérieusement envisager d'activer le mode DM sécurisé. Sans cela, tous les utilisateurs partagent le même contexte de conversation, ce qui peut divulguer des informations privées entre utilisateurs.
Exemple du problème avec les paramètres par défaut :
- Alice (
<SENDER_A>) envoie un message à votre agent sur un sujet privé (par exemple, un rendez-vous médical) - Bob (
<SENDER_B>) envoie un message à votre agent demandant "De quoi parlions-nous ?" - Parce que les deux DM partagent la même session, le modèle peut répondre à Bob en utilisant le contexte précédent d'Alice.
La solution : Définissez dmScope pour isoler les sessions par utilisateur :
// ~/.openclaw/openclaw.json
{
session: {
// Mode DM sécurisé : isoler le contexte DM par canal + expéditeur.
dmScope: "per-channel-peer",
},
}
Quand activer ceci :
- Vous avez des approbations d'appariement pour plus d'un expéditeur
- Vous utilisez une liste d'autorisation DM avec plusieurs entrées
- Vous définissez
dmPolicy: "open" - Plusieurs numéros de téléphone ou comptes peuvent envoyer des messages à votre agent
Notes :
- La valeur par défaut est
dmScope: "main"pour la continuité (tous les DM partagent la session principale). C'est acceptable pour les configurations mono-utilisateur. - L'intégration en ligne de commande locale écrit
session.dmScope: "per-channel-peer"par défaut lorsqu'elle n'est pas définie (les valeurs explicites existantes sont préservées). - Pour les boîtes de réception multi-comptes sur le même canal, préférez
per-account-channel-peer. - Si la même personne vous contacte sur plusieurs canaux, utilisez
session.identityLinkspour fusionner ses sessions DM en une seule identité canonique. - Vous pouvez vérifier vos paramètres DM avec
openclaw security audit(voir sécurité).
La passerelle est la source de vérité
Tout l'état de la session est détenu par la passerelle (le "maître" OpenClaw). Les clients d'interface utilisateur (application macOS, WebChat, etc.) doivent interroger la passerelle pour les listes de sessions et les décomptes de jetons au lieu de lire les fichiers locaux.
- En mode distant, le magasin de sessions qui vous intéresse se trouve sur l'hôte de la passerelle distante, pas sur votre Mac.
- Les décomptes de jetons affichés dans les interfaces utilisateur proviennent des champs de stockage de la passerelle (
inputTokens,outputTokens,totalTokens,contextTokens). Les clients n'analysent pas les transcriptions JSONL pour "corriger" les totaux.
Où se trouve l'état
- Sur l'hôte de la passerelle :
- Fichier de stockage :
~/.openclaw/agents/<agentId>/sessions/sessions.json(par agent).
- Fichier de stockage :
- Transcripts :
~/.openclaw/agents/<agentId>/sessions/<SessionId>.jsonl(les sessions de sujets Telegram utilisent.../<SessionId>-topic-<threadId>.jsonl). - Le stockage est une carte
sessionKey -> { sessionId, updatedAt, ... }. Supprimer des entrées est sûr ; elles sont recréées à la demande. - Les entrées de groupe peuvent inclure
displayName,channel,subject,roometspacepour étiqueter les sessions dans les interfaces utilisateur. - Les entrées de session incluent des métadonnées
origin(étiquette + indices de routage) pour que les interfaces utilisateur puissent expliquer d'où vient une session. - OpenClaw ne lit pas les dossiers de sessions Pi/Tau hérités.
Maintenance
OpenClaw applique une maintenance du magasin de sessions pour garder sessions.json et les artefacts de transcription limités dans le temps.
Valeurs par défaut
session.maintenance.mode:warnsession.maintenance.pruneAfter:30dsession.maintenance.maxEntries:500session.maintenance.rotateBytes:10mbsession.maintenance.resetArchiveRetention: par défautpruneAfter(30d)session.maintenance.maxDiskBytes: non défini (désactivé)session.maintenance.highWaterBytes: par défaut80%demaxDiskByteslorsque la budgétisation est activée
Comment cela fonctionne
La maintenance s'exécute pendant les écritures dans le magasin de sessions, et vous pouvez la déclencher à la demande avec openclaw sessions cleanup.
mode: "warn": rapporte ce qui serait évincé mais ne modifie pas les entrées/transcriptions.mode: "enforce": applique le nettoyage dans cet ordre :- élaguer les entrées périmées plus anciennes que
pruneAfter - limiter le nombre d'entrées à
maxEntries(les plus anciennes d'abord) - archiver les fichiers de transcription pour les entrées supprimées qui ne sont plus référencées
- purger les anciennes archives
*.deleted.<timestamp>et*.reset.<timestamp>selon la politique de rétention - faire tourner
sessions.jsonlorsqu'il dépasserotateBytes - si
maxDiskBytesest défini, appliquer le budget disque vershighWaterBytes(les artefacts les plus anciens d'abord, puis les sessions les plus anciennes)
- élaguer les entrées périmées plus anciennes que
Mise en garde sur les performances pour les grands magasins
Les grands magasins de sessions sont courants dans les configurations à volume élevé. Le travail de maintenance est un travail sur le chemin d'écriture, donc les très grands magasins peuvent augmenter la latence d'écriture. Ce qui augmente le plus le coût :
- des valeurs
session.maintenance.maxEntriestrès élevées - de longues fenêtres
pruneAfterqui gardent des entrées périmées - de nombreux artefacts de transcription/archive dans
~/.openclaw/agents/<agentId>/sessions/ - activer les budgets disque (
maxDiskBytes) sans limites d'élagage/plafond raisonnables
Que faire :
- utilisez
mode: "enforce"en production pour que la croissance soit automatiquement limitée - définissez à la fois des limites de temps et de nombre (
pruneAfter+maxEntries), pas seulement une - définissez
maxDiskBytes+highWaterBytespour des limites supérieures strictes dans les grands déploiements - gardez
highWaterBytessignificativement en dessous demaxDiskBytes(la valeur par défaut est 80%) - exécutez
openclaw sessions cleanup --dry-run --jsonaprès les changements de configuration pour vérifier l'impact projeté avant de l'appliquer - pour les sessions actives fréquentes, passez
--active-keylors de l'exécution d'un nettoyage manuel
Exemples de personnalisation
Utilisez une politique d'application conservatrice :
{
session: {
maintenance: {
mode: "enforce",
pruneAfter: "45d",
maxEntries: 800,
rotateBytes: "20mb",
resetArchiveRetention: "14d",
},
},
}
Activez un budget disque strict pour le répertoire des sessions :
{
session: {
maintenance: {
mode: "enforce",
maxDiskBytes: "1gb",
highWaterBytes: "800mb",
},
},
}
Ajustez pour les installations plus grandes (exemple) :
{
session: {
maintenance: {
mode: "enforce",
pruneAfter: "14d",
maxEntries: 2000,
rotateBytes: "25mb",
maxDiskBytes: "2gb",
highWaterBytes: "1.6gb",
},
},
}
Prévisualisez ou forcez la maintenance depuis la ligne de commande :
openclaw sessions cleanup --dry-run
openclaw sessions cleanup --enforce
Élagage des sessions
Par défaut, OpenClaw supprime les anciens résultats d'outils du contexte en mémoire juste avant les appels LLM. Cela ne réécrit pas l'historique JSONL. Voir /concepts/session-pruning.
Vidage de mémoire pré-compaction
Lorsqu'une session approche de la compaction automatique, OpenClaw peut exécuter un tour de vidage de mémoire silencieux qui rappelle au modèle d'écrire des notes durables sur le disque. Cela ne s'exécute que lorsque l'espace de travail est accessible en écriture. Voir Mémoire et Compaction.
Cartographie des transports → clés de session
- Les discussions directes suivent
session.dmScope(par défautmain).main:agent:<agentId>:<mainKey>(continuité à travers les appareils/canaux).- Plusieurs numéros de téléphone et canaux peuvent correspondre à la même clé principale d'agent ; ils agissent comme des transports vers une conversation unique.
per-peer:agent:<agentId>:dm:<peerId>.per-channel-peer:agent:<agentId>:<channel>:dm:<peerId>.per-account-channel-peer:agent:<agentId>:<channel>:<accountId>:dm:<peerId>(accountId par défautdefault).- Si
session.identityLinkscorrespond à un identifiant de pair préfixé par le fournisseur (par exempletelegram:123), la clé canonique remplace<peerId>pour que la même personne partage une session à travers les canaux.
- Les discussions de groupe isolent l'état :
agent:<agentId>:<channel>:group:<id>(les salles/canaux utilisentagent:<agentId>:<channel>:channel:<id>).- Les sujets de forum Telegram ajoutent
:topic:<threadId>à l'identifiant de groupe pour l'isolation. - Les clés héritées
group:<id>sont toujours reconnues pour la migration.
- Les sujets de forum Telegram ajoutent
- Les contextes entrants peuvent encore utiliser
group:<id>; le canal est déduit deProvideret normalisé vers la forme canoniqueagent:<agentId>:<channel>:group:<id>. - Autres sources :
- Tâches cron :
cron:<job.id> - Webhooks :
hook:<uuid>(sauf s'il est explicitement défini par le webhook) - Exécutions de nœuds :
node-<nodeId>
- Tâches cron :
Cycle de vie
- Politique de réinitialisation : les sessions sont réutilisées jusqu'à leur expiration, et l'expiration est évaluée au prochain message entrant.
- Réinitialisation quotidienne : par défaut à 4h00 heure locale sur l'hôte de la passerelle. Une session est périmée une fois que sa dernière mise à jour est antérieure à l'heure de réinitialisation quotidienne la plus récente.
- Réinitialisation d'inactivité (optionnelle) :
idleMinutesajoute une fenêtre d'inactivité glissante. Lorsque les réinitialisations quotidiennes et d'inactivité sont configurées, celle qui expire en premier force une nouvelle session. - Inactivité seule héritée : si vous définissez
session.idleMinutessans aucune configurationsession.reset/resetByType, OpenClaw reste en mode inactivité seule pour la rétrocompatibilité. - Remplacements par type (optionnels) :
resetByTypevous permet de remplacer la politique pour les sessionsdirect,groupetthread(thread = fils Slack/Discord, sujets Telegram, fils Matrix lorsqu'ils sont fournis par le connecteur). - Remplacements par canal (optionnels) :
resetByChannelremplace la politique de réinitialisation pour un canal (s'applique à tous les types de sessions pour ce canal et prend la priorité surreset/resetByType). - Déclencheurs de réinitialisation : les commandes exactes
/newou/reset(plus tout extra dansresetTriggers) démarrent un nouvel identifiant de session et transmettent le reste du message./new <model>accepte un alias de modèle,provider/modelou un nom de fournisseur (correspondance approximative) pour définir le modèle de la nouvelle session. Si/newou/resetest envoyé seul, OpenClaw exécute un court tour de salutation "bonjour" pour confirmer la réinitialisation. - Réinitialisation manuelle : supprimez des clés spécifiques du magasin ou supprimez la transcription JSONL ; le prochain message les recrée.
- Les tâches cron isolées créent toujours un nouveau
sessionIdpar exécution (pas de réutilisation en cas d'inactivité).
Politique d'envoi (optionnelle)
Bloquez la livraison pour des types de sessions spécifiques sans lister les identifiants individuels.
{
session: {
sendPolicy: {
rules: [
{ action: "deny", match: { channel: "discord", chatType: "group" } },
{ action: "deny", match: { keyPrefix: "cron:" } },
// Correspond à la clé de session brute (incluant le préfixe `agent:<id>:`).
{ action: "deny", match: { rawKeyPrefix: "agent:main:discord:" } },
],
default: "allow",
},
},
}
Remplacement à l'exécution (propriétaire uniquement) :
/send on→ autoriser pour cette session/send off→ refuser pour cette session/send inherit→ effacer le remplacement et utiliser les règles de configuration Envoyez-les comme messages autonomes pour qu'ils soient enregistrés.
Configuration (exemple de renommage optionnel)
// ~/.openclaw/openclaw.json
{
session: {
scope: "per-sender", // garder les clés de groupe séparées
dmScope: "main", // continuité DM (définir per-channel-peer/per-account-channel-peer pour les boîtes de réception partagées)
identityLinks: {
alice: ["telegram:123456789", "discord:987654321012345678"],
},
reset: {
// Valeurs par défaut : mode=daily, atHour=4 (heure locale de l'hôte de la passerelle).
// Si vous définissez également idleMinutes, celui qui expire en premier l'emporte.
mode: "daily",
atHour: 4,
idleMinutes: 120,
},
resetByType: {
thread: { mode: "daily", atHour: 4 },
direct: { mode: "idle", idleMinutes: 240 },
group: { mode: "idle", idleMinutes: 120 },
},
resetByChannel: {
discord: { mode: "idle", idleMinutes: 10080 },
},
resetTriggers: ["/new", "/reset"],
store: "~/.openclaw/agents/{agentId}/sessions/sessions.json",
mainKey: "main",
},
}
Inspection
openclaw status— montre le chemin du magasin et les sessions récentes.openclaw sessions --json— exporte chaque entrée (filtrer avec--active <minutes>).openclaw gateway call sessions.list --params '{}'— récupère les sessions depuis la passerelle en cours d'exécution (utilisez--url/--tokenpour l'accès à une passerelle distante).- Envoyez
/statuscomme message autonome dans le chat pour voir si l'agent est joignable, combien du contexte de session est utilisé, les bascules de réflexion/verbose actuelles, et quand vos identifiants WhatsApp web ont été actualisés pour la dernière fois (aide à détecter les besoins de re-liaison). - Envoyez
/context listou/context detailpour voir ce qui se trouve dans l'invite système et les fichiers d'espace de travail injectés (et les plus grands contributeurs de contexte). - Envoyez
/stop(ou des phrases d'abandon autonomes commestop,stop action,stop run,stop openclaw) pour abandonner l'exécution en cours, effacer les suivis en file d'attente pour cette session et arrêter toute exécution de sous-agent lancée depuis celle-ci (la réponse inclut le nombre d'arrêts). - Envoyez
/compact(instructions optionnelles) comme message autonome pour résumer le contexte plus ancien et libérer de l'espace dans la fenêtre. Voir /concepts/compaction. - Les transcriptions JSONL peuvent être ouvertes directement pour revoir les tours complets.
Conseils
- Gardez la clé principale dédiée au trafic 1:1 ; laissez les groupes garder leurs propres clés.
- Lors de l'automatisation du nettoyage, supprimez des clés individuelles au lieu de tout le magasin pour préserver le contexte ailleurs.
Métadonnées d'origine de session
Chaque entrée de session enregistre d'où elle vient (au mieux) dans origin :
label: étiquette humaine (résolue à partir de l'étiquette de conversation + sujet/groupe/canal)provider: identifiant de canal normalisé (incluant les extensions)from/to: identifiants de routage bruts de l'enveloppe entranteaccountId: identifiant de compte du fournisseur (en multi-compte)threadId: identifiant de fil/sujet lorsque le canal le supporte Les champs d'origine sont remplis pour les messages directs, les canaux et les groupes. Si un connecteur ne met à jour que le routage de livraison (par exemple, pour garder une session DM principale fraîche), il devrait quand même fournir un contexte entrant pour que la session conserve ses métadonnées explicatives. Les extensions peuvent faire cela en envoyantConversationLabel,GroupSubject,GroupChannel,GroupSpaceetSenderNamedans le contexte entrant et en appelantrecordSessionMetaFromInbound(ou en passant le même contexte àupdateLastRoute).