Перейти к содержимому

Дать агенту машину для тестов

Rig — это одноразовая машина, которую агент открывает, когда ему нужно действительно что-то попробовать: загрузить страницу, пощёлкать по приложению рабочего стола, потыкать в телефон. Вы можете смотреть, как он работает, в реальном времени и в любой момент перехватить управление.

Изолированные терминальные, браузерные и настольные rig — это VM с одноразовыми дисками и сетью за шлюзом. Android и iOS — управляемые хостом эмуляторы: состояние их устройств одноразово, но сеть следует за серверным хостом.

Rig работают на машине, где размещён cc_server, — на той же самой машине, а не на той, за которой вы сидите. Есть пять пользовательских поверхностей; настольная поверхность и мобильные требуют настройки на хосте:

Поверхность Где работает Настройка
Терминал (VM) microVM, которая загружает закреплённый образ Ubuntu Не требуется — образ скачивается автоматически при первом использовании
Браузер (VM) microVM, которая загружает закреплённый образ Debian; Chromium, Firefox или WebKit устанавливаются при первом использовании Не требуется — то же самое
Компьютер (VM) QEMU с образом рабочего стола Linux, в который входят Chromium, Firefox, WebKit и базовый набор CLI, как у раннера, размещённого на GitHub Установите QEMU (brew install qemu), затем через Импорт добавьте образ рабочего стола в разделе Настройки → Сервер → Rigs
Android Эмулятор Android от Google Установите Android SDK, создайте AVD и запустите его (ниже)
Симулятор iOS CoreSimulator на серверном Mac Установите Xcode и запрошенную среду выполнения iOS, затем установите мост автоматизации в разделе Настройки → Сервер → Rigs

Терминальные и браузерные машины загружаются из образов, закреплённых по дайджесту: точные байты заданы заранее, скачиваются один раз при первой загрузке и кэшируются — после первой загрузки машины каждого типа последующие машины вовсе пропускают скачивание и поднимаются за секунды. В разделе Настройки → Сервер → Rigs видно, что может загрузить ваш сервер, и все машины, работающие прямо сейчас.

Установленным образом рабочего стола можно управлять с той же страницы: Импорт заменяет его более новым qcow2, а Удалить удаляет его, чтобы вы могли установить свежую сборку.

Мобильные устройства настраиваются иначе

Заголовок раздела «Мобильные устройства настраиваются иначе»

Собственного образа для Android или iOS у нас нет, и это не упущение. Системные образы Android берутся из SDK от Google; среды выполнения iOS — из Xcode. Для Android установите Android Studio (или инструменты SDK командной строки), добавьте виртуальное устройство в Device Manager и запустите его. После этого страница Rigs сообщит, что Android доступен.

Она также точно скажет, какого шага вам не хватает — нет SDK, нет эмулятора, нет виртуального устройства или устройство просто не запущено, — потому что у этих случаев четыре разных исправления, и лишь одно из них — скачивание. Если вы запускаете cc_server из оболочки, которая не видит SDK, экспортируйте его:

Окно терминала
export ANDROID_HOME="$HOME/Library/Android/sdk"

Для iOS сам сервер должен работать в macOS с установленными Xcode и средой выполнения симулятора iOS. Откройте Настройки → Сервер → Rigs и нажмите Установить мост автоматизации iOS. Сервер скачивает артефакт WebDriverAgent, закреплённый по контрольной сумме, проверяет его и устанавливает в принадлежащее серверу хранилище автоматизации. Во время настройки ни один симулятор не загружается.

Машины живут как вкладки — рядом с чатом и diff, в пространстве или на странице PR, в том же меню +, в разделе Машины:

  • Компьютер — рабочий стол Linux с Chromium, Firefox и WebKit
  • Chromium, Firefox или WebKit — браузер
  • Android — запущенный эмулятор Android
  • Симулятор iOS — одноразовый симулятор, созданный для этого разговора

Выберите один и нажмите Запустить машину. Вкладка сообщает, на какой стадии идёт загрузка («Starting the microVM», «Waiting for the guest to come up»), а не просто крутит индикатор.

