Zarządzanie sesjami i kompaktowanie (dogłębna analiza)
Ten dokument wyjaśnia, jak OpenClaw zarządza sesjami od początku do końca:- Routing sesji (jak wiadomości przychodzące mapują się na
sessionKey) - Magazyn sesji (
sessions.json) i co śledzi - Utrwalanie transkryptów (
*.jsonl) oraz ich struktura - Higiena transkryptów (poprawki specyficzne dla dostawcy przed uruchomieniami)
- Limity kontekstu (okno kontekstu vs śledzone tokeny)
- Kompaktowanie (ręczne + automatyczne) oraz miejsca podpięcia prac przed kompaktowaniem
- Ciche porządkowanie (np. zapisy pamięci, które nie powinny generować widocznego dla użytkownika wyjścia)
Źródło prawdy: Gateway
OpenClaw jest zaprojektowany wokół pojedynczego procesu Gateway, który jest właścicielem stanu sesji.- Interfejsy użytkownika (aplikacja na macOS, webowy Control UI, TUI) powinny odpytywać Gateway o listy sesji i liczniki tokenów.
- W trybie zdalnym pliki sesji znajdują się na hoście zdalnym; „sprawdzanie lokalnych plików na Macu” nie odzwierciedla tego, czego używa Gateway.
Dwie warstwy trwałości
OpenClaw utrwala sesje w dwóch warstwach:-
Magazyn sesji (
sessions.json)- Mapa klucz/wartość:
sessionKey -> SessionEntry - Mały, mutowalny, bezpieczny do edycji (lub usuwania wpisów)
- Śledzi metadane sesji (bieżący identyfikator sesji, ostatnią aktywność, przełączniki, liczniki tokenów itp.)
- Mapa klucz/wartość:
-
Transkrypt (
<sessionId>.jsonl)- Transkrypt typu append-only ze strukturą drzewa (wpisy mają
id+parentId) - Przechowuje faktyczną rozmowę + wywołania narzędzi + podsumowania kompaktowania
- Używany do odbudowy kontekstu modelu dla kolejnych tur
- Transkrypt typu append-only ze strukturą drzewa (wpisy mają
Lokalizacje na dysku
Na agenta, na hoście Gateway:- Magazyn:
~/.openclaw/agents/<agentId>/sessions/sessions.json - Transkrypty:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl- Sesje tematów Telegrama:
.../<sessionId>-topic-<threadId>.jsonl
- Sesje tematów Telegrama:
src/config/sessions.ts.
Klucze sesji (sessionKey)
sessionKey identyfikuje do którego koszyka rozmów należysz (routing + izolacja).
Typowe wzorce:
- Główna/bezpośrednia rozmowa (na agenta):
agent:<agentId>:<mainKey>(domyślniemain) - Grupa:
agent:<agentId>:<channel>:group:<id> - Pokój/kanał (Discord/Slack):
agent:<agentId>:<channel>:channel:<id>lub...:room:<id> - Cron:
cron:<job.id> - Webhook:
hook:<uuid>(o ile nie nadpisano)
Identyfikatory sesji (sessionId)
Każdy sessionKey wskazuje na bieżący sessionId (plik transkryptu, który kontynuuje rozmowę).
Zasady praktyczne:
- Reset (
/new,/reset) tworzy nowysessionIddla tegosessionKey. - Reset dzienny (domyślnie 4:00 czasu lokalnego na hoście gateway) tworzy nowy
sessionIdprzy następnej wiadomości po granicy resetu. - Wygaśnięcie bezczynności (
session.reset.idleMinuteslub legacysession.idleMinutes) tworzy nowysessionId, gdy wiadomość nadejdzie po oknie bezczynności. Gdy skonfigurowane są oba (dzienny + bezczynność), wygrywa to, które wygaśnie pierwsze.
initSessionState() w src/auto-reply/reply/session.ts.
Schemat magazynu sesji (sessions.json)
Typem wartości magazynu jest SessionEntry w src/config/sessions.ts.
Kluczowe pola (lista niepełna):
sessionId: bieżący identyfikator transkryptu (nazwa pliku jest od niego wyprowadzana, chyba że ustawionosessionFile)updatedAt: znacznik czasu ostatniej aktywnościsessionFile: opcjonalne jawne nadpisanie ścieżki transkryptuchatType:direct | group | room(pomaga interfejsom UI i polityce wysyłki)provider,subject,room,space,displayName: metadane do etykietowania grup/kanałów- Przełączniki:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(nadpisanie per sesję)
- Wybór modelu:
providerOverride,modelOverride,authProfileOverride
- Liczniki tokenów (best-effort / zależne od dostawcy):
inputTokens,outputTokens,totalTokens,contextTokens
compactionCount: jak często auto-kompaktowanie zakończyło się dla tego klucza sesjimemoryFlushAt: znacznik czasu ostatniego opróżnienia pamięci przed kompaktowaniemmemoryFlushCompactionCount: liczba kompaktowań w momencie ostatniego uruchomienia opróżnienia
Struktura transkryptu (*.jsonl)
Transkrypty są zarządzane przez @mariozechner/pi-coding-agent w SessionManager.
Plik jest w formacie JSONL:
- Pierwsza linia: nagłówek sesji (
type: "session", zawieraid,cwd,timestamp, opcjonalnieparentSession) - Następnie: wpisy sesji z
id+parentId(drzewo)
message: wiadomości użytkownik/asystent/toolResultcustom_message: wiadomości wstrzykiwane przez rozszerzenia, które wchodzą do kontekstu modelu (mogą być ukryte w UI)custom: stan rozszerzenia, który nie wchodzi do kontekstu modelucompaction: utrwalone podsumowanie kompaktowania zfirstKeptEntryIditokensBeforebranch_summary: utrwalone podsumowanie przy nawigacji po gałęzi drzewa
SessionManager do ich odczytu/zapisu.
Okna kontekstu vs śledzone tokeny
Istotne są dwie różne koncepcje:- Okno kontekstu modelu: twardy limit per model (tokeny widoczne dla modelu)
- Liczniki magazynu sesji: statystyki kroczące zapisywane w
sessions.json(używane przez /status i dashboardy)
- Okno kontekstu pochodzi z katalogu modeli (i może być nadpisane przez konfigurację).
contextTokensw magazynie to wartość szacunkowa/raportowa w czasie działania; nie traktuj jej jako ścisłej gwarancji.
Kompaktowanie: czym jest
Kompaktowanie streszcza starszą część rozmowy do utrwalonego wpisucompaction w transkrypcie i zachowuje nienaruszone nowsze wiadomości.
Po kompaktowaniu kolejne tury widzą:
- Podsumowanie kompaktowania
- Wiadomości po
firstKeptEntryId
Kiedy zachodzi auto-kompaktowanie (runtime Pi)
W osadzonym agencie Pi auto-kompaktowanie uruchamia się w dwóch przypadkach:- Odzyskiwanie po przepełnieniu: model zwraca błąd przepełnienia kontekstu → kompaktowanie → ponowienie.
- Utrzymanie progu: po udanej turze, gdy:
contextTokens > contextWindow - reserveTokens
Gdzie:
contextWindowto okno kontekstu modelureserveTokensto zapas zarezerwowany na prompt + następne wyjście modelu
Ustawienia kompaktowania (reserveTokens, keepRecentTokens)
Ustawienia kompaktowania Pi znajdują się w ustawieniach Pi:
- Jeśli
compaction.reserveTokens < reserveTokensFloor, OpenClaw go podnosi. - Domyślny próg minimalny to
20000tokenów. - Ustaw
agents.defaults.compaction.reserveTokensFloor: 0, aby wyłączyć próg minimalny. - Jeśli jest już wyższy, OpenClaw pozostawia go bez zmian.
ensurePiCompactionReserveTokens() w src/agents/pi-settings.ts
(wywoływane z src/agents/pi-embedded-runner.ts).
Powierzchnie widoczne dla użytkownika
Możesz obserwować kompaktowanie i stan sesji poprzez:/status(w dowolnej sesji czatu)openclaw status(CLI)openclaw sessions/sessions --json- Tryb szczegółowy:
🧹 Auto-compaction complete+ licznik kompaktowań
Ciche gospodarstwo domowe (NO_REPLY)
OpenClaw obsługuje „ciche” tury dla zadań w tle, w których użytkownik nie powinien widzieć wyjścia pośredniego.
Konwencja:
- Asystent rozpoczyna swoje wyjście od
NO_REPLY, aby wskazać „nie dostarczać odpowiedzi użytkownikowi”. - OpenClaw usuwa/tłumi to w warstwie dostarczania.
2026.1.10 OpenClaw tłumi także strumieniowanie szkiców/wskaźników pisania, gdy częściowy fragment zaczyna się od NO_REPLY, dzięki czemu ciche operacje nie ujawniają częściowego wyjścia w trakcie tury.
„Opróżnianie pamięci” przed kompaktowaniem (zaimplementowane)
Cel: zanim dojdzie do auto-kompaktowania, uruchomić cichą, agentową turę, która zapisze trwały stan na dysk (np.memory/YYYY-MM-DD.md w obszarze roboczym agenta), tak aby kompaktowanie nie mogło
wymazać krytycznego kontekstu.
OpenClaw stosuje podejście opróżnienia przed progiem:
- Monitoruj użycie kontekstu sesji.
- Gdy przekroczy „miękki próg” (poniżej progu kompaktowania Pi), uruchom ciche polecenie „zapisz pamięć teraz” do agenta.
- Użyj
NO_REPLY, aby użytkownik nic nie zobaczył.
agents.defaults.compaction.memoryFlush):
enabled(domyślnie:true)softThresholdTokens(domyślnie:4000)prompt(wiadomość użytkownika dla tury opróżniania)systemPrompt(dodatkowy prompt systemowy dołączany do tury opróżniania)
- Domyślne prompty (użytkownika/systemowy) zawierają wskazówkę
NO_REPLYdo tłumienia dostarczania. - Opróżnienie uruchamia się raz na cykl kompaktowania (śledzone w
sessions.json). - Opróżnienie działa tylko dla osadzonych sesji Pi (backendy CLI je pomijają).
- Opróżnienie jest pomijane, gdy obszar roboczy sesji jest tylko do odczytu (
workspaceAccess: "ro"lub"none"). - Zobacz Memory, aby poznać układ plików obszaru roboczego i wzorce zapisu.
session_before_compact w API rozszerzeń, jednak logika opróżniania OpenClaw znajduje się dziś po stronie Gateway.
Lista kontrolna rozwiązywania problemów
- Zły klucz sesji? Zacznij od /concepts/session i potwierdź
sessionKeyw/status. - Niezgodność magazyn vs transkrypt? Potwierdź host Gateway i ścieżkę magazynu z
openclaw status. - Nadmierne kompaktowanie? Sprawdź:
- okno kontekstu modelu (zbyt małe)
- ustawienia kompaktowania (
reserveTokenszbyt wysokie względem okna modelu może powodować wcześniejsze kompaktowanie) - nadmiar tool-result: włącz/dostrój przycinanie sesji
- Ciche skręty przeciekają? Potwierdź, że odpowiedź zaczyna się od
NO_REPLY(dokładny token) i że używasz wersji zawierającej poprawkę tłumienia strumieniowania.