---
read_when:
    - Вы хотите управлять Gateway из браузера
    - Вам нужен доступ к Tailnet без SSH-туннелей
sidebarTitle: Control UI
summary: Браузерный интерфейс управления для Gateway (чат, активность, узлы, конфигурация)
title: Интерфейс управления
x-i18n:
    generated_at: "2026-06-28T23:57:10Z"
    model: gpt-5.5
    postprocess_version: locale-links-v1
    provider: openai
    source_hash: dc8b9675454d57bbfb6be10bb7ef94152a89a72c94affdf72be8c79cf14cbb08
    source_path: web/control-ui.md
    workflow: 16
---

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

- по умолчанию: `http://<host>:18789/`
- необязательный префикс: задайте `gateway.controlUi.basePath` (например, `/openclaw`)

Оно взаимодействует **напрямую с Gateway WebSocket** на том же порту.

## Быстрое открытие (локально)

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

- [http://127.0.0.1:18789/](http://127.0.0.1:18789/) (или [http://localhost:18789/](http://localhost:18789/))

Если страница не загружается, сначала запустите 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; пароли не сохраняются. Onboarding обычно создает токен Gateway для аутентификации с общим секретом при первом подключении, но аутентификация по паролю тоже работает, когда `gateway.auth.mode` равен `"password"`.

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

Когда вы подключаетесь к Control UI из нового браузера или с нового устройства, Gateway обычно требует **одноразового подтверждения сопряжения**. Это мера безопасности для предотвращения несанкционированного доступа.

**Что вы увидите:** "disconnected (1008): pairing required"

<Steps>
  <Step title="Выведите список ожидающих запросов">
    ```bash
    openclaw devices list
    ```
  </Step>
  <Step title="Подтвердите по ID запроса">
    ```bash
    openclaw devices approve <requestId>
    ```
  </Step>
</Steps>

Если браузер повторяет сопряжение с измененными данными аутентификации (роль/области доступа/публичный ключ), предыдущий ожидающий запрос заменяется и создается новый `requestId`. Перед подтверждением повторно выполните `openclaw devices list`.

Если браузер уже сопряжен и вы меняете доступ с чтения на доступ записи/администратора, это считается повышением подтверждения, а не тихим переподключением. OpenClaw сохраняет старое подтверждение активным, блокирует переподключение с более широкими правами и просит явно подтвердить новый набор областей доступа.

После подтверждения устройство запоминается и не потребует повторного подтверждения, пока вы не отзовете его командой `openclaw devices revoke --device <id> --role <role>`. См. [CLI устройств](/ru/cli/devices) для ротации и отзыва токенов.

Агенты Paperclip, подключающиеся через адаптер `openclaw_gateway`, используют тот же процесс подтверждения при первом запуске. После первой попытки подключения выполните `openclaw devices approve --latest`, чтобы просмотреть ожидающий запрос, затем повторно выполните напечатанную команду `openclaw devices approve <requestId>`, чтобы подтвердить его. Для удаленного Gateway передайте явные значения `--url` и `--token`. Чтобы подтверждения оставались стабильными между перезапусками, настройте постоянный `adapterConfig.devicePrivateKeyPem` в Paperclip вместо того, чтобы позволять ему создавать новую временную идентичность устройства при каждом запуске.

<Note>
- Прямые подключения браузера через local loopback (`127.0.0.1` / `localhost`) подтверждаются автоматически.
- Tailscale Serve может пропустить цикл сопряжения для операторских сессий Control UI, когда `gateway.auth.allowTailscale: true`, идентичность Tailscale проверена, а браузер предоставляет свою идентичность устройства.
- Прямые привязки Tailnet, подключения браузера по LAN и профили браузера без идентичности устройства по-прежнему требуют явного подтверждения.
- Каждый профиль браузера создает уникальный ID устройства, поэтому смена браузера или очистка данных браузера потребует повторного сопряжения.

</Note>

## Личная идентичность (локально в браузере)

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

Тот же локальный для браузера шаблон применяется к переопределению аватара ассистента. Загруженные аватары ассистента накладываются на идентичность, разрешенную Gateway, только в локальном браузере и никогда не проходят туда и обратно через `config.patch`. Общее поле конфигурации `ui.assistant.avatar` по-прежнему доступно для клиентов не из UI, которые записывают это поле напрямую (например, скриптовых Gateway или пользовательских дашбордов).

## Эндпоинт runtime-конфигурации

Control UI получает свои runtime-настройки из `/control-ui-config.json`, разрешаемого относительно базового пути Control UI в Gateway (например, `/__openclaw__/control-ui-config.json`, когда UI обслуживается по `/__openclaw__/`). Этот эндпоинт защищен той же аутентификацией Gateway, что и остальная HTTP-поверхность: неаутентифицированные браузеры не могут получить его, а успешное получение требует либо уже действительного токена/пароля Gateway, идентичности Tailscale Serve, либо идентичности доверенного прокси.

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

Control UI может локализовать себя при первой загрузке на основе локали вашего браузера. Чтобы переопределить ее позже, откройте **Обзор -> Доступ к 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`) все равно генерируется в publish-репозитории; она может не отображаться в этом выборе, пока Mintlify не начнет поддерживать эти коды.

## Темы внешнего вида

Панель «Внешний вид» сохраняет встроенные темы Claw, Knot и Dash, а также один локальный для браузера слот импорта tweakcn. Чтобы импортировать тему, откройте [редактор tweakcn](https://tweakcn.com/editor/theme), выберите или создайте тему, нажмите **Поделиться** и вставьте скопированную ссылку на тему в раздел «Внешний вид». Импортер также принимает URL реестра `https://tweakcn.com/r/themes/<id>`, URL редактора вида `https://tweakcn.com/editor/theme?theme=amethyst-haze`, относительные пути `/themes/<id>`, необработанные ID тем и имена тем по умолчанию, например `amethyst-haze`.

Раздел «Внешний вид» также включает локальную для браузера настройку размера текста. Настройка хранится вместе с остальными предпочтениями Control UI, применяется к тексту чата, тексту компоновщика, карточкам инструментов и боковым панелям чата, а также сохраняет текстовые поля размером не менее 16px, чтобы мобильный Safari не выполнял автоматическое масштабирование при фокусе.

Импортированные темы хранятся только в текущем профиле браузера. Они не записываются в конфигурацию Gateway и не синхронизируются между устройствами. Замена импортированной темы обновляет один локальный слот; ее очистка переключает активную тему обратно на Claw, если была выбрана импортированная тема.

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

<AccordionGroup>
  <Accordion title="Чат и разговор">
    - Общайтесь с моделью через Gateway WS (`chat.history`, `chat.send`, `chat.abort`, `chat.inject`).
    - Обновления истории чата запрашивают ограниченное недавнее окно с лимитами текста для каждого сообщения, чтобы большие сессии не заставляли браузер отрисовывать полный payload транскрипта до того, как чат станет пригодным для использования.
    - Разговаривайте через realtime-сессии браузера. OpenAI использует прямой WebRTC, Google Live использует ограниченный одноразовый браузерный токен через WebSocket, а backend-only 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, а также маршрутизирует голосовое управление активным запуском через `talk.client.steer` или `talk.session.steer`.
    - Потоково отображайте вызовы инструментов и live-карточки вывода инструментов в чате (события агента).
    - Вкладка активности с локальными для браузера, ориентированными на редактирование секретов сводками live-активности инструментов из существующей доставки `session.tool` / событий инструментов.

  </Accordion>
  <Accordion title="Каналы, инстансы, сессии, dreams">
    - Каналы: статус встроенных, а также bundled/external plugin channels, QR-вход и конфигурация для каждого канала (`channels.status`, `web.login.*`, `config.patch`).
    - Обновления проверок каналов сохраняют предыдущий снимок видимым, пока завершаются медленные проверки провайдеров, а частичные снимки помечаются, когда проверка или аудит превышает свой UI-бюджет.
    - Инстансы: список присутствия + обновление (`system-presence`).
    - Сессии: по умолчанию выводят список сессий настроенного агента, возвращаются от устаревших ключей сессий ненастроенного агента и применяют переопределения модели/мышления/быстрого режима/подробного режима/трассировки/reasoning для каждой сессии (`sessions.list`, `sessions.patch`).
    - Dreams: статус Dreaming, переключатель включения/выключения и читатель дневника снов (`doctor.memory.status`, `doctor.memory.dreamDiary`, `config.patch`).

  </Accordion>
  <Accordion title="Cron, Skills, узлы, подтверждения exec">
    - Задания Cron: список/добавление/редактирование/запуск/включение/отключение + история запусков (`cron.*`).
    - Skills: статус, включение/отключение, установка, обновления API-ключей (`skills.*`).
    - Узлы: список + возможности (`node.list`).
    - Подтверждения exec: редактируйте allowlist Gateway или узла + политику запросов для `exec host=gateway/node` (`exec.approvals.*`).

  </Accordion>
  <Accordion title="Конфигурация">
    - Просмотр/редактирование `~/.openclaw/openclaw.json` (`config.get`, `config.set`).
    - MCP имеет отдельную страницу настроек для настроенных серверов, включения, сводок OAuth/фильтров/параллельности, распространенных операторских команд и scoped-редактора конфигурации `mcp`.
    - Применение + перезапуск с валидацией (`config.apply`) и пробуждение последней активной сессии.
    - Записи включают защиту base-hash, чтобы предотвратить перезапись параллельных изменений.
    - Записи (`config.set`/`config.apply`/`config.patch`) предварительно проверяют разрешение активных SecretRef для ссылок в отправленном payload конфигурации; неразрешенные активные отправленные ссылки отклоняются до записи.
    - Сохранения форм отбрасывают устаревшие отредактированные placeholders, которые нельзя восстановить из сохраненной конфигурации, при этом сохраняя отредактированные значения, которые все еще сопоставляются с сохраненными секретами.
    - Схема + рендеринг формы (`config.schema` / `config.schema.lookup`, включая поля `title` / `description`, совпавшие подсказки UI, сводки непосредственных дочерних элементов, метаданные документации на вложенных узлах object/wildcard/array/composition, а также схемы plugin + канала, когда доступны); редактор Raw JSON доступен только когда снимок имеет безопасный raw round-trip.
    - Если снимок не может безопасно пройти round-trip необработанного текста, Control UI принудительно включает режим формы и отключает режим Raw для этого снимка.
    - В редакторе Raw JSON действие «Сбросить к сохраненному» сохраняет форму, созданную в raw-редакторе (форматирование, комментарии, компоновку `$include`), вместо повторного рендеринга сглаженного снимка, поэтому внешние изменения переживают сброс, когда снимок может безопасно пройти round-trip.
    - Структурированные объектные значения SecretRef отображаются только для чтения в текстовых полях формы, чтобы предотвратить случайное повреждение объекта в строку.

  </Accordion>
  <Accordion title="Отладка, логи, обновление">
    - Отладка: снимки статуса/здоровья/моделей + журнал событий + ручные RPC-вызовы (`status`, `health`, `models.list`).
    - Журнал событий включает тайминги обновлений/RPC Control UI, тайминги медленного рендеринга чата/конфигурации и записи отзывчивости браузера для длинных кадров анимации или долгих задач, когда браузер предоставляет эти типы записей PerformanceObserver.
    - Логи: live tail файловых логов Gateway с фильтрацией/экспортом (`logs.tail`).
    - Обновление: выполните обновление package/git + перезапуск (`update.run`) с отчетом о перезапуске, затем опрашивайте `update.status` после переподключения, чтобы проверить версию запущенного Gateway.

  </Accordion>
  <Accordion title="Примечания к панели заданий Cron">
    - Для изолированных заданий доставка по умолчанию объявляет сводку. Можно переключить на none, если нужны только внутренние запуски.
    - Поля канала/цели появляются, когда выбрано объявление.
    - Режим Webhook использует `delivery.mode = "webhook"` с `delivery.to`, заданным как действительный HTTP(S) Webhook URL.
    - Для заданий основного сеанса доступны режимы доставки webhook и none.
    - Расширенные элементы управления редактированием включают удаление после запуска, сброс переопределения агента, точные/разнесенные параметры cron, переопределения модели/мышления агента и переключатели доставки по мере возможности.
    - Проверка формы выполняется встроенно с ошибками на уровне полей; недопустимые значения отключают кнопку сохранения до исправления.
    - Задайте `cron.webhookToken`, чтобы отправлять выделенный bearer-токен; если он не указан, Webhook отправляется без заголовка авторизации.
    - Устаревший резервный вариант: выполните `openclaw doctor --fix`, чтобы перенести сохраненные устаревшие задания с `notify: true` из `cron.webhook` в явный Webhook для каждого задания или доставку по завершении.

  </Accordion>
</AccordionGroup>

## Страница MCP

Выделенная страница MCP — это операторское представление для MCP-серверов, управляемых OpenClaw, в `mcp.servers`. Она сама не запускает MCP-транспорты; используйте ее для просмотра и редактирования сохраненной конфигурации, а затем выполните `openclaw mcp doctor --probe`, когда нужно живое подтверждение работы сервера.

Типичный рабочий процесс:

1. Откройте **MCP** на боковой панели.
2. Проверьте карточки сводки для общего количества серверов, а также количества включенных, OAuth- и отфильтрованных серверов.
3. Просмотрите строку каждого сервера: транспорт, включение, аутентификацию, фильтры, тайм-ауты и подсказки команд.
4. Переключайте включение, когда сервер должен оставаться настроенным, но не участвовать в обнаружении во время выполнения.
5. Отредактируйте ограниченный раздел конфигурации `mcp` для определений серверов, заголовков, путей TLS/mTLS, метаданных OAuth, фильтров инструментов и метаданных проекции Codex.
6. Используйте **Сохранить** для записи конфигурации или **Сохранить и опубликовать**, когда работающий Gateway должен применить измененную конфигурацию.
7. Выполните `openclaw mcp status --verbose`, `openclaw mcp doctor --probe` или `openclaw mcp reload` из терминала, когда отредактированному процессу нужны статическая диагностика, живое подтверждение или сброс кэшированного рантайма.

Страница скрывает URL-подобные значения, содержащие учетные данные, перед отображением и заключает имена серверов в кавычки во фрагментах команд, чтобы скопированные команды продолжали работать с пробелами или метасимволами оболочки. Полный справочник CLI и конфигурации находится в [MCP](/ru/cli/mcp).

## Вкладка активности

Вкладка активности — это временный локальный для браузера наблюдатель за живой активностью инструментов. Она формируется из того же потока событий Gateway `session.tool` / событий инструментов, который питает карточки инструментов в чате; она не добавляет другое семейство событий Gateway, конечную точку, долговременное хранилище активности, поток метрик или внешний поток наблюдателя.

Записи активности хранят только очищенные сводки и отредактированные, усеченные превью вывода. Значения аргументов инструментов не сохраняются в состоянии активности; UI показывает, что аргументы скрыты, и записывает только количество полей аргументов. Список в памяти привязан к текущей вкладке браузера, сохраняется при навигации внутри Control UI и сбрасывается при перезагрузке страницы, переключении сеанса или нажатии **Очистить**.

## Поведение чата

<AccordionGroup>
  <Accordion title="Семантика отправки и истории">
    - `chat.send` является **неблокирующим**: он сразу подтверждает получение с `{ runId, status: "started" }`, а ответ передается потоком через события `chat`. Доверенные клиенты Control UI также могут получать необязательные метаданные времени ACK для локальной диагностики.
    - Загрузки в чат принимают изображения и не-видео файлы. Изображения сохраняют исходный путь изображения; остальные файлы сохраняются как управляемые медиа и отображаются в истории как ссылки на вложения.
    - Повторная отправка с тем же `idempotencyKey` возвращает `{ status: "in_flight" }` во время выполнения и `{ status: "ok" }` после завершения.
    - Ответы `chat.history` ограничены по размеру для безопасности UI. Когда записи транскрипта слишком велики, Gateway может усекать длинные текстовые поля, опускать тяжелые блоки метаданных и заменять чрезмерно большие сообщения заполнителем (`[chat.history omitted: message too large]`).
    - Когда видимое сообщение ассистента было усечено в `chat.history`, боковой читатель может по требованию получить полную нормализованную для отображения запись транскрипта через `chat.message.get` по `sessionKey`, активному `agentId` при необходимости и `messageId` транскрипта. Если Gateway все еще не может вернуть больше, читатель показывает явное состояние недоступности, а не молча повторяет усеченное превью.
    - Изображения ассистента/сгенерированные изображения сохраняются как управляемые ссылки на медиа и отдаются обратно через аутентифицированные медиа-URL Gateway, поэтому перезагрузки не зависят от того, остаются ли необработанные base64-полезные нагрузки изображений в ответе истории чата.
    - При отображении `chat.history` Control UI удаляет из видимого текста ассистента встроенные директивные теги только для отображения (например, `[[reply_to_*]]` и `[[audio_as_voice]]`), plain-text XML-полезные нагрузки вызовов инструментов (включая `<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](/ru/web/webchat).
    - `chat.inject` добавляет заметку ассистента в транскрипт сеанса и транслирует событие `chat` для обновлений только UI (без запуска агента и без доставки в канал).
    - Заголовок чата показывает фильтр агента перед выбором сеанса, а выбор сеанса ограничен выбранным агентом. При переключении агентов показываются только сеансы, связанные с этим агентом, и выполняется откат к основному сеансу этого агента, если у него еще нет сохраненных сеансов панели.
    - На ширине desktop элементы управления чатом остаются в одной компактной строке и сворачиваются при прокрутке транскрипта вниз; прокрутка вверх, возврат к началу или достижение низа восстанавливают элементы управления.
    - Последовательные повторяющиеся текстовые сообщения отображаются как один пузырь с бейджем количества. Сообщения с изображениями, вложениями, выводом инструментов или превью canvas не сворачиваются.
    - Переключатели модели и мышления в заголовке чата немедленно патчат активный сеанс через `sessions.patch`; это постоянные переопределения сеанса, а не параметры отправки только для одного хода.
    - Если отправить сообщение, пока изменение переключателя модели для того же сеанса еще сохраняется, composer дожидается этого патча сеанса перед вызовом `chat.send`, чтобы отправка использовала выбранную модель.
    - Ввод `/new` в Control UI создает и переключает на тот же новый сеанс панели, что и Новый чат, кроме случая, когда настроено `session.dmScope: "main"` и текущий родитель — основной сеанс агента; тогда основной сеанс сбрасывается на месте. Ввод `/reset` сохраняет явный сброс Gateway на месте для текущего сеанса.
    - Переключатель модели чата запрашивает настроенное представление моделей Gateway. Если присутствует `agents.defaults.models`, этот allowlist управляет переключателем, включая записи `provider/*`, которые сохраняют каталоги в области провайдера динамическими. Иначе переключатель показывает явные записи `models.providers.*.models` плюс провайдеров с пригодной аутентификацией. Полный каталог остается доступен через отладочный RPC `models.list` с `view: "all"`.
    - Когда свежие отчеты Gateway об использовании сеанса включают текущие токены контекста, область composer чата показывает компактный индикатор использования контекста. При высокой нагрузке на контекст он переключается на предупреждающий стиль, а на рекомендуемых уровнях Compaction показывает компактную кнопку, запускающую обычный путь Compaction сеанса. Устаревшие снимки токенов скрываются, пока Gateway снова не сообщит свежие данные использования.

  </Accordion>
  <Accordion title="Режим Talk (браузерный realtime)">
    Режим Talk использует зарегистрированного realtime-провайдера голоса. Настройте OpenAI с `talk.realtime.provider: "openai"` плюс профиль аутентификации API-ключа `openai`, `talk.realtime.providers.openai.apiKey` или `OPENAI_API_KEY`; OAuth-профили OpenAI не настраивают Realtime-голос. Настройте Google с `talk.realtime.provider: "google"` плюс `talk.realtime.providers.google.apiKey`. Браузер никогда не получает стандартный API-ключ провайдера. OpenAI получает временный Realtime client secret для WebRTC. Google Live получает одноразовый ограниченный токен аутентификации Live API для браузерного WebSocket-сеанса, при этом инструкции и объявления инструментов зафиксированы в токене Gateway. Провайдеры, которые предоставляют только backend realtime bridge, работают через relay-транспорт Gateway, поэтому учетные данные и сокеты поставщика остаются на сервере, а браузерное аудио проходит через аутентифицированные RPC Gateway. Подсказка Realtime-сеанса собирается Gateway; `talk.client.create` не принимает предоставленные вызывающим кодом переопределения инструкций.

    Composer чата включает кнопку параметров Talk рядом с кнопкой запуска/остановки Talk. Параметры применяются к следующему сеансу Talk и могут переопределять провайдера, транспорт, модель, голос, усилие рассуждения, порог VAD, длительность тишины и начальный padding. Когда параметр пустой, Gateway использует настроенные значения по умолчанию, если они доступны, или значение по умолчанию провайдера. Выбор Gateway relay принудительно включает путь backend relay; выбор WebRTC оставляет сеанс во владении клиента и приводит к ошибке вместо молчаливого отката к relay, если провайдер не может создать браузерный сеанс.

    В composer чата элемент управления Talk — это кнопка с волнами рядом с кнопкой диктовки через микрофон. Когда Talk запускается, строка состояния composer показывает `Connecting Talk...`, затем `Talk live`, пока аудио подключено, или `Asking OpenClaw...`, пока realtime-вызов инструмента консультируется с настроенной более крупной моделью через `talk.client.toolCall`.

    Живая smoke-проверка для сопровождающих: `OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts` проверяет backend WebSocket bridge OpenAI, WebRTC SDP-обмен OpenAI в браузере, настройку браузерного WebSocket с ограниченным токеном Google Live и браузерный адаптер Gateway relay с поддельным микрофонным медиа. Команда выводит только статус провайдера и не записывает секреты в лог.

  </Accordion>
  <Accordion title="Остановка и прерывание">
    - Нажмите **Остановить** (вызывает `chat.abort`).
    - Пока запуск активен, обычные последующие сообщения ставятся в очередь. Нажмите **Направить** на сообщении в очереди, чтобы внедрить это последующее сообщение в выполняющийся ход.
    - Введите `/stop` (или отдельные фразы прерывания, такие как `stop`, `stop action`, `stop run`, `stop openclaw`, `please stop`), чтобы прервать вне основного потока.
    - `chat.abort` поддерживает `{ sessionKey }` (без `runId`), чтобы прервать все активные запуски для этого сеанса.

  </Accordion>
  <Accordion title="Сохранение частичного результата при прерывании">
    - Когда запуск прерван, частичный текст ассистента все равно может отображаться в UI.
    - Gateway сохраняет прерванный частичный текст ассистента в историю транскрипта, когда существует буферизованный вывод.
    - Сохраненные записи включают метаданные прерывания, чтобы потребители транскрипта могли отличать частичные результаты прерывания от обычного вывода завершения.

  </Accordion>
</AccordionGroup>

## Установка PWA и web push

Control UI поставляется с `manifest.webmanifest` и service worker, поэтому современные браузеры могут устанавливать его как автономное PWA. Web Push позволяет Gateway пробуждать установленное PWA уведомлениями, даже когда вкладка или окно браузера не открыты.

Если страница показывает **Несоответствие протокола** сразу после обновления OpenClaw, сначала заново откройте панель с помощью `openclaw dashboard` и выполните жесткое обновление страницы. Если сбой сохраняется, очистите данные сайта для origin панели или проверьте в приватном окне браузера; старая вкладка или кэш service worker браузера может продолжать запускать набор Control UI до обновления против более нового Gateway.

| Поверхность                                           | Что она делает                                                       |
| ----------------------------------------------------- | ------------------------------------------------------------------ |
| `ui/public/manifest.webmanifest`                      | Манифест PWA. Браузеры предлагают «Установить приложение», когда он становится доступен.   |
| `ui/public/sw.js`                                     | Service worker, который обрабатывает события `push` и клики по уведомлениям. |
| `push/vapid-keys.json` (в каталоге состояния OpenClaw) | Автоматически созданная пара ключей VAPID, используемая для подписи полезных нагрузок Web Push.       |
| `push/web-push-subscriptions.json`                    | Сохраненные конечные точки подписок браузера.                          |

Переопределяйте пару ключей VAPID через переменные окружения процесса Gateway, когда нужно закрепить ключи (для развертываний на нескольких хостах, ротации секретов или тестов):

- `OPENCLAW_VAPID_PUBLIC_KEY`
- `OPENCLAW_VAPID_PRIVATE_KEY`
- `OPENCLAW_VAPID_SUBJECT` (по умолчанию `https://openclaw.ai`)

Control UI использует эти методы Gateway, ограниченные областью доступа, для регистрации и тестирования браузерных подписок:

- `push.web.vapidPublicKey` — получает активный публичный ключ VAPID.
- `push.web.subscribe` — регистрирует `endpoint` плюс `keys.p256dh`/`keys.auth`.
- `push.web.unsubscribe` — удаляет зарегистрированную конечную точку.
- `push.web.test` — отправляет тестовое уведомление в подписку вызывающей стороны.

<Note>
Web Push не зависит от пути ретрансляции iOS APNS (см. [Конфигурация](/ru/gateway/configuration) для push через ретранслятор) и существующего метода `push.test`, которые предназначены для нативного сопряжения с мобильными устройствами.
</Note>

## Встроенные размещенные элементы

Сообщения ассистента могут отображать размещенный веб-контент встроенно с помощью шорткода `[embed ...]`. Политика песочницы iframe управляется параметром `gateway.controlUi.embedSandbox`:

<Tabs>
  <Tab title="strict">
    Отключает выполнение скриптов внутри размещенных встроенных элементов.
  </Tab>
  <Tab title="scripts (default)">
    Разрешает интерактивные встроенные элементы, сохраняя изоляцию origin; это значение по умолчанию и обычно его достаточно для автономных браузерных игр и виджетов.
  </Tab>
  <Tab title="trusted">
    Добавляет `allow-same-origin` поверх `allow-scripts` для документов того же сайта, которым намеренно нужны более сильные привилегии.
  </Tab>
</Tabs>

Пример:

```json5
{
  gateway: {
    controlUi: {
      embedSandbox: "scripts",
    },
  },
}
```

<Warning>
Используйте `trusted` только тогда, когда встроенному документу действительно нужно поведение same-origin. Для большинства игр и интерактивных canvas, созданных агентом, `scripts` — более безопасный выбор.
</Warning>

Абсолютные внешние URL встроенных элементов `http(s)` по умолчанию остаются заблокированными. Если вы намеренно хотите, чтобы `[embed url="https://..."]` загружал сторонние страницы, задайте `gateway.controlUi.allowExternalEmbedUrls: true`.

## Ширина сообщений чата

Сгруппированные сообщения чата используют удобную для чтения максимальную ширину по умолчанию. Развертывания на широких мониторах могут переопределить ее без исправления встроенного CSS, задав `gateway.controlUi.chatMessageMaxWidth`:

```json5
{
  gateway: {
    controlUi: {
      chatMessageMaxWidth: "min(1280px, 82%)",
    },
  },
}
```

Значение проверяется до того, как попадет в браузер. Поддерживаемые значения включают обычные длины и проценты, такие как `960px` или `82%`, а также ограниченные выражения ширины `min(...)`, `max(...)`, `clamp(...)`, `calc(...)` и `fit-content(...)`.

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

<Tabs>
  <Tab title="Integrated Tailscale Serve (preferred)">
    Оставьте Gateway на loopback и позвольте Tailscale Serve проксировать его через HTTPS:

    ```bash
    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 с заголовками Tailscale `x-forwarded-*`. Для операторских сессий Control UI с идентичностью браузерного устройства этот проверенный путь Serve также пропускает цикл сопряжения устройства; браузеры без устройства и подключения с ролью узла по-прежнему проходят обычные проверки устройства. Задайте `gateway.auth.allowTailscale: false`, если хотите требовать явные учетные данные общего секрета даже для трафика Serve. Затем используйте `gateway.auth.mode: "token"` или `"password"`.

    Для этого асинхронного пути идентификации Serve неудачные попытки аутентификации для того же IP клиента и области аутентификации сериализуются перед записями ограничения скорости. Поэтому параллельные неудачные повторы из того же браузера могут показать `retry later` во втором запросе вместо двух обычных несовпадений, выполняющихся параллельно.

    <Warning>
    Аутентификация Serve без токена предполагает, что хост gateway является доверенным. Если на этом хосте может выполняться недоверенный локальный код, требуйте аутентификацию по токену/паролю.
    </Warning>

  </Tab>
  <Tab title="Bind to tailnet + token">
    ```bash
    openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"
    ```

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

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

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

  </Tab>
</Tabs>

## Небезопасный 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)

<AccordionGroup>
  <Accordion title="Insecure-auth toggle behavior">
    ```json5
    {
      gateway: {
        controlUi: { allowInsecureAuth: true },
        bind: "tailnet",
        auth: { mode: "token", token: "replace-me" },
      },
    }
    ```

    `allowInsecureAuth` — это только локальный переключатель совместимости:

    - Он позволяет сессиям Control UI на localhost продолжаться без идентичности устройства в небезопасных HTTP-контекстах.
    - Он не обходит проверки сопряжения.
    - Он не ослабляет требования к идентичности устройства для удаленных (не localhost) подключений.

  </Accordion>
  <Accordion title="Break-glass only">
    ```json5
    {
      gateway: {
        controlUi: { dangerouslyDisableDeviceAuth: true },
        bind: "tailnet",
        auth: { mode: "token", token: "replace-me" },
      },
    }
    ```

    <Warning>
    `dangerouslyDisableDeviceAuth` отключает проверки идентичности устройства Control UI и является серьезным снижением безопасности. Быстро отмените его после аварийного использования.
    </Warning>

  </Accordion>
  <Accordion title="Trusted-proxy note">
    - Успешная аутентификация trusted-proxy может допускать **операторские** сессии Control UI без идентичности устройства.
    - Это **не** распространяется на сессии Control UI с ролью узла.
    - Reverse proxy на loopback того же хоста все равно не удовлетворяют аутентификации trusted-proxy; см. [Аутентификация trusted proxy](/ru/gateway/trusted-proxy-auth).

  </Accordion>
</AccordionGroup>

См. [Tailscale](/ru/gateway/tailscale) для рекомендаций по настройке HTTPS.

## Политика безопасности контента

Control UI поставляется со строгой политикой `img-src`: разрешены только ресурсы **same-origin**, URL `data:` и локально созданные URL `blob:`. Удаленные URL изображений `http(s)` и URL изображений с относительным протоколом отклоняются браузером и не выполняют сетевые запросы.

Что это означает на практике:

- Аватары и изображения, отдаваемые по относительным путям (например, `/avatars/<id>`), по-прежнему отображаются, включая аутентифицированные маршруты аватаров, которые UI загружает и преобразует в локальные URL `blob:`.
- Встроенные URL `data:image/...` по-прежнему отображаются (полезно для полезных нагрузок внутри протокола).
- Локальные 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`. Соберите их с помощью:

```bash
pnpm ui:build
```

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

```bash
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
```

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

```bash
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 панели управления после изменения браузера.

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

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

<Steps>
  <Step title="Start the UI dev server">
    ```bash
    pnpm ui:dev
    ```
  </Step>
  <Step title="Open with gatewayUrl">
    ```text
    http://localhost:5173/?gatewayUrl=ws%3A%2F%2F<gateway-host>%3A18789
    ```

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

    ```text
    http://localhost:5173/?gatewayUrl=wss%3A%2F%2F<gateway-host>%3A18789#token=<gateway-token>
    ```

  </Step>
</Steps>

<AccordionGroup>
  <Accordion title="Примечания">
    - `gatewayUrl` сохраняется в localStorage после загрузки и удаляется из URL.
    - Если вы передаете полный endpoint `ws://` или `wss://` через `gatewayUrl`, URL-кодируйте значение `gatewayUrl`, чтобы браузер правильно разобрал строку запроса.
    - `token` по возможности следует передавать через фрагмент URL (`#token=...`). Фрагменты не отправляются на сервер, что предотвращает утечки через журналы запросов и Referer. Устаревшие параметры запроса `?token=` по-прежнему однократно импортируются для совместимости, но только как fallback, и сразу удаляются после bootstrap.
    - `password` хранится только в памяти.
    - Когда задан `gatewayUrl`, UI не выполняет fallback к учетным данным из конфигурации или окружения. Явно укажите `token` (или `password`). Отсутствие явно заданных учетных данных является ошибкой.
    - Используйте `wss://`, когда Gateway находится за TLS (Tailscale Serve, HTTPS-прокси и т. д.).
    - `gatewayUrl` принимается только в окне верхнего уровня (не во встроенном), чтобы предотвратить clickjacking.
    - Публичные развертывания Control UI вне loopback должны явно задавать `gateway.controlUi.allowedOrigins` (полные origins). Частные загрузки из той же origin в LAN/Tailnet с loopback, RFC1918/link-local, `.local`, `.ts.net` или хостов Tailscale CGNAT принимаются без включения fallback по заголовку Host.
    - При запуске Gateway может добавлять локальные origins, такие как `http://localhost:<port>` и `http://127.0.0.1:<port>`, на основе фактических bind и port времени выполнения, но origins удаленных браузеров все равно требуют явных записей.
    - Не используйте `gateway.controlUi.allowedOrigins: ["*"]`, кроме строго контролируемого локального тестирования. Это означает разрешить любую browser origin, а не «соответствовать тому хосту, который я использую».
    - `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true` включает режим fallback по origin из заголовка Host, но это опасный режим безопасности.

  </Accordion>
</AccordionGroup>

Пример:

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

Подробности настройки удаленного доступа: [Удаленный доступ](/ru/gateway/remote).

## См. также

- [Панель мониторинга](/ru/web/dashboard) — панель мониторинга Gateway
- [Проверки работоспособности](/ru/gateway/health) — мониторинг работоспособности Gateway
- [TUI](/ru/web/tui) — терминальный пользовательский интерфейс
- [WebChat](/ru/web/webchat) — браузерный интерфейс чата
