Веб-интерфейсы

Control UI

Control UI — это небольшое одностраничное приложение на Vite + Lit, обслуживаемое Gateway:

  • по умолчанию: http://<host>:18789/
  • опциональный префикс: установите gateway.controlUi.basePath (например, /openclaw)

Он общается напрямую с WebSocket Gateway на том же порту.

Быстрый запуск (локально)

Если Gateway запущен на том же компьютере, откройте:

Если страница не загружается, сначала запустите Gateway: openclaw gateway. Аутентификация передается во время рукопожатия WebSocket через:

  • connect.params.auth.token
  • connect.params.auth.password Панель настроек панели управления позволяет сохранить токен; пароли не сохраняются. Мастер начальной настройки по умолчанию генерирует токен gateway, поэтому вставьте его здесь при первом подключении.

Сопряжение устройства (первое подключение)

Когда вы подключаетесь к Control UI с нового браузера или устройства, Gateway требует однократного подтверждения сопряжения — даже если вы находитесь в той же сети Tailnet с gateway.auth.allowTailscale: true. Это мера безопасности для предотвращения несанкционированного доступа. Что вы увидите: “disconnected (1008): pairing required” Чтобы подтвердить устройство:

# Список ожидающих запросов
openclaw devices list

# Подтвердить по ID запроса
openclaw devices approve <requestId>

После подтверждения устройство запоминается и не потребует повторного подтверждения, пока вы не отзовете его с помощью openclaw devices revoke --device <id> --role <role>. См. Devices CLI для ротации и отзыва токенов. Примечания:

  • Локальные подключения (127.0.0.1) подтверждаются автоматически.
  • Удаленные подключения (LAN, Tailnet и т.д.) требуют явного подтверждения.
  • Каждый профиль браузера генерирует уникальный ID устройства, поэтому смена браузера или очистка данных браузера потребует повторного сопряжения.

Поддержка языков

Control UI может локализовать себя при первой загрузке на основе языковых настроек вашего браузера, и вы можете изменить язык позже с помощью переключателя в карточке Access.

  • Поддерживаемые локали: en, zh-CN, zh-TW, pt-BR, de, es
  • Переводы на другие языки загружаются в браузере лениво.
  • Выбранная локаль сохраняется в хранилище браузера и используется при последующих посещениях.
  • Отсутствующие ключи перевода возвращаются к английскому языку.

Что он может делать (сегодня)

  • Чат с моделью через Gateway WS (chat.history, chat.send, chat.abort, chat.inject)
  • Потоковые вызовы инструментов + карточки живого вывода инструментов в чате (события агента)
  • Каналы: WhatsApp/Telegram/Discord/Slack + плагины каналов (Mattermost и др.) статус + QR-логин + конфигурация на канал (channels.status, web.login.*, config.patch)
  • Экземпляры: список присутствия + обновление (system-presence)
  • Сессии: список + переопределения thinking/verbose для каждой сессии (sessions.list, sessions.patch)
  • Cron-задания: список/добавление/редактирование/запуск/включение/отключение + история запусков (cron.*)
  • Навыки: статус, включение/отключение, установка, обновление API-ключей (skills.*)
  • Узлы: список + возможности (node.list)
  • Одобрения exec: редактирование списков разрешений gateway или узлов + политика запроса для exec host=gateway/node (exec.approvals.*)
  • Конфигурация: просмотр/редактирование ~/.openclaw/openclaw.json (config.get, config.set)
  • Конфигурация: применение + перезапуск с валидацией (config.apply) и пробуждение последней активной сессии
  • Запись конфигурации включает защиту base-hash для предотвращения конфликтов при параллельном редактировании
  • Схема конфигурации + рендеринг форм (config.schema, включая схемы плагинов и каналов); редактор Raw JSON остается доступным
  • Отладка: снимки статуса/здоровья/моделей + журнал событий + ручные RPC-вызовы (status, health, models.list)
  • Логи: живой вывод файловых логов gateway с фильтром/экспортом (logs.tail)
  • Обновление: запуск обновления пакета/git + перезапуск (update.run) с отчетом о перезапуске

Примечания к панели cron-заданий:

  • Для изолированных заданий доставка по умолчанию — анонс сводки. Вы можете переключить на none, если хотите только внутренние запуски.
  • Поля channel/target появляются при выборе announce.
  • Режим webhook использует delivery.mode = "webhook" с delivery.to, установленным на валидный HTTP(S) URL вебхука.
  • Для заданий основной сессии доступны режимы доставки webhook и none.
  • Расширенные элементы управления редактированием включают delete-after-run, clear agent override, опции cron exact/stagger, переопределения модели/thinking агента и переключатели доставки best-effort.
  • Валидация формы встроенная, с ошибками на уровне полей; невалидные значения отключают кнопку сохранения до исправления.
  • Установите cron.webhookToken, чтобы отправлять выделенный bearer-токен; если опущено, вебхук отправляется без заголовка авторизации.
  • Устаревший фолбэк: сохраненные устаревшие задания с 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]).
  • chat.inject добавляет примечание ассистента в транскрипт сессии и рассылает событие chat для обновлений только в UI (без запуска агента, без доставки в канал).
  • Остановка:
    • Нажмите Stop (вызывает chat.abort)
    • Введите /stop (или отдельные фразы прерывания, такие как stop, stop action, stop run, stop openclaw, please stop) для аборта вне полосы
    • chat.abort поддерживает { sessionKey } (без runId) для прерывания всех активных запусков для этой сессии
  • Сохранение частичного результата при аборте:
    • Когда запуск прерван, частичный текст ассистента все еще может отображаться в UI
    • Gateway сохраняет частичный текст ассистента из прерванного запуска в историю транскрипта, если существует буферизованный вывод
    • Сохраненные записи включают метаданные аборта, чтобы потребители транскрипта могли отличать частичные результаты аборта от обычного завершенного вывода

