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

Rigs

Лише факти. Про модель, що за ними стоїть, читайте Rigs та ізольовані середовища; щоб відкрити машину, дотримуйтеся посібника.

Поверхня Керує Бекенд Значення Обмежений вихід
Термінал (exec) Оболонка через канал exec ВМ мікроВМ smolvm Так
Браузер Headless Chromium (CDP), Firefox (WebDriver BiDi) або WebKit (W3C WebDriver) мікроВМ smolvm Так
Комп’ютер Робочий стіл X11: введення через гіпервізор, захоплення через агент гостя QEMU qemu-hvf (macOS), qemu-kvm (Linux), qemu-tcg (неприскорений запасний варіант, ніколи не вибирається автоматично) Так
Android Android через ADB Емулятор Google android-emulator Ні — емулятор керує власною мережею
iOS Симулятор iOS через WebDriverAgent CoreSimulator ios-simulator Ні — мережа йде за хостом Mac

Термінал і поверхня computer_use поділяють значення поверхні computer; термінал розрізняють за маркером образу exec, і його ніколи не використовують повторно як керований робочий стіл (чи навпаки). Одна розмова повторно використовує одну термінальну машину.

Рушій Значення Протокол Живий перегляд Нерухомі знімки
Chromium chromium (типово) Chrome DevTools Protocol Скринкаст — браузер надсилає кадри, коли сторінка перемальовується JPEG
Firefox firefox WebDriver BiDi Опитувані нерухомі знімки (у BiDi немає скринкасту), обмежено 6 fps JPEG
WebKit webkit W3C WebDriver (класичний) Опитувані нерухомі знімки, транскодовані ffmpeg хоста PNG

Rig виконує один рушій протягом усього свого життя. Одна розмова може містити один rig на рушій — саме це уможливлює порівняння пліч-о-пліч: відкрити «Firefox (VM)» поруч із «Chromium (VM)» — це дві машини, і закриття однієї лишає іншу працювати.

Передайте engine у rig.open або в інструмент browser_use. Невідому назву відхиляють, а не підставляють типову, — просити браузер і тихо отримувати інший означає відповідати на питання про сумісність неправильною відповіддю.

Обмеження, властиві рушіям, названі прямо, а не обійдені:

  • Firefox не має перезавантаження з обходом кешу (він відхиляє ignoreCache у BiDi цілком), тож жорстке перезавантаження — це звичайне перезавантаження.
  • WebKit також не має перезавантаження з обходом кешу й не має потоку консолі (вивід захоплюють, перехоплюючи console.* після кожного переходу, тож усе, залоговане під час завантаження, пропускається — кожен видобуток консолі про це каже), а для живого перегляду йому потрібен ffmpeg на хості.
  • Жоден із них не надає дерева доступності платформи через свій протокол, тож extract (a11y) повертає наближення, похідне від DOM, і позначене як таке.
  • Жоден із них не може прийняти справжнє перекидання файлу; поле вибору файлу все одно можна спрямувати на шляхи всередині машини.
Поверхня Образ Звідки беруться
Термінал ubuntu:24.04, закріплений за дайджестом Автоматично під час першого завантаження, через власну гейтовану мережу машини
Браузер (Chromium, Firefox, WebKit) debian:trixie-slim, закріплений за дайджестом, плюс власні пакети рушія Автоматично під час першого завантаження, потім кешуються як прогрітий пак
Комп’ютер Образ робочого столу qcow2 з Chromium, Firefox, WebKit і тим самим базовим набором CLI, як у ранера, розміщеного на GitHub, який прогріває термінал Імпортувати в Налаштування → Сервер → Rigs (завантаження, закріплені контрольною сумою, де вони опубліковані)
Android Системні образи Google Через Android SDK
iOS Середовище виконання Xcode Simulator плюс закріплений за контрольною сумою WebDriverAgent Середовище виконання через Xcode; місток автоматизації з Налаштування → Сервер → Rigs

