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 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
- Run a command in an existing sandbox.
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
- { command }
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 --
@@ -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":"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","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
- { command }
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":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentkernel",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Node.js SDK for agentkernel — run AI coding agents in secure, isolated microVMs",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",