Przejdź do głównej zawartości

Rigi

Tylko fakty. Model, który za nimi stoi, opisuje Rigi i izolacje; aby otworzyć maszynę, skorzystaj z poradnika.

Powierzchnia Czym steruje Backend Wartość Ruch wychodzący w izolacji
Terminal (exec) Powłoka przez kanał exec VM microVM smolvm Tak
Przeglądarka Chromium bez interfejsu (CDP), Firefox (WebDriver BiDi) albo WebKit (W3C WebDriver) microVM smolvm Tak
Komputer Pulpit X11: dane wejściowe przez hypervisor, przechwytywanie przez agenta systemu gościa QEMU qemu-hvf (macOS), qemu-kvm (Linux), qemu-tcg (awaryjny tryb bez akceleracji, nigdy nie wybierany automatycznie) Tak
Android Android przez ADB Emulator Google’a android-emulator Nie — emulator sam zarządza swoją siecią
iOS Symulator iOS przez WebDriverAgent CoreSimulator ios-simulator Nie — sieć działa przez hosta Mac

Terminal i powierzchnia computer_use dzielą wartość powierzchni computer; terminal wyróżnia znacznik obrazu exec i nigdy nie jest ponownie używany jako sterowalny pulpit (ani odwrotnie). Jedna rozmowa ponownie używa jednej maszyny terminala.

Silnik Wartość Protokół Podgląd na żywo Klatki
Chromium chromium (domyślnie) Chrome DevTools Protocol Transmisja obrazu — przeglądarka wypycha klatki, gdy strona się przerysowuje JPEG
Firefox firefox WebDriver BiDi Odpytywane klatki (BiDi nie ma transmisji obrazu), maks. 6 fps JPEG
WebKit webkit W3C WebDriver (klasyczny) Odpytywane klatki, transkodowane przez ffmpeg hosta PNG

Rig działa na jednym silniku przez całe swoje życie. Jedna rozmowa może mieć po jednym rigu na silnik, co właśnie umożliwia porównanie obok siebie: otwarcie „Firefox (VM)” obok „Chromium (VM)” to dwie maszyny, a zamknięcie jednej zostawia drugą w działaniu.

Przekaż engine do rig.open albo do narzędzia browser_use. Nieznana nazwa jest odrzucana, a nie zastępowana domyślną — proszenie o przeglądarkę i ciche dostanie innej odpowiada na pytanie o zgodność błędną odpowiedzią.

Ograniczenia poszczególnych silników, nazwane wprost, a nie obchodzone:

  • Firefox nie ma przeładowania z pominięciem pamięci podręcznej (odrzuca wprost ignoreCache z BiDi), więc twarde przeładowanie to zwykłe przeładowanie.
  • WebKit też nie ma przeładowania z pominięciem pamięci podręcznej ani kanału konsoli (dane wyjściowe są przechwytywane przez podpięcie się do console.* po każdej nawigacji, więc wszystko zalogowane podczas ładowania zostaje pominięte — każdy wyciąg z konsoli tak mówi), a do podglądu na żywo potrzebuje ffmpeg na hoście.
  • Żaden z nich nie udostępnia przez swój protokół drzewa dostępności platformy, więc extract (a11y) zwraca przybliżenie wywiedzione z DOM, oznaczone jako takie.
  • Żaden z nich nie potrafi przyjąć prawdziwego upuszczenia pliku; pole pliku nadal można wskazać na ścieżki wewnątrz maszyny.
Powierzchnia Obraz Pobieranie
Terminal ubuntu:24.04, przypięty skrótem Automatycznie przy pierwszym uruchomieniu, przez własną, ograniczoną bramę sieciową maszyny
Przeglądarka (Chromium, Firefox, WebKit) debian:trixie-slim, przypięty skrótem, plus własne pakiety silnika Automatycznie przy pierwszym uruchomieniu, a następnie buforowany jako rozgrzany pakiet
Komputer Obraz pulpitu qcow2 z Chromium, Firefoksem, WebKitem i tym samym bazowym zestawem CLI w rodzaju runnerów hostowanych na GitHubie, który rozgrzewa terminal Importuj w Ustawienia → Serwer → Rigi (pobierania przypięte sumą kontrolną, gdy są opublikowane)
Android Obrazy systemowe Google’a Przez Android SDK
iOS Środowisko uruchomieniowe symulatora Xcode oraz WebDriverAgent przypięty sumą kontrolną Środowisko uruchomieniowe przez Xcode; most automatyzacji z Ustawienia → Serwer → Rigi

