---
read_when:
    - Реалізація або оновлення клієнтів WS для Gateway
    - Налагодження невідповідностей протоколу або помилок підключення
    - Повторне генерування схеми/моделей протоколу
summary: 'Протокол WebSocket Gateway: установлення з’єднання, фрейми, версіонування'
title: Протокол Gateway
x-i18n:
    generated_at: "2026-07-16T18:01:45Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: 4cc92cfed4cf1bcc7b9499d90eef9f9225a89c0e6a71bb6230bb416f8f6884b5
    source_path: gateway/protocol.md
    workflow: 16
---

Протокол Gateway WS — це єдина площина керування та транспорт вузлів для
OpenClaw. Клієнти оператора й вузлів (CLI, вебінтерфейс, застосунок macOS, вузли iOS/Android,
вузли без графічного інтерфейсу) підключаються через WebSocket і оголошують **роль** та **область дії** під час
узгодження з’єднання.

## Транспорт і кадрування

- WebSocket, текстові кадри, корисні навантаження JSON.
- Перший кадр **має** бути запитом `connect`.
- Кадри до підключення обмежено розміром 64 KiB (`MAX_PREAUTH_PAYLOAD_BYTES`). Після
  узгодження з’єднання дотримуйтеся `hello-ok.policy.maxPayload` і
  `hello-ok.policy.maxBufferedBytes`. Коли діагностику ввімкнено, надмірно великі
  вхідні кадри й повільні вихідні буфери породжують події `payload.large`, перш ніж
  Gateway закриє з’єднання або відкине кадр. Ці події містять `surface`, розміри
  в байтах, обмеження й безпечний код причини, але ніколи не містять тіла повідомлень, вміст
  вкладень, необроблені байти кадрів, токени, файли cookie чи секрети.

Форми кадрів:

- Запит: `{type:"req", id, method, params}`
- Відповідь: `{type:"res", id, ok, payload|error}`
- Подія: `{type:"event", event, payload, seq?, stateVersion?}`

Методи з побічними ефектами потребують ключів ідемпотентності (див. схему).

## Узгодження з’єднання

Gateway надсилає виклик до підключення:

```json
{
  "type": "event",
  "event": "connect.challenge",
  "payload": { "nonce": "…", "ts": 1737264000000 }
}
```

Клієнт відповідає через `connect`:

```json
{
  "type": "req",
  "id": "…",
  "method": "connect",
  "params": {
    "minProtocol": 4,
    "maxProtocol": 4,
    "client": {
      "id": "cli",
      "version": "1.2.3",
      "platform": "macos",
      "mode": "operator"
    },
    "role": "operator",
    "scopes": ["operator.read", "operator.write"],
    "caps": [],
    "commands": [],
    "permissions": {},
    "auth": { "token": "…" },
    "locale": "en-US",
    "userAgent": "openclaw-cli/1.2.3",
    "device": {
      "id": "device_fingerprint",
      "publicKey": "…",
      "signature": "…",
      "signedAt": 1737264000000,
      "nonce": "…"
    }
  }
}
```

Gateway відповідає через `hello-ok`:

```json
{
  "type": "res",
  "id": "…",
  "ok": true,
  "payload": {
    "type": "hello-ok",
    "protocol": 4,
    "server": { "version": "…", "connId": "…" },
    "features": { "methods": ["…"], "events": ["…"] },
    "snapshot": { "…": "…" },
    "auth": {
      "role": "operator",
      "scopes": ["operator.read", "operator.write"]
    },
    "policy": {
      "maxPayload": 26214400,
      "maxBufferedBytes": 52428800,
      "tickIntervalMs": 15000
    }
  }
}
```

`server`, `features`, `snapshot`, `policy` і `auth` — усі обов’язкові для
`HelloOkSchema` (`packages/gateway-protocol/src/schema/frames.ts`). `auth`
повідомляє узгоджену роль і області дії, навіть коли токен пристрою не видано (форма
вище). `pluginSurfaceUrls` є необов’язковим і зіставляє назви поверхонь Plugin (наприклад,
`canvas`) з розміщеними URL-адресами з обмеженою областю дії; термін їхньої дії може спливати, тому вузли викликають
`node.pluginSurface.refresh` з `{ "surface": "canvas" }`, щоб отримати актуальний запис.
Застарілий шлях `canvasHostUrl` / `canvasCapability` / `node.canvas.capability.refresh`
не підтримується; використовуйте поверхні Plugin.
Необов’язковий `appliedConfigHash` у знімку — це ревізія вихідної конфігурації,
прийнята активним середовищем виконання Gateway. Клієнти можуть порівняти її з
`config.get.configRevisionHash`, щоб визначити, чи новіша збережена конфігурація досі
потребує перезапуску. `config.get.hash` залишається необробленою ревізією кореневого файла, яку використовують
запобіжники конфліктів запису конфігурації.

Поки Gateway ще завершує запуск допоміжних процесів, `connect` може повернути
помилку `UNAVAILABLE`, яку можна повторити, з `details.reason: "startup-sidecars"` і
`retryAfterMs`. Повторіть спробу в межах бюджету підключення замість того, щоб вважати її
остаточною помилкою узгодження з’єднання.

Коли токен пристрою видано, `hello-ok.auth` додає його:

```json
{
  "auth": {
    "deviceToken": "…",
    "role": "operator",
    "scopes": ["operator.read", "operator.write"]
  }
}
```

Вбудоване початкове налаштування за QR-кодом або кодом налаштування — це шлях передавання на мобільний пристрій. Успішне
базове підключення за кодом налаштування повертає основний токен вузла та один обмежений
токен оператора:

```json
{
  "auth": {
    "deviceToken": "…",
    "role": "node",
    "scopes": [],
    "deviceTokens": [
      {
        "deviceToken": "…",
        "role": "operator",
        "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"]
      }
    ]
  }
}
```

Це передавання оператору навмисно обмежене: достатнє для запуску мобільного
циклу оператора й нативного налаштування, зокрема `operator.talk.secrets` для читання
конфігурації Talk, але без областей дії для змінення сполучення та без `operator.admin`. Ширший
доступ до сполучення й адміністрування потребує окремого схваленого процесу сполучення або отримання токена. Зберігайте
`hello-ok.auth.deviceTokens` лише тоді, коли автентифікацію початкового налаштування виконано через довірений
транспорт (`wss://` або сполучення через loopback/локальне з’єднання).

Довірені клієнти серверної частини в тому самому процесі (`client.id: "gateway-client"`,
`client.mode: "backend"`) можуть не вказувати `device` для прямих loopback-з’єднань під час
автентифікації за допомогою спільного токена або пароля Gateway. Цей шлях призначено
для внутрішніх RPC площини керування (наприклад, оновлень сеансів підагентів) і він запобігає
блокуванню локальної роботи серверної частини через застарілі базові дані сполучення CLI/пристрою. Віддалені
клієнти, клієнти з браузерним походженням, вузли та клієнти з явним токеном пристрою або ідентичністю пристрою й надалі
проходять звичайні перевірки сполучення та підвищення областей дії.

### Роль виконавця й закритий протокол

Хмарні виконавці використовують окремий loopback-вхід через тунель SSH, що належить Gateway
і має закріплений ключ хоста. Він приймає лише ідентичність виконавця й ніколи не спрямовує
загальну автентифікацію, події вузлів, RPC оператора чи методи Plugin. Строгий `connect`
перевіряє короткочасні облікові дані з хешем у стані спокою, прив’язані до середовища, хешу пакета,
епохи власника, версії набору RPC, строку дії та одного необов’язкового сеансу; він
окремо перевіряє поточну версію й набір функцій. У разі успіху повертається мінімальний
`worker-hello-ok`; узгодження функцій не залежить від загальної версії
протоколу. Розмір кадрів залишається меншим за 64 KiB, крім узгодженого кадру `worker.inference.start`,
який може мати розмір до 25 MiB. Закритий список дозволеного містить `worker.heartbeat`,
`worker.transcript.commit`, `worker.live-event`, `worker.inference.start` і
`worker.inference.cancel`.

Фіксації транскрипту використовують відсікання за епохою власника, прив’язування сеансу, що належить Gateway,
порівняння й заміну базового кінцевого елемента та довговічне повторне відтворення послідовності; Gateway створює
ідентифікатори записів транскрипту й батьківських елементів через звичайний засіб запису сеансів. Право власності й
строк дії повторно перевіряються під час кожного RPC.

### Можливості клієнта

Клієнти оператора можуть оголошувати необов’язкові можливості в `connect.params.caps`:

- `tool-events`: приймає структуровані події життєвого циклу інструментів.
- `inline-widgets`: може відтворювати результати інструментів розміщених вбудованих віджетів.

Можливості клієнта описують підключеного клієнта, а не авторизацію. Інструменти агента можуть оголошувати обов’язкові можливості; Gateway не надає ці інструменти, якщо кожна вимога не вказана в `caps` початкового клієнта. Запуски, ініційовані каналами, не мають можливостей клієнта Gateway, тому інструменти з обмеженням за можливостями недоступні, навіть якщо політика інструментів явно їх дозволяє.

### Приклад підключення вузла

```json
{
  "type": "req",
  "id": "…",
  "method": "connect",
  "params": {
    "minProtocol": 4,
    "maxProtocol": 4,
    "client": {
      "id": "ios-node",
      "version": "1.2.3",
      "platform": "ios",
      "mode": "node"
    },
    "role": "node",
    "scopes": [],
    "caps": ["camera", "canvas", "screen", "location", "voice"],
    "commands": ["camera.snap", "canvas.navigate", "screen.record", "location.get"],
    "permissions": { "camera.capture": true, "screen.record": false },
    "auth": { "token": "…" },
    "locale": "en-US",
    "userAgent": "openclaw-ios/1.2.3",
    "device": {
      "id": "device_fingerprint",
      "publicKey": "…",
      "signature": "…",
      "signedAt": 1737264000000,
      "nonce": "…"
    }
  }
}
```

Вузли оголошують заявлені можливості під час підключення:

- `caps`: категорії високого рівня, як-от `camera`, `canvas`, `screen`,
  `location`, `voice`, `talk`.
- `commands`: список команд, дозволених для виклику.
- `permissions`: детальні перемикачі (наприклад, `screen.record`, `camera.capture`).

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

## Ролі й області дії

Повну модель областей дії оператора, перевірки під час схвалення та семантику
спільного секрету наведено в розділі [Області дії оператора](/uk/gateway/operator-scopes).

Ролі:

- `operator`: клієнт площини керування (CLI/UI/автоматизація).
- `node`: хост можливостей (камера/екран/полотно/system.run).
- `worker`: хост хмарного виконання у виділеному закритому протоколі виконавців.

Області дії оператора (`src/gateway/operator-scopes.ts`), повний закритий набір:

- `operator.read`
- `operator.write`
- `operator.admin`
- `operator.approvals`
- `operator.pairing`
- `operator.talk.secrets`

`talk.config` з `includeSecrets: true` потребує `operator.talk.secrets` (або
`operator.admin`). Коли включено секрети, прочитайте активні облікові дані постачальника Talk
з `talk.resolved.config.apiKey`; `talk.providers.<id>.apiKey`
зберігає форму джерела й може бути об’єктом SecretRef або редагованим рядком.