Після першого завантаження кожного різновиду мікроВМ сервер кешує попередньо розпаковану копію в каталозі даних і завантажує кожну наступну машину з неї — зокрема попередньо прогріті образи з уже встановленими пакетами. Термінал прогріває набір CLI-інструментів у стилі ранера, розміщеного на GitHub (git, gcc, python3, jq, rsync, архівні утиліти та решту базового набору apt; не Docker і не мовні toolcache). Образ qcow2 для Комп’ютера вбудовує ті самі назви CLI під час збірки образу, поруч із XFCE і трьома браузерами. Кожен браузер прогріває свій рушій. Усі три рушії поділяють основу Debian, але ніколи не поділяють пак: кеш має ключ з образу, рушія і ревізії аудіо (audio-v1-<engine>), бо машина, прогріта для одного рушія — або до того, як PulseAudio і ffmpeg увійшли до складу робочого навантаження, — не має в собі нічого з іншого. Пак термінала має ключ з ревізії набору інструментів (tools-v1) з тієї самої причини: пак, прогрітий до того, як компілятор увійшов до образу, не повинен обслуговувати машину, у якій він має бути.

Немає готового образу автоматизації, вартого того, щоб його брати, — Chromium із chromedp/headless-shell компілює і ALSA, і PulseAudio геть, тож він ніколи не може видати звук; єдиний підтримуваний образ Firefox у 33× більший за основу Debian і все одно не містить socat; підтримуваного образу WebKit немає взагалі. Тож кожен рушій встановлюється під час першого запуску (chromium, firefox-esr або webkit2gtk-driver) і під час цього звертається до архівів Debian (deb.debian.org, security.debian.org, cloudfront.debian.net). Chromium — це пакунковий бінарник, який запускають як chromium --headless=new.

Ключ налаштування Що перекриває
rigs.smolvm.execImage Образ Terminal (VM)
rigs.smolvm.browserImage Образ Browser (VM)

Записують через сховище налаштувань робочого простору, доступне лише адмінам (Налаштування → Сервер → Rigs → Власні образи (цей робочий простір)). Значення має бути посиланням на реєстр — локальні шляхи, архіви та рядки, схожі на прапорці, відхиляють і на полі, і знову під час завантаження. Недійсне збережене значення ігнорують гучно, і натомість завантажується типове. Власний реєстр образу (плюс відомі супутні blob-CDN для Docker Hub, GHCR, Quay, GitLab і GCR) допускають через шлюз виходу для витягування.

Контракт образу термінала — наявний bash; git, curl, socat попередньо встановлені або основа apt Debian/Ubuntu (ізольоване середовище встановлює ці три плюс набір CLI-інструментів у стилі ранера, розміщеного на GitHub, під час першого запуску: компілятори, Python 3, jq, архівні утиліти, rsync. Мовні toolcache і Docker не встановлюються).

Контракт образу браузера — основа apt Debian/Ubuntu (або вже встановлені пакети) з bash і socat, плюс бінарник chromium, який сервер запускає сам як chromium --headless=new з DevTools на гостьовому loopback 9223, переспрямованому на гостьовий порт 9222. PulseAudio і ffmpeg встановлюються під час першого запуску для аудіоканалу. Не збирайте FROM chromedp/headless-shell: headless.gn угорі компілює і ALSA, і PulseAudio геть, тож цей бінарник не може видавати звук. Перекриття застосовується лише до rig Chromium — команда робочого навантаження, яку він завантажує, належить Chromium, і передати її Firefox чи WebKit означало б запустити бінарник, якого там немає. Rig Firefox або WebKit ігнорує його гучно й завантажує свій закріплений образ.

Порти автоматизації — кожна браузерна машина переадресовує рівно один порт loopback хоста на гостьовий 9222. За ним: DevTools Chromium і віддалений агент Firefox сидять на гостьовому loopback 9223 із реле socat попереду (обидва безумовно прив’язуються до loopback); драйвер WebKit приймає --host і сам прив’язується до гостьового NIC. Firefox додатково перевіряє заголовок Host проти власного порту, тож клієнт надсилає авторитет гостьової сторони, а не той, до якого звертався.

Кожну дію розбирають повністю: некоректне навантаження повертає повідомлення з назвою поля, а ніколи не виняток. Дієслова спостереження (позначені ○) лишаються дозволеними, поки керування утримує людина; дієслова, що змінюють стан, відхиляються.

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 с), type, wait○ (0–60 с), set_display, clipboard_read○, clipboard_write.