Доступ через Tailnet (рекомендуется)

Интегрированный Tailscale Serve (предпочтительно)

Оставьте Gateway на loopback и позвольте Tailscale Serve проксировать его с HTTPS:

openclaw gateway --tailscale serve

Откройте:

  • https://<magicdns>/ (или ваш настроенный gateway.controlUi.basePath)

По умолчанию запросы Serve для Control UI/WebSocket могут аутентифицироваться через заголовки идентификации Tailscale (tailscale-user-login), когда gateway.auth.allowTailscale имеет значение true. OpenClaw проверяет идентификацию, разрешая адрес x-forwarded-for с помощью tailscale whois и сопоставляя его с заголовком, и принимает их только тогда, когда запрос попадает на loopback с заголовками x-forwarded-* от Tailscale. Установите gateway.auth.allowTailscale: false (или принудительно gateway.auth.mode: "password"), если хотите требовать токен/пароль даже для трафика Serve. Аутентификация Serve без токена предполагает, что хост gateway доверенный. Если на этом хосте может выполняться ненадежный локальный код, требуйте аутентификацию по токену/паролю.

Привязка к tailnet + токен

openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"

Затем откройте:

  • http://<tailscale-ip>:18789/ (или ваш настроенный gateway.controlUi.basePath)

Вставьте токен в настройки UI (отправляется как connect.params.auth.token).

Небезопасный HTTP

Если вы открываете панель управления по обычному HTTP (http://<lan-ip> или http://<tailscale-ip>), браузер работает в небезопасном контексте и блокирует WebCrypto. По умолчанию OpenClaw блокирует подключения Control UI без идентификации устройства. Рекомендуемое решение: используйте 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. Только для аварийных случаев:

{
  gateway: {
    controlUi: { dangerouslyDisableDeviceAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}

dangerouslyDisableDeviceAuth отключает проверку идентификации устройства Control UI и является серьезным снижением безопасности. Отмените быстро после аварийного использования. См. Tailscale для руководства по настройке HTTPS.

Сборка UI

Gateway обслуживает статические файлы из dist/control-ui. Соберите их с помощью:

pnpm ui:build # автоматически устанавливает зависимости UI при первом запуске

Опциональный абсолютный базовый путь (когда нужны фиксированные URL ресурсов):

OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build

Для локальной разработки (отдельный dev-сервер):

pnpm ui:dev # автоматически устанавливает зависимости UI при первом запуске

Затем укажите UI на URL WebSocket вашего Gateway (например, ws://127.0.0.1:18789).

Отладка/тестирование: dev-сервер + удаленный Gateway

Control UI — это статические файлы; цель WebSocket настраивается и может отличаться от HTTP-источника. Это удобно, когда вы хотите иметь Vite dev-сервер локально, а Gateway работает где-то еще.

  1. Запустите dev-сервер UI: pnpm ui:dev
  2. Откройте URL вида:
http://localhost:5173/?gatewayUrl=ws://<gateway-host>:18789

Опциональная одноразовая аутентификация (если нужно):

http://localhost:5173/?gatewayUrl=wss://<gateway-host>:18789#token=<gateway-token>

Примечания:

  • gatewayUrl сохраняется в localStorage после загрузки и удаляется из URL.
  • token импортируется в память для текущей вкладки и удаляется из URL; он не сохраняется в localStorage.
  • password хранится только в памяти.
  • Когда gatewayUrl установлен, UI не возвращается к учетным данным из конфигурации или окружения. Укажите token (или password) явно. Отсутствие явных учетных данных является ошибкой.
  • Используйте wss://, когда Gateway находится за TLS (Tailscale Serve, HTTPS-прокси и т.д.).
  • gatewayUrl принимается только в окне верхнего уровня (не встроенном), чтобы предотвратить clickjacking.
  • Развертывания Control UI не на loopback должны явно устанавливать gateway.controlUi.allowedOrigins (полные origin). Это включает удаленные dev-настройки.
  • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true включает режим фолбэка на origin из заголовка Host, но это опасный режим безопасности.

Пример:

{
  gateway: {
    controlUi: {
      allowedOrigins: ["http://localhost:5173"],
    },
  },
}

Детали настройки удаленного доступа: Удаленный доступ.

ВебПанель управления