Вкладка привязана к разговору, как и инструмент агента. Вкладка Chromium, Firefox или WebKit и browser_use, Android и mobile_use или Симулятор iOS и ios_use адресуют одну и ту же машину по умолчанию. Дополнительные слоты интерфейса — это отдельные машины для сравнения; инструменты агента всегда используют машину по умолчанию.

Чтобы собрать, установить и запустить приложение Flutter на Android:

Окно терминала
fvm flutter build apk --debug

Затем вызовите mobile_use с install_apk и build/app/outputs/flutter-apk/app-debug.apk, после чего start_app и имя пакета Android. ui_dump, снимки экрана и ввод управляют тем же устройством, которое показано во вкладке для человека. stop_app, clear_app_data, uninstall_app, open_url и вызовы shell в форме argv покрывают остальную часть цикла разработки, не запуская оболочку на серверном хосте.

Чтобы собрать, установить и запустить приложение Flutter в Симуляторе iOS:

Окно терминала
fvm flutter build ios --simulator --debug
/usr/bin/plutil -extract CFBundleIdentifier raw -o - \
build/ios/iphonesimulator/Runner.app/Info.plist

Затем вызовите ios_use с install_app и каталогом .app, после чего start_app и идентификатор пакета, выведенный plutil. Инструмент iOS также предоставляет stop_app, uninstall_app, open_url и действие spawn в форме argv для локальной диагностики симулятора.

Дисплеи рабочего стола и браузера подстраиваются под размер панели. iOS сохраняет фиксированный размер симулятора в точках и вписывает его с чёрными полями. У каждой поверхности по-прежнему два независимых канала: агент получает маленькие дешёвые снимки экрана, а вы — живой просмотр. Переключение вкладок останавливает поток для человека, поэтому фоновая машина не тратит пропускную способность на отображение.

Вкладка rig сама по себе не запускает машину, в том числе при восстановлении раскладки. Это правило не даёт запуску приложения неожиданно загружать VM или создавать устройства симулятора.

Холст доступен для набора текста и кликов, когда исключительное управление не держит никто другой — или когда его держите вы. Пока этот замок у вас, тег состояния гласит Управление у вас, агент по-прежнему может делать снимки экрана, а сервер отклоняет его изменяющие действия в единственной точке, через которую проходит каждое действие. Всё, что вы делаете, записывается под вашим именем.

Когда закончите, нажмите Остановить машину.

Управление исключительно намеренно: когда двое печатают в одной машине, получается ввод, которого не имел в виду ни один из них.

Копирование и вставка работают в обе стороны через холст rig, как и перетаскивание файлов.

Копирование и вставка. Нажмите сочетание для копирования над холстом, и то, что скопировала машина, — текст, изображение, список файлов, — окажется в вашем буфере обмена. Вставка отправляет ваш буфер в обратную сторону и нажимает вставку внутри машины. В macOS это сочетание ⌘C/⌘V; ⌃C по-прежнему доходит до оболочки гостя как прерывание. В Windows и Linux используйте ⌃C/⌃V — гость получает то же нажатие, что и так, поэтому ⌃C в терминале гостя по-прежнему прерывает, а ваш собственный буфер обмена не затрагивается.

Ничего не синхронизируется в фоне. Пароль, скопированный на вашей машине, не окажется внутри VM из-за сработавшего таймера; он пересекает границу, когда вы вставляете.

Вставка в rig разрешена по умолчанию. Копирование из rig сначала запрашивает подтверждение — разрешение на десять минут или Всегда разрешать в разделе Настройки → Сервер → Rigs → Доступ к буферу обмена. Два направления независимы, и они следуют за вами, а не за рабочим пространством.