Координати — це гостьові пікселі в поточному режимі гостя; кожен знімок екрана зазначає розмір дисплея. Сполучення клавіш використовують написання X11 (ctrl+s, alt+Tab, Return).

clipboard_read приймає selection: clipboard (те, що заповнює ctrl+C, типове), primary (виділення-копіювання в X11) або xdnd (перетягування в польоті). Порожній результат — нормальна відповідь для всіх трьох. clipboard_write приймає лише text — зображення й файли їдуть файловим каналом, бо аргументи дії зберігаються в журнал аудиту, і байтам зображень там не місце. Вміст буфера обміну повертається в огорожі як ненадійні дані.

navigate (лише http/https), reload (hard необов’язковий), stop_loading, click (селектор або координата), fill, type, key (назви клавіш DOM), scroll, mouse_move, drag, left_mouse_down, left_mouse_up, extract○ (a11y | dom | console), screenshot○ (full_page необов’язковий), set_viewport (мін. 320×240), history, wait_for○ (селектор, 0.1–30 с), clipboard_read○, clipboard_write.

Видобутий вміст сторінки повертається в огорожі як ненадійні дані.

У браузера рівно один буфер обміну, тож clipboard_read не приймає selection. Обидва дієслова буфера обміну потребують захищеного контексту: сторінка, віддана звичайним http://, взагалі не має API буфера обміну, і дієслово каже про це, а не повідомляє порожній, — там використовуйте type, який вставляє в місці каретки, не проходячи через буфер обміну.

tap, swipe (50–5000 мс), type, key (псевдоніми back, home, recents, enter, delete, backspace, tab, escape, search, menu, volume_up, volume_down, power або будь-який KEYCODE_*), screenshot○, ui_dump○, install_apk (обмежено worktree rig і каталогом даних сервера), start_app, stop_app, clear_app_data, uninstall_app, open_url і shell. shell приймає список argv і виконується всередині Android, ніколи через оболонку хоста; він покриває діагностику для розробників, як-от logcat, dumpsys і pm grant.

mobile_use не має дієслів буфера обміну. Від Android 10 читати буфер обміну може лише застосунок у фокусі.

tap, swipe (50–5000 мс), type, key (enter, backspace, tab, escape, клавіші зі стрілками або один друкований символ; необов’язкові модифікатори command, control, option і shift), home, lock, unlock, screenshot○, ui_dump○, install_app (каталог .app симулятора, обмежений worktree rig або каталогом даних сервера), start_app, stop_app, uninstall_app, open_url і spawn. spawn приймає argv і виконується всередині симулятора через simctl; він ніколи не викликає оболонку хоста.

Координати — це точки екрана iOS, а не пікселі знімка екрана. Живий потік тримає фіксований розмір симулятора й додає до нього рамку (letterbox), а не змінює розмір пристрою. Передавання тексту буфера обміну з хоста в симулятор і з симулятора в хост використовує ту саму політику дозволів для кожного користувача й кожного напрямку, що й інші rig; файли та зображення канал буфера обміну iOS не приймає.

Кожен rig створює власний пристрій CoreSimulator і сеанс WebDriverAgent. Його закриття зупиняє WebDriverAgent, вимикає й видаляє цей пристрій і прибирає його запис із реєстру. Rig iOS працюють лише на сервері macOS із Xcode, встановленим середовищем виконання iOS і закріпленим містком автоматизації. Вони не надають звуку, мікрофона, перекидання файлів, оболонки хоста чи гарантії ізольованої мережі.

