Fundamentals

Цикл агента

Агентний цикл — це повний "реальний" запуск агента: приймання → складання контексту → інференс моделі → виконання інструментів → потокові відповіді → збереження. Це авторитетний шлях, який перетворює повідомлення на дії та фінальну відповідь, водночас зберігаючи узгоджений стан сесії.

В OpenClaw цикл — це один серіалізований запуск на сесію, який генерує події життєвого циклу та потоку, поки модель думає, викликає інструменти й передає вихідні дані потоком. Цей документ пояснює, як цей автентичний цикл з'єднано наскрізно.

Точки входу

  • Gateway RPC: agent і agent.wait.
  • CLI: команда agent.

Як це працює (на високому рівні)

  1. RPC agent перевіряє параметри, визначає сесію (sessionKey/sessionId), зберігає метадані сесії, негайно повертає { runId, acceptedAt }.
  2. agentCommand запускає агента:
    • визначає модель + стандартні значення thinking/verbose/trace
    • завантажує знімок Skills
    • викликає runEmbeddedPiAgent (середовище виконання pi-agent-core)
    • генерує завершення/помилку життєвого циклу, якщо вбудований цикл не генерує такої події
  3. runEmbeddedPiAgent:
    • серіалізує запуски через черги для кожної сесії + глобальні черги
    • визначає модель + профіль автентифікації та створює сесію pi
    • підписується на події pi та транслює дельти асистента/інструментів
    • застосовує тайм-аут -> перериває запуск, якщо його перевищено
    • для ходів app-server Codex перериває прийнятий хід, який припиняє генерувати прогрес app-server до термінальної події
    • повертає payload-и + метадані використання
  4. subscribeEmbeddedPiSession мостить події pi-agent-core у потік OpenClaw agent:
    • події інструментів => stream: "tool"
    • дельти асистента => stream: "assistant"
    • події життєвого циклу => stream: "lifecycle" (phase: "start" | "end" | "error")
  5. agent.wait використовує waitForAgentRun:
    • очікує завершення/помилки життєвого циклу для runId
    • повертає { status: ok|error|timeout, startedAt, endedAt, error? }

Черги + конкурентність

  • Запуски серіалізуються за ключем сесії (сесійна лінія) і, за потреби, через глобальну лінію.
  • Це запобігає гонкам інструментів/сесій і зберігає узгоджену історію сесії.
  • Канали повідомлень можуть вибирати режими черги (collect/steer/followup), які подаються в цю систему ліній. Див. Черга команд.
  • Записи транскрипта також захищені блокуванням запису сесії на файлі сесії. Блокування враховує процеси та базується на файлі, тому воно перехоплює записувачів, які обходять внутрішньопроцесну чергу або надходять з іншого процесу. Записувачі транскрипта сесії чекають до session.writeLock.acquireTimeoutMs перед тим, як повідомити, що сесія зайнята; стандартне значення — 60000 мс.
  • Блокування запису сесії за замовчуванням не є реентрантними. Якщо допоміжний модуль навмисно вкладає отримання того самого блокування, зберігаючи одного логічного записувача, він має явно ввімкнути це за допомогою allowReentrant: true.

Підготовка сесії + робочого простору

  • Робочий простір визначається та створюється; sandbox-запуски можуть перенаправлятися в корінь sandbox-робочого простору.
  • Skills завантажуються (або повторно використовуються зі знімка) та ін'єктуються в env і prompt.
  • Файли bootstrap/контексту визначаються та ін'єктуються у звіт системного prompt.
  • Отримується блокування запису сесії; SessionManager відкривається й готується до початку потокової передачі. Будь-який пізніший шлях переписування транскрипта, Compaction або усічення має взяти те саме блокування перед відкриттям або зміною файла транскрипта.

Складання prompt + системний prompt

  • Системний prompt будується з базового prompt OpenClaw, prompt Skills, bootstrap-контексту та перевизначень для окремого запуску.
  • Застосовуються специфічні для моделі ліміти та резерв токенів Compaction.
  • Див. Системний prompt, щоб дізнатися, що бачить модель.

Точки hook (де можна перехоплювати)