Po pierwszym uruchomieniu każdego rodzaju microVM serwer buforuje wcześniej rozpakowaną kopię w katalogu danych i uruchamia z niej każdą późniejszą maszynę — również wcześniej rozgrzane obrazy z już zainstalowanymi pakietami. Terminal rozgrzewa zestaw narzędzi CLI w stylu runnerów hostowanych na GitHubie (git, gcc, python3, jq, rsync, narzędzia archiwizujące i resztę bazy apt; nie Docker ani pamięci podręczne narzędzi językowych). Obraz qcow2 powierzchni Komputer zawiera te same nazwy CLI już na etapie budowania obrazu, obok XFCE i trzech przeglądarek. Każda przeglądarka rozgrzewa swój silnik. Wszystkie trzy silniki dzielą bazę Debiana, ale nigdy nie dzielą pakietu: pamięć podręczna jest kluczowana obrazem, silnikiem oraz rewizją audio (audio-v1-<engine>), bo maszyna rozgrzana dla jednego silnika — albo przed dodaniem PulseAudio i ffmpeg do obciążenia — nie ma w sobie nic z pozostałych. Pakiet terminala jest kluczowany rewizją zestawu narzędzi (tools-v1) z tego samego powodu: pakiet rozgrzany, zanim kompilator był częścią obrazu, nie może obsłużyć maszyny, która ma go zawierać.

Nie ma gotowego obrazu automatyzacji, który warto by brać — chromedp/headless-shell Chromium wycina kompilacją i ALSA, i PulseAudio, więc nigdy nie wyda dźwięku; jedyny utrzymywany obraz dla Firefoksa jest 33× większy od bazy Debiana i nadal nie zawiera socat; utrzymywanego obrazu dla WebKita nie ma w ogóle. Dlatego każdy silnik instaluje się przy pierwszym starcie (chromium, firefox-esr albo webkit2gtk-driver) i przy okazji sięga do archiwów Debiana (deb.debian.org, security.debian.org, cloudfront.debian.net). Chromium to plik binarny z dystrybucji, uruchamiany jako chromium --headless=new.

Klucz ustawienia Co nadpisuje
rigs.smolvm.execImage Obraz terminala (VM)
rigs.smolvm.browserImage Obraz przeglądarki (VM)

Zapisywane przez magazyn ustawień obszaru roboczego, dostępny tylko dla administratorów (Ustawienia → Serwer → Rigi → Obrazy niestandardowe (ten obszar roboczy)). Wartość musi być odniesieniem do rejestru — ścieżki lokalne, archiwa i ciągi wyglądające na flagi są odrzucane, zarówno w polu, jak i ponownie przy starcie. Nieprawidłowa zapisana wartość jest głośno ignorowana, a zamiast niej uruchamia się obraz domyślny. Własny rejestr obrazu (plus znane towarzyszące CDN-y blobów dla Docker Hub, GHCR, Quay, GitLab i GCR) jest dopuszczany przez bramę ruchu wychodzącego na czas pobierania.

Kontrakt obrazu terminala — obecny bash; git, curl, socat zainstalowane wstępnie albo baza apt Debiana/Ubuntu (środowisko odizolowane instaluje te trzy plus zestaw narzędzi CLI w stylu runnerów hostowanych na GitHubie przy pierwszym starcie: kompilatory, Python 3, jq, narzędzia archiwizujące, rsync. Pamięci podręczne narzędzi językowych i Docker nie są instalowane).

