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

shell
npm install boltzlabs

Node 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.

.env shell
BOLTZLABS_API_KEY=ak_your_key_here

first call

There is no client to build and no session to open. Make a machine, use it, destroy it:

main.js javascript
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.

main.js javascript
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.

run.js javascript
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 accepts

rl 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.

train.js javascript
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.