Інструмент Опис
rig_list Показати rig робочого простору з поверхнею, статусом, дисплеєм і контролером
rig_close Знищити rig і відкинути його диск
Фаза Значення
provisioning Завантажується; деталь статусу дослівно передає поточний крок
ready Доступний і приймає дії
parked Припаркований за простоєм: vCPU зупинено, RAM усе ще резидентна; наступна дія його пробуджує
closing Завершує роботу
closed Зник; рядок лишається для журналу аудиту
failed Загинув або так і не піднявся; його можна відрізнити, щоб інтерфейс міг запропонувати повтор
Причина закриття Спрацьовує, коли
requested Попросила людина або агент
idleTimeout Простій понад 2× вікна простою або витіснення через пам’ять
ttlExpired Вичерпався жорсткий час життя
conversationEnded Розмова-власник завершилася
workspaceGone Робочий простір видалено або втрачено членство
serverShutdown Сервер зупиняється
backendFailure Гіпервізор під ним загинув
Значення Термінал Браузер Комп’ютер Мобільні
Пам’ять 512 MB 2048 MB (Chromium); 2560 MB (Firefox, WebKit) 4096 MB 4096 MB
vCPU 2 2 4 4
Жорсткий TTL 8 год 2 год 2 год 2 год
Вікно простою 45 хв 15 хв 15 хв 15 хв
Екран під час завантаження — 1280×800 1280×800 1080×1920
  • Нерухомі знімки каналу агента обмежено 1280×800; людський канал узгоджує до 2560×1600.
  • Типовий бюджет резидентної пам’яті хоста для всіх rig — 12 GB, рахований у резидентних мегабайтах (припаркована ВМ усе одно тримає свою RAM). Витіснення — за найдавнішим використанням, і воно ніколи не забирає машину, якою хтось керує, за якою спостерігає або в якій має відкритий термінал.
  • Відкритий термінал або канал спостереження закріплює rig проти паркування та прибирання за простоєм; жорсткий TTL усе одно діє.
Порт Де Зарезервовано для
7911 Гостьовий термінал Мультиплексор портів, яким їде кожна переадресація
9222, 9223 Гостьовий браузер Реле й кінцева точка автоматизації (WebKit прив’язується до 9222 напряму й не використовує реле)
80, 443 Гостьовий loopback браузера HTTP/HTTPS-канали dev-домену
  • Виявлення опитує TCP-порти, які слухає гостьовий термінал, приблизно кожні ~4 с, на боці сервера.
  • Щонайбільше 16 портів переадресовують автоматично на кожен rig; більше — лише згадують у журналі, не переадресовують.
  • Переадресація на боці хоста прив’язується до loopback, віддаючи перевагу власному номеру порту гостя; Поділитися в локальній мережі додає порт LAN, призначений ОС.
  • Dev-домени мають відповідати name.test або name.localhost (нижній регістр, мітка до 63 символів). Один домен відображається на один порт.
  • HTTPS для dev-домену використовує локальний для сервера CA (EC P-256, під <dataDir>/rigs/tls/, ключі 0600 і ніколи не в гості) з одним кінцевим wildcard-сертифікатом для *.test / *.localhost. Немає openssl на хості — немає каналу HTTPS; звичайний HTTP усе одно маршрутизується.
Поверхня Типовий список дозволених хостів
Термінал Базова лінія розробника пісочниці (хостинги коду, реєстри пакетів, провайдери моделей) + дзеркала apt Ubuntu + власний хост хостингу коду з worktree
Браузер usectrl.dev (сайт продукту) — плюс архіви Debian під час першого завантаження кожного рушія, поки він встановлює свої пакети. Домашня сторінка — це локальний документ file://, і виходу їй не потрібно
Комп’ютер Порожній — заборонено все — доки виклик не надасть хости
Мобільні Не застосовується (мережею керує емулятор)

Кожен мікроВМ додатково отримує хости реєстру свого образу — лише для витягування. Набір дозволених хостів брокера облікових даних виводять із того самого списку: для хоста, до якого гість не може дістатися, токен не випускають.

Обидва напрямки копіювання й вставлення, а також перетягування файлів усередину й назовні. Доступно людині, яка керує rig; агент отримує буфер обміну через дієслова вище й жодного передавання файлів (у нього вже є оболонка всередині ізольованого середовища).

Перетинання буфера обміну — для кожного користувача й кожного напрямку. Вставлення з хоста в rig дозволене за замовчуванням; копіювання з rig у хост запитує підтвердження (дозвіл на десять хвилин або завжди дозволяти в Налаштування → Сервер → Rigs → Доступ до буфера обміну). Обидва вибори незалежні й ніколи не є налаштуванням робочого простору.

