typescript sdk
Install & auth
The same surface as the Python SDK, as promises — plus RL environment pools, which have no CLI equivalent. Ships typed, with no dependencies.
install
npm install boltzlabsNode 18 or newer, and no transitive dependencies — the package is the SDK and nothing else.
the key
It comes from the environment, or from a .env file found by searching upwards from where you run the script. Nothing is shared with the CLI's login
— the SDK stands on its own.
BOLTZLABS_API_KEY=ak_your_key_herefirst call
There is no client to build and no session to open. Make a machine, use it, destroy it:
import { Sandbox } from 'boltzlabs';
const sb = await Sandbox.create(); // small / base / internet off
console.log(String(await sb.run('print(sum(range(101)))'))); // 5050
await sb.delete();Sandbox.create() is a static rather than a constructor
because a sandbox does not exist until the platform has assigned it an id, and a constructor cannot
await that. Every option has a default — leave them all out, or name only what you are changing:
machine
small
environment
base
name
the assigned id
internet
false
idleTimeout
the platform's
maxLifetime
the platform's
A sandbox bills for as long as it exists, so delete() is the one you should not forget. withSandbox writes it for you, including when the
body throws — the case that otherwise leaves a machine billing until someone notices.
await Sandbox.withSandbox({ environment: 'python' }, async (sb) => {
(await sb.run('print("hi")')).check();
});one-shot execution
Nothing is created and nothing is left over. The language is always named — it is never guessed
from an extension, because a .py file is as likely
to be torch as plain python.
import { execute, languages } from 'boltzlabs';
await execute('print(sum(range(101)))', { language: 'python' }); // 5050
await execute({ file: 'main.go', language: 'go' }); // compiled, then run
await languages(); // the codes the platform acceptsrl pools
One request carries every action and returns every result. A loop that stepped environments one at a time would pay a round trip per environment per step — at a thousand environments that is the whole cost of training.
import { RLPool } from 'boltzlabs';
const pool = await RLPool.create({ environment: 'cartpole', n: 1000 });
let obs = await pool.reset();
for (let i = 0; i < 100; i++) {
const actions = obs.map(() => (Math.random() < 0.5 ? 0 : 1));
const { obs: next, rewards, dones } = await pool.step(actions);
obs = next;
}
console.log(String(pool.timing)); // what the platform cost you, per step
await pool.close();rewards comes back as a Float32Array; observations and infos stay as
they came, because coercing arbitrary JSON into an array would be a guess about your observation
space. See RL pools for writing your own environment.