Salta ai contenuti

Assegna a un agente una macchina su cui testare

Un rig è una macchina usa e getta che un agente apre quando deve davvero provare qualcosa: caricare una pagina, esplorare un’app desktop, armeggiare con un telefono. Puoi guardarlo lavorare in tempo reale e riprendere i controlli quando vuoi.

I rig isolati di terminale, browser e desktop sono VM con dischi usa e getta e reti filtrate da un varco. Android e iOS sono emulatori gestiti dall’host: lo stato dei loro dispositivi è usa e getta, ma la loro rete segue l’host del server.

I rig girano sulla macchina che ospita cc_server — la stessa macchina, non quella che stai guardando. Le superfici esposte all’utente sono cinque; le superfici desktop e mobili richiedono una configurazione sull’host:

Superficie Dove gira Configurazione
Terminale (VM) Una microVM che avvia un’immagine Ubuntu con digest fissato Nessuna — l’immagine viene recuperata automaticamente al primo utilizzo
Browser (VM) Una microVM che avvia un’immagine Debian con digest fissato, con Chromium, Firefox o WebKit installati al primo utilizzo Nessuna — idem
Computer (VM) QEMU con un’immagine desktop Linux che include Chromium, Firefox, WebKit e una base CLI di tipo runner ospitato su GitHub Installa QEMU (brew install qemu), poi Importa un’immagine desktop in Impostazioni → Server → Rig
Android L’emulatore Android di Google Installa l’Android SDK, crea un AVD e avvialo (sotto)
Simulatore iOS CoreSimulator sul Mac del server Installa Xcode e il runtime iOS richiesto, poi installa il bridge di automazione in Impostazioni → Server → Rig

Le macchine Terminale e Browser si avviano da immagini con digest fissato: i byte esatti sono stabiliti in anticipo, recuperati una volta al primo avvio e messi in cache — dopo il primo avvio di ciascun tipo, le macchine successive saltano del tutto il download e si avviano in pochi secondi. Impostazioni → Server → Rig mostra cosa può avviare il tuo server e ogni macchina in esecuzione in questo momento.

Un’immagine desktop installata resta gestibile dalla stessa pagina: Importa la sostituisce con un qcow2 più recente, mentre Elimina la rimuove per permetterti di installare una build nuova.

I dispositivi mobili si configurano in modo diverso

Sezione intitolata “I dispositivi mobili si configurano in modo diverso”

Per Android e iOS non esiste un’immagine nostra, e non è una dimenticanza. Le immagini di sistema Android arrivano dall’SDK di Google; i runtime iOS arrivano da Xcode. Per Android, installa Android Studio (o gli strumenti SDK da riga di comando), aggiungi un dispositivo virtuale in Gestione dispositivi, e avvialo. La pagina Rig segnala quindi Android come disponibile.

Ti dice anche esattamente quale passaggio ti manca — nessun SDK, nessun emulatore, nessun dispositivo virtuale, o un dispositivo che semplicemente non è in esecuzione — perché quei quattro casi hanno correzioni diverse e solo una è un download. Se avvii cc_server da una shell che non vede l’SDK, esportalo:

Finestra del terminale
export ANDROID_HOME="$HOME/Library/Android/sdk"

Per iOS, il server stesso deve girare su macOS con Xcode e un runtime del simulatore iOS installati. Apri Impostazioni → Server → Rig e premi Installa il bridge di automazione iOS. Il server recupera l’artefatto WebDriverAgent con checksum fissato, lo verifica e lo installa nell’archivio di automazione di proprietà del server. Durante la configurazione non viene avviato alcun simulatore.

Le macchine vivono come schede, accanto alla chat e al diff — in uno spazio o in una pagina di PR, nello stesso menu +, sotto Macchine:

  • Computer — un desktop Linux con Chromium, Firefox e WebKit
  • Chromium, Firefox o WebKit — un browser
  • Android — l’emulatore Android in esecuzione
  • Simulatore iOS — un simulatore usa e getta creato per questa conversazione

Scegline una e premi Avvia la macchina. La scheda indica in quale fase si trova l’avvio («Starting the microVM», «Waiting for the guest to come up») invece di limitarsi a girare a vuoto.

