agentkernel 0.8.0 → 0.10.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
@@ -23,6 +23,8 @@ __export(index_exports, {
23
23
  AgentKernel: () => AgentKernel,
24
24
  AgentKernelError: () => AgentKernelError,
25
25
  AuthError: () => AuthError,
26
+ BROWSER_SETUP_CMD: () => BROWSER_SETUP_CMD,
27
+ BrowserSession: () => BrowserSession,
26
28
  NetworkError: () => NetworkError,
27
29
  NotFoundError: () => NotFoundError,
28
30
  SandboxSession: () => SandboxSession,
@@ -113,6 +115,127 @@ function errorFromStatus(status, body) {
113
115
  }
114
116
  }
115
117
 
118
+ // src/browser.ts
119
+ var GOTO_SCRIPT = `
120
+ import asyncio, json, sys
121
+ from playwright.async_api import async_playwright
122
+ async def main():
123
+ url = sys.argv[1]
124
+ async with async_playwright() as p:
125
+ b = await p.chromium.launch()
126
+ page = await b.new_page()
127
+ await page.goto(url, timeout=30000)
128
+ title = await page.title()
129
+ url_final = page.url
130
+ text = await page.evaluate("() => document.body.innerText.slice(0, 8000)")
131
+ links = await page.evaluate('''() =>
132
+ Array.from(document.querySelectorAll('a[href]'))
133
+ .slice(0, 50)
134
+ .map(a => ({text: a.textContent.trim(), href: a.href}))
135
+ .filter(l => l.href.startsWith("http"))
136
+ ''')
137
+ print(json.dumps({"title": title, "url": url_final, "text": text, "links": links}))
138
+ await b.close()
139
+ asyncio.run(main())
140
+ `;
141
+ var SCREENSHOT_SCRIPT = `
142
+ import asyncio, base64, sys
143
+ from playwright.async_api import async_playwright
144
+ async def main():
145
+ url = sys.argv[1]
146
+ async with async_playwright() as p:
147
+ b = await p.chromium.launch()
148
+ page = await b.new_page()
149
+ await page.goto(url, timeout=30000)
150
+ data = await page.screenshot()
151
+ print(base64.b64encode(data).decode())
152
+ await b.close()
153
+ asyncio.run(main())
154
+ `;
155
+ var EVALUATE_SCRIPT = `
156
+ import asyncio, json, sys
157
+ from playwright.async_api import async_playwright
158
+ async def main():
159
+ url = sys.argv[1]
160
+ expr = sys.argv[2]
161
+ async with async_playwright() as p:
162
+ b = await p.chromium.launch()
163
+ page = await b.new_page()
164
+ await page.goto(url, timeout=30000)
165
+ result = await page.evaluate(expr)
166
+ print(json.dumps(result))
167
+ await b.close()
168
+ asyncio.run(main())
169
+ `;
170
+ var BROWSER_SETUP_CMD = [
171
+ "sh",
172
+ "-c",
173
+ "pip install -q playwright && playwright install --with-deps chromium"
174
+ ];
175
+ var BrowserSession = class {
176
+ name;
177
+ _removed = false;
178
+ _lastUrl = null;
179
+ _run;
180
+ _remove;
181
+ /** @internal */
182
+ constructor(name, runFn, removeFn) {
183
+ this.name = name;
184
+ this._run = runFn;
185
+ this._remove = removeFn;
186
+ }
187
+ /** Navigate to a URL and return page data (title, text, links). */
188
+ async goto(url) {
189
+ const result = await this._run(this.name, [
190
+ "python3",
191
+ "-c",
192
+ GOTO_SCRIPT,
193
+ url
194
+ ]);
195
+ this._lastUrl = url;
196
+ return JSON.parse(result.output);
197
+ }
198
+ /** Take a PNG screenshot. Returns a base64-encoded string. */
199
+ async screenshot(url) {
200
+ const target = url ?? this._lastUrl;
201
+ if (!target) {
202
+ throw new Error("No URL specified and no previous goto() call");
203
+ }
204
+ const result = await this._run(this.name, [
205
+ "python3",
206
+ "-c",
207
+ SCREENSHOT_SCRIPT,
208
+ target
209
+ ]);
210
+ return result.output.trim();
211
+ }
212
+ /** Run a JavaScript expression on a page and return the result. */
213
+ async evaluate(expression, url) {
214
+ const target = url ?? this._lastUrl;
215
+ if (!target) {
216
+ throw new Error("No URL specified and no previous goto() call");
217
+ }
218
+ const result = await this._run(this.name, [
219
+ "python3",
220
+ "-c",
221
+ EVALUATE_SCRIPT,
222
+ target,
223
+ expression
224
+ ]);
225
+ return JSON.parse(result.output);
226
+ }
227
+ /** Remove the sandbox. Idempotent. */
228
+ async remove() {
229
+ if (this._removed) return;
230
+ this._removed = true;
231
+ await this._remove(this.name);
232
+ }
233
+ /** Auto-cleanup for `await using`. */
234
+ async [Symbol.asyncDispose]() {
235
+ await this.remove();
236
+ }
237
+ };
238
+
116
239
  // src/sandbox.ts
117
240
  var SandboxSession = class {
118
241
  name;
@@ -120,21 +243,27 @@ var SandboxSession = class {
120
243
  _execInSandbox;
121
244
  _removeSandbox;
122
245
  _getSandbox;
246
+ _writeFiles;
123
247
  /** @internal */
124
- constructor(name, execInSandbox, removeSandbox, getSandbox) {
248
+ constructor(name, execInSandbox, removeSandbox, getSandbox, writeFiles) {
125
249
  this.name = name;
126
250
  this._execInSandbox = execInSandbox;
127
251
  this._removeSandbox = removeSandbox;
128
252
  this._getSandbox = getSandbox;
253
+ this._writeFiles = writeFiles;
129
254
  }
130
255
  /** Run a command in this sandbox. */
131
- async run(command) {
132
- return this._execInSandbox(this.name, command);
256
+ async run(command, opts) {
257
+ return this._execInSandbox(this.name, command, opts);
133
258
  }
134
259
  /** Get sandbox info. */
135
260
  async info() {
136
261
  return this._getSandbox(this.name);
137
262
  }
263
+ /** Write multiple files in one request. */
264
+ async writeFiles(files) {
265
+ return this._writeFiles(this.name, files);
266
+ }
138
267
  /** Remove the sandbox. Idempotent. */
139
268
  async remove() {
140
269
  if (this._removed) return;
@@ -217,7 +346,7 @@ async function* parseSSE(body) {
217
346
  }
218
347
 
219
348
  // src/client.ts
220
- var SDK_VERSION = "0.4.0";
349
+ var SDK_VERSION = "0.3.0";
221
350
  var AgentKernel = class {
222
351
  baseUrl;
223
352
  apiKey;
@@ -285,7 +414,10 @@ var AgentKernel = class {
285
414
  image: opts?.image,
286
415
  vcpus: opts?.vcpus,
287
416
  memory_mb: opts?.memory_mb,
288
- profile: opts?.profile
417
+ profile: opts?.profile,
418
+ source_url: opts?.source_url,
419
+ source_ref: opts?.source_ref,
420
+ volumes: opts?.volumes
289
421
  });
290
422
  }
291
423
  /** Get info about a sandbox. */
@@ -297,11 +429,16 @@ var AgentKernel = class {
297
429
  await this.request("DELETE", `/sandboxes/${encodeURIComponent(name)}`);
298
430
  }
299
431
  /** Run a command in an existing sandbox. */
300
- async execInSandbox(name, command) {
432
+ async execInSandbox(name, command, opts) {
301
433
  return this.request(
302
434
  "POST",
303
435
  `/sandboxes/${encodeURIComponent(name)}/exec`,
304
- { command }
436
+ {
437
+ command,
438
+ env: opts?.env,
439
+ workdir: opts?.workdir,
440
+ sudo: opts?.sudo
441
+ }
305
442
  );
306
443
  }
307
444
  /** Read a file from a sandbox. */
@@ -333,10 +470,60 @@ var AgentKernel = class {
333
470
  `/sandboxes/${encodeURIComponent(name)}/logs`
334
471
  );
335
472
  }
473
+ /** Write multiple files to a sandbox in one request. */
474
+ async writeFiles(name, files) {
475
+ return this.request(
476
+ "POST",
477
+ `/sandboxes/${encodeURIComponent(name)}/files`,
478
+ { files }
479
+ );
480
+ }
336
481
  /** Run multiple commands in parallel. */
337
482
  async batchRun(commands) {
338
483
  return this.request("POST", "/batch/run", { commands });
339
484
  }
485
+ /** Start a detached (background) command in a sandbox. */
486
+ async execDetached(name, command, opts) {
487
+ return this.request(
488
+ "POST",
489
+ `/sandboxes/${encodeURIComponent(name)}/exec/detach`,
490
+ {
491
+ command,
492
+ env: opts?.env,
493
+ workdir: opts?.workdir,
494
+ sudo: opts?.sudo
495
+ }
496
+ );
497
+ }
498
+ /** Get the status of a detached command. */
499
+ async detachedStatus(name, cmdId) {
500
+ return this.request(
501
+ "GET",
502
+ `/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}`
503
+ );
504
+ }
505
+ /** Get logs from a detached command. */
506
+ async detachedLogs(name, cmdId, stream) {
507
+ const query = stream === "stderr" ? "?stream=stderr" : "";
508
+ return this.request(
509
+ "GET",
510
+ `/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}/logs${query}`
511
+ );
512
+ }
513
+ /** Kill a detached command. */
514
+ async detachedKill(name, cmdId) {
515
+ return this.request(
516
+ "DELETE",
517
+ `/sandboxes/${encodeURIComponent(name)}/exec/detached/${encodeURIComponent(cmdId)}`
518
+ );
519
+ }
520
+ /** List detached commands in a sandbox. */
521
+ async detachedList(name) {
522
+ return this.request(
523
+ "GET",
524
+ `/sandboxes/${encodeURIComponent(name)}/exec/detached`
525
+ );
526
+ }
340
527
  /**
341
528
  * Create a sandbox session with automatic cleanup.
342
529
  *
@@ -354,9 +541,75 @@ var AgentKernel = class {
354
541
  await this.createSandbox(name, opts);
355
542
  return new SandboxSession(
356
543
  name,
357
- (n, cmd) => this.execInSandbox(n, cmd),
544
+ (n, cmd, o) => this.execInSandbox(n, cmd, o),
358
545
  (n) => this.removeSandbox(n),
359
- (n) => this.getSandbox(n)
546
+ (n) => this.getSandbox(n),
547
+ (n, f) => this.writeFiles(n, f)
548
+ );
549
+ }
550
+ /**
551
+ * Create a sandboxed browser session with automatic cleanup.
552
+ *
553
+ * Creates a sandbox with Chromium pre-installed via Playwright.
554
+ * Use `goto()`, `screenshot()`, and `evaluate()` to interact with web pages.
555
+ *
556
+ * @example
557
+ * ```ts
558
+ * await using browser = await client.browser("my-browser");
559
+ * const page = await browser.goto("https://example.com");
560
+ * console.log(page.title, page.links);
561
+ * // sandbox auto-removed when scope exits
562
+ * ```
563
+ */
564
+ async browser(name, opts) {
565
+ await this.createSandbox(name, {
566
+ image: "python:3.12-slim",
567
+ memory_mb: opts?.memory_mb ?? 2048,
568
+ profile: "moderate"
569
+ });
570
+ await this.execInSandbox(name, BROWSER_SETUP_CMD);
571
+ return new BrowserSession(
572
+ name,
573
+ (n, cmd) => this.execInSandbox(n, cmd),
574
+ (n) => this.removeSandbox(n)
575
+ );
576
+ }
577
+ // -- TTL & Snapshot methods --
578
+ /** Extend a sandbox's TTL. Returns the new expiry time. */
579
+ async extendTtl(name, opts) {
580
+ return this.request(
581
+ "POST",
582
+ `/sandboxes/${encodeURIComponent(name)}/extend`,
583
+ { by: opts.by }
584
+ );
585
+ }
586
+ /** List all snapshots. */
587
+ async listSnapshots() {
588
+ return this.request("GET", "/snapshots");
589
+ }
590
+ /** Take a snapshot of a sandbox. */
591
+ async takeSnapshot(opts) {
592
+ return this.request("POST", "/snapshots", opts);
593
+ }
594
+ /** Get info about a snapshot. */
595
+ async getSnapshot(name) {
596
+ return this.request(
597
+ "GET",
598
+ `/snapshots/${encodeURIComponent(name)}`
599
+ );
600
+ }
601
+ /** Delete a snapshot. */
602
+ async deleteSnapshot(name) {
603
+ await this.request(
604
+ "DELETE",
605
+ `/snapshots/${encodeURIComponent(name)}`
606
+ );
607
+ }
608
+ /** Restore a sandbox from a snapshot. */
609
+ async restoreSnapshot(name) {
610
+ return this.request(
611
+ "POST",
612
+ `/snapshots/${encodeURIComponent(name)}/restore`
360
613
  );
361
614
  }
362
615
  // -- Internal helpers --
@@ -410,6 +663,8 @@ var AgentKernel = class {
410
663
  AgentKernel,
411
664
  AgentKernelError,
412
665
  AuthError,
666
+ BROWSER_SETUP_CMD,
667
+ BrowserSession,
413
668
  NetworkError,
414
669
  NotFoundError,
415
670
  SandboxSession,
@@ -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/browser.ts","../src/sandbox.ts","../src/sse.ts","../src/client.ts"],"sourcesContent":["export { AgentKernel } from \"./client.js\";\nexport { BrowserSession, BROWSER_SETUP_CMD } from \"./browser.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 ExtendTtlOptions,\n ExtendTtlResponse,\n PageLink,\n PageResult,\n RunOptions,\n RunOutput,\n SandboxInfo,\n SnapshotMeta,\n StreamEvent,\n StreamEventType,\n SecurityProfile,\n SandboxStatus,\n TakeSnapshotOptions,\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","/**\n * Browser session for orchestrating headless browsers in sandboxes.\n *\n * Each method generates a self-contained Python/Playwright script,\n * runs it inside the sandbox, and parses the JSON result.\n */\n\nimport type { PageResult, RunOutput } from \"./types.js\";\n\ntype RunInSandboxFn = (\n name: string,\n command: string[],\n) => Promise<RunOutput>;\ntype RemoveSandboxFn = (name: string) => Promise<void>;\n\nconst GOTO_SCRIPT = `\nimport asyncio, json, sys\nfrom playwright.async_api import async_playwright\nasync def main():\n url = sys.argv[1]\n async with async_playwright() as p:\n b = await p.chromium.launch()\n page = await b.new_page()\n await page.goto(url, timeout=30000)\n title = await page.title()\n url_final = page.url\n text = await page.evaluate(\"() => document.body.innerText.slice(0, 8000)\")\n links = await page.evaluate('''() =>\n Array.from(document.querySelectorAll('a[href]'))\n .slice(0, 50)\n .map(a => ({text: a.textContent.trim(), href: a.href}))\n .filter(l => l.href.startsWith(\"http\"))\n ''')\n print(json.dumps({\"title\": title, \"url\": url_final, \"text\": text, \"links\": links}))\n await b.close()\nasyncio.run(main())\n`;\n\nconst SCREENSHOT_SCRIPT = `\nimport asyncio, base64, sys\nfrom playwright.async_api import async_playwright\nasync def main():\n url = sys.argv[1]\n async with async_playwright() as p:\n b = await p.chromium.launch()\n page = await b.new_page()\n await page.goto(url, timeout=30000)\n data = await page.screenshot()\n print(base64.b64encode(data).decode())\n await b.close()\nasyncio.run(main())\n`;\n\nconst EVALUATE_SCRIPT = `\nimport asyncio, json, sys\nfrom playwright.async_api import async_playwright\nasync def main():\n url = sys.argv[1]\n expr = sys.argv[2]\n async with async_playwright() as p:\n b = await p.chromium.launch()\n page = await b.new_page()\n await page.goto(url, timeout=30000)\n result = await page.evaluate(expr)\n print(json.dumps(result))\n await b.close()\nasyncio.run(main())\n`;\n\n/** Command to install Playwright + Chromium inside the sandbox. */\nexport const BROWSER_SETUP_CMD = [\n \"sh\",\n \"-c\",\n \"pip install -q playwright && playwright install --with-deps chromium\",\n];\n\n/**\n * A sandboxed headless browser controlled from outside.\n *\n * The browser (Chromium via Playwright) runs inside an agentkernel sandbox.\n * You call high-level methods; the SDK generates and runs scripts internally.\n *\n * @example\n * ```ts\n * await using browser = await client.browser(\"my-browser\");\n * const page = await browser.goto(\"https://example.com\");\n * console.log(page.title, page.links);\n * ```\n */\nexport class BrowserSession implements AsyncDisposable {\n readonly name: string;\n private _removed = false;\n private _lastUrl: string | null = null;\n private readonly _run: RunInSandboxFn;\n private readonly _remove: RemoveSandboxFn;\n\n /** @internal */\n constructor(name: string, runFn: RunInSandboxFn, removeFn: RemoveSandboxFn) {\n this.name = name;\n this._run = runFn;\n this._remove = removeFn;\n }\n\n /** Navigate to a URL and return page data (title, text, links). */\n async goto(url: string): Promise<PageResult> {\n const result = await this._run(this.name, [\n \"python3\",\n \"-c\",\n GOTO_SCRIPT,\n url,\n ]);\n this._lastUrl = url;\n return JSON.parse(result.output) as PageResult;\n }\n\n /** Take a PNG screenshot. Returns a base64-encoded string. */\n async screenshot(url?: string): Promise<string> {\n const target = url ?? this._lastUrl;\n if (!target) {\n throw new Error(\"No URL specified and no previous goto() call\");\n }\n const result = await this._run(this.name, [\n \"python3\",\n \"-c\",\n SCREENSHOT_SCRIPT,\n target,\n ]);\n return result.output.trim();\n }\n\n /** Run a JavaScript expression on a page and return the result. */\n async evaluate(expression: string, url?: string): Promise<unknown> {\n const target = url ?? this._lastUrl;\n if (!target) {\n throw new Error(\"No URL specified and no previous goto() call\");\n }\n const result = await this._run(this.name, [\n \"python3\",\n \"-c\",\n EVALUATE_SCRIPT,\n target,\n expression,\n ]);\n return JSON.parse(result.output);\n }\n\n /** Remove the sandbox. Idempotent. */\n async remove(): Promise<void> {\n if (this._removed) return;\n this._removed = true;\n await this._remove(this.name);\n }\n\n /** Auto-cleanup for `await using`. */\n async [Symbol.asyncDispose](): Promise<void> {\n await this.remove();\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 { BrowserSession, BROWSER_SETUP_CMD } from \"./browser.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 ExtendTtlOptions,\n ExtendTtlResponse,\n FileReadResponse,\n FileWriteOptions,\n RunOptions,\n RunOutput,\n SandboxInfo,\n SnapshotMeta,\n StreamEvent,\n TakeSnapshotOptions,\n} from \"./types.js\";\n\nconst SDK_VERSION = \"0.3.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 volumes: opts?.volumes,\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 /**\n * Create a sandboxed browser session with automatic cleanup.\n *\n * Creates a sandbox with Chromium pre-installed via Playwright.\n * Use `goto()`, `screenshot()`, and `evaluate()` to interact with web pages.\n *\n * @example\n * ```ts\n * await using browser = await client.browser(\"my-browser\");\n * const page = await browser.goto(\"https://example.com\");\n * console.log(page.title, page.links);\n * // sandbox auto-removed when scope exits\n * ```\n */\n async browser(\n name: string,\n opts?: { memory_mb?: number },\n ): Promise<BrowserSession> {\n await this.createSandbox(name, {\n image: \"python:3.12-slim\",\n memory_mb: opts?.memory_mb ?? 2048,\n profile: \"moderate\",\n });\n await this.execInSandbox(name, BROWSER_SETUP_CMD);\n return new BrowserSession(\n name,\n (n, cmd) => this.execInSandbox(n, cmd),\n (n) => this.removeSandbox(n),\n );\n }\n\n // -- TTL & Snapshot methods --\n\n /** Extend a sandbox's TTL. Returns the new expiry time. */\n async extendTtl(name: string, opts: ExtendTtlOptions): Promise<ExtendTtlResponse> {\n return this.request<ExtendTtlResponse>(\n \"POST\",\n `/sandboxes/${encodeURIComponent(name)}/extend`,\n { by: opts.by },\n );\n }\n\n /** List all snapshots. */\n async listSnapshots(): Promise<SnapshotMeta[]> {\n return this.request<SnapshotMeta[]>(\"GET\", \"/snapshots\");\n }\n\n /** Take a snapshot of a sandbox. */\n async takeSnapshot(opts: TakeSnapshotOptions): Promise<SnapshotMeta> {\n return this.request<SnapshotMeta>(\"POST\", \"/snapshots\", opts);\n }\n\n /** Get info about a snapshot. */\n async getSnapshot(name: string): Promise<SnapshotMeta> {\n return this.request<SnapshotMeta>(\n \"GET\",\n `/snapshots/${encodeURIComponent(name)}`,\n );\n }\n\n /** Delete a snapshot. */\n async deleteSnapshot(name: string): Promise<void> {\n await this.request<string>(\n \"DELETE\",\n `/snapshots/${encodeURIComponent(name)}`,\n );\n }\n\n /** Restore a sandbox from a snapshot. */\n async restoreSnapshot(name: string): Promise<SandboxInfo> {\n return this.request<SandboxInfo>(\n \"POST\",\n `/snapshots/${encodeURIComponent(name)}/restore`,\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":[]}