Kontrakt obrazu przeglądarki — baza apt Debiana/Ubuntu (albo pakiety już zainstalowane) z bash i socat, plus plik binarny chromium, który serwer uruchamia sam jako chromium --headless=new, z DevTools na pętli zwrotnej systemu gościa 9223, przekazywanymi na port 9222 systemu gościa. PulseAudio i ffmpeg są instalowane przy pierwszym starcie na potrzeby toru audio. Nie buduj obrazu FROM chromedp/headless-shell: headless.gn upstream wycina kompilacją i ALSA, i PulseAudio, więc ten plik binarny nie może wydać dźwięku. Nadpisanie dotyczy tylko rigów Chromium — polecenie obciążenia, które uruchamia, należy do Chromium, a przekazanie go Firefoksowi albo WebKitowi uruchomiłoby plik binarny, którego tam nie ma. Rig Firefoksa albo WebKita głośno je ignoruje i uruchamia swój przypięty obraz.

Porty automatyzacji — każda maszyna przeglądarki przekierowuje dokładnie jeden port pętli zwrotnej hosta na port 9222 systemu gościa. Za nim: DevTools Chromium i zdalny agent Firefoksa siedzą na pętli zwrotnej systemu gościa 9223, a przed nimi działa przekaz socat (oba bezwarunkowo wiążą pętlę zwrotną); sterownik WebKita przyjmuje --host i sam wiąże kartę sieciową systemu gościa. Firefox dodatkowo weryfikuje nagłówek Host względem swojego własnego portu, więc klient wysyła autorytet strony systemu gościa, a nie ten, z którym się połączył.

Każde działanie jest parsowane w całości: błędny ładunek zwraca komunikat wskazujący pole, nigdy wyjątek. Czasowniki obserwacyjne (oznaczone ○) pozostają dozwolone, gdy kontrolę trzyma człowiek; czasowniki modyfikujące są odrzucane.

screenshot○, cursor_position○, mouse_move, left_click, right_click, middle_click, double_click, triple_click, left_mouse_down, left_mouse_up, left_click_drag, scroll, key, hold_key (0–60 s), type, wait○ (0–60 s), set_display, clipboard_read○, clipboard_write.

Współrzędne to piksele systemu gościa w jego bieżącym trybie; każdy zrzut ekranu podaje rozmiar ekranu. Kombinacje klawiszy używają zapisu X11 (ctrl+s, alt+Tab, Return).

clipboard_read przyjmuje selection: clipboard (to, co wypełnia ctrl+C, domyślnie), primary (zaznacz-i-kopiuj X11) albo xdnd (przeciąganie w toku). Pusty wynik jest normalną odpowiedzią dla wszystkich trzech. clipboard_write przyjmuje tylko text — obrazy i pliki jadą torem plików, bo argumenty działania są zapisywane w dzienniku audytu, a bajty obrazów nie mają tam czego szukać. Treść schowka wraca ogrodzona jako dane niezaufane.

navigate (tylko http/https), reload (opcjonalny hard), stop_loading, click (selektor albo współrzędne), fill, type, key (nazwy klawiszy DOM), scroll, mouse_move, drag, left_mouse_down, left_mouse_up, extract○ (a11y | dom | console), screenshot○ (opcjonalny full_page), set_viewport (min. 320×240), history, wait_for○ (selektor, 0,1–30 s), clipboard_read○, clipboard_write.

Wyekstrahowana treść strony wraca ogrodzona jako dane niezaufane.

Przeglądarka ma dokładnie jeden schowek, więc clipboard_read nie przyjmuje selection. Oba czasowniki schowka wymagają bezpiecznego kontekstu: strona serwowana po zwykłym http:// nie ma w ogóle API schowka, a czasownik to mówi, zamiast zgłaszać pusty schowek — użyj tam type, który wstawia tekst w miejscu kursora, nie przechodząc przez schowek.

tap, swipe (50–5000 ms), type, key (aliasy back, home, recents, enter, delete, backspace, tab, escape, search, menu, volume_up, volume_down, power albo dowolny KEYCODE_*), screenshot○, ui_dump○, install_apk (ograniczony do worktree riga i katalogu danych serwera), start_app, stop_app, clear_app_data, uninstall_app, open_url oraz shell. shell przyjmuje listę argv i działa wewnątrz Androida, nigdy przez powłokę hosta; obejmuje diagnostykę deweloperską, taką jak logcat, dumpsys i pm grant.