OpenClaw має дві системи hook:

  • Внутрішні hook-и (hook-и Gateway): керовані подіями скрипти для команд і подій життєвого циклу.
  • Hook-и Plugin: точки розширення всередині життєвого циклу агента/інструментів і конвеєра gateway.

Внутрішні hook-и (hook-и Gateway)

  • agent:bootstrap: запускається під час створення bootstrap-файлів перед фіналізацією системного prompt. Використовуйте це, щоб додавати/видаляти файли bootstrap-контексту.
  • Hook-и команд: /new, /reset, /stop та інші події команд (див. документ Hooks).

Див. Hooks для налаштування та прикладів.

Hook-и Plugin (життєвий цикл агента + gateway)

Вони виконуються всередині циклу агента або конвеєра gateway:

  • before_model_resolve: запускається до сесії (без messages), щоб детерміновано перевизначити provider/model перед визначенням моделі.
  • before_prompt_build: запускається після завантаження сесії (з messages), щоб ін'єктувати prependContext, systemPrompt, prependSystemContext або appendSystemContext перед поданням prompt. Використовуйте prependContext для динамічного тексту на окремий хід, а поля системного контексту — для стабільних настанов, які мають перебувати в просторі системного prompt.
  • before_agent_start: застарілий hook сумісності, який може запускатися в будь-якій фазі; надавайте перевагу явним hook-ам вище.
  • before_agent_reply: запускається після inline-дій і перед викликом LLM, даючи Plugin можливість забрати хід і повернути синтетичну відповідь або повністю заглушити хід.
  • agent_end: перевіряє фінальний список повідомлень і метадані запуску після завершення.
  • before_compaction / after_compaction: спостерігають або анотують цикли Compaction.
  • before_tool_call / after_tool_call: перехоплюють параметри/результати інструментів.
  • before_install: перевіряє вбудовані результати сканування та, за потреби, блокує встановлення skill або Plugin.
  • tool_result_persist: синхронно трансформує результати інструментів перед записом у транскрипт сесії, що належить OpenClaw.
  • message_received / message_sending / message_sent: hook-и вхідних + вихідних повідомлень.
  • session_start / session_end: межі життєвого циклу сесії.
  • gateway_start / gateway_stop: події життєвого циклу gateway.

Правила рішень hook для захистів вихідних повідомлень/інструментів:

  • before_tool_call: { block: true } є термінальним і зупиняє обробники з нижчим пріоритетом.
  • before_tool_call: { block: false } є no-op і не очищає попереднє блокування.
  • before_install: { block: true } є термінальним і зупиняє обробники з нижчим пріоритетом.
  • before_install: { block: false } є no-op і не очищає попереднє блокування.
  • message_sending: { cancel: true } є термінальним і зупиняє обробники з нижчим пріоритетом.
  • message_sending: { cancel: false } є no-op і не очищає попереднє скасування.

Див. Hook-и Plugin для API hook і деталей реєстрації.

Harness-и можуть адаптувати ці hook-и по-різному. Harness app-server Codex зберігає hook-и Plugin OpenClaw як контракт сумісності для задокументованих дзеркальних поверхонь, тоді як нативні hook-и Codex залишаються окремим нижчорівневим механізмом Codex.

Потокова передача + часткові відповіді

  • Дельти асистента транслюються з pi-agent-core і генеруються як події assistant.
  • Потокова передача блоків може генерувати часткові відповіді або на text_end, або на message_end.
  • Потокова передача reasoning може генеруватися як окремий потік або як блокові відповіді.
  • Див. Потокова передача для поведінки chunking і блокових відповідей.

Виконання інструментів + інструменти повідомлень

  • Події start/update/end інструментів генеруються в потоці tool.
  • Результати інструментів очищаються за розміром і payload-ами зображень перед логуванням/генеруванням подій.
  • Надсилання інструментами повідомлень відстежуються, щоб пригнічувати дублікати підтверджень асистента.

