Control UI (przeglądarka)
Control UI to niewielka aplikacja jednostronicowa Vite + Lit serwowana przez Gateway:- domyślnie:
http://<host>:18789/ - opcjonalny prefiks: ustaw
gateway.controlUi.basePath(np./openclaw)
Szybkie otwarcie (lokalnie)
Jeśli Gateway działa na tym samym komputerze, otwórz: Jeśli strona się nie ładuje, najpierw uruchom Gateway:openclaw gateway.
Auth jest dostarczane podczas handshake WebSocket przez:
connect.params.auth.tokenconnect.params.auth.password- nagłówki tożsamości Tailscale Serve, gdy
gateway.auth.allowTailscale: true - nagłówki tożsamości trusted-proxy, gdy
gateway.auth.mode: "trusted-proxy"
gateway.auth.mode ma wartość "password".
Parowanie urządzenia (pierwsze połączenie)
Gdy łączysz się z Control UI z nowej przeglądarki albo urządzenia, Gateway wymaga jednorazowego zatwierdzenia parowania — nawet jeśli jesteś w tym samym tailnet zgateway.auth.allowTailscale: true. To środek bezpieczeństwa zapobiegający
nieautoryzowanemu dostępowi.
Co zobaczysz: „disconnected (1008): pairing required”
Aby zatwierdzić urządzenie:
requestId. Przed zatwierdzeniem
ponownie uruchom openclaw devices list.
Po zatwierdzeniu urządzenie jest zapamiętywane i nie będzie wymagało ponownego zatwierdzenia,
chyba że je odwołasz przez openclaw devices revoke --device <id> --role <role>. Zobacz
Devices CLI, aby poznać rotację tokenów i odwoływanie.
Uwagi:
- Bezpośrednie lokalne połączenia przeglądarki przez loopback (
127.0.0.1/localhost) są zatwierdzane automatycznie. - Połączenia przeglądarki przez tailnet i LAN nadal wymagają jawnego zatwierdzenia, nawet gdy pochodzą z tej samej maszyny.
- Każdy profil przeglądarki generuje unikalny identyfikator urządzenia, więc zmiana przeglądarki albo wyczyszczenie danych przeglądarki będzie wymagało ponownego parowania.
Obsługa języków
Control UI może lokalizować się przy pierwszym wczytaniu na podstawie ustawień regionalnych przeglądarki, a później można to nadpisać z selektora języka na karcie Access.- Obsługiwane locale:
en,zh-CN,zh-TW,pt-BR,de,es - Tłumaczenia inne niż angielskie są leniwie ładowane w przeglądarce.
- Wybrane locale jest zapisywane w pamięci przeglądarki i ponownie używane przy kolejnych wizytach.
- Brakujące klucze tłumaczeń wracają do angielskiego.
Co potrafi (obecnie)
- Czat z modelem przez Gateway WS (
chat.history,chat.send,chat.abort,chat.inject) - Strumieniowanie wywołań narzędzi + karty z wyjściem narzędzi na żywo w czacie (zdarzenia agenta)
- Kanały: status wbudowanych oraz dołączonych/zewnętrznych kanałów wtyczek, logowanie QR i konfiguracja per kanał (
channels.status,web.login.*,config.patch) - Instancje: lista presence + odświeżanie (
system-presence) - Sesje: lista + nadpisania modelu/thinking/fast/verbose/reasoning per sesja (
sessions.list,sessions.patch) - Zadania cron: lista/dodawanie/edycja/uruchamianie/włączanie/wyłączanie + historia uruchomień (
cron.*) - Skills: status, włączanie/wyłączanie, instalacja, aktualizacje kluczy API (
skills.*) - Nody: lista + capabilities (
node.list) - Exec approvals: edycja allowlist gateway albo noda + polityka ask dla
exec host=gateway/node(exec.approvals.*) - Konfiguracja: podgląd/edycja
~/.openclaw/openclaw.json(config.get,config.set) - Konfiguracja: zastosowanie + restart z walidacją (
config.apply) i wybudzenie ostatniej aktywnej sesji - Zapisy konfiguracji zawierają ochronę base-hash, aby zapobiec nadpisaniu równoległych edycji
- Zapisy konfiguracji (
config.set/config.apply/config.patch) wykonują też preflight rozwiązywania aktywnych SecretRef dla refów w przesłanym payloadzie konfiguracji; nierozwiązane aktywne przesłane refy są odrzucane przed zapisem - Schemat konfiguracji + renderowanie formularzy (
config.schema/config.schema.lookup, w tym poletitle/description, dopasowane podpowiedzi UI, podsumowania bezpośrednich dzieci, metadane dokumentacji dla zagnieżdżonych obiektów/wildcardów/tablic/węzłów złożonych, a także schematy wtyczek i kanałów, gdy są dostępne); edytor Raw JSON jest dostępny tylko wtedy, gdy migawka ma bezpieczny raw round-trip - Jeśli migawki nie da się bezpiecznie odtworzyć jako surowego tekstu, Control UI wymusza tryb formularza i wyłącza Raw mode dla tej migawki
- Ustrukturyzowane wartości obiektów SecretRef są renderowane jako tylko do odczytu w polach tekstowych formularza, aby zapobiec przypadkowemu uszkodzeniu obiektu przez konwersję do stringa
- Debugowanie: migawki status/health/models + log zdarzeń + ręczne wywołania RPC (
status,health,models.list) - Logi: live tail logów plikowych gateway z filtrowaniem/eksportem (
logs.tail) - Aktualizacja: uruchamianie aktualizacji pakietu/git + restart (
update.run) z raportem restartu
- Dla zadań izolowanych domyślnym sposobem dostarczania jest ogłoszenie podsumowania. Możesz przełączyć na none, jeśli chcesz tylko uruchomienia wewnętrzne.
- Gdy wybrane jest announce, pojawiają się pola kanału/celu.
- Tryb webhook używa
delivery.mode = "webhook"zdelivery.toustawionym na prawidłowy URL webhooka HTTP(S). - Dla zadań głównej sesji dostępne są tryby dostarczania webhook i none.
- Zaawansowane opcje edycji obejmują delete-after-run, wyczyszczenie nadpisania agenta, opcje dokładnego/stagger cron, nadpisania modelu/thinking agenta oraz przełączniki best-effort delivery.
- Walidacja formularza jest inline z błędami na poziomie pól; nieprawidłowe wartości wyłączają przycisk zapisu, dopóki nie zostaną poprawione.
- Ustaw
cron.webhookToken, aby wysyłać dedykowany bearer token; jeśli pole jest pominięte, webhook jest wysyłany bez nagłówka auth. - Deprecated fallback: zapisane starsze zadania z
notify: truenadal mogą używaćcron.webhook, dopóki nie zostaną zmigrowane.
Zachowanie czatu
chat.sendjest nieblokujące: natychmiast zwraca potwierdzenie{ runId, status: "started" }, a odpowiedź jest strumieniowana przez zdarzeniachat.- Ponowne wysłanie z tym samym
idempotencyKeyzwraca{ status: "in_flight" }podczas działania oraz{ status: "ok" }po zakończeniu. - Odpowiedzi
chat.historymają ograniczony rozmiar dla bezpieczeństwa UI. Gdy wpisy transkryptu są zbyt duże, Gateway może obcinać długie pola tekstowe, pomijać ciężkie bloki metadanych i zastępować zbyt duże wiadomości placeholderem ([chat.history omitted: message too large]). chat.historyusuwa też z widocznego tekstu asystenta tagi inline służące tylko do wyświetlania (na przykład[[reply_to_*]]i[[audio_as_voice]]), tekstowe payloady XML wywołań narzędzi (w tym<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>oraz obcięte bloki wywołań narzędzi), a także wyciekłe tokeny sterujące modelem w ASCII/pełnej szerokości, i pomija wpisy asystenta, których cały widoczny tekst to dokładnie cichy tokenNO_REPLY/no_reply.chat.injectdopisuje notatkę asystenta do transkryptu sesji i rozgłasza zdarzeniechatdla aktualizacji tylko po stronie UI (bez uruchomienia agenta, bez dostarczenia do kanału).- Selektory modelu i thinking w nagłówku czatu natychmiast patchują aktywną sesję przez
sessions.patch; są to trwałe nadpisania sesji, a nie opcje wysyłki tylko na jedną turę. - Stop:
- Kliknij Stop (wywołuje
chat.abort) - Wpisz
/stop(albo samodzielne frazy przerwania, takie jakstop,stop action,stop run,stop openclaw,please stop), aby przerwać poza pasmem chat.abortobsługuje{ sessionKey }(bezrunId) do przerywania wszystkich aktywnych uruchomień dla tej sesji
- Kliknij Stop (wywołuje
- Zachowanie częściowych danych po przerwaniu:
- Gdy uruchomienie zostanie przerwane, częściowy tekst asystenta może nadal być pokazany w UI
- Gateway utrwala częściowy tekst asystenta po przerwaniu w historii transkryptu, gdy istnieje zbuforowane wyjście
- Utrwalone wpisy zawierają metadane przerwania, dzięki czemu konsumenci transkryptu mogą odróżnić części po przerwaniu od normalnie zakończonego wyjścia
Dostęp przez tailnet (zalecany)
Zintegrowane Tailscale Serve (preferowane)
Pozostaw Gateway na loopback i pozwól Tailscale Serve proxywać go przez HTTPS:https://<magicdns>/(albo skonfigurowanegateway.controlUi.basePath)
tailscale-user-login), gdy gateway.auth.allowTailscale ma wartość true. OpenClaw
weryfikuje tożsamość, rozwiązując adres x-forwarded-for przez
tailscale whois i dopasowując go do nagłówka, i akceptuje takie żądania tylko wtedy, gdy
trafiają na loopback z nagłówkami x-forwarded-* Tailscale. Ustaw
gateway.auth.allowTailscale: false, jeśli chcesz wymagać jawnych poświadczeń opartych na współdzielonym sekrecie
nawet dla ruchu Serve. Następnie użyj gateway.auth.mode: "token" albo
"password".
Dla tej asynchronicznej ścieżki tożsamości Serve nieudane próby auth dla tego samego IP klienta
i tego samego zakresu auth są serializowane przed zapisem ograniczenia szybkości. Równoległe błędne próby
z tej samej przeglądarki mogą więc przy drugim żądaniu pokazać retry later
zamiast dwóch zwykłych niedopasowań ścigających się równolegle.
Auth Serve bez tokena zakłada, że host gateway jest zaufany. Jeśli na tym hoście
może działać niezaufany kod lokalny, wymagaj auth tokenem/hasłem.
Bind do tailnet + token
http://<tailscale-ip>:18789/(albo skonfigurowanegateway.controlUi.basePath)
connect.params.auth.token albo connect.params.auth.password).
Niezabezpieczone HTTP
Jeśli otwierasz dashboard przez zwykłe HTTP (http://<lan-ip> albo http://<tailscale-ip>),
przeglądarka działa w niebezpiecznym kontekście i blokuje WebCrypto. Domyślnie
OpenClaw blokuje połączenia Control UI bez tożsamości urządzenia.
Udokumentowane wyjątki:
- zgodność localhost-only dla niezabezpieczonego HTTP z
gateway.controlUi.allowInsecureAuth=true - pomyślne auth operatora Control UI przez
gateway.auth.mode: "trusted-proxy" - awaryjne
gateway.controlUi.dangerouslyDisableDeviceAuth=true
https://<magicdns>/(Serve)http://127.0.0.1:18789/(na hoście gateway)
allowInsecureAuth to tylko lokalny przełącznik zgodności:
- Pozwala sesjom localhost Control UI kontynuować bez tożsamości urządzenia w niezabezpieczonych kontekstach HTTP.
- Nie omija kontroli parowania.
- Nie osłabia wymagań tożsamości urządzenia dla połączeń zdalnych (spoza localhost).
dangerouslyDisableDeviceAuth wyłącza sprawdzanie tożsamości urządzenia w Control UI i jest
poważnym obniżeniem bezpieczeństwa. Po użyciu awaryjnym szybko cofnij tę zmianę.
Uwaga o trusted-proxy:
- pomyślne auth trusted-proxy może dopuścić sesje Control UI operatora bez tożsamości urządzenia
- to nie dotyczy sesji Control UI z rolą node
- reverse proxy na tym samym hoście przez loopback nadal nie spełniają wymagań auth trusted-proxy; zobacz Trusted Proxy Auth
Budowanie UI
Gateway serwuje pliki statyczne zdist/control-ui. Zbuduj je przez:
ws://127.0.0.1:18789).
Debugowanie/testowanie: serwer dev + zdalny Gateway
Control UI to pliki statyczne; docelowy WebSocket jest konfigurowalny i może być inny niż pochodzenie HTTP. Jest to przydatne, gdy chcesz mieć lokalny serwer Vite dev, ale Gateway działa gdzie indziej.- Uruchom serwer dev UI:
pnpm ui:dev - Otwórz URL w rodzaju:
gatewayUrljest po załadowaniu zapisywany w localStorage i usuwany z URL.tokenpowinien być przekazywany przez fragment URL (#token=...), gdy tylko to możliwe. Fragmenty nie są wysyłane do serwera, co zapobiega wyciekom do logów żądań i Referer. Starsze parametry query?token=są nadal jednokrotnie importowane dla zgodności, ale tylko jako fallback, i są natychmiast usuwane po bootstrapie.passwordjest przechowywane tylko w pamięci.- Gdy ustawiono
gatewayUrl, UI nie wraca do poświadczeń z konfiguracji ani środowiska. Przekaż jawnietoken(albopassword). Brak jawnych poświadczeń to błąd. - Używaj
wss://, gdy Gateway znajduje się za TLS (Tailscale Serve, HTTPS proxy itd.). gatewayUrljest akceptowany tylko w oknie najwyższego poziomu (nie osadzonym), aby zapobiec clickjackingowi.- Wdrożenia Control UI poza loopback muszą jawnie ustawić
gateway.controlUi.allowedOrigins(pełne originy). Obejmuje to również zdalne konfiguracje deweloperskie. - Nie używaj
gateway.controlUi.allowedOrigins: ["*"], chyba że do ściśle kontrolowanych lokalnych testów. Oznacza to „zezwól na dowolny origin przeglądarki”, a nie „dopasuj dowolny host, którego używam”. gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=truewłącza tryb fallbacku origin oparty na nagłówku Host, ale jest to niebezpieczny tryb bezpieczeństwa.
Powiązane
- Dashboard — dashboard gateway
- WebChat — interfejs czatu oparty na przeglądarce
- TUI — terminalowy interfejs użytkownika
- Health Checks — monitorowanie stanu gateway