La scheda è limitata alla conversazione, e lo stesso vale per lo strumento dell’agente. Una scheda Chromium, Firefox o WebKit e browser_use, Android e mobile_use, oppure il simulatore iOS e ios_use si rivolgono alla stessa macchina predefinita. Gli slot aggiuntivi dell’interfaccia sono macchine di confronto separate; gli strumenti degli agenti usano sempre quella predefinita.

Per compilare, installare e avviare un’app Flutter su Android:

Finestra del terminale
fvm flutter build apk --debug

Poi chiama mobile_use con install_apk e build/app/outputs/flutter-apk/app-debug.apk, seguito da start_app e dal nome del pacchetto Android. ui_dump, gli screenshot e l’input pilotano lo stesso dispositivo mostrato nella scheda umana. stop_app, clear_app_data, uninstall_app, open_url e le chiamate shell in forma argv coprono il resto del ciclo di sviluppo senza invocare una shell sull’host del server.

Per compilare, installare e avviare un’app Flutter sul simulatore iOS:

Finestra del terminale
fvm flutter build ios --simulator --debug
/usr/bin/plutil -extract CFBundleIdentifier raw -o - \
build/ios/iphonesimulator/Runner.app/Info.plist

Poi chiama ios_use con install_app e la directory .app, seguito da start_app e dall’identificatore di bundle stampato da plutil. Lo strumento iOS espone anche stop_app, uninstall_app, open_url e un’azione spawn in forma argv per le diagnostiche locali al simulatore.

Le visualizzazioni desktop e browser si ridimensionano sul pannello. iOS mantiene la dimensione in punti fissa del simulatore e la incornicia con bande nere. Ogni superficie ha comunque due corsie indipendenti: l’agente riceve screenshot piccoli ed economici, mentre tu ottieni la vista dal vivo. Cambiare scheda arresta il flusso umano, così una macchina in background non consuma banda per la visualizzazione.

Una scheda rig non avvia una macchina da sola, nemmeno durante il ripristino del layout. Questa regola evita che l’avvio dell’app faccia partire inaspettatamente delle VM o crei dispositivi simulatore.

Il canvas è tuo: puoi digitarci e cliccarci ogni volta che nessun altro detiene il controllo esclusivo — o quando lo detieni tu. Mentre tieni quel lock, il tag di stato mostra Hai il controllo, l’agente può comunque fare screenshot, e il server rifiuta le sue azioni mutative nell’unico punto di passaggio da cui transita ogni azione. Tutto ciò che fai viene registrato a tuo nome.

Premi Ferma la macchina quando hai finito.

Il controllo è esclusivo di proposito: due attori che digitano nella stessa macchina producono input che nessuno dei due intendeva.

Copia e incolla funzionano in entrambe le direzioni attraverso il canvas del rig, e così anche il trascinamento dei file.

Copia e incolla. Premi la combinazione di copia sopra il canvas e tutto ciò che la macchina ha copiato — testo, un’immagine, un elenco di file — finisce nei tuoi appunti. L’incolla invia i tuoi nella direzione opposta e preme incolla dentro la macchina. Su macOS la combinazione è ⌘C/⌘V; ⌃C continua ad arrivare a una shell del guest come interruzione. Su Windows e Linux usa ⌃C/⌃V — il guest riceve lo stesso tasto che avrebbe ricevuto comunque, quindi ⌃C in un terminale del guest interrompe ancora e i tuoi appunti restano intatti.

Niente si sincronizza in background. Una password che copi sulla tua macchina non arriva dentro una VM perché è scattato un timer; attraversa il confine quando incolli.

Incollare in un rig è consentito per impostazione predefinita. Copiare da un rig chiede prima il permesso — un’autorizzazione di dieci minuti, oppure Consenti sempre sotto Impostazioni → Server → Rig → Accesso agli appunti. Le due direzioni sono indipendenti e seguono te, non lo spazio di lavoro.

