chore(i18n): refresh uk translations
This commit is contained in:
parent
05786e3286
commit
877d02c5c2
@ -1,29 +1,29 @@
|
||||
---
|
||||
read_when:
|
||||
- Реалізація або оновлення WS-клієнтів Gateway
|
||||
- Реалізація або оновлення клієнтів Gateway WS
|
||||
- Налагодження невідповідностей протоколу або збоїв підключення
|
||||
- Повторна генерація схем/моделей протоколу
|
||||
summary: 'Протокол WebSocket Gateway: рукостискання, кадри, версіонування'
|
||||
- Повторне генерування схеми/моделей протоколу
|
||||
summary: 'Протокол Gateway WebSocket: рукостискання, кадри, керування версіями'
|
||||
title: Протокол Gateway
|
||||
x-i18n:
|
||||
generated_at: "2026-04-16T00:43:06Z"
|
||||
generated_at: "2026-04-17T07:50:06Z"
|
||||
model: gpt-5.4
|
||||
provider: openai
|
||||
source_hash: 683e61ebe993a2d739bc34860060b0e3eda36b5c57267a2bcc03d177ec612fb3
|
||||
source_hash: 4f0eebcfdd8c926c90b4753a6d96c59e3134ddb91740f65478f11eb75be85e41
|
||||
source_path: gateway/protocol.md
|
||||
workflow: 15
|
||||
---
|
||||
|
||||
# Протокол Gateway (WebSocket)
|
||||
|
||||
Протокол WS Gateway — це **єдина контрольна площина + транспорт вузлів** для
|
||||
OpenClaw. Усі клієнти (CLI, вебінтерфейс, застосунок macOS, вузли iOS/Android,
|
||||
Протокол Gateway WS — це **єдина площина керування + транспорт вузлів** для
|
||||
OpenClaw. Усі клієнти (CLI, веб-інтерфейс, застосунок macOS, вузли iOS/Android,
|
||||
безголові вузли) підключаються через WebSocket і оголошують свою **роль** +
|
||||
**область дії** під час рукостискання.
|
||||
**область** під час рукостискання.
|
||||
|
||||
## Транспорт
|
||||
|
||||
- WebSocket, текстові кадри з корисним навантаженням JSON.
|
||||
- WebSocket, текстові кадри з JSON-навантаженнями.
|
||||
- Перший кадр **має** бути запитом `connect`.
|
||||
|
||||
## Рукостискання (connect)
|
||||
@ -96,9 +96,23 @@ Gateway → Client:
|
||||
```
|
||||
|
||||
`server`, `features`, `snapshot` і `policy` є обов’язковими згідно зі схемою
|
||||
(`src/gateway/protocol/schema/frames.ts`). `auth` і `canvasHostUrl` є необов’язковими.
|
||||
(`src/gateway/protocol/schema/frames.ts`). `canvasHostUrl` є необов’язковим. `auth`
|
||||
повідомляє про узгоджені роль/області, коли вони доступні, а також містить `deviceToken`,
|
||||
коли gateway його видає.
|
||||
|
||||
Коли видається токен пристрою, `hello-ok` також містить:
|
||||
Коли токен пристрою не видається, `hello-ok.auth` усе одно може повідомляти про узгоджені
|
||||
дозволи:
|
||||
|
||||
```json
|
||||
{
|
||||
"auth": {
|
||||
"role": "operator",
|
||||
"scopes": ["operator.read", "operator.write"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Коли токен пристрою видається, `hello-ok` також містить:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -110,8 +124,8 @@ Gateway → Client:
|
||||
}
|
||||
```
|
||||
|
||||
Під час передавання в межах довіреного початкового завантаження `hello-ok.auth`
|
||||
також може містити додаткові обмежені записи ролей у `deviceTokens`:
|
||||
Під час передавання довіреного bootstrap `hello-ok.auth` також може містити додаткові
|
||||
обмежені записи ролей у `deviceTokens`:
|
||||
|
||||
```json
|
||||
{
|
||||
@ -130,15 +144,14 @@ Gateway → Client:
|
||||
}
|
||||
```
|
||||
|
||||
Для вбудованого потоку початкового завантаження вузла/оператора основний токен
|
||||
вузла зберігає `scopes: []`, а будь-який переданий токен оператора залишається
|
||||
обмеженим списком дозволів bootstrap-оператора (`operator.approvals`, `operator.read`,
|
||||
`operator.talk.secrets`, `operator.write`). Перевірки областей дії bootstrap
|
||||
залишаються прив’язаними до префікса ролі: записи оператора задовольняють лише
|
||||
запити оператора, а ролі, що не є оператором, усе одно потребують областей дії
|
||||
у межах префікса власної ролі.
|
||||
Для вбудованого bootstrap-потоку node/operator основний токен вузла зберігає
|
||||
`scopes: []`, а будь-який переданий токен оператора залишається обмеженим списком дозволів
|
||||
bootstrap-оператора (`operator.approvals`, `operator.read`,
|
||||
`operator.talk.secrets`, `operator.write`). Перевірки областей bootstrap і надалі
|
||||
залишаються прив’язаними до префікса ролі: записи operator задовольняють лише запити operator, а ролі,
|
||||
що не є operator, усе одно потребують областей під власним префіксом ролі.
|
||||
|
||||
### Приклад вузла
|
||||
### Приклад Node
|
||||
|
||||
```json
|
||||
{
|
||||
@ -179,18 +192,18 @@ Gateway → Client:
|
||||
- **Відповідь**: `{type:"res", id, ok, payload|error}`
|
||||
- **Подія**: `{type:"event", event, payload, seq?, stateVersion?}`
|
||||
|
||||
Методи з побічними ефектами вимагають **ключі ідемпотентності** (див. схему).
|
||||
Методи з побічними ефектами вимагають **ключів ідемпотентності** (див. схему).
|
||||
|
||||
## Ролі + області дії
|
||||
## Ролі + області
|
||||
|
||||
### Ролі
|
||||
|
||||
- `operator` = клієнт контрольної площини (CLI/UI/автоматизація).
|
||||
- `operator` = клієнт площини керування (CLI/UI/автоматизація).
|
||||
- `node` = хост можливостей (camera/screen/canvas/system.run).
|
||||
|
||||
### Області дії (operator)
|
||||
### Області (operator)
|
||||
|
||||
Поширені області дії:
|
||||
Поширені області:
|
||||
|
||||
- `operator.read`
|
||||
- `operator.write`
|
||||
@ -199,24 +212,23 @@ Gateway → Client:
|
||||
- `operator.pairing`
|
||||
- `operator.talk.secrets`
|
||||
|
||||
Для `talk.config` з `includeSecrets: true` потрібен `operator.talk.secrets`
|
||||
`talk.config` з `includeSecrets: true` вимагає `operator.talk.secrets`
|
||||
(або `operator.admin`).
|
||||
|
||||
RPC-методи Gateway, зареєстровані плагінами, можуть вимагати власну область дії
|
||||
оператора, але зарезервовані префікси основного адміністратора (`config.*`, `exec.approvals.*`, `wizard.*`,
|
||||
Методи Gateway RPC, зареєстровані Plugin, можуть запитувати власну область operator, але
|
||||
зарезервовані префікси core admin (`config.*`, `exec.approvals.*`, `wizard.*`,
|
||||
`update.*`) завжди зіставляються з `operator.admin`.
|
||||
|
||||
Область дії методу — лише перший рівень перевірки. Для деяких slash-команд,
|
||||
доступних через `chat.send`, поверх цього застосовуються суворіші перевірки на
|
||||
рівні команди. Наприклад, постійні записи `/config set` і `/config unset`
|
||||
вимагають `operator.admin`.
|
||||
Область методу — це лише перший рівень перевірки. Деякі slash-команди, викликані через
|
||||
`chat.send`, додатково застосовують суворіші перевірки на рівні команд. Наприклад, сталі
|
||||
записи `/config set` і `/config unset` вимагають `operator.admin`.
|
||||
|
||||
`node.pair.approve` також має додаткову перевірку області дії під час
|
||||
затвердження поверх базової області дії методу:
|
||||
`node.pair.approve` також має додаткову перевірку області під час схвалення поверх
|
||||
базової області методу:
|
||||
|
||||
- запити без команд: `operator.pairing`
|
||||
- запити з не-exec-командами вузла: `operator.pairing` + `operator.write`
|
||||
- запити, що включають `system.run`, `system.run.prepare` або `system.which`:
|
||||
- запити без команди: `operator.pairing`
|
||||
- запити з невиконавчими node-командами: `operator.pairing` + `operator.write`
|
||||
- запити, що містять `system.run`, `system.run.prepare` або `system.which`:
|
||||
`operator.pairing` + `operator.admin`
|
||||
|
||||
### Caps/commands/permissions (node)
|
||||
@ -224,308 +236,297 @@ RPC-методи Gateway, зареєстровані плагінами, мож
|
||||
Вузли оголошують заявлені можливості під час підключення:
|
||||
|
||||
- `caps`: високорівневі категорії можливостей.
|
||||
- `commands`: список дозволених команд для invoke.
|
||||
- `commands`: allowlist команд для invoke.
|
||||
- `permissions`: детальні перемикачі (наприклад, `screen.record`, `camera.capture`).
|
||||
|
||||
Gateway розглядає їх як **заяви** і застосовує списки дозволів на боці сервера.
|
||||
Gateway сприймає їх як **заяви** і застосовує серверні allowlist.
|
||||
|
||||
## Presence
|
||||
## Присутність
|
||||
|
||||
- `system-presence` повертає записи, ключовані ідентичністю пристрою.
|
||||
- Записи presence містять `deviceId`, `roles` і `scopes`, щоб UI могли
|
||||
показувати один рядок на пристрій, навіть якщо він підключається і як **operator**,
|
||||
і як **node**.
|
||||
- `system-presence` повертає записи, ключовані за ідентичністю пристрою.
|
||||
- Записи присутності містять `deviceId`, `roles` і `scopes`, щоб UI могли показувати один рядок на пристрій,
|
||||
навіть якщо він підключається і як **operator**, і як **node**.
|
||||
|
||||
## Поширені сімейства RPC-методів
|
||||
## Поширені сімейства методів RPC
|
||||
|
||||
Ця сторінка не є згенерованим повним дампом, але публічна WS-поверхня ширша,
|
||||
ніж наведені вище приклади рукостискання/автентифікації. Ось основні сімейства
|
||||
методів, які Gateway надає сьогодні.
|
||||
Ця сторінка не є згенерованим повним дампом, але публічна поверхня WS ширша,
|
||||
ніж наведені вище приклади рукостискання/автентифікації. Ось основні сімейства методів,
|
||||
які Gateway надає сьогодні.
|
||||
|
||||
`hello-ok.features.methods` — це консервативний список виявлення, побудований з
|
||||
`src/gateway/server-methods-list.ts` плюс експортів методів завантажених плагінів/каналів.
|
||||
Сприймайте його як механізм виявлення можливостей, а не як згенерований дамп
|
||||
кожного викликаного допоміжного методу, реалізованого в `src/gateway/server-methods/*.ts`.
|
||||
`hello-ok.features.methods` — це консервативний список виявлення, зібраний із
|
||||
`src/gateway/server-methods-list.ts` плюс експортів методів завантажених plugin/channel.
|
||||
Сприймайте його як виявлення можливостей, а не як згенерований дамп кожного доступного helper,
|
||||
реалізованого в `src/gateway/server-methods/*.ts`.
|
||||
|
||||
### Система та ідентичність
|
||||
|
||||
- `health` повертає кешований або щойно перевірений знімок стану Gateway.
|
||||
- `status` повертає зведення Gateway у стилі `/status`; чутливі поля
|
||||
включаються лише для клієнтів operator з областю дії admin.
|
||||
- `gateway.identity.get` повертає ідентичність пристрою Gateway, яка
|
||||
використовується потоками relay і pairing.
|
||||
- `system-presence` повертає поточний знімок presence для підключених
|
||||
- `health` повертає кешований або щойно перевірений знімок стану gateway.
|
||||
- `status` повертає зведення gateway у стилі `/status`; чутливі поля
|
||||
включаються лише для operator-клієнтів з admin-областю.
|
||||
- `gateway.identity.get` повертає ідентичність пристрою gateway, яка використовується в потоках relay і
|
||||
pairing.
|
||||
- `system-presence` повертає поточний знімок присутності підключених
|
||||
пристроїв operator/node.
|
||||
- `system-event` додає системну подію та може оновлювати/транслювати контекст
|
||||
presence.
|
||||
присутності.
|
||||
- `last-heartbeat` повертає останню збережену подію Heartbeat.
|
||||
- `set-heartbeats` перемикає обробку Heartbeat на Gateway.
|
||||
- `set-heartbeats` перемикає обробку Heartbeat на gateway.
|
||||
|
||||
### Моделі та використання
|
||||
|
||||
- `models.list` повертає каталог моделей, дозволених у середовищі виконання.
|
||||
- `usage.status` повертає зведення вікон використання постачальника/залишку квоти.
|
||||
- `models.list` повертає каталог моделей, дозволених у runtime.
|
||||
- `usage.status` повертає зведення вікон використання постачальників/залишкової квоти.
|
||||
- `usage.cost` повертає агреговані зведення вартості використання за діапазон дат.
|
||||
- `doctor.memory.status` повертає стан готовності векторної пам’яті / embeddings
|
||||
для активного робочого простору агента за замовчуванням.
|
||||
- `doctor.memory.status` повертає готовність векторної пам’яті / embedding для
|
||||
активного робочого простору агента за замовчуванням.
|
||||
- `sessions.usage` повертає зведення використання по сесіях.
|
||||
- `sessions.usage.timeseries` повертає часовий ряд використання для однієї сесії.
|
||||
- `sessions.usage.logs` повертає записи журналу використання для однієї сесії.
|
||||
|
||||
### Канали та допоміжні засоби входу
|
||||
### Канали та helper для входу
|
||||
|
||||
- `channels.status` повертає зведення стану вбудованих і bundled каналів/плагінів.
|
||||
- `channels.logout` виходить із конкретного каналу/облікового запису, якщо канал
|
||||
- `channels.status` повертає зведення стану вбудованих і комплектних channel/plugin.
|
||||
- `channels.logout` виконує вихід із певного каналу/облікового запису, якщо канал
|
||||
підтримує вихід.
|
||||
- `web.login.start` запускає потік входу через QR/web для поточного QR-сумісного
|
||||
постачальника вебканалу.
|
||||
- `web.login.wait` очікує завершення цього потоку входу через QR/web і в разі
|
||||
успіху запускає канал.
|
||||
- `web.login.start` запускає потік входу через QR/web для поточного QR-сумісного веб-
|
||||
постачальника каналу.
|
||||
- `web.login.wait` очікує завершення цього потоку входу через QR/web і запускає
|
||||
канал у разі успіху.
|
||||
- `push.test` надсилає тестовий APNs push до зареєстрованого вузла iOS.
|
||||
- `voicewake.get` повертає збережені тригери слів пробудження.
|
||||
- `voicewake.set` оновлює тригери слів пробудження та транслює зміну.
|
||||
- `voicewake.get` повертає збережені тригери wake-word.
|
||||
- `voicewake.set` оновлює тригери wake-word і транслює зміну.
|
||||
|
||||
### Повідомлення та журнали
|
||||
|
||||
- `send` — це прямий RPC доставки назовні для надсилання в канал/обліковий
|
||||
запис/тему поза межами виконувача чату.
|
||||
- `logs.tail` повертає хвіст налаштованого файлового журналу Gateway з
|
||||
керуванням курсором/лімітом і максимальним розміром у байтах.
|
||||
- `send` — це прямий RPC вихідної доставки для
|
||||
надсилань, адресованих channel/account/thread, поза chat runner.
|
||||
- `logs.tail` повертає tail налаштованого файлу журналу gateway з cursor/limit і
|
||||
елементами керування максимальною кількістю байтів.
|
||||
|
||||
### Talk і TTS
|
||||
|
||||
- `talk.config` повертає корисне навантаження ефективної конфігурації Talk; для
|
||||
`includeSecrets` потрібен `operator.talk.secrets` (або `operator.admin`).
|
||||
- `talk.mode` встановлює/транслює поточний стан режиму Talk для клієнтів
|
||||
WebChat/Control UI.
|
||||
- `talk.config` повертає ефективне навантаження конфігурації Talk; `includeSecrets`
|
||||
вимагає `operator.talk.secrets` (або `operator.admin`).
|
||||
- `talk.mode` встановлює/транслює поточний стан режиму Talk для клієнтів WebChat/Control UI.
|
||||
- `talk.speak` синтезує мовлення через активного постачальника мовлення Talk.
|
||||
- `tts.status` повертає стан увімкнення TTS, активного постачальника,
|
||||
резервних постачальників і стан конфігурації постачальника.
|
||||
- `tts.status` повертає стан увімкнення TTS, активного постачальника, резервних постачальників
|
||||
і стан конфігурації постачальника.
|
||||
- `tts.providers` повертає видимий інвентар постачальників TTS.
|
||||
- `tts.enable` і `tts.disable` перемикають стан налаштувань TTS.
|
||||
- `tts.setProvider` оновлює бажаного постачальника TTS.
|
||||
- `tts.convert` виконує одноразове перетворення тексту на мовлення.
|
||||
|
||||
### Секрети, конфігурація, оновлення та майстер
|
||||
### Секрети, конфігурація, оновлення та wizard
|
||||
|
||||
- `secrets.reload` повторно зіставляє активні SecretRef і замінює стан секретів
|
||||
у середовищі виконання лише за повного успіху.
|
||||
- `secrets.resolve` зіставляє призначення секретів для цільового набору
|
||||
команд/цілей.
|
||||
- `secrets.reload` повторно розв’язує активні SecretRef і змінює стан секретів runtime
|
||||
лише за повного успіху.
|
||||
- `secrets.resolve` розв’язує призначення секретів для конкретного
|
||||
набору команд/цілей.
|
||||
- `config.get` повертає поточний знімок конфігурації та хеш.
|
||||
- `config.set` записує валідоване корисне навантаження конфігурації.
|
||||
- `config.patch` об’єднує часткове оновлення конфігурації.
|
||||
- `config.apply` виконує валідацію + повну заміну корисного навантаження конфігурації.
|
||||
- `config.schema` повертає корисне навантаження живої схеми конфігурації, яке
|
||||
використовують Control UI і CLI: схема, `uiHints`, версія та метадані генерації,
|
||||
включно з метаданими схем плагінів + каналів, коли середовище виконання може
|
||||
їх завантажити. Схема містить метадані полів `title` / `description`,
|
||||
отримані з тих самих міток і довідкового тексту, що використовуються в UI,
|
||||
включно з вкладеними об’єктами, wildcard, елементами масиву та гілками
|
||||
композиції `anyOf` / `oneOf` / `allOf`, коли існує відповідна документація полів.
|
||||
- `config.schema.lookup` повертає корисне навантаження пошуку в межах шляху для
|
||||
одного шляху конфігурації: нормалізований шлях, вузол неглибокої схеми,
|
||||
відповідний hint + `hintPath` і зведення безпосередніх дочірніх елементів
|
||||
для деталізації в UI/CLI.
|
||||
- Вузли схеми lookup зберігають користувацьку документацію та поширені поля
|
||||
валідації: `title`, `description`, `type`, `enum`, `const`, `format`,
|
||||
`pattern`, числові/рядкові/масивні/об’єктні межі та булеві прапорці, як-от
|
||||
- `config.set` записує валідоване навантаження конфігурації.
|
||||
- `config.patch` зливає часткове оновлення конфігурації.
|
||||
- `config.apply` валідує та замінює повне навантаження конфігурації.
|
||||
- `config.schema` повертає payload схеми живої конфігурації, який використовують Control UI та
|
||||
інструменти CLI: схема, `uiHints`, версія та метадані генерації, включно з
|
||||
метаданими схем plugin + channel, коли runtime може їх завантажити. Схема
|
||||
містить метадані полів `title` / `description`, похідні від тих самих підписів
|
||||
і довідкового тексту, що використовуються в UI, включно з вкладеними об’єктами,
|
||||
wildcard, елементами масиву та гілками композиції `anyOf` / `oneOf` / `allOf`,
|
||||
коли існує відповідна документація поля.
|
||||
- `config.schema.lookup` повертає payload пошуку в межах одного шляху конфігурації:
|
||||
нормалізований шлях, поверхневий вузол схеми, відповідний hint + `hintPath` і
|
||||
зведення безпосередніх дочірніх елементів для деталізації в UI/CLI.
|
||||
- Вузли схеми пошуку зберігають користувацьку документацію та поширені поля валідації:
|
||||
`title`, `description`, `type`, `enum`, `const`, `format`, `pattern`,
|
||||
числові/рядкові/масивні/об’єктні межі та булеві прапори, як-от
|
||||
`additionalProperties`, `deprecated`, `readOnly`, `writeOnly`.
|
||||
- Зведення дочірніх елементів містять `key`, нормалізований `path`, `type`, `required`,
|
||||
`hasChildren`, а також відповідні `hint` / `hintPath`.
|
||||
- `update.run` запускає потік оновлення Gateway і планує перезапуск лише тоді,
|
||||
коли саме оновлення було успішним.
|
||||
- `update.run` запускає потік оновлення gateway і планує перезапуск лише тоді,
|
||||
коли саме оновлення завершилося успішно.
|
||||
- `wizard.start`, `wizard.next`, `wizard.status` і `wizard.cancel` надають
|
||||
майстер онбордингу через WS RPC.
|
||||
onboarding wizard через WS RPC.
|
||||
|
||||
### Наявні основні сімейства
|
||||
|
||||
#### Допоміжні засоби агента та робочого простору
|
||||
#### Helper агента та робочого простору
|
||||
|
||||
- `agents.list` повертає налаштовані записи агентів.
|
||||
- `agents.create`, `agents.update` і `agents.delete` керують записами агентів і
|
||||
прив’язкою робочого простору.
|
||||
підключенням робочого простору.
|
||||
- `agents.files.list`, `agents.files.get` і `agents.files.set` керують файлами
|
||||
bootstrap-робочого простору, доступними для агента.
|
||||
- `agent.identity.get` повертає ефективну ідентичність помічника для агента або
|
||||
сесії.
|
||||
- `agent.wait` очікує завершення виконання та повертає фінальний знімок, якщо він доступний.
|
||||
- `agent.wait` очікує завершення запуску й повертає термінальний знімок, коли
|
||||
він доступний.
|
||||
|
||||
#### Керування сесією
|
||||
|
||||
- `sessions.list` повертає поточний індекс сесій.
|
||||
- `sessions.subscribe` і `sessions.unsubscribe` перемикають підписки на події
|
||||
змін сесій для поточного WS-клієнта.
|
||||
зміни сесій для поточного WS-клієнта.
|
||||
- `sessions.messages.subscribe` і `sessions.messages.unsubscribe` перемикають
|
||||
підписки на події транскрипту/повідомлень для однієї сесії.
|
||||
- `sessions.preview` повертає обмежені попередні перегляди транскриптів для
|
||||
конкретних ключів сесій.
|
||||
- `sessions.resolve` зіставляє або канонізує ціль сесії.
|
||||
підписки на події transcript/message для однієї сесії.
|
||||
- `sessions.preview` повертає обмежені попередні перегляди transcript для вказаних
|
||||
ключів сесій.
|
||||
- `sessions.resolve` розв’язує або канонізує ціль сесії.
|
||||
- `sessions.create` створює новий запис сесії.
|
||||
- `sessions.send` надсилає повідомлення до наявної сесії.
|
||||
- `sessions.steer` — це варіант переривання та спрямування для активної сесії.
|
||||
- `sessions.send` надсилає повідомлення в наявну сесію.
|
||||
- `sessions.steer` — це варіант переривання й спрямування для активної сесії.
|
||||
- `sessions.abort` перериває активну роботу для сесії.
|
||||
- `sessions.patch` оновлює метадані/перевизначення сесії.
|
||||
- `sessions.reset`, `sessions.delete` і `sessions.compact` виконують
|
||||
обслуговування сесії.
|
||||
обслуговування сесій.
|
||||
- `sessions.get` повертає повний збережений рядок сесії.
|
||||
- виконання чату, як і раніше, використовує `chat.history`, `chat.send`, `chat.abort` і
|
||||
- виконання чату й надалі використовує `chat.history`, `chat.send`, `chat.abort` і
|
||||
`chat.inject`.
|
||||
- `chat.history` нормалізується для відображення для UI-клієнтів: вбудовані теги
|
||||
директив видаляються з видимого тексту, простотекстові XML-корисні
|
||||
навантаження викликів інструментів (включно з
|
||||
- `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`, пропускаються, а надто великі рядки
|
||||
можуть бути замінені заповнювачами.
|
||||
усіченими блоками викликів інструментів) та витеклі ASCII/повноширинні токени керування моделі
|
||||
прибираються, чисті рядки помічника з безшумними токенами, як-от точне `NO_REPLY` /
|
||||
`no_reply`, пропускаються, а надто великі рядки можуть замінюватися заповнювачами.
|
||||
|
||||
#### Pairing пристроїв і токени пристроїв
|
||||
|
||||
- `device.pair.list` повертає очікувані й затверджені спарені пристрої.
|
||||
- `device.pair.list` повертає очікувальні та схвалені спарені пристрої.
|
||||
- `device.pair.approve`, `device.pair.reject` і `device.pair.remove` керують
|
||||
записами pairing пристроїв.
|
||||
- `device.token.rotate` ротує токен спареного пристрою в межах затверджених
|
||||
обмежень ролі та області дії.
|
||||
- `device.token.rotate` ротує токен спареного пристрою в межах його схваленої ролі
|
||||
та обмежень областей.
|
||||
- `device.token.revoke` відкликає токен спареного пристрою.
|
||||
|
||||
#### Pairing вузлів, invoke і відкладена робота
|
||||
|
||||
- `node.pair.request`, `node.pair.list`, `node.pair.approve`,
|
||||
`node.pair.reject` і `node.pair.verify` охоплюють pairing вузлів і bootstrap
|
||||
verification.
|
||||
`node.pair.reject` і `node.pair.verify` охоплюють pairing вузлів і bootstrap-
|
||||
перевірку.
|
||||
- `node.list` і `node.describe` повертають стан відомих/підключених вузлів.
|
||||
- `node.rename` оновлює мітку спареного вузла.
|
||||
- `node.invoke` пересилає команду підключеному вузлу.
|
||||
- `node.invoke.result` повертає результат для запиту invoke.
|
||||
- `node.event` переносить події, що походять від вузла, назад у gateway.
|
||||
- `node.canvas.capability.refresh` оновлює токени можливостей canvas з
|
||||
обмеженою областю дії.
|
||||
- `node.canvas.capability.refresh` оновлює токени можливостей canvas з обмеженою областю.
|
||||
- `node.pending.pull` і `node.pending.ack` — це API черги підключеного вузла.
|
||||
- `node.pending.enqueue` і `node.pending.drain` керують стійкою відкладеною
|
||||
роботою для офлайн-/відключених вузлів.
|
||||
- `node.pending.enqueue` і `node.pending.drain` керують стійкою відкладеною роботою
|
||||
для офлайн/відключених вузлів.
|
||||
|
||||
#### Сімейства погоджень
|
||||
#### Сімейства схвалення
|
||||
|
||||
- `exec.approval.request`, `exec.approval.get`, `exec.approval.list` і
|
||||
`exec.approval.resolve` охоплюють одноразові запити погодження exec, а також
|
||||
пошук/повторення відкладених погоджень.
|
||||
- `exec.approval.waitDecision` очікує на одне відкладене погодження exec і
|
||||
повертає остаточне рішення (або `null` у разі тайм-ауту).
|
||||
`exec.approval.resolve` охоплюють одноразові запити на схвалення exec плюс
|
||||
пошук/повторення очікувальних схвалень.
|
||||
- `exec.approval.waitDecision` очікує рішення щодо одного очікувального схвалення exec і повертає
|
||||
фінальне рішення (або `null` у разі тайм-ауту).
|
||||
- `exec.approvals.get` і `exec.approvals.set` керують знімками політики
|
||||
погоджень exec у gateway.
|
||||
- `exec.approvals.node.get` і `exec.approvals.node.set` керують локальною
|
||||
політикою погоджень exec вузла через relay-команди вузла.
|
||||
схвалення exec gateway.
|
||||
- `exec.approvals.node.get` і `exec.approvals.node.set` керують локальною для вузла exec-
|
||||
політикою схвалення через relay-команди вузла.
|
||||
- `plugin.approval.request`, `plugin.approval.list`,
|
||||
`plugin.approval.waitDecision` і `plugin.approval.resolve` охоплюють потоки
|
||||
погодження, визначені плагінами.
|
||||
`plugin.approval.waitDecision` і `plugin.approval.resolve` охоплюють
|
||||
потоки схвалення, визначені Plugin.
|
||||
|
||||
#### Інші основні сімейства
|
||||
|
||||
- automation:
|
||||
- `wake` планує негайне або на наступний Heartbeat введення тексту пробудження
|
||||
- `wake` планує негайне або наступне введення тексту пробудження Heartbeat
|
||||
- `cron.list`, `cron.status`, `cron.add`, `cron.update`, `cron.remove`,
|
||||
`cron.run`, `cron.runs`
|
||||
- skills/tools: `commands.list`, `skills.*`, `tools.catalog`, `tools.effective`
|
||||
|
||||
### Поширені сімейства подій
|
||||
|
||||
- `chat`: оновлення UI-чату, як-от `chat.inject` та інші події чату лише для
|
||||
транскрипту.
|
||||
- `session.message` і `session.tool`: оновлення транскрипту/потоку подій для
|
||||
- `chat`: оновлення чату UI, такі як `chat.inject` та інші
|
||||
події чату лише для transcript.
|
||||
- `session.message` і `session.tool`: оновлення transcript/event-stream для
|
||||
сесії, на яку оформлено підписку.
|
||||
- `sessions.changed`: змінився індекс сесій або метадані.
|
||||
- `presence`: оновлення знімка system presence.
|
||||
- `sessions.changed`: індекс сесій або метадані змінилися.
|
||||
- `presence`: оновлення знімка системної присутності.
|
||||
- `tick`: періодична подія keepalive / liveness.
|
||||
- `health`: оновлення знімка стану Gateway.
|
||||
- `health`: оновлення знімка стану gateway.
|
||||
- `heartbeat`: оновлення потоку подій Heartbeat.
|
||||
- `cron`: подія зміни запуску/завдання Cron.
|
||||
- `shutdown`: сповіщення про вимкнення Gateway.
|
||||
- `cron`: подія зміни запуску/завдання cron.
|
||||
- `shutdown`: сповіщення про вимкнення gateway.
|
||||
- `node.pair.requested` / `node.pair.resolved`: життєвий цикл pairing вузла.
|
||||
- `node.invoke.request`: трансляція запиту invoke вузла.
|
||||
- `device.pair.requested` / `device.pair.resolved`: життєвий цикл спареного пристрою.
|
||||
- `voicewake.changed`: змінено конфігурацію тригерів слів пробудження.
|
||||
- `voicewake.changed`: змінено конфігурацію тригерів wake-word.
|
||||
- `exec.approval.requested` / `exec.approval.resolved`: життєвий цикл
|
||||
погодження exec.
|
||||
- `plugin.approval.requested` / `plugin.approval.resolved`: життєвий цикл
|
||||
погодження плагіна.
|
||||
схвалення exec.
|
||||
- `plugin.approval.requested` / `plugin.approval.resolved`: життєвий цикл схвалення
|
||||
Plugin.
|
||||
|
||||
### Допоміжні методи вузла
|
||||
### Helper-методи вузла
|
||||
|
||||
- Вузли можуть викликати `skills.bins`, щоб отримати поточний список
|
||||
виконуваних файлів навичок для перевірок автодозволу.
|
||||
- Вузли можуть викликати `skills.bins`, щоб отримати поточний список виконуваних файлів skill
|
||||
для перевірок auto-allow.
|
||||
|
||||
### Допоміжні методи оператора
|
||||
### Helper-методи operator
|
||||
|
||||
- Оператори можуть викликати `commands.list` (`operator.read`), щоб отримати
|
||||
інвентар команд часу виконання для агента.
|
||||
- `agentId` є необов’язковим; не вказуйте його, щоб читати робочий простір
|
||||
агента за замовчуванням.
|
||||
- Operator можуть викликати `commands.list` (`operator.read`), щоб отримати
|
||||
інвентар команд runtime для агента.
|
||||
- `agentId` є необов’язковим; опустіть його, щоб читати робочий простір агента за замовчуванням.
|
||||
- `scope` керує тим, яку поверхню використовує основний `name`:
|
||||
- `text` повертає основний текстовий токен команди без початкового `/`
|
||||
- `native` і типовий шлях `both` повертають нативні імена з урахуванням
|
||||
постачальника, коли вони доступні
|
||||
- `textAliases` містить точні slash-аліаси, як-от `/model` і `/m`.
|
||||
- `nativeName` містить нативну назву команди з урахуванням постачальника,
|
||||
коли така існує.
|
||||
- `provider` є необов’язковим і впливає лише на нативне найменування та
|
||||
доступність нативних команд плагіна.
|
||||
- `includeArgs=false` не включає серіалізовані метадані аргументів із відповіді.
|
||||
- Оператори можуть викликати `tools.catalog` (`operator.read`), щоб отримати каталог інструментів
|
||||
часу виконання для агента. Відповідь містить згруповані інструменти та метадані походження:
|
||||
- `native` і типовий шлях `both` повертають обізнані про постачальника native-імена,
|
||||
коли вони доступні
|
||||
- `textAliases` містить точні slash-аліаси, такі як `/model` і `/m`.
|
||||
- `nativeName` містить обізнане про постачальника native-ім’я команди, якщо воно існує.
|
||||
- `provider` є необов’язковим і впливає лише на native-іменування та доступність native-команд
|
||||
Plugin.
|
||||
- `includeArgs=false` пропускає серіалізовані метадані аргументів із відповіді.
|
||||
- Operator можуть викликати `tools.catalog` (`operator.read`), щоб отримати каталог інструментів runtime для
|
||||
агента. Відповідь містить згруповані інструменти та метадані походження:
|
||||
- `source`: `core` або `plugin`
|
||||
- `pluginId`: власник плагіна, коли `source="plugin"`
|
||||
- `optional`: чи є інструмент плагіна необов’язковим
|
||||
- Оператори можуть викликати `tools.effective` (`operator.read`), щоб отримати ефективний інвентар інструментів
|
||||
часу виконання для сесії.
|
||||
- `pluginId`: власник Plugin, коли `source="plugin"`
|
||||
- `optional`: чи є інструмент Plugin необов’язковим
|
||||
- Operator можуть викликати `tools.effective` (`operator.read`), щоб отримати ефективний у runtime
|
||||
інвентар інструментів для сесії.
|
||||
- `sessionKey` є обов’язковим.
|
||||
- Gateway виводить довірений контекст часу виконання з сесії на боці сервера
|
||||
замість того, щоб приймати наданий викликачем контекст автентифікації або доставки.
|
||||
- Відповідь прив’язана до сесії та відображає, що активна розмова може
|
||||
використовувати прямо зараз, включно з інструментами core, plugin і channel.
|
||||
- Оператори можуть викликати `skills.status` (`operator.read`), щоб отримати
|
||||
видимий інвентар Skills для агента.
|
||||
- `agentId` є необов’язковим; не вказуйте його, щоб читати робочий простір
|
||||
агента за замовчуванням.
|
||||
- Відповідь містить відповідність вимогам, відсутні вимоги, перевірки
|
||||
конфігурації та санітизовані параметри встановлення без розкриття сирих
|
||||
секретних значень.
|
||||
- Оператори можуть викликати `skills.search` і `skills.detail` (`operator.read`)
|
||||
для метаданих виявлення ClawHub.
|
||||
- Оператори можуть викликати `skills.install` (`operator.admin`) у двох режимах:
|
||||
- Gateway виводить довірений контекст runtime із сесії на сервері замість того, щоб приймати
|
||||
наданий викликачем контекст auth або доставки.
|
||||
- Відповідь прив’язана до сесії та відображає те, що активна розмова може використовувати просто зараз,
|
||||
включно з інструментами core, Plugin і channel.
|
||||
- Operator можуть викликати `skills.status` (`operator.read`), щоб отримати видимий
|
||||
інвентар Skills для агента.
|
||||
- `agentId` є необов’язковим; опустіть його, щоб читати робочий простір агента за замовчуванням.
|
||||
- Відповідь містить придатність, відсутні вимоги, перевірки конфігурації та
|
||||
санітизовані параметри встановлення без розкриття сирих значень секретів.
|
||||
- Operator можуть викликати `skills.search` і `skills.detail` (`operator.read`) для
|
||||
метаданих виявлення ClawHub.
|
||||
- Operator можуть викликати `skills.install` (`operator.admin`) у двох режимах:
|
||||
- Режим ClawHub: `{ source: "clawhub", slug, version?, force? }` встановлює
|
||||
теку навички до каталогу `skills/` робочого простору агента за замовчуванням.
|
||||
- Режим інсталятора Gateway: `{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }`
|
||||
теку skill у каталог `skills/` робочого простору агента за замовчуванням.
|
||||
- Режим встановлювача Gateway: `{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }`
|
||||
запускає оголошену дію `metadata.openclaw.install` на хості gateway.
|
||||
- Оператори можуть викликати `skills.update` (`operator.admin`) у двох режимах:
|
||||
- Режим ClawHub оновлює один відстежуваний slug або всі відстежувані
|
||||
встановлення ClawHub у робочому просторі агента за замовчуванням.
|
||||
- Режим конфігурації вносить зміни до значень `skills.entries.<skillKey>`,
|
||||
таких як `enabled`, `apiKey` і `env`.
|
||||
- Operator можуть викликати `skills.update` (`operator.admin`) у двох режимах:
|
||||
- Режим ClawHub оновлює один відстежуваний slug або всі відстежувані встановлення ClawHub у
|
||||
робочому просторі агента за замовчуванням.
|
||||
- Режим Config вносить зміни до значень `skills.entries.<skillKey>`, таких як `enabled`,
|
||||
`apiKey` і `env`.
|
||||
|
||||
## Погодження exec
|
||||
## Схвалення exec
|
||||
|
||||
- Коли запит exec потребує погодження, gateway транслює `exec.approval.requested`.
|
||||
- Клієнти operator виконують це через виклик `exec.approval.resolve` (потрібна область дії `operator.approvals`).
|
||||
- Коли запит exec потребує схвалення, gateway транслює `exec.approval.requested`.
|
||||
- Клієнти operator виконують підтвердження, викликаючи `exec.approval.resolve` (потрібна область `operator.approvals`).
|
||||
- Для `host=node` `exec.approval.request` має містити `systemRunPlan` (канонічні `argv`/`cwd`/`rawCommand`/метадані сесії). Запити без `systemRunPlan` відхиляються.
|
||||
- Після погодження переслані виклики `node.invoke system.run` повторно
|
||||
використовують цей канонічний `systemRunPlan` як авторитетний контекст
|
||||
команди/cwd/сесії.
|
||||
- Після схвалення переслані виклики `node.invoke system.run` повторно використовують цей канонічний
|
||||
`systemRunPlan` як авторитетний контекст команди/cwd/сесії.
|
||||
- Якщо викликач змінює `command`, `rawCommand`, `cwd`, `agentId` або
|
||||
`sessionKey` між prepare і остаточним пересиланням погодженого `system.run`,
|
||||
gateway відхиляє запуск замість того, щоб довіряти зміненому корисному
|
||||
навантаженню.
|
||||
`sessionKey` між підготовкою та фінальним пересиланням схваленого `system.run`,
|
||||
gateway відхиляє запуск замість того, щоб довіряти зміненому payload.
|
||||
|
||||
## Резервна доставка агента
|
||||
|
||||
- Запити `agent` можуть включати `deliver=true`, щоб запросити вихідну доставку.
|
||||
- `bestEffortDeliver=false` зберігає сувору поведінку: нерозв’язані або лише внутрішні цілі доставки повертають `INVALID_REQUEST`.
|
||||
- `bestEffortDeliver=true` дозволяє резервний перехід до виконання лише в межах сесії, якщо неможливо визначити зовнішній маршрут доставки (наприклад, для внутрішніх/webchat-сесій або неоднозначних багатоканальних конфігурацій).
|
||||
- Запити `agent` можуть містити `deliver=true`, щоб запитати вихідну доставку.
|
||||
- `bestEffortDeliver=false` зберігає строгий режим: нерозв’язані або лише внутрішні цілі доставки повертають `INVALID_REQUEST`.
|
||||
- `bestEffortDeliver=true` дозволяє резервний перехід до виконання лише в межах сесії, коли неможливо визначити зовнішній маршрут доставки (наприклад, для внутрішніх/вебчат-сесій або неоднозначних багатоканальних конфігурацій).
|
||||
|
||||
## Версіонування
|
||||
## Керування версіями
|
||||
|
||||
- `PROTOCOL_VERSION` розташовано в `src/gateway/protocol/schema/protocol-schemas.ts`.
|
||||
- `PROTOCOL_VERSION` міститься в `src/gateway/protocol/schema/protocol-schemas.ts`.
|
||||
- Клієнти надсилають `minProtocol` + `maxProtocol`; сервер відхиляє невідповідності.
|
||||
- Схеми + моделі генеруються з визначень TypeBox:
|
||||
- `pnpm protocol:gen`
|
||||
@ -534,143 +535,131 @@ Gateway розглядає їх як **заяви** і застосовує сп
|
||||
|
||||
### Константи клієнта
|
||||
|
||||
Еталонний клієнт у `src/gateway/client.ts` використовує ці типові значення. Ці
|
||||
значення стабільні в межах протоколу v3 і є очікуваною базовою лінією для
|
||||
сторонніх клієнтів.
|
||||
Еталонний клієнт у `src/gateway/client.ts` використовує ці значення за замовчуванням. Вони
|
||||
сталі в межах протоколу v3 і є очікуваною базою для сторонніх клієнтів.
|
||||
|
||||
| Константа | Типове значення | Джерело |
|
||||
| ----------------------------------------- | ----------------------------------------------------- | ---------------------------------------------------------- |
|
||||
| `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` |
|
||||
| Тайм-аут запиту (на RPC) | `30_000` ms | `src/gateway/client.ts` (`requestTimeoutMs`) |
|
||||
| Тайм-аут preauth / connect-challenge | `10_000` ms | `src/gateway/handshake-timeouts.ts` (обмеження `250`–`10_000`) |
|
||||
| Початковий backoff повторного підключення | `1_000` ms | `src/gateway/client.ts` (`backoffMs`) |
|
||||
| Максимальний backoff повторного підключення | `30_000` ms | `src/gateway/client.ts` (`scheduleReconnect`) |
|
||||
| Обмеження швидкого повтору після закриття токена пристрою | `250` ms | `src/gateway/client.ts` |
|
||||
| Пільговий період примусової зупинки перед `terminate()` | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` |
|
||||
| Типовий тайм-аут `stopAndWait()` | `1_000` ms | `STOP_AND_WAIT_TIMEOUT_MS` |
|
||||
| Типовий інтервал tick (до `hello-ok`) | `30_000` ms | `src/gateway/client.ts` |
|
||||
| Закриття через тайм-аут tick | код `4000`, коли тиша перевищує `tickIntervalMs * 2` | `src/gateway/client.ts` |
|
||||
| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 MB) | `src/gateway/server-constants.ts` |
|
||||
| Константа | Значення за замовчуванням | Джерело |
|
||||
| ----------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------- |
|
||||
| `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` |
|
||||
| Тайм-аут запиту (на RPC) | `30_000` ms | `src/gateway/client.ts` (`requestTimeoutMs`) |
|
||||
| Тайм-аут preauth / connect-challenge | `10_000` ms | `src/gateway/handshake-timeouts.ts` (clamp `250`–`10_000`) |
|
||||
| Початковий backoff повторного підключення | `1_000` ms | `src/gateway/client.ts` (`backoffMs`) |
|
||||
| Максимальний backoff повторного підключення | `30_000` ms | `src/gateway/client.ts` (`scheduleReconnect`) |
|
||||
| Обмеження швидкого повтору після закриття device-token | `250` ms | `src/gateway/client.ts` |
|
||||
| Grace-період примусової зупинки перед `terminate()` | `250` ms | `FORCE_STOP_TERMINATE_GRACE_MS` |
|
||||
| Тайм-аут за замовчуванням для `stopAndWait()` | `1_000` ms | `STOP_AND_WAIT_TIMEOUT_MS` |
|
||||
| Типовий інтервал tick (до `hello-ok`) | `30_000` ms | `src/gateway/client.ts` |
|
||||
| Закриття через тайм-аут tick | код `4000`, коли тиша перевищує `tickIntervalMs * 2` | `src/gateway/client.ts` |
|
||||
| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 MB) | `src/gateway/server-constants.ts` |
|
||||
|
||||
Сервер оголошує ефективні `policy.tickIntervalMs`, `policy.maxPayload` і
|
||||
`policy.maxBufferedBytes` у `hello-ok`; клієнти повинні дотримуватися цих значень,
|
||||
Сервер оголошує ефективні `policy.tickIntervalMs`, `policy.maxPayload`
|
||||
і `policy.maxBufferedBytes` у `hello-ok`; клієнти повинні дотримуватися цих значень,
|
||||
а не типових значень до рукостискання.
|
||||
|
||||
## Автентифікація
|
||||
|
||||
- Автентифікація Gateway через спільний секрет використовує `connect.params.auth.token` або
|
||||
`connect.params.auth.password` залежно від налаштованого режиму автентифікації.
|
||||
- Автентифікація gateway через спільний секрет використовує `connect.params.auth.token` або
|
||||
`connect.params.auth.password`, залежно від налаштованого режиму автентифікації.
|
||||
- Режими з ідентичністю, як-от Tailscale Serve
|
||||
(`gateway.auth.allowTailscale: true`) або non-loopback
|
||||
`gateway.auth.mode: "trusted-proxy"`, проходять перевірку автентифікації connect за
|
||||
заголовками запиту замість `connect.params.auth.*`.
|
||||
- `gateway.auth.mode: "none"` для приватного ingress повністю пропускає
|
||||
автентифікацію connect через спільний секрет; не відкривайте цей режим для
|
||||
публічного/ненадійного ingress.
|
||||
(`gateway.auth.allowTailscale: true`) або не-loopback
|
||||
`gateway.auth.mode: "trusted-proxy"`, проходять перевірку автентифікації connect на основі
|
||||
заголовків запиту замість `connect.params.auth.*`.
|
||||
- `gateway.auth.mode: "none"` для приватного ingress повністю пропускає автентифікацію connect через спільний секрет; не відкривайте цей режим на публічному/ненадійному ingress.
|
||||
- Після pairing Gateway видає **токен пристрою**, обмежений роллю + областями
|
||||
дії підключення. Він повертається в `hello-ok.auth.deviceToken` і має
|
||||
підключення. Він повертається в `hello-ok.auth.deviceToken` і має
|
||||
зберігатися клієнтом для майбутніх підключень.
|
||||
- Клієнти повинні зберігати основний `hello-ok.auth.deviceToken` після кожного
|
||||
- Клієнти мають зберігати основний `hello-ok.auth.deviceToken` після будь-якого
|
||||
успішного підключення.
|
||||
- Повторне підключення з цим **збереженим** токеном пристрою також має
|
||||
повторно використовувати збережений затверджений набір областей дії для цього
|
||||
токена. Це зберігає вже наданий доступ для читання/перевірок/статусу й
|
||||
запобігає непомітному звуженню повторних підключень до вужчої неявної
|
||||
області дії лише admin.
|
||||
- Формування автентифікації connect на боці клієнта (`selectConnectAuth` у
|
||||
- Під час повторного підключення з цим **збереженим** токеном пристрою також слід повторно використовувати збережений
|
||||
набір схвалених областей для цього токена. Це зберігає вже наданий доступ на
|
||||
читання/probe/status і не дає повторним підключенням непомітно звузитися до
|
||||
вужчої неявної області лише для admin.
|
||||
- Збирання автентифікації connect на боці клієнта (`selectConnectAuth` у
|
||||
`src/gateway/client.ts`):
|
||||
- `auth.password` є ортогональним і завжди пересилається, якщо заданий.
|
||||
- `auth.token` заповнюється в такому порядку пріоритету: спочатку явний
|
||||
спільний токен, потім явний `deviceToken`, потім збережений токен
|
||||
пристрою для конкретного пристрою (ключ: `deviceId` + `role`).
|
||||
- `auth.bootstrapToken` надсилається лише тоді, коли жоден із наведених вище
|
||||
варіантів не дав значення для `auth.token`. Спільний токен або будь-який
|
||||
визначений токен пристрою його пригнічує.
|
||||
- Автопідвищення збереженого токена пристрою під час одноразової повторної
|
||||
спроби `AUTH_TOKEN_MISMATCH` обмежене **лише довіреними endpoint** —
|
||||
- `auth.password` є ортогональним і завжди пересилається, якщо його встановлено.
|
||||
- `auth.token` заповнюється в такому порядку пріоритету: спочатку явний спільний токен,
|
||||
далі явний `deviceToken`, потім збережений токен для пристрою (із ключем за
|
||||
`deviceId` + `role`).
|
||||
- `auth.bootstrapToken` надсилається лише тоді, коли жоден із наведених вище варіантів не визначив
|
||||
`auth.token`. Спільний токен або будь-який визначений токен пристрою його приглушує.
|
||||
- Автоматичне підвищення збереженого токена пристрою під час одноразового
|
||||
повтору `AUTH_TOKEN_MISMATCH` дозволено лише для **довірених endpoint** —
|
||||
loopback або `wss://` із закріпленим `tlsFingerprint`. Публічний `wss://`
|
||||
без pinning не підходить.
|
||||
- Додаткові записи `hello-ok.auth.deviceTokens` — це токени передавання bootstrap.
|
||||
Зберігайте їх лише тоді, коли підключення використовувало bootstrap auth через
|
||||
довірений транспорт, наприклад `wss://` або loopback/local pairing.
|
||||
Зберігайте їх лише тоді, коли підключення використовувало bootstrap-автентифікацію на довіреному транспорті,
|
||||
такому як `wss://` або loopback/local pairing.
|
||||
- Якщо клієнт надає **явний** `deviceToken` або явні `scopes`, цей
|
||||
запитаний викликачем набір областей дії залишається авторитетним; кешовані
|
||||
області дії повторно використовуються лише тоді, коли клієнт повторно
|
||||
використовує збережений токен пристрою для конкретного пристрою.
|
||||
набір областей, запитаний викликачем, залишається авторитетним; кешовані області повторно використовуються лише тоді, коли клієнт повторно використовує збережений токен конкретного пристрою.
|
||||
- Токени пристроїв можна ротувати/відкликати через `device.token.rotate` і
|
||||
`device.token.revoke` (потрібна область дії `operator.pairing`).
|
||||
- Видача/ротація токенів залишається обмеженою затвердженим набором ролей,
|
||||
записаним у записі pairing цього пристрою; ротація токена не може розширити
|
||||
пристрій до ролі, яку pairing approval ніколи не надавав.
|
||||
- Для сесій токенів спарених пристроїв керування пристроями є самостійно
|
||||
обмеженим, якщо тільки викликач також не має `operator.admin`: викликачі без
|
||||
прав admin можуть видаляти/відкликати/ротувати лише **власний** запис пристрою.
|
||||
- `device.token.rotate` також перевіряє запитаний набір областей дії оператора
|
||||
щодо поточних областей дії сесії викликача. Викликачі без прав admin не
|
||||
можуть ротувати токен до ширшого набору областей дії оператора, ніж вони вже мають.
|
||||
- Збої автентифікації містять `error.details.code` плюс підказки для
|
||||
відновлення:
|
||||
`device.token.revoke` (потрібна область `operator.pairing`).
|
||||
- Видача/ротація токенів і надалі обмежується схваленим набором ролей, записаним у
|
||||
записі pairing цього пристрою; ротація токена не може розширити пристрій до
|
||||
ролі, яку схвалення pairing ніколи не надавало.
|
||||
- Для сесій із токеном спареного пристрою керування пристроєм прив’язане до власного контексту, якщо
|
||||
викликач також не має `operator.admin`: не-admin викликачі можуть видаляти/відкликати/ротувати
|
||||
лише **власний** запис пристрою.
|
||||
- `device.token.rotate` також перевіряє запитаний набір областей operator щодо
|
||||
поточних областей сесії викликача. Не-admin викликачі не можуть ротувати токен до
|
||||
ширшого набору областей operator, ніж вони вже мають.
|
||||
- Помилки автентифікації містять `error.details.code` плюс підказки для відновлення:
|
||||
- `error.details.canRetryWithDeviceToken` (boolean)
|
||||
- `error.details.recommendedNextStep` (`retry_with_device_token`, `update_auth_configuration`, `update_auth_credentials`, `wait_then_retry`, `review_auth_configuration`)
|
||||
- Поведінка клієнта для `AUTH_TOKEN_MISMATCH`:
|
||||
- Довірені клієнти можуть виконати одну обмежену повторну спробу з кешованим
|
||||
токеном пристрою для конкретного пристрою.
|
||||
- Якщо ця повторна спроба не вдається, клієнти повинні припинити автоматичні
|
||||
цикли повторного підключення й показати оператору вказівки щодо подальших дій.
|
||||
- Довірені клієнти можуть виконати одну обмежену повторну спробу з кешованим токеном конкретного пристрою.
|
||||
- Якщо ця повторна спроба не вдалася, клієнти мають зупинити автоматичні цикли повторного підключення й показати вказівки для дій оператора.
|
||||
|
||||
## Ідентичність пристрою + pairing
|
||||
|
||||
- Вузли повинні включати стабільну ідентичність пристрою (`device.id`),
|
||||
похідну від відбитка keypair.
|
||||
- Gateway видає токени для кожного пристрою + ролі.
|
||||
- Для нових `device.id` потрібні pairing approvals, якщо не ввімкнено локальне
|
||||
auto-approval.
|
||||
- Pairing auto-approval зосереджене на прямих локальних loopback-підключеннях.
|
||||
- OpenClaw також має вузький шлях self-connect для backend/container-local
|
||||
довірених потоків helper зі спільним секретом.
|
||||
- Підключення tailnet або LAN на тому самому хості однаково вважаються
|
||||
віддаленими для pairing і потребують approval.
|
||||
- Усі WS-клієнти мають включати ідентичність `device` під час `connect` (operator + node).
|
||||
Control UI може пропустити її лише в таких режимах:
|
||||
- `gateway.controlUi.allowInsecureAuth=true` для сумісності з небезпечним HTTP лише на localhost.
|
||||
- успішна автентифікація operator Control UI через `gateway.auth.mode: "trusted-proxy"`.
|
||||
- Вузли мають включати стабільну ідентичність пристрою (`device.id`), похідну від
|
||||
відбитка keypair.
|
||||
- Gateway видають токени для кожного поєднання пристрій + роль.
|
||||
- Для нових `device.id` потрібне схвалення pairing, якщо не увімкнено локальне автоматичне схвалення.
|
||||
- Автоматичне схвалення pairing зосереджене на прямих локальних loopback-підключеннях.
|
||||
- OpenClaw також має вузький шлях self-connect для trusted shared-secret helper flows у backend/container-local.
|
||||
- Підключення tailnet або LAN з того самого хоста все одно вважаються віддаленими для pairing і
|
||||
потребують схвалення.
|
||||
- Усі WS-клієнти мають включати ідентичність `device` під час `connect` (і operator, і node).
|
||||
Control UI може її пропускати лише в таких режимах:
|
||||
- `gateway.controlUi.allowInsecureAuth=true` для сумісності з небезпечним HTTP лише для localhost.
|
||||
- успішна автентифікація operator Control UI з `gateway.auth.mode: "trusted-proxy"`.
|
||||
- `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (аварійний режим, серйозне зниження безпеки).
|
||||
- Усі підключення мають підписувати наданий сервером nonce `connect.challenge`.
|
||||
|
||||
### Діагностика міграції автентифікації пристрою
|
||||
|
||||
Для застарілих клієнтів, які все ще використовують поведінку підписування до challenge, `connect` тепер повертає
|
||||
коди деталей `DEVICE_AUTH_*` у `error.details.code` разом зі стабільним `error.details.reason`.
|
||||
коди деталей `DEVICE_AUTH_*` у `error.details.code` зі стабільним `error.details.reason`.
|
||||
|
||||
Поширені збої міграції:
|
||||
|
||||
| Повідомлення | details.code | details.reason | Значення |
|
||||
| --------------------------- | -------------------------------- | ------------------------ | -------------------------------------------------- |
|
||||
| `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | Клієнт не вказав `device.nonce` (або надіслав порожнє значення). |
|
||||
| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | Клієнт підписався застарілим/неправильним nonce. |
|
||||
| `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | Корисне навантаження підпису не відповідає корисному навантаженню v2. |
|
||||
| `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | Підписана часова позначка виходить за межі дозволеного відхилення. |
|
||||
| `device identity mismatch` | `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch` | `device.id` не відповідає відбитку публічного ключа. |
|
||||
| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | Не вдалося виконати форматування/канонізацію публічного ключа. |
|
||||
| Повідомлення | details.code | details.reason | Значення |
|
||||
| ---------------------------- | -------------------------------- | ------------------------ | ---------------------------------------------------- |
|
||||
| `device nonce required` | `DEVICE_AUTH_NONCE_REQUIRED` | `device-nonce-missing` | Клієнт пропустив `device.nonce` (або надіслав порожнє значення). |
|
||||
| `device nonce mismatch` | `DEVICE_AUTH_NONCE_MISMATCH` | `device-nonce-mismatch` | Клієнт підписав застарілим/неправильним nonce. |
|
||||
| `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | Навантаження підпису не відповідає payload 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, яке містить server nonce.
|
||||
- Підписуйте payload v2, який включає nonce сервера.
|
||||
- Надсилайте той самий nonce у `connect.params.device.nonce`.
|
||||
- Бажаним корисним навантаженням підпису є `v3`, яке прив’язує `platform` і `deviceFamily`
|
||||
- Бажане навантаження підпису — `v3`, яке прив’язує `platform` і `deviceFamily`
|
||||
на додачу до полів device/client/role/scopes/token/nonce.
|
||||
- Застарілі підписи `v2` і далі приймаються для сумісності, але pinning
|
||||
метаданих спарених пристроїв усе одно керує політикою команд під час повторного підключення.
|
||||
- Застарілі підписи `v2` і надалі приймаються для сумісності, але pinning метаданих
|
||||
спареного пристрою все одно керує політикою команд під час повторного підключення.
|
||||
|
||||
## TLS + pinning
|
||||
|
||||
- TLS підтримується для WS-підключень.
|
||||
- Клієнти за бажання можуть закріпити відбиток сертифіката gateway (див. конфігурацію `gateway.tls`
|
||||
- Клієнти можуть за бажанням закріпити відбиток сертифіката gateway (див. конфігурацію `gateway.tls`
|
||||
плюс `gateway.remote.tlsFingerprint` або CLI `--tls-fingerprint`).
|
||||
|
||||
## Область застосування
|
||||
## Область
|
||||
|
||||
Цей протокол надає **повний API gateway** (status, channels, models, chat,
|
||||
agent, sessions, nodes, approvals тощо). Точна поверхня визначена
|
||||
agent, sessions, nodes, approvals тощо). Точна поверхня визначається
|
||||
схемами TypeBox у `src/gateway/protocol/schema.ts`.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user