---
read_when:
    - Реализация или обновление WS-клиентов Gateway
    - Отладка несоответствий протокола или сбоев подключения
    - Повторное создание схемы и моделей протокола
summary: 'Протокол WebSocket для Gateway: рукопожатие, фреймы, версионирование'
title: Протокол Gateway
x-i18n:
    generated_at: "2026-07-16T16:26:01Z"
    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 — это единая плоскость управления и транспорт Node для
OpenClaw. Клиенты оператора и Node (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` является необязательным и сопоставляет имена поверхностей плагинов (например,
`canvas`) с размещёнными URL-адресами с ограниченной областью действия; срок его действия может истечь, поэтому узлы вызывают
`node.pluginSurface.refresh` с `{ "surface": "canvas" }`, чтобы получить новую запись.
Устаревший путь `canvasHostUrl` / `canvasCapability` / `node.canvas.capability.refresh`
не поддерживается; используйте поверхности плагинов.
Необязательное поле `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-точку входа через принадлежащий Gateway
SSH-туннель с закреплённым ключом хоста. Она принимает только идентификаторы рабочих процессов и никогда не передаёт
общую аутентификацию, события узлов, RPC операторов или методы плагинов. Строгая проверка `connect`
проверяет хранимые в виде хеша краткосрочные учётные данные, привязанные к среде, хешу
пакета, эпохе владельца, версии набора RPC, сроку действия и одному допускающему значение null сеансу; она
отдельно проверяет текущую версию и набор функций. При успехе возвращается минимальный
`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 рассматривает их как заявления и применяет серверные списки разрешений.

## Роли и области действия

Полное описание модели областей действия оператора, проверок при одобрении и
семантики общих секретов см. в разделе [Области действия оператора](/ru/gateway/operator-scopes).

Роли:

- `operator`: клиент плоскости управления (CLI/UI/автоматизация).
- `node`: узел предоставления возможностей (camera/screen/canvas/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 или отредактированной строкой.

Зарегистрированные плагинами методы 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 рассматривает их как **заявленные возможности** и применяет серверные списки разрешений.
Подключённые узлы могут публиковать необязательные, видимые агенту дескрипторы плагинов или инструментов MCP
с помощью `node.pluginTools.update` после успешного подключения или
повторного подключения. Хосты узлов без графического интерфейса перезапускаются для применения декларативных изменений
инвентаря MCP. Этот метод обновления является единственным способом публикации; дескрипторы инструментов плагинов не принимаются в
параметрах `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` клиентам с областью доступа на чтение.
Поведение выбора, конфиденциальности, контекста модели и маршрутизации
уведомлений описано в разделе [Присутствие активного компьютера](/ru/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.*` по умолчанию ограничиваются `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` и экспортируемых методов загруженных
плагинов и каналов; это не сгенерированный перечень всех методов, и некоторые методы (например,
`push.test`, `web.login.start`, `web.login.wait`, `sessions.usage`)
намеренно исключены из обнаружения, хотя они существуют и доступны для вызова.
Рассматривайте его как средство обнаружения возможностей, а не как полный перечень
`src/gateway/server-methods/*.ts`.

<AccordionGroup>
  <Accordion title="Система и идентификация">
    - `health` возвращает кэшированный или заново полученный снимок состояния Gateway.
    - `diagnostics.stability` возвращает недавние ограниченные данные диагностического регистратора стабильности: имена событий, количества, размеры в байтах, показания памяти, состояние очередей и сеансов, имена каналов и плагинов, идентификаторы сеансов. Без текста чатов, тел вебхуков, результатов инструментов, необработанных тел запросов и ответов, токенов, файлов 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"` с `timeZone` стандарта IANA для учитывающих переходы на летнее время границ и интервалов календарных дней. `utcOffset` по-прежнему поддерживается для старых клиентов и используется как резервный вариант, если среда выполнения Gateway не распознаёт запрошенную зону.
    - `sessions.usage.timeseries` возвращает временной ряд использования для одного сеанса.
    - `sessions.usage.logs` возвращает записи журнала использования для одного сеанса.

  </Accordion>

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

  </Accordion>

  <Accordion title="Управление плагинами">
    - `plugins.list` (`operator.read`) возвращает список установленных плагинов, локально отобранные официальные варианты, диагностические данные и сведения о том, допускает ли текущий режим установки изменения.
    - `plugins.search` (`operator.read`) ищет доступные для установки семейства плагинов кода и пакетных плагинов 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`) изменяет политику включения одного установленного плагина с помощью `{ pluginId, enabled }`. Ответ включает обновлённую запись каталога, метаданные перезапуска и предупреждения о выборе слота.
    - `plugins.uninstall` (`operator.admin`) удаляет один внешний установленный плагин с помощью `{ pluginId }`: ссылки в конфигурации, запись установки и управляемые файлы. Поставляемые в комплекте плагины нельзя удалить, их можно только отключить. В ответе перечисляются действия по удалению, и всегда требуется перезапуск 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 МиБ, помещает его в закрытый временный каталог со сроком хранения 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, включая отсоединённые.

  </Accordion>

  <Accordion title="Разговор и TTS">
    - `talk.catalog` возвращает доступный только для чтения каталог провайдеров разговорного режима для синтеза речи, потоковой транскрипции и голосового взаимодействия в реальном времени: канонические идентификаторы провайдеров, псевдонимы реестра, метки, состояние настройки, необязательный результат `ready` уровня группы, доступные идентификаторы моделей и голосов, канонические режимы, транспорты, стратегии управляющей модели и флаги аудио и возможностей реального времени — без возврата секретов провайдера и изменения глобальной конфигурации. Текущие Gateway устанавливают `ready` после применения выбора провайдера во время выполнения; на старых Gateway отсутствие этого значения следует считать признаком непроверенного состояния.
    - `talk.config` возвращает фактическую конфигурацию разговорного режима; для `includeSecrets` требуется `operator.talk.secrets` (или `operator.admin`).
    - `talk.session.create` создаёт принадлежащий Gateway сеанс разговорного режима для `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 в принадлежащие Gateway сеансы ретрансляции в реальном времени и транскрипции.
    - `talk.session.startTurn`, `talk.session.endTurn` и `talk.session.cancelTurn` управляют жизненным циклом реплики в управляемой комнате, отклоняя устаревшие реплики до очистки состояния.
    - `talk.session.cancelOutput` останавливает вывод аудио ассистента, прежде всего для прерывания речи, управляемого VAD, в сеансах ретрансляции Gateway.
    - `talk.session.submitToolResult` завершает вызов инструмента провайдера, созданный принадлежащим Gateway сеансом ретрансляции в реальном времени. Запрос ожидает любого асинхронного сигнала завершения, предоставляемого мостом провайдера; неудачные отправки сохраняют связанный запуск активным и не генерируют событие успешного результата инструмента. Передайте `options: { willContinue: true }` для промежуточного вывода инструмента или `options: { suppressResponse: true }`, если мост провайдера объявляет поддержку подавления и результат не должен запускать ещё один ответ.
    - `talk.session.steer` передаёт голосовое управление активным запуском в принадлежащий Gateway сеанс разговорного режима на базе агента: `{ sessionId, text, mode? }`, где `mode` — это `status`, `steer`, `cancel` или `followup`; если режим не указан, он определяется по произнесённому тексту.
    - `talk.session.close` закрывает принадлежащий Gateway сеанс ретрансляции, транскрипции или управляемой комнаты и генерирует завершающие события разговорного режима.
    - `talk.mode` устанавливает и рассылает текущее состояние разговорного режима клиентам WebChat/Control UI.
    - `talk.client.create` создаёт принадлежащий клиенту сеанс провайдера реального времени с использованием `webrtc` или `provider-websocket`, при этом Gateway управляет конфигурацией, учётными данными, инструкциями и политикой инструментов.
    - `talk.client.toolCall` позволяет принадлежащим клиенту транспортам реального времени передавать вызовы инструментов провайдера политике Gateway. Первым поддерживаемым инструментом является `openclaw_agent_consult`; клиенты получают идентификатор запуска и ожидают обычных событий жизненного цикла чата, прежде чем отправить специфичный для провайдера результат инструмента.
    - `talk.client.steer` передаёт голосовое управление активным запуском для принадлежащих клиенту транспортов реального времени. Gateway определяет активный встроенный запуск по `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` из тех же меток и справочного текста, что и UI, включая ветви композиции вложенных объектов, подстановочных знаков, элементов массива и `anyOf` / `oneOf` / `allOf`, если существует соответствующая документация поля.
    - `config.schema.lookup` возвращает данные поиска с областью действия в пределах одного пути конфигурации: нормализованный путь, неглубокий узел схемы, соответствующую подсказку и `hintPath`, необязательный `reloadKind`, а также сводки непосредственных дочерних элементов для поэтапного просмотра в UI/CLI. `reloadKind` принимает одно из значений `restart`, `hot` или `none` (`src/config/schema.ts`) и отражает планировщик перезагрузки конфигурации Gateway для запрошенного пути. Узлы схемы поиска сохраняют пользовательскую документацию и общие поля проверки (`title`, `description`, `type`, `enum`, `const`, `format`, `pattern`, ограничения чисел, строк, массивов и объектов, `additionalProperties`, `deprecated`, `readOnly`, `writeOnly`). Сводки дочерних элементов содержат `key`, нормализованный `path`, `type`, `required`, `hasChildren`, необязательный `reloadKind`, а также соответствующие `hint` / `hintPath`.
    - `update.run` запускает процесс обновления Gateway и планирует перезапуск только при успешном обновлении; вызывающие стороны с сеансом могут включить `continuationMessage`, чтобы после запуска возобновить один последующий ход агента через очередь продолжения после перезапуска. Обновления через менеджер пакетов и контролируемые обновления рабочей копии Git из плоскости управления используют отсоединённую передачу управления службе вместо замены дерева пакетов или изменения рабочей копии и результатов сборки внутри работающего Gateway. Запущенная передача управления возвращает `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 не проверит перезапущенный Gateway и не запишет окончательный маркер `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`) предоставляют клиентам в доверенном домене оператора, описанном в разделе [Области доступа оператора](/ru/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` нормализуется для отображения в клиентах UI: из видимого текста удаляются встроенные теги директив, текстовые 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` возвращает краткие заголовки назначения для вызовов инструментов, отображаемых в Control UI (пакетно, не более 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`), чтобы переопределить сохранённый режим очереди только для этого запроса; явные действия перенаправления в Control UI используют `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 для вызова настроенного локального для Node инструмента MCP. Она передаётся через `node.invoke`, требует, чтобы Node объявил команду, и по-прежнему требует подтверждения сопряжения и соблюдения `gateway.nodes.denyCommands`.
    - `node.event` передаёт события, исходящие от Node, обратно в Gateway.
    - `node.pluginTools.update` — единственный путь публикации для замены доступных агенту дескрипторов плагинов и инструментов 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` охватывают определённые плагинами потоки подтверждения.

  </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`: жизненный цикл
  подтверждения плагина.

### Вспомогательные методы Node

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

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

`audit.activity.list` предоставляет клиентам оператора стабильное представление с сортировкой от новых записей к старым для метаданных
жизненного цикла запусков агента, действий инструментов и сообщений с явным согласием. Для него требуется
`operator.read`. Запросы исключают записи старше 30 дней, а общий
журнал SQLite ограничен 100,000 записями. Просроченные строки удаляются при
запуске Gateway, во время ежечасного обслуживания и при последующих операциях записи. Модель данных и семантику конфиденциальности см. в разделе
[История аудита](/ru/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`. Поставленные в очередь
повторяемые или неоднозначные отправки регистрируются только после подтверждения, помещения в очередь
недоставленных сообщений или сверки. Локальные пути плагинов и пути прямой отправки, обходящие эти
общие границы, пока не охватываются. Ограниченная очередь воркеров работает по принципу максимальных усилий
и при сбое или переполнении может терять записи, поэтому этот интерфейс не является
полным архивом для соблюдения нормативных требований без потерь.

