Перейти до основного вмісту

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

Інтерфейс керування — це невеликий односторінковий застосунок Vite + Lit, який обслуговує Gateway:
  • типово: http://<host>:18789/
  • необов’язковий префікс: задайте gateway.controlUi.basePath (наприклад, /openclaw)
Він працює безпосередньо з Gateway WebSocket на тому самому порту.

Швидке відкриття (локально)

Якщо Gateway запущено на тому самому комп’ютері, відкрийте: Якщо сторінка не завантажується, спочатку запустіть Gateway: openclaw gateway. Автентифікація передається під час WebSocket-рукостискання через:
  • connect.params.auth.token
  • connect.params.auth.password
  • заголовки ідентичності Tailscale Serve, коли gateway.auth.allowTailscale: true
  • заголовки ідентичності довіреного проксі, коли gateway.auth.mode: "trusted-proxy"
Панель налаштувань дашборда зберігає токен для поточної сесії вкладки браузера та вибраної URL-адреси шлюзу; паролі не зберігаються. Онбординг зазвичай генерує токен шлюзу для автентифікації зі спільним секретом під час першого підключення, але автентифікація паролем також працює, коли gateway.auth.mode має значення "password".

Спарювання пристрою (перше підключення)

Коли ви підключаєтеся до інтерфейсу керування з нового браузера або пристрою, Gateway зазвичай вимагає одноразового схвалення спарювання. Це захід безпеки для запобігання несанкціонованому доступу. Що ви побачите: “disconnected (1008): pairing required”
1

Перелічіть запити в очікуванні

openclaw devices list
2

Схваліть за ID запиту

openclaw devices approve <requestId>
Якщо браузер повторює спробу спарювання зі зміненими даними автентифікації (роль/області дії/публічний ключ), попередній запит в очікуванні замінюється, і створюється новий requestId. Перед схваленням повторно виконайте openclaw devices list. Якщо браузер уже спарено і ви змінюєте для нього доступ із читання на запис/адміністрування, це розглядається як підвищення схвалення, а не безшумне повторне підключення. OpenClaw зберігає старе схвалення активним, блокує ширше повторне підключення та просить вас явно схвалити новий набір областей дії. Після схвалення пристрій запам’ятовується і не потребуватиме повторного схвалення, якщо ви не відкличете його за допомогою openclaw devices revoke --device <id> --role <role>. Див. CLI пристроїв щодо ротації та відкликання токенів.
  • Прямі браузерні підключення через local loopback (127.0.0.1 / localhost) схвалюються автоматично.
  • Tailscale Serve може пропустити цикл спарювання для операторських сесій інтерфейсу керування, коли gateway.auth.allowTailscale: true, ідентичність Tailscale перевірено, а браузер надає ідентичність свого пристрою.
  • Прямі прив’язки Tailnet, підключення браузера з LAN і профілі браузера без ідентичності пристрою все одно потребують явного схвалення.
  • Кожен профіль браузера генерує унікальний ID пристрою, тому перемикання браузерів або очищення даних браузера вимагатиме повторного спарювання.

Особиста ідентичність (локально в браузері)

Інтерфейс керування підтримує особисту ідентичність для кожного браузера (відображуване ім’я та аватар), яка додається до вихідних повідомлень для атрибуції у спільних сесіях. Вона зберігається в сховищі браузера, обмежена поточним профілем браузера та не синхронізується з іншими пристроями й не зберігається на сервері, окрім звичайних метаданих авторства стенограми для повідомлень, які ви фактично надсилаєте. Очищення даних сайту або перемикання браузерів скидає її до порожнього значення. Та сама локальна для браузера схема застосовується до перевизначення аватара асистента. Завантажені аватари асистента накладаються на ідентичність, визначену шлюзом, лише в локальному браузері й ніколи не проходять повний шлях через config.patch. Спільне поле конфігурації ui.assistant.avatar усе ще доступне для клієнтів не з UI, які записують поле напряму (наприклад, скриптових шлюзів або власних дашбордів).

Кінцева точка конфігурації виконання