Зареєстровані Plugin методи RPC Gateway можуть запитувати власну область дії оператора,
але ці зарезервовані основні префікси завжди відповідають `operator.admin`
(`src/shared/gateway-method-policy.ts`): `config.*`, `exec.approvals.*`,
`wizard.*`, `update.*`.

Область дії методу — лише перший запобіжник. Деякі команди з косою рискою, доступні через
`chat.send`, застосовують суворіші перевірки на рівні команд: постійний запис `/config set` і
`/config unset` потребує `operator.admin` навіть для клієнтів Gateway, які
вже мають нижчу область дії оператора.

`node.pair.approve` має додаткову перевірку області дії під час схвалення на додачу до базової
області дії методу (`operator.pairing`) на основі оголошеного в очікуваному запиті
`commands` (`src/infra/node-pairing-authz.ts`):

| Оголошені команди                                                                                                             | Необхідні області дії                       |
| ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| немає                                                                                                                          | `operator.pairing`                    |
| звичайні команди                                                                                                             | `operator.pairing` + `operator.write` |
| містить `system.run`, `system.run.prepare`, `system.which`, `browser.proxy`, `fs.listDir` або `system.execApprovals.get/set` | `operator.pairing` + `operator.admin` |

### Можливості/команди/дозволи (вузол)

Вузли оголошують заявлені можливості під час підключення:

- `caps`: категорії можливостей високого рівня, як-от `camera`, `canvas`, `screen`,
  `location`, `voice` і `talk`.
- `commands`: список команд, дозволених для виклику.
- `permissions`: детальні перемикачі (наприклад, `screen.record`, `camera.capture`).

Gateway розглядає їх як **заявлені можливості** та забезпечує дотримання серверних списків дозволів.
Підключені вузли можуть публікувати необов’язкові, видимі агенту дескриптори інструментів Plugin або MCP
за допомогою `node.pluginTools.update` після успішного підключення або
повторного підключення. Хости вузлів без графічного інтерфейсу перезапускаються, щоб застосувати декларативні зміни
інвентарю MCP. Цей метод оновлення є єдиним способом публікації; дескриптори інструментів Plugin не приймаються в
параметрах `connect`. Кожен дескриптор має використовувати безпечне для провайдера значення `name` інструмента та вказувати
`command` із поточного списку дозволених команд вузла. Gateway довіряє метаданим дескрипторів
від спареного вузла, відфільтровує дескриптори поза межами затвердженої поверхні
команд, видаляє їх після відключення вузла та відхиляє спроби оператора
змінити каталог іншого вузла. Установіть `gateway.nodes.pluginTools.enabled: false`,
щоб ігнорувати опубліковані вузлами дескриптори.

Підключені хости вузлів публікують повний каталог замін навичок за допомогою
`node.skills.update`. Цей метод для ролі вузла є єдиним способом публікації
навичок вузла; навички не приймаються в параметрах `connect`. Кожен дескриптор містить
безпечну назву, опис і вміст `SKILL.md` обмеженого розміру. Gateway аналізує цей
вміст за допомогою звичайного завантажувача навичок, додає його до знімків навичок агента,
поки вузол підключений, і видаляє після відключення. Установіть
`gateway.nodes.skills.enabled: false`, щоб ігнорувати опубліковані вузлами навички.

## Присутність

- `system-presence` повертає записи, ключами яких є ідентичності пристроїв, зокрема
  `deviceId`, `roles` і `scopes`, щоб інтерфейси могли показувати один рядок для кожного пристрою, навіть
  якщо він підключається одночасно як оператор і вузол.
- `node.list` містить необов’язкові `lastSeenAtMs` і `lastSeenReason`. Підключені
  вузли повідомляють поточний час підключення з причиною `connect`; спарені вузли також можуть
  повідомляти про сталу фонову присутність через довірену подію вузла.

Нативні вузли macOS також можуть надсилати автентифіковані події `node.presence.activity`
з обмеженим часом бездіяльності введення. Gateway визначає часові позначки активності за
власним годинником, надає найсвіжіший підключений Mac через `node.list` і
`node.describe` та транслює оновлення `node.presence` клієнтам із правами читання.
Докладніше про вибір, конфіденційність, контекст моделі
та маршрутизацію сповіщень див. у розділі [Присутність активного комп’ютера](/nodes/presence).

### Фонова подія активності вузла

Вузли викликають `node.event` з `event: "node.presence.alive"`, щоб зафіксувати, що
спарений вузол був активний під час фонового пробудження, не позначаючи його як підключений:

```json
{
  "event": "node.presence.alive",
  "payloadJSON": "{\"trigger\":\"silent_push\",\"sentAtMs\":1737264000000,\"displayName\":\"Peter's iPhone\",\"version\":\"2026.4.28\",\"platform\":\"iOS 18.4.0\",\"deviceFamily\":\"iPhone\",\"modelIdentifier\":\"iPhone17,1\",\"pushTransport\":\"relay\"}"
}
```

`trigger` — це закритий перелік: `background`, `silent_push`, `bg_app_refresh`,
`significant_location`, `manual`, `connect`. Невідомі значення нормалізуються до
`background` (`src/shared/node-presence.ts`). Подія зберігається лише для
автентифікованих сеансів пристроїв вузлів; сеанси без пристрою або без спарення повертають
`handled: false`.

У разі успіху Gateway повертає структурований результат:

```json
{
  "ok": true,
  "event": "node.presence.alive",
  "handled": true,
  "reason": "persisted"
}
```

Старіші версії Gateway можуть повертати лише `{ "ok": true }` для `node.event`; це слід вважати
підтвердженим RPC, а не сталим збереженням присутності.

## Обмеження області трансляційних подій

Надіслані сервером трансляційні події обмежуються областями, щоб сеанси,
призначені лише для спарення або вузлів, пасивно не отримували вміст сеансів
(`src/gateway/server-broadcast.ts`):

- Кадри чату, агента й результатів інструментів (потокові події `agent`, події
  результатів інструментів) потребують принаймні `operator.read`. Сеанси без цього
  дозволу повністю пропускають ці кадри.
- Визначені Plugin трансляції `plugin.*` типово обмежуються `operator.write` або
  `operator.admin`; явні записи, як-от
  `plugin.approval.requested` / `plugin.approval.resolved`, натомість використовують
  `operator.approvals`.
- Події стану й транспорту (`heartbeat`, `presence`, `tick`, життєвий цикл
  підключення/відключення) залишаються необмеженими, щоб стан транспорту був доступний для спостереження кожному
  автентифікованому сеансу.
- Невідомі сімейства трансляційних подій типово обмежуються областями (закриті за замовчуванням),
  якщо зареєстрований обробник явно не послаблює ці обмеження.

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

## Сімейства методів RPC

`hello-ok.features.methods` — це консервативний список виявлення, сформований із
`src/gateway/server-methods-list.ts` та експортованих методів завантажених Plugin і каналів,
а не автоматично створений перелік усіх методів; деякі методи (наприклад,
`push.test`, `web.login.start`, `web.login.wait`, `sessions.usage`)
навмисно вилучено з виявлення, хоча вони є справжніми доступними для виклику
методами. Розглядайте це як виявлення функцій, а не повний перелік
`src/gateway/server-methods/*.ts`.