Запись включена по умолчанию и управляется параметром
[`audit.enabled`](/ru/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`](/ru/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` является необязательным и влияет только на нативное именование и доступность нативных команд
    плагина.
  - `includeArgs=false` исключает из ответа сериализованные метаданные аргументов.
- `tools.catalog` (`operator.read`) получает каталог инструментов среды выполнения для
  агента. Ответ включает сгруппированные инструменты и метаданные происхождения:
  - `source`: `core` или `plugin`
  - `pluginId`: плагин-владелец, когда `source="plugin"`
  - `optional`: является ли инструмент плагина необязательным
- `tools.effective` (`operator.read`) получает фактический перечень инструментов среды выполнения
  для сессии.
  - `sessionKey` является обязательным.
  - Gateway получает доверенный контекст среды выполнения из сессии на стороне сервера,
    а не принимает предоставленный вызывающей стороной контекст аутентификации или доставки.
  - Ответ представляет собой ограниченную сессией, сформированную сервером проекцию активного
    перечня, включая инструменты ядра, плагинов, каналов и уже обнаруженных серверов 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? })`
    создаёт загрузку, привязанную к этому слагу и значению принудительной установки.
  - `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>` рабочего пространства агента по умолчанию. Слаг и значение принудительной установки должны соответствовать
    исходному запросу `skills.upload.begin`. Запрос отклоняется, если
    не включён `skills.install.allowUploadedArchives`; эта настройка не
    влияет на установки из ClawHub.
  - Режим установщика Gateway: `{ name, installId, timeoutMs? }` выполняет объявленное
    действие `metadata.openclaw.install` на хосте Gateway. Старые клиенты всё ещё могут
    отправлять `dangerouslyForceUnsafeInstall`; это поле устарело,
    принимается только для совместимости протокола и игнорируется. Используйте
    `security.installPolicy` для решений об установке, принадлежащих оператору.
- `skills.update` (`operator.admin`) имеет два режима:
  - Режим ClawHub обновляет один отслеживаемый слаг или все отслеживаемые установки 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` как авторитетный контекст команды, cwd и сеанса.