Перетаскивание файлов внутрь. Сбросьте их в любое место холста.

  • В Браузере (VM) страница получает настоящее событие сброса в точке, где вы отпустили, поэтому зона загрузки ведёт себя точно так же, как с локальным файлом.
  • В Компьютере (VM) файлы попадают в ~/Drops, а их пути оказываются в буфере обмена машины, поэтому ⌃V вставляет их в файловый менеджер или поле загрузки. Хост не может синтезировать перетаскивание в произвольное приложение Linux, не запустив привилегированный демон внутри VM, которого у rig намеренно нет, — поэтому всплывающее уведомление сообщает, куда попали файлы, вместо того чтобы делать вид, что произошёл сброс.
  • В терминале файл копируется внутрь, а его путь набирается в приглашении, готовый к передаче команде. Вставка изображения в терминал делает то же самое: оно сохраняется в машине, и вы получаете путь.

Перетаскивание файлов наружу работает из Компьютера (VM). Начните перетаскивать файл внутри машины, выведите указатель за пределы холста — и это станет настоящим перетаскиванием на вашем рабочем столе: отпустите его в Finder или Explorer. Копирование файлов в файловом менеджере машины и вставка на вашей стороне тоже работает. Браузер (VM) этого не предлагает: у безголового браузера нет полезной нагрузки перетаскивания, которую можно прочитать, а догадка по выделению текста на странице перехватывала бы обычные клики.

Терминалы в пространстве или на странице PR могут работать внутри rig, а не на самой машине сервера. Когда это так, на панели показывается бейдж Изолированная VM.

Что меняется:

  • Ничто из того, что вы запускаете, не достигает хоста. rm -rf там стоит вам rig.
  • Сеть запрещена по умолчанию. Доступны только хосты из списка разрешённых у rig, и всё проходит через шлюз, который этот список обеспечивает.
  • git push по-прежнему работает в терминале, который открыли вы. У rig нет сохранённых учётных данных: для каждой операции он запрашивает у сервера недолговечный токен, ограниченный вашим собственным доступом к хосту кода, и этот токен отзывается при закрытии rig. Rig, открытый агентом, получает учётные данные только для чтения, поэтому может делать fetch, но не push.

