diff --git a/docs/uk/cli/mcp.md b/docs/uk/cli/mcp.md index 8aef78d6a..7effee525 100644 --- a/docs/uk/cli/mcp.md +++ b/docs/uk/cli/mcp.md @@ -2,30 +2,30 @@ read_when: - Підключення Codex, Claude Code або іншого MCP-клієнта до каналів на базі OpenClaw - Запуск `openclaw mcp serve` - - Керування визначеннями серверів MCP, збереженими OpenClaw + - Керування визначеннями серверів MCP, збереженими в OpenClaw sidebarTitle: MCP -summary: Відкривайте доступ до розмов каналів OpenClaw через MCP та керуйте збереженими визначеннями серверів MCP +summary: Надавайте доступ до розмов у каналах OpenClaw через MCP і керуйте збереженими визначеннями серверів MCP title: MCP x-i18n: - generated_at: "2026-04-28T11:07:40Z" + generated_at: "2026-05-02T13:34:06Z" model: gpt-5.5 provider: openai - source_hash: d66ec20b81ab3894c7202ee1c1c6666bd9cdeffc8d48a280b1f298bb358887ef + source_hash: d1d3b5d7c3a9075c020a35bc9617d6e6902c96b40cc03e76119d01d0d94fd014 source_path: cli/mcp.md workflow: 16 --- -`openclaw mcp` має дві задачі: +`openclaw mcp` має два завдання: - запускати OpenClaw як MCP-сервер за допомогою `openclaw mcp serve` -- керувати визначеннями вихідних MCP-серверів, що належать OpenClaw, за допомогою `list`, `show`, `set` і `unset` +- керувати вихідними визначеннями MCP-серверів, що належать OpenClaw, за допомогою `list`, `show`, `set` і `unset` -Іншими словами: +Інакше кажучи: - `serve` — це OpenClaw, що діє як MCP-сервер - `list` / `show` / `set` / `unset` — це OpenClaw, що діє як клієнтський реєстр MCP для інших MCP-серверів, які його середовища виконання можуть споживати пізніше -Використовуйте [`openclaw acp`](/uk/cli/acp), коли OpenClaw має самостійно розміщувати сеанс середовища кодування та маршрутизувати це середовище виконання через ACP. +Використовуйте [`openclaw acp`](/uk/cli/acp), коли OpenClaw має самостійно розмістити сеанс кодового середовища й маршрутизувати це середовище виконання через ACP. ## OpenClaw як MCP-сервер @@ -36,18 +36,18 @@ x-i18n: Використовуйте `openclaw mcp serve`, коли: - Codex, Claude Code або інший MCP-клієнт має напряму взаємодіяти з розмовами каналів, підтриманими OpenClaw -- у вас уже є локальний або віддалений OpenClaw Gateway з маршрутизованими сеансами -- вам потрібен один MCP-сервер, який працює з усіма канал-бекендами OpenClaw, замість запуску окремих мостів для кожного каналу +- у вас уже є локальний або віддалений OpenClaw Gateway із маршрутизованими сеансами +- вам потрібен один MCP-сервер, що працює з різними каналовими бекендами OpenClaw, замість запуску окремих мостів для кожного каналу -Натомість використовуйте [`openclaw acp`](/uk/cli/acp), коли OpenClaw має самостійно розміщувати середовище виконання кодування та тримати сеанс агента всередині OpenClaw. +Натомість використовуйте [`openclaw acp`](/uk/cli/acp), коли OpenClaw має сам розмістити кодове середовище виконання й утримувати сеанс агента всередині OpenClaw. ### Як це працює `openclaw mcp serve` запускає stdio MCP-сервер. MCP-клієнт володіє цим процесом. Поки клієнт тримає stdio-сеанс відкритим, міст підключається до локального або віддаленого OpenClaw Gateway через WebSocket і надає маршрутизовані розмови каналів через MCP. - - MCP-клієнт запускає `openclaw mcp serve`. + + MCP-клієнт породжує `openclaw mcp serve`. Міст підключається до OpenClaw Gateway через WebSocket. @@ -58,20 +58,20 @@ x-i18n: Живі події ставляться в чергу в пам’яті, поки міст підключений. - - Якщо режим каналу Claude увімкнено, той самий сеанс також може отримувати push-сповіщення, специфічні для Claude. + + Якщо ввімкнено режим каналу Claude, той самий сеанс також може отримувати специфічні для Claude push-сповіщення. - стан живої черги починається, коли міст підключається - - старіша історія стенограми читається за допомогою `messages_read` + - старіша історія стенограми читається через `messages_read` - push-сповіщення Claude існують лише поки MCP-сеанс активний - коли клієнт відключається, міст завершує роботу, а жива черга зникає - - одноразові точки входу агента, як-от `openclaw agent` і `openclaw infer model run`, завершують усі комплектні MCP-середовища виконання, які вони відкривають, коли відповідь завершується, тому повторні скриптові запуски не накопичують дочірні stdio MCP-процеси - - stdio MCP-сервери, запущені OpenClaw (комплектні або налаштовані користувачем), завершуються як дерево процесів під час вимкнення, тому дочірні підпроцеси, запущені сервером, не залишаються після виходу батьківського stdio-клієнта - - видалення або скидання сеансу утилізує MCP-клієнти цього сеансу через спільний шлях очищення середовища виконання, тому не залишається завислих stdio-з’єднань, прив’язаних до видаленого сеансу + - одноразові точки входу агента, як-от `openclaw agent` і `openclaw infer model run`, завершують будь-які вбудовані MCP-середовища виконання, які вони відкривають, після завершення відповіді, тому повторні скриптові запуски не накопичують дочірні stdio MCP-процеси + - stdio MCP-сервери, запущені OpenClaw (вбудовані або налаштовані користувачем), під час завершення роботи зупиняються як дерево процесів, тому дочірні підпроцеси, запущені сервером, не залишаються після виходу батьківського stdio-клієнта + - видалення або скидання сеансу прибирає MCP-клієнтів цього сеансу через спільний шлях очищення середовища виконання, тому не лишається завислих stdio-з’єднань, прив’язаних до видаленого сеансу @@ -85,20 +85,20 @@ x-i18n: Лише стандартні MCP-інструменти. Використовуйте `conversations_list`, `messages_read`, `events_poll`, `events_wait`, `messages_send` та інструменти схвалення. - Стандартні MCP-інструменти плюс адаптер каналу, специфічний для Claude. Увімкніть `--claude-channel-mode on` або залиште типове значення `auto`. + Стандартні MCP-інструменти плюс специфічний для Claude адаптер каналу. Увімкніть `--claude-channel-mode on` або залиште типове значення `auto`. -Сьогодні `auto` поводиться так само, як `on`. Виявлення можливостей клієнта поки немає. +Сьогодні `auto` поводиться так само, як `on`. Виявлення можливостей клієнта ще немає. ### Що надає `serve` -Міст використовує наявні метадані маршруту сеансу Gateway, щоб надавати розмови, підтримані каналами. Розмова з’являється, коли OpenClaw уже має стан сеансу з відомим маршрутом, наприклад: +Міст використовує наявні метадані маршрутів сеансів Gateway, щоб надавати розмови, підтримані каналами. Розмова з’являється, коли OpenClaw уже має стан сеансу з відомим маршрутом, таким як: - `channel` -- метадані отримувача або призначення +- метадані одержувача або призначення - необов’язковий `accountId` - необов’язковий `threadId` @@ -138,11 +138,11 @@ x-i18n: ### Інструменти мосту -Поточний міст надає ці MCP-інструменти: +Поточний міст надає такі MCP-інструменти: - Перелічує нещодавні розмови, підтримані сеансами, які вже мають метадані маршруту в стані сеансу Gateway. + Перелічує нещодавні розмови, підтримані сеансами, які вже мають метадані маршрутів у стані сеансу Gateway. Корисні фільтри: @@ -154,7 +154,7 @@ x-i18n: - Повертає одну розмову за `session_key`. + Повертає одну розмову за `session_key` через прямий пошук сеансу Gateway. Читає нещодавні повідомлення стенограми для однієї розмови, підтриманої сеансом. @@ -163,12 +163,12 @@ x-i18n: Витягує нетекстові блоки вмісту повідомлення з одного повідомлення стенограми. Це подання метаданих поверх вмісту стенограми, а не окреме довговічне сховище blob-вкладень. - Читає поставлені в чергу живі події після числового курсора. + Читає живі події в черзі від числового курсора. - Виконує довге опитування, доки не надійде наступна відповідна подія в черзі або не мине час очікування. + Виконує long-poll, доки не надійде наступна відповідна подія в черзі або не спливе час очікування. - Використовуйте це, коли загальному MCP-клієнту потрібна доставка майже в реальному часі без push-протоколу, специфічного для Claude. + Використовуйте це, коли загальному MCP-клієнту потрібна майже реальна доставка без специфічного для Claude push-протоколу. @@ -176,8 +176,8 @@ x-i18n: Поточна поведінка: - - вимагає наявного маршруту розмови - - використовує канал сеансу, отримувача, ідентифікатор облікового запису та ідентифікатор гілки + - потребує наявного маршруту розмови + - використовує канал, одержувача, ідентифікатор облікового запису та ідентифікатор потоку сеансу - надсилає лише текст @@ -185,7 +185,7 @@ x-i18n: Перелічує очікувані запити на схвалення exec/plugin, які міст спостерігав від моменту підключення до Gateway. - Розв’язує один очікуваний запит на схвалення exec/plugin за допомогою: + Вирішує один очікуваний запит на схвалення exec/plugin за допомогою: - `allow-once` - `allow-always` @@ -196,7 +196,7 @@ x-i18n: ### Модель подій -Міст тримає чергу подій у пам’яті, поки він підключений. +Міст утримує чергу подій у пам’яті, поки він підключений. Поточні типи подій: @@ -208,21 +208,21 @@ x-i18n: - `claude_permission_request` -- черга призначена лише для живих подій; вона починається, коли MCP-міст запускається +- черга є лише живою; вона запускається, коли запускається MCP-міст - `events_poll` і `events_wait` самі не відтворюють старішу історію Gateway -- довговічний backlog слід читати за допомогою `messages_read` +- довговічний backlog слід читати через `messages_read` ### Сповіщення каналу Claude -Міст також може надавати сповіщення каналу, специфічні для Claude. Це еквівалент адаптера каналу Claude Code в OpenClaw: стандартні MCP-інструменти залишаються доступними, але живі вхідні повідомлення також можуть надходити як MCP-сповіщення, специфічні для Claude. +Міст також може надавати специфічні для Claude сповіщення каналу. Це еквівалент адаптера каналу Claude Code в OpenClaw: стандартні MCP-інструменти залишаються доступними, але живі вхідні повідомлення також можуть надходити як специфічні для Claude MCP-сповіщення. - + `--claude-channel-mode off`: лише стандартні MCP-інструменти. - + `--claude-channel-mode on`: увімкнути сповіщення каналу Claude. @@ -240,7 +240,7 @@ x-i18n: - вхідні повідомлення стенограми `user` пересилаються як `notifications/claude/channel` - запити дозволів Claude, отримані через MCP, відстежуються в пам’яті - якщо пов’язана розмова пізніше надсилає `yes abcde` або `no abcde`, міст перетворює це на `notifications/claude/channel/permission` -- ці сповіщення існують лише в живому сеансі; якщо MCP-клієнт відключається, цілі для push-доставки немає +- ці сповіщення існують лише в живому сеансі; якщо MCP-клієнт відключиться, push-цілі не буде Це навмисно специфічно для клієнта. Загальні MCP-клієнти мають покладатися на стандартні інструменти опитування. @@ -266,26 +266,26 @@ x-i18n: } ``` -Для більшості загальних MCP-клієнтів починайте зі стандартної поверхні інструментів і ігноруйте режим Claude. Увімкніть режим Claude лише для клієнтів, які справді розуміють методи сповіщень, специфічні для Claude. +Для більшості загальних MCP-клієнтів почніть зі стандартної поверхні інструментів і ігноруйте режим Claude. Увімкніть режим Claude лише для клієнтів, які справді розуміють специфічні для Claude методи сповіщень. ### Параметри `openclaw mcp serve` підтримує: - URL WebSocket для Gateway. + URL WebSocket Gateway. Токен Gateway. - Читати токен із файлу. + Зчитати токен із файлу. Пароль Gateway. - Читати пароль із файлу. + Зчитати пароль із файлу. Режим сповіщень Claude. @@ -295,7 +295,7 @@ x-i18n: -Коли можливо, надавайте перевагу `--token-file` або `--password-file` замість inline-секретів. +Коли можливо, віддавайте перевагу `--token-file` або `--password-file` замість секретів у командному рядку. ### Безпека та межа довіри @@ -304,52 +304,52 @@ x-i18n: Це означає: -- списки дозволених відправників, pairing і довіра на рівні каналу досі належать до базової конфігурації каналу OpenClaw +- списки дозволених відправників, сполучення та довіра на рівні каналу все ще належать базовій конфігурації каналу OpenClaw - `messages_send` може відповідати лише через наявний збережений маршрут -- стан схвалення є живим/у пам’яті лише для поточного сеансу мосту +- стан схвалень є живим/у пам’яті лише для поточного сеансу мосту - автентифікація мосту має використовувати ті самі засоби керування токеном або паролем Gateway, яким ви довіряли б для будь-якого іншого віддаленого клієнта Gateway -Якщо розмови немає в `conversations_list`, звичайна причина не в конфігурації MCP. Це відсутні або неповні метадані маршруту в базовому сеансі Gateway. +Якщо розмова відсутня в `conversations_list`, звичайна причина — не конфігурація MCP. Причина в тому, що в базовому сеансі Gateway відсутні або неповні метадані маршруту. ### Тестування -OpenClaw постачає детермінований Docker smoke для цього мосту: +OpenClaw постачає детермінований Docker smoke-тест для цього мосту: ```bash pnpm test:docker:mcp-channels ``` -Цей smoke: +Цей smoke-тест: -- запускає seeded Gateway-контейнер +- запускає контейнер Gateway із початковими даними - запускає другий контейнер, який породжує `openclaw mcp serve` -- перевіряє виявлення розмов, читання стенограм, читання метаданих вкладень, поведінку живої черги подій і маршрутизацію вихідного надсилання -- перевіряє сповіщення каналу та дозволів у стилі Claude через реальний stdio MCP-міст +- перевіряє виявлення розмов, читання стенограми, читання метаданих вкладень, поведінку живої черги подій і маршрутизацію вихідних надсилань +- перевіряє сповіщення каналу та дозволів у стилі Claude через справжній stdio MCP-міст -Це найшвидший спосіб довести, що міст працює, без підключення реального облікового запису Telegram, Discord або iMessage до тестового запуску. +Це найшвидший спосіб довести, що міст працює, без підключення справжнього облікового запису Telegram, Discord або iMessage до тестового запуску. -Для ширшого контексту тестування див. [Тестування](/uk/help/testing). +Ширший контекст тестування див. у [Тестування](/uk/help/testing). ### Усунення несправностей - Зазвичай означає, що сеанс Gateway ще не придатний до маршрутизації. Підтвердьте, що базовий сеанс має збережені метадані маршруту каналу/провайдера, отримувача та необов’язкового облікового запису/гілки. + Зазвичай це означає, що сеанс Gateway ще не маршрутизований. Переконайтеся, що базовий сеанс має збережені метадані маршруту каналу/провайдера, одержувача та необов’язкового облікового запису/потоку. - Очікувано. Жива черга починається, коли міст підключається. Читайте старішу історію стенограми за допомогою `messages_read`. + Очікувано. Жива черга запускається, коли міст підключається. Читайте старішу історію стенограми через `messages_read`. - Перевірте все це: + Перевірте все наведене: - клієнт тримав stdio MCP-сеанс відкритим - `--claude-channel-mode` має значення `on` або `auto` - - клієнт справді розуміє методи сповіщень, специфічні для Claude - - вхідне повідомлення надійшло після підключення мосту + - клієнт справді розуміє специфічні для Claude методи сповіщень + - вхідне повідомлення сталося після підключення мосту - `permissions_list_open` показує лише запити на схвалення, спостережені, поки міст був підключений. Це не API довговічної історії схвалень. + `permissions_list_open` показує лише запити на схвалення, які спостерігалися, поки міст був підключений. Це не API довговічної історії схвалень. @@ -357,23 +357,23 @@ pnpm test:docker:mcp-channels Це шлях `openclaw mcp list`, `show`, `set` і `unset`. -Ці команди не надають доступ до OpenClaw через MCP. Вони керують визначеннями MCP-серверів, що належать OpenClaw, у `mcp.servers` у конфігурації OpenClaw. +Ці команди не відкривають OpenClaw через MCP. Вони керують визначеннями MCP-серверів, що належать OpenClaw, у `mcp.servers` у конфігурації OpenClaw. -Ці збережені визначення призначені для середовищ виконання, які OpenClaw запускає або налаштовує пізніше, як-от вбудований Pi та інші адаптери середовища виконання. OpenClaw зберігає визначення централізовано, щоб цим середовищам виконання не доводилося підтримувати власні дублікати списків MCP-серверів. +Ці збережені визначення призначені для середовищ виконання, які OpenClaw запускає або налаштовує пізніше, як-от вбудований Pi та інші адаптери середовища виконання. OpenClaw зберігає визначення централізовано, щоб цим середовищам виконання не потрібно було підтримувати власні дублікати списків MCP-серверів. - ці команди лише читають або записують конфігурацію OpenClaw - вони не підключаються до цільового MCP-сервера - - вони не перевіряють, чи команда, URL або віддалений транспорт доступні просто зараз + - вони не перевіряють, чи команда, URL або віддалений транспорт доступні зараз - адаптери середовища виконання вирішують, які форми транспорту вони фактично підтримують під час виконання - - вбудований Pi надає налаштовані MCP-інструменти у звичайних профілях інструментів `coding` і `messaging`; `minimal` усе ще приховує їх, а `tools.deny: ["bundle-mcp"]` вимикає їх явно - - сеансові вбудовані MCP-середовища виконання прибираються після `mcp.sessionIdleTtlMs` мілісекунд простою (стандартно 10 хвилин; установіть `0`, щоб вимкнути), а одноразові вбудовані запуски очищають їх наприкінці виконання + - вбудований Pi відкриває налаштовані MCP-інструменти у звичайних профілях інструментів `coding` і `messaging`; `minimal` все ще приховує їх, а `tools.deny: ["bundle-mcp"]` явно вимикає їх + - обмежені сеансом вбудовані середовища виконання MCP прибираються після `mcp.sessionIdleTtlMs` мілісекунд простою (стандартно 10 хвилин; установіть `0`, щоб вимкнути), а одноразові вбудовані запуски очищають їх наприкінці виконання -Адаптери середовища виконання можуть нормалізувати цей спільний реєстр у форму, яку очікує їхній нижчий клієнт. Наприклад, вбудований Pi споживає значення OpenClaw `transport` напряму, тоді як Claude Code і Gemini отримують нативні для CLI значення `type`, як-от `http`, `sse` або `stdio`. +Адаптери середовища виконання можуть нормалізувати цей спільний реєстр до форми, якої очікує їхній нижчий клієнт. Наприклад, вбудований Pi напряму споживає значення OpenClaw `transport`, тоді як Claude Code і Gemini отримують нативні для CLI значення `type`, як-от `http`, `sse` або `stdio`. ### Збережені визначення MCP-серверів @@ -391,8 +391,8 @@ OpenClaw також зберігає полегшений реєстр MCP-се - `list` сортує імена серверів. - `show` без імені виводить повний налаштований об’єкт MCP-сервера. - `set` очікує одне значення JSON-об’єкта в командному рядку. -- Використовуйте `transport: "streamable-http"` для Streamable HTTP MCP-серверів. `openclaw mcp set` також нормалізує нативне для CLI `type: "http"` до тієї самої канонічної форми конфігурації для сумісності. -- `unset` завершується помилкою, якщо сервер із вказаним іменем не існує. +- Використовуйте `transport: "streamable-http"` для MCP-серверів Streamable HTTP. `openclaw mcp set` також нормалізує нативне для CLI `type: "http"` до тієї самої канонічної форми конфігурації для сумісності. +- `unset` завершується помилкою, якщо сервер із таким іменем не існує. Приклади: @@ -425,7 +425,7 @@ openclaw mcp unset context7 ### Транспорт stdio -Запускає локальний дочірній процес і обмінюється даними через stdin/stdout. +Запускає локальний дочірній процес і взаємодіє через stdin/stdout. | Поле | Опис | | -------------------------- | ----------------------------------------- | @@ -435,22 +435,22 @@ openclaw mcp unset context7 | `cwd` / `workingDirectory` | Робочий каталог для процесу | -**Фільтр безпеки stdio env** +**Фільтр безпеки env для stdio** -OpenClaw відхиляє ключі env запуску інтерпретатора, які можуть змінити те, як stdio MCP-сервер запускається до першого RPC, навіть якщо вони з’являються в блоці `env` сервера. Заблоковані ключі включають `NODE_OPTIONS`, `PYTHONSTARTUP`, `PYTHONPATH`, `PERL5OPT`, `RUBYOPT`, `SHELLOPTS`, `PS4` і подібні змінні керування середовищем виконання. Запуск відхиляє їх із помилкою конфігурації, щоб вони не могли додати неявну прелюдію, підмінити інтерпретатор або ввімкнути зневаджувач для процесу stdio. Звичайні облікові дані, проксі та специфічні для сервера змінні env (`GITHUB_TOKEN`, `HTTP_PROXY`, власні `*_API_KEY` тощо) не зачіпаються. +OpenClaw відхиляє ключі env запуску інтерпретатора, які можуть змінити те, як stdio MCP-сервер запускається до першого RPC, навіть якщо вони з’являються в блоці `env` сервера. Заблоковані ключі включають `NODE_OPTIONS`, `PYTHONSTARTUP`, `PYTHONPATH`, `PERL5OPT`, `RUBYOPT`, `SHELLOPTS`, `PS4` і подібні змінні керування середовищем виконання. Запуск відхиляє їх із помилкою конфігурації, щоб вони не могли ін’єктувати неявну преамбулу, підмінити інтерпретатор або ввімкнути налагоджувач для процесу stdio. Звичайні облікові дані, проксі та специфічні для сервера змінні env (`GITHUB_TOKEN`, `HTTP_PROXY`, власні `*_API_KEY` тощо) не зачіпаються. -Якщо вашому MCP-серверу справді потрібна одна із заблокованих змінних, установіть її в процесі хоста gateway, а не в `env` сервера stdio. +Якщо вашому MCP-серверу справді потрібна одна із заблокованих змінних, установіть її в хост-процесі gateway замість `env` stdio-сервера. ### Транспорт SSE / HTTP Підключається до віддаленого MCP-сервера через HTTP Server-Sent Events. -| Поле | Опис | -| --------------------- | -------------------------------------------------------------------- | -| `url` | HTTP або HTTPS URL віддаленого сервера (обов’язково) | -| `headers` | Необов’язкова мапа HTTP-заголовків ключ-значення (наприклад токени автентифікації) | -| `connectionTimeoutMs` | Тайм-аут підключення для окремого сервера в мс (необов’язково) | +| Поле | Опис | +| --------------------- | ----------------------------------------------------------------- | +| `url` | HTTP- або HTTPS-URL віддаленого сервера (обов’язково) | +| `headers` | Необов’язкова мапа ключ-значення HTTP-заголовків (наприклад, токени авторизації) | +| `connectionTimeoutMs` | Тайм-аут підключення для кожного сервера в мс (необов’язково) | Приклад: @@ -473,16 +473,16 @@ OpenClaw відхиляє ключі env запуску інтерпретато ### Транспорт Streamable HTTP -`streamable-http` є додатковим варіантом транспорту поряд із `sse` і `stdio`. Він використовує HTTP-стримінг для двонапрямної комунікації з віддаленими MCP-серверами. +`streamable-http` — це додатковий варіант транспорту поряд із `sse` і `stdio`. Він використовує потокове передавання HTTP для двонапрямної взаємодії з віддаленими MCP-серверами. | Поле | Опис | | --------------------- | ------------------------------------------------------------------------------------ | -| `url` | HTTP або HTTPS URL віддаленого сервера (обов’язково) | -| `transport` | Установіть `"streamable-http"`, щоб вибрати цей транспорт; якщо пропущено, OpenClaw використовує `sse` | -| `headers` | Необов’язкова мапа HTTP-заголовків ключ-значення (наприклад токени автентифікації) | -| `connectionTimeoutMs` | Тайм-аут підключення для окремого сервера в мс (необов’язково) | +| `url` | HTTP- або HTTPS-URL віддаленого сервера (обов’язково) | +| `transport` | Установіть `"streamable-http"`, щоб вибрати цей транспорт; якщо опущено, OpenClaw використовує `sse` | +| `headers` | Необов’язкова мапа ключ-значення HTTP-заголовків (наприклад, токени авторизації) | +| `connectionTimeoutMs` | Тайм-аут підключення для кожного сервера в мс (необов’язково) | -Конфігурація OpenClaw використовує `transport: "streamable-http"` як канонічне написання. Нативні для CLI MCP-значення `type: "http"` приймаються під час збереження через `openclaw mcp set` і виправляються `openclaw doctor --fix` в наявній конфігурації, але `transport` — це те, що вбудований Pi споживає напряму. +Конфігурація OpenClaw використовує `transport: "streamable-http"` як канонічне написання. Нативні для CLI значення MCP `type: "http"` приймаються під час збереження через `openclaw mcp set` і виправляються `openclaw doctor --fix` в існуючій конфігурації, але саме `transport` напряму споживає вбудований Pi. Приклад: @@ -504,12 +504,12 @@ OpenClaw відхиляє ключі env запуску інтерпретато ``` -Ці команди керують лише збереженою конфігурацією. Вони не запускають міст каналу, не відкривають живий сеанс MCP-клієнта й не доводять, що цільовий сервер доступний. +Ці команди керують лише збереженою конфігурацією. Вони не запускають міст каналу, не відкривають живий клієнтський сеанс MCP і не доводять, що цільовий сервер доступний. ## Поточні обмеження -Ця сторінка документує міст у тому вигляді, у якому його постачають сьогодні. +Ця сторінка документує міст у тому вигляді, у якому він постачається сьогодні. Поточні обмеження: diff --git a/docs/uk/gateway/protocol.md b/docs/uk/gateway/protocol.md index 8359bd2c4..118e5c9da 100644 --- a/docs/uk/gateway/protocol.md +++ b/docs/uk/gateway/protocol.md @@ -1,39 +1,39 @@ --- read_when: - Реалізація або оновлення WS-клієнтів Gateway - - Налагодження невідповідностей протоколу або збоїв підключення + - Налагодження невідповідностей протоколу або помилок підключення - Повторне генерування схеми/моделей протоколу -summary: 'Протокол WebSocket Gateway: рукостискання, фрейми, версіонування' +summary: 'Протокол WebSocket для Gateway: початкове узгодження, кадри, версіювання' title: Протокол Gateway x-i18n: - generated_at: "2026-05-01T08:59:21Z" + generated_at: "2026-05-02T13:34:06Z" model: gpt-5.5 provider: openai - source_hash: 8295e4e416250e7381393c0aa6a0016719f96552485cf9d56bb3896c9704c4a9 + source_hash: bc8bd6bae485f13bbd0e8762d30abdfab7e2aee635f8ebac1a38798493239798 source_path: gateway/protocol.md workflow: 16 --- -Протокол Gateway WS є **єдиною площиною керування + транспортом вузлів** для -OpenClaw. Усі клієнти (CLI, вебінтерфейс, застосунок macOS, вузли iOS/Android, безголові -вузли) підключаються через WebSocket і оголошують свої **role** + **scope** під час -рукостискання. +The Gateway WS protocol is the **single control plane + node transport** for +OpenClaw. All clients (CLI, web UI, macOS app, iOS/Android nodes, headless +nodes) connect over WebSocket and declare their **role** + **scope** at +handshake time. -## Транспорт +## Transport -- WebSocket, текстові фрейми з JSON-навантаженнями. -- Перший фрейм **має** бути запитом `connect`. -- Фрейми до підключення обмежені 64 KiB. Після успішного рукостискання клієнти - мають дотримуватися обмежень `hello-ok.policy.maxPayload` і - `hello-ok.policy.maxBufferedBytes`. Якщо діагностику ввімкнено, - завеликі вхідні фрейми та повільні вихідні буфери генерують події `payload.large` - до того, як Gateway закриє або відкине відповідний фрейм. Ці події зберігають - розміри, ліміти, поверхні та безпечні коди причин. Вони не зберігають тіло повідомлення, - вміст вкладень, сире тіло фрейму, токени, cookies або секретні значення. +- WebSocket, text frames with JSON payloads. +- First frame **must** be a `connect` request. +- Pre-connect frames are capped at 64 KiB. After a successful handshake, clients + should follow the `hello-ok.policy.maxPayload` and + `hello-ok.policy.maxBufferedBytes` limits. With diagnostics enabled, + oversized inbound frames and slow outbound buffers emit `payload.large` events + before the gateway closes or drops the affected frame. These events keep + sizes, limits, surfaces, and safe reason codes. They do not keep the message + body, attachment contents, raw frame body, tokens, cookies, or secret values. -## Рукостискання (connect) +## Handshake (connect) -Gateway → Клієнт (виклик до підключення): +Gateway → Client (pre-connect challenge): ```json { @@ -43,7 +43,7 @@ Gateway → Клієнт (виклик до підключення): } ``` -Клієнт → Gateway: +Client → Gateway: ```json { @@ -78,7 +78,7 @@ Gateway → Клієнт (виклик до підключення): } ``` -Gateway → Клієнт: +Gateway → Client: ```json { @@ -104,18 +104,18 @@ Gateway → Клієнт: } ``` -Поки Gateway ще завершує запуск допоміжних компонентів, запит `connect` може -повернути повторювану помилку `UNAVAILABLE`, де `details.reason` встановлено на -`"startup-sidecars"` і вказано `retryAfterMs`. Клієнти мають повторити цей запит -у межах свого загального бюджету підключення, а не показувати його як остаточну -помилку рукостискання. +While the Gateway is still finishing startup sidecars, the `connect` request can +return a retryable `UNAVAILABLE` error with `details.reason` set to +`"startup-sidecars"` and `retryAfterMs`. Clients should retry that response +within their overall connection budget instead of surfacing it as a terminal +handshake failure. -`server`, `features`, `snapshot` і `policy` усі обов’язкові за схемою -(`src/gateway/protocol/schema/frames.ts`). `auth` також обов’язковий і повідомляє -узгоджені role/scopes. `canvasHostUrl` необов’язковий. +`server`, `features`, `snapshot`, and `policy` are all required by the schema +(`src/gateway/protocol/schema/frames.ts`). `auth` is also required and reports +the negotiated role/scopes. `canvasHostUrl` is optional. -Коли токен пристрою не видано, `hello-ok.auth` повідомляє узгоджені -дозволи без полів токена: +When no device token is issued, `hello-ok.auth` reports the negotiated +permissions without token fields: ```json { @@ -126,15 +126,15 @@ Gateway → Клієнт: } ``` -Довірені бекенд-клієнти в тому самому процесі (`client.id: "gateway-client"`, -`client.mode: "backend"`) можуть пропускати `device` у прямих підключеннях local loopback, -коли вони автентифікуються спільним токеном/паролем Gateway. Цей шлях зарезервований -для внутрішніх RPC площини керування й не дає застарілим базовим даним парування CLI/пристрою -блокувати локальну бекенд-роботу, наприклад оновлення сесій підлеглих агентів. Віддалені клієнти, -клієнти з браузерним origin, вузлові клієнти та явні клієнти з токеном пристрою/ідентичністю -пристрою й надалі використовують звичайні перевірки парування та підвищення scope. +Trusted same-process backend clients (`client.id: "gateway-client"`, +`client.mode: "backend"`) may omit `device` on direct loopback connections when +they authenticate with the shared gateway token/password. This path is reserved +for internal control-plane RPCs and keeps stale CLI/device pairing baselines from +blocking local backend work such as subagent session updates. Remote clients, +browser-origin clients, node clients, and explicit device-token/device-identity +clients still use the normal pairing and scope-upgrade checks. -Коли токен пристрою видано, `hello-ok` також містить: +When a device token is issued, `hello-ok` also includes: ```json { @@ -146,8 +146,8 @@ Gateway → Клієнт: } ``` -Під час довіреної передачі bootstrap `hello-ok.auth` також може містити додаткові -обмежені записи ролей у `deviceTokens`: +During trusted bootstrap handoff, `hello-ok.auth` may also include additional +bounded role entries in `deviceTokens`: ```json { @@ -166,14 +166,14 @@ Gateway → Клієнт: } ``` -Для вбудованого bootstrap-потоку вузол/оператор основний токен вузла лишається -`scopes: []`, а будь-який переданий токен оператора лишається обмеженим allowlist -оператора bootstrap (`operator.approvals`, `operator.read`, -`operator.talk.secrets`, `operator.write`). Перевірки scope bootstrap лишаються -префіксованими роллю: записи оператора задовольняють лише запити оператора, а ролі -неоператорів усе ще потребують scopes під власним префіксом ролі. +For the built-in node/operator bootstrap flow, the primary node token stays +`scopes: []` and any handed-off operator token stays bounded to the bootstrap +operator allowlist (`operator.approvals`, `operator.read`, +`operator.talk.secrets`, `operator.write`). Bootstrap scope checks stay +role-prefixed: operator entries only satisfy operator requests, and non-operator +roles still need scopes under their own role prefix. -### Приклад вузла +### Node example ```json { @@ -208,24 +208,24 @@ Gateway → Клієнт: } ``` -## Фреймування +## Framing -- **Запит**: `{type:"req", id, method, params}` -- **Відповідь**: `{type:"res", id, ok, payload|error}` -- **Подія**: `{type:"event", event, payload, seq?, stateVersion?}` +- **Request**: `{type:"req", id, method, params}` +- **Response**: `{type:"res", id, ok, payload|error}` +- **Event**: `{type:"event", event, payload, seq?, stateVersion?}` -Методи з побічними ефектами потребують **ключів ідемпотентності** (див. схему). +Side-effecting methods require **idempotency keys** (see schema). -## Ролі + scopes +## Roles + scopes -### Ролі +### Roles -- `operator` = клієнт площини керування (CLI/UI/автоматизація). -- `node` = хост можливостей (camera/screen/canvas/system.run). +- `operator` = control plane client (CLI/UI/automation). +- `node` = capability host (camera/screen/canvas/system.run). -### Scopes (оператор) +### Scopes (operator) -Поширені scopes: +Common scopes: - `operator.read` - `operator.write` @@ -234,48 +234,48 @@ Gateway → Клієнт: - `operator.pairing` - `operator.talk.secrets` -`talk.config` з `includeSecrets: true` потребує `operator.talk.secrets` -(або `operator.admin`). +`talk.config` with `includeSecrets: true` requires `operator.talk.secrets` +(or `operator.admin`). -RPC-методи Gateway, зареєстровані Plugin, можуть запитувати власний scope оператора, але -зарезервовані основні адміністративні префікси (`config.*`, `exec.approvals.*`, `wizard.*`, -`update.*`) завжди зіставляються з `operator.admin`. +Plugin-registered gateway RPC methods may request their own operator scope, but +reserved core admin prefixes (`config.*`, `exec.approvals.*`, `wizard.*`, +`update.*`) always resolve to `operator.admin`. -Scope методу є лише першою перевіркою. Деякі slash-команди, доступні через -`chat.send`, накладають суворіші перевірки рівня команди поверх цього. Наприклад, постійні -записи `/config set` і `/config unset` потребують `operator.admin`. +Method scope is only the first gate. Some slash commands reached through +`chat.send` apply stricter command-level checks on top. For example, persistent +`/config set` and `/config unset` writes require `operator.admin`. -`node.pair.approve` також має додаткову перевірку scope під час затвердження поверх -базового scope методу: +`node.pair.approve` also has an extra approval-time scope check on top of the +base method scope: -- запити без команд: `operator.pairing` -- запити з не-exec командами вузла: `operator.pairing` + `operator.write` -- запити, що містять `system.run`, `system.run.prepare` або `system.which`: +- commandless requests: `operator.pairing` +- requests with non-exec node commands: `operator.pairing` + `operator.write` +- requests that include `system.run`, `system.run.prepare`, or `system.which`: `operator.pairing` + `operator.admin` -### Caps/commands/permissions (вузол) +### Caps/commands/permissions (node) -Вузли оголошують заявлені можливості під час підключення: +Nodes declare capability claims at connect time: -- `caps`: категорії можливостей високого рівня. -- `commands`: allowlist команд для invoke. -- `permissions`: гранулярні перемикачі (наприклад, `screen.record`, `camera.capture`). +- `caps`: high-level capability categories. +- `commands`: command allowlist for invoke. +- `permissions`: granular toggles (e.g. `screen.record`, `camera.capture`). -Gateway трактує їх як **claims** і застосовує серверні allowlists. +The Gateway treats these as **claims** and enforces server-side allowlists. -## Присутність +## Presence -- `system-presence` повертає записи, ключовані ідентичністю пристрою. -- Записи присутності містять `deviceId`, `roles` і `scopes`, щоб UI могли показувати один рядок на пристрій - навіть коли він підключається і як **operator**, і як **node**. -- `node.list` містить необов’язкові поля `lastSeenAtMs` і `lastSeenReason`. Підключені вузли повідомляють - свій поточний час підключення як `lastSeenAtMs` з причиною `connect`; спаровані вузли також можуть повідомляти - тривалу фонову присутність, коли довірена подія вузла оновлює їхні метадані парування. +- `system-presence` returns entries keyed by device identity. +- Presence entries include `deviceId`, `roles`, and `scopes` so UIs can show a single row per device + even when it connects as both **operator** and **node**. +- `node.list` includes optional `lastSeenAtMs` and `lastSeenReason` fields. Connected nodes report + their current connection time as `lastSeenAtMs` with reason `connect`; paired nodes can also report + durable background presence when a trusted node event updates their pairing metadata. -### Фонова подія активності вузла +### Node background alive event -Вузли можуть викликати `node.event` з `event: "node.presence.alive"`, щоб записати, що спарований вузол був -активний під час фонового пробудження, не позначаючи його підключеним. +Nodes may call `node.event` with `event: "node.presence.alive"` to record that a paired node was +alive during a background wake without marking it connected. ```json { @@ -284,12 +284,12 @@ Gateway трактує їх як **claims** і застосовує сервер } ``` -`trigger` є закритим enum: `background`, `silent_push`, `bg_app_refresh`, -`significant_location`, `manual` або `connect`. Невідомі рядки trigger нормалізуються до -`background` Gateway перед збереженням. Подія є тривалою лише для автентифікованих сесій -пристроїв вузлів; сесії без пристрою або без парування повертають `handled: false`. +`trigger` is a closed enum: `background`, `silent_push`, `bg_app_refresh`, +`significant_location`, `manual`, or `connect`. Unknown trigger strings are normalized to +`background` by the gateway before persistence. The event is durable only for authenticated node +device sessions; device-less or unpaired sessions return `handled: false`. -Успішні Gateway повертають структурований результат: +Successful gateways return a structured result: ```json { @@ -300,67 +300,67 @@ Gateway трактує їх як **claims** і застосовує сервер } ``` -Старіші Gateway усе ще можуть повертати `{ "ok": true }` для `node.event`; клієнти мають трактувати це як -підтверджений RPC, а не як тривале збереження присутності. +Older gateways may still return `{ "ok": true }` for `node.event`; clients should treat that as an +acknowledged RPC, not as durable presence persistence. -## Обмеження області broadcast-подій +## Broadcast event scoping -Broadcast-події WebSocket, які надсилає сервер, обмежені за scope, щоб сесії з областю парування або лише вузлові сесії не отримували пасивно вміст сесій. +Server-pushed WebSocket broadcast events are scope-gated so that pairing-scoped or node-only sessions do not passively receive session content. -- **Фрейми чату, агента та результатів інструментів** (включно зі streamed подіями `agent` і результатами викликів інструментів) потребують щонайменше `operator.read`. Сесії без `operator.read` повністю пропускають ці фрейми. -- **Визначені Plugin broadcast-події `plugin.*`** обмежуються `operator.write` або `operator.admin`, залежно від того, як Plugin їх зареєстрував. -- **Події стану й транспорту** (`heartbeat`, `presence`, `tick`, життєвий цикл connect/disconnect тощо) лишаються необмеженими, щоб стан транспорту був видимий кожній автентифікованій сесії. -- **Невідомі сімейства broadcast-подій** за замовчуванням обмежуються scope (fail-closed), якщо зареєстрований handler явно не послаблює їх. +- **Chat, agent, and tool-result frames** (including streamed `agent` events and tool call results) require at least `operator.read`. Sessions without `operator.read` skip these frames entirely. +- **Plugin-defined `plugin.*` broadcasts** are gated to `operator.write` or `operator.admin`, depending on how the plugin registered them. +- **Status and transport events** (`heartbeat`, `presence`, `tick`, connect/disconnect lifecycle, etc.) remain unrestricted so transport health stays observable to every authenticated session. +- **Unknown broadcast event families** are scope-gated by default (fail-closed) unless a registered handler explicitly relaxes them. -Кожне клієнтське підключення зберігає власний поклієнтський порядковий номер, тому broadcast-події зберігають монотонне впорядкування на цьому сокеті навіть тоді, коли різні клієнти бачать різні підмножини потоку подій, відфільтровані за scope. +Each client connection keeps its own per-client sequence number so broadcasts preserve monotonic ordering on that socket even when different clients see different scope-filtered subsets of the event stream. -## Поширені сімейства RPC-методів +## Common RPC method families -Публічна поверхня WS ширша за наведені вище приклади рукостискання/автентифікації. Це -не згенерований дамп — `hello-ok.features.methods` є консервативним -списком виявлення, побудованим із `src/gateway/server-methods-list.ts` плюс завантажених -експортів методів Plugin/каналів. Сприймайте його як виявлення функцій, а не як повний -перелік `src/gateway/server-methods/*.ts`. +The public WS surface is broader than the handshake/auth examples above. This +is not a generated dump — `hello-ok.features.methods` is a conservative +discovery list built from `src/gateway/server-methods-list.ts` plus loaded +plugin/channel method exports. Treat it as feature discovery, not a full +enumeration of `src/gateway/server-methods/*.ts`. - - - `health` повертає кешований або щойно перевірений знімок стану Gateway. - - `diagnostics.stability` повертає нещодавній обмежений реєстратор діагностичної стабільності. Він зберігає операційні метадані, як-от назви подій, лічильники, розміри в байтах, показники пам’яті, стан черги/сесії, назви каналів/Plugin і ідентифікатори сесій. Він не зберігає текст чату, тіла webhook, виводи інструментів, сирі тіла запитів або відповідей, токени, cookies чи секретні значення. Потрібен scope читання оператора. - - `status` повертає підсумок Gateway у стилі `/status`; чутливі поля включаються лише для клієнтів-операторів зі scope адміністратора. - - `gateway.identity.get` повертає ідентичність пристрою Gateway, яку використовують потоки ретрансляції та парування. - - `system-presence` повертає поточний знімок присутності для підключених пристроїв operator/node. - - `system-event` додає системну подію та може оновлювати/broadcast контекст присутності. - - `last-heartbeat` повертає останню збережену подію Heartbeat. - - `set-heartbeats` вмикає або вимикає обробку Heartbeat у Gateway. + + - `health` returns the cached or freshly probed gateway health snapshot. + - `diagnostics.stability` returns the recent bounded diagnostic stability recorder. It keeps operational metadata such as event names, counts, byte sizes, memory readings, queue/session state, channel/plugin names, and session ids. It does not keep chat text, webhook bodies, tool outputs, raw request or response bodies, tokens, cookies, or secret values. Operator read scope is required. + - `status` returns the `/status`-style gateway summary; sensitive fields are included only for admin-scoped operator clients. + - `gateway.identity.get` returns the gateway device identity used by relay and pairing flows. + - `system-presence` returns the current presence snapshot for connected operator/node devices. + - `system-event` appends a system event and can update/broadcast presence context. + - `last-heartbeat` returns the latest persisted heartbeat event. + - `set-heartbeats` toggles heartbeat processing on the gateway. - - `models.list` повертає каталог моделей, дозволених середовищем виконання. Передайте `{ "view": "configured" }` для налаштованих моделей розміру вибірника (`agents.defaults.models` спочатку, потім `models.providers.*.models`) або `{ "view": "all" }` для повного каталогу. - - `usage.status` повертає вікна використання провайдера / зведення залишку квоти. - - `usage.cost` повертає агреговані зведення використання вартості за діапазон дат. - - `doctor.memory.status` повертає готовність векторної памʼяті / кешованих embedding для активної типової робочої області агента. Передавайте `{ "probe": true }` або `{ "deep": true }` лише тоді, коли викликач явно хоче виконати живий ping провайдера embedding. - - `doctor.memory.remHarness` повертає обмежений, доступний лише для читання попередній перегляд REM harness для віддалених клієнтів площини керування. Він може містити шляхи робочої області, фрагменти памʼяті, відрендерений обґрунтований markdown і кандидатів для глибокого просування, тому викликачам потрібен `operator.read`. - - `sessions.usage` повертає зведення використання по сеансах. - - `sessions.usage.timeseries` повертає часові ряди використання для одного сеансу. - - `sessions.usage.logs` повертає записи журналу використання для одного сеансу. + - `models.list` повертає дозволений під час виконання каталог моделей. Передайте `{ "view": "configured" }` для налаштованих моделей розміру picker (`agents.defaults.models` спочатку, потім `models.providers.*.models`), або `{ "view": "all" }` для повного каталогу. + - `usage.status` повертає зведення вікон використання провайдера / залишку квоти. + - `usage.cost` повертає агреговані зведення витрат за діапазон дат. + - `doctor.memory.status` повертає готовність векторної пам’яті / кешованих embedding для активного робочого простору агента за замовчуванням. Передавайте `{ "probe": true }` або `{ "deep": true }` лише коли викликач явно хоче живий ping до embedding-провайдера. + - `doctor.memory.remHarness` повертає обмежений, лише для читання попередній перегляд REM harness для віддалених клієнтів площини керування. Він може містити шляхи робочого простору, фрагменти пам’яті, відрендерений grounded markdown і кандидатів для глибокого просування, тому викликачам потрібен `operator.read`. + - `sessions.usage` повертає зведення використання за сесіями. + - `sessions.usage.timeseries` повертає часові ряди використання для однієї сесії. + - `sessions.usage.logs` повертає записи журналу використання для однієї сесії. - - - `channels.status` повертає зведення статусів вбудованих і bundled каналів/плагінів. + + - `channels.status` повертає зведення стану вбудованих + включених у комплект каналів/Plugin. - `channels.logout` виконує вихід із певного каналу/облікового запису, якщо канал підтримує вихід. - - `web.login.start` запускає потік входу через QR/web для поточного провайдера web-каналу з підтримкою QR. - - `web.login.wait` очікує завершення цього потоку входу через QR/web і в разі успіху запускає канал. - - `push.test` надсилає тестовий APNs push на зареєстрований iOS Node. + - `web.login.start` запускає потік QR/web входу для поточного QR-сумісного провайдера вебканалу. + - `web.login.wait` очікує завершення цього потоку QR/web входу та запускає канал у разі успіху. + - `push.test` надсилає тестовий APNs push до зареєстрованого iOS Node. - `voicewake.get` повертає збережені тригери wake-word. - `voicewake.set` оновлює тригери wake-word і транслює зміну. - - `send` є прямим RPC для вихідної доставки, орієнтованої на канал/обліковий запис/thread, поза chat runner. - - `logs.tail` повертає налаштований tail файлового журналу Gateway із cursor/limit і засобами керування max-byte. + - `send` є прямим RPC вихідної доставки для надсилань, націлених на канал/обліковий запис/потік, поза chat runner. + - `logs.tail` повертає налаштований хвіст файлового журналу gateway з керуванням cursor/limit і max-byte. @@ -377,79 +377,80 @@ Broadcast-події WebSocket, які надсилає сервер, обмеж - - `secrets.reload` повторно розвʼязує активні SecretRefs і замінює стан секретів середовища виконання лише за повного успіху. - - `secrets.resolve` розвʼязує призначення секретів, орієнтовані на команду, для конкретного набору команд/цілей. - - `config.get` повертає поточний знімок конфігурації та hash. - - `config.set` записує валідоване корисне навантаження конфігурації. - - `config.patch` обʼєднує часткове оновлення конфігурації. - - `config.apply` валідує та замінює повне корисне навантаження конфігурації. - - `config.schema` повертає живе корисне навантаження схеми конфігурації, яке використовують інструменти Control UI і CLI: схему, `uiHints`, версію та метадані генерації, включно з метаданими схем Plugin і каналів, коли середовище виконання може їх завантажити. Схема містить метадані полів `title` / `description`, похідні від тих самих labels і довідкового тексту, які використовує UI, включно з вкладеними обʼєктами, wildcard, array-item і гілками композиції `anyOf` / `oneOf` / `allOf`, коли існує відповідна документація полів. - - `config.schema.lookup` повертає корисне навантаження пошуку, обмежене шляхом, для одного шляху конфігурації: нормалізований шлях, поверхневий вузол схеми, відповідну підказку + `hintPath` і короткі зведення безпосередніх дочірніх елементів для деталізації в UI/CLI. Вузли схеми пошуку зберігають користувацьку документацію та поширені поля валідації (`title`, `description`, `type`, `enum`, `const`, `format`, `pattern`, межі numeric/string/array/object і прапорці на кшталт `additionalProperties`, `deprecated`, `readOnly`, `writeOnly`). Зведення дочірніх елементів показують `key`, нормалізований `path`, `type`, `required`, `hasChildren`, а також відповідні `hint` / `hintPath`. - - `update.run` запускає потік оновлення Gateway і планує перезапуск лише тоді, коли саме оновлення завершилося успішно. Оновлення через менеджер пакетів примусово виконують невідкладений перезапуск після оновлення без cooldown після заміни пакета, щоб старий процес Gateway не продовжував lazy-loading із заміненого дерева `dist`. - - `update.status` повертає останній кешований sentinel перезапуску після оновлення, включно з версією, що працює після перезапуску, коли вона доступна. - - `wizard.start`, `wizard.next`, `wizard.status` і `wizard.cancel` надають доступ до майстра onboarding через WS RPC. + - `secrets.reload` повторно розв’язує активні SecretRefs і замінює стан секретів під час виконання лише за повного успіху. + - `secrets.resolve` розв’язує призначення секретів, націлені на команду, для конкретного набору команди/цілі. + - `config.get` повертає поточний знімок конфігурації та хеш. + - `config.set` записує перевірене корисне навантаження конфігурації. + - `config.patch` об’єднує часткове оновлення конфігурації. + - `config.apply` перевіряє + замінює повне корисне навантаження конфігурації. + - `config.schema` повертає живе корисне навантаження схеми конфігурації, яке використовують інструменти Control UI і CLI: схему, `uiHints`, версію та метадані генерації, зокрема метадані схем Plugin + каналу, коли runtime може їх завантажити. Схема містить метадані полів `title` / `description`, отримані з тих самих міток і довідкового тексту, які використовує UI, зокрема вкладений об’єкт, wildcard, елемент масиву та гілки композиції `anyOf` / `oneOf` / `allOf`, коли існує відповідна документація поля. + - `config.schema.lookup` повертає корисне навантаження пошуку з областю шляху для одного шляху конфігурації: нормалізований шлях, поверхневий вузол схеми, відповідну підказку + `hintPath` і безпосередні зведення дочірніх елементів для деталізації в UI/CLI. Вузли схеми пошуку зберігають користувацьку документацію та поширені поля валідації (`title`, `description`, `type`, `enum`, `const`, `format`, `pattern`, межі для чисел/рядків/масивів/об’єктів і прапорці на кшталт `additionalProperties`, `deprecated`, `readOnly`, `writeOnly`). Зведення дочірніх елементів показують `key`, нормалізований `path`, `type`, `required`, `hasChildren`, а також відповідні `hint` / `hintPath`. + - `update.run` запускає потік оновлення Gateway і планує перезапуск лише коли саме оновлення успішне. Оновлення менеджера пакетів примусово виконують невідкладений перезапуск оновлення без cooldown після заміни пакета, щоб старий процес Gateway не продовжував lazy-loading із заміненого дерева `dist`. + - `update.status` повертає останній кешований sentinel перезапуску оновлення, зокрема поточну версію після перезапуску, якщо доступно. + - `wizard.start`, `wizard.next`, `wizard.status` і `wizard.cancel` надають майстер onboarding через WS RPC. - - - `agents.list` повертає налаштовані записи агентів, включно з ефективною моделлю та метаданими середовища виконання. - - `agents.create`, `agents.update` і `agents.delete` керують записами агентів і привʼязкою робочих областей. - - `agents.files.list`, `agents.files.get` і `agents.files.set` керують bootstrap-файлами робочої області, доступними для агента. - - `artifacts.list`, `artifacts.get` і `artifacts.download` надають зведення артефактів, похідних від transcript, і завантаження для явної області `sessionKey`, `runId` або `taskId`. Запити run і task розвʼязують власний сеанс на боці сервера та повертають лише transcript-медіа з відповідним provenance; небезпечні або локальні джерела URL повертають непідтримувані завантаження замість отримання на боці сервера. - - `agent.identity.get` повертає ефективну ідентичність асистента для агента або сеансу. - - `agent.wait` очікує завершення run і повертає кінцевий знімок, коли він доступний. + + - `agents.list` повертає налаштовані записи агентів, зокрема ефективну модель і runtime-метадані. + - `agents.create`, `agents.update` і `agents.delete` керують записами агентів і прив’язкою робочого простору. + - `agents.files.list`, `agents.files.get` і `agents.files.set` керують початковими файлами робочого простору, відкритими для агента. + - `artifacts.list`, `artifacts.get` і `artifacts.download` надають зведення артефактів, отриманих із transcript, і завантаження для явної області `sessionKey`, `runId` або `taskId`. Запити run і task розв’язують сесію-власника на сервері та повертають лише медіа transcript із відповідним походженням; небезпечні або локальні URL-джерела повертають непідтримувані завантаження замість отримання на сервері. + - `agent.identity.get` повертає ефективну ідентичність асистента для агента або сесії. + - `agent.wait` очікує завершення run і повертає кінцевий знімок, коли доступно. - - - `sessions.list` повертає поточний індекс сеансів, включно з метаданими `agentRuntime` для кожного рядка, коли налаштовано backend середовища виконання агента. - - `sessions.subscribe` і `sessions.unsubscribe` перемикають підписки на події змін сеансів для поточного WS-клієнта. - - `sessions.messages.subscribe` і `sessions.messages.unsubscribe` перемикають підписки на події transcript/повідомлень для одного сеансу. - - `sessions.preview` повертає обмежені попередні перегляди transcript для конкретних ключів сеансів. - - `sessions.resolve` розвʼязує або канонізує ціль сеансу. - - `sessions.create` створює новий запис сеансу. - - `sessions.send` надсилає повідомлення в наявний сеанс. - - `sessions.steer` є interrupt-and-steer варіантом для активного сеансу. - - `sessions.abort` перериває активну роботу для сеансу. Викликач може передати `key` плюс необовʼязковий `runId` або передати лише `runId` для активних run, які Gateway може розвʼязати до сеансу. - - `sessions.patch` оновлює метадані/overrides сеансу та повідомляє розвʼязану канонічну модель плюс ефективний `agentRuntime`. - - `sessions.reset`, `sessions.delete` і `sessions.compact` виконують обслуговування сеансу. - - `sessions.get` повертає повний збережений рядок сеансу. - - Виконання чату й надалі використовує `chat.history`, `chat.send`, `chat.abort` і `chat.inject`. `chat.history` нормалізовано для відображення клієнтам UI: inline directive tags вилучаються з видимого тексту, plain-text XML payloads викликів інструментів (включно з `...`, `...`, `...`, `...` і обрізаними блоками викликів інструментів) і витеклі ASCII/full-width керівні токени моделі вилучаються, суто silent-token рядки асистента, як-от точні `NO_REPLY` / `no_reply`, опускаються, а надто великі рядки можуть бути замінені placeholders. + + - `sessions.list` повертає поточний індекс сесій, зокрема метадані `agentRuntime` для кожного рядка, коли налаштовано runtime backend агента. + - `sessions.subscribe` і `sessions.unsubscribe` перемикають підписки на події зміни сесій для поточного WS-клієнта. + - `sessions.messages.subscribe` і `sessions.messages.unsubscribe` перемикають підписки на події transcript/повідомлень для однієї сесії. + - `sessions.preview` повертає обмежені попередні перегляди transcript для конкретних ключів сесій. + - `sessions.describe` повертає один рядок сесії Gateway для точного ключа сесії. + - `sessions.resolve` розв’язує або канонізує ціль сесії. + - `sessions.create` створює новий запис сесії. + - `sessions.send` надсилає повідомлення в наявну сесію. + - `sessions.steer` є варіантом interrupt-and-steer для активної сесії. + - `sessions.abort` перериває активну роботу для сесії. Викликач може передати `key` плюс необов’язковий `runId`, або передати лише `runId` для активних run, які Gateway може розв’язати до сесії. + - `sessions.patch` оновлює метадані/перевизначення сесії та повідомляє розв’язану канонічну модель плюс ефективний `agentRuntime`. + - `sessions.reset`, `sessions.delete` і `sessions.compact` виконують обслуговування сесій. + - `sessions.get` повертає повний збережений рядок сесії. + - Виконання чату все ще використовує `chat.history`, `chat.send`, `chat.abort` і `chat.inject`. `chat.history` display-normalized для UI-клієнтів: inline directive tags вилучаються з видимого тексту, plain-text XML-навантаження викликів інструментів (зокрема `...`, `...`, `...`, `...` і обрізані блоки викликів інструментів) та витіклі ASCII/full-width токени керування моделлю вилучаються, чисті рядки асистента з silent-token, як-от точні `NO_REPLY` / `no_reply`, пропускаються, а надмірно великі рядки можуть замінюватися placeholders. - - `device.pair.list` повертає пристрої, що очікують, і затверджені сполучені пристрої. + - `device.pair.list` повертає пристрої в очікуванні та затверджені сполучені пристрої. - `device.pair.approve`, `device.pair.reject` і `device.pair.remove` керують записами сполучення пристроїв. - - `device.token.rotate` ротує токен сполученого пристрою в межах його затвердженої ролі та меж області викликача. - - `device.token.revoke` відкликає токен сполученого пристрою в межах його затвердженої ролі та меж області викликача. + - `device.token.rotate` ротує токен сполученого пристрою в межах його затвердженої ролі та області викликача. + - `device.token.revoke` відкликає токен сполученого пристрою в межах його затвердженої ролі та області викликача. - `node.pair.request`, `node.pair.list`, `node.pair.approve`, `node.pair.reject`, `node.pair.remove` і `node.pair.verify` охоплюють сполучення Node і bootstrap verification. - `node.list` і `node.describe` повертають відомий/підключений стан Node. - - `node.rename` оновлює label сполученого Node. + - `node.rename` оновлює мітку сполученого Node. - `node.invoke` пересилає команду до підключеного Node. - `node.invoke.result` повертає результат для запиту invoke. - - `node.event` переносить події, створені Node, назад у Gateway. - - `node.canvas.capability.refresh` оновлює scoped canvas-capability tokens. + - `node.event` переносить події, що походять від Node, назад у gateway. + - `node.canvas.capability.refresh` оновлює токени canvas-capability з областю дії. - `node.pending.pull` і `node.pending.ack` є API черги підключеного Node. - `node.pending.enqueue` і `node.pending.drain` керують довговічною роботою в очікуванні для offline/disconnected Node. - - `exec.approval.request`, `exec.approval.get`, `exec.approval.list` і `exec.approval.resolve` охоплюють одноразові запити схвалення exec плюс пошук/повторне відтворення схвалень в очікуванні. - - `exec.approval.waitDecision` очікує одне схвалення exec в очікуванні й повертає остаточне рішення (або `null` у разі timeout). - - `exec.approvals.get` і `exec.approvals.set` керують знімками політики схвалення exec Gateway. - - `exec.approvals.node.get` і `exec.approvals.node.set` керують локальною для Node політикою схвалення exec через relay-команди Node. - - `plugin.approval.request`, `plugin.approval.list`, `plugin.approval.waitDecision` і `plugin.approval.resolve` охоплюють потоки схвалень, визначені Plugin. + - `exec.approval.request`, `exec.approval.get`, `exec.approval.list` і `exec.approval.resolve` охоплюють одноразові запити схвалення exec, а також пошук/відтворення схвалень в очікуванні. + - `exec.approval.waitDecision` очікує на одне схвалення exec в очікуванні та повертає остаточне рішення (або `null` у разі timeout). + - `exec.approvals.get` і `exec.approvals.set` керують знімками політики схвалення exec gateway. + - `exec.approvals.node.get` і `exec.approvals.node.set` керують локальною для Node політикою схвалення exec через команди ретрансляції Node. + - `plugin.approval.request`, `plugin.approval.list`, `plugin.approval.waitDecision` і `plugin.approval.resolve` охоплюють визначені Plugin потоки схвалення. - - Автоматизація: `wake` планує негайну або next-heartbeat інʼєкцію wake text; `cron.list`, `cron.status`, `cron.add`, `cron.update`, `cron.remove`, `cron.run`, `cron.runs` керують запланованою роботою. + - Автоматизація: `wake` планує негайну або next-heartbeat ін’єкцію wake text; `cron.list`, `cron.status`, `cron.add`, `cron.update`, `cron.remove`, `cron.run`, `cron.runs` керують запланованою роботою. - Skills та інструменти: `commands.list`, `skills.*`, `tools.catalog`, `tools.effective`, `tools.invoke`. @@ -457,259 +458,235 @@ Broadcast-події WebSocket, які надсилає сервер, обмеж ### Поширені сімейства подій -- `chat`: оновлення UI-чату, як-от `chat.inject` та інші події чату лише transcript. -- `session.message` і `session.tool`: оновлення transcript/event-stream для підписаного сеансу. -- `sessions.changed`: індекс сеансів або метадані змінено. -- `presence`: оновлення знімків присутності системи. +- `chat`: оновлення UI-чату, як-от `chat.inject` та інші події лише transcript + чату. +- `session.message` і `session.tool`: оновлення transcript/event-stream для + підписаної сесії. +- `sessions.changed`: індекс сесій або метадані змінено. +- `presence`: оновлення знімка присутності системи. - `tick`: періодична подія keepalive / liveness. -- `health`: оновлення знімка стану Gateway. -- `heartbeat`: оновлення потоку подій Heartbeat. -- `cron`: подія зміни run/job Cron. -- `shutdown`: сповіщення про завершення роботи Gateway. +- `health`: оновлення знімка справності gateway. +- `heartbeat`: оновлення потоку подій heartbeat. +- `cron`: подія зміни cron run/job. +- `shutdown`: сповіщення про завершення роботи gateway. - `node.pair.requested` / `node.pair.resolved`: життєвий цикл сполучення Node. - `node.invoke.request`: трансляція запиту invoke Node. - `device.pair.requested` / `device.pair.resolved`: життєвий цикл сполученого пристрою. - `voicewake.changed`: конфігурацію тригерів wake-word змінено. - `exec.approval.requested` / `exec.approval.resolved`: життєвий цикл схвалення exec. -- `plugin.approval.requested` / `plugin.approval.resolved`: життєвий цикл схвалення Plugin. +- `plugin.approval.requested` / `plugin.approval.resolved`: життєвий цикл схвалення plugin. ### Допоміжні методи Node -- Nodes можуть викликати `skills.bins`, щоб отримати поточний список виконуваних файлів Skills для перевірок auto-allow. +- Node можуть викликати `skills.bins`, щоб отримати поточний список виконуваних файлів skill + для перевірок auto-allow. ### Допоміжні методи оператора -- Оператори можуть викликати `commands.list` (`operator.read`), щоб отримати runtime - інвентар команд для агента. - - `agentId` необов’язковий; опустіть його, щоб читати робочий простір агента за замовчуванням. - - `scope` керує тим, на яку поверхню націлюється основне `name`: +- Оператори можуть викликати `commands.list` (`operator.read`), щоб отримати інвентар команд середовища виконання для агента. + - `agentId` необов’язковий; пропустіть його, щоб прочитати робочу область агента за замовчуванням. + - `scope` керує тим, на яку поверхню націлена основна `name`: - `text` повертає основний текстовий токен команди без початкового `/` - - `native` і типовий шлях `both` повертають нативні імена з урахуванням провайдера, - коли вони доступні - - `textAliases` містить точні slash-аліаси, як-от `/model` і `/m`. - - `nativeName` містить нативне ім’я команди з урахуванням провайдера, коли воно існує. - - `provider` необов’язковий і впливає лише на нативне іменування та доступність - нативних команд Plugin. - - `includeArgs=false` не включає серіалізовані метадані аргументів у відповідь. -- Оператори можуть викликати `tools.catalog` (`operator.read`), щоб отримати runtime-каталог інструментів для - агента. Відповідь містить згруповані інструменти та метадані походження: + - `native` і стандартний шлях `both` повертають нативні імена з урахуванням провайдера, коли вони доступні + - `textAliases` містить точні slash aliases, як-от `/model` і `/m`. + - `nativeName` містить нативну назву команди з урахуванням провайдера, коли вона існує. + - `provider` необов’язковий і впливає лише на нативне іменування та доступність нативних команд Plugin. + - `includeArgs=false` вилучає серіалізовані метадані аргументів із відповіді. +- Оператори можуть викликати `tools.catalog` (`operator.read`), щоб отримати каталог інструментів середовища виконання для агента. Відповідь містить згруповані інструменти та метадані походження: - `source`: `core` або `plugin` - `pluginId`: власник Plugin, коли `source="plugin"` - - `optional`: чи є інструмент Plugin необов’язковим -- Оператори можуть викликати `tools.effective` (`operator.read`), щоб отримати runtime-ефективний - інвентар інструментів для сеансу. + - `optional`: чи інструмент Plugin є необов’язковим +- Оператори можуть викликати `tools.effective` (`operator.read`), щоб отримати фактично доступний у середовищі виконання інвентар інструментів для сесії. - `sessionKey` обов’язковий. - - Gateway виводить довірений runtime-контекст із сеансу на серверному боці, замість приймати - контекст автентифікації або доставлення, наданий викликачем. - - Відповідь обмежена сеансом і відображає те, що активна розмова може використовувати просто зараз, - включно з інструментами ядра, Plugin і каналу. -- Оператори можуть викликати `tools.invoke` (`operator.write`), щоб викликати один доступний інструмент через - той самий шлях політики Gateway, що й `/tools/invoke`. - - `name` обов’язковий. `args`, `sessionKey`, `agentId`, `confirm` і - `idempotencyKey` необов’язкові. - - Якщо наявні і `sessionKey`, і `agentId`, агент розв’язаного сеансу має збігатися з - `agentId`. - - Відповідь є конвертом для SDK з полями `ok`, `toolName`, необов’язковим `output` і типізованими - полями `error`. Відмови через схвалення або політику повертають `ok:false` у payload, а не - обходять pipeline політики інструментів Gateway. -- Оператори можуть викликати `skills.status` (`operator.read`), щоб отримати видимий - інвентар Skills для агента. - - `agentId` необов’язковий; опустіть його, щоб читати робочий простір агента за замовчуванням. - - Відповідь містить придатність, відсутні вимоги, перевірки конфігурації та - санітизовані параметри встановлення без розкриття сирих секретних значень. -- Оператори можуть викликати `skills.search` і `skills.detail` (`operator.read`) для - метаданих виявлення ClawHub. + - Gateway виводить довірений контекст середовища виконання із сесії на боці сервера замість того, щоб приймати наданий викликачем контекст автентифікації або доставки. + - Відповідь обмежена сесією і відображає те, що активна розмова може використовувати прямо зараз, зокрема інструменти ядра, Plugin і каналу. +- Оператори можуть викликати `tools.invoke` (`operator.write`), щоб викликати один доступний інструмент через той самий шлях політики Gateway, що й `/tools/invoke`. + - `name` обов’язковий. `args`, `sessionKey`, `agentId`, `confirm` і `idempotencyKey` необов’язкові. + - Якщо наявні і `sessionKey`, і `agentId`, розв’язаний агент сесії має збігатися з `agentId`. + - Відповідь є конвертом для SDK з полями `ok`, `toolName`, необов’язковим `output` і типізованими полями `error`. Відмови через схвалення або політику повертають `ok:false` у payload, а не обходять конвеєр політики інструментів Gateway. +- Оператори можуть викликати `skills.status` (`operator.read`), щоб отримати видимий інвентар Skills для агента. + - `agentId` необов’язковий; пропустіть його, щоб прочитати робочу область агента за замовчуванням. + - Відповідь містить придатність, відсутні вимоги, перевірки конфігурації та санітизовані параметри встановлення без розкриття сирих значень секретів. +- Оператори можуть викликати `skills.search` і `skills.detail` (`operator.read`) для метаданих виявлення ClawHub. - Оператори можуть викликати `skills.install` (`operator.admin`) у двох режимах: - - Режим ClawHub: `{ source: "clawhub", slug, version?, force? }` встановлює - папку skill у каталог `skills/` робочого простору агента за замовчуванням. - - Режим інсталятора Gateway: `{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` - запускає оголошену дію `metadata.openclaw.install` на хості Gateway. + - Режим ClawHub: `{ source: "clawhub", slug, version?, force? }` встановлює папку skill до каталогу `skills/` робочої області агента за замовчуванням. + - Режим інсталятора Gateway: `{ name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }` запускає оголошену дію `metadata.openclaw.install` на хості Gateway. - Оператори можуть викликати `skills.update` (`operator.admin`) у двох режимах: - - Режим ClawHub оновлює один відстежуваний slug або всі відстежувані встановлення ClawHub у - робочому просторі агента за замовчуванням. - - Режим конфігурації виправляє значення `skills.entries.`, як-от `enabled`, - `apiKey` і `env`. + - Режим ClawHub оновлює один відстежуваний slug або всі відстежувані встановлення ClawHub у робочій області агента за замовчуванням. + - Режим конфігурації виправляє значення `skills.entries.`, як-от `enabled`, `apiKey` і `env`. ### Подання `models.list` `models.list` приймає необов’язковий параметр `view`: -- Опущено або `"default"`: поточна runtime-поведінка. Якщо налаштовано `agents.defaults.models`, відповідь є дозволеним каталогом; інакше відповідь є повним каталогом Gateway. -- `"configured"`: поведінка розміру picker. Якщо налаштовано `agents.defaults.models`, він усе одно має пріоритет. Інакше відповідь використовує явні записи `models.providers.*.models`, повертаючись до повного каталогу лише тоді, коли немає налаштованих рядків моделей. -- `"all"`: повний каталог Gateway, в обхід `agents.defaults.models`. Використовуйте це для діагностики та UI виявлення, а не для звичайних picker моделей. +- Пропущено або `"default"`: поточна поведінка середовища виконання. Якщо `agents.defaults.models` налаштовано, відповіддю буде дозволений каталог; інакше відповіддю буде повний каталог Gateway. +- `"configured"`: поведінка розміру засобу вибору. Якщо `agents.defaults.models` налаштовано, він усе одно має пріоритет. Інакше відповідь використовує явні записи `models.providers.*.models`, повертаючись до повного каталогу лише тоді, коли немає налаштованих рядків моделей. +- `"all"`: повний каталог Gateway, в обхід `agents.defaults.models`. Використовуйте це для діагностики та інтерфейсів виявлення, а не для звичайних засобів вибору моделей. -## Схвалення exec +## Схвалення виконання -- Коли exec-запит потребує схвалення, Gateway транслює `exec.approval.requested`. -- Операторські клієнти виконують розв’язання, викликаючи `exec.approval.resolve` (потребує scope `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 - відхиляє запуск замість довіряти зміненому payload. +- Коли запит на виконання потребує схвалення, 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 відхиляє запуск замість того, щоб довіряти зміненому payload. -## Резервний варіант доставлення агента +## Резервний варіант доставки агента -- Запити `agent` можуть містити `deliver=true`, щоб запросити вихідне доставлення. -- `bestEffortDeliver=false` зберігає сувору поведінку: нерозв’язані або лише внутрішні цілі доставлення повертають `INVALID_REQUEST`. -- `bestEffortDeliver=true` дозволяє резервний перехід до виконання лише в сеансі, коли неможливо розв’язати зовнішній доставний маршрут (наприклад, внутрішні/webchat-сеанси або неоднозначні багатоканальні конфігурації). +- Запити `agent` можуть містити `deliver=true`, щоб запросити вихідну доставку. +- `bestEffortDeliver=false` зберігає сувору поведінку: нерозв’язані або лише внутрішні цілі доставки повертають `INVALID_REQUEST`. +- `bestEffortDeliver=true` дозволяє резервний перехід до виконання лише в сесії, коли неможливо розв’язати зовнішній маршрут доставки (наприклад, внутрішні/webchat-сесії або неоднозначні багатоканальні конфігурації). ## Версіонування -- `PROTOCOL_VERSION` розташований у `src/gateway/protocol/schema/protocol-schemas.ts`. +- `PROTOCOL_VERSION` міститься в `src/gateway/protocol/schema/protocol-schemas.ts`. - Клієнти надсилають `minProtocol` + `maxProtocol`; сервер відхиляє невідповідності. - Схеми + моделі генеруються з визначень TypeBox: - `pnpm protocol:gen` - `pnpm protocol:gen:swift` - `pnpm protocol:check` -### Клієнтські константи +### Константи клієнта -Еталонний клієнт у `src/gateway/client.ts` використовує ці типові значення. Значення -стабільні в межах protocol v3 і є очікуваною базовою лінією для сторонніх клієнтів. +Еталонний клієнт у `src/gateway/client.ts` використовує ці значення за замовчуванням. Значення стабільні в межах протоколу v3 і є очікуваною базовою лінією для сторонніх клієнтів. -| Константа | Типове значення | Джерело | -| ----------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------ | -| `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` | -| Тайм-аут запиту (на RPC) | `30_000` мс | `src/gateway/client.ts` (`requestTimeoutMs`) | +| Константа | За замовчуванням | Джерело | +| ----------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| `PROTOCOL_VERSION` | `3` | `src/gateway/protocol/schema/protocol-schemas.ts` | +| Тайм-аут запиту (на RPC) | `30_000` мс | `src/gateway/client.ts` (`requestTimeoutMs`) | | Тайм-аут preauth / connect-challenge | `15_000` мс | `src/gateway/handshake-timeouts.ts` (config/env можуть збільшити парний бюджет сервера/клієнта) | -| Початкова затримка reconnect | `1_000` мс | `src/gateway/client.ts` (`backoffMs`) | -| Максимальна затримка reconnect | `30_000` мс | `src/gateway/client.ts` (`scheduleReconnect`) | -| Обмеження fast-retry після закриття device-token | `250` мс | `src/gateway/client.ts` | -| Пільговий період force-stop перед `terminate()` | `250` мс | `FORCE_STOP_TERMINATE_GRACE_MS` | -| Типовий тайм-аут `stopAndWait()` | `1_000` мс | `STOP_AND_WAIT_TIMEOUT_MS` | -| Типовий інтервал tick (до `hello-ok`) | `30_000` мс | `src/gateway/client.ts` | -| Закриття через tick-timeout | код `4000`, коли мовчання перевищує `tickIntervalMs * 2` | `src/gateway/client.ts` | -| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 МБ) | `src/gateway/server-constants.ts` | +| Початкова затримка повторного підключення | `1_000` мс | `src/gateway/client.ts` (`backoffMs`) | +| Максимальна затримка повторного підключення | `30_000` мс | `src/gateway/client.ts` (`scheduleReconnect`) | +| Обмеження швидкої повторної спроби після закриття device-token | `250` мс | `src/gateway/client.ts` | +| Пільговий період force-stop перед `terminate()` | `250` мс | `FORCE_STOP_TERMINATE_GRACE_MS` | +| Тайм-аут за замовчуванням для `stopAndWait()` | `1_000` мс | `STOP_AND_WAIT_TIMEOUT_MS` | +| Інтервал tick за замовчуванням (до `hello-ok`) | `30_000` мс | `src/gateway/client.ts` | +| Закриття через tick-timeout | код `4000`, коли тиша перевищує `tickIntervalMs * 2` | `src/gateway/client.ts` | +| `MAX_PAYLOAD_BYTES` | `25 * 1024 * 1024` (25 МБ) | `src/gateway/server-constants.ts` | -Сервер оголошує ефективні `policy.tickIntervalMs`, `policy.maxPayload` -і `policy.maxBufferedBytes` у `hello-ok`; клієнти мають дотримуватися цих значень, -а не типових значень до handshake. +Сервер оголошує ефективні `policy.tickIntervalMs`, `policy.maxPayload` і `policy.maxBufferedBytes` у `hello-ok`; клієнти мають дотримуватися цих значень, а не значень за замовчуванням до handshake. ## Автентифікація - Автентифікація Gateway зі спільним секретом використовує `connect.params.auth.token` або `connect.params.auth.password`, залежно від налаштованого режиму автентифікації. -- Режими з ідентифікацією, як-от Tailscale Serve +- Режими з ідентичністю, як-от Tailscale Serve (`gateway.auth.allowTailscale: true`) або не-loopback - `gateway.auth.mode: "trusted-proxy"`, проходять перевірку автентифікації підключення за - заголовками запиту, а не через `connect.params.auth.*`. -- `gateway.auth.mode: "none"` для приватного входу повністю пропускає - автентифікацію підключення зі спільним секретом; не відкривайте цей режим для - публічного або ненадійного входу. -- Після спарювання Gateway видає **токен пристрою**, обмежений роллю підключення - + scopes. Він повертається в `hello-ok.auth.deviceToken`, і клієнт має + `gateway.auth.mode: "trusted-proxy"`, проходять перевірку автентифікації connect за + заголовками запиту замість `connect.params.auth.*`. +- Private-ingress `gateway.auth.mode: "none"` повністю пропускає автентифікацію connect + зі спільним секретом; не відкривайте цей режим на публічному/недовіреному ingress. +- Після спарювання Gateway видає **токен пристрою**, обмежений роллю + підключення + scopes. Він повертається в `hello-ok.auth.deviceToken`, і клієнт має зберігати його для майбутніх підключень. - Клієнти мають зберігати основний `hello-ok.auth.deviceToken` після будь-якого успішного підключення. -- Повторне підключення з цим **збереженим** токеном пристрою також має - повторно використовувати збережений затверджений набір scopes для цього токена. - Це зберігає вже наданий доступ для читання/перевірки/статусу й уникає - непомітного звуження повторних підключень до неявного scope лише для адміністратора. -- Збирання автентифікації підключення на боці клієнта (`selectConnectAuth` у +- Повторне підключення з цим **збереженим** токеном пристрою також має повторно + використовувати збережений затверджений набір scopes для цього токена. Це зберігає + доступ для читання/проби/статусу, який уже було надано, і не дає повторним + підключенням непомітно звузитися до неявного scope лише для адміністратора. +- Формування автентифікації connect на стороні клієнта (`selectConnectAuth` у `src/gateway/client.ts`): - - `auth.password` є незалежним і завжди пересилається, коли заданий. - - `auth.token` заповнюється в порядку пріоритету: спершу явний спільний токен, - потім явний `deviceToken`, потім збережений токен для окремого пристрою - (ключований за `deviceId` + `role`). + - `auth.password` є незалежним і завжди передається, якщо заданий. + - `auth.token` заповнюється в порядку пріоритету: спочатку явний спільний токен, + потім явний `deviceToken`, потім збережений токен для пристрою (ключований за + `deviceId` + `role`). - `auth.bootstrapToken` надсилається лише тоді, коли жоден із наведених вище - варіантів не дав `auth.token`. Спільний токен або будь-який знайдений токен - пристрою пригнічує його. + варіантів не визначив `auth.token`. Спільний токен або будь-який визначений + токен пристрою пригнічує його. - Автоматичне підвищення збереженого токена пристрою під час одноразової - повторної спроби `AUTH_TOKEN_MISMATCH` дозволене **лише для довірених кінцевих точок** — + повторної спроби `AUTH_TOKEN_MISMATCH` дозволене **лише для довірених endpoints** — loopback або `wss://` із закріпленим `tlsFingerprint`. Публічний `wss://` - без закріплення не підходить. -- Додаткові записи `hello-ok.auth.deviceTokens` є токенами передавання bootstrap. - Зберігайте їх лише тоді, коли підключення використовувало bootstrap-автентифікацію на довіреному транспорті, - як-от `wss://` або loopback/local pairing. + без pinning не підходить. +- Додаткові записи `hello-ok.auth.deviceTokens` є токенами передачі bootstrap. + Зберігайте їх лише тоді, коли connect використовував bootstrap-автентифікацію через + довірений транспорт, як-от `wss://` або loopback/local pairing. - Якщо клієнт надає **явний** `deviceToken` або явні `scopes`, цей запитаний - викликачем набір scopes лишається авторитетним; кешовані scopes повторно + викликачем набір scopes залишається авторитетним; кешовані scopes повторно використовуються лише тоді, коли клієнт повторно використовує збережений токен - для окремого пристрою. + для пристрою. - Токени пристроїв можна ротувати/відкликати через `device.token.rotate` і `device.token.revoke` (потрібен scope `operator.pairing`). -- `device.token.rotate` повертає метадані ротації. Він віддзеркалює замінний - bearer-токен лише для викликів із того самого пристрою, які вже автентифіковані - цим токеном пристрою, щоб клієнти лише з токеном могли зберегти свою заміну до - повторного підключення. Ротації через спільний/адміністративний доступ не - віддзеркалюють bearer-токен. -- Видача, ротація та відкликання токенів лишаються обмеженими затвердженим набором ролей, - записаним у записі спарювання цього пристрою; мутація токена не може розширити - або націлитися на роль пристрою, яку затвердження спарювання ніколи не надавало. -- Для сесій токенів спарених пристроїв керування пристроєм має self-scoped характер, - якщо викликач також не має `operator.admin`: неадміністративні викликачі можуть - видаляти/відкликати/ротувати лише запис **власного** пристрою. -- `device.token.rotate` і `device.token.revoke` також перевіряють набір scopes цільового - токена оператора щодо поточних scopes сесії викликача. Неадміністративні викликачі - не можуть ротувати або відкликати ширший токен оператора, ніж той, який вони вже мають. -- Збої автентифікації містять `error.details.code` разом із підказками для відновлення: - - `error.details.canRetryWithDeviceToken` (булеве значення) +- `device.token.rotate` повертає метадані ротації. Він дублює replacement + bearer token лише для викликів із того самого пристрою, які вже автентифіковані цим + токеном пристрою, щоб клієнти лише з токеном могли зберегти replacement перед + повторним підключенням. Ротації shared/admin не дублюють bearer token. +- Видача, ротація та відкликання токенів залишаються обмеженими затвердженим + набором ролей, записаним у pairing-записі цього пристрою; мутація токена не може + розширити або націлити роль пристрою, яку схвалення pairing ніколи не надало. +- Для paired-device token sessions керування пристроями має self-scoped характер, + якщо викликач також не має `operator.admin`: викликачі без прав адміністратора + можуть видаляти/відкликати/ротувати лише запис **власного** пристрою. +- `device.token.rotate` і `device.token.revoke` також перевіряють набір scopes + цільового operator token щодо поточних session scopes викликача. Викликачі без + прав адміністратора не можуть ротувати або відкликати ширший operator token, ніж + уже мають. +- Помилки автентифікації містять `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`: - - Довірені клієнти можуть виконати одну обмежену повторну спробу з кешованим токеном для окремого пристрою. - - Якщо ця повторна спроба не вдається, клієнти мають зупинити автоматичні цикли повторного підключення й показати оператору інструкції щодо дій. + - Довірені клієнти можуть спробувати одну обмежену повторну спробу з кешованим токеном для пристрою. + - Якщо ця повторна спроба не вдається, клієнти мають зупинити автоматичні цикли повторного підключення й показати guidance щодо дій оператора. ## Ідентичність пристрою + спарювання -- Nodes мають містити стабільну ідентичність пристрою (`device.id`), виведену з - відбитка ключової пари. +- Node-и мають містити стабільну ідентичність пристрою (`device.id`), похідну від + fingerprint пари ключів. - Gateways видають токени для кожного пристрою + ролі. -- Затвердження спарювання потрібні для нових ідентифікаторів пристроїв, якщо - локальне автоматичне затвердження не ввімкнене. -- Автоматичне затвердження спарювання зосереджене на прямих підключеннях local loopback. -- OpenClaw також має вузький шлях локального самопідключення backend/контейнера для - довірених допоміжних потоків зі спільним секретом. -- Підключення з того самого хоста через tailnet або LAN все одно розглядаються як віддалені для спарювання та - потребують затвердження. -- WS-клієнти зазвичай додають ідентичність `device` під час `connect` (оператор + - node). Єдині винятки для оператора без пристрою — це явні довірені шляхи: - - `gateway.controlUi.allowInsecureAuth=true` для сумісності небезпечного HTTP лише на localhost. - - успішна автентифікація оператора Control UI через `gateway.auth.mode: "trusted-proxy"`. - - `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (break-glass, серйозне зниження безпеки). - - прямі loopback backend RPC `gateway-client`, автентифіковані спільним - токеном/паролем Gateway. +- Схвалення pairing потрібні для нових ID пристроїв, якщо не ввімкнене локальне автоматичне схвалення. +- Автоматичне схвалення pairing зосереджене на прямих підключеннях local loopback. +- OpenClaw також має вузький backend/container-local self-connect шлях для + довірених helper flows зі спільним секретом. +- Підключення same-host tailnet або LAN усе одно вважаються віддаленими для pairing і + потребують схвалення. +- WS-клієнти зазвичай включають ідентичність `device` під час `connect` (operator + + node). Єдині operator exceptions без пристрою — це явні trust paths: + - `gateway.controlUi.allowInsecureAuth=true` для сумісності з localhost-only insecure HTTP. + - успішна автентифікація operator Control UI через `gateway.auth.mode: "trusted-proxy"`. + - `gateway.controlUi.dangerouslyDisableDeviceAuth=true` (break-glass, суттєве зниження безпеки). + - direct-loopback `gateway-client` backend RPCs, автентифіковані спільним + gateway token/password. - Усі підключення мають підписувати наданий сервером nonce `connect.challenge`. ### Діагностика міграції автентифікації пристрою -Для застарілих клієнтів, які все ще використовують поведінку підписування до виклику, `connect` тепер повертає -коди деталей `DEVICE_AUTH_*` у `error.details.code` зі стабільним `error.details.reason`. +Для legacy clients, які досі використовують поведінку підписування до challenge, `connect` тепер повертає +detail codes `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` | Корисне навантаження підпису не відповідає 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` | Формат/канонікалізація публічного ключа не вдалися. | +| `device signature invalid` | `DEVICE_AUTH_SIGNATURE_INVALID` | `device-signature` | Payload підпису не відповідає v2 payload. | +| `device signature expired` | `DEVICE_AUTH_SIGNATURE_EXPIRED` | `device-signature-stale` | Підписана timestamp поза дозволеним skew. | +| `device identity mismatch` | `DEVICE_AUTH_DEVICE_ID_MISMATCH` | `device-id-mismatch` | `device.id` не відповідає fingerprint публічного ключа. | +| `device public key invalid` | `DEVICE_AUTH_PUBLIC_KEY_INVALID` | `device-public-key` | Не вдалося обробити формат/канонікалізацію публічного ключа. | Ціль міграції: -- Завжди очікуйте `connect.challenge`. -- Підписуйте payload v2, який містить серверний nonce. +- Завжди чекайте на `connect.challenge`. +- Підписуйте v2 payload, який містить server nonce. - Надсилайте той самий nonce у `connect.params.device.nonce`. -- Бажаний payload підпису — `v3`, який прив’язує `platform` і `deviceFamily` - на додачу до полів пристрою/клієнта/ролі/scopes/токена/nonce. -- Застарілі підписи `v2` лишаються прийнятими для сумісності, але закріплення - метаданих спареного пристрою все одно керує політикою команд під час повторного підключення. +- Бажаний signature payload — `v3`, який прив’язує `platform` і `deviceFamily` + на додачу до полів device/client/role/scopes/token/nonce. +- Legacy `v2` signatures залишаються прийнятими для сумісності, але metadata pinning + paired-device усе одно керує command policy під час повторного підключення. -## TLS + закріплення +## TLS + pinning -- TLS підтримується для WS-з’єднань. -- Клієнти можуть за потреби закріпити відбиток сертифіката Gateway (див. конфігурацію `gateway.tls` +- TLS підтримується для WS-підключень. +- Клієнти можуть за бажанням закріпити fingerprint сертифіката gateway (див. конфігурацію `gateway.tls` плюс `gateway.remote.tlsFingerprint` або CLI `--tls-fingerprint`). -## Область +## Scope -Цей протокол відкриває **повний API Gateway** (статус, channels, models, chat, -agent, sessions, nodes, approvals тощо). Точна поверхня визначена -TypeBox-схемами у `src/gateway/protocol/schema.ts`. +Цей протокол відкриває **повний gateway API** (status, channels, models, chat, +agent, sessions, nodes, approvals тощо). Точна поверхня визначається +TypeBox schemas у `src/gateway/protocol/schema.ts`. ## Пов’язане -- [Протокол bridge](/uk/gateway/bridge-protocol) +- [Протокол Bridge](/uk/gateway/bridge-protocol) - [Runbook Gateway](/uk/gateway)