mobile_use nie ma czasowników schowka. Od Androida 10 tylko aplikacja z fokusem może czytać schowek.

tap, swipe (50–5000 ms), type, key (enter, backspace, tab, escape, klawisze strzałek albo jeden znak drukowalny; opcjonalne modyfikatory command, control, option i shift), home, lock, unlock, screenshot○, ui_dump○, install_app (katalog .app symulatora ograniczony do worktree riga albo katalogu danych serwera), start_app, stop_app, uninstall_app, open_url oraz spawn. spawn przyjmuje argv i wykonuje się wewnątrz symulatora przez simctl; nigdy nie wywołuje powłoki hosta.

Współrzędne to punkty ekranu iOS, a nie piksele zrzutu ekranu. Strumień na żywo zachowuje stały rozmiar symulatora i dodaje pasy, zamiast zmieniać rozmiar urządzenia. Transfer tekstu przez schowek z hosta do symulatora i z symulatora na host podlega tej samej polityce uprawnień dla każdego użytkownika i każdego kierunku co w innych rigach; pliki i obrazy nie są przyjmowane przez tor schowka iOS.

Każdy rig tworzy własne urządzenie CoreSimulator i sesję WebDriverAgent. Zamknięcie go zatrzymuje WebDriverAgent, wyłącza i usuwa to urządzenie oraz usuwa jego wpis w rejestrze. Rigi iOS działają tylko na serwerze macOS z Xcode, zainstalowanym środowiskiem uruchomieniowym iOS i przypiętym mostem automatyzacji. Nie udostępniają dźwięku, mikrofonu, upuszczania plików, powłoki hosta ani gwarancji izolacji sieci.

Narzędzie Opis
rig_list Wyświetla listę rigów obszaru roboczego z powierzchnią, stanem, wyświetlaczem i kontrolerem
rig_close Niszczy rig i odrzuca jego dysk
Faza Znaczenie
provisioning Uruchamianie; szczegóły stanu podają bieżący krok dosłownie
ready Osiągalny i przyjmuje działania
parked Zaparkowany z powodu bezczynności: vCPU zatrzymane, pamięć RAM nadal zajęta; budzi go następne działanie
closing Wyłączanie
closed Zniknął; wiersz pozostaje na potrzeby dziennika audytu
failed Padł albo nigdy nie wystartował; odróżnialny, żeby interfejs mógł zaproponować ponowną próbę
Powód zamknięcia Kiedy występuje
requested Poprosiła o to osoba albo agent
idleTimeout Bezczynność dłuższa niż 2× okno bezczynności albo usunięcie z powodu pamięci
ttlExpired Skończył się twardy czas życia
conversationEnded Zakończyła się rozmowa będąca właścicielem
workspaceGone Obszar roboczy został usunięty albo utracono członkostwo
serverShutdown Serwer się zatrzymuje
backendFailure Hypervisor padł pod nim
Wartość Terminal Przeglądarka Komputer Mobilne
Pamięć 512 MB 2048 MB (Chromium); 2560 MB (Firefox, WebKit) 4096 MB 4096 MB
vCPU 2 2 4 4
Twardy TTL 8 h 2 h 2 h 2 h
Okno bezczynności 45 min 15 min 15 min 15 min
Wyświetlacz przy starcie — 1280×800 1280×800 1080×1920
  • Klatki toru agenta są ograniczone do 1280×800; tor człowieka negocjuje do 2560×1600.
  • Budżet pamięci rezydentnej hosta dla wszystkich rigów domyślnie wynosi 12 GB i jest liczony w megabajtach rezydentnych (zaparkowana VM nadal trzyma swoją pamięć RAM). Usuwanie odbywa się według zasady najdawniej używanych i nigdy nie zabiera maszyny, którą ktoś steruje, na którą patrzy albo w której ma otwarty terminal.
  • Otwarty terminal albo tor podglądu przypina rig, chroniąc go przed zaparkowaniem i sprzątaniem bezczynnych maszyn; twardy TTL nadal obowiązuje.
