Technical reference

Поглиблений розгляд керування сеансами

OpenClaw керує сесіями від початку до кінця в таких областях:

  • Маршрутизація сесій (як вхідні повідомлення зіставляються з sessionKey)
  • Сховище сесій (sessions.json) і що воно відстежує
  • Збереження транскриптів (*.jsonl) і їхня структура
  • Гігієна транскриптів (специфічні для провайдерів виправлення перед запусками)
  • Обмеження контексту (контекстне вікно проти відстежуваних токенів)
  • Compaction (ручна й автоматична Compaction) і де під’єднувати роботу перед Compaction
  • Тихе обслуговування (записи пам’яті, які не мають створювати видимий для користувача вивід)

Якщо спочатку потрібен огляд вищого рівня, почніть із:


Джерело істини: Gateway

OpenClaw спроєктовано навколо одного процесу Gateway, який володіє станом сесій.

  • Інтерфейси користувача (застосунок macOS, веб Control UI, TUI) мають запитувати в Gateway списки сесій і кількість токенів.
  • У віддаленому режимі файли сесій розташовані на віддаленому хості; «перевірка ваших локальних файлів Mac» не відобразить того, що використовує Gateway.

Два рівні збереження

OpenClaw зберігає сесії на двох рівнях:

  1. Сховище сесій (sessions.json)

    • Карта ключ/значення: sessionKey -> SessionEntry
    • Невелике, змінюване, безпечне для редагування (або видалення записів)
    • Відстежує метадані сесії (поточний ідентифікатор сесії, останню активність, перемикачі, лічильники токенів тощо)
  2. Транскрипт (<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

OpenClaw визначає ці шляхи через src/config/sessions.ts.


Обслуговування сховища та керування диском

Збереження сесій має автоматичні елементи керування обслуговуванням (session.maintenance) для sessions.json, артефактів транскриптів і допоміжних файлів траєкторій:

  • mode: warn (типово) або enforce
  • pruneAfter: граничний вік застарілих записів (типово 30d)
  • maxEntries: обмеження кількості записів у sessions.json (типово 500)
  • resetArchiveRetention: строк зберігання архівів транскриптів *.reset.<timestamp> (типово: такий самий, як pruneAfter; false вимикає очищення)
  • maxDiskBytes: необов’язковий бюджет каталогу сесій
  • highWaterBytes: необов’язкова ціль після очищення (типово 80% від maxDiskBytes)

Звичайні записи Gateway проходять через автор сесій для окремого сховища, який серіалізує внутрішньопроцесні мутації без взяття файлового блокування під час виконання. Допоміжні засоби патчів на гарячому шляху позичають перевірений змінюваний кеш, поки утримують цей слот автора, тому великі файли sessions.json не клонуються і не перечитуються для кожного оновлення метаданих. Код часу виконання має віддавати перевагу updateSessionStore(...) або updateSessionStoreEntry(...); прямі збереження всього сховища є інструментами сумісності та офлайн-обслуговування. Коли Gateway доступний, команди openclaw sessions cleanup без --dry-run і openclaw agents delete делегують мутації сховища Gateway, щоб очищення приєднувалося до тієї самої черги автора; --store <path> є явним шляхом офлайн-відновлення для прямого файлового обслуговування. Очищення maxEntries все ще пакетне для обмежень виробничого розміру, тому сховище може короткочасно перевищувати налаштоване обмеження, перш ніж наступне очищення за верхнім порогом перепише його до меншого розміру. Читання сховища сесій не обрізає і не обмежує записи під час запуску Gateway; для очищення використовуйте записи або openclaw sessions cleanup --enforce. openclaw sessions cleanup --enforce усе одно негайно застосовує налаштоване обмеження та обрізає старі непосилальні артефакти транскриптів, контрольних точок і траєкторій, навіть коли дисковий бюджет не налаштовано.

Обслуговування зберігає довговічні зовнішні вказівники розмов, як-от групові сесії та сесії чату в межах теми, але синтетичні записи часу виконання для cron, хуків, Heartbeat, ACP і субагентів усе ще можуть видалятися, коли перевищують налаштований бюджет віку, кількості або диска.

OpenClaw більше не створює автоматичні ротаційні резервні копії sessions.json.bak.* під час записів Gateway. Застарілий ключ session.maintenance.rotateBytes ігнорується, а openclaw doctor --fix видаляє його зі старіших конфігурацій.

Мутації транскриптів використовують блокування запису сесії на файлі транскрипту. Отримання блокування чекає до session.writeLock.acquireTimeoutMs, перш ніж показати помилку зайнятої сесії; типове значення — 60000 мс. Збільшуйте це лише тоді, коли легітимна підготовка, очищення, Compaction або робота дзеркалювання транскриптів довше конкурує на повільних машинах. Виявлення застарілих блокувань і попередження про максимальне утримання залишаються окремими політиками.

Порядок примусового очищення дискового бюджету (mode: "enforce"):

  1. Спочатку видаляйте найстаріші архівовані артефакти, осиротілі транскрипти або осиротілі траєкторії.
  2. Якщо все ще вище цілі, витісняйте найстаріші записи сесій та їхні файли транскриптів/траєкторій.
  3. Продовжуйте, доки використання не буде на рівні або нижче highWaterBytes.

У mode: "warn" OpenClaw повідомляє про потенційні витіснення, але не змінює сховище/файли.

Запустіть обслуговування на вимогу:

openclaw sessions cleanup --dry-run
openclaw 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, мітки та явні вибрані користувачем перевизначення моделі/автентифікації. Він відкидає навколишній контекст розмови, як-от маршрутизацію каналу/групи, політику надсилання або черги, підвищення, походження та прив’язку часу виконання ACP, щоб свіжий ізольований запуск не міг успадкувати застарілу доставку або повноваження часу виконання від старішого запуску.


Ключі сесій (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) можуть змінювати рядок сесії, але не подовжують свіжість щоденного/бездіяльного скидання. Перехід скидання відкидає поставлені в чергу сповіщення системних подій для попередньої сесії перед побудовою свіжого prompt.
  • Політика батьківського форку використовує активну гілку Pi під час створення гілки обговорення або форку субагента. Якщо ця гілка завелика, OpenClaw запускає дочірній процес з ізольованим контекстом замість відмови або успадкування непридатної історії. Політика визначення розміру автоматична; застарілу конфігурацію session.parentForkMaxTokens видаляє openclaw doctor --fix.

Деталь реалізації: рішення відбувається в initSessionState() у src/auto-reply/reply/session.ts.


Схема сховища сесій (sessions.json)

Тип значення сховища — SessionEntry у src/config/sessions.ts.

Ключові поля (не вичерпно):

  • sessionId: поточний ідентифікатор транскрипту (ім’я файлу виводиться з нього, якщо sessionFile не задано)
  • sessionStartedAt: часова позначка початку для поточного sessionId; свіжість щоденного скидання використовує це. Застарілі рядки можуть виводити її із заголовка сесії JSONL.
  • lastInteractionAt: часова позначка останньої реальної взаємодії користувача/каналу; свіжість скидання через бездіяльність використовує це, тому події heartbeat, cron і exec не підтримують сесії активними. Застарілі рядки без цього поля повертаються до відновленого часу початку сесії для свіжості бездіяльності.
  • updatedAt: часова позначка останньої мутації рядка сховища, використовується для списків, обрізання та службового обліку. Вона не є авторитетним джерелом для свіжості щоденного/бездіяльного скидання.
  • sessionFile: необов’язкове явне перевизначення шляху транскрипту
  • chatType: direct | group | room (допомагає інтерфейсам користувача та політиці надсилання)
  • provider, subject, room, space, displayName: метадані для маркування груп/каналів
  • Перемикачі:
    • thinkingLevel, verboseLevel, reasoningLevel, elevatedLevel
    • sendPolicy (перевизначення для окремої сесії)
  • Вибір моделі:
    • providerOverride, modelOverride, authProfileOverride
  • Лічильники токенів (найкраще можливе / залежить від провайдера):
    • inputTokens, outputTokens, totalTokens, contextTokens
  • compactionCount: як часто автоматична Compaction завершувалася для цього ключа сесії
  • memoryFlushAt: часова позначка останнього скидання пам’яті перед Compaction
  • memoryFlushCompactionCount: кількість Compaction, коли останнє скидання виконувалося

Сховище безпечно редагувати, але Gateway є авторитетним джерелом: він може переписувати або повторно гідратувати записи під час виконання сесій.


Структура транскрипту (*.jsonl)

Транскриптами керує SessionManager із @mariozechner/pi-coding-agent.

Файл має формат JSONL:

  • Перший рядок: заголовок сесії (type: "session", містить id, cwd, timestamp, необов’язковий parentSession)
  • Далі: записи сесії з id + parentId (дерево)

Важливі типи записів:

  • message: повідомлення користувача/асистента/результату інструмента
  • custom_message: повідомлення, вставлені розширенням, які входять у контекст моделі (можуть бути приховані від UI)
  • custom: стан розширення, який не входить у контекст моделі
  • compaction: збережене зведення Compaction із firstKeptEntryId і tokensBefore
  • branch_summary: збережене зведення під час навігації гілкою дерева

OpenClaw навмисно не «виправляє» транскрипти; Gateway використовує SessionManager, щоб читати/записувати їх.


Контекстні вікна проти відстежуваних токенів

Мають значення два різні поняття:

  1. Контекстне вікно моделі: жорстке обмеження на модель (токени, видимі моделі)
  2. Лічильники сховища сесій: ковзна статистика, записана в sessions.json (використовується для /status і панелей)

Якщо ви налаштовуєте обмеження:

  • Контекстне вікно надходить із каталогу моделей (і може бути перевизначене через конфігурацію).
  • contextTokens у сховищі — це оцінка/значення звітності часу виконання; не вважайте його суворою гарантією.

Докладніше див. /token-use.


Compaction: що це таке

Compaction підсумовує старішу розмову в збережений запис compaction у транскрипті та залишає останні повідомлення без змін.

Після Compaction майбутні ходи бачать:

  • Зведення Compaction
  • Повідомлення після firstKeptEntryId

Compaction є стійкою (на відміну від обрізання сесії). Див. /concepts/session-pruning.

Межі фрагментів Compaction і парування інструментів

Коли OpenClaw розбиває довгий транскрипт на фрагменти Compaction, він зберігає виклики інструментів асистента спареними з відповідними записами toolResult.

  • Якщо поділ за часткою токенів потрапляє між викликом інструмента та його результатом, OpenClaw зміщує межу до повідомлення асистента з викликом інструмента, а не розділяє пару.
  • Якщо кінцевий блок результату інструмента інакше вивів би фрагмент за цільовий розмір, OpenClaw зберігає цей очікуваний блок інструмента й залишає нескорочений хвіст неушкодженим.
  • Перервані блоки викликів інструментів або блоки з помилками не утримують очікуваний поділ відкритим.

Коли відбувається автоматичний Compaction (середовище виконання Pi)

У вбудованому агенті Pi автоматичний Compaction спрацьовує у двох випадках:

  1. Відновлення після переповнення: модель повертає помилку переповнення контексту (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.
  2. Підтримання порога: після успішного ходу, коли:

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 після Compaction обертає активний транскрипт у стиснений наступний JSONL. Старий повний транскрипт залишається заархівованим і пов'язаним із контрольною точкою 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 зареєстрованого провайдера, розширення safeguard делегує підсумовування цьому провайдеру замість вбудованого конвеєра summarizeInStages.

  • provider: id зареєстрованого Plugin провайдера Compaction. Не задавайте для типового LLM-підсумовування.
  • Встановлення provider примусово задає mode: "safeguard".
  • Провайдери отримують ті самі інструкції Compaction і політику збереження ідентифікаторів, що й вбудований шлях.
  • Захист усе ще зберігає контекст суфікса недавніх ходів і розділених ходів після виводу провайдера.
  • Вбудоване підсумовування safeguard повторно дистилює попередні підсумки з новими повідомленнями замість того, щоб дослівно зберігати весь попередній підсумок.
  • Режим safeguard за замовчуванням вмикає аудити якості підсумку; встановіть 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
  • Докладний режим: 🧹 Auto-compaction complete + кількість Compaction

Тихе обслуговування (NO_REPLY)

OpenClaw підтримує "тихі" ходи для фонових задач, де користувач не повинен бачити проміжний вивід.

Угода:

  • Асистент починає свій вивід із точного тихого токена NO_REPLY / no_reply, щоб указати "не доставляти відповідь користувачу".
  • OpenClaw прибирає/пригнічує це на шарі доставки.
  • Пригнічення точного тихого токена не залежить від регістру, тож NO_REPLY і no_reply обидва враховуються, коли весь payload складається лише з тихого токена.
  • Це лише для справді фонових ходів без доставки; це не скорочення для звичайних дієвих запитів користувача.

Станом на 2026.1.10, OpenClaw також пригнічує потокове передавання чернетки/набирання, коли частковий фрагмент починається з NO_REPLY, тож тихі операції не витікають частковим виводом у середині ходу.


"Скидання пам'яті" перед Compaction (реалізовано)

Мета: перед тим, як відбудеться автоматичний Compaction, запустити тихий агентний хід, який записує довговічний стан на диск (наприклад, memory/YYYY-MM-DD.md у робочій області агента), щоб Compaction не міг стерти критичний контекст.

OpenClaw використовує підхід скидання перед порогом:

  1. Відстежувати використання контексту сесії.
  2. Коли воно перетинає "м'який поріг" (нижче порога Compaction Pi), запустити тиху директиву "запиши пам'ять зараз" для агента.
  3. Використати точний тихий токен NO_REPLY / no_reply, щоб користувач не бачив нічого.

Конфігурація (agents.defaults.compaction.memoryFlush):

  • enabled (за замовчуванням: true)
  • model (опціональне точне перевизначення провайдера/моделі для ходу скидання, наприклад ollama/qwen3:8b)
  • softThresholdTokens (за замовчуванням: 4000)
  • prompt (повідомлення користувача для ходу скидання)
  • systemPrompt (додаткова системна підказка, додана для ходу скидання)

Примітки:

  • Типові prompt/system prompt містять підказку NO_REPLY, щоб пригнітити доставку.
  • Коли model встановлено, хід скидання використовує цю модель без успадкування ланцюга fallback активної сесії, тож локальне обслуговування не виконує непомітний fallback до платної розмовної моделі.
  • Скидання виконується один раз на цикл 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 (точний токен без урахування регістру) і ви використовуєте збірку, що містить виправлення пригнічення потокового передавання.

Пов'язане