Інтерфейс керування отримує свої налаштування виконання з /__openclaw/control-ui-config.json. Цю кінцеву точку захищено тією самою автентифікацією шлюзу, що й решту HTTP-поверхні: неавтентифіковані браузери не можуть її отримати, а успішне отримання потребує або вже дійсного токена/пароля шлюзу, ідентичності Tailscale Serve, або ідентичності довіреного проксі.

Підтримка мов

Інтерфейс керування може локалізуватися під час першого завантаження на основі локалі вашого браузера. Щоб змінити її пізніше, відкрийте Огляд -> Доступ до Gateway -> Мова. Засіб вибору локалі розташований у картці доступу до Gateway, а не в розділі вигляду.
  • Підтримувані локалі: en, zh-CN, zh-TW, pt-BR, de, es, ja-JP, ko, fr, ar, it, tr, uk, id, pl, th, vi, nl, fa
  • Неанглійські переклади ліниво завантажуються в браузері.
  • Вибрана локаль зберігається в сховищі браузера та повторно використовується під час майбутніх відвідувань.
  • Відсутні ключі перекладу повертаються до англійської.
Переклади документації генеруються для того самого набору неанглійських локалей, але вбудований у сайт документації мовний перемикач Mintlify обмежено кодами локалей, які приймає Mintlify. Документація тайською (th) і перською (fa) все одно генерується в репозиторії публікації; вона може не з’являтися в цьому перемикачі, доки Mintlify не підтримуватиме ці коди.

Теми вигляду

Панель вигляду зберігає вбудовані теми Claw, Knot і Dash, а також один локальний для браузера слот імпорту tweakcn. Щоб імпортувати тему, відкрийте редактор tweakcn, виберіть або створіть тему, натисніть Поділитися і вставте скопійоване посилання на тему у вигляді. Імпортер також приймає URL-адреси реєстру https://tweakcn.com/r/themes/<id>, URL-адреси редактора на кшталт https://tweakcn.com/editor/theme?theme=amethyst-haze, відносні шляхи /themes/<id>, сирі ID тем і типові назви тем, як-от amethyst-haze. Імпортовані теми зберігаються лише в поточному профілі браузера. Вони не записуються до конфігурації шлюзу й не синхронізуються між пристроями. Заміна імпортованої теми оновлює один локальний слот; її очищення перемикає активну тему назад на Claw, якщо було вибрано імпортовану тему.