- Если вызывающая сторона изменяет `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`](/ru/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://` без закрепления этому условию не соответствует.
- Встроенная начальная загрузка с помощью кода настройки возвращает
  `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`). Для ротации или отзыва токена
  узла либо другой роли, не являющейся оператором, также требуется `operator.admin`.
- `device.token.rotate` возвращает метаданные ротации. Новый токен-носитель
  возвращается только для вызовов с того же устройства, уже аутентифицированных
  с помощью токена этого устройства, чтобы клиенты, использующие только токен,
  могли сохранить замену перед повторным подключением. При ротации с помощью
  общего секрета или прав администратора токен-носитель не возвращается.
- Выдача, ротация и отзыв токенов ограничены утверждённым набором ролей,
  записанным в данных сопряжения этого устройства; изменение токена не может
  расширить роль устройства или назначить ему роль, которая никогда не была
  предоставлена при утверждении сопряжения.
- Для сеансов с токенами сопряжённых устройств управление устройством
  ограничено самим устройством, если у вызывающей стороны также нет `operator.admin`:
  вызывающие стороны без прав администратора могут управлять только токеном оператора
  для записи собственного устройства. Управление токенами узла и других ролей,
  не являющихся оператором, доступно только администратору даже для собственного
  устройства вызывающей стороны.