Port Gdzie Zarezerwowany dla
7911 System gościa terminala Multiplekser portów, przez który przechodzi każde przekierowanie
9222, 9223 System gościa przeglądarki Przekaz i punkt końcowy automatyzacji (WebKit wiąże 9222 bezpośrednio i nie używa przekazu)
80, 443 Pętla zwrotna systemu gościa przeglądarki Tory HTTP/HTTPS domen deweloperskich
  • Wykrywanie odpytuje nasłuchujące porty TCP systemu gościa terminala co ~4 s, po stronie serwera.
  • Na rig automatycznie przekierowywanych jest najwyżej 16 portów; pozostałe są wypisywane w dzienniku, ale nieprzekierowywane.
  • Przekierowanie po stronie hosta wiąże pętlę zwrotną, preferując własny numer portu systemu gościa; Udostępnij w sieci lokalnej dodaje port LAN przydzielony przez system.
  • Domeny deweloperskie muszą pasować do name.test albo name.localhost (małe litery, etykieta maks. 63 znaki). Jedna domena mapuje się na jeden port.
  • HTTPS domen deweloperskich używa lokalnego na serwerze urzędu certyfikacji (EC P-256, w <dataDir>/rigs/tls/, klucze 0600 i nigdy w systemie gościa) z jednym certyfikatem wieloznacznym dla *.test / *.localhost. Brak openssl na hoście oznacza brak toru HTTPS; zwykły HTTP nadal działa.
Powierzchnia Domyślna lista dozwolonych
Terminal Bazowy zestaw deweloperski sandboxa (hosty kodu, rejestry pakietów, dostawcy modeli) + mirrory apt Ubuntu + własny host kodu danego worktree
Przeglądarka usectrl.dev (witryna produktu) — plus archiwa Debiana przy pierwszym starcie każdego silnika, gdy instaluje on swoje pakiety. Strona główna to lokalny dokument file:// i nie potrzebuje ruchu wychodzącego
Komputer Pusta — wszystko odrzucane — dopóki wywołujący nie dopuści hostów
Mobilne Niewymuszane (siecią zarządza emulator)

Każdy microVM dostaje dodatkowo hosty rejestru swojego obrazu, wyłącznie na czas pobierania. Zbiór dozwolonych hostów brokera poświadczeń pochodzi z tej samej listy dozwolonych: żaden token nie zostanie wystawiony dla hosta, którego system gościa nie może osiągnąć.

Kopiowanie i wklejanie w obie strony oraz przeciąganie plików do środka i na zewnątrz. Dostępne dla osoby sterującej rigiem; agent dostaje schowek przez powyższe czasowniki, a transferu plików nie dostaje wcale (ma już powłokę wewnątrz środowiska odizolowanego).

Przekraczanie schowka jest osobne dla każdego użytkownika i każdego kierunku. Wklejanie z hosta do riga jest domyślnie dozwolone; kopiowanie z riga na host pyta (dziesięciominutowe zezwolenie albo Zawsze zezwalaj w Ustawienia → Serwer → Rigi → Dostęp do schowka). Te dwa wybory są niezależne i nigdy nie są ustawieniem obszaru roboczego.