Що він може робити (сьогодні)

  • Спілкуватися з моделлю через Gateway WS (chat.history, chat.send, chat.abort, chat.inject).
  • Оновлення історії чату запитує обмежене недавнє вікно з обмеженнями тексту на повідомлення, щоб великі сесії не змушували браузер рендерити повне навантаження стенограми до того, як чат стане придатним до використання.
  • Розмовляти через браузерні realtime-сесії. OpenAI використовує прямий WebRTC, Google Live використовує обмежений одноразовий браузерний токен через WebSocket, а бекендові realtime-голосові plugins використовують relay-транспорт Gateway. Сесії провайдера, якими володіє клієнт, починаються з talk.client.create; relay-сесії Gateway починаються з talk.session.create. Relay зберігає облікові дані провайдера на Gateway, тоді як браузер передає PCM з мікрофона через talk.session.appendAudio і пересилає виклики інструментів провайдера openclaw_agent_consult через talk.client.toolCall для політики Gateway і більшої налаштованої моделі OpenClaw.
  • Потоково передавати виклики інструментів і живі картки виводу інструментів у чаті (події агента).
  • Канали: вбудований статус каналів, а також статус каналів із bundled/external plugins, QR-вхід і конфігурація для кожного каналу (channels.status, web.login.*, config.patch).
  • Оновлення перевірок каналів зберігають попередній знімок видимим, доки повільні перевірки провайдера завершуються, а часткові знімки позначаються, коли перевірка або аудит перевищує свій UI-бюджет.
  • Екземпляри: список присутності + оновлення (system-presence).
  • Сесії: типово перелічувати сесії налаштованого агента, відступати від застарілих ключів сесій неналаштованого агента та застосовувати перевизначення моделі/мислення/швидкого режиму/докладності/трасування/reasoning для кожної сесії (sessions.list, sessions.patch).
  • Сни: статус Dreaming, перемикач увімкнення/вимкнення і читач щоденника снів (doctor.memory.status, doctor.memory.dreamDiary, config.patch).
  • Завдання Cron: перелік/додавання/редагування/запуск/увімкнення/вимкнення + історія запусків (cron.*).
  • Skills: статус, увімкнення/вимкнення, встановлення, оновлення ключів API (skills.*).
  • Вузли: перелік + можливості (node.list).
  • Схвалення exec: редагування allowlist шлюзу або вузла + політика запитів для exec host=gateway/node (exec.approvals.*).
  • Перегляд/редагування ~/.openclaw/openclaw.json (config.get, config.set).
  • Застосування + перезапуск із перевіркою (config.apply) і пробудження останньої активної сесії.
  • Записи містять запобіжник base-hash, щоб запобігти перезапису паралельних редагувань.
  • Записи (config.set/config.apply/config.patch) попередньо перевіряють розв’язання активних SecretRef для посилань у надісланому конфігураційному навантаженні; нерозв’язані активні надіслані посилання відхиляються до запису.
  • Схема + рендеринг форми (config.schema / config.schema.lookup, зокрема поле title / description, відповідні підказки UI, безпосередні підсумки дочірніх елементів, метадані документації на вкладених вузлах object/wildcard/array/composition, а також схеми plugin + каналу, коли доступні); редактор Raw JSON доступний лише тоді, коли знімок має безпечний raw round-trip.
  • Якщо знімок не може безпечно виконати raw round-trip тексту, інтерфейс керування примусово вмикає режим форми та вимикає Raw-режим для цього знімка.
  • “Reset to saved” у редакторі Raw JSON зберігає raw-створену форму (форматування, коментарі, макет $include) замість повторного рендерингу сплощеного знімка, тож зовнішні редагування переживають скидання, коли знімок може безпечно виконати round-trip.
  • Структуровані значення об’єктів SecretRef рендеряться лише для читання в текстових полях форми, щоб запобігти випадковому пошкодженню через перетворення об’єкта на рядок.
  • Налагодження: знімки статусу/справності/моделей + журнал подій + ручні RPC-виклики (status, health, models.list).
  • Журнал подій містить таймінги оновлення/RPC інтерфейсу керування, таймінги повільного рендерингу чату/конфігурації та записи про чуйність браузера для довгих кадрів анімації або довгих завдань, коли браузер надає ці типи записів PerformanceObserver.
  • Журнали: live tail файлових журналів шлюзу з фільтром/експортом (logs.tail).
  • Оновлення: запуск оновлення пакета/git + перезапуск (update.run) зі звітом про перезапуск, потім опитування update.status після повторного підключення, щоб перевірити версію запущеного шлюзу.
  • Для ізольованих завдань доставка типово оголошує підсумок. Ви можете перемкнути на відсутність доставки, якщо потрібні лише внутрішні запуски.
  • Поля каналу/цілі з’являються, коли вибрано оголошення.
  • Режим Webhook використовує delivery.mode = "webhook" з delivery.to, установленим на дійсну HTTP(S) URL-адресу webhook.
  • Для завдань основної сесії доступні режими доставки webhook і none.
  • Розширені елементи керування редагуванням містять видалення після запуску, очищення перевизначення агента, параметри точного/рознесеного cron, перевизначення моделі/мислення агента та перемикачі best-effort доставки.
  • Перевірка форми є вбудованою з помилками на рівні полів; недійсні значення вимикають кнопку збереження до виправлення.
  • Установіть cron.webhookToken, щоб надіслати окремий bearer-токен; якщо його пропущено, webhook надсилається без заголовка автентифікації.
  • Застарілий fallback: збережені legacy-завдання з notify: true усе ще можуть використовувати cron.webhook до міграції.

