Community translations by veiseule.ai — Help improve them on Crowdin
Skip to main content

Sessionshantering och kompaktering (fördjupning)

Det här dokumentet förklarar hur OpenClaw hanterar sessioner från början till slut:

  • Sessionsroutning (hur inkommande meddelanden mappar till en sessionKey)
  • Sessionslagring (sessions.json) och vad den spårar
  • Persistens av transkript (*.jsonl) och dess struktur
  • Transkripthygien (leverantörsspecifika korrigeringar före körningar)
  • Kontextgränser (kontextfönster vs spårade tokens)
  • Kompaktering (manuell + automatisk kompaktering) och var man kan haka in arbete före kompaktering
  • Tyst städning (t.ex. minnesskrivningar som inte ska ge användarsynlig utdata)

Om du vill ha en mer övergripande översikt först, börja med:


Sanningskälla: Gateway

OpenClaw är designat kring en enda Gateway-process som äger sessionstillståndet.

  • UI:er (macOS-app, webbaserat Control UI, TUI) ska fråga Gateway om sessionslistor och tokenräkningar.
  • I fjärrläge ligger sessionsfilerna på fjärrvärden; att ”kontrollera dina lokala Mac-filer” återspeglar inte vad Gateway använder.

Två persistenslager

OpenClaw persisterar sessioner i två lager:

  1. Sessionslagring (sessions.json) - Nyckel/värde-karta: sessionKey -> SessionEntry - Liten, muterbar, säker att redigera (eller radera poster) - Spårar sessionsmetadata (aktuellt sessions-id, senaste aktivitet, växlar, tokenräknare m.m.)

  2. Transkript (<sessionId>.jsonl) - Append-only-transkript med trädstruktur (poster har id + parentId) - Lagrar den faktiska konversationen + verktygsanrop + kompakteringssammanfattningar - Används för att bygga upp modellkontexten för framtida vändor


Platser på disk

Per agent, på Gateway-värden:

  • Lagring: ~/.openclaw/agents/<agentId>/sessions/sessions.json
  • Transkript: ~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl
  • Telegram-ämnessessioner: .../<sessionId>-topic-<threadId>.jsonl

OpenClaw löser dessa via src/config/sessions.ts.


Sessionsnycklar (sessionKey)

En sessionKey identifierar vilken konversationshink du befinner dig i (routning + isolering).

Vanliga mönster:

  • Huvud-/direktchatt (per agent): agent:<agentId>:<mainKey> (standard main)
  • Grupp: agent:<agentId>:<channel>:group:<id>
  • Rum/kanal (Discord/Slack): agent:<agentId>:<channel>:channel:<id> eller ...:room:<id>
  • Cron: cron:<job.id>
  • Webhook: hook:<uuid> (om inte åsidosatt)

De kanoniska reglerna är dokumenterade på /concepts/session.


Sessions-id:n (sessionId)

Varje sessionKey pekar på ett aktuellt sessionId (transkriptfilen som fortsätter konversationen).

Tumregler:

  • Återställning (/new, /reset) skapar ett nytt sessionId för den sessionKey.
  • Daglig återställning (standard 04:00 lokal tid på Gateway-värden) skapar ett nytt sessionId vid nästa meddelande efter återställningsgränsen.
  • Idle utgång (session.reset.idleMinutes eller äldre session.idleMinutes) skapar en ny sessionId när ett meddelande kommer efter tomgångsfönstret. När dagligen + inaktiv är båda konfigurerade, vilket som löper ut första vinner.

Implementationsdetalj: beslutet sker i initSessionState() i src/auto-reply/reply/session.ts.


Schema för sessionslagring (sessions.json)

Lagringens värdetyp är SessionEntry i src/config/sessions.ts.

Viktiga fält (inte uttömmande):

  • sessionId: aktuellt transkript-id (filnamn härleds från detta om inte sessionFile är satt)
  • updatedAt: tidsstämpel för senaste aktivitet
  • sessionFile: valfri explicit åsidosättning av transkriptsökväg
  • chatType: direct | group | room (hjälper UI:er och sändpolicy)
  • provider, subject, room, space, displayName: metadata för grupp-/kanaletikettering
  • Växlar:
  • thinkingLevel, verboseLevel, reasoningLevel, elevatedLevel
  • sendPolicy (åsidosättning per session)
  • Modellval:
  • providerOverride, modelOverride, authProfileOverride
  • Tokenräknare (best-effort / leverantörsberoende):
  • inputTokens, outputTokens, totalTokens, contextTokens
  • compactionCount: hur ofta automatisk kompaktering har slutförts för denna sessionsnyckel
  • memoryFlushAt: tidsstämpel för senaste pre-kompakterings-minnesflush
  • memoryFlushCompactionCount: kompakteringsräkning när senaste flush kördes

Lagringen är säker att redigera, men Gateway är auktoriteten: den kan skriva om eller rehydrera poster när sessioner körs.


Transkriptstruktur (*.jsonl)

Transkript hanteras av @mariozechner/pi-coding-agents SessionManager.

Filen är JSONL:

  • Första raden: sessionshuvud (type: "session", inkluderar id, cwd, timestamp, valfri parentSession)
  • Därefter: sessionsposter med id + parentId (träd)

Anmärkningsvärda posttyper:

  • message: användar-/assistent-/toolResult-meddelanden
  • custom_message: tilläggsinjicerade meddelanden som kommer in i modellkontext (kan döljas från UI)
  • custom: tilläggstillstånd som inte kommer in i modellkontext
  • compaction: persisterad kompakteringssammanfattning med firstKeptEntryId och tokensBefore
  • branch_summary: persisterad sammanfattning vid navigering av en trädgren