- `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` означает, что токен устройства распознан, но не
  охватывает запрошенную роль или области доступа. Не представляйте это как неверный
  токен; предложите оператору повторно выполнить сопряжение или утвердить более узкий
  либо широкий набор областей доступа.

## Идентификатор устройства и сопряжение

- Узлам следует передавать стабильный идентификатор устройства
  (`device.id`), полученный из отпечатка пары ключей.
- Gateway выдаёт токены отдельно для каждой комбинации устройства и роли.
- Для новых идентификаторов устройств требуется утверждение сопряжения,
  если не включено автоматическое локальное утверждение.
- Автоматическое утверждение сопряжения предназначено прежде всего
  для прямых локальных loopback-подключений.
- В OpenClaw также предусмотрен узкий путь локального самоподключения
  серверной части или контейнера для доверенных вспомогательных процессов
  с общим секретом.
- Подключения с того же узла через tailnet или локальную сеть по-прежнему
  считаются удалёнными для сопряжения и требуют утверждения.
- Клиенты WS обычно передают идентификатор `device` во время
  `connect` (оператор и узел). Единственными исключениями для оператора
  без устройства являются явно заданные доверенные пути:
  - `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 плоскости управления; пользовательские идентификаторы серверной
  части не получают этого исключения.
- Все подключения должны подписывать предоставленный сервером одноразовый
  код `connect.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`  | Клиент подписал данные с устаревшим или неверным одноразовым кодом.            |
| `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, включающую одноразовый код сервера.
- Отправляйте тот же одноразовый код в `connect.params.device.nonce`.
- Предпочтительная полезная нагрузка подписи — `v3`
  (`buildDeviceAuthPayloadV3` в `packages/gateway-client/src/device-auth.ts`),
  которая наряду с полями устройства, клиента, роли, областей доступа, токена
  и одноразового кода связывает `platform` и `deviceFamily`.
- Устаревшие подписи `v2` по-прежнему принимаются
  для совместимости, но закрепление метаданных сопряжённого устройства продолжает
  определять политику команд при повторном подключении.

## TLS и закрепление

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

## Область действия

Этот протокол предоставляет полный API Gateway: состояние, каналы, модели, чат,
агент, сеансы, узлы, утверждения и многое другое. Точный интерфейс определяется
схемами TypeBox, повторно экспортируемыми из `packages/gateway-protocol/src/schema.ts`.

## Связанные материалы

- [Протокол моста](/ru/gateway/bridge-protocol)
- [Руководство по эксплуатации Gateway](/ru/gateway)