Что важно знать:

  • Восстановленный изолированный терминал ждёт вас. Как и вкладка rig, терминал microvm, возвращающийся вместе с вашей раскладкой, показывает кнопку Открыть оболочку, а не загружает свою VM при запуске. Терминал в оболочке хоста стоит процесса, а изолированный — машины.
  • Файлы, сброшенные на терминал, набираются, а не открываются. Сбросьте CSV на изолированный терминал — файл скопируется в машину, а в приглашении появится его гостевой путь: путь на хосте был бы командой, которая там не сработает.
  • Копия в rig — это копия. Ваш worktree на хосте остаётся источником истины. Коммиты, сделанные внутри rig, переносятся обратно в refs/rigs/<id>/*, когда вы об этом попросите, — они никогда не сдвигают вашу ветку и не трогают ваше рабочее дерево.
  • Работа, нацеленная на хост, всё равно выполняется на хосте. Гость Linux не может собирать для macOS или запускать xcodebuild. Для этого явно выбирайте нативный бэкенд; приложение попросит подтвердить, а не переключится молча.

Запустите dev-сервер в Терминале (VM) — скажем, pnpm dev на порту 3000 — и через несколько секунд значок портов в углу терминала загорится: порт пробрасывается на localhost:3000 на вашей машине, доступен по localhost:3000 внутри Браузера (VM), открывается в вашей локальной сети и получает имя https://myapp.test. Весь этот процесс — автопроброс, общий доступ в локальной сети, dev-домены с HTTPS — описан в отдельном руководстве: Пробросить порты из терминала.

Рабочее пространство может указать для Терминала (VM) и Браузера (VM) свои образы — в разделе Настройки → Сервер → Rigs → Свои образы (это рабочее пространство). Типичное применение: дополнить стандартный образ инструментами, нужными вашему проекту, чтобы каждый терминал стартовал готовым, или использовать образ, который уже публикует ваша команда.

Машина по-прежнему загружается в той же изолированной среде: тот же шлюз исходящего доступа, тот же брокер учётных данных, тот же жизненный цикл. Менять эту настройку могут только администраторы рабочего пространства, новые машины её подхватывают (уже запущенные сохраняют свою), а ссылка должна указывать на образ из реестра — локальные пути отклоняются.

Что должен предоставлять образ:

  • Терминал (VM) — образ Linux с bash. Ему также нужны git, curl и socat — либо предустановленные, либо устанавливаемые при первом запуске (подойдёт любой образ на основе Debian/Ubuntu: они устанавливаются автоматически вместе с набором CLI в стиле раннера, размещённого на GitHub: компиляторы, Python 3, jq, инструменты для архивов, rsync. Среды выполнения языков вроде Node/Go/Java и Docker не предустанавливаются). Гостевой порт 7911 зарезервирован за пробросом портов.
  • Браузер (VM) — образ Debian/Ubuntu с bash и socat, а также бинарник chromium. Сервер сам запускает Chromium как chromium --headless=new и перенаправляет DevTools с гостевого порта 9223 на 9222. PulseAudio и ffmpeg устанавливаются при первом запуске. Не собирайте FROM chromedp/headless-shell — в этом бинарнике нет звука. Переопределение применяется только к браузерным rig на Chromium; Firefox и WebKit его игнорируют и загружают закреплённый образ Debian. Гостевые порты 9222/9223 зарезервированы.

Две рекомендации: закрепляйте ссылку по дайджесту (@sha256:…), чтобы байты не изменились у вас под руками, и размещайте образ в Docker Hub или GitHub Container Registry — хосты загрузки этих реестров допускаются через шлюз исходящего доступа автоматически; другим может потребоваться, чтобы их хосты доставки контента были доступны для скачивания.

Rig задуманы как временные:

  • Простой — примерно через 15 минут без событий браузерный, настольный или мобильный rig паркуется (замораживается и мгновенно просыпается при следующем действии). Изолированный терминал ждёт 45 минут. По истечении двойного окна простоя он закрывается.
  • Ограничение по времени — у каждого rig есть жёсткое время жизни, которое он не может продлить, чем бы он ни занимался.
  • Память — если серверу нужно место для нового rig, он закрывает тот, к которому дольше всего не обращались. Rig, которым кто-то управляет, за которым смотрит или в котором открыт терминал, никогда не забирают.

Когда изолированный rig закрывается, его диск отбрасывается. Закрытие Android-rig отключается от эмулятора на хосте, но не удаляет его. iOS-rig удаляет созданное им устройство CoreSimulator. Сначала перенесите обратно всё, что хотите сохранить.

Изолированные терминальные, браузерные и настольные rig по умолчанию используют шлюз исходящего доступа, запрещающий всё: вы выдаёте разрешения хостам явно, и единственный маршрут гостя — шлюз, который обеспечивает этот список. Браузерный rig также сразу допускает сайт продукта (usectrl.dev). Брокер учётных данных использует тот же список.

Две честные оговорки:

  • Мобильная сеть следует за хостом. Эмулятор Android и CoreSimulator от Apple не находятся за шлюзом исходящего доступа изолированной среды. Ни одна из мобильных вкладок не предлагает управление обходом сети, потому что управляемая хостом сеть и так не ограничена.
  • Всё, что читает rig, недоверенно. Текст страниц, DOM, деревья доступности и дампы интерфейса возвращаются агенту обёрнутыми в маркеры, которые говорят «это данные, а не инструкции». Страница, которая пытается отдавать вашему агенту приказы, читается как строка в кавычках.

Всё, что работает, видно, и всё это можно остановить в разделе Настройки → Сервер → Rigs.

  • Rigs и изолированные среды — модель, стоящая за всем этим: почему VM, два канала отображения, брокер учётных данных, жизненный цикл
  • Пробросить порты из терминала — как добраться до dev-сервера откуда угодно, где это важно
  • Справочник по rig — каждая поверхность, команда, порт и значение по умолчанию в одном месте
  • Настроить ограничения — Drive an enclosure (rig) — это класс действий, который можно задать как «разрешить», «спросить сначала» или «запретить», для рабочего пространства, агента или пространства. Режимы только для чтения запрещают его целиком.