Esta guía pone en marcha una sandbox desde JavaScript o TypeScript. Arrancarás una microVM Firecracker aislada, ejecutarás código en tres lenguajes, moverás archivos y seguirás la salida de un trabajo largo. Cada paso es un fragmento corto.
Necesitas Node.js 18+ (o Deno, o Bun) y una cuenta de EQVPS.
1. Consigue un token
El SDK se autentica con un token de cuenta normal. Conectar tu cuenta muestra cómo obtenerlo desde el panel, la API o el servidor MCP.
export EQVPS_API_KEY="your-token"
Una cuenta nueva sin saldo recibe 1 $ de crédito para sandboxes la primera vez que crea una. Eso cubre esta guía muchas veces.
2. Instala el SDK
npm i @eqvps/sdk
Los ejemplos usan módulos ES y await de nivel superior. Guárdalos como archivos .mjs, o como .ts y ejecútalos con npx tsx.
3. Arranca una sandbox y ejecuta código
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 salida es el id de la sandbox (sb_ y 24 caracteres más) y luego 0 3.12.x. Sandbox.with borra la sandbox cuando el callback termina, también si lanza una excepción.
El lenguaje por defecto es Python. Los otros dos están a una opción de distancia:
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 que falla no lanza nada. Comprueba r.ok, que es true cuando exit_code es 0 y el comando no agotó su tiempo.
4. Comandos de shell y paquetes
exec acepta una cadena de shell o un array argv. La sandbox tiene acceso a Internet, así que las instalaciones con npm y pip funcionan:
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);
});
Una llamada síncrona dura como máximo 55 segundos. Lo que dure más va a una tarea en segundo plano (paso 6).
5. Archivos
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 acepta una cadena o un Uint8Array. download devuelve un Uint8Array y downloadText una cadena. Cada transferencia está limitada a 5 MB.
6. Trabajos largos con salida en directo
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 tarea vuelve de inmediato y no tiene el límite de 55 segundos. wait consulta cada 2 segundos por defecto (pollIntervalMs lo cambia). task.kill() la detiene; sb.task(id) se vuelve a conectar desde otro proceso.
Errores
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;
}
El SDK reintenta por sí solo los 429 y 503, hasta tres veces, cuando el servidor envía Retry-After. El 429 más común aparece al ejecutar más de dos comandos a la vez en una cuenta. Todas las clases están en la referencia del SDK.
Coste de esta guía
Cada ejemplo vivió unos segundos y se facturó con el mínimo de 60 segundos: 0,00055 $ en small, 0,0011 $ en standard. El trabajo del paso 6 corrió unos 100 segundos en standard, unos 0,002 $. Todo junto queda muy por debajo de un centavo. La lista completa de precios está en límites y facturación de sandboxes.
Siguientes pasos
- Lo mismo en Python: SDK de Python para sandboxes en 5 minutos.
- Conecta un modelo y deja que ejecute su propio código: tu primera tarea de agente en una sandbox.
- Tarifas y la prueba de 1 $: la página de sandboxes.
Comentarios
Aún no hay comentarios. Sé el primero.