@aerol-ai/aerolvm-sdk 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/MicroVM.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { type APIVersion } from "./internal/client.js";
2
2
  import { Sandbox } from "./Sandbox.js";
3
- import type { CreateOptions, CreateSessionOptions, ExecStreamHandle, ExecStreamOptions, HealthStatus, Lifecycle, MountSpecRedacted, ResizeOptions, Session, SessionAttachHandle, SessionAttachOptions } from "./types.js";
3
+ import type { CreateOptions, CreateSessionOptions, ExecStreamHandle, ExecStreamOptions, HealthStatus, Lifecycle, MountSpecRedacted, ResizeOptions, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions } from "./types.js";
4
4
  type FetchLike = typeof fetch;
5
5
  export interface MicroVMConfig {
6
6
  patToken?: string;
@@ -24,6 +24,7 @@ export declare class MicroVM {
24
24
  get(id: string): Promise<Sandbox>;
25
25
  start(id: string): Promise<Sandbox>;
26
26
  stop(id: string): Promise<Sandbox>;
27
+ createSnapshot(id: string, name: string): Promise<SandboxSnapshot>;
27
28
  destroy(id: string): Promise<void>;
28
29
  resize(id: string, options: ResizeOptions): Promise<Sandbox>;
29
30
  updateLifecycle(id: string, lifecycle: Lifecycle): Promise<Sandbox>;
package/dist/MicroVM.js CHANGED
@@ -41,6 +41,9 @@ export class MicroVM {
41
41
  const sandbox = await this.client.stop(id);
42
42
  return this.wrap(sandbox.toJSON());
43
43
  }
44
+ async createSnapshot(id, name) {
45
+ return this.client.createSnapshot(id, name);
46
+ }
44
47
  async destroy(id) {
45
48
  await this.client.destroy(id);
46
49
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { MicroVM } from "./MicroVM.js";
2
2
  export { Sandbox } from "./Sandbox.js";
3
3
  export type { MicroVMConfig } from "./MicroVM.js";
4
- export type { BinaryLike, CreateOptions, CreateSessionOptions, ExecRequest, ExecResult, ExecExitInfo, ExposedPort, ExposePortOptions, ExposeProtocol, ExposeResult, HealthStatus, Lifecycle, MountSpec, MountSpecRedacted, MountType, RegistryAuth, ResizeOptions, Sandbox as SandboxData, SandboxStatus, Session, SessionAttachHandle, SessionAttachOptions, SessionStatus, UpdateLifecycleOptions, } from "./types.js";
4
+ export type { BinaryLike, CreateOptions, CreateSessionOptions, ExecRequest, ExecResult, ExecExitInfo, ExposedPort, ExposePortOptions, ExposeProtocol, ExposeResult, HealthStatus, Lifecycle, MountSpec, MountSpecRedacted, MountType, RegistryAuth, ResizeOptions, Sandbox as SandboxData, SandboxSnapshot, SandboxStatus, Session, SessionAttachHandle, SessionAttachOptions, SessionStatus, UpdateLifecycleOptions, } from "./types.js";
@@ -1,4 +1,4 @@
1
- import type { BinaryLike, CreateOptions, CreateSessionOptions, ExecRequest, ExecResult, ExecStreamHandle, ExecStreamOptions, ExposedPort, ExposePortOptions, ExposeResult, HealthStatus, Lifecycle, MountSpecRedacted, ResizeOptions, Sandbox, Session, SessionAttachHandle, SessionAttachOptions } from "../types.js";
1
+ import type { BinaryLike, CreateOptions, CreateSessionOptions, ExecRequest, ExecResult, ExecStreamHandle, ExecStreamOptions, ExposedPort, ExposePortOptions, ExposeResult, HealthStatus, Lifecycle, MountSpecRedacted, NetworkUsage, SetNetworkLimitsOptions, ResizeOptions, Sandbox, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions } from "../types.js";
2
2
  type FetchLike = typeof fetch;
3
3
  /**
4
4
  * Wire version of the sandbox daemon API this client speaks. The SDK and the
@@ -37,6 +37,7 @@ export declare class APIClient {
37
37
  get(id: string): Promise<SandboxResource>;
38
38
  start(id: string): Promise<SandboxResource>;
39
39
  stop(id: string): Promise<SandboxResource>;
40
+ createSnapshot(id: string, name: string): Promise<SandboxSnapshot>;
40
41
  destroy(id: string): Promise<void>;
41
42
  resize(id: string, options: ResizeOptions): Promise<SandboxResource>;
42
43
  updateLifecycle(id: string, lifecycle: Lifecycle): Promise<SandboxResource>;
@@ -71,6 +72,8 @@ export declare class APIClient {
71
72
  reconcile(): Promise<void>;
72
73
  health(): Promise<HealthStatus>;
73
74
  mounts(id: string): Promise<MountSpecRedacted[]>;
75
+ getNetworkUsage(id: string): Promise<NetworkUsage>;
76
+ setNetworkLimits(id: string, options: SetNetworkLimitsOptions): Promise<NetworkUsage>;
74
77
  private wrap;
75
78
  private doJSON;
76
79
  private doBytes;
@@ -118,11 +121,14 @@ export declare class SandboxResource implements Sandbox {
118
121
  downloadFile(targetPath: string): Promise<Uint8Array>;
119
122
  exposePort(port: number, options?: ExposePortOptions): Promise<ExposeResult>;
120
123
  unexposePort(port: number): Promise<void>;
124
+ createSnapshot(name: string): Promise<SandboxSnapshot>;
121
125
  start(): Promise<this>;
122
126
  stop(): Promise<this>;
123
127
  destroy(): Promise<void>;
124
128
  resize(options: ResizeOptions): Promise<this>;
125
129
  updateLifecycle(lifecycle: Lifecycle): Promise<this>;
130
+ getNetworkUsage(): Promise<NetworkUsage>;
131
+ setNetworkLimits(options: SetNetworkLimitsOptions): Promise<NetworkUsage>;
126
132
  toJSON(): Sandbox;
127
133
  private apply;
128
134
  }
@@ -46,6 +46,10 @@ export class APIClient {
46
46
  const response = await this.doJSON("POST", `${this.versionPrefix}/sandboxes/${id}/stop`);
47
47
  return this.wrap(response);
48
48
  }
49
+ async createSnapshot(id, name) {
50
+ const response = await this.doJSON("POST", `${this.versionPrefix}/sandboxes/${id}/snapshot`, { name });
51
+ return fromApiSandboxSnapshot(response);
52
+ }
49
53
  async destroy(id) {
50
54
  await this.doJSON("DELETE", `${this.versionPrefix}/sandboxes/${id}`);
51
55
  }
@@ -142,6 +146,14 @@ export class APIClient {
142
146
  const response = await this.doJSON("GET", `${this.versionPrefix}/sandboxes/${id}/mounts`);
143
147
  return response.mounts.map(fromApiMountSpecRedacted);
144
148
  }
149
+ async getNetworkUsage(id) {
150
+ const response = await this.doJSON("GET", `${this.versionPrefix}/sandboxes/${id}/network/usage`);
151
+ return fromApiNetworkUsage(response);
152
+ }
153
+ async setNetworkLimits(id, options) {
154
+ const response = await this.doJSON("PATCH", `${this.versionPrefix}/sandboxes/${id}/network/limits`, toApiSetNetworkLimitsOptions(options));
155
+ return fromApiNetworkUsage(response);
156
+ }
145
157
  wrap(sandbox) {
146
158
  return new SandboxResource(this, fromApiSandbox(sandbox));
147
159
  }
@@ -237,6 +249,9 @@ export class SandboxResource {
237
249
  async unexposePort(port) {
238
250
  await this.client.unexposePort(this.id, port);
239
251
  }
252
+ async createSnapshot(name) {
253
+ return this.client.createSnapshot(this.id, name);
254
+ }
240
255
  async start() {
241
256
  const updated = await this.client.start(this.id);
242
257
  this.apply(updated.toJSON());
@@ -260,6 +275,12 @@ export class SandboxResource {
260
275
  this.apply(updated.toJSON());
261
276
  return this;
262
277
  }
278
+ async getNetworkUsage() {
279
+ return this.client.getNetworkUsage(this.id);
280
+ }
281
+ async setNetworkLimits(options) {
282
+ return this.client.setNetworkLimits(this.id, options);
283
+ }
263
284
  toJSON() {
264
285
  return cloneSandbox(this);
265
286
  }
@@ -276,6 +297,8 @@ function toApiCreateOptions(options) {
276
297
  env: options.env,
277
298
  os_user: options.osUser,
278
299
  network_block_all: options.networkBlockAll,
300
+ network_bytes_in_limit: options.networkBytesInLimit,
301
+ network_bytes_out_limit: options.networkBytesOutLimit,
279
302
  registry: options.registry,
280
303
  container_command: options.containerCommand,
281
304
  mounts: options.mounts?.map(toApiMountSpec),
@@ -359,6 +382,15 @@ function fromApiCreateSandboxResponse(response) {
359
382
  sshPrivateKey: response.ssh_private_key,
360
383
  };
361
384
  }
385
+ function fromApiSandboxSnapshot(snapshot) {
386
+ return {
387
+ name: snapshot.name,
388
+ image: snapshot.image,
389
+ imageID: snapshot.image_id,
390
+ sourceSandboxID: snapshot.source_sandbox_id,
391
+ createdAt: snapshot.created_at,
392
+ };
393
+ }
362
394
  function fromApiSession(session) {
363
395
  return {
364
396
  id: session.id,
@@ -438,6 +470,24 @@ function fromApiMountSpecRedacted(mount) {
438
470
  hasCredentials: mount.has_credentials,
439
471
  };
440
472
  }
473
+ function fromApiNetworkUsage(usage) {
474
+ return {
475
+ sandboxID: usage.sandbox_id,
476
+ bytesIn: usage.bytes_in,
477
+ bytesOut: usage.bytes_out,
478
+ bytesInLimit: usage.bytes_in_limit,
479
+ bytesOutLimit: usage.bytes_out_limit,
480
+ quotaExceeded: usage.quota_exceeded,
481
+ quotaExceededAt: usage.quota_exceeded_at ?? undefined,
482
+ lastSampledAt: usage.last_sampled_at ?? undefined,
483
+ };
484
+ }
485
+ function toApiSetNetworkLimitsOptions(options) {
486
+ return {
487
+ network_bytes_in_limit: options.networkBytesInLimit,
488
+ network_bytes_out_limit: options.networkBytesOutLimit,
489
+ };
490
+ }
441
491
  function fromApiLifecycle(lifecycle) {
442
492
  const result = {};
443
493
  if (lifecycle?.stop_if_idle_for !== undefined) {
package/dist/types.d.ts CHANGED
@@ -69,6 +69,19 @@ export interface CreateOptions {
69
69
  env?: Record<string, string>;
70
70
  osUser?: string;
71
71
  networkBlockAll?: boolean;
72
+ /**
73
+ * Cap on bytes the sandbox may receive from outside the container before its
74
+ * ingress is dropped via per-IP iptables rule. `0` (default) is unlimited.
75
+ * Limits can be raised or lifted at runtime via `setNetworkLimits`.
76
+ */
77
+ networkBytesInLimit?: number;
78
+ /**
79
+ * Cap on bytes the sandbox may send to outside the container before its
80
+ * egress is dropped. `0` (default) is unlimited. The block reuses the same
81
+ * iptables row as `networkBlockAll`; clearing the quota does not lift an
82
+ * operator-set blanket egress block.
83
+ */
84
+ networkBytesOutLimit?: number;
72
85
  registry?: RegistryAuth;
73
86
  containerCommand?: string[];
74
87
  mounts?: MountSpec[];
@@ -140,6 +153,13 @@ export interface ExposePortOptions {
140
153
  /** Defaults to "http" when omitted. */
141
154
  protocol?: ExposeProtocol;
142
155
  }
156
+ export interface SandboxSnapshot {
157
+ name: string;
158
+ image: string;
159
+ imageID?: string;
160
+ sourceSandboxID: string;
161
+ createdAt: string;
162
+ }
143
163
  /**
144
164
  * Discriminated result from `exposePort`. Branch on `protocol` to access the
145
165
  * fields that are meaningful for the chosen wire protocol — only the raw-TCP
@@ -189,6 +209,29 @@ export interface Sandbox {
189
209
  /** GPU configuration this sandbox was created with. Absent means no GPU. */
190
210
  gpus?: GPUOptions;
191
211
  }
212
+ /**
213
+ * Per-sandbox network byte counters and the configured caps that drive the
214
+ * quota enforcer. `bytesIn` is traffic the container received (ingress);
215
+ * `bytesOut` is traffic the container sent (egress). A `*Limit` of `0` means
216
+ * unlimited. `quotaExceeded` flips true the first time the meter crosses
217
+ * either configured cap and stays true until the operator raises the limit.
218
+ */
219
+ export interface NetworkUsage {
220
+ sandboxID: string;
221
+ bytesIn: number;
222
+ bytesOut: number;
223
+ bytesInLimit: number;
224
+ bytesOutLimit: number;
225
+ quotaExceeded: boolean;
226
+ quotaExceededAt?: string;
227
+ /** Absent until the netstats poller has produced at least one sample. */
228
+ lastSampledAt?: string;
229
+ }
230
+ export interface SetNetworkLimitsOptions {
231
+ /** Omit (undefined) to leave unchanged. `0` means unlimited. */
232
+ networkBytesInLimit?: number;
233
+ networkBytesOutLimit?: number;
234
+ }
192
235
  export interface ExecRequest {
193
236
  command: string;
194
237
  workDir?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aerol-ai/aerolvm-sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,11 +13,12 @@
13
13
  },
14
14
  "scripts": {
15
15
  "build": "tsc -p tsconfig.json",
16
+ "example:browser-isolation:src": "npx tsx src/examples/browserIsolation.ts",
16
17
  "example:create": "npm run build && node dist/examples/createSandbox.js",
17
18
  "example:create:src": "npx tsx src/examples/createSandbox.ts",
18
19
  "example:delete": "npm run build && node dist/examples/deleteSandbox.js",
19
20
  "example:delete:src": "npx tsx src/examples/deleteSandbox.ts",
20
- "test": "tsc -p tsconfig.test.json --outDir dist-test && node --test dist-test/*.test.js"
21
+ "test": "tsc -p tsconfig.test.json --outDir dist-test && node --test dist-test/*.test.js dist-test/internal/*.test.js"
21
22
  },
22
23
  "devDependencies": {
23
24
  "@types/node": "^25.6.2",