Tor Trasa Co przenosi
Schowek GET/POST /rig/clipboard/<rigId> Tekst, jeden plik PNG/JPEG (≤16 MB) i ścieżki plików w schowku po stronie systemu gościa
Pliki POST /rig/files/<rigId> Do 64 plików, każdy ≤256 MB i ≤512 MB na jedno upuszczenie, z opcjonalnym punktem upuszczenia w pikselach systemu gościa
Pliki GET /rig/files/<rigId>?p=<base64url path> Bajty jednego pliku, na zewnątrz
  • HTTP, nie RPC. Gniazdo RPC zamyka połączenie przy przychodzącej ramce większej niż 256 KB — zabezpieczenie przed DoS, właściwe dla poleceń JSON, a zabójcze dla wklejonego zrzutu ekranu. Bajty jadą taką samą trasą, jaką już wykorzystują klatki rigów i dźwięk spotkań.
  • Uwierzytelnianie opiera się na podpisanym celu rig-files:<workspaceId>/<rigId> oraz członkostwie w obszarze roboczym — to osobny cel, więc URL wystawiony do podglądu maszyny nie może jednocześnie zapisywać w niej plików.
  • Przejęcie kontroli obowiązuje. Zapis do schowka i upuszczanie plików są modyfikujące i są odrzucane, gdy kontrolę trzyma ktoś inny; odczyt schowka i odczyt pliku na zewnątrz to obserwacja, więc nie są.
  • Gdzie lądują upuszczone pliki: ~/Drops (pulpit), ~/drops (terminal — obok worktree, nigdy w środku, więc upuszczenie nigdy nie pojawia się jako nieśledzona zmiana), /tmp/cc-drops (przeglądarka). Katalog wybiera serwer; wywołujący nie może go wskazać. Istniejące pliki nigdy nie są nadpisywane — kolidująca nazwa ląduje jako 2-name.ext.
  • Co dostaje system gościa: strona przeglądarki otrzymuje prawdziwe zdarzenie upuszczenia w żądanym punkcie (Input.dispatchDragEvent); pulpit dostaje pliki oraz ich URI w swoim schowku, bo żaden host nie potrafi zsyntezować przeciągania XDND do dowolnego zestawu narzędzi bez uprzywilejowanego demona w systemie gościa. Odpowiedź mówi, który z tych przypadków zachodzi.
  • Przeciąganie na zewnątrz działa tylko na pulpicie i odczytuje XdndSelection systemu gościa, gdy przeciąganie trwa. Ładunek identyczny z tym, który system gościa już trzymał w chwili rozpoczęcia przeciągania, jest traktowany jako nieaktualne zaznaczenie po zakończonym przeciąganiu, a nie jako nowe — X nie ma kroku „przeciąganie się skończyło”.
  • Wymagania dotyczące obrazu: obraz pulpitu musi mieć protokół 2 albo nowszy (zbudowany po dodaniu obsługi schowka). Starszy obraz odpowiada 404, a aplikacja proponuje przebudowanie go, zamiast zgłaszać zepsutą maszynę.
  • Dziennik audytu zapisuje kształt, nigdy treść: wiersze clipboard_read, clipboard_write, drop_files i read_file zawierają liczby, rozmiary i ścieżki. W schowku poświadczenia żyją po kilka sekund naraz i nic z tego nie zostaje zapisane.
  • Narzędzia rigów deklarują klasę działań enclosureControl (a narzędzia use dodatkowo networkEgress i processSpawn; mobile_use i ios_use deklarują też packageInstall). rig_close deklaruje enclosureControl; rig_list nie deklaruje żadnej. Domyślnie dozwolona; tryby tylko do odczytu odmawiają jej w całości; pokrętło autonomii przestrzeni może ją zdegradować do pytania o zgodę.
  • Zdarzenia domenowe: RigClosedEvent (z powodem zamknięcia), RigControlChanged (przejęcie / zwrot kontroli), RigReaped (sprzątanie z powodu bezczynności, TTL albo pamięci, ze sterującym agentem). Otwarcie riga nie jest zdarzeniem. Zobacz zdarzenia domenowe.
  • Przechowywanie: rig_sessions i rig_action_log w bazie danych każdego obszaru roboczego. Dziennik działań zapisuje każde zdarzenie wejściowe wraz z podmiotem i monotonicznym numerem sekwencji w obrębie riga; wpisany tekst jest redukowany do długości i skrótu, zanim zostanie zapisany.
  • Katalog danych: rigs/images/ (zaimportowane obrazy qcow2), rigs/smolvm/ (stan środowiska uruchomieniowego poszczególnych rigów), rigs/smolvm-packs/ (wcześniej rozpakowane pakiety maszyn), rigs/tls/ (urząd certyfikacji domen deweloperskich), rigs/run/ (nakładki i ziarna QEMU).
  • Trasy: podgląd na żywo to karta w przestrzeni albo na stronie PR; /settings/server/rigs to ekran ustawień Rigów.