Ce guide fait tourner une sandbox depuis JavaScript ou TypeScript. Vous démarrerez une microVM Firecracker isolée, exécuterez du code dans trois langages, transférerez des fichiers et suivrez la sortie d'une longue tâche. Chaque étape est un court extrait.
Il vous faut Node.js 18+ (ou Deno, ou Bun) et un compte EQVPS.
1. Obtenir un token
Le SDK s'authentifie avec un token de compte ordinaire. Connecter votre compte montre comment en obtenir un depuis le tableau de bord, l'API ou le serveur MCP.
export EQVPS_API_KEY="your-token"
Un nouveau compte sans solde reçoit 1 $ de crédit sandbox la première fois qu'il crée une sandbox. Cela couvre ce guide de nombreuses fois.
2. Installer le SDK
npm i @eqvps/sdk
Les exemples utilisent des modules ES et await au niveau supérieur. Enregistrez-les en fichiers .mjs, ou en .ts et lancez-les avec npx tsx.
3. Démarrer une sandbox et exécuter du code
import { Sandbox } from "@eqvps/sdk";
await Sandbox.with({ tariff: "small" }, async (sb) => {
console.log(sb.id);
const r = await sb.run("import platform; print(platform.python_version())");
console.log(r.exit_code, r.stdout);
});
La sortie est l'identifiant de la sandbox (sb_ suivi de 24 caractères), puis 0 3.12.x. Sandbox.with supprime la sandbox quand le callback se termine, même s'il lève une exception.
Le langage par défaut est Python. Les deux autres sont à une option près :
await Sandbox.with({}, async (sb) => {
const js = await sb.run("console.log(process.version)", { language: "node" });
const sh = await sb.run("uname -r && nproc", { language: "bash" });
console.log(js.stdout, sh.stdout);
});
Un script qui échoue ne lève rien. Vérifiez r.ok, qui vaut true quand exit_code est 0 et que la commande n'a pas expiré.
4. Commandes shell et paquets
exec accepte une chaîne shell ou un tableau argv. La sandbox a accès à Internet, les installations npm et pip fonctionnent donc :
await Sandbox.with({ tariff: "small" }, async (sb) => {
await sb.exec("mkdir -p /root/app && cd /root/app && npm init -y && npm i lodash", { timeout: 55 });
const r = await sb.exec(["node", "-e", "console.log(require('/root/app/node_modules/lodash').VERSION)"]);
console.log(r.stdout);
});
Un appel synchrone dure au maximum 55 secondes. Au-delà, passez par une tâche de fond (étape 6).
5. Fichiers
await Sandbox.with({}, async (sb) => {
await sb.upload("/root/input.json", JSON.stringify({ values: [3, 5, 8] }));
await sb.run("import json; d = json.load(open('/root/input.json')); open('/root/out.txt', 'w').write(str(sum(d['values'])))");
console.log(await sb.downloadText("/root/out.txt")); // 16
});
upload accepte une chaîne ou un Uint8Array. download renvoie un Uint8Array, downloadText une chaîne. Un transfert est limité à 5 MB.
6. Longues tâches avec sortie en direct
await Sandbox.with({ tariff: "standard" }, async (sb) => {
const task = await sb.exec("for i in 1 2 3 4 5; do echo step $i; sleep 20; done", { background: true });
const res = await task.wait({ onOutput: (out) => process.stdout.write(out) });
console.log(res.state, res.exit_code); // done 0
});
La tâche rend la main immédiatement et n'a pas de limite de 55 secondes. wait interroge toutes les 2 secondes par défaut (pollIntervalMs le change). task.kill() l'arrête ; sb.task(id) s'y rattache depuis un autre processus.
Erreurs
import { Sandbox, InsufficientBalanceError, RateLimitError } from "@eqvps/sdk";
try {
await Sandbox.with({}, async (sb) => console.log((await sb.run("print(1)")).stdout));
} catch (e) {
if (e instanceof InsufficientBalanceError) console.log("Top up the balance");
else if (e instanceof RateLimitError) console.log("Busy, retry in", e.retryAfter);
else throw e;
}
Le SDK relance lui-même les 429 et 503, jusqu'à trois fois, quand le serveur envoie Retry-After. Le 429 le plus courant vient de plus de deux commandes simultanées sur un même compte. Toutes les classes sont dans la référence du SDK.
Coût de ce guide
Chaque exemple a vécu quelques secondes et a été facturé au minimum de 60 secondes : 0,00055 $ sur small, 0,0011 $ sur standard. La tâche de l'étape 6 a tourné environ 100 secondes sur standard, soit environ 0,002 $. Le tout reste bien en dessous d'un centime. La grille complète est dans limites et facturation des sandboxes.
Pour aller plus loin
- La même chose en Python : SDK Python pour sandboxes en 5 minutes.
- Brancher un modèle et le laisser exécuter son propre code : votre première tâche d'agent dans une sandbox.
- Tarifs et essai à 1 $ : la page sandboxes.
Commentaires
Pas encore de commentaires. Soyez le premier.