Формування відповіді + пригнічення

  • Фінальні payload-и складаються з:
    • тексту асистента (і необов'язкового reasoning)
    • inline-зведень інструментів (коли verbose + дозволено)
    • тексту помилки асистента, коли модель дає помилку
  • Точний мовчазний токен NO_REPLY / no_reply відфільтровується з вихідних payload-ів.
  • Дублікати інструментів повідомлень видаляються з фінального списку payload-ів.
  • Якщо не лишається payload-ів, придатних для рендерингу, і інструмент завершився помилкою, генерується резервна відповідь про помилку інструмента (якщо інструмент повідомлень уже не надіслав видиму для користувача відповідь).

Compaction + повторні спроби

  • Auto-compaction генерує події потоку compaction і може запустити повторну спробу.
  • Під час повторної спроби буфери в пам'яті та зведення інструментів скидаються, щоб уникнути дублювання виводу.
  • Див. Compaction для конвеєра Compaction.

Потоки подій (сьогодні)

  • lifecycle: генерується subscribeEmbeddedPiSession (і як fallback через agentCommand)
  • assistant: потокові дельти з pi-agent-core
  • tool: потокові події інструментів з pi-agent-core

Обробка чат-каналів

  • Дельти асистента буферизуються в чат-повідомлення delta.
  • Чат final генерується на завершення/помилку життєвого циклу.

Тайм-аути

  • Стандартне значення agent.wait: 30 с (лише очікування). Параметр timeoutMs перевизначає.
  • Середовище виконання агента: стандартне значення agents.defaults.timeoutSeconds — 172800 с (48 годин); застосовується таймером переривання в runEmbeddedPiAgent.
  • Середовище виконання Cron: timeoutSeconds ізольованого ходу агента належить cron. Планувальник запускає цей таймер, коли починається виконання, перериває базовий запуск на налаштованому дедлайні, а потім виконує обмежене очищення перед записом тайм-ауту, щоб застаріла дочірня сесія не могла тримати лінію заблокованою.
  • Діагностика живості сесії: коли діагностику ввімкнено, diagnostics.stuckSessionWarnMs класифікує тривалі сесії processing, у яких не спостерігається прогрес відповіді, інструмента, статусу, блоку або ACP. Активні вбудовані запуски, виклики моделі та виклики інструментів позначаються як session.long_running; активна робота без нещодавнього прогресу позначається як session.stalled; session.stuck зарезервовано для обліку застарілих сесій без активної роботи. Облік застарілої сесії негайно звільняє відповідну сесійну лінію; завислі вбудовані запуски перериваються з дренуванням лише після diagnostics.stuckSessionAbortMs (стандартно: щонайменше 10 хвилин і 5x порога попередження), щоб робота в черзі могла відновитися без обривання просто повільних запусків. Відновлення генерує структуровані requested/completed результати, а діагностичний стан позначається як idle лише якщо те саме покоління processing усе ще актуальне. Повторні діагностики session.stuck застосовують backoff, поки сесія залишається незмінною.
  • Тайм-аут простою моделі: OpenClaw перериває запит до моделі, коли до завершення вікна простою не надходять chunks відповіді. models.providers.<id>.timeoutSeconds розширює цей сторожовий таймер простою для повільних local/self-hosted provider-ів; інакше OpenClaw використовує agents.defaults.timeoutSeconds, коли його налаштовано, зі стандартним обмеженням 120 с. Запуски, ініційовані Cron, без явного тайм-ауту моделі або агента вимикають сторожовий таймер простою та покладаються на зовнішній тайм-аут cron.
  • Тайм-аут HTTP-запиту provider-а: models.providers.<id>.timeoutSeconds застосовується до HTTP fetch-ів моделі цього provider-а, включно з connect, headers, body, тайм-аутом SDK-запиту, загальною обробкою переривання guarded-fetch і сторожовим таймером простою потоку моделі. Використовуйте це для повільних local/self-hosted provider-ів, таких як Ollama, перш ніж підвищувати тайм-аут усього середовища виконання агента.

Де все може завершитися раніше

  • Тайм-аут агента (переривання)
  • AbortSignal (скасування)
  • Роз'єднання Gateway або тайм-аут RPC
  • Тайм-аут agent.wait (лише очікування, не зупиняє агента)

Пов'язане

  • Інструменти — доступні інструменти агента
  • Hooks — керовані подіями скрипти, що запускаються подіями життєвого циклу агента
  • Compaction — як підсумовуються довгі розмови
  • Схвалення Exec — шлюзи схвалення для shell-команд
  • Thinking — налаштування рівня thinking/reasoning