Technical reference
Поглиблений огляд керування сеансами
OpenClaw керує сеансами від початку до кінця в цих сферах:
- Маршрутизація сеансів (як вхідні повідомлення зіставляються з
sessionKey) - Сховище сеансів (
sessions.json) і що воно відстежує - Збереження транскриптів (
*.jsonl) і їхня структура - Гігієна транскриптів (виправлення, специфічні для провайдера, перед запусками)
- Обмеження контексту (вікно контексту проти відстежуваних токенів)
- Compaction (ручна й auto-compaction) і де підключати роботу перед Compaction
- Тихе обслуговування (записи пам’яті, які не мають створювати видимий для користувача вивід)
Якщо спершу потрібен загальніший огляд, почніть із:
Джерело істини: Gateway
OpenClaw спроєктовано навколо єдиного процесу Gateway, який володіє станом сеансів.
- UI (застосунок macOS, веб Control UI, TUI) мають запитувати в Gateway списки сеансів і кількість токенів.
- У віддаленому режимі файли сеансів розташовані на віддаленому хості; «перевірка локальних файлів на вашому Mac» не відображатиме того, що використовує Gateway.
Два рівні збереження
OpenClaw зберігає сеанси на двох рівнях:
-
Сховище сеансів (
sessions.json)- Мапа ключ/значення:
sessionKey -> SessionEntry - Невелике, змінне, безпечне для редагування (або видалення записів)
- Відстежує метадані сеансу (поточний ідентифікатор сеансу, останню активність, перемикачі, лічильники токенів тощо)
- Мапа ключ/значення:
-
Транскрипт (
<sessionId>.jsonl)- Транскрипт лише з додаванням, зі структурою дерева (записи мають
id+parentId) - Зберігає фактичну розмову + виклики інструментів + підсумки Compaction
- Використовується для відбудови контексту моделі для майбутніх ходів
- Великі налагоджувальні контрольні точки перед Compaction пропускаються, щойно активний
транскрипт перевищує ліміт розміру контрольної точки, щоб уникнути другої гігантської
копії
.checkpoint.*.jsonl.
- Транскрипт лише з додаванням, зі структурою дерева (записи мають
Зчитувачі історії Gateway мають уникати матеріалізації всього транскрипту, якщо
поверхні явно не потрібен довільний доступ до історичних даних. Історія першої сторінки,
вбудована історія чату, відновлення після перезапуску та перевірки токенів/використання застосовують обмежене читання хвоста.
Повне сканування транскриптів проходить через асинхронний індекс транскриптів, який
кешується за шляхом файлу плюс mtimeMs/size і спільно використовується конкурентними зчитувачами.
Розташування на диску
Для кожного агента, на хості Gateway:
- Сховище:
~/.openclaw/agents/<agentId>/sessions/sessions.json - Транскрипти:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl- Сеанси тем Telegram:
.../<sessionId>-topic-<threadId>.jsonl
- Сеанси тем Telegram:
OpenClaw визначає ці шляхи через src/config/sessions.ts.
Обслуговування сховища й керування диском
Збереження сеансів має автоматичні засоби обслуговування (session.maintenance) для sessions.json, артефактів транскриптів і допоміжних trajectory-файлів:
mode:warn(типово) абоenforcepruneAfter: поріг віку застарілих записів (типово30d)maxEntries: ліміт записів уsessions.json(типово500)resetArchiveRetention: строк зберігання архівів транскриптів*.reset.<timestamp>(типово: такий самий, якpruneAfter;falseвимикає очищення)maxDiskBytes: необов’язковий бюджет каталогу сеансівhighWaterBytes: необов’язкова ціль після очищення (типово80%відmaxDiskBytes)
Звичайні записи Gateway проходять через окремий для сховища записувач сеансів, який серіалізує внутрішньопроцесні мутації без отримання файлового блокування під час виконання. Допоміжні засоби виправлення на гарячому шляху позичають перевірений змінний кеш, поки утримують слот цього записувача, тож великі файли sessions.json не клонуються й не перечитуються для кожного оновлення метаданих. Runtime-код має віддавати перевагу updateSessionStore(...) або updateSessionStoreEntry(...); прямі збереження всього сховища є інструментами сумісності та offline-обслуговування. Коли Gateway доступний, команди openclaw sessions cleanup без dry-run і openclaw agents delete делегують мутації сховища Gateway, щоб очищення потрапляло до тієї самої черги записувача; --store <path> — це явний offline-шлях ремонту для прямого обслуговування файлів. Очищення maxEntries і далі пакетне для лімітів виробничого масштабу, тому сховище може короткочасно перевищити налаштований ліміт, перш ніж наступне очищення high-water перепише його до потрібного розміру. Читання сховища сеансів не обрізають і не обмежують записи під час запуску Gateway; для очищення використовуйте записи або openclaw sessions cleanup --enforce. openclaw sessions cleanup --enforce все ще негайно застосовує налаштований ліміт і обрізає старі транскрипти, контрольні точки та trajectory-артефакти без посилань, навіть коли бюджет диска не налаштовано.
Обслуговування зберігає довговічні зовнішні вказівники на розмови, як-от групові сеанси та сеанси чату з прив’язкою до тредів, але синтетичні runtime-записи для Cron, hooks, Heartbeat, ACP і sub-agents усе ще можуть видалятися, коли вони перевищують налаштований вік, кількість або бюджет диска.
OpenClaw більше не створює автоматичні ротаційні резервні копії sessions.json.bak.* під час записів Gateway. Застарілий ключ session.maintenance.rotateBytes ігнорується, а openclaw doctor --fix видаляє його зі старіших конфігурацій.
Мутації транскрипту використовують блокування запису сеансу на файлі транскрипту. Отримання блокування очікує до
session.writeLock.acquireTimeoutMs, перш ніж показати помилку зайнятого сеансу; типове значення — 60000
мс. Збільшуйте його лише тоді, коли легітимна підготовка, очищення, Compaction або робота з дзеркалом транскрипту конкурує
довше на повільних машинах. Виявлення застарілих блокувань і попередження про максимальний час утримання залишаються окремими політиками.
Порядок застосування очищення бюджету диска (mode: "enforce"):
- Спочатку видаляти найстаріші архівовані, orphan transcript або orphan trajectory артефакти.
- Якщо все ще вище цілі, вилучати найстаріші записи сеансів і їхні файли транскриптів/trajectory.
- Продовжувати, доки використання не стане на рівні або нижче
highWaterBytes.
У mode: "warn" OpenClaw повідомляє про потенційні вилучення, але не змінює сховище/файли.
Запускайте обслуговування на вимогу:
openclaw sessions cleanup --dry-runopenclaw sessions cleanup --enforceСеанси Cron і журнали запусків
Ізольовані запуски Cron також створюють записи/транскрипти сеансів і мають окремі засоби керування зберіганням:
cron.sessionRetention(типово24h) обрізає старі сеанси ізольованих запусків Cron зі сховища сеансів (falseвимикає).cron.runLog.maxBytes+cron.runLog.keepLinesобрізають файли~/.openclaw/cron/runs/<jobId>.jsonl(типові значення:2_000_000байтів і2000рядків).
Коли Cron примусово створює новий ізольований сеанс запуску, він санітизує попередній
запис сеансу cron:<jobId> перед записом нового рядка. Він переносить безпечні
налаштування, як-от параметри thinking/fast/verbose, мітки та явні
перевизначення моделі/auth, вибрані користувачем. Він відкидає навколишній контекст розмови,
як-от маршрутизацію каналів/груп, політику надсилання або черги, підвищення, походження та
runtime-прив’язку ACP, щоб свіжий ізольований запуск не міг успадкувати застарілу доставку або
runtime-повноваження зі старішого запуску.
Ключі сеансів (sessionKey)
sessionKey визначає, у якому кошику розмови ви перебуваєте (маршрутизація + ізоляція).
Поширені шаблони:
- Основний/прямий чат (на агента):
agent:<agentId>:<mainKey>(типовоmain) - Група:
agent:<agentId>:<channel>:group:<id> - Кімната/канал (Discord/Slack):
agent:<agentId>:<channel>:channel:<id>або...:room:<id> - Cron:
cron:<job.id> - Webhook:
hook:<uuid>(якщо не перевизначено)
Канонічні правила задокументовано на /concepts/session.
Ідентифікатори сеансів (sessionId)
Кожен sessionKey вказує на поточний sessionId (файл транскрипту, який продовжує розмову).
Практичні правила:
- Скидання (
/new,/reset) створює новийsessionIdдля цьогоsessionKey. - Щоденне скидання (типово 4:00 AM за локальним часом на хості gateway) створює новий
sessionIdу наступному повідомленні після межі скидання. - Завершення через неактивність (
session.reset.idleMinutesабо застарілийsession.idleMinutes) створює новийsessionId, коли повідомлення надходить після вікна неактивності. Коли налаштовані і щоденне скидання, і неактивність, перемагає те, що спливає першим. - Системні події (Heartbeat, пробудження Cron, сповіщення exec, службове ведення Gateway) можуть змінювати рядок сеансу, але не подовжують свіжість щоденного/idle-скидання. Перехід скидання відкидає queued системні сповіщення для попереднього сеансу перед побудовою свіжого prompt.
- Політика parent fork використовує активну гілку PI під час створення треду або форку subagent. Якщо ця гілка завелика, OpenClaw запускає дочірній процес з ізольованим контекстом замість помилки або успадкування непридатної історії. Політика визначення розміру автоматична; застарілу конфігурацію
session.parentForkMaxTokensвидаляєopenclaw doctor --fix.
Деталь реалізації: рішення відбувається в initSessionState() у src/auto-reply/reply/session.ts.
Схема сховища сеансів (sessions.json)
Тип значення сховища — SessionEntry у src/config/sessions.ts.
Ключові поля (не вичерпно):
sessionId: поточний ідентифікатор транскрипту (ім’я файлу виводиться з нього, якщоsessionFileне задано)sessionStartedAt: timestamp початку для поточногоsessionId; свіжість щоденного скидання використовує це поле. Застарілі рядки можуть виводити його з заголовка сеансу JSONL.lastInteractionAt: timestamp останньої реальної взаємодії користувача/каналу; свіжість idle-скидання використовує це поле, тож події Heartbeat, Cron і exec не підтримують сеанси активними. Застарілі рядки без цього поля повертаються до відновленого часу початку сеансу для свіжості idle.updatedAt: timestamp останньої мутації рядка сховища, використовується для списків, обрізання та службового обліку. Він не є авторитетним джерелом для свіжості щоденного/idle-скидання.sessionFile: необов’язкове явне перевизначення шляху транскриптуchatType:direct | group | room(допомагає UI і політиці надсилання)provider,subject,room,space,displayName: метадані для маркування груп/каналів- Перемикачі:
thinkingLevel,verboseLevel,reasoningLevel,elevatedLevelsendPolicy(перевизначення для окремого сеансу)
- Вибір моделі:
providerOverride,modelOverride,authProfileOverride
- Лічильники токенів (найкраща спроба / залежить від провайдера):
inputTokens,outputTokens,totalTokens,contextTokens
compactionCount: як часто auto-compaction завершувалася для цього ключа сеансуmemoryFlushAt: timestamp останнього скидання пам’яті перед CompactionmemoryFlushCompactionCount: кількість Compaction, коли останнє скидання виконувалося
Сховище безпечно редагувати, але Gateway є авторитетним джерелом: він може переписувати або регідратувати записи під час виконання сеансів.
Структура транскрипту (*.jsonl)
Транскриптами керує SessionManager з @earendil-works/pi-coding-agent.
Файл має формат JSONL:
- Перший рядок: заголовок сеансу (
type: "session", міститьid,cwd,timestamp, необов’язковийparentSession) - Далі: записи сеансу з
id+parentId(дерево)
Помітні типи записів:
message: повідомлення user/assistant/toolResultcustom_message: повідомлення, ін’єктовані розширенням, які входять до контексту моделі (можуть бути приховані від UI)custom: стан розширення, який не входить до контексту моделіcompaction: збережений підсумок Compaction зfirstKeptEntryIdіtokensBeforebranch_summary: збережений підсумок під час навігації гілкою дерева
OpenClaw навмисно не «виправляє» транскрипти; Gateway використовує SessionManager для їх читання/запису.
Вікна контексту проти відстежуваних токенів
Важливі два різні поняття:
- Вікно контексту моделі: жорсткий ліміт на модель (токени, видимі моделі)
- Лічильники сховища сеансів: ковзна статистика, записана в
sessions.json(використовується для /status і dashboards)
Якщо ви налаштовуєте ліміти:
- Вікно контексту береться з каталогу моделей (і може бути перевизначене через конфігурацію).
contextTokensу сховищі — це runtime-оцінка/звітне значення; не вважайте його суворою гарантією.
Докладніше див. /token-use.
Compaction: що це таке
Compaction підсумовує старішу розмову в збережений запис compaction у транскрипті та залишає останні повідомлення недоторканими.
Після Compaction майбутні ходи бачать:
- Підсумок Compaction
- Повідомлення після
firstKeptEntryId
Compaction має постійний характер (на відміну від обрізання сесії). Див. /concepts/session-pruning.
Межі фрагментів Compaction і зв’язування інструментів
Коли OpenClaw розбиває довгу стенограму на фрагменти Compaction, він зберігає
виклики інструментів асистента в парі з відповідними записами toolResult.
- Якщо поділ за часткою токенів потрапляє між викликом інструмента та його результатом, OpenClaw зміщує межу до повідомлення асистента з викликом інструмента, замість того щоб розділяти пару.
- Якщо кінцевий блок результату інструмента інакше вивів би фрагмент за цільовий розмір, OpenClaw зберігає цей очікуваний блок інструмента й залишає нескомпонований хвіст без змін.
- Перервані або помилкові блоки викликів інструментів не утримують очікуваний поділ відкритим.
Коли відбувається автоматична Compaction (середовище виконання Pi)
У вбудованому агенті Pi автоматична Compaction спрацьовує у двох випадках:
- Відновлення після переповнення: модель повертає помилку переповнення контексту
(
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 exceededта подібні варіанти у форматі провайдера) → compact → retry. - Підтримання порога: після успішного ходу, коли:
contextTokens > contextWindow - reserveTokens
Де:
contextWindow— контекстне вікно моделіreserveTokens— запас, зарезервований для промптів + наступного виводу моделі
Це семантика середовища виконання Pi (OpenClaw споживає події, але Pi вирішує, коли виконувати Compaction).
OpenClaw також може запускати попередню локальну Compaction перед відкриттям наступного
запуску, коли встановлено agents.defaults.compaction.maxActiveTranscriptBytes і
активний файл стенограми досягає цього розміру. Це запобіжник за розміром файлу для локальної
вартості повторного відкриття, а не необроблене архівування: OpenClaw усе ще виконує звичайну семантичну Compaction,
і для цього потрібен truncateAfterCompaction, щоб скомпонований підсумок міг стати
новою наступною стенограмою.
Для вбудованих запусків Pi agents.defaults.compaction.midTurnPrecheck.enabled: true
додає додатковий запобіжник циклу інструментів. Після додавання результату інструмента й перед
наступним викликом моделі OpenClaw оцінює навантаження на промпт, використовуючи ту саму попередню
бюджетну логіку, що й на початку ходу. Якщо контекст більше не вміщується, запобіжник
не виконує Compaction всередині хуку transformContext Pi. Він піднімає структурований
сигнал попередньої перевірки посеред ходу, зупиняє поточне надсилання промпта й дає
зовнішньому циклу запуску використати наявний шлях відновлення: обрізати завеликі результати інструментів,
коли цього достатньо, або запустити налаштований режим Compaction і повторити спробу. Опція
типово вимкнена й працює з режимами Compaction default і safeguard,
включно з Compaction із запобіжником на основі провайдера.
Це незалежно від maxActiveTranscriptBytes: запобіжник за розміром у байтах працює
перед відкриттям ходу, тоді як попередня перевірка посеред ходу запускається пізніше у вбудованому циклі інструментів Pi
після додавання нових результатів інструментів.
Налаштування Compaction (reserveTokens, keepRecentTokens)
Налаштування Compaction для Pi містяться в налаштуваннях Pi:
{ compaction: { enabled: true, reserveTokens: 16384, keepRecentTokens: 20000, },}OpenClaw також застосовує безпечний нижній поріг для вбудованих запусків:
- Якщо
compaction.reserveTokens < reserveTokensFloor, OpenClaw підвищує значення. - Типовий нижній поріг —
20000токенів. - Установіть
agents.defaults.compaction.reserveTokensFloor: 0, щоб вимкнути нижній поріг. - Якщо значення вже вище, OpenClaw залишає його без змін.
- Ручна
/compactвраховує явнийagents.defaults.compaction.keepRecentTokensі зберігає точку відсікання недавнього хвоста Pi. Без явного бюджету збереження ручна Compaction лишається жорсткою контрольною точкою, а перебудований контекст починається з нового підсумку. - Установіть
agents.defaults.compaction.midTurnPrecheck.enabled: true, щоб запускати додаткову попередню перевірку циклу інструментів після нових результатів інструментів і перед наступним викликом моделі. Це лише тригер; створення підсумку все ще використовує налаштований шлях Compaction. Це незалежно відmaxActiveTranscriptBytes, який є запобіжником розміру активної стенограми в байтах на початку ходу. - Установіть
agents.defaults.compaction.maxActiveTranscriptBytesу значення в байтах або рядок на кшталт"20mb", щоб запускати локальну Compaction перед ходом, коли активна стенограма стає великою. Цей запобіжник активний лише тоді, колиtruncateAfterCompactionтакож увімкнено. Залиште його невстановленим або встановіть0, щоб вимкнути. - Коли
agents.defaults.compaction.truncateAfterCompactionувімкнено, OpenClaw повертає активну стенограму в скомпоновану наступну JSONL після Compaction. Стара повна стенограма залишається заархівованою та пов’язаною з контрольною точкою Compaction, замість переписування на місці.
Навіщо: залишити достатньо запасу для багатоходового "обслуговування" (наприклад, записів пам’яті), перш ніж Compaction стане неминучою.
Реалізація: ensurePiCompactionReserveTokens() у src/agents/pi-settings.ts
(викликається з src/agents/pi-embedded-runner.ts).
Підключувані провайдери Compaction
Plugins можуть зареєструвати провайдера Compaction через registerCompactionProvider() в API plugin. Коли agents.defaults.compaction.provider встановлено на зареєстрований id провайдера, розширення запобіжника делегує підсумовування цьому провайдеру замість вбудованого конвеєра summarizeInStages.
provider: id зареєстрованого plugin-провайдера Compaction. Залиште невстановленим для типового підсумовування LLM.- Установлення
providerпримусово вмикаєmode: "safeguard". - Провайдери отримують ті самі інструкції Compaction і політику збереження ідентифікаторів, що й вбудований шлях.
- Запобіжник усе ще зберігає контекст суфікса недавніх ходів і розділеного ходу після виводу провайдера.
- Вбудоване підсумовування із запобіжником повторно дистилює попередні підсумки з новими повідомленнями замість збереження повного попереднього підсумку дослівно.
- Режим запобіжника типово вмикає аудити якості підсумку; установіть
qualityGuard.enabled: false, щоб пропустити поведінку повторної спроби при некоректно сформованому виводі. - Якщо провайдер зазнає невдачі або повертає порожній результат, OpenClaw автоматично повертається до вбудованого підсумовування LLM.
- Сигнали переривання або тайм-ауту повторно викидаються (не поглинаються), щоб поважати скасування викликачем.
Джерело: src/plugins/compaction-provider.ts, src/agents/pi-hooks/compaction-safeguard.ts.
Поверхні, видимі користувачу
Ви можете спостерігати Compaction і стан сесії через:
/status(у будь-якій чат-сесії)openclaw status(CLI)openclaw sessions/sessions --json- Журнали Gateway (
pnpm gateway:watchабоopenclaw logs --follow):embedded run auto-compaction start+complete - Докладний режим:
🧹 Auto-compaction complete+ кількість Compaction
Тихе обслуговування (NO_REPLY)
OpenClaw підтримує "тихі" ходи для фонових завдань, де користувач не має бачити проміжний вивід.
Умова:
- Асистент починає свій вивід з точного тихого токена
NO_REPLY/no_reply, щоб позначити "не доставляти відповідь користувачу". - OpenClaw видаляє/пригнічує це на рівні доставки.
- Пригнічення точного тихого токена не залежить від регістру, тому
NO_REPLYіno_replyобидва враховуються, коли все корисне навантаження — лише тихий токен. - Це лише для справді фонових ходів без доставки; це не скорочення для звичайних дієвих запитів користувача.
Починаючи з 2026.1.10, OpenClaw також пригнічує потокове передавання чернетки/набору тексту, коли
частковий фрагмент починається з NO_REPLY, тому тихі операції не розкривають частковий
вивід посеред ходу.
"Скидання пам’яті" перед Compaction (реалізовано)
Мета: перед автоматичною Compaction запустити тихий агентний хід, який записує довговічний
стан на диск (наприклад, memory/YYYY-MM-DD.md у робочій області агента), щоб Compaction не могла
стерти критичний контекст.
OpenClaw використовує підхід скидання перед порогом:
- Відстежувати використання контексту сесії.
- Коли воно перетинає "м’який поріг" (нижче порога Compaction Pi), запустити тиху директиву "запиши пам’ять зараз" для агента.
- Використати точний тихий токен
NO_REPLY/no_reply, щоб користувач нічого не бачив.
Конфігурація (agents.defaults.compaction.memoryFlush):
enabled(типово:true)model(необов’язкове точне перевизначення провайдера/моделі для ходу скидання, наприкладollama/qwen3:8b)softThresholdTokens(типово:4000)prompt(повідомлення користувача для ходу скидання)systemPrompt(додатковий системний промпт, доданий для ходу скидання)
Примітки:
- Типовий промпт/системний промпт містять підказку
NO_REPLY, щоб пригнітити доставку. - Коли
modelвстановлено, хід скидання використовує цю модель без успадкування резервного ланцюга активної сесії, тому локальне обслуговування не переходить непомітно на платну розмовну модель. - Скидання виконується один раз за цикл Compaction (відстежується в
sessions.json). - Скидання виконується лише для вбудованих сесій Pi (бекенди CLI його пропускають).
- Скидання пропускається, коли робоча область сесії доступна лише для читання (
workspaceAccess: "ro"або"none"). - Див. Пам’ять щодо структури файлів робочої області та шаблонів запису.
Pi також надає хук session_before_compact в API розширення, але логіка
скидання OpenClaw наразі живе на боці Gateway.
Контрольний список усунення несправностей
- Неправильний ключ сесії? Почніть із /concepts/session і підтвердьте
sessionKeyу/status. - Невідповідність сховища та стенограми? Підтвердьте хост Gateway і шлях сховища з
openclaw status. - Спам Compaction? Перевірте:
- контекстне вікно моделі (занадто мале)
- налаштування Compaction (
reserveTokensзанадто високий для вікна моделі може спричинити ранішу Compaction) - роздування результатів інструментів: увімкніть/налаштуйте обрізання сесії
- Тихі ходи просочуються? Переконайтеся, що відповідь починається з
NO_REPLY(точний токен без урахування регістру) і ви використовуєте збірку, яка містить виправлення пригнічення потокового передавання.