Поведінка чату

  • chat.send є неблокувальним: він одразу підтверджує отримання за допомогою { runId, status: "started" }, а відповідь передається потоком через події chat.
  • Завантаження в чат приймають зображення та невідеофайли. Зображення зберігають власний шлях до зображення; інші файли зберігаються як керовані медіа й показуються в історії як посилання на вкладення.
  • Повторне надсилання з тим самим idempotencyKey повертає { status: "in_flight" } під час виконання та { status: "ok" } після завершення.
  • Відповіді chat.history обмежені за розміром для безпеки UI. Коли записи транскрипту завеликі, Gateway може обрізати довгі текстові поля, пропускати важкі блоки метаданих і замінювати надмірно великі повідомлення заповнювачем ([chat.history omitted: message too large]).
  • Зображення від асистента або згенеровані зображення зберігаються як керовані медіапосилання та повертаються через автентифіковані медіа-URL Gateway, тому перезавантаження не залежать від збереження необроблених base64-навантажень зображень у відповіді історії чату.
  • Під час відтворення chat.history Control UI прибирає з видимого тексту асистента лише-для-відображення вбудовані теги директив (наприклад [[reply_to_*]] і [[audio_as_voice]]), XML-навантаження викликів інструментів у plain text (зокрема <tool_call>...</tool_call>, <function_call>...</function_call>, <tool_calls>...</tool_calls>, <function_calls>...</function_calls> та обрізані блоки викликів інструментів), а також витіклі ASCII/повноширинні керувальні токени моделі, і пропускає записи асистента, весь видимий текст яких є лише точним беззвучним токеном NO_REPLY / no_reply або токеном підтвердження Heartbeat HEARTBEAT_OK.
  • Під час активного надсилання й фінального оновлення історії подання чату зберігає видимими локальні оптимістичні повідомлення користувача/асистента, якщо chat.history на короткий час повертає старіший знімок; канонічний транскрипт замінює ці локальні повідомлення, щойно історія Gateway наздоганяє.
  • Події chat наживо є станом доставлення, тоді як chat.history перебудовується зі сталого транскрипту сесії. Після фінальних подій інструментів Control UI перезавантажує історію та об’єднує лише невеликий оптимістичний хвіст; межу транскрипту задокументовано в WebChat.
  • chat.inject додає нотатку асистента до транскрипту сесії та транслює подію chat для оновлень лише в UI (без запуску агента й без доставлення каналом).
  • Заголовок чату показує фільтр агента перед вибирачем сесії, а вибирач сесії обмежується вибраним агентом. Перемикання агентів показує лише сесії, прив’язані до цього агента, і повертається до головної сесії цього агента, якщо в нього ще немає збережених dashboard-сесій.
  • На desktop-ширинах елементи керування чатом залишаються в одному компактному рядку та згортаються під час прокручування транскрипту вниз; прокручування вгору, повернення нагору або досягнення низу відновлює елементи керування.
  • Послідовні дублікати повідомлень лише з текстом відтворюються як одна бульбашка з бейджем кількості. Повідомлення, що містять зображення, вкладення, вивід інструментів або попередні перегляди canvas, не згортаються.
  • Вибирачі моделі та thinking у заголовку чату негайно оновлюють активну сесію через sessions.patch; це сталі перевизначення сесії, а не параметри надсилання лише для одного ходу.
  • Якщо ви надсилаєте повідомлення, поки зміна вибирача моделі для тієї самої сесії ще зберігається, composer чекає на цей patch сесії перед викликом chat.send, щоб надсилання використовувало вибрану модель.
  • Введення /new у Control UI створює ту саму нову dashboard-сесію, що й New Chat, і перемикається на неї, крім випадку, коли налаштовано session.dmScope: "main" і поточний батьківський елемент є головною сесією агента; у такому разі він скидає головну сесію на місці. Введення /reset зберігає явне скидання на місці Gateway для поточної сесії.
  • Вибирач моделі чату запитує налаштоване подання моделей Gateway. Якщо наявний agents.defaults.models, цей allowlist керує вибирачем, зокрема записами provider/*, які зберігають динамічними каталоги в межах провайдера. Інакше вибирач показує явні записи models.providers.*.models плюс провайдерів із придатною автентифікацією. Повний каталог залишається доступним через налагоджувальний RPC models.list з view: "all".
  • Коли свіжі звіти Gateway про використання сесії містять поточні токени контексту, область composer чату показує компактний індикатор використання контексту. Він перемикається на попереджувальний стиль за високого тиску на контекст і, на рекомендованих рівнях Compaction, показує компактну кнопку, яка запускає звичайний шлях Compaction сесії. Застарілі знімки токенів приховано, доки Gateway знову не повідомить свіже використання.
Режим розмови використовує зареєстрованого realtime-провайдера голосу. Налаштуйте OpenAI за допомогою talk.realtime.provider: "openai" плюс talk.realtime.providers.openai.apiKey, OPENAI_API_KEY або OAuth-профіль openai-codex; налаштуйте Google за допомогою talk.realtime.provider: "google" плюс talk.realtime.providers.google.apiKey. Браузер ніколи не отримує стандартний API-ключ провайдера. OpenAI отримує тимчасовий клієнтський secret Realtime для WebRTC. Google Live отримує одноразовий обмежений токен автентифікації Live API для браузерної WebSocket-сесії, із інструкціями та деклараціями інструментів, заблокованими в токені Gateway. Провайдери, які надають лише backend realtime bridge, працюють через relay-транспорт Gateway, тому облікові дані та vendor-сокети залишаються на серверному боці, тоді як браузерне аудіо проходить через автентифіковані RPC Gateway. Підказка Realtime-сесії збирається Gateway; talk.client.create не приймає перевизначення інструкцій, надані викликачем.Composer чату містить кнопку параметрів Talk поруч із кнопкою запуску/зупинки Talk. Параметри застосовуються до наступної сесії Talk і можуть перевизначати провайдера, транспорт, модель, голос, reasoning effort, поріг VAD, тривалість тиші та початковий відступ. Коли параметр порожній, Gateway використовує налаштовані defaults, якщо вони доступні, або default провайдера. Вибір Gateway relay примусово вмикає backend relay path; вибір WebRTC залишає сесію під керуванням клієнта й завершується помилкою замість тихого fallback до relay, якщо провайдер не може створити браузерну сесію.У composer чату елемент керування Talk — це кнопка з хвилями поруч із кнопкою мікрофонного диктування. Коли Talk запускається, рядок стану composer показує Connecting Talk..., потім Talk live, доки аудіо підключене, або Asking OpenClaw..., доки realtime-виклик інструмента звертається до налаштованої більшої моделі через talk.client.toolCall.Maintainer live smoke: OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts перевіряє OpenAI backend WebSocket bridge, OpenAI browser WebRTC SDP exchange, Google Live constrained-token browser WebSocket setup і Gateway relay browser adapter із фейковим медіа мікрофона. Команда друкує лише стан провайдера й не журналює secrets.
  • Натисніть Stop (викликає chat.abort).
  • Поки run активний, звичайні follow-up стають у чергу. Натисніть Steer на повідомленні в черзі, щоб вставити цей follow-up у поточний хід.
  • Введіть /stop (або окремі фрази переривання на кшталт stop, stop action, stop run, stop openclaw, please stop), щоб перервати поза основним потоком.
  • chat.abort підтримує { sessionKey } (без runId), щоб перервати всі активні run для цієї сесії.
  • Коли run перервано, частковий текст асистента все ще може показуватися в UI.
  • Gateway зберігає перерваний частковий текст асистента в історії транскрипту, коли є буферизований вивід.
  • Збережені записи містять метадані переривання, щоб споживачі транскрипту могли відрізнити часткові дані після переривання від виводу нормального завершення.

Встановлення PWA та web push

Control UI постачається з manifest.webmanifest і service worker, тож сучасні браузери можуть встановити його як standalone PWA. Web Push дає Gateway змогу будити встановлену PWA сповіщеннями, навіть коли вкладка або вікно браузера не відкриті.
ПоверхняЩо робить
ui/public/manifest.webmanifestМаніфест PWA. Браузери пропонують “Install app”, щойно він стає доступним.
ui/public/sw.jsService worker, який обробляє події push і натискання сповіщень.
push/vapid-keys.json (у каталозі стану OpenClaw)Автоматично згенерована пара ключів VAPID, що використовується для підписування payload Web Push.
push/web-push-subscriptions.jsonЗбережені endpoints підписок браузера.
Перевизначте пару ключів VAPID через env vars у процесі Gateway, коли потрібно закріпити ключі (для багатохостових deployment, ротації secrets або тестів):
  • OPENCLAW_VAPID_PUBLIC_KEY
  • OPENCLAW_VAPID_PRIVATE_KEY
  • OPENCLAW_VAPID_SUBJECT (default — mailto:openclaw@localhost)
Control UI використовує ці scope-gated методи Gateway для реєстрації та тестування браузерних підписок:
  • push.web.vapidPublicKey — отримує активний відкритий ключ VAPID.
  • push.web.subscribe — реєструє endpoint плюс keys.p256dh/keys.auth.
  • push.web.unsubscribe — видаляє зареєстрований endpoint.
  • push.web.test — надсилає тестове сповіщення до підписки викликача.
Web Push не залежить від шляху iOS APNS relay (див. Конфігурація для push із relay-backed) і наявного методу push.test, які націлені на native mobile pairing.

Hosted embeds

Повідомлення асистента можуть відтворювати розміщений web-вміст inline за допомогою shortcode [embed ...]. Політика sandbox iframe керується gateway.controlUi.embedSandbox:
Вимикає виконання скриптів усередині розміщених embeds.
Приклад:
{
  gateway: {
    controlUi: {
      embedSandbox: "scripts",
    },
  },
}
Використовуйте trusted лише тоді, коли вбудованому документу справді потрібна same-origin поведінка. Для більшості згенерованих агентом ігор та інтерактивних canvases scripts є безпечнішим вибором.
Абсолютні зовнішні URL embeds http(s) залишаються заблокованими за default. Якщо ви навмисно хочете, щоб [embed url="https://..."] завантажував сторонні сторінки, встановіть gateway.controlUi.allowExternalEmbedUrls: true.

Ширина повідомлень чату

Згруповані повідомлення чату використовують читабельну default максимальну ширину. Deployment для широких моніторів можуть перевизначити її без patch bundled CSS, встановивши gateway.controlUi.chatMessageMaxWidth:
{
  gateway: {
    controlUi: {
      chatMessageMaxWidth: "min(1280px, 82%)",
    },
  },
}
Значення перевіряється перед тим, як потрапити до браузера. Підтримувані значення включають прості довжини та відсотки, як-от 960px або 82%, а також обмежені width-вирази min(...), max(...), clamp(...), calc(...) і fit-content(...).

Доступ до tailnet (рекомендовано)

Тримайте Gateway на loopback і дозвольте Tailscale Serve проксіювати його через HTTPS:
openclaw gateway --tailscale serve
Відкрийте:
  • https://<magicdns>/ (або ваш налаштований gateway.controlUi.basePath)
За замовчуванням запити Control UI/WebSocket Serve можуть автентифікуватися через заголовки ідентичності Tailscale (tailscale-user-login), коли gateway.auth.allowTailscale має значення true. OpenClaw перевіряє ідентичність, зіставляючи адресу x-forwarded-for через tailscale whois із заголовком, і приймає їх лише тоді, коли запит надходить на loopback із заголовками x-forwarded-* від Tailscale. Для операторських сеансів Control UI з ідентичністю браузерного пристрою цей перевірений шлях Serve також пропускає цикл спарювання пристрою; браузери без пристрою та підключення з роллю вузла й далі проходять звичайні перевірки пристрою. Установіть gateway.auth.allowTailscale: false, якщо хочете вимагати явні облікові дані зі спільним секретом навіть для трафіку Serve. Потім використовуйте gateway.auth.mode: "token" або "password".Для цього асинхронного шляху ідентичності Serve невдалі спроби автентифікації для тієї самої IP-адреси клієнта й області автентифікації серіалізуються перед записами обмеження частоти. Тому одночасні невдалі повторні спроби з того самого браузера можуть показати retry later у другому запиті замість двох звичайних невідповідностей, що змагаються паралельно.
Автентифікація Serve без токена припускає, що хост gateway є довіреним. Якщо на цьому хості може виконуватися недовірений локальний код, вимагайте автентифікацію через токен/пароль.

Незахищений HTTP

Якщо ви відкриваєте панель керування через звичайний HTTP (http://<lan-ip> або http://<tailscale-ip>), браузер працює в небезпечному контексті та блокує WebCrypto. За замовчуванням OpenClaw блокує підключення Control UI без ідентичності пристрою. Задокументовані винятки:
  • сумісність із незахищеним HTTP лише для localhost через gateway.controlUi.allowInsecureAuth=true
  • успішна автентифікація операторського Control UI через gateway.auth.mode: "trusted-proxy"
  • аварійний параметр gateway.controlUi.dangerouslyDisableDeviceAuth=true
Рекомендоване виправлення: використовуйте HTTPS (Tailscale Serve) або відкрийте UI локально:
  • https://<magicdns>/ (Serve)
  • http://127.0.0.1:18789/ (на хості gateway)
{
  gateway: {
    controlUi: { allowInsecureAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}
allowInsecureAuth — це лише локальний перемикач сумісності:
  • Він дозволяє сеансам Control UI на localhost продовжувати роботу без ідентичності пристрою в небезпечних HTTP-контекстах.
  • Він не обходить перевірки спарювання.
  • Він не послаблює вимоги до ідентичності пристрою для віддалених (не localhost) підключень.
{
  gateway: {
    controlUi: { dangerouslyDisableDeviceAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}
dangerouslyDisableDeviceAuth вимикає перевірки ідентичності пристрою Control UI і є серйозним послабленням безпеки. Після аварійного використання швидко поверніть попереднє значення.
  • Успішна автентифікація через довірений проксі може допускати операторські сеанси Control UI без ідентичності пристрою.
  • Це не поширюється на сеанси Control UI з роллю вузла.
  • Зворотні проксі loopback на тому самому хості все одно не задовольняють автентифікацію довіреного проксі; див. Автентифікація довіреного проксі.
Див. Tailscale для вказівок із налаштування HTTPS.

Політика безпеки вмісту

Control UI постачається зі строгою політикою img-src: дозволені лише ресурси того самого походження, URL-адреси data: і локально згенеровані URL-адреси blob:. Віддалені URL-адреси зображень http(s) і URL-адреси відносно протоколу відхиляються браузером і не спричиняють мережевих запитів. Що це означає на практиці:
  • Аватари й зображення, що подаються через відносні шляхи (наприклад /avatars/<id>), і далі відображаються, зокрема автентифіковані маршрути аватарів, які UI отримує та перетворює на локальні URL-адреси blob:.
  • Вбудовані URL-адреси data:image/... і далі відображаються (корисно для payload у протоколі).
  • Локальні URL-адреси blob:, створені Control UI, і далі відображаються.
  • Віддалені URL-адреси аватарів, які надходять із метаданих каналу, видаляються в допоміжних функціях аватарів Control UI і замінюються вбудованим логотипом/бейджем, тому скомпрометований або зловмисний канал не може примусити браузер оператора виконувати довільні віддалені запити зображень.
Щоб отримати цю поведінку, нічого змінювати не потрібно — вона завжди ввімкнена й не налаштовується.

Автентифікація маршруту аватара

Коли автентифікацію gateway налаштовано, кінцева точка аватарів Control UI вимагає той самий токен gateway, що й решта API:
  • GET /avatar/<agentId> повертає зображення аватара лише автентифікованим викликам. GET /avatar/<agentId>?meta=1 повертає метадані аватара за тим самим правилом.
  • Неавтентифіковані запити до будь-якого з цих маршрутів відхиляються (відповідно до сусіднього маршруту assistant-media). Це запобігає витоку ідентичності агента через маршрут аватара на хостах, які інакше захищені.
  • Сам Control UI пересилає токен gateway як bearer-заголовок під час отримання аватарів і використовує автентифіковані URL-адреси blob, щоб зображення й далі відображалося на панелях керування.
Якщо ви вимкнете автентифікацію gateway (не рекомендовано на спільних хостах), маршрут аватара також стане неавтентифікованим, відповідно до решти gateway.

Автентифікація маршруту медіа асистента

Коли автентифікацію gateway налаштовано, локальні медіапрев’ю асистента використовують двоетапний маршрут:
  • GET /__openclaw__/assistant-media?meta=1&source=<path> вимагає звичайну операторську автентифікацію Control UI. Браузер надсилає токен gateway як bearer-заголовок під час перевірки доступності.
  • Успішні відповіді метаданих містять короткостроковий mediaTicket, обмежений саме цим шляхом джерела.
  • URL-адреси зображень, аудіо, відео й документів, що відображаються браузером, використовують mediaTicket=<ticket> замість активного токена або пароля gateway. Квиток швидко спливає і не може авторизувати інше джерело.
Це зберігає сумісність звичайного відтворення медіа з нативними медіаелементами браузера, не розміщуючи повторно використовувані облікові дані gateway у видимих медіа-URL.

Збірка UI

Gateway подає статичні файли з dist/control-ui. Зберіть їх за допомогою:
pnpm ui:build
Необов’язкова абсолютна база (коли потрібні фіксовані URL-адреси ресурсів):
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
Для локальної розробки (окремий сервер розробки):
pnpm ui:dev
Потім спрямуйте UI на URL Gateway WS (наприклад ws://127.0.0.1:18789).

Порожня сторінка Control UI

Якщо браузер завантажує порожню панель керування, а DevTools не показує корисної помилки, розширення або ранній content script міг завадити оцінюванню JavaScript-модульного застосунку. Статична сторінка містить звичайну HTML-панель відновлення, яка з’являється, коли <openclaw-app> не зареєстровано після запуску. Скористайтеся дією Спробувати ще раз на панелі після зміни середовища браузера або перезавантажте вручну після цих перевірок:
  • Вимкніть розширення, які інжектують код на всі сторінки, особливо розширення з content scripts <all_urls>.
  • Спробуйте приватне вікно, чистий профіль браузера або інший браузер.
  • Тримайте Gateway запущеним і перевірте ту саму URL-адресу панелі керування після зміни браузера.

Налагодження/тестування: сервер розробки + віддалений Gateway

Control UI — це статичні файли; ціль WebSocket налаштовується і може відрізнятися від HTTP-origin. Це зручно, коли ви хочете запускати сервер розробки Vite локально, а Gateway — деінде.
1

Запустіть сервер розробки UI

pnpm ui:dev
2

Відкрийте з gatewayUrl

http://localhost:5173/?gatewayUrl=ws%3A%2F%2F<gateway-host>%3A18789
Необов’язкова одноразова автентифікація (за потреби):
http://localhost:5173/?gatewayUrl=wss%3A%2F%2F<gateway-host>%3A18789#token=<gateway-token>
  • gatewayUrl зберігається в localStorage після завантаження та видаляється з URL.
  • Якщо ви передаєте повну кінцеву точку ws:// або wss:// через gatewayUrl, URL-кодуйте значення gatewayUrl, щоб браузер правильно розібрав рядок запиту.
  • token слід передавати через URL-фрагмент (#token=...), коли це можливо. Фрагменти не надсилаються на сервер, що запобігає витоку через журнали запитів і Referer. Застарілі параметри запиту ?token= усе ще одноразово імпортуються для сумісності, але лише як запасний варіант, і негайно видаляються після bootstrap.
  • password зберігається лише в пам’яті.
  • Коли gatewayUrl задано, UI не повертається до облікових даних із конфігурації або середовища. Надайте token (або password) явно. Відсутність явних облікових даних є помилкою.
  • Використовуйте wss://, коли Gateway розташований за TLS (Tailscale Serve, HTTPS-проксі тощо).
  • gatewayUrl приймається лише у вікні верхнього рівня (не у вбудованому), щоб запобігти clickjacking.
  • Розгортання Control UI не на loopback повинні явно задавати gateway.controlUi.allowedOrigins (повні origins). Це включає віддалені середовища розробки.
  • Запуск Gateway може додавати локальні origins, як-от http://localhost:<port> і http://127.0.0.1:<port>, на основі фактичної runtime-прив’язки та порту, але віддалені origins браузера все одно потребують явних записів.
  • Не використовуйте gateway.controlUi.allowedOrigins: ["*"], крім суворо контрольованого локального тестування. Це означає дозволити будь-який origin браузера, а не «зіставити будь-який хост, який я використовую».
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true вмикає режим fallback origin за заголовком Host, але це небезпечний режим безпеки.
Приклад:
{
  gateway: {
    controlUi: {
      allowedOrigins: ["http://localhost:5173"],
    },
  },
}
Докладніше про налаштування віддаленого доступу: Віддалений доступ.

Пов’язане