preview
Avec preview, un agent met quelque chose qui a une interface web sur un lien
public, pour que vous puissiez l’ouvrir depuis votre téléphone ou l’envoyer à
quelqu’un : un serveur de dev qui écoute sur un port de la machine du relais, ou
un dossier de fichiers ordinaires. Il peut aussi lister et fermer les aperçus de
sa propre conversation.
Demandez-le avec des mots simples : « démarre le serveur de dev et donne-moi un
lien », « montre-moi le site construit ». L’agent a pour consigne d’utiliser
l’outil chaque fois que vous voulez voir, essayer ou partager une interface web,
et de ne jamais vous renvoyer vers localhost.
Un lien d’aperçu est public
Quiconque a le lien peut ouvrir l’app sans se connecter. Le token du lien est la seule protection. L’agent a pour consigne de le dire quand il vous donne un lien. Fermez un aperçu quand vous n’en avez plus besoin.
Ce que vous voyez #
- Une carte pour l’aperçu dans le panneau des tâches de fond de la conversation, avec Open (Ouvrir), Copy link (Copier le lien) et Close (Fermer).
- Une carte de lien dans le fil de la conversation, sur la réponse dans laquelle
l’agent l’a publié. Elle affiche un badge
closedune fois l’aperçu disparu. Une vue partagée de la conversation n’affiche que le libellé de la carte, jamais le lien. - Tous les aperçus du relais, toutes conversations confondues, sous Settings → Previews (Réglages → Aperçus), chacun avec un bouton pour le fermer.
- Un badge
offlinesur la carte quand le serveur de dev derrière un aperçu de port ne répond plus. Le lien reste enregistré : redémarrez le serveur sur le même port et le même lien fonctionne de nouveau.
Vous pouvez faire la même chose sans agent en tapant / dans la zone de saisie :
/preview 5173 web app publish a port
/preview ./dist built site publish a folder
/preview list list the previews
/preview close close one
La mise en place #
Les aperçus sont désactivés tant que l’opérateur du relais ne les a pas mis en place. Il leur faut un nom d’hôte à eux, distinct de celui du relais, pour qu’une app en aperçu ne puisse jamais atteindre le relais lui-même. Trois choses :
- Un nom d’hôte que vous contrôlez et qui diffère de celui du relais par le nom, pas seulement par le port.
- Un proxy frontal (Caddy, un Cloudflare Tunnel, …) qui fait pointer ce nom d’hôte vers le port des aperçus.
- Un bloc
previewsdans leconfig.du relais :json
{
"publicHostnames": ["relay.example.com"],
"previews": {
"enabled": true,
"port": 3334,
"bindHost": "127.0.0.1",
"publicBaseUrl": "https://preview.example.com",
"allowedTargetHosts": [],
"maxLive": 8
}
}
Les agents ont l’outil, que ce soit fait ou non. Sinon, un appel create
revient avec la raison, et l’agent a pour consigne de vous la transmettre :
c’est à l’opérateur de corriger.
Par fournisseur #
| Fournisseur | |
|---|---|
| Claude, Claude API Ajouté en 0.9.18, DeepSeek Ajouté en 0.9.17, Cursor | a l’outil preview |
| Grok ; GitHub Copilot et OpenAI sur le moteur d’extension | a l’outil preview, via le serveur MCP d’OAR Ajouté en 0.9.4 |
| GitHub Copilot et OpenAI sur le moteur SDK | pas d’outil. Tant que les aperçus sont mis en place, l’agent reçoit les instructions pour appeler l’API d’aperçu du relais, avec les mêmes règles et sa conversation déjà inscrite dans les appels. Ce que vous voyez est identique. |
| Claude Cloud | aucun : une session cloud tourne dans un bac à sable chez Anthropic, et il n’y a ni port ni dossier de votre machine à publier |
Actions #
| Action | Ce qu’elle fait | Paramètres |
|---|---|---|
create |
publier un port ou un dossier | port ou dir, éventuellement label |
list |
lister les aperçus de cette conversation | |
close |
fermer l’un des aperçus de cette conversation | token, facultatif quand la conversation en a exactement un |
Un résultat est du JSON avec "ok": true, ou "ok": false et un texte error.
L’outil n’échoue jamais d’une autre manière ; un paramètre erroné revient sous
forme d’error que l’agent peut lire.
create #
Publie soit un port, soit un dossier, jamais les deux dans un même appel.
Ajouté en 0.9.11 Publier de nouveau le même port ou le même dossier dans la même
conversation renvoie l’aperçu déjà actif, avec le même lien et le libellé
inchangé ; le résultat indique alors "existing": true.
| Paramètre | Type | |
|---|---|---|
port |
1024–65535 | le port local d’un serveur de dev |
dir |
chemin | un dossier à servir comme fichiers ordinaires : absolu, ou relatif au dossier de travail de la conversation |
label |
texte, jusqu’à 120 caractères | le nom sur la carte de l’aperçu |
Un serveur de dev (port) #
Le relais transmet les requêtes à un serveur qui écoute sur ce port. Il ne démarre, ne surveille ni ne redémarre ce serveur ; cela reste une tâche de fond ordinaire de l’agent, avec son propre bouton d’arrêt.
Chaque aperçu vit sous son propre chemin sur le nom d’hôte des aperçus. Le
navigateur demande / ; le relais retire ce préfixe avant de
transmettre la requête, et indique le préfixe à l’app dans X-.
Il ne réécrit pas les pages. Une app fonctionne donc quand les liens et les
adresses de ressources qu’elle envoie sont relatifs ou portent le préfixe, tout
en répondant aux requêtes sans le préfixe. Une app qui demande /
à la racine de l’hôte ne le trouvera pas.
C’est pourquoi l’agent a pour consigne d’appeler create d’abord et de lire
le base du résultat avant de démarrer le serveur de dev.
Ce qu’on dit aux agents ne convient pas à tous les serveurs de dev
La description de l’outil lui-même suggère de démarrer le serveur avec le chemin
de base défini (Vite --base, Next.js base, un préfixe de montage
Express). Un serveur qui attend alors le préfixe dans les requêtes qu’il reçoit
ne correspond pas à ce que transmet le relais : le serveur de dev de Vite et un
routeur Express monté sur le préfixe ne fonctionnent pas ainsi. Aperçus
explique ce qui fonctionne.
{ "action": "create", "port": 5173, "label": "web app" }
{
"ok": true,
"existing": false,
"url": "https://preview.example.com/test_0123456789abcdef0123456789abcdef/",
"basePath": "/test_0123456789abcdef0123456789abcdef/",
"token": "0123456789abcdef0123456789abcdef",
"mode": "port",
"hint": "Serve the app under /test_0123456789abcdef0123456789abcdef/ (the proxy strips the prefix and sends X-Forwarded-Prefix). Bind the dev server to 127.0.0.1, not 0.0.0.0: the relay's proxy reaches it there and nothing else should. Tell the user the URL and that the link is public."
}
Ajouté en 0.9.17 Le hint dit aussi à l’agent de lier le serveur de dev à
127., et non à 0. : le proxy du relais l’y atteint, et rien
d’autre ne devrait l’atteindre. Seules les sessions qui ont l’outil preview
reçoivent cette ligne (voir Par
fournisseur). Les agents à qui l’on enseigne l’API d’aperçu au
lieu de l’outil ne la reçoivent pas : GitHub Copilot et OpenAI sur le moteur
SDK, ainsi que Grok et le moteur d’extension de Copilot quand le relais tourne
avec OAR_.
Un dossier (dir) #
Le relais sert lui-même les fichiers du dossier. Rien n’a besoin de tourner : idéal pour une sortie de build, une maquette, un simple fichier HTML ou un rapport de couverture.
- Le dossier doit se trouver dans le dossier de travail de la conversation. C’est revérifié à chaque requête : un lien ne peut donc pas être amené plus tard à mener à l’extérieur.
- Les fichiers et dossiers dont le nom commence par un point (
.,git .) ne sont jamais servis, pas plus que les fichiers de clés (env *.,pem *.,key id_).rsa… index.est servi pour un chemin de dossier.html - Les chemins de ressources relatifs fonctionnent tels quels. Les chemins depuis
la racine de l’hôte (
/) ne fonctionnent pas.assets/ app. js - Pas de connexions WebSocket.
{ "action": "create", "dir": "./dist", "label": "built site" }
Le résultat a les mêmes champs, avec "mode": "static".
list #
Liste les aperçus de la propre conversation de l’agent, avec token, label,
url, target (le dossier, ou localhost:<port>), online et la
conversation. Ajouté en 0.9.14 Avant 0.9.14, la liste couvrait tous les aperçus du
relais ; le token d’un aperçu est sa seule protection, donc un agent ne voit
désormais que les siens. La liste de tout le relais est à vous, dans
Settings → Previews et avec /. Un aperçu que le relais n’a pas pu vérifier après un redémarrage porte "unverified": true
et n’est pas servi tant que la vérification n’a pas répondu (voir
Après un redémarrage du relais).
{ "action": "list" }
{
"ok": true,
"enabled": true,
"previews": [
{ "token": "0123456789abcdef0123456789abcdef", "label": "web app", "url": "https://preview.example.com/test_0123456789abcdef0123456789abcdef/", "target": "localhost:5173", "online": true, "conversationId": "3f9c…" }
]
}
close #
Ferme le lien. Un serveur de dev derrière lui continue de tourner.
| Paramètre | Type | |
|---|---|---|
token |
32 caractères hexadécimaux | le token issu de create ou de list. Peut être omis quand la conversation a exactement un aperçu. |
Sans token et avec plusieurs aperçus dans la conversation, l’appel revient
avec une error et la liste parmi laquelle choisir.
Ajouté en 0.9.14 Un agent ne ferme que les aperçus de sa propre conversation. Le token de l’aperçu d’une autre conversation est refusé :
{ "ok": false, "error": "This preview belongs to another conversation; a conversation can close only its own previews. The owner can close it in Settings → Previews." }
{ "action": "close", "token": "0123456789abcdef0123456789abcdef" }
{ "ok": true, "closed": { "token": "0123456789abcdef0123456789abcdef", "label": "web app" } }
Limites #
| Limite | Valeur |
|---|---|
| Aperçus simultanés, sur tout le relais | 8 (previews.) |
| Aperçus qu’un agent peut lister et fermer | ceux de sa propre conversation Ajouté en 0.9.14 |
| Port | 1024–65535, et jamais l’un des ports propres du relais |
| Où un aperçu de port peut pointer | la machine du relais elle-même (bouclage), plus les hôtes que l’opérateur liste dans previews. |
| Où un aperçu de dossier peut pointer | dans le dossier de travail de la conversation |
| Durée de vie | jusqu’à ce qu’il soit fermé ou que sa conversation soit supprimée. Ajouté en 0.9.11 Il survit à un redémarrage du relais ; un aperçu de port prend fin quand la machine redémarre, un aperçu de dossier quand son dossier sort du dossier de travail. Un aperçu n’expire pas de lui-même. |
| Libellé | 120 caractères |
Les aperçus sont tenus à l’écart du relais : ils sont servis sur un port distinct, sous un nom d’hôte distinct, où aucune des pages ni de l’API du relais n’existe. Les aperçus partagent ce nom d’hôte entre eux, chacun sous son propre chemin.
La portée par conversation n’est pas un mur
Le relais limite une requête d’aperçu à la conversation qu’elle nomme, dans le
paramètre de requête conversation ou dans l’en-tête de conversation
qu’envoient chaque worker de session et le serveur MCP d’OAR. Les agents
utilisent le même token du relais que vous : la portée est donc déclarée par la
requête, pas prouvée, et une requête qui ne nomme aucune conversation obtient
toujours tous les aperçus. La portée cantonne l’outil et les appels qu’on
enseigne aux agents à leur propre conversation ; elle n’arrête pas un agent qui
lit le token du relais et appelle l’API à la main. Voir
Ce qu’OAR expose.