<AccordionGroup>
  <Accordion title="Система та ідентичність">
    - `health` повертає кешований або щойно отриманий знімок стану працездатності Gateway.
    - `diagnostics.stability` повертає останні записи обмеженого діагностичного реєстратора стабільності: назви подій, кількість, розміри в байтах, показники пам’яті, стан черг і сеансів, назви каналів і Plugin, ідентифікатори сеансів. Без тексту чатів, тіл webhook, результатів інструментів, необроблених тіл запитів і відповідей, токенів, файлів cookie або секретів. Потребує `operator.read`.
    - `status` повертає зведення Gateway у стилі `/status`; конфіденційні поля доступні лише клієнтам-операторам з областю адміністратора.
    - `gateway.identity.get` повертає ідентичність пристрою Gateway, яку використовують процеси ретрансляції та спарення.
    - `system-presence` повертає поточний знімок присутності підключених пристроїв операторів і вузлів.
    - `system-event` додає системну подію та може оновлювати або транслювати контекст присутності.
    - `last-heartbeat` повертає останню збережену подію Heartbeat.
    - `set-heartbeats` вмикає або вимикає оброблення Heartbeat у Gateway.
    - `gateway.suspend.prepare` створює коротку оренду для узгодженого призупинення лише тоді, коли відстежувана робота Gateway неактивна. `gateway.suspend.status` перевіряє цю оренду, а `gateway.suspend.resume` звільняє її після відновлення або перерваної операції хоста.

  </Accordion>

  <Accordion title="Моделі та використання">
    - `models.list` повертає дозволений середовищем виконання каталог моделей. Див. «Подання `models.list`» нижче.
    - `usage.status` повертає зведення вікон використання та залишку квоти провайдера.
    - `usage.cost` повертає агреговані зведення витрат за діапазон дат. Передайте `agentId` для одного агента або `agentScope: "all"`, щоб агрегувати налаштованих агентів.
    - `doctor.memory.status` повертає стан готовності векторної пам’яті та кешованих вбудовувань для активного типового робочого простору агента. Передавайте `{ "probe": true }` або `{ "deep": true }` лише для явної оперативної перевірки провайдера вбудовувань. Передайте `{ "agentId": "agent-id" }`, щоб обмежити статистику сховища Dreaming одним робочим простором агента; якщо його не вказати, агрегуються налаштовані робочі простори Dreaming.
    - `doctor.memory.dreamDiary`, `doctor.memory.backfillDreamDiary`, `doctor.memory.resetDreamDiary`, `doctor.memory.resetGroundedShortTerm`, `doctor.memory.repairDreamingArtifacts` і `doctor.memory.dedupeDreamDiary` приймають необов’язковий `{ "agentId": "agent-id" }`; якщо його не вказати, вони працюють із налаштованим типовим робочим простором агента.
    - `doctor.memory.remHarness` повертає обмежений попередній перегляд стенда REM лише для читання для віддалених клієнтів площини керування, зокрема шляхи робочого простору, фрагменти пам’яті, відтворений обґрунтований Markdown і кандидати на поглиблене просування. Потребує `operator.read`.
    - `sessions.usage` повертає зведення використання для кожного сеансу. Передайте `agentId` для одного агента або `agentScope: "all"`, щоб перелічити налаштованих агентів разом.
      Обидва методи використання приймають `mode: "specific"` із часовим поясом IANA `timeZone` для меж і сегментів календарних днів з урахуванням літнього часу. `utcOffset` досі підтримується для старіших клієнтів і як резервний варіант, коли середовище виконання Gateway не розпізнає запитаний часовий пояс.
    - `sessions.usage.timeseries` повертає часовий ряд використання для одного сеансу.
    - `sessions.usage.logs` повертає записи журналу використання для одного сеансу.

  </Accordion>

  <Accordion title="Канали та допоміжні засоби входу">
    - `channels.status` повертає зведення стану вбудованих і комплектних каналів та Plugin.
    - `channels.logout` виконує вихід із певного каналу або облікового запису, якщо канал це підтримує.
    - `web.login.start` запускає процес входу через QR-код або вебінтерфейс для поточного провайдера вебканалу з підтримкою QR-коду.
    - `web.login.wait` очікує завершення цього процесу та в разі успіху запускає канал.
    - `push.test` надсилає тестове push-сповіщення APNs зареєстрованому вузлу iOS.
    - `voicewake.get` повертає збережені фрази активації.
    - `voicewake.set` оновлює фрази активації та транслює зміну.

  </Accordion>

  <Accordion title="Керування Plugin">
    - `plugins.list` (`operator.read`) повертає інвентар установлених Plugin, локально сформовану добірку офіційних варіантів, діагностику та відомості про те, чи дозволяє поточний режим установлення зміни.
    - `plugins.search` (`operator.read`) шукає доступні для встановлення сімейства Plugin коду та пакетів у ClawHub. Передайте непорожній `query` і необов’язковий `limit` від 1 до 100.
    - `plugins.install` (`operator.admin`) установлює або офіційний запис каталогу з `{ source: "official", pluginId }`, або пакет ClawHub з `{ source: "clawhub", packageName, version?, acknowledgeClawHubRisk? }`. Установлення з ClawHub зберігають перевірки довіри Gateway, цілісності та політики встановлення. Після успішного встановлення Gateway потрібно перезапустити.
    - `plugins.setEnabled` (`operator.admin`) змінює політику ввімкнення одного встановленого Plugin за допомогою `{ pluginId, enabled }`. Відповідь містить оновлений запис каталогу, метадані перезапуску та всі попередження щодо вибору слота.
    - `plugins.uninstall` (`operator.admin`) видаляє один установлений іззовні Plugin за допомогою `{ pluginId }`: посилання в конфігурації, запис установлення та керовані файли. Комплектні Plugin не можна видалити — їх можна лише вимкнути. Відповідь містить перелік дій із видалення та завжди вимагає перезапуску Gateway.

  </Accordion>

  <Accordion title="Повідомлення та журнали">
    - `send` — це RPC прямого вихідного доставлення для надсилань, спрямованих на канал, обліковий запис або гілку, поза засобом виконання чату.
    - `logs.tail` повертає кінцеву частину налаштованого файлового журналу Gateway з керуванням курсором, лімітом і максимальною кількістю байтів.

  </Accordion>

  <Accordion title="Термінал оператора">
    - `terminal.open` запускає PTY хоста для явно вказаного `agentId` або агента за замовчуванням і повертає визначеного агента, робочий каталог, оболонку та стан ізоляції.
    - `terminal.input`, `terminal.resize` і `terminal.close` працюють лише із сеансами, що належать з’єднанню, яке їх викликає.
    - `terminal.upload` приймає один файл у кодуванні base64 розміром до 16 MiB, розміщує його в приватному тимчасовому каталозі зі строком зберігання 24 години на Gateway сеансу або хості спареного вузла та повертає абсолютний шлях. Сторона виклику все одно має вставити або іншим способом використати цей шлях; RPC ніколи не записує дані в термінал і не виконує команду.
    - Події `terminal.data` і `terminal.exit` передаються лише з’єднанню, якому належить сеанс.
    - Сеанси, з’єднання яких розірвано, від’єднуються, а не завершуються: вони залишаються доступними для повторного приєднання протягом `gateway.terminal.detachedSessionTimeoutSeconds` (за замовчуванням 300; `0` відновлює завершення після роз’єднання), а нещодавній вивід накопичується в обмеженому буфері на боці сервера.
    - `terminal.list` повертає доступні для приєднання сеанси; `terminal.attach` повторно прив’язує активний або від’єднаний сеанс до з’єднання, яке викликає метод, і повертає буфер повторного відтворення (перехоплення у стилі tmux — попередній активний власник отримує `terminal.exit` із причиною `detached`); `terminal.text` читає буфер як звичайний текст без приєднання.
    - Кожен метод термінала потребує `operator.admin`; значення `gateway.terminal.enabled` має бути явно встановлено на true. Повністю ізольованим агентам доступ заборонено, а зміна політики агента закриває наявні PTY та PTY, що виконуються, включно з від’єднаними.

  </Accordion>

  <Accordion title="Розмова та TTS">
    - `talk.catalog` повертає доступний лише для читання каталог постачальників розмовних функцій для синтезу мовлення, потокової транскрипції та голосового зв’язку в реальному часі: канонічні ідентифікатори постачальників, псевдоніми реєстру, мітки, стан налаштування, необов’язковий результат `ready` на рівні групи, доступні ідентифікатори моделей і голосів, канонічні режими, транспорти, стратегії мозку та прапорці аудіо й можливостей реального часу — без повернення секретів постачальників або зміни глобальної конфігурації. Поточні шлюзи встановлюють `ready` після застосування вибору постачальника середовища виконання; на старіших шлюзах відсутність цього значення слід вважати неперевіреним станом.
    - `talk.config` повертає фактичне корисне навантаження конфігурації розмовних функцій; `includeSecrets` потребує `operator.talk.secrets` (або `operator.admin`).
    - `talk.session.create` створює сеанс розмовних функцій, яким керує шлюз, для `realtime/gateway-relay`, `transcription/gateway-relay` або `stt-tts/managed-room`. Для `stt-tts/managed-room` сторони виклику `operator.write`, які передають `sessionKey`, також мають передати `spawnedBy` для видимості ключа сеансу в межах області дії; створення `sessionKey` без області дії та `brain: "direct-tools"` потребують `operator.admin`.
    - `talk.session.join` перевіряє токен сеансу керованої кімнати, за потреби генерує `session.ready` або `session.replaced` і повертає метадані кімнати й сеансу разом із нещодавніми подіями розмовних функцій, але ніколи не повертає токен у відкритому вигляді чи його хеш.
    - `talk.session.appendAudio` додає вхідні аудіодані PCM у кодуванні base64 до сеансів ретрансляції в реальному часі та транскрипції, якими керує шлюз.
    - `talk.session.startTurn`, `talk.session.endTurn` і `talk.session.cancelTurn` керують життєвим циклом репліки керованої кімнати, відхиляючи застарілі репліки до очищення стану.
    - `talk.session.cancelOutput` зупиняє аудіовихід асистента, насамперед для перебивання, керованого VAD, у сеансах ретрансляції шлюзу.
    - `talk.session.submitToolResult` завершує виклик інструмента постачальника, створений сеансом ретрансляції в реальному часі, яким керує шлюз. Запит очікує на будь-який асинхронний сигнал завершення, наданий мостом постачальника; невдалі надсилання залишають пов’язаний запуск активним і не генерують подію успішного результату інструмента. Передайте `options: { willContinue: true }` для проміжного виводу інструмента або `options: { suppressResponse: true }`, якщо міст постачальника оголошує підтримку придушення й результат не повинен запускати ще одну відповідь.
    - `talk.session.steer` надсилає голосову команду керування активним запуском до сеансу розмовних функцій на основі агента, яким керує шлюз: `{ sessionId, text, mode? }`, де `mode` — це `status`, `steer`, `cancel` або `followup`; якщо режим не вказано, його класифікують за промовленим текстом.
    - `talk.session.close` закриває сеанс ретрансляції, транскрипції або керованої кімнати, яким керує шлюз, і генерує завершальні події розмовних функцій.
    - `talk.mode` установлює та транслює поточний стан режиму розмовних функцій для клієнтів WebChat/Control UI.
    - `talk.client.create` створює сеанс постачальника реального часу, яким керує клієнт, за допомогою `webrtc` або `provider-websocket`, тоді як шлюз керує конфігурацією, обліковими даними, інструкціями та політикою інструментів.
    - `talk.client.toolCall` дає змогу транспортам реального часу, якими керує клієнт, пересилати виклики інструментів постачальника до політики шлюзу. Перший підтримуваний інструмент — `openclaw_agent_consult`; клієнти отримують ідентифікатор запуску й очікують на звичайні події життєвого циклу чату, перш ніж надіслати результат інструмента, специфічний для постачальника.
    - `talk.client.steer` надсилає голосову команду керування активним запуском для транспортів реального часу, якими керує клієнт. Шлюз визначає активний вбудований запуск із `sessionKey` і повертає структурований результат прийняття або відхилення замість мовчазного відкидання керівної команди.
    - `talk.event` — єдиний канал подій розмовних функцій для адаптерів реального часу, транскрипції, STT/TTS, керованих кімнат, телефонії та зустрічей.
    - `talk.speak` синтезує мовлення через активного постачальника синтезу мовлення розмовних функцій.
    - `tts.status` повертає стан увімкнення TTS, активного постачальника, резервних постачальників і стан конфігурації постачальників.
    - `tts.providers` повертає видимий перелік постачальників TTS.
    - `tts.enable` і `tts.disable` перемикають стан налаштувань TTS.
    - `tts.setProvider` оновлює бажаного постачальника TTS.
    - `tts.convert` виконує одноразове перетворення тексту на мовлення.
    - `tts.speak` (`operator.write`) озвучує непорожній `text` за допомогою налаштованого загального ланцюжка постачальників TTS і повертає один повний аудіофрагмент безпосередньо як `audioBase64`, а також `provider` і необов’язкові метадані `outputFormat`, `mimeType` та `fileExtension`. На відміну від `tts.convert`, він не повертає локальний для Gateway шлях; на відміну від `talk.speak`, він не потребує постачальника розмовних функцій. Текст, обсяг якого перевищує `messages.tts.maxTextLength`, повертає `INVALID_REQUEST`; помилки синтезу повертають `UNAVAILABLE`.

  </Accordion>

  <Accordion title="Секрети, конфігурація, оновлення та майстер">
    - `secrets.reload` повторно визначає активні SecretRefs і замінює стан секретів середовища виконання лише в разі повного успіху.
    - `secrets.resolve` визначає призначення секретів цільових об’єктів команди для певного набору команд і цілей.
    - `config.get` повертає поточний знімок конфігурації на диску, необроблений `hash` кореневого файла, визначений `configRevisionHash` і необов’язковий `appliedConfigHash` для визначеної ревізії, прийнятої активним середовищем виконання Gateway.
    - `config.set` записує перевірене корисне навантаження конфігурації.
    - `config.patch` об’єднує часткове оновлення конфігурації. Деструктивна заміна масиву потребує зазначення відповідного шляху в `replacePaths`; вкладені масиви всередині елементів масиву використовують шляхи `[]`, як-от `agents.list[].skills`.
    - `config.apply` перевіряє та замінює повне корисне навантаження конфігурації.
    - `config.schema` повертає актуальне корисне навантаження схеми конфігурації, яке використовують інструменти Control UI та CLI: схему, `uiHints`, версію, метадані генерування, метадані схем плагінів і каналів, якщо їх можна завантажити. Воно містить метадані `title` / `description` із тих самих міток і тексту довідки, що й інтерфейс користувача, включно з гілками композиції вкладених об’єктів, шаблонів, елементів масивів і `anyOf` / `oneOf` / `allOf`, якщо існує відповідна документація полів.
    - `config.schema.lookup` повертає корисне навантаження пошуку в межах шляху для одного шляху конфігурації: нормалізований шлях, поверхневий вузол схеми, відповідну підказку та `hintPath`, необов’язковий `reloadKind` і короткі відомості про безпосередні дочірні елементи для деталізації в UI/CLI. `reloadKind` має одне зі значень `restart`, `hot` або `none` (`src/config/schema.ts`) і відображає планувальник перезавантаження конфігурації шлюзу для запитаного шляху. Вузли схеми пошуку зберігають користувацьку документацію та поширені поля перевірки (`title`, `description`, `type`, `enum`, `const`, `format`, `pattern`, числові, рядкові, масивні й об’єктні обмеження, `additionalProperties`, `deprecated`, `readOnly`, `writeOnly`). Короткі відомості про дочірні елементи надають `key`, нормалізований `path`, `type`, `required`, `hasChildren`, необов’язковий `reloadKind`, а також відповідні `hint` / `hintPath`.
    - `update.run` запускає процес оновлення шлюзу та планує перезапуск лише за умови успішного оновлення; сторони виклику із сеансом можуть додати `continuationMessage`, щоб після запуску відновити один наступний хід агента через чергу продовження після перезапуску. Оновлення через менеджер пакетів і контрольовані оновлення робочої копії Git із площини керування використовують відокремлену передачу керованій службі замість заміни дерева пакетів або зміни робочої копії чи результатів збирання всередині активного шлюзу. Запущена передача повертає `ok: true` із `result.reason: "managed-service-handoff-started"` і `handoff.status: "started"`; недоступні або невдалі передачі повертають `ok: false` із `managed-service-handoff-unavailable` або `managed-service-handoff-failed`, а також `handoff.command`, якщо потрібне ручне оновлення через оболонку. Недоступність означає, що OpenClaw не має безпечної межі супервізора або сталої ідентичності служби, як-от `OPENCLAW_SYSTEMD_UNIT` для systemd. Під час запущеної передачі маркер перезапуску може короткочасно повідомляти `stats.reason: "restart-health-pending"`; продовження відкладається, доки CLI не перевірить перезапущений шлюз і не запише остаточний маркер `ok`.
    - `update.status` оновлює та повертає найновіший маркер перезапуску після оновлення, включно з поточною версією після перезапуску, якщо вона доступна.
    - `wizard.start`, `wizard.next`, `wizard.status` і `wizard.cancel` надають доступ до майстра початкового налаштування через WS RPC.

  </Accordion>

  <Accordion title="Допоміжні засоби агента та робочого простору">
    - `agents.list` повертає налаштовані записи агентів, зокрема фактичну модель і метадані середовища виконання.
    - `agents.create`, `agents.update` і `agents.delete` керують записами агентів і підключенням робочого простору.
    - `agents.files.list`, `agents.files.get` і `agents.files.set` керують початковими файлами робочого простору, доступними агенту.
    - `audit.activity.list` повертає версіонований журнал активності, що містить лише метадані; `audit.list` залишається сумісним RPC для запусків та інструментів.
    - `agents.workspace.list` і `agents.workspace.get` (`operator.read`) надають клієнтам у довіреному домені оператора, описаному в розділі [Області доступу оператора](/uk/gateway/operator-scopes), доступ лише для читання з посторінковим переглядом каталогу робочого простору агента. Запити приймають лише шляхи відносно робочого простору; читання обмежене коренем робочого простору після визначення реального шляху (вихід за його межі через символічні та жорсткі посилання відхиляється), має обмеження розміру й підтримує лише текст UTF-8 та поширені типи зображень (base64). Відповіді не розкривають шлях до робочого простору на хості. У цьому просторі імен немає операцій запису.
    - `tasks.list`, `tasks.get` і `tasks.cancel` надають клієнтам SDK та оператора доступ до журналу завдань Gateway. Див. [RPC журналу завдань](#task-ledger-rpcs) нижче.
    - `artifacts.list`, `artifacts.get` і `artifacts.download` надають зведення та завантаження артефактів, отриманих із транскрипту, для явно заданої області `sessionKey`, `runId` або `taskId`. Запити запусків і завдань визначають на сервері сеанс-власник та повертають лише медіафайли транскрипту з відповідним походженням; для небезпечних або локальних URL-джерел повертаються непідтримувані завантаження замість отримання даних на сервері.
    - `environments.list` і `environments.status` зберігають виявлення локального середовища Gateway і середовища Node. Налаштовані хмарні виконавці та довготривалі записи, залишені попередніми профілями, додають метадані `worker` з `providerId`, необов’язковим `leaseId`, `state`, `ageMs`, необов’язковим `idleMs` і `attachedSessionIds`. Стани життєвого циклу виконавця: `requested`, `provisioning`, `bootstrapping`, `ready`, `attached`, `idle`, `draining`, `destroying`, `destroyed`, `failed` і `orphaned`.
    - `environments.create` (`{ profileId, idempotencyKey }`) створює виконавця з налаштованого профілю постачальника плагіна; повторні спроби з тим самим ключем використовують повторно довготривалу операцію. `environments.destroy` (`{ environmentId }`) запитує ідемпотентне видалення довготривалого середовища виконавця. Обидві операції потребують `operator.admin`, виконують запис на рівні керування та повертають те саме представлення зведення про середовище, що й відповіді про стан.
    - `agent.identity.get` повертає фактичну ідентичність асистента для агента або сеансу.
    - `agent.wait` очікує завершення запуску й повертає кінцевий знімок стану, коли він доступний.

  </Accordion>

  <Accordion title="Керування сеансами">
    - `sessions.list` повертає поточний індекс сеансів, зокрема метадані `agentRuntime` для кожного рядка, коли налаштовано серверну частину середовища виконання агента. Коли ввімкнено розміщення у хмарних виконавцях або існує довготривалий стан відновлення, рядки сеансів також містять замкнений стан `placement` (`local`, `requested`, `provisioning`, `syncing`, `starting`, `active`, `draining`, `reconciling`, `reclaimed` або `failed`), а також специфічні для стану поля середовища, епохи власника, робочого простору, пакета, курсора ACK або відновлення.
    - `sessions.subscribe` і `sessions.unsubscribe` вмикають або вимикають підписки поточного клієнта WS на події змін сеансів.
    - `sessions.messages.subscribe` і `sessions.messages.unsubscribe` вмикають або вимикають підписки на події транскрипту й повідомлень для одного сеансу. Передайте `includeApprovals: true`, щоб також отримувати очищені події життєвого циклу `session.approval` для схвалень, у збережену аудиторію яких входить саме цей сеанс і прив’язка рецензента яких авторизує клієнта-підписника. Тоді відповідь на підписку містить обмежений список очікування `approvalReplay`; він є авторитетним, коли `truncated` має значення false. Увімкнення задається окремо для кожного виклику підписки й не зберігається: повторна підписка на той самий сеанс без `includeApprovals: true` видаляє наявну підписку на схвалення. Окрім звичайних повноважень на читання сеансу, для цього ввімкнення потрібен `operator.admin` або `operator.approvals` на спареному пристрої.
    - `sessions.preview` повертає обмежені попередні перегляди транскриптів для певних ключів сеансів.
    - `sessions.describe` повертає один рядок сеансу Gateway для точного ключа сеансу.
    - `sessions.resolve` визначає або канонізує ціль сеансу.
    - `sessions.create` створює новий запис сеансу. Необов’язкові значення `model` і `thinkingLevel` атомарно зберігають початкові перевизначення моделі та міркування. `worktree: true` створює кероване робоче дерево; необов’язкові `worktreeBaseRef`/`worktreeName` вибирають базове посилання та назву гілки, а `execNode` (`operator.admin`) прив’язує виконання сеансу до хоста Node. Створене робоче дерево повертається в результаті та зберігається в рядку сеансу (`worktree: { id, branch, repoRoot }`). Якщо запис створено, але вкладений початковий `chat.send` відхилено, успішний результат містить `runStarted: false` і `runError`; клієнти можуть зберегти запит і повторити спробу з повернутим ключем сеансу.
    - `sessions.dispatch` (`operator.admin`) переміщує наявний локальний сеанс OpenClaw із керованим робочим деревом, що належить сеансу, до налаштованого профілю хмарного виконавця. Передайте `{ key, profileId, agentId? }`. Метод відсутній, якщо не налаштовано профіль виконавця; він припиняє локальний допуск нових ходів перед завершенням активної роботи та повертає результат лише після того, як розміщення досягне стану володіння виконавцем `active`. Передавання одностороннє; повернення від виконавця до локального середовища не входить до цього RPC.
    - `sessions.groups.list`, `sessions.groups.put`, `sessions.groups.rename` і `sessions.groups.delete` керують належним Gateway каталогом користувацьких груп сеансів (назви та порядок відображення). Членство зберігається в полі `category` кожного сеансу; перейменування та видалення оновлюють сеанси-учасники на сервері.
    - `sessions.send` надсилає повідомлення до наявного сеансу.
    - `sessions.steer` — варіант із перериванням і зміною напряму для активного сеансу.
    - `sessions.abort` перериває активну роботу сеансу. Передайте `key` разом із необов’язковим `runId` або лише `runId` для активних запусків, які Gateway може зіставити із сеансом.
    - `sessions.patch` оновлює метадані й перевизначення сеансу та повідомляє визначену канонічну модель разом із фактичним `agentRuntime`.
    - `sessions.reset`, `sessions.delete` і `sessions.compact` виконують обслуговування сеансу.
    - `sessions.get` повертає повний збережений рядок сеансу.
    - Для виконання чату й надалі використовуються `chat.history`, `chat.send`, `chat.abort` і `chat.inject`. `chat.history` нормалізується для відображення у клієнтах інтерфейсу: вбудовані теги директив видаляються з видимого тексту, текстові XML-дані викликів інструментів (`<tool_call>...</tool_call>`, `<function_call>...</function_call>`, `<tool_calls>...</tool_calls>`, `<function_calls>...</function_calls>` і обрізані блоки викликів інструментів) та розкриті ASCII/повноширинні керівні токени моделі видаляються, рядки асистента, що містять лише токен мовчання (точно `NO_REPLY` / `no_reply`), пропускаються, а надмірно великі рядки можуть замінюватися заповнювачами.
    - `chat.message.get` — додатковий обмежений засіб читання повних повідомлень для одного видимого запису транскрипту. Передайте `sessionKey`, необов’язковий `agentId`, коли вибір сеансу обмежений агентом, і `messageId` транскрипту, раніше наданий через `chat.history`; Gateway повертає те саме нормалізоване для відображення представлення без обмеження обрізання спрощеної історії, якщо збережений запис усе ще доступний і не є надмірно великим.
    - `chat.toolTitles` повертає короткі назви призначення для викликів інструментів, що відображаються в інтерфейсі керування (пакетно, не більше 24 елементів з обмеженими вхідними даними). Функція вмикається явно через `gateway.controlUi.toolTitles` (типово вимкнена); вимкнені Gateway відповідають `{ titles: {}, disabled: true }` без виклику моделі, щоб клієнти припинили надсилати запити. Коли функцію ввімкнено, назви використовують стандартну маршрутизацію службової моделі: явно налаштований `utilityModel` (рішення оператора, яке, як і всі службові завдання, може надсилати обмежений вміст завдання вибраному постачальнику) або оголошену постачальником сеансу типову малу модель, щоб неявно не з’являвся новий напрямок передавання даних; порожній `utilityModel` повністю вимикає їх. Назви ніколи не переходять резервно на основну модель. Результати кешуються в базі даних стану окремого агента за ключем із назви інструмента та вхідних даних, тому повторні перегляди ніколи повторно не оплачують ті самі виклики.
    - `chat.send` приймає одноходовий `fastMode: "auto"`, щоб використовувати швидкий режим для викликів моделі, розпочатих до автоматичної граничної миті, а пізніші повторні, резервні виклики, виклики результатів інструментів або продовження запускати без швидкого режиму. Типова гранична тривалість становить 60 секунд (`DEFAULT_FAST_MODE_AUTO_ON_SECONDS`) і може бути налаштована для кожної моделі через `agents.defaults.models["<provider>/<model>"].params.fastAutoOnSeconds`. Викликач `chat.send` може передати одноходовий `fastAutoOnSeconds`, щоб перевизначити граничну тривалість для цього запиту. Передайте `queueMode` (`steer`, `followup`, `collect` або `interrupt`), щоб перевизначити збережений режим черги лише для цього запиту; явні дії зміни напряму в інтерфейсі керування використовують `queueMode: "steer"`.

  </Accordion>

  <Accordion title="Спарювання пристроїв і токени пристроїв">
    - `device.pair.list` повертає пристрої, що очікують спарювання, і схвалені спарені пристрої.
    - `device.pair.setupCode` створює код налаштування мобільного пристрою та, типово, URL-адресу даних PNG QR-коду. Для цього потрібен `operator.admin`, і метод навмисно не включено до оприлюдненого виявлення. Результат містить `setupCode`, необов’язковий `qrDataUrl`, `gatewayUrl`, несекретну мітку `auth` і `urlSource`.
    - `device.pair.approve`, `device.pair.reject` і `device.pair.remove` керують записами спарювання пристроїв.
    - `device.pair.rename` призначає мітку оператора (`{ deviceId, label }`), яка має перевагу над відображуваною назвою, повідомленою клієнтом, і зберігається після відновлення або повторного схвалення пристрою.
    - `device.token.rotate` змінює токен спареного пристрою в межах його схваленої ролі та областей доступу викликача.
    - `device.token.revoke` відкликає токен спареного пристрою в межах його схваленої ролі та областей доступу викликача.

    Код налаштування містить короткочасні початкові облікові дані. Клієнти не повинні
    записувати їх у журнал або зберігати після завершення процесу спарювання.

  </Accordion>

  <Accordion title="Сполучення Node, виклики та робота в очікуванні">
    - `node.pair.list`, `node.pair.approve`, `node.pair.reject` і `node.pair.remove` охоплюють схвалення можливостей Node. `node.pair.request` і `node.pair.verify` було видалено у версії 2026.7 разом з окремим сховищем сполучень Node; запити в очікуванні створює Gateway під час підключення Node.
    - `node.list` і `node.describe` повертають стан відомих/підключених Node.
    - `node.rename` оновлює мітку сполученого Node.
    - `node.invoke` пересилає команду підключеному Node.
    - `node.invoke.result` повертає результат запиту на виклик.
    - `mcp.tools.call.v1` — це команда вузлового хоста без графічного інтерфейсу для виклику налаштованого локального для Node інструмента MCP. Вона передається через `node.invoke`, вимагає, щоб Node оголосив команду, і надалі потребує схвалення сполучення та `gateway.nodes.denyCommands`.
    - `node.event` передає події, що походять від Node, назад до Gateway.
    - `node.pluginTools.update` — єдиний шлях публікації для заміни видимих агенту дескрипторів Plugin/інструментів MCP підключеного Node; параметри `connect` їх не містять.
    - `node.pending.pull` і `node.pending.ack` — API черги підключеного Node.
    - `node.pending.enqueue` і `node.pending.drain` керують довготривалою роботою в очікуванні для автономних/відключених Node.

  </Accordion>

  <Accordion title="Групи схвалень">
    - `approval.get` і `approval.resolve` — незалежні від типу методи довготривалого схвалення (область дії `operator.approvals`). `approval.get` повертає очищене подання очікуваного або збереженого кінцевого стану зі стабільним `urlPath`; `approval.resolve` приймає канонічний ідентифікатор схвалення, явний `kind` і рішення, застосовує правило «перша відповідь перемагає» та завжди повертає записаний канонічний результат.
    - `exec.approval.request`, `exec.approval.get`, `exec.approval.list` і `exec.approval.resolve` охоплюють одноразові запити на схвалення виконання, а також пошук/повторне відтворення схвалень в очікуванні. Це адаптери межі протоколу над тим самим довготривалим реєстром схвалень.
    - `exec.approval.waitDecision` очікує на одне схвалення виконання в очікуванні та повертає остаточне рішення (або `null` після завершення часу очікування).
    - `exec.approvals.get` і `exec.approvals.set` керують знімками політики схвалення виконання Gateway.
    - `exec.approvals.node.get` і `exec.approvals.node.set` керують локальною для Node політикою схвалення виконання за допомогою команд ретрансляції Node.
    - `plugin.approval.request`, `plugin.approval.list`, `plugin.approval.waitDecision` і `plugin.approval.resolve` охоплюють визначені Plugin процеси схвалення.

  </Accordion>

  <Accordion title="Автоматизація, Skills та інструменти">
    - Автоматизація: `wake` планує негайне або під час наступного Heartbeat введення тексту пробудження; `cron.get`, `cron.list`, `cron.status`, `cron.add`, `cron.update`, `cron.remove`, `cron.run`, `cron.runs` керують запланованою роботою.
    - `cron.run` залишається RPC у стилі додавання до черги для ручних запусків. Клієнтам, яким потрібна семантика завершення, слід прочитати повернений `runId` і опитувати `cron.runs`.
    - `cron.runs` приймає необов’язковий непорожній фільтр `runId`, щоб клієнти могли відстежувати один поставлений у чергу ручний запуск без конфлікту з іншими записами історії для того самого завдання.
    - Skills та інструменти: `commands.list`, `skills.*`, `tools.catalog`, `tools.effective`, `tools.invoke`. Див. [Допоміжні методи оператора](#operator-helper-methods) нижче.

  </Accordion>
</AccordionGroup>

### Поширені групи подій

- `chat`: оновлення чату інтерфейсу, як-от `chat.inject`, та інші події чату
  лише для транскрипту. У протоколі v4 корисні навантаження дельт містять `deltaText`; `message` залишається
  накопичувальним знімком відповіді асистента. Заміни, що не є префіксними, задають
  `replace=true` і використовують `deltaText` як текст заміни.
- `session.message`, `session.operation`, `session.tool`: оновлення транскрипту, поточної
  операції сеансу та потоку подій для сеансу з підпискою.
- `session.approval`: очищені достовірні дані про очікуване та кінцеве схвалення для
  абонента точного сеансу, який явно погодився на отримання. Дочірні схвалення використовують
  збережену аудиторію предка; події ніколи не змінюють транскрипти й не пробуджують агентів.
- `sessions.changed`: індекс або метадані сеансу змінено.
- `presence`: оновлення знімка присутності системи.
- `tick`: періодична подія підтримання з’єднання/працездатності.
- `health`: оновлення знімка стану Gateway.
- `heartbeat`: оновлення потоку подій Heartbeat.
- `cron`: подія зміни запуску/завдання Cron.
- `shutdown`: сповіщення про завершення роботи Gateway.
- `node.pair.requested` / `node.pair.resolved`: життєвий цикл сполучення Node.
- `node.invoke.request`: широкомовна передача запиту на виклик Node.
- `device.pair.requested` / `device.pair.resolved`: життєвий цикл сполученого пристрою.
- `voicewake.changed`: конфігурацію тригера слова пробудження змінено.
- `exec.approval.requested` / `exec.approval.resolved`: життєвий цикл
  схвалення виконання.
- `plugin.approval.requested` / `plugin.approval.resolved`: життєвий цикл
  схвалення Plugin.

### Допоміжні методи Node

Node можуть викликати `skills.bins`, щоб отримати поточний список виконуваних файлів Skills
для перевірок автоматичного дозволу.

## RPC журналу аудиту

`audit.activity.list` надає клієнтам оператора стабільне впорядковане від найновіших подання метаданих життєвого циклу
запусків агентів, дій інструментів і повідомлень, для яких явно ввімкнено збирання. Він вимагає
`operator.read`. Запити виключають записи, старші за 30 днів, а спільний
журнал SQLite обмежено 100,000 записами. Прострочені рядки видаляються під час
запуску Gateway, щогодинного обслуговування та наступних операцій запису. Модель даних і семантику конфіденційності див. у розділі
[Історія аудиту](/gateway/audit).

- Параметри: необов’язкові точні `agentId`, `sessionKey` або `runId`; необов’язковий `kind`
  (`"agent_run"`, `"tool_action"` або `"message"`); необов’язковий `status`
  (`"started"`, `"succeeded"`, `"failed"`, `"cancelled"`, `"timed_out"`,
  `"blocked"` або `"unknown"`); необов’язковий `direction` повідомлення (`"inbound"` або
  `"outbound"`) і точний `channel`; необов’язкові включні межі `after` / `before`
  у мілісекундах Unix; необов’язковий `limit` від `1` до `500`; і необов’язковий
  рядок `cursor` з попередньої сторінки.
- Результат: `{ "events": AuditActivityEventV1[], "nextCursor"?: string }`.

Іменоване об’єднання результатів V1 має окремі схеми запуску агента, дії інструмента, вхідного повідомлення
та вихідного повідомлення. Дискримінатор `eventType` відповідно має значення
`agent_run`, `tool_action`, `inbound_message` або `outbound_message`; `kind` і
`direction` повідомлення залишаються доступними для фільтрування та відображення. Кожна подія має
цілочисельний `schemaVersion: 1`. Посилання на ідентичність повідомлення використовують точний
формат `hmac-sha256:v1:<32 hex key id>:<64 hex digest>`; ідентифікатор суб’єкта-відправника каналу
використовує той самий формат.

Усі варіанти вимагають `eventType`, `schemaVersion`, `eventId`, `sequence`,
`sourceSequence`, `occurredAt`, `kind`, `action`, `status`, `actor` і
`redaction`. Поля варіантів:

| `eventType`        | Обов’язкові поля                                                   | Необов’язкові поля                                                                                                                 |
| ------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `agent_run`        | `agentId`, `runId`; `kind: "agent_run"`                           | `sessionKey`, `sessionId`, `errorCode`                                                                                          |
| `tool_action`      | `agentId`, `runId`; `kind: "tool_action"`                         | `sessionKey`, `sessionId`, `toolCallId`, `toolName`, `errorCode`                                                                |
| `inbound_message`  | `direction: "inbound"`, `channel`, `conversationKind`, `outcome`  | `agentId`, `runId`, `durationMs`, `resultCount`, посилання на ідентичність, `reasonCode`, `errorCode`                                 |
| `outbound_message` | `direction: "outbound"`, `channel`, `conversationKind`, `outcome` | `agentId`, `runId`, `durationMs`, `resultCount`, посилання на ідентичність, `reasonCode`, `deliveryKind`, `failureStage`, `errorCode` |

Закриті переліки повідомлень:

- `conversationKind`: `direct`, `group`, `channel` або `unknown`.
- Вхідний `outcome`: `completed`, `skipped` або `failed`; необов’язковий
  `reasonCode`: `duplicate`, `reply_operation_active`,
  `reply_operation_aborted`, `fast_abort`, `plugin_bound_handled`,
  `plugin_bound_unavailable`, `plugin_bound_declined`, `plugin_bound_error`,
  `before_dispatch_handled`, `acp_dispatch_completed`, `acp_dispatch_failed`,
  `acp_dispatch_empty` або `acp_dispatch_aborted`.
- Вихідний `outcome`: `sent`, `suppressed`, `failed` або `unknown`; необов’язковий
  `reasonCode`: `cancelled_by_message_sending_hook`,
  `cancelled_by_reply_payload_sending_hook`,
  `empty_after_message_sending_hook`, `empty_after_reply_payload_sending_hook`
  або `no_visible_payload`. Адаптер, який не повертає ідентичність платформи, має значення
  `unknown`, оскільки зовнішній побічний ефект неможливо спростувати.
- `deliveryKind`: `text`, `media` або `other`; `failureStage`:
  `platform_send`, `queue` або `unknown`.

Кінцеві поля взаємопов’язані, а не незалежно необов’язкові:

| Варіант          | Відображення кінцевого стану                                                                                                                                                   |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Запуск агента        | `started` не має `errorCode`; кожен завершений стан, відмінний від успішного, вимагає відповідного коду `run_*`.                                                                 |
| Дія інструмента      | `started` і успішний стан не мають `errorCode`; кожен інший завершений стан вимагає відповідного коду `tool_*`.                                                       |
| Вхідне повідомлення  | успішно = `completed`; заблоковано = `skipped`; помилка = `failed` плюс `message_processing_failed`. `reasonCode`, якщо наявний, має належати до цієї групи кінцевих станів. |
| Вихідне повідомлення | успішно = `sent`; заблоковано = `suppressed` плюс `reasonCode`; помилка = `failed` плюс `errorCode` і `failureStage`; невідомо = `unknown` плюс `failureStage`.      |

Кожна подія активності містить стабільний ідентифікатор події, монотонну послідовність журналу,
послідовність вихідної події, позначку часу, суб’єкта, дію, стан, ціле число
`schemaVersion: 1` і `redaction: "metadata_only"`. Записи запусків та інструментів
потребують даних про походження агента й запуску та можуть містити дані про походження сеансу. Записи
повідомлень можуть містити ідентифікатори агента й запуску, але навмисно ніколи не містять
`sessionKey` або `sessionId`; тому фільтр запиту `sessionKey` застосовується
лише до рядків запусків та інструментів. Події інструментів можуть містити ідентифікатор виклику інструмента та назву інструмента.

Записи повідомлень використовують `message.inbound.processed` або
`message.outbound.finished` і додають напрямок, канал, тип розмови,
нормалізований результат, а також необов’язкові тип доставки, етап збою, тривалість,
кількість результатів, код причини та локальні для інсталяції псевдоніми
облікового запису/розмови/повідомлення/цілі на основі ключа. Ці псевдоніми допомагають
зіставленню, але не є анонімізацією: база даних стану містить їхній ключ,
тоді як експорти RPC і CLI — ні. Журнал не зберігає запити, вміст повідомлень,
аргументи інструментів, результати інструментів, вивід команд або необроблений текст помилок.
Значення `sessionKey` запусків/інструментів залишаються необробленими метаданими зіставлення та можуть містити
ідентифікатори облікових записів платформи або співрозмовників; записи повідомлень не містять ключів сеансів.

Для вхідних рядків `durationMs` вимірює час від диспетчеризації ядром до її завершення, а
`resultCount` підраховує завершені поставлені в чергу корисні навантаження інструментів, блоків і відповідей. Для
вихідних рядків `durationMs` охоплює період володіння доставкою до підтвердження,
потрапляння до черги недоставлених повідомлень або узгодження (зокрема час очікування в черзі), а `resultCount`
підраховує визначені фізичні надсилання на платформу. `deliveryKind`, якщо наявне,
описує фактичне корисне навантаження після обробників і відтворення; у пригнічених або
неоднозначних через аварійне завершення рядках воно відсутнє.

Поточне охоплення повідомлень включає прийняті вхідні повідомлення, що доходять до
диспетчеризації ядром, зокрема результати обробки дублікатів/завершення ядром. Для вихідних повідомлень
записується один завершальний рядок на кожне початкове логічне корисне навантаження відповіді, що досягає спільного надійного
механізму доставки; поділ на частини та розгалуження адаптера агрегуються в `resultCount`. Поставлені в чергу
повторювані або неоднозначні надсилання записуються лише після підтвердження, потрапляння
до черги недоставлених повідомлень або узгодження. Локальні для Plugin і прямі шляхи надсилання, які оминають ці
спільні межі, поки що не охоплено. Обмежена черга воркерів працює за принципом найкращих зусиль
і може втрачати записи в разі збою або переповнення, тому цей інтерфейс не є
повним архівом для забезпечення відповідності вимогам.

Записування ввімкнено за замовчуванням і контролюється параметром
[`audit.enabled`](/uk/gateway/configuration-reference#audit). Записування повідомлень
контролюється окремо параметром `audit.messages`, значення якого за замовчуванням — `"off"`. Коли
записування вимкнено, `audit.activity.list` продовжує надавати раніше записані
записи, доки не завершиться термін їх зберігання.

Опубліковані схеми запиту й результату `audit.list`, а також схема `AuditEvent`
залишаються незмінними та повертають лише записи запусків агентів і дій інструментів. Новим операторським
клієнтам слід викликати `audit.activity.list`, коли Gateway повідомляє про його підтримку. Старіші
версії Gateway можуть повертати або `unknown method: audit.activity.list`, або, оскільки
в опублікованих версіях авторизація передувала пошуку методу, `missing scope:
operator.admin` для запиту з областю читання. Вважайте останню відповідь ознакою відсутності методу
лише тоді, коли метод не було оголошено. Після цього клієнт може повторити запит `audit.list`
лише тоді, коли його фільтри не потребують підтримки типу повідомлення, напрямку або каналу.

Використовуйте [`openclaw audit`](/uk/cli/audit) для текстових запитів і обмежених експортів JSON.

## RPC журналу завдань

Операторські клієнти переглядають і скасовують записи фонових завдань Gateway через
RPC журналу завдань (`packages/gateway-protocol/src/schema/tasks.ts`). Вони
повертають очищені зведення завдань, а не необроблений стан середовища виконання.

- `tasks.list` потребує `operator.read`.
  - Параметри: необов’язковий `status` (`"queued"`, `"running"`, `"completed"`,
    `"failed"`, `"cancelled"` або `"timed_out"`) чи масив цих станів,
    необов’язковий `agentId`, необов’язковий `sessionKey`, необов’язковий `limit` від `1` до
    `500` та необов’язковий рядок `cursor`.
  - Результат: `{ "tasks": TaskSummary[], "nextCursor"?: string }`.
- `tasks.get` потребує `operator.read`.
  - Параметри: `{ "taskId": string }`.
  - Результат: `{ "task": TaskSummary }`.
  - Для відсутніх ідентифікаторів завдань повертається структура помилки Gateway «не знайдено».
- `tasks.cancel` потребує `operator.write`.
  - Параметри: `{ "taskId": string, "reason"?: string }`.
  - Результат: `{ "found": boolean, "cancelled": boolean, "reason"?: string, "task"?: TaskSummary }`.
  - `found` повідомляє, чи містив журнал відповідне завдання. `cancelled`
    повідомляє, чи середовище виконання прийняло або зареєструвало скасування.

`TaskSummary` містить `id`, `status` і необов’язкові метадані: `kind`,
`runtime`, `title`, `agentId`, `sessionKey`, `childSessionKey`, `ownerKey`,
`runId`, `taskId`, `flowId`, `parentTaskId`, `sourceId`, позначки часу, поступ виконання,
підсумок завершення та очищений текст помилки. `agentId` визначає агента,
який виконує завдання; `sessionKey` і `ownerKey` зберігають контекст запитувача та керування.

## Допоміжні методи оператора

- `commands.list` (`operator.read`) отримує перелік команд середовища виконання для
  агента.
  - `agentId` є необов’язковим; не вказуйте його, щоб прочитати стандартний робочий простір агента.
  - `scope` визначає, на який інтерфейс спрямовано основний `name`: `text` повертає
    основний текстовий токен команди без початкового `/`; `native` і
    стандартний шлях `both` повертають нативні назви з урахуванням провайдера, коли вони доступні.
  - `textAliases` містить точні псевдоніми команд із похилою рискою, як-от `/model` і `/m`.
  - `nativeName` містить нативну назву команди з урахуванням провайдера, якщо
    така існує.
  - `provider` є необов’язковим і впливає лише на нативне іменування та доступність нативних команд
    Plugin.
  - `includeArgs=false` вилучає з відповіді серіалізовані метадані аргументів.
- `tools.catalog` (`operator.read`) отримує каталог інструментів середовища виконання для
  агента. Відповідь містить згруповані інструменти та метадані походження:
  - `source`: `core` або `plugin`
  - `pluginId`: власник Plugin, коли `source="plugin"`
  - `optional`: чи є інструмент Plugin необов’язковим
- `tools.effective` (`operator.read`) отримує фактичний перелік інструментів
  середовища виконання для сеансу.
  - `sessionKey` є обов’язковим.
  - Gateway отримує довірений контекст середовища виконання із сеансу на стороні сервера,
    замість приймання наданого викликачем контексту автентифікації або доставки.
  - Відповідь є отриманою сервером проєкцією активного переліку в межах сеансу,
    яка включає інструменти ядра, Plugin, каналу та вже виявлених серверів MCP.
  - `tools.effective` працює лише для читання MCP: він може пропустити каталог MCP активного сеансу
    через остаточну політику інструментів, але не створює середовищ виконання MCP,
    не підключає транспорти й не видає `tools/list`. Якщо відповідного активного каталогу
    немає, відповідь може містити сповіщення, як-от `mcp-not-yet-connected`,
    `mcp-not-yet-listed` або `mcp-stale-catalog`.
  - Фактичні записи інструментів використовують `source="core"`, `source="plugin"`,
    `source="channel"` або `source="mcp"`.
- `tools.invoke` (`operator.write`) викликає один доступний інструмент через той самий
  шлях політики Gateway, що й `/tools/invoke`.
  - `name` є обов’язковим. `args`, `sessionKey`, `agentId`, `confirm` і
    `idempotencyKey` є необов’язковими.
  - Якщо наявні обидва `sessionKey` і `agentId`, визначений агент сеансу
    має відповідати `agentId`.
  - Доступні лише власнику обгортки ядра, як-от `cron`, `gateway` і `nodes`, потребують
    ідентичності власника/адміністратора (`operator.admin`), хоча сам `tools.invoke`
    має значення `operator.write`.
  - Відповідь є призначеним для SDK конвертом із `ok`, `toolName`, необов’язковим
    `output` і типізованими полями `error`. Відмови через схвалення або політику повертають
    `ok:false` у корисному навантаженні, не оминаючи конвеєр політики інструментів
    Gateway.
- `skills.status` (`operator.read`) отримує видимий перелік навичок для
  агента.
  - `agentId` є необов’язковим; не вказуйте його, щоб прочитати стандартний робочий простір агента.
  - Відповідь містить відповідність вимогам, відсутні вимоги, перевірки конфігурації
    та очищені варіанти встановлення без розкриття необроблених значень секретів.
- `skills.search` і `skills.detail` (`operator.read`) повертають метадані
  виявлення ClawHub.
- `skills.upload.begin`, `skills.upload.chunk` і `skills.upload.commit`
  (`operator.admin`) готують приватний архів навички перед установленням. Це
  окремий шлях адміністративного завантаження для довірених клієнтів, а не звичайний процес установлення
  навички з ClawHub; за замовчуванням його вимкнено, якщо не ввімкнено
  `skills.install.allowUploadedArchives`.
  - `skills.upload.begin({ kind: "skill-archive", slug, sizeBytes, sha256?, force?, idempotencyKey? })`
    створює завантаження, прив’язане до цього slug і значення примусового встановлення.
  - `skills.upload.chunk({ uploadId, offset, dataBase64 })` додає байти за
    точною декодованою позицією.
  - `skills.upload.commit({ uploadId, sha256? })` перевіряє кінцевий розмір і
    SHA-256. Фіксація лише завершує завантаження; вона не встановлює навичку.
  - Завантажені архіви навичок є zip-архівами, що містять кореневий `SKILL.md`. Назва
    внутрішнього каталогу архіву ніколи не визначає ціль установлення.
- `skills.install` (`operator.admin`) має три режими:
  - Режим ClawHub: `{ source: "clawhub", slug, version?, force? }` встановлює
    каталог навички до каталогу `skills/` стандартного робочого простору агента.
  - Режим завантаження: `{ source: "upload", uploadId, slug, force?, sha256?, timeoutMs? }`
    встановлює зафіксоване завантаження до каталогу
    `skills/<slug>` стандартного робочого простору агента. Slug і значення примусового встановлення мають відповідати
    початковому запиту `skills.upload.begin`. Запит відхиляється, якщо не ввімкнено
    `skills.install.allowUploadedArchives`; цей параметр не
    впливає на встановлення з ClawHub.
  - Режим інсталятора Gateway: `{ name, installId, timeoutMs? }` запускає оголошену дію
    `metadata.openclaw.install` на хості Gateway. Старіші клієнти все ще можуть
    надсилати `dangerouslyForceUnsafeInstall`; це поле застаріле,
    приймається лише для сумісності протоколу та ігнорується. Використовуйте
    `security.installPolicy` для рішень щодо встановлення, які належать оператору.
- `skills.update` (`operator.admin`) має два режими:
  - Режим ClawHub оновлює один відстежуваний slug або всі відстежувані встановлення ClawHub у
    стандартному робочому просторі агента.
  - Режим конфігурації змінює значення `skills.entries.<skillKey>`, як-от `enabled`,
    `apiKey` і `env`.

### Подання `models.list`

`models.list` приймає необов’язковий параметр `view`
(`src/agents/model-catalog-visibility.ts`):

- Не вказано або `"default"`: якщо налаштовано `agents.defaults.models`,
  відповіддю є дозволений каталог, зокрема динамічно виявлені моделі
  для записів `provider/*`. Інакше відповіддю є повний каталог
  Gateway.
- `"configured"`: поведінка, адаптована до засобу вибору. Якщо
  налаштовано `agents.defaults.models`, він усе одно має пріоритет, зокрема для
  виявлення в межах постачальника для записів `provider/*`. Без списку
  дозволених відповідь використовує явні записи `models.providers.<provider>.models` і переходить
  до повного каталогу, лише коли немає жодного налаштованого рядка моделі.
- `"provider-config"`: сформований джерелом перелік `models.providers.*.models`,
  незалежний від списків дозволених засобу вибору. Рядки містять загальнодоступні
  можливості моделей і доступність з урахуванням маршруту, але не містять кінцевих
  точок постачальника, матеріалів автентифікації та конфігурації запитів середовища виконання.
- `"all"`: повний каталог Gateway в обхід `agents.defaults.models`.
  Використовуйте для інтерфейсів діагностики й виявлення, а не для звичайних
  засобів вибору моделі.

## Схвалення виконання

- Коли запит на виконання потребує схвалення, Gateway транслює
  `exec.approval.requested`.
- Клієнти оператора ухвалюють рішення викликом `exec.approval.resolve`
  (потрібен `operator.approvals`).
- Для `host=node` поле `exec.approval.request` має містити
  `systemRunPlan` (канонічні метадані `argv`/`cwd`/`rawCommand`/сеансу).
  Запити без `systemRunPlan` відхиляються.
- Після схвалення переспрямовані виклики `node.invoke system.run`
  повторно використовують цей канонічний `systemRunPlan` як авторитетний
  контекст команди, робочого каталогу та сеансу.
- Якщо викликач змінює `command`, `rawCommand`,
  `cwd`, `agentId` або `sessionKey` між підготовкою
  та остаточним переспрямуванням схваленого `system.run`, Gateway відхиляє
  виконання замість того, щоб довіряти зміненому корисному навантаженню.

## Резервний варіант доставки агента

- Запити `agent` можуть містити `deliver=true`,
  щоб запитати вихідну доставку.
- `bestEffortDeliver=false` (типове значення) зберігає сувору поведінку:
  нерозв’язані або доступні лише внутрішньо цілі доставки повертають
  `INVALID_REQUEST`.
- `bestEffortDeliver=true` дозволяє перейти до виконання лише в межах
  сеансу, коли не вдається визначити зовнішній маршрут доставки (наприклад, для
  внутрішніх сеансів, сеансів вебчату або неоднозначних багатоканальних конфігурацій).
- Остаточні результати `agent` можуть містити
  `result.deliveryStatus`, коли було запитано доставку, використовуючи ті самі статуси
  `sent`, `suppressed`, `partial_failed` та
  `failed`, що задокументовані для
  [`openclaw agent --json --deliver`](/uk/cli/agent#json-delivery-status).

## Керування версіями

- `PROTOCOL_VERSION`, `MIN_CLIENT_PROTOCOL_VERSION`,
  `MIN_NODE_PROTOCOL_VERSION` та `MIN_PROBE_PROTOCOL_VERSION` містяться в
  `packages/gateway-protocol/src/version.ts`.
- Клієнти надсилають `minProtocol` + `maxProtocol`.
  Клієнти оператора та інтерфейсу мають включати поточний протокол до цього
  діапазону; поточні клієнти й сервери працюють із протоколом v4.
- Автентифіковані клієнти, що мають і `role: "node"`, і
  `client.mode: "node"`, можуть використовувати протокол Node версії N-1 (наразі
  v3). Полегшені перевірки після перезапуску використовують те саме вікно N-1.
  Це вікно сумісності не змінює автентифікацію пристрою, сполучення, області
  доступу, політику команд і схвалення виконання. Можливості та команди Node,
  якими володіють плагіни, недоступні, доки Node не оновиться до поточного
  протоколу, оскільки розміщені ними поверхні не є частиною контракту N-1.
- Схеми та моделі генеруються з визначень TypeBox:
  - `pnpm protocol:gen`
  - `pnpm protocol:gen:swift`
  - `pnpm protocol:check`

### Константи клієнта

Еталонна реалізація клієнта міститься в `packages/gateway-client/src/`
(OpenClaw обгортає її тонким фасадом `src/gateway/client.ts`). Ці типові значення
стабільні в межах протоколу v4 та є очікуваною базовою конфігурацією для
сторонніх клієнтів.

| Константа                                 | Типове значення                                        | Джерело                                                                                                                   |
| ----------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `PROTOCOL_VERSION`                        | `4`                                                   | `packages/gateway-protocol/src/version.ts`                                                                                |
| `MIN_CLIENT_PROTOCOL_VERSION`             | `4`                                                   | `packages/gateway-protocol/src/version.ts`                                                                                |
| `MIN_NODE_PROTOCOL_VERSION`               | `3`                                                   | `packages/gateway-protocol/src/version.ts`                                                                                |
| `MIN_PROBE_PROTOCOL_VERSION`              | `3`                                                   | `packages/gateway-protocol/src/version.ts`                                                                                |
| Час очікування запиту (для кожного RPC)   | `30_000` мс                                          | `packages/gateway-client/src/client.ts` (`requestTimeoutMs`)                                                              |
| Час очікування попередньої автентифікації / виклику підключення | `15_000` мс | `packages/gateway-client/src/timeouts.ts` (змінна середовища `OPENCLAW_HANDSHAKE_TIMEOUT_MS` може збільшити спільний ліміт сервера й клієнта) |
| Початкова затримка повторного підключення | `1_000` мс                                           | `packages/gateway-client/src/client.ts` (`GATEWAY_RECONNECT_POLICY`)                                                      |
| Максимальна затримка повторного підключення | `30_000` мс                                         | `packages/gateway-client/src/client.ts` (`GATEWAY_RECONNECT_POLICY`)                                                      |
| Обмеження швидкого повтору після закриття через токен пристрою | `250` мс | `packages/gateway-client/src/client.ts`                                                                                   |
| Пільговий період примусової зупинки перед `terminate()` | `250` мс | `FORCE_STOP_TERMINATE_GRACE_MS`                                                                                           |
| Типовий час очікування `stopAndWait()` | `1_000` мс                                           | `STOP_AND_WAIT_TIMEOUT_MS`                                                                                                |
| Типовий інтервал тактування (до `hello-ok`) | `30_000` мс                                  | `packages/gateway-client/src/client.ts`                                                                                   |
| Закриття через час очікування такту       | код `4000`, коли тиша перевищує `tickIntervalMs * 2` | `packages/gateway-client/src/client.ts`                                                                                   |
| `MAX_PAYLOAD_BYTES`                       | `25 * 1024 * 1024` (25 МБ)                            | `src/gateway/server-constants.ts`                                                                                         |

Сервер повідомляє фактичні `policy.tickIntervalMs`, `policy.maxPayload` та
`policy.maxBufferedBytes` у `hello-ok`; клієнти мають дотримуватися цих
значень, а не типових значень до рукостискання.

Еталонний клієнт дозволяє скінченним запитам керувати власним налаштованим
кінцевим терміном, коли кожен запит в очікуванні має такий термін. Запит
`expectFinal` без скінченного `timeoutMs`, будь-який запит із
`timeoutMs: null` або поєднання скінченних і необмежених запитів залишає
сторожовий таймер тактування активним. Якщо вхідні події та відповіді не
надходять довше за поріг часу очікування такту, клієнт закриває сокет із кодом
`4000`, відхиляє кожен запит в очікуванні та повторно підключається.
Після повторного підключення він не відтворює відхилені запити.

## Автентифікація

- Автентифікація Gateway за допомогою спільного секрету використовує `connect.params.auth.token` або
  `connect.params.auth.password`, залежно від налаштованого
  `gateway.auth.mode` (`"none" | "token" | "password" | "trusted-proxy"`).
- Режими з передаванням ідентичності, як-от Tailscale Serve (`gateway.auth.allowTailscale: true`)
  або не-loopback `gateway.auth.mode: "trusted-proxy"`, проходять перевірку автентифікації
  підключення за заголовками запиту замість `connect.params.auth.*`.
- Для приватного вхідного трафіку `gateway.auth.mode: "none"` повністю пропускає автентифікацію
  підключення за допомогою спільного секрету; не надавайте доступ до цього режиму через публічний або ненадійний вхідний канал.
- Після сполучення Gateway видає токен пристрою, обмежений роллю та областями
  підключення, і повертає його в `hello-ok.auth.deviceToken`. Клієнтам слід
  зберігати його після кожного успішного підключення.
- Під час повторного підключення із цим збереженим токеном пристрою слід також повторно використовувати
  збережений набір затверджених областей для цього токена. Це зберігає вже наданий
  доступ до читання, перевірки та стану й запобігає непомітному звуженню областей
  повторних підключень до неявної області лише для адміністратора.
- Формування автентифікації підключення на боці клієнта (`selectConnectAuth` у
  `packages/gateway-client/src/client.ts`):
  - `auth.password` є незалежним і завжди передається, якщо його задано.
  - `auth.token` заповнюється в такому порядку пріоритетності: спочатку явно заданий спільний токен,
    потім явно заданий `deviceToken`, а далі збережений токен окремого пристрою (ключ:
    `deviceId` + `role`).
  - `auth.bootstrapToken` надсилається лише тоді, коли жоден із наведених вище варіантів не визначив
    `auth.token`. Спільний токен або будь-який визначений токен пристрою скасовує його надсилання.
  - Автоматичне підвищення пріоритету збереженого токена пристрою під час одноразової
    повторної спроби `AUTH_TOKEN_MISMATCH` дозволено лише для надійних кінцевих точок: loopback
    або `wss://` із закріпленим `tlsFingerprint`. Публічний `wss://` без закріплення
    не відповідає цій умові.
- Вбудована початкова ініціалізація за кодом налаштування повертає основний Node
  `hello-ok.auth.deviceToken` разом з обмеженим токеном оператора в
  `hello-ok.auth.deviceTokens` для надійної передачі на мобільний пристрій. Токен оператора
  містить `operator.talk.secrets` для читання власної конфігурації Talk, але
  не містить областей зміни сполучення та `operator.admin`.
- Поки початкова ініціалізація за кодом налаштування, що не належить до базового рівня, очікує на схвалення,
  відомості `PAIRING_REQUIRED` містять `recommendedNextStep: "wait_then_retry"`,
  `retryable: true` і `pauseReconnect: false`. Продовжуйте повторно підключатися з тим
  самим токеном початкової ініціалізації, доки запит не буде схвалено або токен не стане
  недійсним.
- Зберігайте `hello-ok.auth.deviceTokens` лише тоді, коли підключення використовувало автентифікацію
  початкової ініціалізації через надійний транспорт, як-от `wss://` або локальне сполучення через loopback.
- Якщо клієнт надає явно заданий `deviceToken` або явно заданий `scopes`, цей
  запитаний викликачем набір областей залишається визначальним; кешовані області
  використовуються повторно лише тоді, коли клієнт повторно використовує збережений токен окремого пристрою.
- Токени пристроїв можна змінювати або відкликати за допомогою `device.token.rotate` і
  `device.token.revoke` (потрібен `operator.pairing`). Для зміни або відкликання
  токена Node чи іншої неоператорської ролі також потрібен `operator.admin`.
- `device.token.rotate` повертає метадані зміни токена. Він повертає токен-носій заміни
  лише для викликів із того самого пристрою, уже автентифікованих за допомогою
  токена цього пристрою, щоб клієнти, які використовують лише токен, могли зберегти заміну перед
  повторним підключенням. У разі зміни за допомогою спільного або адміністративного доступу токен-носій не повертається.
- Видача, зміна та відкликання токенів залишаються обмеженими затвердженим набором ролей,
  записаним у даних сполучення цього пристрою; зміна токена не може розширити права або
  націлитися на роль пристрою, яку ніколи не було надано під час схвалення сполучення.
- Для сеансів із токеном сполученого пристрою керування пристроєм обмежене власним пристроєм, якщо
  викликач також не має `operator.admin`: викликачі без прав адміністратора можуть керувати лише
  токеном оператора для запису свого пристрою. Керувати токенами Node та інших
  неоператорських ролей може лише адміністратор, навіть для власного пристрою викликача.
- `device.token.rotate` і `device.token.revoke` також перевіряють набір областей цільового
  токена оператора щодо областей поточного сеансу викликача.
  Викликачі без прав адміністратора не можуть змінити або відкликати токен оператора з ширшими областями, ніж
  уже мають.
- Помилки автентифікації містять `error.details.code` і підказки щодо відновлення:
  - `error.details.canRetryWithDeviceToken` (логічне значення)
  - `error.details.recommendedNextStep`: одне з `retry_with_device_token`,
    `update_auth_configuration`, `update_auth_credentials`,
    `wait_then_retry`, `review_auth_configuration`
    (`packages/gateway-protocol/src/connect-error-details.ts`).
- Поведінка клієнта для `AUTH_TOKEN_MISMATCH`:
  - Надійні клієнти можуть виконати одну обмежену повторну спробу з кешованим токеном
    окремого пристрою.
  - Якщо ця повторна спроба завершується невдало, припиніть цикли автоматичного повторного підключення та покажіть оператору
    вказівки щодо необхідних дій.
- `AUTH_SCOPE_MISMATCH` означає, що токен пристрою розпізнано, але він не
  охоплює запитані роль або області. Не подавайте це як неправильний токен; запропонуйте
  оператору повторно виконати сполучення або схвалити вужчий чи ширший контракт областей.

## Ідентичність і сполучення пристроїв

- Nodes мають додавати стабільну ідентичність пристрою (`device.id`), отриману з
  відбитка пари ключів.
- Gateways видають токени для кожної комбінації пристрою та ролі.
- Для нових ідентифікаторів пристроїв потрібне схвалення сполучення, якщо не ввімкнено локальне
  автоматичне схвалення.
- Автоматичне схвалення сполучення орієнтоване на прямі локальні підключення через loopback.
- OpenClaw також має вузькоспеціалізований шлях самопідключення в межах бекенда або контейнера для
  надійних допоміжних процесів зі спільним секретом.
- Підключення через tailnet або LAN на тому самому хості все одно вважаються віддаленими для сполучення
  й потребують схвалення.
- Клієнти WS зазвичай додають ідентичність `device` під час `connect` (оператор +
  Node). Єдині винятки для оператора без пристрою — це явні надійні шляхи:
  - `gateway.controlUi.allowInsecureAuth=true` для сумісності з незахищеним
    HTTP лише на localhost.
  - успішна автентифікація оператора Control UI через `gateway.auth.mode: "trusted-proxy"`.
  - `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (аварійний доступ, значне
    зниження рівня безпеки).
  - RPC бекенда через прямий loopback `gateway-client` на зарезервованому внутрішньому
    допоміжному шляху.
- Відсутність ідентичності пристрою впливає на області. Коли підключення
  оператора без пристрою дозволено через явний надійний шлях, OpenClaw
  усе одно очищає самостійно оголошені області до порожнього набору, якщо цей шлях не має
  іменованого винятку для збереження областей. Методи з перевіркою областей після цього завершуються помилкою
  `missing scope`.
- `gateway.controlUi.dangerouslyDisableDeviceAuth=true` — це аварійний шлях Control UI
  зі збереженням областей. Він не надає областей довільним
  спеціалізованим бекендам або WebSocket-клієнтам у стилі CLI.
- Зарезервований допоміжний шлях бекенда через прямий loopback `gateway-client` зберігає
  області лише для внутрішніх локальних RPC площини керування; спеціалізовані ідентифікатори бекенда
  не отримують цього винятку.
- Усі підключення мають підписувати наданий сервером nonce `connect.challenge`.

### Діагностика міграції автентифікації пристрою

Для застарілих клієнтів, які досі використовують підписування до отримання challenge, `connect`
повертає коди відомостей `DEVICE_AUTH_*` у `error.details.code` зі стабільним
`error.details.reason`.

Поширені помилки міграції:

| Повідомлення                 | details.code                     | details.reason           | Значення                                           |
| --------------------------- | -------------------------------- | ------------------------ | -------------------------------------------------- |
| `device nonce required`     | `DEVICE_AUTH_NONCE_REQUIRED`     | `device-nonce-missing`   | Клієнт не надав `device.nonce` (або надіслав порожнє значення). |
| `device nonce mismatch`     | `DEVICE_AUTH_NONCE_MISMATCH`     | `device-nonce-mismatch`  | Клієнт підписав за допомогою застарілого або неправильного nonce. |
| `device signature invalid`  | `DEVICE_AUTH_SIGNATURE_INVALID`  | `device-signature`       | Корисне навантаження підпису не відповідає корисному навантаженню v2. |
| `device signature expired`  | `DEVICE_AUTH_SIGNATURE_EXPIRED`  | `device-signature-stale` | Позначка часу підпису виходить за межі дозволеного відхилення. |
| `device identity mismatch`  | `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch`     | `device.id` не відповідає відбитку відкритого ключа. |
| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key`      | Не вдалося обробити формат або канонічне подання відкритого ключа. |

Ціль міграції:

- Завжди очікуйте на `connect.challenge`.
- Підписуйте корисне навантаження v2, що містить nonce сервера.
- Надсилайте той самий nonce у `connect.params.device.nonce`.
- Бажане корисне навантаження підпису — `v3`
  (`buildDeviceAuthPayloadV3` у `packages/gateway-client/src/device-auth.ts`),
  яке прив'язує `platform` і `deviceFamily` на додаток до
  полів пристрою, клієнта, ролі, областей, токена та nonce.
- Застарілі підписи `v2` і далі приймаються для сумісності, але закріплення
  метаданих сполученого пристрою все одно визначає політику команд під час повторного підключення.

## TLS і закріплення

- TLS підтримується для підключень WS (конфігурація `gateway.tls`).
- Клієнти за бажанням можуть закріпити відбиток сертифіката Gateway через
  `gateway.remote.tlsFingerprint` або CLI `--tls-fingerprint`.

## Область

Цей протокол надає повний API Gateway: стан, канали, моделі, чат,
агент, сеанси, Nodes, схвалення тощо. Точну поверхню визначають
схеми TypeBox, повторно експортовані з `packages/gateway-protocol/src/schema.ts`.

## Пов’язані матеріали

- [Протокол мосту](/uk/gateway/bridge-protocol)
- [Посібник з експлуатації Gateway](/uk/gateway)