Trascina i file dentro. Rilasciali in qualsiasi punto del canvas.

  • Sul Browser (VM), la pagina riceve un drop reale nel punto in cui rilasci, quindi una zona di caricamento si comporta esattamente come farebbe con un file locale.
  • Sul Computer (VM), i file finiscono in ~/Drops e i loro percorsi vanno negli appunti della macchina, così ⌃V li incolla in un file manager o in un campo di caricamento. Un host non può sintetizzare un trascinamento verso un’app Linux arbitraria senza eseguire un demone privilegiato dentro la VM, che i rig deliberatamente non hanno — quindi il messaggio ti dice dove sono finiti i file invece di fingere che sia avvenuto un drop.
  • Su un terminale, il file viene copiato dentro e il suo percorso viene digitato al prompt, pronto per essere passato a un comando. Incollare un’immagine in un terminale fa la stessa cosa: viene salvata nella macchina e tu ottieni il percorso.

Trascinare i file fuori funziona dal Computer (VM). Inizia a trascinare un file dentro la macchina, porta il puntatore fuori dal canvas e diventa un vero trascinamento sul tuo desktop — rilascialo in Finder o in Explorer. Anche copiare file nel file manager della macchina e incollarli dalla tua parte funziona. Il Browser (VM) non lo offre: un browser headless non ha alcun payload di trascinamento da leggere, e indovinare dalla selezione di testo della pagina dirotterebbe i clic normali.

I terminali di uno spazio o di una pagina di PR possono girare dentro un rig invece che sulla macchina del server stesso. Quando lo fanno, il pannello mostra un badge VM isolata.

Cosa cambia:

  • Nulla di ciò che esegui raggiunge l’host. Un rm -rf lì dentro ti costa il rig.
  • La rete è negata per impostazione predefinita. Solo gli host presenti nell’allowlist del rig sono raggiungibili, e tutto passa attraverso un varco che la applica.
  • git push funziona comunque in un terminale che hai aperto tu. Il rig non conserva alcuna credenziale; chiede al server un token di breve durata per singola operazione, limitato al tuo accesso al forge, e quel token viene revocato alla chiusura del rig. Un rig aperto da un agente riceve una credenziale di sola lettura, quindi può eseguire fetch ma non push.