OpenClaw ”fixar” medvetet inte transkript; Gateway använder SessionManager för att läsa/skriva dem.


Kontextfönster vs spårade tokens

Två olika begrepp är viktiga:

  1. Modellens kontextfönster: hård gräns per modell (tokens synliga för modellen)
  2. Räknare i sessionslagringen: rullande statistik som skrivs till sessions.json (används för /status och dashboards)

Om du justerar gränser:

  • Kontextfönstret kommer från modellkatalogen (och kan åsidosättas via konfig).
  • contextTokens i lagringen är ett körtidsestimat/rapporteringsvärde; behandla det inte som en strikt garanti.

Mer information finns på /token-use.


Kompaktering: vad det är

Kompaktering sammanfattar äldre konversation till en persisterad compaction-post i transkriptet och behåller senaste meddelanden intakta.

Efter kompaktering ser framtida vändor:

  • Kompakteringssammanfattningen
  • Meddelanden efter firstKeptEntryId

Komprimering är persistent (till skillnad från sessionsbeskärning). Se /concepts/session-pruning.


När automatisk kompaktering sker (Pi runtime)

I den inbäddade Pi-agenten triggas automatisk kompaktering i två fall:

  1. Återhämtning vid överskridande: modellen returnerar ett fel om kontextöverskridande → kompakta → försök igen.
  2. Tröskelunderhåll: efter en lyckad vända, när:

contextTokens > contextWindow - reserveTokens

Där:

  • contextWindow är modellens kontextfönster
  • reserveTokens är marginal reserverad för promptar + nästa modellutdata

Detta är semantik i Pi runtime (OpenClaw konsumerar händelserna, men Pi avgör när kompaktering ska ske).


Inställningar för kompaktering (reserveTokens, keepRecentTokens)

Pis kompakteringsinställningar finns i Pi-inställningar:

{
  compaction: {
    enabled: true,
    reserveTokens: 16384,
    keepRecentTokens: 20000,
  },
}

OpenClaw tillämpar också ett säkerhetsgolv för inbäddade körningar:

  • Om compaction.reserveTokens < reserveTokensFloor, höjer OpenClaw det.
  • Standardgolvet är 20000 tokens.
  • Sätt agents.defaults.compaction.reserveTokensFloor: 0 för att inaktivera golvet.
  • Om det redan är högre lämnar OpenClaw det orört.

Varför: lämna tillräckligt med marginal för flervändors ”städning” (som minnesskrivningar) innan kompaktering blir oundviklig.

Implementering: ensurePiCompactionReserveTokens() i src/agents/pi-settings.ts (anropas från src/agents/pi-embedded-runner.ts).


Användarsynliga ytor

Du kan observera kompaktering och sessionstillstånd via:

  • /status (i valfri chattsession)
  • openclaw status (CLI)
  • openclaw sessions / sessions --json
  • Utförligt läge: 🧹 Auto-compaction complete + kompakteringsräkning

Tyst städning (NO_REPLY)

OpenClaw stöder ”tysta” vändor för bakgrundsuppgifter där användaren inte ska se mellanliggande utdata.

Konvention:

  • Assistenten inleder sin utdata med NO_REPLY för att indikera ”leverera inget svar till användaren”.
  • OpenClaw strimlar/undertrycker detta i leveranslagret.

Från och med 2026.1.10 undertrycker OpenClaw även utkast-/skrivstreaming när ett partiellt chunk börjar med NO_REPLY, så att tysta operationer inte läcker partiell utdata mitt i en vända.


”Minnesflush” före kompaktering (implementerad)

Mål: innan automatisk komprimering händer, kör en tyst agentic tur som skriver hållbar tillstånd till disk (e. . minne/YYY-MM-DD.md i agentens arbetsyta) så komprimering kan inte radera kritiska sammanhang.

OpenClaw använder metoden pre-tröskel-flush:

  1. Övervaka sessionens kontextanvändning.
  2. När den passerar en ”mjuk tröskel” (under Pis kompakteringströskel), kör en tyst ”skriv minne nu”-direktiv till agenten.
  3. Använd NO_REPLY så att användaren inte ser något.

Konfig (agents.defaults.compaction.memoryFlush):

  • enabled (standard: true)
  • softThresholdTokens (standard: 4000)
  • prompt (användarmeddelande för flush-vändan)
  • systemPrompt (extra systemprompt som läggs till för flush-vändan)

Noteringar:

  • Standardprompt/systemprompt innehåller en NO_REPLY-hint för att undertrycka leverans.
  • Flush körs en gång per kompakteringscykel (spåras i sessions.json).
  • Flush körs endast för inbäddade Pi-sessioner (CLI-backends hoppar över den).
  • Flush hoppas över när sessionens arbetsyta är skrivskyddad (workspaceAccess: "ro" eller "none").
  • Se Memory för arbetsytans fillayout och skrivmönster.

Pi exponerar också en session_before_compact-hook i tilläggs-API:t, men OpenClaws flushlogik ligger i dag på Gateway-sidan.


Felsökningschecklista

  • Sessionsnyckel fel? Börja med /concepts/session och bekräfta sessionKey i /status.
  • Lagra vs utskrift felaktigt? Bekräfta Gateway-värden och butikssökvägen från openclaw status.
  • Komprimering skräppost? Kontroll:
  • modellens kontextfönster (för litet)
  • kompakteringsinställningar (reserveTokens för högt i förhållande till modellfönstret kan orsaka tidigare kompaktering)
  • uppblåst tool-result: aktivera/justera session pruning
  • Tysta svängar läckande? Bekräfta svaret börjar med NO_REPLY (exakt token) och du är på en byggnad som inkluderar strömmande dämpning fix.