agentkernel 0.8.0 → 0.9.0
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 +138 -3
- package/dist/index.cjs +72 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -5
- package/dist/index.d.ts +57 -5
- package/dist/index.js +72 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,6 +37,105 @@ console.log(result.output);
|
|
|
37
37
|
// sandbox auto-removed when scope exits
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
## Exec Options
|
|
41
|
+
|
|
42
|
+
Run commands with a working directory, environment variables, or as root:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
const result = await client.execInSandbox("my-sandbox", ["npm", "start"], {
|
|
46
|
+
workdir: "/app",
|
|
47
|
+
env: ["NODE_ENV=production"],
|
|
48
|
+
sudo: true,
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Works on sandbox sessions too:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
await using sb = await client.sandbox("dev");
|
|
56
|
+
await sb.run(["pip", "install", "-r", "requirements.txt"], {
|
|
57
|
+
workdir: "/app",
|
|
58
|
+
sudo: true,
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Git Source Cloning
|
|
63
|
+
|
|
64
|
+
Clone a git repo into the sandbox at creation time:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
const sb = await client.createSandbox("my-project", {
|
|
68
|
+
image: "node:20-alpine",
|
|
69
|
+
source_url: "https://github.com/user/repo.git",
|
|
70
|
+
source_ref: "main",
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Persistent Volumes
|
|
75
|
+
|
|
76
|
+
Mount volumes that persist across sandbox restarts:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// First create volumes via CLI: agentkernel volume create mydata
|
|
80
|
+
|
|
81
|
+
const sb = await client.createSandbox("my-project", {
|
|
82
|
+
image: "node:20-alpine",
|
|
83
|
+
volumes: ["mydata:/data", "cache:/tmp/cache:ro"],
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Data in /data persists across sandbox restarts
|
|
87
|
+
await sb.run(["sh", "-c", "echo hello > /data/test.txt"]);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## File Operations
|
|
91
|
+
|
|
92
|
+
Read, write, and delete files in a sandbox:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// Write a file
|
|
96
|
+
await client.writeFile("my-sandbox", "app/main.py", "print('hello')");
|
|
97
|
+
|
|
98
|
+
// Read a file
|
|
99
|
+
const file = await client.readFile("my-sandbox", "app/main.py");
|
|
100
|
+
console.log(file.content);
|
|
101
|
+
|
|
102
|
+
// Delete a file
|
|
103
|
+
await client.deleteFile("my-sandbox", "app/main.py");
|
|
104
|
+
|
|
105
|
+
// Batch write multiple files at once
|
|
106
|
+
await client.writeFiles("my-sandbox", {
|
|
107
|
+
"/app/index.js": "console.log('hi')",
|
|
108
|
+
"/app/package.json": '{"name":"app"}',
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Detached Commands
|
|
113
|
+
|
|
114
|
+
Run long-lived processes in the background and retrieve their output later:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// Start a background process
|
|
118
|
+
const cmd = await client.execDetached("my-sandbox", ["python3", "train.py"]);
|
|
119
|
+
console.log(`Started: ${cmd.id} (pid ${cmd.pid})`);
|
|
120
|
+
|
|
121
|
+
// Check status
|
|
122
|
+
const status = await client.detachedStatus("my-sandbox", cmd.id);
|
|
123
|
+
console.log(status.status); // "running" | "completed" | "failed"
|
|
124
|
+
|
|
125
|
+
// Get logs
|
|
126
|
+
const logs = await client.detachedLogs("my-sandbox", cmd.id);
|
|
127
|
+
console.log(logs.stdout);
|
|
128
|
+
|
|
129
|
+
// Get stderr only
|
|
130
|
+
const stderr = await client.detachedLogs("my-sandbox", cmd.id, "stderr");
|
|
131
|
+
|
|
132
|
+
// List all detached commands
|
|
133
|
+
const all = await client.detachedList("my-sandbox");
|
|
134
|
+
|
|
135
|
+
// Kill a running command
|
|
136
|
+
await client.detachedKill("my-sandbox", cmd.id);
|
|
137
|
+
```
|
|
138
|
+
|
|
40
139
|
## Streaming
|
|
41
140
|
|
|
42
141
|
```typescript
|
|
@@ -91,7 +190,7 @@ List all sandboxes.
|
|
|
91
190
|
|
|
92
191
|
### `client.createSandbox(name, options?)`
|
|
93
192
|
|
|
94
|
-
Create a new sandbox.
|
|
193
|
+
Create a new sandbox. Options: `image`, `vcpus`, `memory_mb`, `profile`, `source_url`, `source_ref`, `volumes`.
|
|
95
194
|
|
|
96
195
|
### `client.getSandbox(name)`
|
|
97
196
|
|
|
@@ -101,9 +200,45 @@ Get sandbox info.
|
|
|
101
200
|
|
|
102
201
|
Remove a sandbox.
|
|
103
202
|
|
|
104
|
-
### `client.execInSandbox(name, command)`
|
|
203
|
+
### `client.execInSandbox(name, command, options?)`
|
|
204
|
+
|
|
205
|
+
Run a command in an existing sandbox. Options: `env`, `workdir`, `sudo`.
|
|
206
|
+
|
|
207
|
+
### `client.readFile(name, path)`
|
|
208
|
+
|
|
209
|
+
Read a file from a sandbox.
|
|
210
|
+
|
|
211
|
+
### `client.writeFile(name, path, content, options?)`
|
|
212
|
+
|
|
213
|
+
Write a file to a sandbox.
|
|
214
|
+
|
|
215
|
+
### `client.deleteFile(name, path)`
|
|
216
|
+
|
|
217
|
+
Delete a file from a sandbox.
|
|
218
|
+
|
|
219
|
+
### `client.writeFiles(name, files)`
|
|
220
|
+
|
|
221
|
+
Write multiple files to a sandbox in one request. `files` is a `Record<string, string>` of path to content.
|
|
222
|
+
|
|
223
|
+
### `client.execDetached(name, command, options?)`
|
|
224
|
+
|
|
225
|
+
Start a detached (background) command. Returns a `DetachedCommand`.
|
|
226
|
+
|
|
227
|
+
### `client.detachedStatus(name, cmdId)`
|
|
228
|
+
|
|
229
|
+
Get the status of a detached command.
|
|
230
|
+
|
|
231
|
+
### `client.detachedLogs(name, cmdId, stream?)`
|
|
232
|
+
|
|
233
|
+
Get stdout/stderr from a detached command. Pass `"stderr"` to get only stderr.
|
|
234
|
+
|
|
235
|
+
### `client.detachedKill(name, cmdId)`
|
|
236
|
+
|
|
237
|
+
Kill a detached command.
|
|
238
|
+
|
|
239
|
+
### `client.detachedList(name)`
|
|
105
240
|
|
|
106
|
-
|
|
241
|
+
List all detached commands in a sandbox.
|
|
107
242
|
|
|
108
243
|
### `client.sandbox(name, options?)`
|
|
109
244
|
|
package/dist/index.cjs
CHANGED
|
@@ -120,21 +120,27 @@ var SandboxSession = class {
|
|
|
120
120
|
_execInSandbox;
|
|
121
121
|
_removeSandbox;
|
|
122
122
|
_getSandbox;
|
|
123
|
+
_writeFiles;
|
|
123
124
|
/** @internal */
|
|
124
|
-
constructor(name, execInSandbox, removeSandbox, getSandbox) {
|
|
125
|
+
constructor(name, execInSandbox, removeSandbox, getSandbox, writeFiles) {
|
|
125
126
|
this.name = name;
|
|
126
127
|
this._execInSandbox = execInSandbox;
|
|
127
128
|
this._removeSandbox = removeSandbox;
|
|
128
129
|
this._getSandbox = getSandbox;
|
|
130
|
+
this._writeFiles = writeFiles;
|
|
129
131
|
}
|
|
130
132
|
/** Run a command in this sandbox. */
|
|
131
|
-
async run(command) {
|
|
132
|
-
return this._execInSandbox(this.name, command);
|
|
133
|
+
async run(command, opts) {
|
|
134
|
+
return this._execInSandbox(this.name, command, opts);
|
|
133
135
|
}
|
|
134
136
|
/** Get sandbox info. */
|
|
135
137
|
async info() {
|
|
136
138
|
return this._getSandbox(this.name);
|
|
137
139
|
}
|
|
140
|
+
/** Write multiple files in one request. */
|
|
141
|
+
async writeFiles(files) {
|
|
142
|
+
return this._writeFiles(this.name, files);
|
|
143
|
+
}
|
|
138
144
|
/** Remove the sandbox. Idempotent. */
|
|
139
145
|
async remove() {
|
|
140
146
|
if (this._removed) return;
|
|
@@ -285,7 +291,9 @@ var AgentKernel = class {
|
|
|
285
291
|
image: opts?.image,
|
|
286
292
|
vcpus: opts?.vcpus,
|
|
287
293
|
memory_mb: opts?.memory_mb,
|
|
288
|
-
profile: opts?.profile
|
|
294
|
+
profile: opts?.profile,
|
|
295
|
+
source_url: opts?.source_url,
|
|
296
|
+
source_ref: opts?.source_ref
|
|
289
297
|
});
|
|
290
298
|
}
|
|
291
299
|
/** Get info about a sandbox. */
|
|
@@ -297,11 +305,16 @@ var AgentKernel = class {
|
|
|
297
305
|
await this.request("DELETE", `/sandboxes/${encodeURIComponent(name)}`);
|
|
298
306
|
}
|
|
299
307
|
/** Run a command in an existing sandbox. */
|
|
300
|
-
async execInSandbox(name, command) {
|
|
308
|
+
async execInSandbox(name, command, opts) {
|
|
301
309
|
return this.request(
|
|
302
310
|
"POST",
|
|
303
311
|
`/sandboxes/${encodeURIComponent(name)}/exec`,
|
|
304
|
-
{
|
|
312
|
+
{
|
|
313
|
+
command,
|
|
314
|
+
env: opts?.env,
|
|
315
|
+
workdir: opts?.workdir,
|
|
316
|
+
sudo: opts?.sudo
|
|
317
|
+
}
|
|
305
318
|
);
|
|
306
319
|
}
|
|
307
320
|
/** Read a file from a sandbox. */
|
|
@@ -333,10 +346,60 @@ var AgentKernel = class {
|
|
|
333
346
|
`/sandboxes/${encodeURIComponent(name)}/logs`
|
|
334
347
|
);
|
|
335
348
|
}
|
|
349
|
+
/** Write multiple files to a sandbox in one request. */
|
|
350
|
+
async writeFiles(name, files) {
|
|
351
|
+
return this.request(
|
|
352
|
+
"POST",
|
|
353
|
+
`/sandboxes/${encodeURIComponent(name)}/files`,
|
|
354
|
+
{ files }
|
|
355
|
+
);
|
|
356
|
+
}
|
|
336
357
|
/** Run multiple commands in parallel. */
|
|
337
358
|
async batchRun(commands) {
|
|
338
359
|
return this.request("POST", "/batch/run", { commands });
|
|
339
360
|
}
|
|
361
|
+
/** Start a detached (background) command in a sandbox. */
|
|
362
|
+
async execDetached(name, command, opts) {
|
|
363
|
+
return this.request(
|
|
364
|
+
"POST",
|
|
365
|
+
`/sandboxes/${encodeURIComponent(name)}/exec/detach`,
|
|
366
|
+
{
|
|
367
|
+
command,
|
|
368
|
+
env: opts?.env,
|
|
369
|
+
workdir: opts?.workdir,
|
|
370
|
+
sudo: opts?.sudo
|
|
371
|
+
}
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
/** Get the status of a detached command. */
|
|
375
|
+
async detachedStatus(name, cmdId) {
|
|
376
|
+
return this.request(
|
|
377
|
+
"GET",
|
|
378
|
+
`/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}`
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
/** Get logs from a detached command. */
|
|
382
|
+
async detachedLogs(name, cmdId, stream) {
|
|
383
|
+
const query = stream === "stderr" ? "?stream=stderr" : "";
|
|
384
|
+
return this.request(
|
|
385
|
+
"GET",
|
|
386
|
+
`/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}/logs${query}`
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
/** Kill a detached command. */
|
|
390
|
+
async detachedKill(name, cmdId) {
|
|
391
|
+
return this.request(
|
|
392
|
+
"DELETE",
|
|
393
|
+
`/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}`
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
/** List detached commands in a sandbox. */
|
|
397
|
+
async detachedList(name) {
|
|
398
|
+
return this.request(
|
|
399
|
+
"GET",
|
|
400
|
+
`/sandboxes/${encodeURIComponent(name)}/exec/detached`
|
|
401
|
+
);
|
|
402
|
+
}
|
|
340
403
|
/**
|
|
341
404
|
* Create a sandbox session with automatic cleanup.
|
|
342
405
|
*
|
|
@@ -354,9 +417,10 @@ var AgentKernel = class {
|
|
|
354
417
|
await this.createSandbox(name, opts);
|
|
355
418
|
return new SandboxSession(
|
|
356
419
|
name,
|
|
357
|
-
(n, cmd) => this.execInSandbox(n, cmd),
|
|
420
|
+
(n, cmd, o) => this.execInSandbox(n, cmd, o),
|
|
358
421
|
(n) => this.removeSandbox(n),
|
|
359
|
-
(n) => this.getSandbox(n)
|
|
422
|
+
(n) => this.getSandbox(n),
|
|
423
|
+
(n, f) => this.writeFiles(n, f)
|
|
360
424
|
);
|
|
361
425
|
}
|
|
362
426
|
// -- Internal helpers --
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/errors.ts","../src/sandbox.ts","../src/sse.ts","../src/client.ts"],"sourcesContent":["export { AgentKernel } from \"./client.js\";\nexport { SandboxSession } from \"./sandbox.js\";\nexport {\n AgentKernelError,\n AuthError,\n NotFoundError,\n ValidationError,\n ServerError,\n NetworkError,\n StreamError,\n} from \"./errors.js\";\nexport type {\n AgentKernelOptions,\n RunOptions,\n CreateSandboxOptions,\n RunOutput,\n SandboxInfo,\n StreamEvent,\n StreamEventType,\n SecurityProfile,\n SandboxStatus,\n ApiResponse,\n} from \"./types.js\";\n","import type { AgentKernelOptions } from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"http://localhost:18888\";\nconst DEFAULT_TIMEOUT = 30_000;\n\n/** Resolve configuration from constructor args, env vars, and defaults. */\nexport function resolveConfig(opts?: AgentKernelOptions) {\n const baseUrl =\n opts?.baseUrl ??\n process.env.AGENTKERNEL_BASE_URL ??\n DEFAULT_BASE_URL;\n\n const apiKey =\n opts?.apiKey ??\n process.env.AGENTKERNEL_API_KEY ??\n undefined;\n\n const timeout = opts?.timeout ?? DEFAULT_TIMEOUT;\n\n return {\n baseUrl: baseUrl.replace(/\\/+$/, \"\"),\n apiKey,\n timeout,\n };\n}\n","/** Base error for all agentkernel SDK errors. */\nexport class AgentKernelError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AgentKernelError\";\n }\n}\n\n/** 401 Unauthorized. */\nexport class AuthError extends AgentKernelError {\n readonly status = 401;\n constructor(message = \"Unauthorized\") {\n super(message);\n this.name = \"AuthError\";\n }\n}\n\n/** 404 Not Found. */\nexport class NotFoundError extends AgentKernelError {\n readonly status = 404;\n constructor(message = \"Not found\") {\n super(message);\n this.name = \"NotFoundError\";\n }\n}\n\n/** 400 Bad Request. */\nexport class ValidationError extends AgentKernelError {\n readonly status = 400;\n constructor(message = \"Bad request\") {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\n/** 500 Internal Server Error. */\nexport class ServerError extends AgentKernelError {\n readonly status = 500;\n constructor(message = \"Internal server error\") {\n super(message);\n this.name = \"ServerError\";\n }\n}\n\n/** Network / connection error. */\nexport class NetworkError extends AgentKernelError {\n constructor(message = \"Network error\") {\n super(message);\n this.name = \"NetworkError\";\n }\n}\n\n/** SSE streaming error. */\nexport class StreamError extends AgentKernelError {\n constructor(message = \"Stream error\") {\n super(message);\n this.name = \"StreamError\";\n }\n}\n\n/** Map an HTTP status code + body to the appropriate error. */\nexport function errorFromStatus(status: number, body: string): AgentKernelError {\n let message: string;\n try {\n const parsed = JSON.parse(body);\n message = parsed.error ?? body;\n } catch {\n message = body;\n }\n\n switch (status) {\n case 400:\n return new ValidationError(message);\n case 401:\n return new AuthError(message);\n case 404:\n return new NotFoundError(message);\n default:\n return new ServerError(message);\n }\n}\n","import type { RunOutput, SandboxInfo } from \"./types.js\";\n\ntype ExecFn = (name: string, command: string[]) => Promise<RunOutput>;\ntype RemoveFn = (name: string) => Promise<void>;\ntype GetFn = (name: string) => Promise<SandboxInfo>;\n\n/**\n * A sandbox session that auto-removes the sandbox on dispose.\n *\n * Supports both explicit cleanup via remove() and automatic cleanup via\n * Symbol.asyncDispose (TS 5.2+ `await using`).\n *\n * @example\n * ```ts\n * await using sb = await client.sandbox(\"test\");\n * await sb.exec([\"echo\", \"hello\"]);\n * // sandbox auto-removed when scope exits\n * ```\n */\nexport class SandboxSession implements AsyncDisposable {\n readonly name: string;\n private _removed = false;\n private readonly _execInSandbox: ExecFn;\n private readonly _removeSandbox: RemoveFn;\n private readonly _getSandbox: GetFn;\n\n /** @internal */\n constructor(\n name: string,\n execInSandbox: ExecFn,\n removeSandbox: RemoveFn,\n getSandbox: GetFn,\n ) {\n this.name = name;\n this._execInSandbox = execInSandbox;\n this._removeSandbox = removeSandbox;\n this._getSandbox = getSandbox;\n }\n\n /** Run a command in this sandbox. */\n async run(command: string[]): Promise<RunOutput> {\n return this._execInSandbox(this.name, command);\n }\n\n /** Get sandbox info. */\n async info(): Promise<SandboxInfo> {\n return this._getSandbox(this.name);\n }\n\n /** Remove the sandbox. Idempotent. */\n async remove(): Promise<void> {\n if (this._removed) return;\n this._removed = true;\n await this._removeSandbox(this.name);\n }\n\n /** Auto-cleanup for `await using`. */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.remove();\n }\n}\n","import { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport type { StreamEvent, StreamEventType } from \"./types.js\";\n\nconst KNOWN_EVENTS = new Set<string>([\"started\", \"progress\", \"output\", \"done\", \"error\"]);\n\n/** Shared mutable state between the pump and the generator. */\ninterface PumpState {\n events: StreamEvent[];\n resolve: (() => void) | null;\n done: boolean;\n}\n\nfunction pushEvent(state: PumpState, event: StreamEvent): void {\n state.events.push(event);\n if (state.resolve) {\n const cb = state.resolve;\n state.resolve = null;\n cb();\n }\n}\n\n/**\n * Parse an SSE response body into an async generator of StreamEvents.\n *\n * Consumes a ReadableStream<Uint8Array> from fetch() and yields typed events\n * until the stream closes or a \"done\"/\"error\" event is received.\n */\nexport async function* parseSSE(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<StreamEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n const state: PumpState = { events: [], resolve: null, done: false };\n\n const parser = createParser({\n onEvent(event: EventSourceMessage) {\n const type = event.event ?? \"message\";\n if (!KNOWN_EVENTS.has(type)) return;\n\n let data: Record<string, unknown>;\n try {\n data = JSON.parse(event.data);\n } catch {\n data = { raw: event.data };\n }\n\n pushEvent(state, { type: type as StreamEventType, data });\n },\n });\n\n // Read the stream in the background\n const pump = (async () => {\n try {\n for (;;) {\n const result = await reader.read();\n if (result.done) break;\n parser.feed(decoder.decode(result.value, { stream: true }));\n }\n } catch (err) {\n pushEvent(state, {\n type: \"error\",\n data: { message: err instanceof Error ? err.message : String(err) },\n });\n } finally {\n state.done = true;\n if (state.resolve) {\n const cb = state.resolve;\n state.resolve = null;\n cb();\n }\n }\n })();\n\n try {\n for (;;) {\n // Yield all buffered events\n while (state.events.length > 0) {\n const event = state.events.shift()!;\n yield event;\n if (event.type === \"done\" || event.type === \"error\") return;\n }\n\n // If the stream is done and no more events, exit\n if (state.done) return;\n\n // Wait for the next event\n await new Promise<void>((r) => {\n state.resolve = r;\n });\n }\n } finally {\n reader.cancel().catch(() => {});\n await pump.catch(() => {});\n }\n}\n","import { resolveConfig } from \"./config.js\";\nimport {\n AgentKernelError,\n NetworkError,\n errorFromStatus,\n} from \"./errors.js\";\nimport { SandboxSession } from \"./sandbox.js\";\nimport { parseSSE } from \"./sse.js\";\nimport type {\n AgentKernelOptions,\n ApiResponse,\n BatchCommand,\n BatchRunResponse,\n CreateSandboxOptions,\n FileReadResponse,\n FileWriteOptions,\n RunOptions,\n RunOutput,\n SandboxInfo,\n StreamEvent,\n} from \"./types.js\";\n\nconst SDK_VERSION = \"0.4.0\";\n\n/**\n * Client for the agentkernel HTTP API.\n *\n * @example\n * ```ts\n * const client = new AgentKernel();\n * const result = await client.run([\"echo\", \"hello\"]);\n * console.log(result.output); // \"hello\\n\"\n * ```\n */\nexport class AgentKernel {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly timeout: number;\n\n constructor(opts?: AgentKernelOptions) {\n const config = resolveConfig(opts);\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n this.timeout = config.timeout;\n }\n\n // -- Core API methods --\n\n /** Health check. Returns \"ok\" if the server is running. */\n async health(): Promise<string> {\n const res = await this.request<string>(\"GET\", \"/health\");\n return res;\n }\n\n /** Run a command in a temporary sandbox. */\n async run(command: string[], opts?: RunOptions): Promise<RunOutput> {\n return this.request<RunOutput>(\"POST\", \"/run\", {\n command,\n image: opts?.image,\n profile: opts?.profile,\n fast: opts?.fast ?? true,\n });\n }\n\n /**\n * Run a command with SSE streaming output.\n *\n * @example\n * ```ts\n * for await (const event of client.runStream([\"python3\", \"script.py\"])) {\n * if (event.type === \"output\") process.stdout.write(String(event.data.data));\n * }\n * ```\n */\n async *runStream(\n command: string[],\n opts?: RunOptions,\n ): AsyncGenerator<StreamEvent> {\n const body = JSON.stringify({\n command,\n image: opts?.image,\n profile: opts?.profile,\n fast: opts?.fast ?? true,\n });\n\n const response = await this.fetch(\"/run/stream\", {\n method: \"POST\",\n headers: this.headers(\"application/json\"),\n body,\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw errorFromStatus(response.status, text);\n }\n\n if (!response.body) {\n throw new AgentKernelError(\"No response body for SSE stream\");\n }\n\n yield* parseSSE(response.body);\n }\n\n /** List all sandboxes. */\n async listSandboxes(): Promise<SandboxInfo[]> {\n return this.request<SandboxInfo[]>(\"GET\", \"/sandboxes\");\n }\n\n /** Create a new sandbox. */\n async createSandbox(\n name: string,\n opts?: CreateSandboxOptions,\n ): Promise<SandboxInfo> {\n return this.request<SandboxInfo>(\"POST\", \"/sandboxes\", {\n name,\n image: opts?.image,\n vcpus: opts?.vcpus,\n memory_mb: opts?.memory_mb,\n profile: opts?.profile,\n });\n }\n\n /** Get info about a sandbox. */\n async getSandbox(name: string): Promise<SandboxInfo> {\n return this.request<SandboxInfo>(\"GET\", `/sandboxes/${encodeURIComponent(name)}`);\n }\n\n /** Remove a sandbox. */\n async removeSandbox(name: string): Promise<void> {\n await this.request<string>(\"DELETE\", `/sandboxes/${encodeURIComponent(name)}`);\n }\n\n /** Run a command in an existing sandbox. */\n async execInSandbox(name: string, command: string[]): Promise<RunOutput> {\n return this.request<RunOutput>(\n \"POST\",\n `/sandboxes/${encodeURIComponent(name)}/exec`,\n { command },\n );\n }\n\n /** Read a file from a sandbox. */\n async readFile(name: string, path: string): Promise<FileReadResponse> {\n return this.request<FileReadResponse>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n );\n }\n\n /** Write a file to a sandbox. */\n async writeFile(\n name: string,\n path: string,\n content: string,\n opts?: FileWriteOptions,\n ): Promise<string> {\n return this.request<string>(\n \"PUT\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n { content, encoding: opts?.encoding ?? \"utf8\" },\n );\n }\n\n /** Delete a file from a sandbox. */\n async deleteFile(name: string, path: string): Promise<string> {\n return this.request<string>(\n \"DELETE\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n );\n }\n\n /** Get audit log entries for a sandbox. */\n async getSandboxLogs(name: string): Promise<Record<string, unknown>[]> {\n return this.request<Record<string, unknown>[]>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/logs`,\n );\n }\n\n /** Run multiple commands in parallel. */\n async batchRun(commands: BatchCommand[]): Promise<BatchRunResponse> {\n return this.request<BatchRunResponse>(\"POST\", \"/batch/run\", { commands });\n }\n\n /**\n * Create a sandbox session with automatic cleanup.\n *\n * The returned SandboxSession implements AsyncDisposable,\n * so it works with `await using` (TS 5.2+):\n *\n * @example\n * ```ts\n * await using sb = await client.sandbox(\"test\", { image: \"python:3.12-alpine\" });\n * await sb.run([\"pip\", \"install\", \"numpy\"]);\n * // sandbox auto-removed when scope exits\n * ```\n */\n async sandbox(\n name: string,\n opts?: CreateSandboxOptions,\n ): Promise<SandboxSession> {\n await this.createSandbox(name, opts);\n return new SandboxSession(\n name,\n (n, cmd) => this.execInSandbox(n, cmd),\n (n) => this.removeSandbox(n),\n (n) => this.getSandbox(n),\n );\n }\n\n // -- Internal helpers --\n\n private headers(contentType?: string): Record<string, string> {\n const h: Record<string, string> = {\n \"User-Agent\": `agentkernel-nodejs-sdk/${SDK_VERSION}`,\n };\n if (contentType) h[\"Content-Type\"] = contentType;\n if (this.apiKey) h[\"Authorization\"] = `Bearer ${this.apiKey}`;\n return h;\n }\n\n private async fetch(path: string, init: RequestInit): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n try {\n return await fetch(url, {\n ...init,\n signal: AbortSignal.timeout(this.timeout),\n });\n } catch (err) {\n if (err instanceof DOMException && err.name === \"TimeoutError\") {\n throw new NetworkError(`Request timed out after ${this.timeout}ms`);\n }\n if (err instanceof TypeError) {\n throw new NetworkError(`Failed to connect to ${this.baseUrl}: ${err.message}`);\n }\n throw new NetworkError(\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: this.headers(body ? \"application/json\" : undefined),\n };\n if (body) init.body = JSON.stringify(body);\n\n const response = await this.fetch(path, init);\n\n const text = await response.text();\n if (!response.ok) {\n throw errorFromStatus(response.status, text);\n }\n\n const parsed: ApiResponse<T> = JSON.parse(text);\n if (!parsed.success) {\n throw new AgentKernelError(parsed.error ?? \"Unknown error\");\n }\n return parsed.data as T;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAM,mBAAmB;AACzB,IAAM,kBAAkB;AAGjB,SAAS,cAAc,MAA2B;AACvD,QAAM,UACJ,MAAM,WACN,QAAQ,IAAI,wBACZ;AAEF,QAAM,SACJ,MAAM,UACN,QAAQ,IAAI,uBACZ;AAEF,QAAM,UAAU,MAAM,WAAW;AAEjC,SAAO;AAAA,IACL,SAAS,QAAQ,QAAQ,QAAQ,EAAE;AAAA,IACnC;AAAA,IACA;AAAA,EACF;AACF;;;ACvBO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,YAAN,cAAwB,iBAAiB;AAAA,EACrC,SAAS;AAAA,EAClB,YAAY,UAAU,gBAAgB;AACpC,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,gBAAN,cAA4B,iBAAiB;AAAA,EACzC,SAAS;AAAA,EAClB,YAAY,UAAU,aAAa;AACjC,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,kBAAN,cAA8B,iBAAiB;AAAA,EAC3C,SAAS;AAAA,EAClB,YAAY,UAAU,eAAe;AACnC,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,cAAN,cAA0B,iBAAiB;AAAA,EACvC,SAAS;AAAA,EAClB,YAAY,UAAU,yBAAyB;AAC7C,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,eAAN,cAA2B,iBAAiB;AAAA,EACjD,YAAY,UAAU,iBAAiB;AACrC,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,cAAN,cAA0B,iBAAiB;AAAA,EAChD,YAAY,UAAU,gBAAgB;AACpC,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,SAAS,gBAAgB,QAAgB,MAAgC;AAC9E,MAAI;AACJ,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,cAAU,OAAO,SAAS;AAAA,EAC5B,QAAQ;AACN,cAAU;AAAA,EACZ;AAEA,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,IAAI,gBAAgB,OAAO;AAAA,IACpC,KAAK;AACH,aAAO,IAAI,UAAU,OAAO;AAAA,IAC9B,KAAK;AACH,aAAO,IAAI,cAAc,OAAO;AAAA,IAClC;AACE,aAAO,IAAI,YAAY,OAAO;AAAA,EAClC;AACF;;;AC7DO,IAAM,iBAAN,MAAgD;AAAA,EAC5C;AAAA,EACD,WAAW;AAAA,EACF;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAGjB,YACE,MACA,eACA,eACA,YACA;AACA,SAAK,OAAO;AACZ,SAAK,iBAAiB;AACtB,SAAK,iBAAiB;AACtB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,MAAM,IAAI,SAAuC;AAC/C,WAAO,KAAK,eAAe,KAAK,MAAM,OAAO;AAAA,EAC/C;AAAA;AAAA,EAGA,MAAM,OAA6B;AACjC,WAAO,KAAK,YAAY,KAAK,IAAI;AAAA,EACnC;AAAA;AAAA,EAGA,MAAM,SAAwB;AAC5B,QAAI,KAAK,SAAU;AACnB,SAAK,WAAW;AAChB,UAAM,KAAK,eAAe,KAAK,IAAI;AAAA,EACrC;AAAA;AAAA,EAGA,OAAO,OAAO,YAAY,IAAmB;AAC3C,UAAM,KAAK,OAAO;AAAA,EACpB;AACF;;;AC5DA,gCAAsD;AAGtD,IAAM,eAAe,oBAAI,IAAY,CAAC,WAAW,YAAY,UAAU,QAAQ,OAAO,CAAC;AASvF,SAAS,UAAU,OAAkB,OAA0B;AAC7D,QAAM,OAAO,KAAK,KAAK;AACvB,MAAI,MAAM,SAAS;AACjB,UAAM,KAAK,MAAM;AACjB,UAAM,UAAU;AAChB,OAAG;AAAA,EACL;AACF;AAQA,gBAAuB,SACrB,MAC6B;AAC7B,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,QAAmB,EAAE,QAAQ,CAAC,GAAG,SAAS,MAAM,MAAM,MAAM;AAElE,QAAM,aAAS,wCAAa;AAAA,IAC1B,QAAQ,OAA2B;AACjC,YAAM,OAAO,MAAM,SAAS;AAC5B,UAAI,CAAC,aAAa,IAAI,IAAI,EAAG;AAE7B,UAAI;AACJ,UAAI;AACF,eAAO,KAAK,MAAM,MAAM,IAAI;AAAA,MAC9B,QAAQ;AACN,eAAO,EAAE,KAAK,MAAM,KAAK;AAAA,MAC3B;AAEA,gBAAU,OAAO,EAAE,MAA+B,KAAK,CAAC;AAAA,IAC1D;AAAA,EACF,CAAC;AAGD,QAAM,QAAQ,YAAY;AACxB,QAAI;AACF,iBAAS;AACP,cAAM,SAAS,MAAM,OAAO,KAAK;AACjC,YAAI,OAAO,KAAM;AACjB,eAAO,KAAK,QAAQ,OAAO,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,CAAC;AAAA,MAC5D;AAAA,IACF,SAAS,KAAK;AACZ,gBAAU,OAAO;AAAA,QACf,MAAM;AAAA,QACN,MAAM,EAAE,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE;AAAA,MACpE,CAAC;AAAA,IACH,UAAE;AACA,YAAM,OAAO;AACb,UAAI,MAAM,SAAS;AACjB,cAAM,KAAK,MAAM;AACjB,cAAM,UAAU;AAChB,WAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF,GAAG;AAEH,MAAI;AACF,eAAS;AAEP,aAAO,MAAM,OAAO,SAAS,GAAG;AAC9B,cAAM,QAAQ,MAAM,OAAO,MAAM;AACjC,cAAM;AACN,YAAI,MAAM,SAAS,UAAU,MAAM,SAAS,QAAS;AAAA,MACvD;AAGA,UAAI,MAAM,KAAM;AAGhB,YAAM,IAAI,QAAc,CAAC,MAAM;AAC7B,cAAM,UAAU;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF,UAAE;AACA,WAAO,OAAO,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAC9B,UAAM,KAAK,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAC3B;AACF;;;ACxEA,IAAM,cAAc;AAYb,IAAM,cAAN,MAAkB;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,MAA2B;AACrC,UAAM,SAAS,cAAc,IAAI;AACjC,SAAK,UAAU,OAAO;AACtB,SAAK,SAAS,OAAO;AACrB,SAAK,UAAU,OAAO;AAAA,EACxB;AAAA;AAAA;AAAA,EAKA,MAAM,SAA0B;AAC9B,UAAM,MAAM,MAAM,KAAK,QAAgB,OAAO,SAAS;AACvD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,IAAI,SAAmB,MAAuC;AAClE,WAAO,KAAK,QAAmB,QAAQ,QAAQ;AAAA,MAC7C;AAAA,MACA,OAAO,MAAM;AAAA,MACb,SAAS,MAAM;AAAA,MACf,MAAM,MAAM,QAAQ;AAAA,IACtB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,OAAO,UACL,SACA,MAC6B;AAC7B,UAAM,OAAO,KAAK,UAAU;AAAA,MAC1B;AAAA,MACA,OAAO,MAAM;AAAA,MACb,SAAS,MAAM;AAAA,MACf,MAAM,MAAM,QAAQ;AAAA,IACtB,CAAC;AAED,UAAM,WAAW,MAAM,KAAK,MAAM,eAAe;AAAA,MAC/C,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ,kBAAkB;AAAA,MACxC;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,gBAAgB,SAAS,QAAQ,IAAI;AAAA,IAC7C;AAEA,QAAI,CAAC,SAAS,MAAM;AAClB,YAAM,IAAI,iBAAiB,iCAAiC;AAAA,IAC9D;AAEA,WAAO,SAAS,SAAS,IAAI;AAAA,EAC/B;AAAA;AAAA,EAGA,MAAM,gBAAwC;AAC5C,WAAO,KAAK,QAAuB,OAAO,YAAY;AAAA,EACxD;AAAA;AAAA,EAGA,MAAM,cACJ,MACA,MACsB;AACtB,WAAO,KAAK,QAAqB,QAAQ,cAAc;AAAA,MACrD;AAAA,MACA,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,MACb,WAAW,MAAM;AAAA,MACjB,SAAS,MAAM;AAAA,IACjB,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,WAAW,MAAoC;AACnD,WAAO,KAAK,QAAqB,OAAO,cAAc,mBAAmB,IAAI,CAAC,EAAE;AAAA,EAClF;AAAA;AAAA,EAGA,MAAM,cAAc,MAA6B;AAC/C,UAAM,KAAK,QAAgB,UAAU,cAAc,mBAAmB,IAAI,CAAC,EAAE;AAAA,EAC/E;AAAA;AAAA,EAGA,MAAM,cAAc,MAAc,SAAuC;AACvE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,cAAc,mBAAmB,IAAI,CAAC;AAAA,MACtC,EAAE,QAAQ;AAAA,IACZ;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,SAAS,MAAc,MAAyC;AACpE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,cAAc,mBAAmB,IAAI,CAAC,UAAU,IAAI;AAAA,IACtD;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,UACJ,MACA,MACA,SACA,MACiB;AACjB,WAAO,KAAK;AAAA,MACV;AAAA,MACA,cAAc,mBAAmB,IAAI,CAAC,UAAU,IAAI;AAAA,MACpD,EAAE,SAAS,UAAU,MAAM,YAAY,OAAO;AAAA,IAChD;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,WAAW,MAAc,MAA+B;AAC5D,WAAO,KAAK;AAAA,MACV;AAAA,MACA,cAAc,mBAAmB,IAAI,CAAC,UAAU,IAAI;AAAA,IACtD;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,eAAe,MAAkD;AACrE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,cAAc,mBAAmB,IAAI,CAAC;AAAA,IACxC;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,SAAS,UAAqD;AAClE,WAAO,KAAK,QAA0B,QAAQ,cAAc,EAAE,SAAS,CAAC;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,QACJ,MACA,MACyB;AACzB,UAAM,KAAK,cAAc,MAAM,IAAI;AACnC,WAAO,IAAI;AAAA,MACT;AAAA,MACA,CAAC,GAAG,QAAQ,KAAK,cAAc,GAAG,GAAG;AAAA,MACrC,CAAC,MAAM,KAAK,cAAc,CAAC;AAAA,MAC3B,CAAC,MAAM,KAAK,WAAW,CAAC;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA,EAIQ,QAAQ,aAA8C;AAC5D,UAAM,IAA4B;AAAA,MAChC,cAAc,0BAA0B,WAAW;AAAA,IACrD;AACA,QAAI,YAAa,GAAE,cAAc,IAAI;AACrC,QAAI,KAAK,OAAQ,GAAE,eAAe,IAAI,UAAU,KAAK,MAAM;AAC3D,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,MAAM,MAAc,MAAsC;AACtE,UAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI;AAClC,QAAI;AACF,aAAO,MAAM,MAAM,KAAK;AAAA,QACtB,GAAG;AAAA,QACH,QAAQ,YAAY,QAAQ,KAAK,OAAO;AAAA,MAC1C,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,eAAe,gBAAgB,IAAI,SAAS,gBAAgB;AAC9D,cAAM,IAAI,aAAa,2BAA2B,KAAK,OAAO,IAAI;AAAA,MACpE;AACA,UAAI,eAAe,WAAW;AAC5B,cAAM,IAAI,aAAa,wBAAwB,KAAK,OAAO,KAAK,IAAI,OAAO,EAAE;AAAA,MAC/E;AACA,YAAM,IAAI;AAAA,QACR,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,QACZ,QACA,MACA,MACY;AACZ,UAAM,OAAoB;AAAA,MACxB;AAAA,MACA,SAAS,KAAK,QAAQ,OAAO,qBAAqB,MAAS;AAAA,IAC7D;AACA,QAAI,KAAM,MAAK,OAAO,KAAK,UAAU,IAAI;AAEzC,UAAM,WAAW,MAAM,KAAK,MAAM,MAAM,IAAI;AAE5C,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,gBAAgB,SAAS,QAAQ,IAAI;AAAA,IAC7C;AAEA,UAAM,SAAyB,KAAK,MAAM,IAAI;AAC9C,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,IAAI,iBAAiB,OAAO,SAAS,eAAe;AAAA,IAC5D;AACA,WAAO,OAAO;AAAA,EAChB;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/errors.ts","../src/sandbox.ts","../src/sse.ts","../src/client.ts"],"sourcesContent":["export { AgentKernel } from \"./client.js\";\nexport { SandboxSession } from \"./sandbox.js\";\nexport {\n AgentKernelError,\n AuthError,\n NotFoundError,\n ValidationError,\n ServerError,\n NetworkError,\n StreamError,\n} from \"./errors.js\";\nexport type {\n AgentKernelOptions,\n BatchFileWriteResponse,\n CreateSandboxOptions,\n DetachedCommand,\n DetachedLogsResponse,\n DetachedStatus,\n ExecOptions,\n RunOptions,\n RunOutput,\n SandboxInfo,\n StreamEvent,\n StreamEventType,\n SecurityProfile,\n SandboxStatus,\n ApiResponse,\n} from \"./types.js\";\n","import type { AgentKernelOptions } from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"http://localhost:18888\";\nconst DEFAULT_TIMEOUT = 30_000;\n\n/** Resolve configuration from constructor args, env vars, and defaults. */\nexport function resolveConfig(opts?: AgentKernelOptions) {\n const baseUrl =\n opts?.baseUrl ??\n process.env.AGENTKERNEL_BASE_URL ??\n DEFAULT_BASE_URL;\n\n const apiKey =\n opts?.apiKey ??\n process.env.AGENTKERNEL_API_KEY ??\n undefined;\n\n const timeout = opts?.timeout ?? DEFAULT_TIMEOUT;\n\n return {\n baseUrl: baseUrl.replace(/\\/+$/, \"\"),\n apiKey,\n timeout,\n };\n}\n","/** Base error for all agentkernel SDK errors. */\nexport class AgentKernelError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AgentKernelError\";\n }\n}\n\n/** 401 Unauthorized. */\nexport class AuthError extends AgentKernelError {\n readonly status = 401;\n constructor(message = \"Unauthorized\") {\n super(message);\n this.name = \"AuthError\";\n }\n}\n\n/** 404 Not Found. */\nexport class NotFoundError extends AgentKernelError {\n readonly status = 404;\n constructor(message = \"Not found\") {\n super(message);\n this.name = \"NotFoundError\";\n }\n}\n\n/** 400 Bad Request. */\nexport class ValidationError extends AgentKernelError {\n readonly status = 400;\n constructor(message = \"Bad request\") {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\n/** 500 Internal Server Error. */\nexport class ServerError extends AgentKernelError {\n readonly status = 500;\n constructor(message = \"Internal server error\") {\n super(message);\n this.name = \"ServerError\";\n }\n}\n\n/** Network / connection error. */\nexport class NetworkError extends AgentKernelError {\n constructor(message = \"Network error\") {\n super(message);\n this.name = \"NetworkError\";\n }\n}\n\n/** SSE streaming error. */\nexport class StreamError extends AgentKernelError {\n constructor(message = \"Stream error\") {\n super(message);\n this.name = \"StreamError\";\n }\n}\n\n/** Map an HTTP status code + body to the appropriate error. */\nexport function errorFromStatus(status: number, body: string): AgentKernelError {\n let message: string;\n try {\n const parsed = JSON.parse(body);\n message = parsed.error ?? body;\n } catch {\n message = body;\n }\n\n switch (status) {\n case 400:\n return new ValidationError(message);\n case 401:\n return new AuthError(message);\n case 404:\n return new NotFoundError(message);\n default:\n return new ServerError(message);\n }\n}\n","import type {\n BatchFileWriteResponse,\n ExecOptions,\n RunOutput,\n SandboxInfo,\n} from \"./types.js\";\n\ntype ExecFn = (\n name: string,\n command: string[],\n opts?: ExecOptions,\n) => Promise<RunOutput>;\ntype RemoveFn = (name: string) => Promise<void>;\ntype GetFn = (name: string) => Promise<SandboxInfo>;\ntype WriteFilesFn = (\n name: string,\n files: Record<string, string>,\n) => Promise<BatchFileWriteResponse>;\n\n/**\n * A sandbox session that auto-removes the sandbox on dispose.\n *\n * Supports both explicit cleanup via remove() and automatic cleanup via\n * Symbol.asyncDispose (TS 5.2+ `await using`).\n *\n * @example\n * ```ts\n * await using sb = await client.sandbox(\"test\");\n * await sb.exec([\"echo\", \"hello\"]);\n * // sandbox auto-removed when scope exits\n * ```\n */\nexport class SandboxSession implements AsyncDisposable {\n readonly name: string;\n private _removed = false;\n private readonly _execInSandbox: ExecFn;\n private readonly _removeSandbox: RemoveFn;\n private readonly _getSandbox: GetFn;\n private readonly _writeFiles: WriteFilesFn;\n\n /** @internal */\n constructor(\n name: string,\n execInSandbox: ExecFn,\n removeSandbox: RemoveFn,\n getSandbox: GetFn,\n writeFiles: WriteFilesFn,\n ) {\n this.name = name;\n this._execInSandbox = execInSandbox;\n this._removeSandbox = removeSandbox;\n this._getSandbox = getSandbox;\n this._writeFiles = writeFiles;\n }\n\n /** Run a command in this sandbox. */\n async run(command: string[], opts?: ExecOptions): Promise<RunOutput> {\n return this._execInSandbox(this.name, command, opts);\n }\n\n /** Get sandbox info. */\n async info(): Promise<SandboxInfo> {\n return this._getSandbox(this.name);\n }\n\n /** Write multiple files in one request. */\n async writeFiles(\n files: Record<string, string>,\n ): Promise<BatchFileWriteResponse> {\n return this._writeFiles(this.name, files);\n }\n\n /** Remove the sandbox. Idempotent. */\n async remove(): Promise<void> {\n if (this._removed) return;\n this._removed = true;\n await this._removeSandbox(this.name);\n }\n\n /** Auto-cleanup for `await using`. */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.remove();\n }\n}\n","import { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport type { StreamEvent, StreamEventType } from \"./types.js\";\n\nconst KNOWN_EVENTS = new Set<string>([\"started\", \"progress\", \"output\", \"done\", \"error\"]);\n\n/** Shared mutable state between the pump and the generator. */\ninterface PumpState {\n events: StreamEvent[];\n resolve: (() => void) | null;\n done: boolean;\n}\n\nfunction pushEvent(state: PumpState, event: StreamEvent): void {\n state.events.push(event);\n if (state.resolve) {\n const cb = state.resolve;\n state.resolve = null;\n cb();\n }\n}\n\n/**\n * Parse an SSE response body into an async generator of StreamEvents.\n *\n * Consumes a ReadableStream<Uint8Array> from fetch() and yields typed events\n * until the stream closes or a \"done\"/\"error\" event is received.\n */\nexport async function* parseSSE(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<StreamEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n const state: PumpState = { events: [], resolve: null, done: false };\n\n const parser = createParser({\n onEvent(event: EventSourceMessage) {\n const type = event.event ?? \"message\";\n if (!KNOWN_EVENTS.has(type)) return;\n\n let data: Record<string, unknown>;\n try {\n data = JSON.parse(event.data);\n } catch {\n data = { raw: event.data };\n }\n\n pushEvent(state, { type: type as StreamEventType, data });\n },\n });\n\n // Read the stream in the background\n const pump = (async () => {\n try {\n for (;;) {\n const result = await reader.read();\n if (result.done) break;\n parser.feed(decoder.decode(result.value, { stream: true }));\n }\n } catch (err) {\n pushEvent(state, {\n type: \"error\",\n data: { message: err instanceof Error ? err.message : String(err) },\n });\n } finally {\n state.done = true;\n if (state.resolve) {\n const cb = state.resolve;\n state.resolve = null;\n cb();\n }\n }\n })();\n\n try {\n for (;;) {\n // Yield all buffered events\n while (state.events.length > 0) {\n const event = state.events.shift()!;\n yield event;\n if (event.type === \"done\" || event.type === \"error\") return;\n }\n\n // If the stream is done and no more events, exit\n if (state.done) return;\n\n // Wait for the next event\n await new Promise<void>((r) => {\n state.resolve = r;\n });\n }\n } finally {\n reader.cancel().catch(() => {});\n await pump.catch(() => {});\n }\n}\n","import { resolveConfig } from \"./config.js\";\nimport {\n AgentKernelError,\n NetworkError,\n errorFromStatus,\n} from \"./errors.js\";\nimport { SandboxSession } from \"./sandbox.js\";\nimport { parseSSE } from \"./sse.js\";\nimport type {\n AgentKernelOptions,\n ApiResponse,\n BatchCommand,\n BatchFileWriteResponse,\n BatchRunResponse,\n CreateSandboxOptions,\n DetachedCommand,\n DetachedLogsResponse,\n ExecOptions,\n FileReadResponse,\n FileWriteOptions,\n RunOptions,\n RunOutput,\n SandboxInfo,\n StreamEvent,\n} from \"./types.js\";\n\nconst SDK_VERSION = \"0.4.0\";\n\n/**\n * Client for the agentkernel HTTP API.\n *\n * @example\n * ```ts\n * const client = new AgentKernel();\n * const result = await client.run([\"echo\", \"hello\"]);\n * console.log(result.output); // \"hello\\n\"\n * ```\n */\nexport class AgentKernel {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly timeout: number;\n\n constructor(opts?: AgentKernelOptions) {\n const config = resolveConfig(opts);\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n this.timeout = config.timeout;\n }\n\n // -- Core API methods --\n\n /** Health check. Returns \"ok\" if the server is running. */\n async health(): Promise<string> {\n const res = await this.request<string>(\"GET\", \"/health\");\n return res;\n }\n\n /** Run a command in a temporary sandbox. */\n async run(command: string[], opts?: RunOptions): Promise<RunOutput> {\n return this.request<RunOutput>(\"POST\", \"/run\", {\n command,\n image: opts?.image,\n profile: opts?.profile,\n fast: opts?.fast ?? true,\n });\n }\n\n /**\n * Run a command with SSE streaming output.\n *\n * @example\n * ```ts\n * for await (const event of client.runStream([\"python3\", \"script.py\"])) {\n * if (event.type === \"output\") process.stdout.write(String(event.data.data));\n * }\n * ```\n */\n async *runStream(\n command: string[],\n opts?: RunOptions,\n ): AsyncGenerator<StreamEvent> {\n const body = JSON.stringify({\n command,\n image: opts?.image,\n profile: opts?.profile,\n fast: opts?.fast ?? true,\n });\n\n const response = await this.fetch(\"/run/stream\", {\n method: \"POST\",\n headers: this.headers(\"application/json\"),\n body,\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw errorFromStatus(response.status, text);\n }\n\n if (!response.body) {\n throw new AgentKernelError(\"No response body for SSE stream\");\n }\n\n yield* parseSSE(response.body);\n }\n\n /** List all sandboxes. */\n async listSandboxes(): Promise<SandboxInfo[]> {\n return this.request<SandboxInfo[]>(\"GET\", \"/sandboxes\");\n }\n\n /** Create a new sandbox. */\n async createSandbox(\n name: string,\n opts?: CreateSandboxOptions,\n ): Promise<SandboxInfo> {\n return this.request<SandboxInfo>(\"POST\", \"/sandboxes\", {\n name,\n image: opts?.image,\n vcpus: opts?.vcpus,\n memory_mb: opts?.memory_mb,\n profile: opts?.profile,\n source_url: opts?.source_url,\n source_ref: opts?.source_ref,\n });\n }\n\n /** Get info about a sandbox. */\n async getSandbox(name: string): Promise<SandboxInfo> {\n return this.request<SandboxInfo>(\"GET\", `/sandboxes/${encodeURIComponent(name)}`);\n }\n\n /** Remove a sandbox. */\n async removeSandbox(name: string): Promise<void> {\n await this.request<string>(\"DELETE\", `/sandboxes/${encodeURIComponent(name)}`);\n }\n\n /** Run a command in an existing sandbox. */\n async execInSandbox(\n name: string,\n command: string[],\n opts?: ExecOptions,\n ): Promise<RunOutput> {\n return this.request<RunOutput>(\n \"POST\",\n `/sandboxes/${encodeURIComponent(name)}/exec`,\n {\n command,\n env: opts?.env,\n workdir: opts?.workdir,\n sudo: opts?.sudo,\n },\n );\n }\n\n /** Read a file from a sandbox. */\n async readFile(name: string, path: string): Promise<FileReadResponse> {\n return this.request<FileReadResponse>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n );\n }\n\n /** Write a file to a sandbox. */\n async writeFile(\n name: string,\n path: string,\n content: string,\n opts?: FileWriteOptions,\n ): Promise<string> {\n return this.request<string>(\n \"PUT\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n { content, encoding: opts?.encoding ?? \"utf8\" },\n );\n }\n\n /** Delete a file from a sandbox. */\n async deleteFile(name: string, path: string): Promise<string> {\n return this.request<string>(\n \"DELETE\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n );\n }\n\n /** Get audit log entries for a sandbox. */\n async getSandboxLogs(name: string): Promise<Record<string, unknown>[]> {\n return this.request<Record<string, unknown>[]>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/logs`,\n );\n }\n\n /** Write multiple files to a sandbox in one request. */\n async writeFiles(\n name: string,\n files: Record<string, string>,\n ): Promise<BatchFileWriteResponse> {\n return this.request<BatchFileWriteResponse>(\n \"POST\",\n `/sandboxes/${encodeURIComponent(name)}/files`,\n { files },\n );\n }\n\n /** Run multiple commands in parallel. */\n async batchRun(commands: BatchCommand[]): Promise<BatchRunResponse> {\n return this.request<BatchRunResponse>(\"POST\", \"/batch/run\", { commands });\n }\n\n /** Start a detached (background) command in a sandbox. */\n async execDetached(\n name: string,\n command: string[],\n opts?: ExecOptions,\n ): Promise<DetachedCommand> {\n return this.request<DetachedCommand>(\n \"POST\",\n `/sandboxes/${encodeURIComponent(name)}/exec/detach`,\n {\n command,\n env: opts?.env,\n workdir: opts?.workdir,\n sudo: opts?.sudo,\n },\n );\n }\n\n /** Get the status of a detached command. */\n async detachedStatus(\n name: string,\n cmdId: string,\n ): Promise<DetachedCommand> {\n return this.request<DetachedCommand>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}`,\n );\n }\n\n /** Get logs from a detached command. */\n async detachedLogs(\n name: string,\n cmdId: string,\n stream?: \"stdout\" | \"stderr\",\n ): Promise<DetachedLogsResponse> {\n const query = stream === \"stderr\" ? \"?stream=stderr\" : \"\";\n return this.request<DetachedLogsResponse>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}/logs${query}`,\n );\n }\n\n /** Kill a detached command. */\n async detachedKill(name: string, cmdId: string): Promise<string> {\n return this.request<string>(\n \"DELETE\",\n `/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}`,\n );\n }\n\n /** List detached commands in a sandbox. */\n async detachedList(name: string): Promise<DetachedCommand[]> {\n return this.request<DetachedCommand[]>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/exec/detached`,\n );\n }\n\n /**\n * Create a sandbox session with automatic cleanup.\n *\n * The returned SandboxSession implements AsyncDisposable,\n * so it works with `await using` (TS 5.2+):\n *\n * @example\n * ```ts\n * await using sb = await client.sandbox(\"test\", { image: \"python:3.12-alpine\" });\n * await sb.run([\"pip\", \"install\", \"numpy\"]);\n * // sandbox auto-removed when scope exits\n * ```\n */\n async sandbox(\n name: string,\n opts?: CreateSandboxOptions,\n ): Promise<SandboxSession> {\n await this.createSandbox(name, opts);\n return new SandboxSession(\n name,\n (n, cmd, o) => this.execInSandbox(n, cmd, o),\n (n) => this.removeSandbox(n),\n (n) => this.getSandbox(n),\n (n, f) => this.writeFiles(n, f),\n );\n }\n\n // -- Internal helpers --\n\n private headers(contentType?: string): Record<string, string> {\n const h: Record<string, string> = {\n \"User-Agent\": `agentkernel-nodejs-sdk/${SDK_VERSION}`,\n };\n if (contentType) h[\"Content-Type\"] = contentType;\n if (this.apiKey) h[\"Authorization\"] = `Bearer ${this.apiKey}`;\n return h;\n }\n\n private async fetch(path: string, init: RequestInit): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n try {\n return await fetch(url, {\n ...init,\n signal: AbortSignal.timeout(this.timeout),\n });\n } catch (err) {\n if (err instanceof DOMException && err.name === \"TimeoutError\") {\n throw new NetworkError(`Request timed out after ${this.timeout}ms`);\n }\n if (err instanceof TypeError) {\n throw new NetworkError(`Failed to connect to ${this.baseUrl}: ${err.message}`);\n }\n throw new NetworkError(\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: this.headers(body ? \"application/json\" : undefined),\n };\n if (body) init.body = JSON.stringify(body);\n\n const response = await this.fetch(path, init);\n\n const text = await response.text();\n if (!response.ok) {\n throw errorFromStatus(response.status, text);\n }\n\n const parsed: ApiResponse<T> = JSON.parse(text);\n if (!parsed.success) {\n throw new AgentKernelError(parsed.error ?? \"Unknown error\");\n }\n return parsed.data as T;\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -29,6 +29,21 @@ interface CreateSandboxOptions {
|
|
|
29
29
|
vcpus?: number;
|
|
30
30
|
memory_mb?: number;
|
|
31
31
|
profile?: SecurityProfile;
|
|
32
|
+
/** Git repository URL to clone into the sandbox. */
|
|
33
|
+
source_url?: string;
|
|
34
|
+
/** Git ref to checkout after cloning. */
|
|
35
|
+
source_ref?: string;
|
|
36
|
+
/** Volume mounts (slug:/path or slug:/path:ro). Create volumes via CLI first. */
|
|
37
|
+
volumes?: string[];
|
|
38
|
+
}
|
|
39
|
+
/** Options for executing a command in a sandbox. */
|
|
40
|
+
interface ExecOptions {
|
|
41
|
+
/** Environment variables (KEY=VALUE). */
|
|
42
|
+
env?: string[];
|
|
43
|
+
/** Working directory inside the container. */
|
|
44
|
+
workdir?: string;
|
|
45
|
+
/** Run as root. */
|
|
46
|
+
sudo?: boolean;
|
|
32
47
|
}
|
|
33
48
|
/** Output from a command execution. */
|
|
34
49
|
interface RunOutput {
|
|
@@ -73,6 +88,27 @@ interface BatchResult {
|
|
|
73
88
|
interface BatchRunResponse {
|
|
74
89
|
results: BatchResult[];
|
|
75
90
|
}
|
|
91
|
+
/** Result of a batch file write. */
|
|
92
|
+
interface BatchFileWriteResponse {
|
|
93
|
+
written: number;
|
|
94
|
+
}
|
|
95
|
+
/** Status of a detached command. */
|
|
96
|
+
type DetachedStatus = "running" | "completed" | "failed";
|
|
97
|
+
/** A detached (background) command running in a sandbox. */
|
|
98
|
+
interface DetachedCommand {
|
|
99
|
+
id: string;
|
|
100
|
+
sandbox: string;
|
|
101
|
+
command: string[];
|
|
102
|
+
pid: number;
|
|
103
|
+
status: DetachedStatus;
|
|
104
|
+
exit_code: number | null;
|
|
105
|
+
started_at: string;
|
|
106
|
+
}
|
|
107
|
+
/** Response from detached command logs. */
|
|
108
|
+
interface DetachedLogsResponse {
|
|
109
|
+
stdout?: string;
|
|
110
|
+
stderr?: string;
|
|
111
|
+
}
|
|
76
112
|
/** API response wrapper. */
|
|
77
113
|
interface ApiResponse<T> {
|
|
78
114
|
success: boolean;
|
|
@@ -80,9 +116,10 @@ interface ApiResponse<T> {
|
|
|
80
116
|
error?: string;
|
|
81
117
|
}
|
|
82
118
|
|
|
83
|
-
type ExecFn = (name: string, command: string[]) => Promise<RunOutput>;
|
|
119
|
+
type ExecFn = (name: string, command: string[], opts?: ExecOptions) => Promise<RunOutput>;
|
|
84
120
|
type RemoveFn = (name: string) => Promise<void>;
|
|
85
121
|
type GetFn = (name: string) => Promise<SandboxInfo>;
|
|
122
|
+
type WriteFilesFn = (name: string, files: Record<string, string>) => Promise<BatchFileWriteResponse>;
|
|
86
123
|
/**
|
|
87
124
|
* A sandbox session that auto-removes the sandbox on dispose.
|
|
88
125
|
*
|
|
@@ -102,12 +139,15 @@ declare class SandboxSession implements AsyncDisposable {
|
|
|
102
139
|
private readonly _execInSandbox;
|
|
103
140
|
private readonly _removeSandbox;
|
|
104
141
|
private readonly _getSandbox;
|
|
142
|
+
private readonly _writeFiles;
|
|
105
143
|
/** @internal */
|
|
106
|
-
constructor(name: string, execInSandbox: ExecFn, removeSandbox: RemoveFn, getSandbox: GetFn);
|
|
144
|
+
constructor(name: string, execInSandbox: ExecFn, removeSandbox: RemoveFn, getSandbox: GetFn, writeFiles: WriteFilesFn);
|
|
107
145
|
/** Run a command in this sandbox. */
|
|
108
|
-
run(command: string[]): Promise<RunOutput>;
|
|
146
|
+
run(command: string[], opts?: ExecOptions): Promise<RunOutput>;
|
|
109
147
|
/** Get sandbox info. */
|
|
110
148
|
info(): Promise<SandboxInfo>;
|
|
149
|
+
/** Write multiple files in one request. */
|
|
150
|
+
writeFiles(files: Record<string, string>): Promise<BatchFileWriteResponse>;
|
|
111
151
|
/** Remove the sandbox. Idempotent. */
|
|
112
152
|
remove(): Promise<void>;
|
|
113
153
|
/** Auto-cleanup for `await using`. */
|
|
@@ -153,7 +193,7 @@ declare class AgentKernel {
|
|
|
153
193
|
/** Remove a sandbox. */
|
|
154
194
|
removeSandbox(name: string): Promise<void>;
|
|
155
195
|
/** Run a command in an existing sandbox. */
|
|
156
|
-
execInSandbox(name: string, command: string[]): Promise<RunOutput>;
|
|
196
|
+
execInSandbox(name: string, command: string[], opts?: ExecOptions): Promise<RunOutput>;
|
|
157
197
|
/** Read a file from a sandbox. */
|
|
158
198
|
readFile(name: string, path: string): Promise<FileReadResponse>;
|
|
159
199
|
/** Write a file to a sandbox. */
|
|
@@ -162,8 +202,20 @@ declare class AgentKernel {
|
|
|
162
202
|
deleteFile(name: string, path: string): Promise<string>;
|
|
163
203
|
/** Get audit log entries for a sandbox. */
|
|
164
204
|
getSandboxLogs(name: string): Promise<Record<string, unknown>[]>;
|
|
205
|
+
/** Write multiple files to a sandbox in one request. */
|
|
206
|
+
writeFiles(name: string, files: Record<string, string>): Promise<BatchFileWriteResponse>;
|
|
165
207
|
/** Run multiple commands in parallel. */
|
|
166
208
|
batchRun(commands: BatchCommand[]): Promise<BatchRunResponse>;
|
|
209
|
+
/** Start a detached (background) command in a sandbox. */
|
|
210
|
+
execDetached(name: string, command: string[], opts?: ExecOptions): Promise<DetachedCommand>;
|
|
211
|
+
/** Get the status of a detached command. */
|
|
212
|
+
detachedStatus(name: string, cmdId: string): Promise<DetachedCommand>;
|
|
213
|
+
/** Get logs from a detached command. */
|
|
214
|
+
detachedLogs(name: string, cmdId: string, stream?: "stdout" | "stderr"): Promise<DetachedLogsResponse>;
|
|
215
|
+
/** Kill a detached command. */
|
|
216
|
+
detachedKill(name: string, cmdId: string): Promise<string>;
|
|
217
|
+
/** List detached commands in a sandbox. */
|
|
218
|
+
detachedList(name: string): Promise<DetachedCommand[]>;
|
|
167
219
|
/**
|
|
168
220
|
* Create a sandbox session with automatic cleanup.
|
|
169
221
|
*
|
|
@@ -216,4 +268,4 @@ declare class StreamError extends AgentKernelError {
|
|
|
216
268
|
constructor(message?: string);
|
|
217
269
|
}
|
|
218
270
|
|
|
219
|
-
export { AgentKernel, AgentKernelError, type AgentKernelOptions, type ApiResponse, AuthError, type CreateSandboxOptions, NetworkError, NotFoundError, type RunOptions, type RunOutput, type SandboxInfo, SandboxSession, type SandboxStatus, type SecurityProfile, ServerError, StreamError, type StreamEvent, type StreamEventType, ValidationError };
|
|
271
|
+
export { AgentKernel, AgentKernelError, type AgentKernelOptions, type ApiResponse, AuthError, type BatchFileWriteResponse, type CreateSandboxOptions, type DetachedCommand, type DetachedLogsResponse, type DetachedStatus, type ExecOptions, NetworkError, NotFoundError, type RunOptions, type RunOutput, type SandboxInfo, SandboxSession, type SandboxStatus, type SecurityProfile, ServerError, StreamError, type StreamEvent, type StreamEventType, ValidationError };
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,21 @@ interface CreateSandboxOptions {
|
|
|
29
29
|
vcpus?: number;
|
|
30
30
|
memory_mb?: number;
|
|
31
31
|
profile?: SecurityProfile;
|
|
32
|
+
/** Git repository URL to clone into the sandbox. */
|
|
33
|
+
source_url?: string;
|
|
34
|
+
/** Git ref to checkout after cloning. */
|
|
35
|
+
source_ref?: string;
|
|
36
|
+
/** Volume mounts (slug:/path or slug:/path:ro). Create volumes via CLI first. */
|
|
37
|
+
volumes?: string[];
|
|
38
|
+
}
|
|
39
|
+
/** Options for executing a command in a sandbox. */
|
|
40
|
+
interface ExecOptions {
|
|
41
|
+
/** Environment variables (KEY=VALUE). */
|
|
42
|
+
env?: string[];
|
|
43
|
+
/** Working directory inside the container. */
|
|
44
|
+
workdir?: string;
|
|
45
|
+
/** Run as root. */
|
|
46
|
+
sudo?: boolean;
|
|
32
47
|
}
|
|
33
48
|
/** Output from a command execution. */
|
|
34
49
|
interface RunOutput {
|
|
@@ -73,6 +88,27 @@ interface BatchResult {
|
|
|
73
88
|
interface BatchRunResponse {
|
|
74
89
|
results: BatchResult[];
|
|
75
90
|
}
|
|
91
|
+
/** Result of a batch file write. */
|
|
92
|
+
interface BatchFileWriteResponse {
|
|
93
|
+
written: number;
|
|
94
|
+
}
|
|
95
|
+
/** Status of a detached command. */
|
|
96
|
+
type DetachedStatus = "running" | "completed" | "failed";
|
|
97
|
+
/** A detached (background) command running in a sandbox. */
|
|
98
|
+
interface DetachedCommand {
|
|
99
|
+
id: string;
|
|
100
|
+
sandbox: string;
|
|
101
|
+
command: string[];
|
|
102
|
+
pid: number;
|
|
103
|
+
status: DetachedStatus;
|
|
104
|
+
exit_code: number | null;
|
|
105
|
+
started_at: string;
|
|
106
|
+
}
|
|
107
|
+
/** Response from detached command logs. */
|
|
108
|
+
interface DetachedLogsResponse {
|
|
109
|
+
stdout?: string;
|
|
110
|
+
stderr?: string;
|
|
111
|
+
}
|
|
76
112
|
/** API response wrapper. */
|
|
77
113
|
interface ApiResponse<T> {
|
|
78
114
|
success: boolean;
|
|
@@ -80,9 +116,10 @@ interface ApiResponse<T> {
|
|
|
80
116
|
error?: string;
|
|
81
117
|
}
|
|
82
118
|
|
|
83
|
-
type ExecFn = (name: string, command: string[]) => Promise<RunOutput>;
|
|
119
|
+
type ExecFn = (name: string, command: string[], opts?: ExecOptions) => Promise<RunOutput>;
|
|
84
120
|
type RemoveFn = (name: string) => Promise<void>;
|
|
85
121
|
type GetFn = (name: string) => Promise<SandboxInfo>;
|
|
122
|
+
type WriteFilesFn = (name: string, files: Record<string, string>) => Promise<BatchFileWriteResponse>;
|
|
86
123
|
/**
|
|
87
124
|
* A sandbox session that auto-removes the sandbox on dispose.
|
|
88
125
|
*
|
|
@@ -102,12 +139,15 @@ declare class SandboxSession implements AsyncDisposable {
|
|
|
102
139
|
private readonly _execInSandbox;
|
|
103
140
|
private readonly _removeSandbox;
|
|
104
141
|
private readonly _getSandbox;
|
|
142
|
+
private readonly _writeFiles;
|
|
105
143
|
/** @internal */
|
|
106
|
-
constructor(name: string, execInSandbox: ExecFn, removeSandbox: RemoveFn, getSandbox: GetFn);
|
|
144
|
+
constructor(name: string, execInSandbox: ExecFn, removeSandbox: RemoveFn, getSandbox: GetFn, writeFiles: WriteFilesFn);
|
|
107
145
|
/** Run a command in this sandbox. */
|
|
108
|
-
run(command: string[]): Promise<RunOutput>;
|
|
146
|
+
run(command: string[], opts?: ExecOptions): Promise<RunOutput>;
|
|
109
147
|
/** Get sandbox info. */
|
|
110
148
|
info(): Promise<SandboxInfo>;
|
|
149
|
+
/** Write multiple files in one request. */
|
|
150
|
+
writeFiles(files: Record<string, string>): Promise<BatchFileWriteResponse>;
|
|
111
151
|
/** Remove the sandbox. Idempotent. */
|
|
112
152
|
remove(): Promise<void>;
|
|
113
153
|
/** Auto-cleanup for `await using`. */
|
|
@@ -153,7 +193,7 @@ declare class AgentKernel {
|
|
|
153
193
|
/** Remove a sandbox. */
|
|
154
194
|
removeSandbox(name: string): Promise<void>;
|
|
155
195
|
/** Run a command in an existing sandbox. */
|
|
156
|
-
execInSandbox(name: string, command: string[]): Promise<RunOutput>;
|
|
196
|
+
execInSandbox(name: string, command: string[], opts?: ExecOptions): Promise<RunOutput>;
|
|
157
197
|
/** Read a file from a sandbox. */
|
|
158
198
|
readFile(name: string, path: string): Promise<FileReadResponse>;
|
|
159
199
|
/** Write a file to a sandbox. */
|
|
@@ -162,8 +202,20 @@ declare class AgentKernel {
|
|
|
162
202
|
deleteFile(name: string, path: string): Promise<string>;
|
|
163
203
|
/** Get audit log entries for a sandbox. */
|
|
164
204
|
getSandboxLogs(name: string): Promise<Record<string, unknown>[]>;
|
|
205
|
+
/** Write multiple files to a sandbox in one request. */
|
|
206
|
+
writeFiles(name: string, files: Record<string, string>): Promise<BatchFileWriteResponse>;
|
|
165
207
|
/** Run multiple commands in parallel. */
|
|
166
208
|
batchRun(commands: BatchCommand[]): Promise<BatchRunResponse>;
|
|
209
|
+
/** Start a detached (background) command in a sandbox. */
|
|
210
|
+
execDetached(name: string, command: string[], opts?: ExecOptions): Promise<DetachedCommand>;
|
|
211
|
+
/** Get the status of a detached command. */
|
|
212
|
+
detachedStatus(name: string, cmdId: string): Promise<DetachedCommand>;
|
|
213
|
+
/** Get logs from a detached command. */
|
|
214
|
+
detachedLogs(name: string, cmdId: string, stream?: "stdout" | "stderr"): Promise<DetachedLogsResponse>;
|
|
215
|
+
/** Kill a detached command. */
|
|
216
|
+
detachedKill(name: string, cmdId: string): Promise<string>;
|
|
217
|
+
/** List detached commands in a sandbox. */
|
|
218
|
+
detachedList(name: string): Promise<DetachedCommand[]>;
|
|
167
219
|
/**
|
|
168
220
|
* Create a sandbox session with automatic cleanup.
|
|
169
221
|
*
|
|
@@ -216,4 +268,4 @@ declare class StreamError extends AgentKernelError {
|
|
|
216
268
|
constructor(message?: string);
|
|
217
269
|
}
|
|
218
270
|
|
|
219
|
-
export { AgentKernel, AgentKernelError, type AgentKernelOptions, type ApiResponse, AuthError, type CreateSandboxOptions, NetworkError, NotFoundError, type RunOptions, type RunOutput, type SandboxInfo, SandboxSession, type SandboxStatus, type SecurityProfile, ServerError, StreamError, type StreamEvent, type StreamEventType, ValidationError };
|
|
271
|
+
export { AgentKernel, AgentKernelError, type AgentKernelOptions, type ApiResponse, AuthError, type BatchFileWriteResponse, type CreateSandboxOptions, type DetachedCommand, type DetachedLogsResponse, type DetachedStatus, type ExecOptions, NetworkError, NotFoundError, type RunOptions, type RunOutput, type SandboxInfo, SandboxSession, type SandboxStatus, type SecurityProfile, ServerError, StreamError, type StreamEvent, type StreamEventType, ValidationError };
|
package/dist/index.js
CHANGED
|
@@ -86,21 +86,27 @@ var SandboxSession = class {
|
|
|
86
86
|
_execInSandbox;
|
|
87
87
|
_removeSandbox;
|
|
88
88
|
_getSandbox;
|
|
89
|
+
_writeFiles;
|
|
89
90
|
/** @internal */
|
|
90
|
-
constructor(name, execInSandbox, removeSandbox, getSandbox) {
|
|
91
|
+
constructor(name, execInSandbox, removeSandbox, getSandbox, writeFiles) {
|
|
91
92
|
this.name = name;
|
|
92
93
|
this._execInSandbox = execInSandbox;
|
|
93
94
|
this._removeSandbox = removeSandbox;
|
|
94
95
|
this._getSandbox = getSandbox;
|
|
96
|
+
this._writeFiles = writeFiles;
|
|
95
97
|
}
|
|
96
98
|
/** Run a command in this sandbox. */
|
|
97
|
-
async run(command) {
|
|
98
|
-
return this._execInSandbox(this.name, command);
|
|
99
|
+
async run(command, opts) {
|
|
100
|
+
return this._execInSandbox(this.name, command, opts);
|
|
99
101
|
}
|
|
100
102
|
/** Get sandbox info. */
|
|
101
103
|
async info() {
|
|
102
104
|
return this._getSandbox(this.name);
|
|
103
105
|
}
|
|
106
|
+
/** Write multiple files in one request. */
|
|
107
|
+
async writeFiles(files) {
|
|
108
|
+
return this._writeFiles(this.name, files);
|
|
109
|
+
}
|
|
104
110
|
/** Remove the sandbox. Idempotent. */
|
|
105
111
|
async remove() {
|
|
106
112
|
if (this._removed) return;
|
|
@@ -251,7 +257,9 @@ var AgentKernel = class {
|
|
|
251
257
|
image: opts?.image,
|
|
252
258
|
vcpus: opts?.vcpus,
|
|
253
259
|
memory_mb: opts?.memory_mb,
|
|
254
|
-
profile: opts?.profile
|
|
260
|
+
profile: opts?.profile,
|
|
261
|
+
source_url: opts?.source_url,
|
|
262
|
+
source_ref: opts?.source_ref
|
|
255
263
|
});
|
|
256
264
|
}
|
|
257
265
|
/** Get info about a sandbox. */
|
|
@@ -263,11 +271,16 @@ var AgentKernel = class {
|
|
|
263
271
|
await this.request("DELETE", `/sandboxes/${encodeURIComponent(name)}`);
|
|
264
272
|
}
|
|
265
273
|
/** Run a command in an existing sandbox. */
|
|
266
|
-
async execInSandbox(name, command) {
|
|
274
|
+
async execInSandbox(name, command, opts) {
|
|
267
275
|
return this.request(
|
|
268
276
|
"POST",
|
|
269
277
|
`/sandboxes/${encodeURIComponent(name)}/exec`,
|
|
270
|
-
{
|
|
278
|
+
{
|
|
279
|
+
command,
|
|
280
|
+
env: opts?.env,
|
|
281
|
+
workdir: opts?.workdir,
|
|
282
|
+
sudo: opts?.sudo
|
|
283
|
+
}
|
|
271
284
|
);
|
|
272
285
|
}
|
|
273
286
|
/** Read a file from a sandbox. */
|
|
@@ -299,10 +312,60 @@ var AgentKernel = class {
|
|
|
299
312
|
`/sandboxes/${encodeURIComponent(name)}/logs`
|
|
300
313
|
);
|
|
301
314
|
}
|
|
315
|
+
/** Write multiple files to a sandbox in one request. */
|
|
316
|
+
async writeFiles(name, files) {
|
|
317
|
+
return this.request(
|
|
318
|
+
"POST",
|
|
319
|
+
`/sandboxes/${encodeURIComponent(name)}/files`,
|
|
320
|
+
{ files }
|
|
321
|
+
);
|
|
322
|
+
}
|
|
302
323
|
/** Run multiple commands in parallel. */
|
|
303
324
|
async batchRun(commands) {
|
|
304
325
|
return this.request("POST", "/batch/run", { commands });
|
|
305
326
|
}
|
|
327
|
+
/** Start a detached (background) command in a sandbox. */
|
|
328
|
+
async execDetached(name, command, opts) {
|
|
329
|
+
return this.request(
|
|
330
|
+
"POST",
|
|
331
|
+
`/sandboxes/${encodeURIComponent(name)}/exec/detach`,
|
|
332
|
+
{
|
|
333
|
+
command,
|
|
334
|
+
env: opts?.env,
|
|
335
|
+
workdir: opts?.workdir,
|
|
336
|
+
sudo: opts?.sudo
|
|
337
|
+
}
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
/** Get the status of a detached command. */
|
|
341
|
+
async detachedStatus(name, cmdId) {
|
|
342
|
+
return this.request(
|
|
343
|
+
"GET",
|
|
344
|
+
`/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}`
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
/** Get logs from a detached command. */
|
|
348
|
+
async detachedLogs(name, cmdId, stream) {
|
|
349
|
+
const query = stream === "stderr" ? "?stream=stderr" : "";
|
|
350
|
+
return this.request(
|
|
351
|
+
"GET",
|
|
352
|
+
`/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}/logs${query}`
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
/** Kill a detached command. */
|
|
356
|
+
async detachedKill(name, cmdId) {
|
|
357
|
+
return this.request(
|
|
358
|
+
"DELETE",
|
|
359
|
+
`/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}`
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
/** List detached commands in a sandbox. */
|
|
363
|
+
async detachedList(name) {
|
|
364
|
+
return this.request(
|
|
365
|
+
"GET",
|
|
366
|
+
`/sandboxes/${encodeURIComponent(name)}/exec/detached`
|
|
367
|
+
);
|
|
368
|
+
}
|
|
306
369
|
/**
|
|
307
370
|
* Create a sandbox session with automatic cleanup.
|
|
308
371
|
*
|
|
@@ -320,9 +383,10 @@ var AgentKernel = class {
|
|
|
320
383
|
await this.createSandbox(name, opts);
|
|
321
384
|
return new SandboxSession(
|
|
322
385
|
name,
|
|
323
|
-
(n, cmd) => this.execInSandbox(n, cmd),
|
|
386
|
+
(n, cmd, o) => this.execInSandbox(n, cmd, o),
|
|
324
387
|
(n) => this.removeSandbox(n),
|
|
325
|
-
(n) => this.getSandbox(n)
|
|
388
|
+
(n) => this.getSandbox(n),
|
|
389
|
+
(n, f) => this.writeFiles(n, f)
|
|
326
390
|
);
|
|
327
391
|
}
|
|
328
392
|
// -- Internal helpers --
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/sandbox.ts","../src/sse.ts","../src/client.ts"],"sourcesContent":["import type { AgentKernelOptions } from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"http://localhost:18888\";\nconst DEFAULT_TIMEOUT = 30_000;\n\n/** Resolve configuration from constructor args, env vars, and defaults. */\nexport function resolveConfig(opts?: AgentKernelOptions) {\n const baseUrl =\n opts?.baseUrl ??\n process.env.AGENTKERNEL_BASE_URL ??\n DEFAULT_BASE_URL;\n\n const apiKey =\n opts?.apiKey ??\n process.env.AGENTKERNEL_API_KEY ??\n undefined;\n\n const timeout = opts?.timeout ?? DEFAULT_TIMEOUT;\n\n return {\n baseUrl: baseUrl.replace(/\\/+$/, \"\"),\n apiKey,\n timeout,\n };\n}\n","/** Base error for all agentkernel SDK errors. */\nexport class AgentKernelError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AgentKernelError\";\n }\n}\n\n/** 401 Unauthorized. */\nexport class AuthError extends AgentKernelError {\n readonly status = 401;\n constructor(message = \"Unauthorized\") {\n super(message);\n this.name = \"AuthError\";\n }\n}\n\n/** 404 Not Found. */\nexport class NotFoundError extends AgentKernelError {\n readonly status = 404;\n constructor(message = \"Not found\") {\n super(message);\n this.name = \"NotFoundError\";\n }\n}\n\n/** 400 Bad Request. */\nexport class ValidationError extends AgentKernelError {\n readonly status = 400;\n constructor(message = \"Bad request\") {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\n/** 500 Internal Server Error. */\nexport class ServerError extends AgentKernelError {\n readonly status = 500;\n constructor(message = \"Internal server error\") {\n super(message);\n this.name = \"ServerError\";\n }\n}\n\n/** Network / connection error. */\nexport class NetworkError extends AgentKernelError {\n constructor(message = \"Network error\") {\n super(message);\n this.name = \"NetworkError\";\n }\n}\n\n/** SSE streaming error. */\nexport class StreamError extends AgentKernelError {\n constructor(message = \"Stream error\") {\n super(message);\n this.name = \"StreamError\";\n }\n}\n\n/** Map an HTTP status code + body to the appropriate error. */\nexport function errorFromStatus(status: number, body: string): AgentKernelError {\n let message: string;\n try {\n const parsed = JSON.parse(body);\n message = parsed.error ?? body;\n } catch {\n message = body;\n }\n\n switch (status) {\n case 400:\n return new ValidationError(message);\n case 401:\n return new AuthError(message);\n case 404:\n return new NotFoundError(message);\n default:\n return new ServerError(message);\n }\n}\n","import type { RunOutput, SandboxInfo } from \"./types.js\";\n\ntype ExecFn = (name: string, command: string[]) => Promise<RunOutput>;\ntype RemoveFn = (name: string) => Promise<void>;\ntype GetFn = (name: string) => Promise<SandboxInfo>;\n\n/**\n * A sandbox session that auto-removes the sandbox on dispose.\n *\n * Supports both explicit cleanup via remove() and automatic cleanup via\n * Symbol.asyncDispose (TS 5.2+ `await using`).\n *\n * @example\n * ```ts\n * await using sb = await client.sandbox(\"test\");\n * await sb.exec([\"echo\", \"hello\"]);\n * // sandbox auto-removed when scope exits\n * ```\n */\nexport class SandboxSession implements AsyncDisposable {\n readonly name: string;\n private _removed = false;\n private readonly _execInSandbox: ExecFn;\n private readonly _removeSandbox: RemoveFn;\n private readonly _getSandbox: GetFn;\n\n /** @internal */\n constructor(\n name: string,\n execInSandbox: ExecFn,\n removeSandbox: RemoveFn,\n getSandbox: GetFn,\n ) {\n this.name = name;\n this._execInSandbox = execInSandbox;\n this._removeSandbox = removeSandbox;\n this._getSandbox = getSandbox;\n }\n\n /** Run a command in this sandbox. */\n async run(command: string[]): Promise<RunOutput> {\n return this._execInSandbox(this.name, command);\n }\n\n /** Get sandbox info. */\n async info(): Promise<SandboxInfo> {\n return this._getSandbox(this.name);\n }\n\n /** Remove the sandbox. Idempotent. */\n async remove(): Promise<void> {\n if (this._removed) return;\n this._removed = true;\n await this._removeSandbox(this.name);\n }\n\n /** Auto-cleanup for `await using`. */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.remove();\n }\n}\n","import { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport type { StreamEvent, StreamEventType } from \"./types.js\";\n\nconst KNOWN_EVENTS = new Set<string>([\"started\", \"progress\", \"output\", \"done\", \"error\"]);\n\n/** Shared mutable state between the pump and the generator. */\ninterface PumpState {\n events: StreamEvent[];\n resolve: (() => void) | null;\n done: boolean;\n}\n\nfunction pushEvent(state: PumpState, event: StreamEvent): void {\n state.events.push(event);\n if (state.resolve) {\n const cb = state.resolve;\n state.resolve = null;\n cb();\n }\n}\n\n/**\n * Parse an SSE response body into an async generator of StreamEvents.\n *\n * Consumes a ReadableStream<Uint8Array> from fetch() and yields typed events\n * until the stream closes or a \"done\"/\"error\" event is received.\n */\nexport async function* parseSSE(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<StreamEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n const state: PumpState = { events: [], resolve: null, done: false };\n\n const parser = createParser({\n onEvent(event: EventSourceMessage) {\n const type = event.event ?? \"message\";\n if (!KNOWN_EVENTS.has(type)) return;\n\n let data: Record<string, unknown>;\n try {\n data = JSON.parse(event.data);\n } catch {\n data = { raw: event.data };\n }\n\n pushEvent(state, { type: type as StreamEventType, data });\n },\n });\n\n // Read the stream in the background\n const pump = (async () => {\n try {\n for (;;) {\n const result = await reader.read();\n if (result.done) break;\n parser.feed(decoder.decode(result.value, { stream: true }));\n }\n } catch (err) {\n pushEvent(state, {\n type: \"error\",\n data: { message: err instanceof Error ? err.message : String(err) },\n });\n } finally {\n state.done = true;\n if (state.resolve) {\n const cb = state.resolve;\n state.resolve = null;\n cb();\n }\n }\n })();\n\n try {\n for (;;) {\n // Yield all buffered events\n while (state.events.length > 0) {\n const event = state.events.shift()!;\n yield event;\n if (event.type === \"done\" || event.type === \"error\") return;\n }\n\n // If the stream is done and no more events, exit\n if (state.done) return;\n\n // Wait for the next event\n await new Promise<void>((r) => {\n state.resolve = r;\n });\n }\n } finally {\n reader.cancel().catch(() => {});\n await pump.catch(() => {});\n }\n}\n","import { resolveConfig } from \"./config.js\";\nimport {\n AgentKernelError,\n NetworkError,\n errorFromStatus,\n} from \"./errors.js\";\nimport { SandboxSession } from \"./sandbox.js\";\nimport { parseSSE } from \"./sse.js\";\nimport type {\n AgentKernelOptions,\n ApiResponse,\n BatchCommand,\n BatchRunResponse,\n CreateSandboxOptions,\n FileReadResponse,\n FileWriteOptions,\n RunOptions,\n RunOutput,\n SandboxInfo,\n StreamEvent,\n} from \"./types.js\";\n\nconst SDK_VERSION = \"0.4.0\";\n\n/**\n * Client for the agentkernel HTTP API.\n *\n * @example\n * ```ts\n * const client = new AgentKernel();\n * const result = await client.run([\"echo\", \"hello\"]);\n * console.log(result.output); // \"hello\\n\"\n * ```\n */\nexport class AgentKernel {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly timeout: number;\n\n constructor(opts?: AgentKernelOptions) {\n const config = resolveConfig(opts);\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n this.timeout = config.timeout;\n }\n\n // -- Core API methods --\n\n /** Health check. Returns \"ok\" if the server is running. */\n async health(): Promise<string> {\n const res = await this.request<string>(\"GET\", \"/health\");\n return res;\n }\n\n /** Run a command in a temporary sandbox. */\n async run(command: string[], opts?: RunOptions): Promise<RunOutput> {\n return this.request<RunOutput>(\"POST\", \"/run\", {\n command,\n image: opts?.image,\n profile: opts?.profile,\n fast: opts?.fast ?? true,\n });\n }\n\n /**\n * Run a command with SSE streaming output.\n *\n * @example\n * ```ts\n * for await (const event of client.runStream([\"python3\", \"script.py\"])) {\n * if (event.type === \"output\") process.stdout.write(String(event.data.data));\n * }\n * ```\n */\n async *runStream(\n command: string[],\n opts?: RunOptions,\n ): AsyncGenerator<StreamEvent> {\n const body = JSON.stringify({\n command,\n image: opts?.image,\n profile: opts?.profile,\n fast: opts?.fast ?? true,\n });\n\n const response = await this.fetch(\"/run/stream\", {\n method: \"POST\",\n headers: this.headers(\"application/json\"),\n body,\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw errorFromStatus(response.status, text);\n }\n\n if (!response.body) {\n throw new AgentKernelError(\"No response body for SSE stream\");\n }\n\n yield* parseSSE(response.body);\n }\n\n /** List all sandboxes. */\n async listSandboxes(): Promise<SandboxInfo[]> {\n return this.request<SandboxInfo[]>(\"GET\", \"/sandboxes\");\n }\n\n /** Create a new sandbox. */\n async createSandbox(\n name: string,\n opts?: CreateSandboxOptions,\n ): Promise<SandboxInfo> {\n return this.request<SandboxInfo>(\"POST\", \"/sandboxes\", {\n name,\n image: opts?.image,\n vcpus: opts?.vcpus,\n memory_mb: opts?.memory_mb,\n profile: opts?.profile,\n });\n }\n\n /** Get info about a sandbox. */\n async getSandbox(name: string): Promise<SandboxInfo> {\n return this.request<SandboxInfo>(\"GET\", `/sandboxes/${encodeURIComponent(name)}`);\n }\n\n /** Remove a sandbox. */\n async removeSandbox(name: string): Promise<void> {\n await this.request<string>(\"DELETE\", `/sandboxes/${encodeURIComponent(name)}`);\n }\n\n /** Run a command in an existing sandbox. */\n async execInSandbox(name: string, command: string[]): Promise<RunOutput> {\n return this.request<RunOutput>(\n \"POST\",\n `/sandboxes/${encodeURIComponent(name)}/exec`,\n { command },\n );\n }\n\n /** Read a file from a sandbox. */\n async readFile(name: string, path: string): Promise<FileReadResponse> {\n return this.request<FileReadResponse>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n );\n }\n\n /** Write a file to a sandbox. */\n async writeFile(\n name: string,\n path: string,\n content: string,\n opts?: FileWriteOptions,\n ): Promise<string> {\n return this.request<string>(\n \"PUT\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n { content, encoding: opts?.encoding ?? \"utf8\" },\n );\n }\n\n /** Delete a file from a sandbox. */\n async deleteFile(name: string, path: string): Promise<string> {\n return this.request<string>(\n \"DELETE\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n );\n }\n\n /** Get audit log entries for a sandbox. */\n async getSandboxLogs(name: string): Promise<Record<string, unknown>[]> {\n return this.request<Record<string, unknown>[]>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/logs`,\n );\n }\n\n /** Run multiple commands in parallel. */\n async batchRun(commands: BatchCommand[]): Promise<BatchRunResponse> {\n return this.request<BatchRunResponse>(\"POST\", \"/batch/run\", { commands });\n }\n\n /**\n * Create a sandbox session with automatic cleanup.\n *\n * The returned SandboxSession implements AsyncDisposable,\n * so it works with `await using` (TS 5.2+):\n *\n * @example\n * ```ts\n * await using sb = await client.sandbox(\"test\", { image: \"python:3.12-alpine\" });\n * await sb.run([\"pip\", \"install\", \"numpy\"]);\n * // sandbox auto-removed when scope exits\n * ```\n */\n async sandbox(\n name: string,\n opts?: CreateSandboxOptions,\n ): Promise<SandboxSession> {\n await this.createSandbox(name, opts);\n return new SandboxSession(\n name,\n (n, cmd) => this.execInSandbox(n, cmd),\n (n) => this.removeSandbox(n),\n (n) => this.getSandbox(n),\n );\n }\n\n // -- Internal helpers --\n\n private headers(contentType?: string): Record<string, string> {\n const h: Record<string, string> = {\n \"User-Agent\": `agentkernel-nodejs-sdk/${SDK_VERSION}`,\n };\n if (contentType) h[\"Content-Type\"] = contentType;\n if (this.apiKey) h[\"Authorization\"] = `Bearer ${this.apiKey}`;\n return h;\n }\n\n private async fetch(path: string, init: RequestInit): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n try {\n return await fetch(url, {\n ...init,\n signal: AbortSignal.timeout(this.timeout),\n });\n } catch (err) {\n if (err instanceof DOMException && err.name === \"TimeoutError\") {\n throw new NetworkError(`Request timed out after ${this.timeout}ms`);\n }\n if (err instanceof TypeError) {\n throw new NetworkError(`Failed to connect to ${this.baseUrl}: ${err.message}`);\n }\n throw new NetworkError(\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: this.headers(body ? \"application/json\" : undefined),\n };\n if (body) init.body = JSON.stringify(body);\n\n const response = await this.fetch(path, init);\n\n const text = await response.text();\n if (!response.ok) {\n throw errorFromStatus(response.status, text);\n }\n\n const parsed: ApiResponse<T> = JSON.parse(text);\n if (!parsed.success) {\n throw new AgentKernelError(parsed.error ?? \"Unknown error\");\n }\n return parsed.data as T;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/sandbox.ts","../src/sse.ts","../src/client.ts"],"sourcesContent":["import type { AgentKernelOptions } from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"http://localhost:18888\";\nconst DEFAULT_TIMEOUT = 30_000;\n\n/** Resolve configuration from constructor args, env vars, and defaults. */\nexport function resolveConfig(opts?: AgentKernelOptions) {\n const baseUrl =\n opts?.baseUrl ??\n process.env.AGENTKERNEL_BASE_URL ??\n DEFAULT_BASE_URL;\n\n const apiKey =\n opts?.apiKey ??\n process.env.AGENTKERNEL_API_KEY ??\n undefined;\n\n const timeout = opts?.timeout ?? DEFAULT_TIMEOUT;\n\n return {\n baseUrl: baseUrl.replace(/\\/+$/, \"\"),\n apiKey,\n timeout,\n };\n}\n","/** Base error for all agentkernel SDK errors. */\nexport class AgentKernelError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AgentKernelError\";\n }\n}\n\n/** 401 Unauthorized. */\nexport class AuthError extends AgentKernelError {\n readonly status = 401;\n constructor(message = \"Unauthorized\") {\n super(message);\n this.name = \"AuthError\";\n }\n}\n\n/** 404 Not Found. */\nexport class NotFoundError extends AgentKernelError {\n readonly status = 404;\n constructor(message = \"Not found\") {\n super(message);\n this.name = \"NotFoundError\";\n }\n}\n\n/** 400 Bad Request. */\nexport class ValidationError extends AgentKernelError {\n readonly status = 400;\n constructor(message = \"Bad request\") {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\n/** 500 Internal Server Error. */\nexport class ServerError extends AgentKernelError {\n readonly status = 500;\n constructor(message = \"Internal server error\") {\n super(message);\n this.name = \"ServerError\";\n }\n}\n\n/** Network / connection error. */\nexport class NetworkError extends AgentKernelError {\n constructor(message = \"Network error\") {\n super(message);\n this.name = \"NetworkError\";\n }\n}\n\n/** SSE streaming error. */\nexport class StreamError extends AgentKernelError {\n constructor(message = \"Stream error\") {\n super(message);\n this.name = \"StreamError\";\n }\n}\n\n/** Map an HTTP status code + body to the appropriate error. */\nexport function errorFromStatus(status: number, body: string): AgentKernelError {\n let message: string;\n try {\n const parsed = JSON.parse(body);\n message = parsed.error ?? body;\n } catch {\n message = body;\n }\n\n switch (status) {\n case 400:\n return new ValidationError(message);\n case 401:\n return new AuthError(message);\n case 404:\n return new NotFoundError(message);\n default:\n return new ServerError(message);\n }\n}\n","import type {\n BatchFileWriteResponse,\n ExecOptions,\n RunOutput,\n SandboxInfo,\n} from \"./types.js\";\n\ntype ExecFn = (\n name: string,\n command: string[],\n opts?: ExecOptions,\n) => Promise<RunOutput>;\ntype RemoveFn = (name: string) => Promise<void>;\ntype GetFn = (name: string) => Promise<SandboxInfo>;\ntype WriteFilesFn = (\n name: string,\n files: Record<string, string>,\n) => Promise<BatchFileWriteResponse>;\n\n/**\n * A sandbox session that auto-removes the sandbox on dispose.\n *\n * Supports both explicit cleanup via remove() and automatic cleanup via\n * Symbol.asyncDispose (TS 5.2+ `await using`).\n *\n * @example\n * ```ts\n * await using sb = await client.sandbox(\"test\");\n * await sb.exec([\"echo\", \"hello\"]);\n * // sandbox auto-removed when scope exits\n * ```\n */\nexport class SandboxSession implements AsyncDisposable {\n readonly name: string;\n private _removed = false;\n private readonly _execInSandbox: ExecFn;\n private readonly _removeSandbox: RemoveFn;\n private readonly _getSandbox: GetFn;\n private readonly _writeFiles: WriteFilesFn;\n\n /** @internal */\n constructor(\n name: string,\n execInSandbox: ExecFn,\n removeSandbox: RemoveFn,\n getSandbox: GetFn,\n writeFiles: WriteFilesFn,\n ) {\n this.name = name;\n this._execInSandbox = execInSandbox;\n this._removeSandbox = removeSandbox;\n this._getSandbox = getSandbox;\n this._writeFiles = writeFiles;\n }\n\n /** Run a command in this sandbox. */\n async run(command: string[], opts?: ExecOptions): Promise<RunOutput> {\n return this._execInSandbox(this.name, command, opts);\n }\n\n /** Get sandbox info. */\n async info(): Promise<SandboxInfo> {\n return this._getSandbox(this.name);\n }\n\n /** Write multiple files in one request. */\n async writeFiles(\n files: Record<string, string>,\n ): Promise<BatchFileWriteResponse> {\n return this._writeFiles(this.name, files);\n }\n\n /** Remove the sandbox. Idempotent. */\n async remove(): Promise<void> {\n if (this._removed) return;\n this._removed = true;\n await this._removeSandbox(this.name);\n }\n\n /** Auto-cleanup for `await using`. */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.remove();\n }\n}\n","import { createParser, type EventSourceMessage } from \"eventsource-parser\";\nimport type { StreamEvent, StreamEventType } from \"./types.js\";\n\nconst KNOWN_EVENTS = new Set<string>([\"started\", \"progress\", \"output\", \"done\", \"error\"]);\n\n/** Shared mutable state between the pump and the generator. */\ninterface PumpState {\n events: StreamEvent[];\n resolve: (() => void) | null;\n done: boolean;\n}\n\nfunction pushEvent(state: PumpState, event: StreamEvent): void {\n state.events.push(event);\n if (state.resolve) {\n const cb = state.resolve;\n state.resolve = null;\n cb();\n }\n}\n\n/**\n * Parse an SSE response body into an async generator of StreamEvents.\n *\n * Consumes a ReadableStream<Uint8Array> from fetch() and yields typed events\n * until the stream closes or a \"done\"/\"error\" event is received.\n */\nexport async function* parseSSE(\n body: ReadableStream<Uint8Array>,\n): AsyncGenerator<StreamEvent> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n const state: PumpState = { events: [], resolve: null, done: false };\n\n const parser = createParser({\n onEvent(event: EventSourceMessage) {\n const type = event.event ?? \"message\";\n if (!KNOWN_EVENTS.has(type)) return;\n\n let data: Record<string, unknown>;\n try {\n data = JSON.parse(event.data);\n } catch {\n data = { raw: event.data };\n }\n\n pushEvent(state, { type: type as StreamEventType, data });\n },\n });\n\n // Read the stream in the background\n const pump = (async () => {\n try {\n for (;;) {\n const result = await reader.read();\n if (result.done) break;\n parser.feed(decoder.decode(result.value, { stream: true }));\n }\n } catch (err) {\n pushEvent(state, {\n type: \"error\",\n data: { message: err instanceof Error ? err.message : String(err) },\n });\n } finally {\n state.done = true;\n if (state.resolve) {\n const cb = state.resolve;\n state.resolve = null;\n cb();\n }\n }\n })();\n\n try {\n for (;;) {\n // Yield all buffered events\n while (state.events.length > 0) {\n const event = state.events.shift()!;\n yield event;\n if (event.type === \"done\" || event.type === \"error\") return;\n }\n\n // If the stream is done and no more events, exit\n if (state.done) return;\n\n // Wait for the next event\n await new Promise<void>((r) => {\n state.resolve = r;\n });\n }\n } finally {\n reader.cancel().catch(() => {});\n await pump.catch(() => {});\n }\n}\n","import { resolveConfig } from \"./config.js\";\nimport {\n AgentKernelError,\n NetworkError,\n errorFromStatus,\n} from \"./errors.js\";\nimport { SandboxSession } from \"./sandbox.js\";\nimport { parseSSE } from \"./sse.js\";\nimport type {\n AgentKernelOptions,\n ApiResponse,\n BatchCommand,\n BatchFileWriteResponse,\n BatchRunResponse,\n CreateSandboxOptions,\n DetachedCommand,\n DetachedLogsResponse,\n ExecOptions,\n FileReadResponse,\n FileWriteOptions,\n RunOptions,\n RunOutput,\n SandboxInfo,\n StreamEvent,\n} from \"./types.js\";\n\nconst SDK_VERSION = \"0.4.0\";\n\n/**\n * Client for the agentkernel HTTP API.\n *\n * @example\n * ```ts\n * const client = new AgentKernel();\n * const result = await client.run([\"echo\", \"hello\"]);\n * console.log(result.output); // \"hello\\n\"\n * ```\n */\nexport class AgentKernel {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly timeout: number;\n\n constructor(opts?: AgentKernelOptions) {\n const config = resolveConfig(opts);\n this.baseUrl = config.baseUrl;\n this.apiKey = config.apiKey;\n this.timeout = config.timeout;\n }\n\n // -- Core API methods --\n\n /** Health check. Returns \"ok\" if the server is running. */\n async health(): Promise<string> {\n const res = await this.request<string>(\"GET\", \"/health\");\n return res;\n }\n\n /** Run a command in a temporary sandbox. */\n async run(command: string[], opts?: RunOptions): Promise<RunOutput> {\n return this.request<RunOutput>(\"POST\", \"/run\", {\n command,\n image: opts?.image,\n profile: opts?.profile,\n fast: opts?.fast ?? true,\n });\n }\n\n /**\n * Run a command with SSE streaming output.\n *\n * @example\n * ```ts\n * for await (const event of client.runStream([\"python3\", \"script.py\"])) {\n * if (event.type === \"output\") process.stdout.write(String(event.data.data));\n * }\n * ```\n */\n async *runStream(\n command: string[],\n opts?: RunOptions,\n ): AsyncGenerator<StreamEvent> {\n const body = JSON.stringify({\n command,\n image: opts?.image,\n profile: opts?.profile,\n fast: opts?.fast ?? true,\n });\n\n const response = await this.fetch(\"/run/stream\", {\n method: \"POST\",\n headers: this.headers(\"application/json\"),\n body,\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw errorFromStatus(response.status, text);\n }\n\n if (!response.body) {\n throw new AgentKernelError(\"No response body for SSE stream\");\n }\n\n yield* parseSSE(response.body);\n }\n\n /** List all sandboxes. */\n async listSandboxes(): Promise<SandboxInfo[]> {\n return this.request<SandboxInfo[]>(\"GET\", \"/sandboxes\");\n }\n\n /** Create a new sandbox. */\n async createSandbox(\n name: string,\n opts?: CreateSandboxOptions,\n ): Promise<SandboxInfo> {\n return this.request<SandboxInfo>(\"POST\", \"/sandboxes\", {\n name,\n image: opts?.image,\n vcpus: opts?.vcpus,\n memory_mb: opts?.memory_mb,\n profile: opts?.profile,\n source_url: opts?.source_url,\n source_ref: opts?.source_ref,\n });\n }\n\n /** Get info about a sandbox. */\n async getSandbox(name: string): Promise<SandboxInfo> {\n return this.request<SandboxInfo>(\"GET\", `/sandboxes/${encodeURIComponent(name)}`);\n }\n\n /** Remove a sandbox. */\n async removeSandbox(name: string): Promise<void> {\n await this.request<string>(\"DELETE\", `/sandboxes/${encodeURIComponent(name)}`);\n }\n\n /** Run a command in an existing sandbox. */\n async execInSandbox(\n name: string,\n command: string[],\n opts?: ExecOptions,\n ): Promise<RunOutput> {\n return this.request<RunOutput>(\n \"POST\",\n `/sandboxes/${encodeURIComponent(name)}/exec`,\n {\n command,\n env: opts?.env,\n workdir: opts?.workdir,\n sudo: opts?.sudo,\n },\n );\n }\n\n /** Read a file from a sandbox. */\n async readFile(name: string, path: string): Promise<FileReadResponse> {\n return this.request<FileReadResponse>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n );\n }\n\n /** Write a file to a sandbox. */\n async writeFile(\n name: string,\n path: string,\n content: string,\n opts?: FileWriteOptions,\n ): Promise<string> {\n return this.request<string>(\n \"PUT\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n { content, encoding: opts?.encoding ?? \"utf8\" },\n );\n }\n\n /** Delete a file from a sandbox. */\n async deleteFile(name: string, path: string): Promise<string> {\n return this.request<string>(\n \"DELETE\",\n `/sandboxes/${encodeURIComponent(name)}/files/${path}`,\n );\n }\n\n /** Get audit log entries for a sandbox. */\n async getSandboxLogs(name: string): Promise<Record<string, unknown>[]> {\n return this.request<Record<string, unknown>[]>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/logs`,\n );\n }\n\n /** Write multiple files to a sandbox in one request. */\n async writeFiles(\n name: string,\n files: Record<string, string>,\n ): Promise<BatchFileWriteResponse> {\n return this.request<BatchFileWriteResponse>(\n \"POST\",\n `/sandboxes/${encodeURIComponent(name)}/files`,\n { files },\n );\n }\n\n /** Run multiple commands in parallel. */\n async batchRun(commands: BatchCommand[]): Promise<BatchRunResponse> {\n return this.request<BatchRunResponse>(\"POST\", \"/batch/run\", { commands });\n }\n\n /** Start a detached (background) command in a sandbox. */\n async execDetached(\n name: string,\n command: string[],\n opts?: ExecOptions,\n ): Promise<DetachedCommand> {\n return this.request<DetachedCommand>(\n \"POST\",\n `/sandboxes/${encodeURIComponent(name)}/exec/detach`,\n {\n command,\n env: opts?.env,\n workdir: opts?.workdir,\n sudo: opts?.sudo,\n },\n );\n }\n\n /** Get the status of a detached command. */\n async detachedStatus(\n name: string,\n cmdId: string,\n ): Promise<DetachedCommand> {\n return this.request<DetachedCommand>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}`,\n );\n }\n\n /** Get logs from a detached command. */\n async detachedLogs(\n name: string,\n cmdId: string,\n stream?: \"stdout\" | \"stderr\",\n ): Promise<DetachedLogsResponse> {\n const query = stream === \"stderr\" ? \"?stream=stderr\" : \"\";\n return this.request<DetachedLogsResponse>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}/logs${query}`,\n );\n }\n\n /** Kill a detached command. */\n async detachedKill(name: string, cmdId: string): Promise<string> {\n return this.request<string>(\n \"DELETE\",\n `/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}`,\n );\n }\n\n /** List detached commands in a sandbox. */\n async detachedList(name: string): Promise<DetachedCommand[]> {\n return this.request<DetachedCommand[]>(\n \"GET\",\n `/sandboxes/${encodeURIComponent(name)}/exec/detached`,\n );\n }\n\n /**\n * Create a sandbox session with automatic cleanup.\n *\n * The returned SandboxSession implements AsyncDisposable,\n * so it works with `await using` (TS 5.2+):\n *\n * @example\n * ```ts\n * await using sb = await client.sandbox(\"test\", { image: \"python:3.12-alpine\" });\n * await sb.run([\"pip\", \"install\", \"numpy\"]);\n * // sandbox auto-removed when scope exits\n * ```\n */\n async sandbox(\n name: string,\n opts?: CreateSandboxOptions,\n ): Promise<SandboxSession> {\n await this.createSandbox(name, opts);\n return new SandboxSession(\n name,\n (n, cmd, o) => this.execInSandbox(n, cmd, o),\n (n) => this.removeSandbox(n),\n (n) => this.getSandbox(n),\n (n, f) => this.writeFiles(n, f),\n );\n }\n\n // -- Internal helpers --\n\n private headers(contentType?: string): Record<string, string> {\n const h: Record<string, string> = {\n \"User-Agent\": `agentkernel-nodejs-sdk/${SDK_VERSION}`,\n };\n if (contentType) h[\"Content-Type\"] = contentType;\n if (this.apiKey) h[\"Authorization\"] = `Bearer ${this.apiKey}`;\n return h;\n }\n\n private async fetch(path: string, init: RequestInit): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n try {\n return await fetch(url, {\n ...init,\n signal: AbortSignal.timeout(this.timeout),\n });\n } catch (err) {\n if (err instanceof DOMException && err.name === \"TimeoutError\") {\n throw new NetworkError(`Request timed out after ${this.timeout}ms`);\n }\n if (err instanceof TypeError) {\n throw new NetworkError(`Failed to connect to ${this.baseUrl}: ${err.message}`);\n }\n throw new NetworkError(\n err instanceof Error ? err.message : String(err),\n );\n }\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const init: RequestInit = {\n method,\n headers: this.headers(body ? \"application/json\" : undefined),\n };\n if (body) init.body = JSON.stringify(body);\n\n const response = await this.fetch(path, init);\n\n const text = await response.text();\n if (!response.ok) {\n throw errorFromStatus(response.status, text);\n }\n\n const parsed: ApiResponse<T> = JSON.parse(text);\n if (!parsed.success) {\n throw new AgentKernelError(parsed.error ?? \"Unknown error\");\n }\n return parsed.data as T;\n }\n}\n"],"mappings":"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","names":[]}
|