Technical reference
Szczegółowe omówienie zarządzania sesjami
Jeden proces Gateway kompleksowo zarządza stanem sesji. Interfejsy użytkownika (aplikacja macOS, webowy interfejs Control UI, TUI) wysyłają do Gateway zapytania o listy sesji i liczbę tokenów. W trybie zdalnym pliki sesji znajdują się na zdalnym hoście, więc sprawdzanie plików na lokalnym Macu nie odzwierciedla danych używanych przez Gateway.
Najpierw dokumentacja ogólna: Zarządzanie sesjami, Compaction, Przegląd pamięci, Wyszukiwanie w pamięci, Oczyszczanie sesji, Higiena transkrypcji, pełna dokumentacja konfiguracji: Konfiguracja agenta.
Dwie warstwy trwałości
- Wiersze sesji (SQLite dla każdego agenta) - mapa klucz/wartość
sessionKey -> SessionEntry. Modyfikowalny stan środowiska uruchomieniowego zarządzany przez Gateway. Śledzi metadane: identyfikator bieżącej sesji, ostatnią aktywność, przełączniki i liczniki tokenów. - Zdarzenia transkrypcji (SQLite dla każdego agenta) - struktura drzewiasta tylko do dopisywania (wpisy mają
id+parentId). Przechowuje rozmowę, wywołania narzędzi i podsumowania kompaktowania; odtwarza kontekst modelu dla przyszłych tur. Punkty kontrolne kompaktowania są metadanymi skompaktowanej transkrypcji następczej — nowe kompaktowanie nie zapisuje drugiej kopii.checkpoint.*.jsonl.
Starsze instalacje mogą nadal zawierać pliki sessions.json w katalogu agenta sessions/. Pliki te należy traktować jako starsze dane wejściowe migracji wierszy sesji lub jawne cele konserwacji offline. Uruchomienie Gateway i polecenie openclaw doctor --fix automatycznie importują aktywne starsze wiersze oraz historię transkrypcji do magazynu SQLite poszczególnych agentów. Gdy potrzebna jest jawna inspekcja lub dowód walidacji, należy uruchomić openclaw doctor --session-sqlite inspect --session-sqlite-all-agents, a następnie wykonać sekwencję migracji narzędzia Doctor. Jeśli migracja nie powiedzie się po zarchiwizowaniu starszych artefaktów transkrypcji, należy użyć trybu odzyskiwania narzędzia Doctor opisanego w tej sekwencji. Odzyskiwanie korzysta z manifestów migracji, przywraca wyłącznie odpowiednie zarchiwizowane artefakty pomocnicze, na żądanie przygotowuje oczyszczone zgłoszenie problemu w GitHubie i nie powoduje ponownego odczytywania plików JSONL przez aktywne środowisko uruchomieniowe.
Mechanizmy odczytu historii Gateway nie materializują całej transkrypcji, chyba że dana powierzchnia wymaga swobodnego dostępu do danych historycznych. Historia pierwszej strony, osadzona historia czatu, odzyskiwanie po ponownym uruchomieniu oraz kontrole tokenów i użycia korzystają z ograniczonych odczytów końca danych z SQLite. Pełne skanowanie transkrypcji odbywa się za pośrednictwem asynchronicznego indeksu transkrypcji i jest współdzielone przez współbieżne mechanizmy odczytu.
Lokalizacje na dysku
Dla każdego agenta na hoście Gateway (ustalane za pomocą src/config/sessions.ts):
- Magazyn wierszy sesji środowiska uruchomieniowego:
~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite - Wiersze transkrypcji środowiska uruchomieniowego:
~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite - Starsze/zarchiwizowane artefakty transkrypcji:
~/.openclaw/agents/<agentId>/sessions/ - Starsze dane wejściowe migracji wierszy:
~/.openclaw/agents/<agentId>/sessions/sessions.json
Konserwacja magazynu i limity dyskowe
session.maintenance steruje automatyczną konserwacją wierszy sesji SQLite, wierszy transkrypcji SQLite, artefaktów archiwalnych oraz plików pomocniczych trajektorii:
| Klucz | Wartość domyślna | Uwagi |
|---|---|---|
mode |
"enforce" |
lub "warn" (tylko raportowanie, bez modyfikacji) |
pruneAfter |
"30d" |
graniczny wiek nieaktualnych wpisów |
maxEntries |
500 |
limit liczby wpisów sesji |
resetArchiveRetention |
zachowaj (bez limitu wieku) | graniczny wiek archiwów transkrypcji *.reset.*/*.deleted.*; podanie czasu trwania włącza usuwanie |
maxDiskBytes |
2gb |
budżet dyskowy sesji dla każdego agenta; false wyłącza |
highWaterBytes |
80% z maxDiskBytes |
wartość docelowa po oczyszczaniu budżetu |
Zarchiwizowane transkrypcje są domyślnie zachowywane i kompresowane za pomocą zstd (*.jsonl.<reason>.<timestamp>.zst), jeśli środowisko uruchomieniowe to obsługuje, dzięki czemu usunięcie lub zresetowanie sesji nigdy nie powoduje niejawnego odrzucenia historii rozmowy. Budżet dyskowy najpierw usuwa najstarsze archiwa, zanim wpłynie na aktywne sesje.
Aktywne wymuszanie limitu maxDiskBytes w SQLite mierzy dla każdej sesji łączną liczbę bajtów danych JSON wiersza sesji i zdarzeń transkrypcji; starsze wymuszanie limitów podczas konserwacji offline mierzy pliki w wybranym katalogu sesji.
Sesje testowe uruchomień modelu Gateway (klucze pasujące do agent:*:explicit:model-run-<uuid>) mają oddzielny, stały okres przechowywania 24h. To oczyszczanie jest uruchamiane pod presją: następuje wyłącznie po osiągnięciu progu konserwacji lub limitu liczby wpisów sesji i tylko przed globalnym etapem usuwania lub ograniczania liczby nieaktualnych wpisów. Inne jawne sesje nie korzystają z tego okresu przechowywania.
Kolejność wymuszania podczas oczyszczania budżetu dyskowego (mode: "enforce"):
- Najpierw usuń najstarsze zarchiwizowane artefakty transkrypcji, osierocone starsze artefakty lub osierocone artefakty trajektorii.
- Jeśli wartość nadal przekracza cel, usuń najstarsze wpisy sesji wraz z ich wierszami transkrypcji lub artefaktami trajektorii.
- Powtarzaj, aż użycie będzie równe lub niższe niż
highWaterBytes.
mode: "warn" zgłasza potencjalne usunięcia bez modyfikowania magazynu ani plików.
Uruchamianie konserwacji na żądanie:
openclaw sessions cleanup --dry-runopenclaw sessions cleanup --enforceKonserwacja zachowuje trwałe zewnętrzne wskaźniki rozmów, takie jak sesje grupowe i sesje czatu powiązane z wątkiem, ale syntetyczne wpisy środowiska uruchomieniowego (cron, hooki, heartbeat, ACP, podagenci) mogą zostać usunięte po przekroczeniu skonfigurowanego wieku, liczby lub budżetu dyskowego. Izolowane uruchomienia cron korzystają z oddzielnego ustawienia cron.sessionRetention, niezależnego od okresu przechowywania sesji testowych uruchomień modelu.
Zwykłe zapisy Gateway przechodzą przez akcesor sesji, który serializuje modyfikacje SQLite dla poszczególnych agentów za pośrednictwem ścieżki zapisu środowiska uruchomieniowego. Kod środowiska uruchomieniowego powinien preferować funkcje pomocnicze akcesora w src/config/sessions/session-accessor.ts; starsze funkcje pomocnicze sessions.json są narzędziami migracji i konserwacji offline. Gdy Gateway jest osiągalny, polecenia openclaw sessions cleanup i openclaw agents delete bez trybu próbnego przekazują modyfikacje magazynu do Gateway, dzięki czemu oczyszczanie dołącza do tej samej kolejki zapisu; --store <path> jest jawną ścieżką naprawy offline wybranego starszego magazynu i zawsze pozostaje lokalne (tak samo jak --dry-run). Oczyszczanie maxEntries odbywa się partiami w przypadku magazynów o rozmiarze produkcyjnym, więc magazyn może przez krótki czas przekraczać skonfigurowany limit, zanim kolejne oczyszczanie po przekroczeniu górnego progu zmniejszy go do wymaganej wielkości. Odczyty nigdy nie oczyszczają ani nie ograniczają liczby wpisów podczas uruchamiania Gateway — robią to wyłącznie zapisy lub openclaw sessions cleanup --enforce; to ostatnie również natychmiast stosuje limit i usuwa stare, nieużywane starsze artefakty transkrypcji, punktów kontrolnych oraz trajektorii, nawet jeśli nie skonfigurowano budżetu dyskowego.
OpenClaw nie tworzy już automatycznych kopii zapasowych rotacji sessions.json.bak.* podczas zapisów Gateway. Bieżący schemat odrzuca starszy klucz session.maintenance.rotateBytes, a openclaw doctor --fix usuwa go ze starszych konfiguracji.
Modyfikacje transkrypcji korzystają z kolejki zapisu sesji dla docelowej transkrypcji SQLite:
| Ustawienie | Wartość domyślna | Nadpisanie zmienną środowiskową |
|---|---|---|
session.writeLock.acquireTimeoutMs |
60000 |
OPENCLAW_SESSION_WRITE_LOCK_ACQUIRE_TIMEOUT_MS |
session.writeLock.staleMs |
1800000 |
OPENCLAW_SESSION_WRITE_LOCK_STALE_MS |
session.writeLock.maxHoldMs |
300000 |
OPENCLAW_SESSION_WRITE_LOCK_MAX_HOLD_MS |
acquireTimeoutMs określa, jak długo oczekiwanie na blokadę powoduje zgłaszanie błędu zajętej sesji przed rezygnacją; wartość tę należy zwiększać tylko wtedy, gdy uzasadnione przygotowanie, oczyszczanie, kompaktowanie lub tworzenie kopii lustrzanej transkrypcji powoduje dłuższe konflikty na wolnych maszynach. staleMs określa, kiedy istniejąca blokada może zostać odzyskana jako nieaktualna. maxHoldMs to próg zwolnienia blokady przez mechanizm nadzorczy w obrębie procesu.
Powrót do starszej wersji po przejściu na SQLite
Przed uruchomieniem starszej wersji OpenClaw korzystającej z plików należy przywrócić zarchiwizowane starsze artefakty transkrypcji:
openclaw doctor --session-sqlite restore --session-sqlite-all-agentsMigracja pozostawia starsze pliki sessions.json na potrzeby pomocy technicznej i wycofania zmian, ale aktywne pliki JSONL transkrypcji zaimportowane do SQLite są przemianowywane na session-sqlite-import-archive/. Starsze środowiska uruchomieniowe korzystające z plików odwołują się do ścieżek sessionFile w sessions.json, dlatego wymagają przywrócenia tych artefaktów przed uruchomieniem. Przywracanie korzysta z manifestów migracji, przenosi wyłącznie zarejestrowane zarchiwizowane artefakty, których oryginalne ścieżki nie istnieją, i pozostawia bazę danych SQLite na miejscu na potrzeby późniejszego odzyskiwania.
Sesje utworzone po przejściu na SQLite istnieją wyłącznie w SQLite i nie będą widoczne dla starszego środowiska uruchomieniowego korzystającego z plików. W przypadku ponownego uaktualnienia po powrocie do starszej wersji należy ponownie wykonać sekwencję inspekcji i walidacji narzędzia Doctor, aby OpenClaw mógł zweryfikować przywrócone starsze artefakty przed importem.
Sesje cron i dzienniki uruchomień
Izolowane uruchomienia cron tworzą własne wpisy sesji i transkrypcje z dedykowanym okresem przechowywania:
cron.sessionRetention(domyślnie"24h") usuwa z magazynu stare sesje izolowanych uruchomień cron;falsewyłącza tę funkcję.- Historia uruchomień zachowuje 2000 najnowszych wierszy końcowych dla każdego zadania cron. Utracone wiersze zachowują 24-godzinne okno oczyszczania.
Gdy cron wymusza utworzenie nowej izolowanej sesji uruchomienia, przed zapisaniem nowego wiersza oczyszcza poprzedni wpis sesji cron:<jobId>: przenosi bezpieczne preferencje (ustawienia myślenia, szybkości, szczegółowości i rozumowania, etykiety oraz nazwę wyświetlaną) i jawnie wybrane przez użytkownika nadpisania modelu oraz uwierzytelniania, ale usuwa otaczający kontekst rozmowy (trasowanie kanału i grupy, zasady wysyłania i kolejkowania, podwyższenie uprawnień, źródło oraz powiązanie środowiska uruchomieniowego ACP), dzięki czemu nowe izolowane uruchomienie nie może odziedziczyć nieaktualnych uprawnień do dostarczania ani środowiska uruchomieniowego po starszym uruchomieniu.
Klucze sesji (sessionKey)
sessionKey określa używany zasobnik rozmowy (trasowanie i izolacja). Reguły kanoniczne: /concepts/session.
| Wzorzec | Przykład |
|---|---|
| Czat główny/bezpośredni (na agenta) | agent:<agentId>:<mainKey> (domyślnie main) |
| 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 bieżący sessionId (tożsamość transkrypcji SQLite kontynuującej rozmowę). Logika decyzyjna znajduje się w initSessionState() w src/auto-reply/reply/session.ts.
- Resetowanie (
/new,/reset) tworzy nową wartośćsessionIddla tegosessionKey. - Resetowanie codzienne (domyślnie o 4:00 czasu lokalnego na hoście Gateway) tworzy nową wartość
sessionIdprzy pierwszej wiadomości po przekroczeniu granicy resetowania. - Wygaśnięcie bezczynności (
session.reset.idleMinuteslub starszesession.idleMinutes) tworzy nową wartośćsessionId, gdy wiadomość nadejdzie po upływie okresu bezczynności. Jeśli skonfigurowano zarówno resetowanie codzienne, jak i wygaśnięcie bezczynności, obowiązuje to, które nastąpi wcześniej. - Wznowienie po ponownym połączeniu interfejsu sterowania zachowuje aktualnie widoczną sesję na potrzeby jednego wysłania po ponownym połączeniu, gdy Gateway otrzyma pasującą wartość
sessionIdod klienckiego interfejsu operatora. Jest to sygnał jednorazowy; zwykłe wysłania z nieaktualnym stanem nadal tworzą nową wartośćsessionId. - Zdarzenia systemowe (Heartbeat, wybudzenia Cron, powiadomienia exec, wewnętrzna obsługa Gateway) mogą modyfikować wiersz sesji, ale nigdy nie przedłużają okresu aktualności resetowania codziennego ani resetowania po bezczynności. Przejście do nowej sesji podczas resetowania odrzuca oczekujące powiadomienia o zdarzeniach systemowych z poprzedniej sesji przed utworzeniem nowego promptu.
- Zasady rozwidlania sesji nadrzędnej podczas tworzenia wątku lub rozwidlenia podagenta korzystają z aktywnej gałęzi OpenClaw. Jeśli ta gałąź jest zbyt duża (przekracza stały wewnętrzny limit, obecnie 100K tokenów), OpenClaw uruchamia sesję podrzędną z odizolowanym kontekstem, zamiast zgłaszać błąd lub dziedziczyć bezużyteczną historię. Dobór rozmiaru odbywa się automatycznie i nie można go konfigurować; starsza konfiguracja
session.parentForkMaxTokensjest usuwana przezopenclaw doctor --fix. - Rozwidlenia operatora:
sessions.create { parentSessionKey, fork: true }tworzy nową sesję, której transkrypcja rozgałęzia się od bieżącego stanu sesji nadrzędnej (wykorzystując ten sam mechanizm rozwidlania co przy uruchamianiu podagentów, w tym powyższy limit rozmiaru). Rozwidlenie jest odrzucane, gdy sesja nadrzędna ma aktywne uruchomienie, dziedziczy wybór modelu sesji nadrzędnej, chyba że jawnie przekazano inny, oraz oznacza sesję podrzędną jakoforkedFromParentz nowymi licznikami tokenów.
Schemat magazynu sesji
Magazyn środowiska uruchomieniowego przechowuje wartości SessionEntry w bazie SQLite poszczególnych agentów. Typ wartości to SessionEntry w src/config/sessions.ts. Najważniejsze pola (lista niewyczerpująca):
sessionId: bieżący identyfikator transkrypcji używany do adresowania jej wierszy w SQLitesessionStartedAt: znacznik czasu rozpoczęcia bieżącej wartościsessionId; jest używany do określania aktualności resetowania codziennego. Starsze wiersze mogą wyznaczać go z nagłówka sesji JSONL.lastInteractionAt: znacznik czasu ostatniej rzeczywistej interakcji użytkownika lub kanału; jest używany do określania aktualności resetowania po bezczynności, dzięki czemu zdarzenia Heartbeat, Cron i exec nie utrzymują sesji przy życiu. W przypadku starszych wierszy bez tego pola używany jest odzyskany czas rozpoczęcia sesji.updatedAt: znacznik czasu ostatniej modyfikacji wiersza magazynu, używany do wyświetlania list, usuwania i wewnętrznej obsługi — nie jest źródłem rozstrzygającym o aktualności resetowania codziennego ani resetowania po bezczynności.archivedAt: opcjonalny znacznik czasu archiwizacji. Zarchiwizowane sesje pozostają w magazynie z nienaruszoną transkrypcją i są wykluczone ze zwykłych list aktywnych sesji.pinnedAt: opcjonalny znacznik czasu przypięcia. Aktywne przypięte sesje są sortowane przed nieprzypiętymi; zarchiwizowanie sesji usuwa jej przypięcie.- Współdziałanie z wątkami Codex: oba pola są zgodne ze strukturą zarządzania wątkami Codex — wartości logiczne
archived/pinnedprzesyłane protokołem są zawsze wyprowadzane ze znacznika czasu i nadawane po stronie serwera, zgodnie z semantyką Codexthreads.archived_atoraz serializacją camelCase. Znaczniki czasu OpenClaw są wyrażane w milisekundach epoki, natomiast Codex używa sekund epoki, dlatego mosty dokonują konwersji na granicy pluginucodex. Codex nie ma jeszcze interfejsu API przypinania (obsługuje tylkothread/archive/thread/unarchive); stan przypięcia pozostaje po stronie OpenClaw do czasu udostępnienia takiego interfejsu, a wtedy zgodność struktur umożliwi powiązanym sesjom mechaniczne przekazywanie stanu przypięcia w obie strony. - Nadzór Codex wyświetla tylko niezarchiwizowane wątki natywne. Lokalny dla Gateway wątek
idlelubnotLoadedo nieznanej aktywności można zarchiwizować przez natywnethread/archivedopiero po jawnym potwierdzeniu przez operatora, że nie należy on do żadnego innego procesu Codex; plugin najpierw ponownie odczytuje lokalny stan procesu, po czym wątek znika z katalogu. Odczyt ten nie może dowieść, że inny proces App Server nie korzysta z wątku. OpenClaw odmawia archiwizowania aktywnych wierszy oraz wierszy w stanie błędu, a archiwizacja na sparowanym węźle jest niedostępna, dopóki most węzła nie będzie mógł obsługiwać pełnego cyklu życia strumieniowanego wątku. Cofnięcie archiwizacji w natywnym kliencie Codex sprawia, że wątek może pojawić się ponownie. lastReadAt/markedUnreadAt: znaczniki czasu stanu odczytu nadawane po stronie serwera przezsessions.patch { unread }—unread: falserejestruje odczyt (ustawialastReadAt, usuwamarkedUnreadAt);unread: trueoznacza sesję jako nieprzeczytaną do następnego odczytu. Wiersze sesji udostępniają wyprowadzoną wartość logicznąunread: sesja jest jawnie oznaczona jako nieprzeczytana albo została odczytana przed ostatnią aktywnością. Sesje, których nigdy nie oznaczono jako przeczytane, pozostająunread: false, dzięki czemu istniejące instalacje nie wskazują ich jako nieprzeczytane po uaktualnieniu.lastActivityAt: znacznik czasu ostatniego ukończonego uruchomienia agenta, które jest uznawane za aktywność powodującą stan nieprzeczytany (uruchomienia użytkownika, kanału i Cron). Tury Heartbeat i zdarzeń wewnętrznych oraz poprawki metadanych go nie aktualizują;updatedAtnie jest sygnałem aktywności.sessionFile: starszy znacznik zachowany na potrzeby zgodności migracji i archiwizacji; aktywne środowisko uruchomieniowe używa tożsamości SQLitechatType:direct | group | roomprovider,subject,room,space,displayName: metadane etykietowania grupy/kanału- Przełączniki:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevel,sendPolicy(nadpisanie dla poszczególnej sesji) - Wybór modelu:
providerOverride,modelOverride,authProfileOverride - Liczniki tokenów (orientacyjne/zależne od dostawcy):
inputTokens,outputTokens,totalTokens,contextTokens compactionCount: liczba ukończeń automatycznej operacji Compaction dla tego klucza sesjimemoryFlushAt/memoryFlushCompactionCount: znacznik czasu i liczba operacji Compaction ostatniego opróżnienia pamięci przed operacją Compaction
Gateway jest źródłem rozstrzygającym: może przepisywać lub ponownie odtwarzać wpisy w trakcie
działania sesji. W starszych instalacjach korzystających z magazynu plikowego należy przeprowadzić migrację za pomocą
openclaw doctor --session-sqlite import --session-sqlite-all-agents, zamiast
edytować sessions.json i oczekiwać, że środowisko uruchomieniowe nadal będzie odczytywać ten plik.
Struktura zdarzeń transkrypcji
Transkrypcjami zarządza moduł dostępu do sesji OpenClaw, a kod środowiska uruchomieniowego uzyskuje do nich dostęp przez pomocnicze funkcje oparte na tożsamości. Strumień zdarzeń umożliwia wyłącznie dopisywanie:
- Pierwszy wpis: nagłówek sesji —
type: "session",id,cwd,timestamp, opcjonalnieparentSession. - Następnie: wpisy z
id+parentId(struktura drzewa).
Istotne typy wpisów:
message: wiadomości użytkownika/asystenta/toolResultcustom_message: wiadomość wstrzyknięta przez rozszerzenie, która wchodzi do kontekstu modelu (renderowana w TUI, gdydisplay: true, całkowicie ukryta, gdydisplay: false)custom: stan rozszerzenia, który nie wchodzi do kontekstu modelu (służy do utrwalania stanu rozszerzenia między ponownymi załadowaniami)compaction: utrwalone podsumowanie operacji Compaction zfirstKeptEntryIditokensBeforebranch_summary: utrwalone podsumowanie podczas nawigowania po gałęzi drzewa
OpenClaw celowo nie „naprawia” transkrypcji; Gateway używa SessionManager do ich odczytu/zapisu.
Okna kontekstu a śledzone tokeny
Są to dwa różne pojęcia:
- Okno kontekstu modelu: sztywny limit dla poszczególnych modeli (tokeny widoczne dla modelu). Pochodzi z katalogu modeli i może zostać nadpisany w konfiguracji.
- Liczniki magazynu sesji: statystyki kroczące zapisywane w wierszu sesji (używane przez
/statusi pulpity).contextTokensjest wartością szacowaną/raportowaną przez środowisko uruchomieniowe — nie należy traktować jej jako ścisłej gwarancji.
Więcej informacji o limitach: /reference/token-use.
Compaction: czym jest
Compaction podsumowuje starszą część rozmowy w utrwalonym wpisie compaction w transkrypcji i zachowuje ostatnie wiadomości bez zmian. Po operacji Compaction przyszłe tury widzą jej podsumowanie oraz wiadomości po firstKeptEntryId. Compaction jest trwała, w przeciwieństwie do przycinania sesji — zobacz /concepts/session-pruning.
Ponowne wstrzykiwanie sekcji AGENTS.md po operacji Compaction jest opcjonalne i włączane przez agents.defaults.compaction.postCompactionSections; gdy ta wartość nie jest ustawiona lub wynosi [], OpenClaw nie dołącza fragmentów AGENTS.md do podsumowania operacji Compaction.
Granice fragmentów i parowanie narzędzi
Podczas dzielenia długiej transkrypcji na fragmenty na potrzeby operacji Compaction OpenClaw zachowuje wywołania narzędzi przez asystenta w parze z odpowiadającymi im wpisami toolResult:
- Jeśli podział według udziału tokenów miałby wypaść między wywołaniem narzędzia a jego wynikiem, OpenClaw przesuwa granicę do wiadomości asystenta zawierającej wywołanie narzędzia, zamiast rozdzielać parę.
- Jeśli końcowy blok wyników narzędzi przekroczyłby docelowy rozmiar fragmentu, OpenClaw zachowuje ten oczekujący blok narzędzia i pozostawia niepodsumowany koniec transkrypcji bez zmian.
- Przerwane lub zakończone błędem bloki wywołań narzędzi nie utrzymują oczekującego podziału w stanie otwartym.
Kiedy następuje automatyczna operacja Compaction
W osadzonym agencie OpenClaw istnieją dwa wyzwalacze:
- Odzyskiwanie po przepełnieniu: model zwraca błąd przepełnienia kontekstu (
request_too_large,context length exceeded,input exceeds the maximum number of tokens,input token count exceeds the maximum number of input tokens,input is too long for the model,ollama error: context length exceededi inne warianty zależne od dostawcy) — wykonaj operację Compaction, a następnie ponów próbę. Gdy dostawca zgłasza liczbę tokenów użytych w próbie, OpenClaw przekazuje tę zaobserwowaną liczbę do operacji Compaction podczas odzyskiwania po przepełnieniu; jeśli dostawca potwierdza przepełnienie, ale nie udostępnia liczby możliwej do przeanalizowania, OpenClaw przekazuje mechanizmom Compaction i diagnostyce syntetyczną liczbę minimalnie przekraczającą budżet. Jeśli odzyskiwanie po przepełnieniu nadal się nie powiedzie, OpenClaw wyświetla jednoznaczne wskazówki i zachowuje bieżące mapowanie sesji, zamiast po cichu przełączać się na nowy identyfikator sesji — należy ponowić wiadomość, uruchomić/compactlub uruchomić/new. - Utrzymanie progu: po pomyślnej turze, gdy
contextTokens > contextWindow - reserveTokens, gdziecontextWindowjest oknem kontekstu modelu, areserveTokensjest zapasem zarezerwowanym na prompty oraz następną odpowiedź modelu.
Poza tymi dwoma wyzwalaczami działają jeszcze dwa zabezpieczenia:
- Lokalna operacja Compaction przed uruchomieniem: należy ustawić
agents.defaults.compaction.maxActiveTranscriptBytes(w bajtach lub jako ciąg taki jak"20mb"), aby przed rozpoczęciem następnego uruchomienia wyzwolić lokalną operację Compaction, gdy aktywna transkrypcja osiągnie ten rozmiar. Jest to zabezpieczenie rozmiaru ograniczające lokalny koszt ponownego otwarcia, a nie prosta archiwizacja — nadal wykonywana jest zwykła semantyczna operacja Compaction, która wymagatruncateAfterCompaction, aby podsumowanie operacji Compaction stało się nową transkrypcją następczą. - Kontrola wstępna w trakcie tury: należy ustawić
agents.defaults.compaction.midTurnPrecheck.enabled: true(domyślniefalse), aby dodać zabezpieczenie pętli narzędzi. Po dopisaniu wyniku narzędzia, a przed następnym wywołaniem modelu, OpenClaw szacuje obciążenie promptu przy użyciu tej samej logiki budżetu wstępnego, która jest stosowana na początku tury. Jeśli kontekst przestaje się mieścić, zabezpieczenie nie wykonuje operacji Compaction bezpośrednio — zgłasza ustrukturyzowany sygnał kontroli wstępnej w trakcie tury, zatrzymuje bieżące przesyłanie promptu i pozwala zewnętrznej pętli uruchomienia użyć istniejącej ścieżki odzyskiwania (przyciąć zbyt duże wyniki narzędzi, jeśli to wystarczy, albo wyzwolić skonfigurowany tryb Compaction i ponowić próbę). Działa z trybami Compactiondefaultisafeguard, w tym z zabezpieczającą operacją Compaction obsługiwaną przez dostawcę. Jest niezależne odmaxActiveTranscriptBytes: zabezpieczenie rozmiaru w bajtach działa przed rozpoczęciem tury, a kontrola wstępna w trakcie tury działa później, po dopisaniu nowych wyników narzędzi.
Ustawienia Compaction
{ agents: { defaults: { compaction: { enabled: true, reserveTokens: 16384, keepRecentTokens: 20000, }, }, },}OpenClaw wymusza również minimalny próg bezpieczeństwa dla uruchomień osadzonych: jeśli compaction.reserveTokens jest mniejsze niż reserveTokensFloor (domyślnie 20000), OpenClaw zwiększa tę wartość. Ustaw agents.defaults.compaction.reserveTokensFloor: 0, aby wyłączyć ten próg. Gdy okno kontekstu aktywnego modelu jest znane, zarówno próg, jak i ostateczna efektywna rezerwa są ograniczane, aby rezerwa nie mogła pochłonąć całego budżetu promptu. Dzięki temu modele z małym kontekstem (na przykład lokalny model z 16 tys. tokenów) nie rozpoczynają Compaction od pierwszego tokenu; bez znanego okna kontekstu skonfigurowane i bieżące budżety rezerwy pozostają nieograniczone. Po co w ogóle próg: aby pozostawić wystarczający zapas na wieloturowe „prace porządkowe” (takie jak opisany niżej zapis pamięci), zanim Compaction stanie się nieuniknione. Implementacja: applyAgentCompactionSettingsFromConfig() w src/agents/agent-settings.ts, wywoływane ze ścieżek konfiguracji tury osadzonego modułu uruchomieniowego i Compaction.
Ręczne /compact respektuje jawne agents.defaults.compaction.keepRecentTokens i zachowuje punkt odcięcia ostatniej części środowiska uruchomieniowego. Bez jawnego budżetu zachowania ręczne Compaction jest twardym punktem kontrolnym, a odbudowany kontekst rozpoczyna się od nowego podsumowania.
Gdy włączone jest truncateAfterCompaction, OpenClaw po Compaction przełącza aktywną transkrypcję na skompaktowanego następcę. Akcje punktu kontrolnego rozgałęzienia/przywracania używają tego skompaktowanego następcy; starsze pliki punktów kontrolnych sprzed Compaction pozostają możliwe do odczytu, dopóki istnieją do nich odwołania.
Wymienni dostawcy Compaction
Pluginy rejestrują dostawcę Compaction za pośrednictwem registerCompactionProvider() w API pluginu. Gdy agents.defaults.compaction.provider jest ustawione na identyfikator zarejestrowanego dostawcy, rozszerzenie zabezpieczające deleguje podsumowywanie do tego dostawcy zamiast używać wbudowanego potoku summarizeInStages.
provider: identyfikator zarejestrowanego pluginu dostawcy Compaction. Pozostaw bez ustawienia, aby używać domyślnego podsumowywania przez LLM. Ustawienieproviderwymuszamode: "safeguard".- Dostawcy otrzymują te same instrukcje Compaction i zasady zachowywania identyfikatorów co ścieżka wbudowana, a zabezpieczenie nadal zachowuje po wyniku dostawcy kontekst ostatnich tur oraz końcowy kontekst podzielonej tury.
- Wbudowane podsumowywanie zabezpieczające ponownie destyluje wcześniejsze podsumowania wraz z nowymi wiadomościami, zamiast zachowywać dosłownie pełne poprzednie podsumowanie.
- Tryb zabezpieczający domyślnie włącza audyty jakości podsumowań; ustaw
qualityGuard.enabled: false, aby pominąć ponawianie po otrzymaniu nieprawidłowo sformatowanego wyniku. - Jeśli dostawca zawiedzie lub zwróci pusty wynik, OpenClaw automatycznie użyje wbudowanego podsumowywania przez LLM. Sygnały przerwania/przekroczenia limitu czasu jawnie wywołane przez kod wywołujący są ponownie zgłaszane, a nie pomijane, dzięki czemu anulowanie jest zawsze respektowane.
Źródło: src/plugins/compaction-provider.ts, src/agents/agent-hooks/compaction-safeguard.ts.
Powierzchnie widoczne dla użytkownika
/statusw dowolnej sesji czatuopenclaw status(CLI)openclaw sessions/openclaw sessions --json- Logi Gateway (
pnpm gateway:watchlubopenclaw logs --follow):embedded run auto-compaction start+complete - Tryb szczegółowy:
🧹 Auto-compaction completewraz z liczbą operacji Compaction
Ciche prace porządkowe (NO_REPLY)
OpenClaw obsługuje „ciche” tury zadań w tle, w których użytkownik nie powinien widzieć wyników pośrednich.
- Asystent rozpoczyna swój wynik od dokładnego cichego tokenu
NO_REPLY/no_reply, co oznacza „nie dostarczaj odpowiedzi użytkownikowi”. OpenClaw usuwa/pomija go w warstwie dostarczania. - Pomijanie dokładnego cichego tokenu nie uwzględnia wielkości liter: zarówno
NO_REPLY, jak ino_replysą rozpoznawane, gdy cały ładunek składa się wyłącznie z cichego tokenu. - Od wersji
2026.1.10OpenClaw pomija również strumieniowanie wersji roboczej/wskaźnika pisania, gdy częściowy fragment zaczyna się odNO_REPLY, dzięki czemu ciche operacje nie ujawniają częściowego wyniku w trakcie tury. - Jest to przeznaczone wyłącznie do rzeczywistych tur działających w tle/bez dostarczania — nie jest to skrót dla zwykłych żądań użytkownika wymagających działania.
Zapis pamięci przed Compaction
Przed automatycznym Compaction OpenClaw może uruchomić cichą turę agenta, która zapisuje trwały stan na dysku (na przykład memory/YYYY-MM-DD.md w przestrzeni roboczej agenta), aby Compaction nie mogło usunąć krytycznego kontekstu. Monitoruje wykorzystanie kontekstu sesji, a gdy przekroczy ono miękki próg poniżej progu Compaction, wysyła cichą dyrektywę „zapisz pamięć teraz”, używając dokładnego cichego tokenu NO_REPLY / no_reply, dzięki czemu użytkownik niczego nie widzi.
Konfiguracja (agents.defaults.compaction.memoryFlush), pełna dokumentacja w /gateway/config-agents:
| Klucz | Wartość domyślna | Uwagi |
|---|---|---|
enabled |
true |
|
model |
nieustawione | dokładne nadpisanie dostawcy/modelu wyłącznie dla tury zapisu, na przykład ollama/qwen3:8b |
softThresholdTokens |
4000 |
odstęp poniżej progu Compaction, który wyzwala zapis |
forceFlushTranscriptBytes |
nieustawione (wyłączone) | wymusza zapis, gdy plik transkrypcji osiągnie ten rozmiar w bajtach (lub ciąg taki jak "2mb"), nawet jeśli liczniki tokenów są nieaktualne; 0 wyłącza |
prompt |
wbudowana | wiadomość użytkownika dla tury zapisu |
systemPrompt |
wbudowany | dodatkowy prompt systemowy dołączany do tury zapisu |
Uwagi:
- Domyślny prompt/prompt systemowy zawiera wskazówkę
NO_REPLY, która powoduje pominięcie dostarczania. - Gdy ustawiono
model, tura zapisu używa tego modelu bez dziedziczenia łańcucha modeli zapasowych aktywnej sesji, dzięki czemu lokalne prace porządkowe w przypadku awarii nie przełączają się po cichu na płatny model konwersacyjny. - Zapis jest wykonywany raz na cykl Compaction (śledzony w wierszu sesji).
- Zapis jest wykonywany wyłącznie dla osadzonych sesji OpenClaw; backendy CLI i tury Heartbeat go pomijają.
- Zapis jest pomijany, gdy przestrzeń robocza sesji jest tylko do odczytu (
workspaceAccess: "ro"lub"none"). - Układ plików przestrzeni roboczej i wzorce zapisu opisano w sekcji Pamięć.
OpenClaw udostępnia punkt zaczepienia session_before_compact w API rozszerzeń, ale opisana powyżej logika zapisu znajduje się po stronie Gateway (src/auto-reply/reply/memory-flush.ts, src/auto-reply/reply/agent-runner-memory.ts), a nie w tym punkcie zaczepienia.
Lista kontrolna rozwiązywania problemów
- Nieprawidłowy klucz sesji? Zacznij od /concepts/session i potwierdź
sessionKeyw/status. - Niezgodność magazynu z transkrypcją? Potwierdź host Gateway oraz ścieżkę magazynu z
openclaw status. - Nadmiernie częste Compaction? Sprawdź okno kontekstu modelu (zbyt małe wymusza częste Compaction),
reserveTokens(wartość zbyt wysoka dla okna modelu powoduje wcześniejsze Compaction) oraz nadmiarowe wyniki narzędzi (dostosuj przycinanie sesji). - Każdy prompt zdaje się przepełniać mały model lokalny? Potwierdź, że dostawca zgłasza prawidłowe okno kontekstu modelu. OpenClaw może ograniczyć efektywną rezerwę tylko wtedy, gdy to okno jest znane.
- Ciche tury ujawniają dane? Potwierdź, że odpowiedź zaczyna się od dokładnego cichego tokenu
NO_REPLY(bez uwzględniania wielkości liter) oraz że używana kompilacja zawiera poprawkę pomijania strumieniowania (2026.1.10+).