Cosa sapere:

  • Un terminale isolato ripristinato ti aspetta. Come una scheda rig, un terminale microvm che ritorna con il tuo layout mostra un pulsante Apri la shell invece di avviare la sua VM al lancio. Un terminale nella shell dell’host costa un processo; uno isolato costa una macchina.
  • I file rilasciati sul terminale vengono digitati, non aperti. Rilascia un CSV su un terminale isolato: viene copiato nella macchina e il suo percorso nel guest appare al prompt — il percorso dell’host sarebbe un comando che fallisce lì.
  • La copia nel rig è una copia. Il tuo worktree sull’host resta la fonte di verità. I commit che fai dentro un rig vengono riportati in refs/rigs/<id>/* quando lo chiedi — non spostano mai il tuo branch né toccano il tuo working tree.
  • Il lavoro destinato all’host gira comunque sull’host. Un guest Linux non può compilare per macOS né eseguire xcodebuild. Per questo scegli esplicitamente il backend nativo; l’app ti chiederà di confermare invece di cambiare in silenzio.

Avvia un dev server nel Terminale (VM) — pnpm dev sulla porta 3000, per esempio — e nel giro di pochi secondi l’icona della spina nell’angolo del terminale si accende: la porta viene inoltrata a localhost:3000 sulla tua macchina, raggiungibile su localhost:3000 dentro il Browser (VM), condivisibile sulla tua rete e denominabile come https://myapp.test. L’intero flusso — inoltro automatico, condivisione in LAN, domini di sviluppo con HTTPS — ha una guida dedicata: Inoltra porte da un terminale.

Uno spazio di lavoro può puntare il Terminale (VM) e il Browser (VM) verso immagini proprie — sotto Impostazioni → Server → Rig → Immagini personalizzate (questo spazio di lavoro). Uso tipico: estendere l’immagine predefinita con la toolchain di cui ha bisogno il tuo progetto, così ogni terminale parte già pronto, oppure riutilizzare un’immagine che il tuo team pubblica già.

La macchina si avvia comunque dentro lo stesso recinto: stesso varco dell’uscita in rete, stesso broker delle credenziali, stesso ciclo di vita. Solo gli amministratori dello spazio di lavoro possono modificare l’impostazione, le nuove macchine la adottano (quelle in esecuzione mantengono la loro), e il riferimento deve essere un’immagine di un registry — i percorsi locali vengono rifiutati.

Cosa deve fornire un’immagine:

  • Terminale (VM) — un’immagine Linux con bash. Serve anche git, curl e socat — preinstallati oppure installabili al primo avvio (qualsiasi immagine basata su Debian/Ubuntu va bene: vengono installati automaticamente, insieme a un set di strumenti CLI di tipo runner ospitato su GitHub: compilatori, Python 3, jq, strumenti per archivi, rsync. I runtime dei linguaggi come Node/Go/Java e Docker non sono preinstallati). La porta guest 7911 è riservata al port forwarder.
  • Browser (VM) — un’immagine Debian/Ubuntu con bash e socat, più un binario chromium. Il server avvia Chromium da sé come chromium --headless=new e inoltra DevTools dalla porta guest 9223 alla 9222. PulseAudio e ffmpeg vengono installati al primo avvio. Non costruire FROM chromedp/headless-shell — quel binario non ha audio. L’override si applica solo ai rig Chromium; Firefox e WebKit lo ignorano e avviano l’immagine Debian fissata. Le porte guest 9222/9223 sono riservate.

Due raccomandazioni: fissa il riferimento tramite digest (@sha256:…) così i byte non possono cambiare sotto di te, e ospitala su Docker Hub o GitHub Container Registry — gli host di download di questi registry vengono ammessi automaticamente attraverso il varco dell’uscita in rete; per gli altri potrebbe essere necessario rendere raggiungibili i loro host di content delivery per il pull.

I rig sono pensati per essere temporanei:

  • Inattività — dopo circa 15 minuti senza che accada nulla un rig browser, desktop o mobile va in pausa (congelato, si risveglia all’istante all’azione successiva). Un terminale isolato attende 45 minuti. Dopo il doppio della finestra di inattività, si chiude.
  • Limite di tempo — ogni rig ha una durata di vita rigida che non può prolungare, qualunque cosa stia facendo.
  • Memoria — se il server ha bisogno di spazio per un nuovo rig, chiude quello usato meno di recente. Un rig che qualcuno sta pilotando o guardando, o in cui ha un terminale aperto, non viene mai tolto.

Quando un rig isolato si chiude, il suo disco viene scartato. Chiudere un rig Android si scollega dall’emulatore dell’host — non lo elimina. Un rig iOS elimina il dispositivo CoreSimulator che ha creato. Riporta fuori prima tutto ciò che vuoi conservare.

I rig isolati di terminale, browser e desktop usano per impostazione predefinita un varco dell’uscita in rete che nega tutto: concedi gli host esplicitamente, e l’unica via del guest è un varco che applica quell’elenco. Un rig browser ammette inoltre il sito del prodotto (usectrl.dev) fin da subito. Il broker delle credenziali usa lo stesso elenco.

Due avvertenze oneste:

  • La rete dei dispositivi mobili segue l’host. L’emulatore di Android e CoreSimulator di Apple non sono dietro il varco dell’uscita in rete del recinto. Nessuna delle due schede mobili offre un controllo per aggirare la rete, perché la rete gestita dall’host è già senza restrizioni.
  • Tutto ciò che un rig legge è non attendibile. Il testo delle pagine, il DOM, gli alberi di accessibilità e i dump delle viste tornano all’agente avvolti in marcatori che dicono «questi sono dati, non istruzioni». Una pagina che cerca di impartire ordini al tuo agente viene letta come una stringa citata.

Puoi vedere tutto ciò che è in esecuzione, e fermare qualsiasi cosa, in Impostazioni → Server → Rig.

  • Rig e recinti — il modello dietro tutto questo: perché le VM, le due corsie di visualizzazione, il broker delle credenziali, il ciclo di vita
  • Inoltra porte da un terminale — raggiungi un dev server ovunque serva
  • Riferimento sui rig — ogni superficie, verbo, porta e valore predefinito in un unico posto
  • Configura i guardrail — Drive an enclosure (rig) è una classe di azioni che puoi impostare su consenti, chiedi prima o nega, per spazio di lavoro, agente o spazio. Le modalità di sola lettura la negano del tutto.