@lizard-build/sdk 0.1.6 → 0.1.15
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/README.md +12 -12
- package/dist/index.d.mts +45 -9
- package/dist/index.d.ts +45 -9
- package/dist/index.js +75 -15
- package/dist/index.mjs +73 -14
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -21,8 +21,8 @@ pip install lizard-sdk
|
|
|
21
21
|
```ts
|
|
22
22
|
import { Sandbox } from '@lizard-build/sdk'
|
|
23
23
|
|
|
24
|
-
// Boot a
|
|
25
|
-
const sandbox = await Sandbox.create('
|
|
24
|
+
// Boot a microVM from the 'base' template (Debian + Node.js 20)
|
|
25
|
+
const sandbox = await Sandbox.create('base')
|
|
26
26
|
|
|
27
27
|
// Write a file directly into the microVM filesystem
|
|
28
28
|
await sandbox.fs.write('/app/server.js', `
|
|
@@ -46,8 +46,8 @@ await sandbox.kill()
|
|
|
46
46
|
```python
|
|
47
47
|
from lizard import Sandbox
|
|
48
48
|
|
|
49
|
-
# Boot a Python microVM from the '
|
|
50
|
-
sandbox = Sandbox.create("
|
|
49
|
+
# Boot a Python microVM from the 'code-interpreter-v1' template
|
|
50
|
+
sandbox = Sandbox.create("code-interpreter-v1")
|
|
51
51
|
|
|
52
52
|
# Write a script into the microVM filesystem
|
|
53
53
|
sandbox.fs.write("/app/main.py", """
|
|
@@ -77,7 +77,7 @@ Sandboxes can be snapshotted mid-execution and resumed exactly where they left o
|
|
|
77
77
|
|
|
78
78
|
```ts
|
|
79
79
|
// Boot and set up the environment once
|
|
80
|
-
const sandbox = await Sandbox.create('
|
|
80
|
+
const sandbox = await Sandbox.create('code-interpreter-v1')
|
|
81
81
|
await sandbox.process.exec('pip install numpy pandas scikit-learn')
|
|
82
82
|
const id = sandbox.sandboxId
|
|
83
83
|
await sandbox.pause()
|
|
@@ -92,7 +92,7 @@ await resumed.kill()
|
|
|
92
92
|
```python
|
|
93
93
|
from lizard import Sandbox
|
|
94
94
|
|
|
95
|
-
sandbox = Sandbox.create("
|
|
95
|
+
sandbox = Sandbox.create("code-interpreter-v1")
|
|
96
96
|
sandbox.process.exec_("pip install numpy pandas scikit-learn")
|
|
97
97
|
sandbox_id = sandbox.sandbox_id
|
|
98
98
|
sandbox.pause()
|
|
@@ -108,11 +108,11 @@ resumed.kill()
|
|
|
108
108
|
|
|
109
109
|
### `Sandbox.create(template?, opts?)`
|
|
110
110
|
|
|
111
|
-
Boot a new Lizard microVM. Built-in templates: `base
|
|
111
|
+
Boot a new Lizard microVM. Built-in templates: `base` (Debian + Node.js 20) and `code-interpreter-v1` (Python 3.11 + Node.js 20). Custom templates can be pushed via `lizard push`.
|
|
112
112
|
|
|
113
113
|
```ts
|
|
114
|
-
const sandbox = await Sandbox.create('
|
|
115
|
-
const sandbox = await Sandbox.create('
|
|
114
|
+
const sandbox = await Sandbox.create('base')
|
|
115
|
+
const sandbox = await Sandbox.create('code-interpreter-v1', { timeoutMs: 10 * 60 * 1000 })
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
### `Sandbox.connect(sandboxId, opts?)`
|
|
@@ -154,7 +154,7 @@ Returns a public HTTPS URL for a port listening inside the microVM — no tunnel
|
|
|
154
154
|
```ts
|
|
155
155
|
await sandbox.process.exec('npx -y serve -p 3000 &')
|
|
156
156
|
const url = sandbox.getHost(3000)
|
|
157
|
-
// https://{sandboxId}-3000.sandbox.
|
|
157
|
+
// https://{sandboxId}-3000.sandbox.{region}.onlizard.com
|
|
158
158
|
```
|
|
159
159
|
|
|
160
160
|
### `sandbox.pause()` / `sandbox.resume()`
|
|
@@ -175,8 +175,8 @@ Extend or reduce the sandbox timeout.
|
|
|
175
175
|
|
|
176
176
|
| Variable | Description |
|
|
177
177
|
|---|---|
|
|
178
|
-
| `LIZARD_API_KEY` | API key (required — get one at [lizard.
|
|
179
|
-
| `LIZARD_API_URL` | Override the API base URL (default: `https://
|
|
178
|
+
| `LIZARD_API_KEY` | API key (required — get one at [lizard.build](https://lizard.build)) |
|
|
179
|
+
| `LIZARD_API_URL` | Override the API base URL (default: `https://lizard.build`) |
|
|
180
180
|
|
|
181
181
|
The `X-API-Key` header is used for all authenticated requests.
|
|
182
182
|
|
package/dist/index.d.mts
CHANGED
|
@@ -141,6 +141,7 @@ interface SandboxOpts extends ConnectionOpts {
|
|
|
141
141
|
metadata?: Record<string, string>;
|
|
142
142
|
envs?: Record<string, string>;
|
|
143
143
|
timeoutMs?: number;
|
|
144
|
+
volumeId?: string;
|
|
144
145
|
}
|
|
145
146
|
/**
|
|
146
147
|
* Low-level HTTP client for the Lizard sandbox API.
|
|
@@ -156,6 +157,10 @@ declare class SandboxClient {
|
|
|
156
157
|
protected static listSandboxes(opts?: ConnectionOpts): Promise<SandboxInfo[]>;
|
|
157
158
|
protected static getSandboxInfo(sandboxId: string, opts?: ConnectionOpts): Promise<SandboxInfo>;
|
|
158
159
|
protected static setTimeoutSandbox(sandboxId: string, timeoutMs: number, opts?: ConnectionOpts): Promise<void>;
|
|
160
|
+
protected static exposeSandboxPort(sandboxId: string, port: number, opts?: ConnectionOpts): Promise<{
|
|
161
|
+
hostname: string;
|
|
162
|
+
url: string;
|
|
163
|
+
}>;
|
|
159
164
|
}
|
|
160
165
|
|
|
161
166
|
/**
|
|
@@ -170,7 +175,7 @@ declare class SandboxClient {
|
|
|
170
175
|
* ```ts
|
|
171
176
|
* import { Sandbox } from 'lizard'
|
|
172
177
|
*
|
|
173
|
-
* const sandbox = await Sandbox.create('
|
|
178
|
+
* const sandbox = await Sandbox.create('base')
|
|
174
179
|
* await sandbox.fs.write('/app/index.js', 'console.log("hello world")')
|
|
175
180
|
* const result = await sandbox.process.exec('node /app/index.js')
|
|
176
181
|
* console.log(result.stdout) // "hello world"
|
|
@@ -179,7 +184,7 @@ declare class SandboxClient {
|
|
|
179
184
|
*
|
|
180
185
|
* @example Pause and resume a long-running session:
|
|
181
186
|
* ```ts
|
|
182
|
-
* const sandbox = await Sandbox.create('
|
|
187
|
+
* const sandbox = await Sandbox.create('code-interpreter-v1')
|
|
183
188
|
* await sandbox.process.exec('pip install numpy')
|
|
184
189
|
* const id = sandbox.sandboxId
|
|
185
190
|
* await sandbox.pause()
|
|
@@ -231,15 +236,16 @@ declare class Sandbox extends SandboxClient {
|
|
|
231
236
|
/**
|
|
232
237
|
* Create a new Lizard sandbox from the specified template.
|
|
233
238
|
*
|
|
234
|
-
* Available templates
|
|
235
|
-
* templates can be built and pushed via
|
|
239
|
+
* Available templates: `base` (Debian + Node.js 20) and `code-interpreter-v1`
|
|
240
|
+
* (Python 3.11 + Node.js 20). Custom templates can be built and pushed via
|
|
241
|
+
* `lizard push`.
|
|
236
242
|
*
|
|
237
243
|
* @param template Name of the sandbox template to boot from.
|
|
238
244
|
*
|
|
239
245
|
* @example
|
|
240
246
|
* ```ts
|
|
241
|
-
* const sandbox = await Sandbox.create('
|
|
242
|
-
* const sandbox = await Sandbox.create('
|
|
247
|
+
* const sandbox = await Sandbox.create('base')
|
|
248
|
+
* const sandbox = await Sandbox.create('code-interpreter-v1', { timeoutMs: 10 * 60 * 1000 })
|
|
243
249
|
* ```
|
|
244
250
|
*/
|
|
245
251
|
static create(template: string, opts?: SandboxOpts): Promise<Sandbox>;
|
|
@@ -305,10 +311,10 @@ declare class Sandbox extends SandboxClient {
|
|
|
305
311
|
* ```ts
|
|
306
312
|
* await sandbox.process.exec('npx -y serve -p 3000 &')
|
|
307
313
|
* const url = sandbox.getHost(3000)
|
|
308
|
-
* // https://{sandboxId}-3000.sandbox.
|
|
314
|
+
* // https://{sandboxId}-3000.sandbox.{region}.onlizard.com
|
|
309
315
|
* ```
|
|
310
316
|
*/
|
|
311
|
-
getHost(port: number): string
|
|
317
|
+
getHost(port: number, opts?: ConnectionOpts): Promise<string>;
|
|
312
318
|
private resolveOpts;
|
|
313
319
|
}
|
|
314
320
|
|
|
@@ -476,4 +482,34 @@ declare class CodeSandbox extends Sandbox {
|
|
|
476
482
|
static connect(sandboxId: string, opts?: ConnectionOpts): Promise<CodeSandbox>;
|
|
477
483
|
}
|
|
478
484
|
|
|
479
|
-
|
|
485
|
+
interface VolumeInfo {
|
|
486
|
+
id: string;
|
|
487
|
+
projectId: string;
|
|
488
|
+
name: string;
|
|
489
|
+
sizeGb: number;
|
|
490
|
+
sizeMb?: number;
|
|
491
|
+
status: string;
|
|
492
|
+
attachedTo?: string | null;
|
|
493
|
+
createdAt: number;
|
|
494
|
+
}
|
|
495
|
+
interface CreateVolumeOpts extends ConnectionOpts {
|
|
496
|
+
sizeGb?: number;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* A persistent volume that outlives sandboxes.
|
|
500
|
+
* Mount it to a sandbox via `Sandbox.create({ volumeId: volume.volumeId })`.
|
|
501
|
+
*/
|
|
502
|
+
declare class Volume {
|
|
503
|
+
readonly volumeId: string;
|
|
504
|
+
private readonly config;
|
|
505
|
+
constructor(opts: {
|
|
506
|
+
volumeId: string;
|
|
507
|
+
} & ConnectionOpts);
|
|
508
|
+
static create(projectId: string, name: string, opts?: CreateVolumeOpts): Promise<Volume>;
|
|
509
|
+
static get(projectId: string, volumeId: string, opts?: ConnectionOpts): Promise<Volume>;
|
|
510
|
+
static list(projectId: string, opts?: ConnectionOpts): Promise<VolumeInfo[]>;
|
|
511
|
+
getInfo(projectId: string): Promise<VolumeInfo>;
|
|
512
|
+
delete(projectId: string): Promise<void>;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
export { AuthenticationError, type CodeContext, CodeSandbox, type ConnectionOpts, type CreateContextOpts, type CreateVolumeOpts, Execution, ExecutionError, type FileInfo, type FsOpts, LizardError, NotFoundError, type ProcessOpts, type ProcessResult, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, TimeoutError, Volume, type VolumeInfo };
|
package/dist/index.d.ts
CHANGED
|
@@ -141,6 +141,7 @@ interface SandboxOpts extends ConnectionOpts {
|
|
|
141
141
|
metadata?: Record<string, string>;
|
|
142
142
|
envs?: Record<string, string>;
|
|
143
143
|
timeoutMs?: number;
|
|
144
|
+
volumeId?: string;
|
|
144
145
|
}
|
|
145
146
|
/**
|
|
146
147
|
* Low-level HTTP client for the Lizard sandbox API.
|
|
@@ -156,6 +157,10 @@ declare class SandboxClient {
|
|
|
156
157
|
protected static listSandboxes(opts?: ConnectionOpts): Promise<SandboxInfo[]>;
|
|
157
158
|
protected static getSandboxInfo(sandboxId: string, opts?: ConnectionOpts): Promise<SandboxInfo>;
|
|
158
159
|
protected static setTimeoutSandbox(sandboxId: string, timeoutMs: number, opts?: ConnectionOpts): Promise<void>;
|
|
160
|
+
protected static exposeSandboxPort(sandboxId: string, port: number, opts?: ConnectionOpts): Promise<{
|
|
161
|
+
hostname: string;
|
|
162
|
+
url: string;
|
|
163
|
+
}>;
|
|
159
164
|
}
|
|
160
165
|
|
|
161
166
|
/**
|
|
@@ -170,7 +175,7 @@ declare class SandboxClient {
|
|
|
170
175
|
* ```ts
|
|
171
176
|
* import { Sandbox } from 'lizard'
|
|
172
177
|
*
|
|
173
|
-
* const sandbox = await Sandbox.create('
|
|
178
|
+
* const sandbox = await Sandbox.create('base')
|
|
174
179
|
* await sandbox.fs.write('/app/index.js', 'console.log("hello world")')
|
|
175
180
|
* const result = await sandbox.process.exec('node /app/index.js')
|
|
176
181
|
* console.log(result.stdout) // "hello world"
|
|
@@ -179,7 +184,7 @@ declare class SandboxClient {
|
|
|
179
184
|
*
|
|
180
185
|
* @example Pause and resume a long-running session:
|
|
181
186
|
* ```ts
|
|
182
|
-
* const sandbox = await Sandbox.create('
|
|
187
|
+
* const sandbox = await Sandbox.create('code-interpreter-v1')
|
|
183
188
|
* await sandbox.process.exec('pip install numpy')
|
|
184
189
|
* const id = sandbox.sandboxId
|
|
185
190
|
* await sandbox.pause()
|
|
@@ -231,15 +236,16 @@ declare class Sandbox extends SandboxClient {
|
|
|
231
236
|
/**
|
|
232
237
|
* Create a new Lizard sandbox from the specified template.
|
|
233
238
|
*
|
|
234
|
-
* Available templates
|
|
235
|
-
* templates can be built and pushed via
|
|
239
|
+
* Available templates: `base` (Debian + Node.js 20) and `code-interpreter-v1`
|
|
240
|
+
* (Python 3.11 + Node.js 20). Custom templates can be built and pushed via
|
|
241
|
+
* `lizard push`.
|
|
236
242
|
*
|
|
237
243
|
* @param template Name of the sandbox template to boot from.
|
|
238
244
|
*
|
|
239
245
|
* @example
|
|
240
246
|
* ```ts
|
|
241
|
-
* const sandbox = await Sandbox.create('
|
|
242
|
-
* const sandbox = await Sandbox.create('
|
|
247
|
+
* const sandbox = await Sandbox.create('base')
|
|
248
|
+
* const sandbox = await Sandbox.create('code-interpreter-v1', { timeoutMs: 10 * 60 * 1000 })
|
|
243
249
|
* ```
|
|
244
250
|
*/
|
|
245
251
|
static create(template: string, opts?: SandboxOpts): Promise<Sandbox>;
|
|
@@ -305,10 +311,10 @@ declare class Sandbox extends SandboxClient {
|
|
|
305
311
|
* ```ts
|
|
306
312
|
* await sandbox.process.exec('npx -y serve -p 3000 &')
|
|
307
313
|
* const url = sandbox.getHost(3000)
|
|
308
|
-
* // https://{sandboxId}-3000.sandbox.
|
|
314
|
+
* // https://{sandboxId}-3000.sandbox.{region}.onlizard.com
|
|
309
315
|
* ```
|
|
310
316
|
*/
|
|
311
|
-
getHost(port: number): string
|
|
317
|
+
getHost(port: number, opts?: ConnectionOpts): Promise<string>;
|
|
312
318
|
private resolveOpts;
|
|
313
319
|
}
|
|
314
320
|
|
|
@@ -476,4 +482,34 @@ declare class CodeSandbox extends Sandbox {
|
|
|
476
482
|
static connect(sandboxId: string, opts?: ConnectionOpts): Promise<CodeSandbox>;
|
|
477
483
|
}
|
|
478
484
|
|
|
479
|
-
|
|
485
|
+
interface VolumeInfo {
|
|
486
|
+
id: string;
|
|
487
|
+
projectId: string;
|
|
488
|
+
name: string;
|
|
489
|
+
sizeGb: number;
|
|
490
|
+
sizeMb?: number;
|
|
491
|
+
status: string;
|
|
492
|
+
attachedTo?: string | null;
|
|
493
|
+
createdAt: number;
|
|
494
|
+
}
|
|
495
|
+
interface CreateVolumeOpts extends ConnectionOpts {
|
|
496
|
+
sizeGb?: number;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* A persistent volume that outlives sandboxes.
|
|
500
|
+
* Mount it to a sandbox via `Sandbox.create({ volumeId: volume.volumeId })`.
|
|
501
|
+
*/
|
|
502
|
+
declare class Volume {
|
|
503
|
+
readonly volumeId: string;
|
|
504
|
+
private readonly config;
|
|
505
|
+
constructor(opts: {
|
|
506
|
+
volumeId: string;
|
|
507
|
+
} & ConnectionOpts);
|
|
508
|
+
static create(projectId: string, name: string, opts?: CreateVolumeOpts): Promise<Volume>;
|
|
509
|
+
static get(projectId: string, volumeId: string, opts?: ConnectionOpts): Promise<Volume>;
|
|
510
|
+
static list(projectId: string, opts?: ConnectionOpts): Promise<VolumeInfo[]>;
|
|
511
|
+
getInfo(projectId: string): Promise<VolumeInfo>;
|
|
512
|
+
delete(projectId: string): Promise<void>;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
export { AuthenticationError, type CodeContext, CodeSandbox, type ConnectionOpts, type CreateContextOpts, type CreateVolumeOpts, Execution, ExecutionError, type FileInfo, type FsOpts, LizardError, NotFoundError, type ProcessOpts, type ProcessResult, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, TimeoutError, Volume, type VolumeInfo };
|
package/dist/index.js
CHANGED
|
@@ -25,12 +25,13 @@ __export(index_exports, {
|
|
|
25
25
|
LizardError: () => LizardError,
|
|
26
26
|
NotFoundError: () => NotFoundError,
|
|
27
27
|
Sandbox: () => Sandbox,
|
|
28
|
-
TimeoutError: () => TimeoutError
|
|
28
|
+
TimeoutError: () => TimeoutError,
|
|
29
|
+
Volume: () => Volume
|
|
29
30
|
});
|
|
30
31
|
module.exports = __toCommonJS(index_exports);
|
|
31
32
|
|
|
32
33
|
// src/config.ts
|
|
33
|
-
var DEFAULT_API_URL = "https://
|
|
34
|
+
var DEFAULT_API_URL = "https://lizard.build";
|
|
34
35
|
var DEFAULT_SANDBOX_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
35
36
|
var ConnectionConfig = class {
|
|
36
37
|
constructor(opts) {
|
|
@@ -240,7 +241,8 @@ var SandboxClient = class {
|
|
|
240
241
|
template,
|
|
241
242
|
timeoutMs,
|
|
242
243
|
metadata: opts?.metadata,
|
|
243
|
-
envs: opts?.envs
|
|
244
|
+
envs: opts?.envs,
|
|
245
|
+
volumeId: opts?.volumeId
|
|
244
246
|
})
|
|
245
247
|
});
|
|
246
248
|
if (!res.ok) await handleApiError(res);
|
|
@@ -301,6 +303,15 @@ var SandboxClient = class {
|
|
|
301
303
|
});
|
|
302
304
|
if (!res.ok) await handleApiError(res);
|
|
303
305
|
}
|
|
306
|
+
static async exposeSandboxPort(sandboxId, port, opts) {
|
|
307
|
+
const config = new ConnectionConfig(opts);
|
|
308
|
+
const res = await fetch(`${config.apiUrl}/api/sandboxes/${sandboxId}/expose/${port}`, {
|
|
309
|
+
method: "POST",
|
|
310
|
+
headers: config.headers
|
|
311
|
+
});
|
|
312
|
+
if (!res.ok) await handleApiError(res);
|
|
313
|
+
return res.json();
|
|
314
|
+
}
|
|
304
315
|
};
|
|
305
316
|
|
|
306
317
|
// src/sandbox/index.ts
|
|
@@ -396,13 +407,12 @@ var Sandbox = class extends SandboxClient {
|
|
|
396
407
|
* ```ts
|
|
397
408
|
* await sandbox.process.exec('npx -y serve -p 3000 &')
|
|
398
409
|
* const url = sandbox.getHost(3000)
|
|
399
|
-
* // https://{sandboxId}-3000.sandbox.
|
|
410
|
+
* // https://{sandboxId}-3000.sandbox.{region}.onlizard.com
|
|
400
411
|
* ```
|
|
401
412
|
*/
|
|
402
|
-
getHost(port) {
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
return `${this.sandboxId}-${port}.sandbox.${baseHost}`;
|
|
413
|
+
async getHost(port, opts) {
|
|
414
|
+
const { hostname } = await SandboxClient.exposeSandboxPort(this.sandboxId, port, this.resolveOpts(opts));
|
|
415
|
+
return hostname;
|
|
406
416
|
}
|
|
407
417
|
resolveOpts(opts) {
|
|
408
418
|
return { ...this.connectionConfig, ...opts };
|
|
@@ -442,7 +452,7 @@ var Execution = class {
|
|
|
442
452
|
var CODE_INTERPRETER_PORT = 8080;
|
|
443
453
|
var CodeSandbox = class extends Sandbox {
|
|
444
454
|
get serverUrl() {
|
|
445
|
-
return
|
|
455
|
+
return this.getHost(CODE_INTERPRETER_PORT).then((h) => `https://${h}`);
|
|
446
456
|
}
|
|
447
457
|
/**
|
|
448
458
|
* Execute code in a persistent kernel.
|
|
@@ -477,7 +487,7 @@ var CodeSandbox = class extends Sandbox {
|
|
|
477
487
|
const controller = new AbortController();
|
|
478
488
|
const timer = opts?.timeoutMs ? setTimeout(() => controller.abort(), opts.timeoutMs) : void 0;
|
|
479
489
|
try {
|
|
480
|
-
const res = await fetch(`${this.serverUrl}/execute`, {
|
|
490
|
+
const res = await fetch(`${await this.serverUrl}/execute`, {
|
|
481
491
|
method: "POST",
|
|
482
492
|
headers: { "Content-Type": "application/json" },
|
|
483
493
|
body: JSON.stringify(body),
|
|
@@ -537,7 +547,7 @@ var CodeSandbox = class extends Sandbox {
|
|
|
537
547
|
* ```
|
|
538
548
|
*/
|
|
539
549
|
async createContext(opts) {
|
|
540
|
-
const res = await fetch(`${this.serverUrl}/contexts`, {
|
|
550
|
+
const res = await fetch(`${await this.serverUrl}/contexts`, {
|
|
541
551
|
method: "POST",
|
|
542
552
|
headers: { "Content-Type": "application/json" },
|
|
543
553
|
body: JSON.stringify({
|
|
@@ -552,7 +562,7 @@ var CodeSandbox = class extends Sandbox {
|
|
|
552
562
|
* List all active execution contexts in this sandbox.
|
|
553
563
|
*/
|
|
554
564
|
async listContexts() {
|
|
555
|
-
const res = await fetch(`${this.serverUrl}/contexts`);
|
|
565
|
+
const res = await fetch(`${await this.serverUrl}/contexts`);
|
|
556
566
|
if (!res.ok) throw new Error(`Failed to list contexts: ${await res.text()}`);
|
|
557
567
|
return res.json();
|
|
558
568
|
}
|
|
@@ -561,7 +571,7 @@ var CodeSandbox = class extends Sandbox {
|
|
|
561
571
|
*/
|
|
562
572
|
async deleteContext(context) {
|
|
563
573
|
const id = typeof context === "string" ? context : context.id;
|
|
564
|
-
const res = await fetch(`${this.serverUrl}/contexts/${id}`, { method: "DELETE" });
|
|
574
|
+
const res = await fetch(`${await this.serverUrl}/contexts/${id}`, { method: "DELETE" });
|
|
565
575
|
if (!res.ok) throw new Error(`Failed to delete context: ${await res.text()}`);
|
|
566
576
|
}
|
|
567
577
|
/**
|
|
@@ -569,7 +579,7 @@ var CodeSandbox = class extends Sandbox {
|
|
|
569
579
|
*/
|
|
570
580
|
async restartContext(context) {
|
|
571
581
|
const id = typeof context === "string" ? context : context.id;
|
|
572
|
-
const res = await fetch(`${this.serverUrl}/contexts/${id}/restart`, { method: "POST" });
|
|
582
|
+
const res = await fetch(`${await this.serverUrl}/contexts/${id}/restart`, { method: "POST" });
|
|
573
583
|
if (!res.ok) throw new Error(`Failed to restart context: ${await res.text()}`);
|
|
574
584
|
}
|
|
575
585
|
static async create(templateOrOpts, opts) {
|
|
@@ -600,6 +610,55 @@ async function* readLines(body) {
|
|
|
600
610
|
reader.releaseLock();
|
|
601
611
|
}
|
|
602
612
|
}
|
|
613
|
+
|
|
614
|
+
// src/volume/index.ts
|
|
615
|
+
var Volume = class _Volume {
|
|
616
|
+
constructor(opts) {
|
|
617
|
+
this.volumeId = opts.volumeId;
|
|
618
|
+
this.config = new ConnectionConfig(opts);
|
|
619
|
+
}
|
|
620
|
+
static async create(projectId, name, opts) {
|
|
621
|
+
const config = new ConnectionConfig(opts);
|
|
622
|
+
const res = await fetch(`${config.apiUrl}/api/projects/${projectId}/volumes`, {
|
|
623
|
+
method: "POST",
|
|
624
|
+
headers: config.headers,
|
|
625
|
+
body: JSON.stringify({ name, sizeGb: opts?.sizeGb ?? 5 })
|
|
626
|
+
});
|
|
627
|
+
if (!res.ok) await handleApiError(res);
|
|
628
|
+
const vol = await res.json();
|
|
629
|
+
return new _Volume({ volumeId: vol.id, ...opts });
|
|
630
|
+
}
|
|
631
|
+
static async get(projectId, volumeId, opts) {
|
|
632
|
+
const config = new ConnectionConfig(opts);
|
|
633
|
+
const res = await fetch(`${config.apiUrl}/api/projects/${projectId}/volumes/${volumeId}`, {
|
|
634
|
+
headers: config.headers
|
|
635
|
+
});
|
|
636
|
+
if (!res.ok) await handleApiError(res);
|
|
637
|
+
return new _Volume({ volumeId, ...opts });
|
|
638
|
+
}
|
|
639
|
+
static async list(projectId, opts) {
|
|
640
|
+
const config = new ConnectionConfig(opts);
|
|
641
|
+
const res = await fetch(`${config.apiUrl}/api/projects/${projectId}/volumes`, {
|
|
642
|
+
headers: config.headers
|
|
643
|
+
});
|
|
644
|
+
if (!res.ok) await handleApiError(res);
|
|
645
|
+
return res.json();
|
|
646
|
+
}
|
|
647
|
+
async getInfo(projectId) {
|
|
648
|
+
const res = await fetch(`${this.config.apiUrl}/api/projects/${projectId}/volumes/${this.volumeId}`, {
|
|
649
|
+
headers: this.config.headers
|
|
650
|
+
});
|
|
651
|
+
if (!res.ok) await handleApiError(res);
|
|
652
|
+
return res.json();
|
|
653
|
+
}
|
|
654
|
+
async delete(projectId) {
|
|
655
|
+
const res = await fetch(`${this.config.apiUrl}/api/projects/${projectId}/volumes/${this.volumeId}`, {
|
|
656
|
+
method: "DELETE",
|
|
657
|
+
headers: this.config.headers
|
|
658
|
+
});
|
|
659
|
+
if (!res.ok) await handleApiError(res);
|
|
660
|
+
}
|
|
661
|
+
};
|
|
603
662
|
// Annotate the CommonJS export names for ESM import in node:
|
|
604
663
|
0 && (module.exports = {
|
|
605
664
|
AuthenticationError,
|
|
@@ -607,5 +666,6 @@ async function* readLines(body) {
|
|
|
607
666
|
LizardError,
|
|
608
667
|
NotFoundError,
|
|
609
668
|
Sandbox,
|
|
610
|
-
TimeoutError
|
|
669
|
+
TimeoutError,
|
|
670
|
+
Volume
|
|
611
671
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/config.ts
|
|
2
|
-
var DEFAULT_API_URL = "https://
|
|
2
|
+
var DEFAULT_API_URL = "https://lizard.build";
|
|
3
3
|
var DEFAULT_SANDBOX_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
4
4
|
var ConnectionConfig = class {
|
|
5
5
|
constructor(opts) {
|
|
@@ -209,7 +209,8 @@ var SandboxClient = class {
|
|
|
209
209
|
template,
|
|
210
210
|
timeoutMs,
|
|
211
211
|
metadata: opts?.metadata,
|
|
212
|
-
envs: opts?.envs
|
|
212
|
+
envs: opts?.envs,
|
|
213
|
+
volumeId: opts?.volumeId
|
|
213
214
|
})
|
|
214
215
|
});
|
|
215
216
|
if (!res.ok) await handleApiError(res);
|
|
@@ -270,6 +271,15 @@ var SandboxClient = class {
|
|
|
270
271
|
});
|
|
271
272
|
if (!res.ok) await handleApiError(res);
|
|
272
273
|
}
|
|
274
|
+
static async exposeSandboxPort(sandboxId, port, opts) {
|
|
275
|
+
const config = new ConnectionConfig(opts);
|
|
276
|
+
const res = await fetch(`${config.apiUrl}/api/sandboxes/${sandboxId}/expose/${port}`, {
|
|
277
|
+
method: "POST",
|
|
278
|
+
headers: config.headers
|
|
279
|
+
});
|
|
280
|
+
if (!res.ok) await handleApiError(res);
|
|
281
|
+
return res.json();
|
|
282
|
+
}
|
|
273
283
|
};
|
|
274
284
|
|
|
275
285
|
// src/sandbox/index.ts
|
|
@@ -365,13 +375,12 @@ var Sandbox = class extends SandboxClient {
|
|
|
365
375
|
* ```ts
|
|
366
376
|
* await sandbox.process.exec('npx -y serve -p 3000 &')
|
|
367
377
|
* const url = sandbox.getHost(3000)
|
|
368
|
-
* // https://{sandboxId}-3000.sandbox.
|
|
378
|
+
* // https://{sandboxId}-3000.sandbox.{region}.onlizard.com
|
|
369
379
|
* ```
|
|
370
380
|
*/
|
|
371
|
-
getHost(port) {
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
return `${this.sandboxId}-${port}.sandbox.${baseHost}`;
|
|
381
|
+
async getHost(port, opts) {
|
|
382
|
+
const { hostname } = await SandboxClient.exposeSandboxPort(this.sandboxId, port, this.resolveOpts(opts));
|
|
383
|
+
return hostname;
|
|
375
384
|
}
|
|
376
385
|
resolveOpts(opts) {
|
|
377
386
|
return { ...this.connectionConfig, ...opts };
|
|
@@ -411,7 +420,7 @@ var Execution = class {
|
|
|
411
420
|
var CODE_INTERPRETER_PORT = 8080;
|
|
412
421
|
var CodeSandbox = class extends Sandbox {
|
|
413
422
|
get serverUrl() {
|
|
414
|
-
return
|
|
423
|
+
return this.getHost(CODE_INTERPRETER_PORT).then((h) => `https://${h}`);
|
|
415
424
|
}
|
|
416
425
|
/**
|
|
417
426
|
* Execute code in a persistent kernel.
|
|
@@ -446,7 +455,7 @@ var CodeSandbox = class extends Sandbox {
|
|
|
446
455
|
const controller = new AbortController();
|
|
447
456
|
const timer = opts?.timeoutMs ? setTimeout(() => controller.abort(), opts.timeoutMs) : void 0;
|
|
448
457
|
try {
|
|
449
|
-
const res = await fetch(`${this.serverUrl}/execute`, {
|
|
458
|
+
const res = await fetch(`${await this.serverUrl}/execute`, {
|
|
450
459
|
method: "POST",
|
|
451
460
|
headers: { "Content-Type": "application/json" },
|
|
452
461
|
body: JSON.stringify(body),
|
|
@@ -506,7 +515,7 @@ var CodeSandbox = class extends Sandbox {
|
|
|
506
515
|
* ```
|
|
507
516
|
*/
|
|
508
517
|
async createContext(opts) {
|
|
509
|
-
const res = await fetch(`${this.serverUrl}/contexts`, {
|
|
518
|
+
const res = await fetch(`${await this.serverUrl}/contexts`, {
|
|
510
519
|
method: "POST",
|
|
511
520
|
headers: { "Content-Type": "application/json" },
|
|
512
521
|
body: JSON.stringify({
|
|
@@ -521,7 +530,7 @@ var CodeSandbox = class extends Sandbox {
|
|
|
521
530
|
* List all active execution contexts in this sandbox.
|
|
522
531
|
*/
|
|
523
532
|
async listContexts() {
|
|
524
|
-
const res = await fetch(`${this.serverUrl}/contexts`);
|
|
533
|
+
const res = await fetch(`${await this.serverUrl}/contexts`);
|
|
525
534
|
if (!res.ok) throw new Error(`Failed to list contexts: ${await res.text()}`);
|
|
526
535
|
return res.json();
|
|
527
536
|
}
|
|
@@ -530,7 +539,7 @@ var CodeSandbox = class extends Sandbox {
|
|
|
530
539
|
*/
|
|
531
540
|
async deleteContext(context) {
|
|
532
541
|
const id = typeof context === "string" ? context : context.id;
|
|
533
|
-
const res = await fetch(`${this.serverUrl}/contexts/${id}`, { method: "DELETE" });
|
|
542
|
+
const res = await fetch(`${await this.serverUrl}/contexts/${id}`, { method: "DELETE" });
|
|
534
543
|
if (!res.ok) throw new Error(`Failed to delete context: ${await res.text()}`);
|
|
535
544
|
}
|
|
536
545
|
/**
|
|
@@ -538,7 +547,7 @@ var CodeSandbox = class extends Sandbox {
|
|
|
538
547
|
*/
|
|
539
548
|
async restartContext(context) {
|
|
540
549
|
const id = typeof context === "string" ? context : context.id;
|
|
541
|
-
const res = await fetch(`${this.serverUrl}/contexts/${id}/restart`, { method: "POST" });
|
|
550
|
+
const res = await fetch(`${await this.serverUrl}/contexts/${id}/restart`, { method: "POST" });
|
|
542
551
|
if (!res.ok) throw new Error(`Failed to restart context: ${await res.text()}`);
|
|
543
552
|
}
|
|
544
553
|
static async create(templateOrOpts, opts) {
|
|
@@ -569,11 +578,61 @@ async function* readLines(body) {
|
|
|
569
578
|
reader.releaseLock();
|
|
570
579
|
}
|
|
571
580
|
}
|
|
581
|
+
|
|
582
|
+
// src/volume/index.ts
|
|
583
|
+
var Volume = class _Volume {
|
|
584
|
+
constructor(opts) {
|
|
585
|
+
this.volumeId = opts.volumeId;
|
|
586
|
+
this.config = new ConnectionConfig(opts);
|
|
587
|
+
}
|
|
588
|
+
static async create(projectId, name, opts) {
|
|
589
|
+
const config = new ConnectionConfig(opts);
|
|
590
|
+
const res = await fetch(`${config.apiUrl}/api/projects/${projectId}/volumes`, {
|
|
591
|
+
method: "POST",
|
|
592
|
+
headers: config.headers,
|
|
593
|
+
body: JSON.stringify({ name, sizeGb: opts?.sizeGb ?? 5 })
|
|
594
|
+
});
|
|
595
|
+
if (!res.ok) await handleApiError(res);
|
|
596
|
+
const vol = await res.json();
|
|
597
|
+
return new _Volume({ volumeId: vol.id, ...opts });
|
|
598
|
+
}
|
|
599
|
+
static async get(projectId, volumeId, opts) {
|
|
600
|
+
const config = new ConnectionConfig(opts);
|
|
601
|
+
const res = await fetch(`${config.apiUrl}/api/projects/${projectId}/volumes/${volumeId}`, {
|
|
602
|
+
headers: config.headers
|
|
603
|
+
});
|
|
604
|
+
if (!res.ok) await handleApiError(res);
|
|
605
|
+
return new _Volume({ volumeId, ...opts });
|
|
606
|
+
}
|
|
607
|
+
static async list(projectId, opts) {
|
|
608
|
+
const config = new ConnectionConfig(opts);
|
|
609
|
+
const res = await fetch(`${config.apiUrl}/api/projects/${projectId}/volumes`, {
|
|
610
|
+
headers: config.headers
|
|
611
|
+
});
|
|
612
|
+
if (!res.ok) await handleApiError(res);
|
|
613
|
+
return res.json();
|
|
614
|
+
}
|
|
615
|
+
async getInfo(projectId) {
|
|
616
|
+
const res = await fetch(`${this.config.apiUrl}/api/projects/${projectId}/volumes/${this.volumeId}`, {
|
|
617
|
+
headers: this.config.headers
|
|
618
|
+
});
|
|
619
|
+
if (!res.ok) await handleApiError(res);
|
|
620
|
+
return res.json();
|
|
621
|
+
}
|
|
622
|
+
async delete(projectId) {
|
|
623
|
+
const res = await fetch(`${this.config.apiUrl}/api/projects/${projectId}/volumes/${this.volumeId}`, {
|
|
624
|
+
method: "DELETE",
|
|
625
|
+
headers: this.config.headers
|
|
626
|
+
});
|
|
627
|
+
if (!res.ok) await handleApiError(res);
|
|
628
|
+
}
|
|
629
|
+
};
|
|
572
630
|
export {
|
|
573
631
|
AuthenticationError,
|
|
574
632
|
CodeSandbox,
|
|
575
633
|
LizardError,
|
|
576
634
|
NotFoundError,
|
|
577
635
|
Sandbox,
|
|
578
|
-
TimeoutError
|
|
636
|
+
TimeoutError,
|
|
637
|
+
Volume
|
|
579
638
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lizard-build/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"description": "Lizard SDK — cloud sandboxes for AI agents",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -29,6 +29,12 @@
|
|
|
29
29
|
"firecracker"
|
|
30
30
|
],
|
|
31
31
|
"license": "Apache-2.0",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/lizard-build/lizard-sdk.git",
|
|
35
|
+
"directory": "packages/js"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://lizard.build",
|
|
32
38
|
"devDependencies": {
|
|
33
39
|
"@types/node": "^20.0.0",
|
|
34
40
|
"tsup": "^8.0.0",
|