Канал Маршрут Переносить
Буфер обміну GET/POST /rig/clipboard/<rigId> Текст, один PNG/JPEG (≤16 MB) і гостьові шляхи файлів у буфері обміну
Файли POST /rig/files/<rigId> До 64 файлів, ≤256 MB кожен і ≤512 MB на перекидання, з необов’язковою точкою перекидання в гостьових пікселях
Файли GET /rig/files/<rigId>?p=<base64url path> Байти одного файлу, назад назовні
  • HTTP, не RPC. RPC-сокет закриває з’єднання на вхідному фреймі понад 256 KB — це захист від DoS, який правильний для команд JSON і фатальний для вставленого знімка екрана. Байти їдуть таким самим маршрутом, яким уже їдуть кадри rig і аудіо зустрічей.
  • Автентифікація — це підписана ціль rig-files:<workspaceId>/<rigId> плюс членство в робочому просторі — окрема ціль, тож URL, випущений, щоб спостерігати машину, не може також записувати в неї файли.
  • Перехоплення застосовується. Запис у буфер обміну й перекидання файлів змінюють стан, і їх відхиляють, поки керування утримує хтось інший; читання буфера обміну й вичитування файлу назовні — це спостереження, і їх не відхиляють.
  • Куди потрапляють перекинуті файли: ~/Drops (робочий стіл), ~/drops (термінал — поряд із worktree, ніколи всередині нього, тож перекинутий файл ніколи не з’являється як незафіксована зміна), /tmp/cc-drops (браузер). Каталог вибирає сервер; той, хто викликає, не може його назвати. Наявні файли ніколи не перезаписують — ім’я, що збігається, лягає як 2-name.ext.
  • Що кажуть гостю: сторінка браузера отримує справжню подію перекидання в запитаній точці (Input.dispatchDragEvent); робочий стіл отримує файли разом з їхніми URI у своєму буфері обміну, бо жоден хост не може синтезувати перетягування XDND у довільний інструментарій без привілейованого демона всередині гостя. Відповідь каже, який із двох варіантів стався.
  • Перетягування назовні працює лише на робочому столі й читає XdndSelection гостя, поки перетягування триває. Навантаження, ідентичне тому, яке гість уже тримав на момент початку натискання, вважають застарілим виділенням із завершеного перетягування, а не новим, — у X немає кроку «перетягування завершено».
  • Вимоги до образу: образ робочого столу має бути протоколу 2 або новішого (зібраний після появи підтримки буфера обміну). Старіший образ відповідає 404, і застосунок каже перезібрати його, а не повідомляє про зламану машину.
  • Журнал аудиту записує форму, ніколи вміст: рядки clipboard_read, clipboard_write, drop_files і read_file містять кількості, розміри та шляхи. Буфер обміну — це місце, де облікові дані живуть по кілька секунд за раз, і ніщо з цього не записується.
  • Інструменти rig оголошують клас дій enclosureControl (плюс networkEgress і processSpawn в інструментах використання; mobile_use та ios_use також оголошують packageInstall). rig_close оголошує enclosureControl; rig_list не оголошує жодного. Дозволено за замовчуванням; режими лише для читання забороняють його цілком; регулятор автономності для кожного простору може знизити його до рівня «спершу запитати».
  • Доменні події: RigClosedEvent (з її причиною закриття), RigControlChanged (перехоплення / повернення керування), RigReaped (простій, TTL або витіснення за пам’яттю, з агентом, який керував). Відкриття rig не є подією. Див. Доменні події.
  • Сховище: rig_sessions і rig_action_log у базі даних кожного робочого простору. Журнал дій записує кожну подію введення з її суб’єктом і монотонною послідовністю для кожного rig; набраний текст редагують до довжини та хешу, перш ніж записати.
  • Каталог даних: rigs/images/ (імпортовані образи qcow2), rigs/smolvm/ (стан середовища виконання кожного rig), rigs/smolvm-packs/ (попередньо розпаковані пакети машин), rigs/tls/ (CA dev-домену), rigs/run/ (оверлеї та сіди QEMU).
  • Маршрути: живий перегляд — це вкладка в просторі або на сторінці PR; /settings/server/rigs — екран налаштувань Rigs.