Sessiebeheer & Compactie (Diepgaande uitleg)¶
Dit document legt uit hoe OpenClaw sessies end-to-end beheert:
- Sessierouting (hoe inkomende berichten worden toegewezen aan een
sessionKey) - Sessiestore (
sessions.json) en wat deze bijhoudt - Transcriptpersistentie (
*.jsonl) en de structuur ervan - Transcript-hygiëne (provider-specifieke correcties vóór runs)
- Contextlimieten (contextvenster versus bijgehouden tokens)
- Compactie (handmatige + auto-compactie) en waar je pre-compactiewerk kunt inhaken
- Stille huishoudtaken (bijv. geheugenschrijvingen die geen voor de gebruiker zichtbare uitvoer mogen produceren)
Wil je eerst een overzicht op hoger niveau, begin dan met:
Bron van waarheid: de Gateway¶
OpenClaw is ontworpen rond één enkel Gateway-proces dat de sessiestatus beheert.
- UI’s (macOS-app, web Control UI, TUI) moeten de Gateway raadplegen voor sessielijsten en tokentellingen.
- In remote-modus staan sessiebestanden op de externe host; “je lokale Mac-bestanden controleren” weerspiegelt niet wat de Gateway gebruikt.
Twee persistentielagen¶
OpenClaw bewaart sessies in twee lagen:
-
Sessiestore (
sessions.json) - Sleutel/waarde-map:sessionKey -> SessionEntry- Klein, muteerbaar, veilig om te bewerken (of items te verwijderen) - Houdt sessiemetadata bij (huidige sessie-id, laatste activiteit, toggles, tokentellers, enz.) -
Transcript (
<sessionId>.jsonl) - Alleen-aanvulbaar transcript met boomstructuur (items hebbenid+parentId) - Slaat het daadwerkelijke gesprek + tool-aanroepen + compactiesamenvattingen op - Wordt gebruikt om de modelcontext voor toekomstige beurten opnieuw op te bouwen
Locaties op schijf¶
Per agent, op de Gateway-host:
- Opslag:
~/.openclaw/agents/<agentId>/sessions/sessions.json - Transcripties:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl - Telegram-topic-sessies:
.../<sessionId>-topic-<threadId>.jsonl
OpenClaw resolveert deze via src/config/sessions.ts.
Sessiesleutels (sessionKey)¶
Een sessionKey identificeert welke conversatie-emmer je gebruikt (routing + isolatie).
Veelvoorkomende patronen:
- Hoofd/direct chat (per agent):
agent:<agentId>:<mainKey>(standaardmain) - Groep:
agent:<agentId>:<channel>:group:<id> - Kamer/kanaal (Discord/Slack):
agent:<agentId>:<channel>:channel:<id>of...:room:<id> - Cron:
cron:<job.id> - Webhook:
hook:<uuid>(tenzij overschreven)
De canonieke regels zijn gedocumenteerd op /concepts/session.
Sessie-id’s (sessionId)¶
Elke sessionKey wijst naar een huidige sessionId (het transcriptbestand dat de conversatie voortzet).
Vuistregels:
- Reset (
/new,/reset) maakt een nieuwesessionIdvoor diesessionKey. - Dagelijkse reset (standaard 4:00 uur lokale tijd op de Gateway-host) maakt een nieuwe
sessionIdbij het eerstvolgende bericht na de resetgrens. - Inactiviteitsverval (
session.reset.idleMinutesof legacysession.idleMinutes) maakt een nieuwesessionIdwanneer een bericht arriveert na het inactiviteitsvenster. Als dagelijkse + inactiviteit beide zijn geconfigureerd, wint degene die het eerst verloopt.
Implementatiedetail: de beslissing gebeurt in initSessionState() in src/auto-reply/reply/session.ts.
Schema van de sessiestore (sessions.json)¶
Het waardetype van de store is SessionEntry in src/config/sessions.ts.
Belangrijke velden (niet uitputtend):
sessionId: huidige transcript-id (bestandsnaam wordt hiervan afgeleid tenzijsessionFileis ingesteld)updatedAt: tijdstempel van laatste activiteitsessionFile: optionele expliciete overschrijving van het transcriptpadchatType:direct | group | room(helpt UI’s en verzendbeleid)provider,subject,room,space,displayName: metadata voor groeps-/kanaallabeling- Toggles:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(per-sessie-overschrijving)- Modelselectie:
providerOverride,modelOverride,authProfileOverride- Tokentellers (best-effort / provider-afhankelijk):
inputTokens,outputTokens,totalTokens,contextTokenscompactionCount: hoe vaak auto-compactie voor deze sessiesleutel is voltooidmemoryFlushAt: tijdstempel van de laatste pre-compactie geheugen-flushmemoryFlushCompactionCount: compactietelling toen de laatste flush draaide
De store is veilig om te bewerken, maar de Gateway is de autoriteit: deze kan items herschrijven of opnieuw hydrateren terwijl sessies lopen.
Transcriptstructuur (*.jsonl)¶
Transcripties worden beheerd door @mariozechner/pi-coding-agent’s SessionManager.
Het bestand is JSONL:
- Eerste regel: sessieheader (
type: "session", bevatid,cwd,timestamp, optioneelparentSession) - Daarna: sessie-items met
id+parentId(boom)
Opvallende itemtypes:
message: user/assistant/toolResult-berichtencustom_message: door extensies geïnjecteerde berichten die wel de modelcontext ingaan (kunnen verborgen zijn voor de UI)custom: extensiestatus die niet de modelcontext ingaatcompaction: persistente compactiesamenvatting metfirstKeptEntryIdentokensBeforebranch_summary: persistente samenvatting bij het navigeren van een boomtak
OpenClaw “repareert” transcripties bewust niet; de Gateway gebruikt SessionManager om ze te lezen/schrijven.
Contextvensters versus bijgehouden tokens¶
Twee verschillende concepten zijn belangrijk:
- Modelcontextvenster: harde limiet per model (tokens zichtbaar voor het model)
- Sessiestore-tellers: rollende statistieken die in
sessions.jsonworden geschreven (gebruikt voor /status en dashboards)
Als je limieten afstelt:
- Het contextvenster komt uit de modelcatalogus (en kan via config worden overschreven).
contextTokensin de store is een runtime-schatting/rapportagewaarde; behandel dit niet als een strikte garantie.
Zie voor meer /token-use.
Compactie: wat het is¶
Compactie vat oudere conversatie samen in een persistente compaction-entry in het transcript en houdt recente berichten intact.
Na compactie zien toekomstige beurten:
- De compactiesamenvatting
- Berichten na
firstKeptEntryId
Compactie is persistent (in tegenstelling tot sessie-pruning). Zie /concepts/session-pruning.
Wanneer auto-compactie plaatsvindt (Pi-runtime)¶
In de ingebedde Pi-agent wordt auto-compactie in twee gevallen getriggerd:
- Overflow-herstel: het model retourneert een context-overflowfout → compacteren → opnieuw proberen.
- Drempelonderhoud: na een succesvolle beurt, wanneer:
contextTokens > contextWindow - reserveTokens
Waarbij:
contextWindowhet contextvenster van het model isreserveTokensgereserveerde ruimte is voor prompts + de volgende modeluitvoer
Dit zijn Pi-runtime-semantiek (OpenClaw consumeert de events, maar Pi beslist wanneer te compacteren).
Compactie-instellingen (reserveTokens, keepRecentTokens)¶
De compactie-instellingen van Pi staan in de Pi-instellingen:
{
compaction: {
enabled: true,
reserveTokens: 16384,
keepRecentTokens: 20000,
},
}
OpenClaw dwingt ook een veiligheidsvloer af voor ingebedde runs:
- Als
compaction.reserveTokens < reserveTokensFloor, verhoogt OpenClaw dit. - Standaardvloer is
20000tokens. - Stel
agents.defaults.compaction.reserveTokensFloor: 0in om de vloer uit te schakelen. - Als deze al hoger is, laat OpenClaw het ongemoeid.
Waarom: voldoende ruimte laten voor meerbeurten-“huishoudtaken” (zoals geheugenschrijvingen) voordat compactie onvermijdelijk wordt.
Implementatie: ensurePiCompactionReserveTokens() in src/agents/pi-settings.ts
(aangeroepen vanuit src/agents/pi-embedded-runner.ts).
Voor de gebruiker zichtbare oppervlakken¶
Je kunt compactie en sessiestatus waarnemen via:
/status(in elke chatsessie)openclaw status(CLI)openclaw sessions/sessions --json- Verbose-modus:
🧹 Auto-compaction complete+ compactietelling
Stille huishoudtaken (NO_REPLY)¶
OpenClaw ondersteunt “stille” beurten voor achtergrondtaken waarbij de gebruiker geen tussentijdse uitvoer mag zien.
Conventie:
- De assistant begint zijn uitvoer met
NO_REPLYom aan te geven “geen antwoord aan de gebruiker afleveren”. - OpenClaw stript/onderdrukt dit in de afleverlaag.
Sinds 2026.1.10 onderdrukt OpenClaw ook concept-/typestreaming wanneer een gedeeltelijke chunk begint met NO_REPLY, zodat stille operaties geen gedeeltelijke uitvoer midden in de beurt lekken.
Pre-compactie “geheugen-flush” (geïmplementeerd)¶
Doel: vóórdat auto-compactie plaatsvindt, een stille agentische beurt uitvoeren die duurzame
status naar schijf schrijft (bijv. memory/YYYY-MM-DD.md in de agent-werkruimte), zodat compactie geen kritieke context kan
wissen.
OpenClaw gebruikt de pre-drempel-flush-aanpak:
- Monitor sessiecontextgebruik.
- Wanneer dit een “zachte drempel” overschrijdt (onder Pi’s compactiedrempel), voer een stille “schrijf nu geheugen”-instructie uit naar de agent.
- Gebruik
NO_REPLYzodat de gebruiker niets ziet.
Config (agents.defaults.compaction.memoryFlush):
enabled(standaard:true)softThresholdTokens(standaard:4000)prompt(gebruikersbericht voor de flush-beurt)systemPrompt(extra systeemprompt die voor de flush-beurt wordt toegevoegd)
Notities:
- De standaardprompt/systeemprompt bevat een
NO_REPLY-hint om aflevering te onderdrukken. - De flush draait eenmaal per compactiecyclus (bijgehouden in
sessions.json). - De flush draait alleen voor ingebedde Pi-sessies (CLI-backends slaan dit over).
- De flush wordt overgeslagen wanneer de sessiewerkruimte alleen-lezen is (
workspaceAccess: "ro"of"none"). - Zie Memory voor de indeling van werkruimtebestanden en schrijfpatronen.
Pi biedt ook een session_before_compact-hook in de extensie-API, maar OpenClaw’s
flush-logica leeft vandaag aan de Gateway-kant.
Checklist voor problemen oplossen¶
- Sessiesleutel onjuist? Begin met /concepts/session en bevestig de
sessionKeyin/status. - Store- versus transcript-mismatch? Bevestig de Gateway-host en het store-pad uit
openclaw status. - Compactiespam? Controleer:
- modelcontextvenster (te klein)
- compactie-instellingen (
reserveTokenste hoog voor het modelvenster kan eerdere compactie veroorzaken) - tool-result-bloat: schakel sessie-pruning in of stel het af
- Lekken stille beurten? Bevestig dat het antwoord begint met
NO_REPLY(exact token) en dat je op een build zit die de streaming-onderdrukkingsfix bevat.