@opencoredev/sandbox-sdk 0.1.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +33 -0
  4. package/dist/agentos-BOFA_q-a.mjs +389 -0
  5. package/dist/agentos-BOFA_q-a.mjs.map +1 -0
  6. package/dist/ai/harness.d.mts +16 -0
  7. package/dist/ai/harness.mjs +69 -0
  8. package/dist/ai/harness.mjs.map +1 -0
  9. package/dist/ai/index.d.mts +54 -0
  10. package/dist/ai/index.mjs +4 -0
  11. package/dist/ai-DhfwIZdL.mjs +243 -0
  12. package/dist/ai-DhfwIZdL.mjs.map +1 -0
  13. package/dist/capabilities-CEowrzRM.mjs +99 -0
  14. package/dist/capabilities-CEowrzRM.mjs.map +1 -0
  15. package/dist/capabilities-CMnszzpt.d.mts +13 -0
  16. package/dist/capabilities-COKpwoFH.mjs +28 -0
  17. package/dist/capabilities-COKpwoFH.mjs.map +1 -0
  18. package/dist/errors-Ch9PHKTd.mjs +61 -0
  19. package/dist/errors-Ch9PHKTd.mjs.map +1 -0
  20. package/dist/eve/index.d.mts +19 -0
  21. package/dist/eve/index.mjs +155 -0
  22. package/dist/eve/index.mjs.map +1 -0
  23. package/dist/index-B1YT6OQ8.d.mts +25 -0
  24. package/dist/index-BMFkO6Fv.d.mts +31 -0
  25. package/dist/index.d.mts +5 -0
  26. package/dist/index.mjs +38 -0
  27. package/dist/index.mjs.map +1 -0
  28. package/dist/mastra/index.d.mts +118 -0
  29. package/dist/mastra/index.mjs +662 -0
  30. package/dist/mastra/index.mjs.map +1 -0
  31. package/dist/metadata.d.mts +34 -0
  32. package/dist/metadata.mjs +103 -0
  33. package/dist/metadata.mjs.map +1 -0
  34. package/dist/provider-_caCV8kk.d.mts +91 -0
  35. package/dist/provider-utils-DilOYLBO.mjs +201 -0
  36. package/dist/provider-utils-DilOYLBO.mjs.map +1 -0
  37. package/dist/providers/agentos/index.d.mts +7 -0
  38. package/dist/providers/agentos/index.mjs +8 -0
  39. package/dist/providers/daytona/index.d.mts +21 -0
  40. package/dist/providers/daytona/index.mjs +205 -0
  41. package/dist/providers/daytona/index.mjs.map +1 -0
  42. package/dist/providers/e2b/index.d.mts +17 -0
  43. package/dist/providers/e2b/index.mjs +168 -0
  44. package/dist/providers/e2b/index.mjs.map +1 -0
  45. package/dist/providers/local/index.d.mts +22 -0
  46. package/dist/providers/local/index.mjs +21 -0
  47. package/dist/providers/local/index.mjs.map +1 -0
  48. package/dist/providers/upstash/index.d.mts +17 -0
  49. package/dist/providers/upstash/index.mjs +210 -0
  50. package/dist/providers/upstash/index.mjs.map +1 -0
  51. package/dist/providers/vercel/index.d.mts +27 -0
  52. package/dist/providers/vercel/index.mjs +185 -0
  53. package/dist/providers/vercel/index.mjs.map +1 -0
  54. package/dist/sandbox-BUYT-1C9.d.mts +17 -0
  55. package/dist/sandbox-BwyHcB_C.mjs +102 -0
  56. package/dist/sandbox-BwyHcB_C.mjs.map +1 -0
  57. package/dist/testing/index.d.mts +27 -0
  58. package/dist/testing/index.mjs +173 -0
  59. package/dist/testing/index.mjs.map +1 -0
  60. package/dist/types-BTagTtsp.d.mts +100 -0
  61. package/package.json +151 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ ## @opencoredev/sandbox-sdk@0.1.0
2
+
3
+ ### Initial release
4
+
5
+ - Run one TypeScript sandbox API across Local, E2B, Daytona, Vercel Sandbox, and Upstash Box.
6
+ - Use normalized files, commands, processes, ports, snapshots, and provider capabilities.
7
+ - Integrate sandbox sessions with AI SDK, Harness, Eve, and Mastra.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OpenCore
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,33 @@
1
+ <p align="center">
2
+ <img alt="Sandbox SDK with supported provider logos" src="https://raw.githubusercontent.com/opencoredev/sandbox-sdk/main/Background-with-text.png" width="820" />
3
+ </p>
4
+
5
+ Run the same TypeScript sandbox code on Local, E2B, Daytona, Vercel Sandbox, or Upstash Box.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ bun add @opencoredev/sandbox-sdk
11
+ ```
12
+
13
+ Node.js 22 or 24 is supported. Bun 1.3 or newer is also supported.
14
+
15
+ ## Providers
16
+
17
+ | Provider | Runtime | Best for |
18
+ | --------------------------------------------------------------- | ----------------------- | -------------------------------------- |
19
+ | [Local](https://sandbox-sdk.app/docs/providers/local) | AgentOS VM | Development, CI, and self-hosting |
20
+ | [E2B](https://sandbox-sdk.app/docs/providers/e2b) | Hosted Linux sandbox | Coding agents and isolated jobs |
21
+ | [Daytona](https://sandbox-sdk.app/docs/providers/daytona) | Cloud workspace | Persistent projects and GPUs |
22
+ | [Vercel Sandbox](https://sandbox-sdk.app/docs/providers/vercel) | Hosted Linux sandbox | Vercel workloads and previews |
23
+ | [Upstash Box](https://sandbox-sdk.app/docs/providers/upstash) | Durable cloud container | Serverless agents and long-lived state |
24
+
25
+ Local is included. Cloud providers use their official SDKs and credentials.
26
+
27
+ ## Documentation
28
+
29
+ Setup, usage, integrations, and API reference are available at [sandbox-sdk.app/docs](https://sandbox-sdk.app/docs).
30
+
31
+ ## License
32
+
33
+ [MIT](./LICENSE) © OpenCore
@@ -0,0 +1,389 @@
1
+ import { t as SandboxError } from "./errors-Ch9PHKTd.mjs";
2
+ import { i as localCapabilities } from "./capabilities-CEowrzRM.mjs";
3
+ import { n as portResult, o as withManagedSessions, r as toUint8Array } from "./provider-utils-DilOYLBO.mjs";
4
+ import { randomUUID } from "node:crypto";
5
+
6
+ //#region src/providers/agentos/index.ts
7
+ const DEFAULT_PERMISSIONS = {
8
+ fs: "allow",
9
+ childProcess: "allow",
10
+ process: "allow",
11
+ env: "allow",
12
+ network: {
13
+ default: "deny",
14
+ rules: [{
15
+ mode: "allow",
16
+ operations: ["listen"],
17
+ patterns: ["**"]
18
+ }, {
19
+ mode: "allow",
20
+ operations: ["http"],
21
+ patterns: [
22
+ "tcp://127.0.0.1:*",
23
+ "tcp://[::1]:*",
24
+ "tcp://localhost:*"
25
+ ]
26
+ }]
27
+ },
28
+ binding: "deny"
29
+ };
30
+ const DEFAULT_LIMITS = {
31
+ resources: {
32
+ cpuCount: 1,
33
+ maxProcesses: 64,
34
+ maxOpenFds: 256,
35
+ maxPipes: 128,
36
+ maxPtys: 16,
37
+ maxSockets: 128,
38
+ maxConnections: 64,
39
+ maxFilesystemBytes: 512 * 1024 * 1024,
40
+ maxInodeCount: 1e5,
41
+ maxWasmMemoryBytes: 256 * 1024 * 1024
42
+ },
43
+ http: { maxFetchResponseBytes: 16 * 1024 * 1024 },
44
+ jsRuntime: {
45
+ v8HeapLimitMb: 256,
46
+ wallClockLimitMs: 12e4,
47
+ capturedOutputLimitBytes: 8 * 1024 * 1024,
48
+ stdinBufferLimitBytes: 1024 * 1024
49
+ }
50
+ };
51
+ /**
52
+ * Internal constructor for the AgentOS VM that powers the Local provider.
53
+ *
54
+ * Outbound networking is denied by default. Pass an explicit agentOS permission policy when the
55
+ * guest needs network or host bindings.
56
+ */
57
+ function createAgentOsProvider(options = {}) {
58
+ return withManagedSessions({
59
+ id: "local",
60
+ capabilities: localCapabilities,
61
+ async create(createOptions) {
62
+ const id = randomUUID();
63
+ const snapshots = /* @__PURE__ */ new Map();
64
+ const baseOptions = options.agentOs ?? {};
65
+ let vm = null;
66
+ let suspendedRoot;
67
+ let stopped = false;
68
+ const createVm = async (root) => {
69
+ let AgentOs;
70
+ try {
71
+ ({AgentOs} = await import("@rivet-dev/agentos-core"));
72
+ } catch (error) {
73
+ throw new SandboxError({
74
+ code: "unavailable",
75
+ provider: "local",
76
+ operation: "sandbox.create",
77
+ message: "The Local provider could not load its @rivet-dev/agentos-core runtime dependency.",
78
+ cause: error
79
+ });
80
+ }
81
+ const next = await AgentOs.create({
82
+ ...baseOptions,
83
+ permissions: baseOptions.permissions ?? DEFAULT_PERMISSIONS,
84
+ limits: baseOptions.limits ?? DEFAULT_LIMITS,
85
+ ...root ? { rootFilesystem: {
86
+ disableDefaultBaseLayer: true,
87
+ lowers: [root]
88
+ } } : {}
89
+ });
90
+ await next.mkdir(createOptions.cwd, { recursive: true });
91
+ return next;
92
+ };
93
+ const currentVm = () => {
94
+ if (stopped) throw new SandboxError({
95
+ code: "terminated",
96
+ provider: "local",
97
+ operation: "sandbox",
98
+ message: "Sandbox has stopped"
99
+ });
100
+ if (!vm) throw new SandboxError({
101
+ code: "terminated",
102
+ provider: "local",
103
+ operation: "sandbox",
104
+ message: "Sandbox is suspended; call sandbox.raw.resume() before using it"
105
+ });
106
+ return vm;
107
+ };
108
+ const suspend = async () => {
109
+ if (stopped || !vm) return;
110
+ suspendedRoot = await vm.snapshotRootFilesystem();
111
+ await vm.dispose();
112
+ vm = null;
113
+ };
114
+ const resume = async () => {
115
+ if (stopped) throw new SandboxError({
116
+ code: "terminated",
117
+ provider: "local",
118
+ operation: "sandbox.resume",
119
+ message: "A stopped sandbox cannot be resumed"
120
+ });
121
+ if (vm) return;
122
+ vm = await createVm(suspendedRoot);
123
+ suspendedRoot = void 0;
124
+ };
125
+ vm = await createVm();
126
+ return {
127
+ id,
128
+ raw: {
129
+ get vm() {
130
+ return currentVm();
131
+ },
132
+ suspend,
133
+ resume
134
+ },
135
+ capabilities: localCapabilities,
136
+ files: {
137
+ write: async (path, value) => currentVm().writeFile(path, await toUint8Array(value)),
138
+ read: (path) => currentVm().readFile(path),
139
+ async list(path) {
140
+ return (await currentVm().readdirRecursive(path, { maxDepth: 0 })).map((entry) => ({
141
+ name: entry.path.slice(entry.path.lastIndexOf("/") + 1),
142
+ path: entry.path,
143
+ type: entry.type,
144
+ size: entry.type === "file" ? entry.size : void 0
145
+ }));
146
+ },
147
+ mkdir: (path) => currentVm().mkdir(path, { recursive: true }),
148
+ async remove(path) {
149
+ if (path === "/") throw new SandboxError({
150
+ code: "invalid_input",
151
+ provider: "local",
152
+ operation: "files.remove",
153
+ message: "Cannot remove the sandbox root"
154
+ });
155
+ await currentVm().delete(path, { recursive: true });
156
+ },
157
+ exists: (path) => currentVm().exists(path)
158
+ },
159
+ run: (command, runOptions) => runCommand(currentVm(), command, withEnv(createOptions, runOptions)),
160
+ async start(command, runOptions) {
161
+ return startProcess(currentVm(), command, withEnv(createOptions, runOptions));
162
+ },
163
+ async expose(port) {
164
+ validatePort(port);
165
+ const url = `http://agentos-${id}.internal:${port}`;
166
+ return portResult(port, url, false, false, (path = "/", init) => {
167
+ const request = new Request(new URL(path, url), init);
168
+ return currentVm().fetch(port, request);
169
+ });
170
+ },
171
+ snapshots: {
172
+ async create(snapshotOptions) {
173
+ const snapshot = {
174
+ id: randomUUID(),
175
+ name: snapshotOptions?.name,
176
+ mode: "filesystem",
177
+ createdAt: /* @__PURE__ */ new Date()
178
+ };
179
+ snapshots.set(snapshot.id, {
180
+ metadata: snapshot,
181
+ root: await currentVm().snapshotRootFilesystem()
182
+ });
183
+ return snapshot;
184
+ },
185
+ async delete(snapshot) {
186
+ const id$1 = typeof snapshot === "string" ? snapshot : snapshot.id;
187
+ if (!snapshots.delete(id$1)) throw snapshotNotFound(id$1, "snapshot.delete");
188
+ },
189
+ async restore(snapshot) {
190
+ const id$1 = typeof snapshot === "string" ? snapshot : snapshot.id;
191
+ const stored = snapshots.get(id$1);
192
+ if (!stored) throw snapshotNotFound(id$1, "snapshot.restore");
193
+ const previous = currentVm();
194
+ vm = null;
195
+ await previous.dispose();
196
+ try {
197
+ vm = await createVm(stored.root);
198
+ } catch (error) {
199
+ stopped = true;
200
+ throw error;
201
+ }
202
+ }
203
+ },
204
+ async stop() {
205
+ if (stopped) return;
206
+ stopped = true;
207
+ suspendedRoot = void 0;
208
+ snapshots.clear();
209
+ const active = vm;
210
+ vm = null;
211
+ await active?.dispose();
212
+ }
213
+ };
214
+ }
215
+ }, [], {
216
+ stop: (sandbox) => sandbox.raw.suspend(),
217
+ resume: (sandbox) => sandbox.raw.resume()
218
+ });
219
+ }
220
+ /**
221
+ * @deprecated AgentOS now powers `local()` under the hood. Import `local` from
222
+ * `@opencoredev/sandbox-sdk/local` instead.
223
+ */
224
+ function agentos(options = {}) {
225
+ return createAgentOsProvider(options);
226
+ }
227
+ function withEnv(createOptions, runOptions) {
228
+ return {
229
+ ...runOptions,
230
+ env: {
231
+ ...createOptions.env,
232
+ ...runOptions.env
233
+ }
234
+ };
235
+ }
236
+ function commandParts(command) {
237
+ return typeof command === "string" ? ["sh", ["-lc", command]] : [command.command, [...command.args ?? []]];
238
+ }
239
+ function startProcess(vm, command, options) {
240
+ if (options.signal?.aborted) throw interrupted("process.start");
241
+ const [executable, args] = commandParts(command);
242
+ const history = [];
243
+ const waiting = /* @__PURE__ */ new Set();
244
+ let state = "running";
245
+ let exitCode;
246
+ const push = (stream, data) => {
247
+ const output = stream === "stderr" ? withoutInternalAgentOsWarnings(data) : data;
248
+ if (output.byteLength === 0) return;
249
+ history.push({
250
+ stream,
251
+ data: new Uint8Array(output),
252
+ timestamp: /* @__PURE__ */ new Date()
253
+ });
254
+ for (const wake of waiting) wake();
255
+ waiting.clear();
256
+ };
257
+ const process = vm.spawn(executable, args, {
258
+ cwd: options.cwd,
259
+ env: options.env ? { ...options.env } : void 0,
260
+ streamStdin: true,
261
+ onStdout: (data) => push("stdout", data),
262
+ onStderr: (data) => push("stderr", data)
263
+ });
264
+ const completed = vm.waitProcess(process.pid).then((code) => {
265
+ exitCode = code;
266
+ state = code === 137 || code === 143 ? "killed" : "exited";
267
+ for (const wake of waiting) wake();
268
+ waiting.clear();
269
+ return { exitCode: code };
270
+ });
271
+ const abort = () => vm.stopProcess(process.pid);
272
+ options.signal?.addEventListener("abort", abort, { once: true });
273
+ completed.finally(() => options.signal?.removeEventListener("abort", abort));
274
+ return {
275
+ id: String(process.pid),
276
+ async status() {
277
+ return state;
278
+ },
279
+ async *output() {
280
+ let index = 0;
281
+ while (state === "running" || index < history.length) {
282
+ while (index < history.length) yield history[index++];
283
+ if (state !== "running") break;
284
+ await new Promise((resolve) => waiting.add(resolve));
285
+ }
286
+ },
287
+ write: (value) => vm.writeProcessStdin(process.pid, value),
288
+ wait: () => exitCode === void 0 ? completed : Promise.resolve({ exitCode }),
289
+ async kill(signal = "SIGTERM") {
290
+ if (state !== "running") return;
291
+ if (signal === "SIGKILL" || signal === "KILL" || signal === "9") vm.killProcess(process.pid);
292
+ else vm.stopProcess(process.pid);
293
+ }
294
+ };
295
+ }
296
+ function withoutInternalAgentOsWarnings(data) {
297
+ const value = new TextDecoder().decode(data).replaceAll("\x1B[33m WARN\x1B[0m could not retrieve pid for child process\n", "");
298
+ return new TextEncoder().encode(value);
299
+ }
300
+ async function runCommand(vm, command, options) {
301
+ const started = performance.now();
302
+ const process = startProcess(vm, command, options);
303
+ const stdout = [];
304
+ const stderr = [];
305
+ const collect = (async () => {
306
+ for await (const event of process.output()) {
307
+ const bytes = typeof event.data === "string" ? new TextEncoder().encode(event.data) : event.data;
308
+ (event.stream === "stdout" ? stdout : stderr).push(bytes);
309
+ }
310
+ })();
311
+ let timeout;
312
+ let removeAbort = () => {};
313
+ const interruptions = [];
314
+ if (options.timeout && options.timeout > 0) interruptions.push(new Promise((_, reject) => {
315
+ timeout = setTimeout(() => {
316
+ process.kill("SIGKILL");
317
+ reject(new SandboxError({
318
+ code: "timeout",
319
+ provider: "local",
320
+ operation: "process.run",
321
+ message: `Command timed out after ${options.timeout}ms`
322
+ }));
323
+ }, options.timeout);
324
+ }));
325
+ if (options.signal) interruptions.push(new Promise((_, reject) => {
326
+ const abort = () => {
327
+ process.kill("SIGKILL");
328
+ reject(interrupted("process.run"));
329
+ };
330
+ options.signal.addEventListener("abort", abort, { once: true });
331
+ removeAbort = () => options.signal.removeEventListener("abort", abort);
332
+ }));
333
+ try {
334
+ const result = await Promise.race([process.wait(), ...interruptions]);
335
+ await collect;
336
+ return {
337
+ stdout: decodeChunks(stdout),
338
+ stderr: decodeChunks(stderr),
339
+ exitCode: result.exitCode,
340
+ success: result.exitCode === 0,
341
+ durationMs: Math.round(performance.now() - started)
342
+ };
343
+ } catch (error) {
344
+ await process.wait().catch(() => {});
345
+ await collect.catch(() => {});
346
+ throw error;
347
+ } finally {
348
+ if (timeout) clearTimeout(timeout);
349
+ removeAbort();
350
+ }
351
+ }
352
+ function decodeChunks(chunks) {
353
+ const length = chunks.reduce((total, chunk) => total + chunk.byteLength, 0);
354
+ const output = new Uint8Array(length);
355
+ let offset = 0;
356
+ for (const chunk of chunks) {
357
+ output.set(chunk, offset);
358
+ offset += chunk.byteLength;
359
+ }
360
+ return new TextDecoder().decode(output);
361
+ }
362
+ function validatePort(port) {
363
+ if (!Number.isInteger(port) || port < 1 || port > 65535) throw new SandboxError({
364
+ code: "invalid_input",
365
+ provider: "local",
366
+ operation: "ports.expose",
367
+ message: `Invalid port: ${port}`
368
+ });
369
+ }
370
+ function snapshotNotFound(id, operation) {
371
+ return new SandboxError({
372
+ code: "not_found",
373
+ provider: "local",
374
+ operation,
375
+ message: `Snapshot not found: ${id}`
376
+ });
377
+ }
378
+ function interrupted(operation) {
379
+ return new SandboxError({
380
+ code: "terminated",
381
+ provider: "local",
382
+ operation,
383
+ message: "Operation was aborted"
384
+ });
385
+ }
386
+
387
+ //#endregion
388
+ export { agentos as t };
389
+ //# sourceMappingURL=agentos-BOFA_q-a.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentos-BOFA_q-a.mjs","names":["DEFAULT_PERMISSIONS: Permissions","DEFAULT_LIMITS: NonNullable<AgentOsOptions[\"limits\"]>","vm: AgentOsVm | null","suspendedRoot: RootSnapshotExport | undefined","AgentOs: (typeof import(\"@rivet-dev/agentos-core\"))[\"AgentOs\"]","snapshot: SandboxSnapshot","id","history: ProcessOutputEvent[]","state: ProcessStatus","exitCode: number | undefined","stdout: Uint8Array[]","stderr: Uint8Array[]","timeout: ReturnType<typeof setTimeout> | undefined","interruptions: Promise<never>[]"],"sources":["../src/providers/agentos/index.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type {\n AgentOs as AgentOsVm,\n AgentOsOptions,\n Permissions,\n RootSnapshotExport,\n} from \"@rivet-dev/agentos-core\";\nimport { SandboxError } from \"../../core/errors\";\nimport type { SandboxProvider, SandboxRuntime } from \"../../core/provider\";\nimport type {\n CommandInput,\n CommandResult,\n ProcessOutputEvent,\n ProcessStatus,\n RunOptions,\n SandboxDirectoryEntry,\n SandboxProcess,\n SandboxSnapshot,\n} from \"../../core/types\";\nimport { withManagedSessions } from \"../../internal/managed-provider\";\nimport { portResult, toUint8Array } from \"../../internal/provider-utils\";\nimport { localCapabilities } from \"../capabilities\";\n\nconst DEFAULT_PERMISSIONS: Permissions = {\n fs: \"allow\",\n childProcess: \"allow\",\n process: \"allow\",\n env: \"allow\",\n network: {\n default: \"deny\",\n rules: [\n { mode: \"allow\", operations: [\"listen\"], patterns: [\"**\"] },\n {\n mode: \"allow\",\n operations: [\"http\"],\n patterns: [\"tcp://127.0.0.1:*\", \"tcp://[::1]:*\", \"tcp://localhost:*\"],\n },\n ],\n },\n binding: \"deny\",\n};\n\nconst DEFAULT_LIMITS: NonNullable<AgentOsOptions[\"limits\"]> = {\n resources: {\n cpuCount: 1,\n maxProcesses: 64,\n maxOpenFds: 256,\n maxPipes: 128,\n maxPtys: 16,\n maxSockets: 128,\n maxConnections: 64,\n maxFilesystemBytes: 512 * 1024 * 1024,\n maxInodeCount: 100_000,\n maxWasmMemoryBytes: 256 * 1024 * 1024,\n },\n http: { maxFetchResponseBytes: 16 * 1024 * 1024 },\n jsRuntime: {\n v8HeapLimitMb: 256,\n wallClockLimitMs: 120_000,\n capturedOutputLimitBytes: 8 * 1024 * 1024,\n stdinBufferLimitBytes: 1024 * 1024,\n },\n};\n\nexport interface AgentOsProviderOptions {\n /**\n * Native agentOS VM options. The provider supplies production-oriented permissions and limits\n * unless these fields are explicitly provided.\n */\n agentOs?: AgentOsOptions;\n}\n\nexport interface AgentOsSandbox {\n /** The currently running native VM. Access throws while the sandbox is suspended or stopped. */\n readonly vm: AgentOsVm;\n suspend(): Promise<void>;\n resume(): Promise<void>;\n}\n\ntype StoredSnapshot = {\n metadata: SandboxSnapshot;\n root: RootSnapshotExport;\n};\n\nexport { agentosCapabilities } from \"../capabilities\";\n\n/**\n * Internal constructor for the AgentOS VM that powers the Local provider.\n *\n * Outbound networking is denied by default. Pass an explicit agentOS permission policy when the\n * guest needs network or host bindings.\n */\nfunction createAgentOsProvider(\n options: AgentOsProviderOptions = {},\n): SandboxProvider<AgentOsSandbox> {\n const provider: SandboxProvider<AgentOsSandbox> = {\n id: \"local\",\n capabilities: localCapabilities,\n async create(createOptions) {\n const id = randomUUID();\n const snapshots = new Map<string, StoredSnapshot>();\n const baseOptions = options.agentOs ?? {};\n let vm: AgentOsVm | null = null;\n let suspendedRoot: RootSnapshotExport | undefined;\n let stopped = false;\n\n const createVm = async (root?: RootSnapshotExport): Promise<AgentOsVm> => {\n let AgentOs: (typeof import(\"@rivet-dev/agentos-core\"))[\"AgentOs\"];\n try {\n ({ AgentOs } = await import(\"@rivet-dev/agentos-core\"));\n } catch (error) {\n throw new SandboxError({\n code: \"unavailable\",\n provider: \"local\",\n operation: \"sandbox.create\",\n message:\n \"The Local provider could not load its @rivet-dev/agentos-core runtime dependency.\",\n cause: error,\n });\n }\n const next = await AgentOs.create({\n ...baseOptions,\n permissions: baseOptions.permissions ?? DEFAULT_PERMISSIONS,\n limits: baseOptions.limits ?? DEFAULT_LIMITS,\n ...(root\n ? {\n rootFilesystem: {\n disableDefaultBaseLayer: true,\n lowers: [root],\n },\n }\n : {}),\n });\n await next.mkdir(createOptions.cwd, { recursive: true });\n return next;\n };\n\n const currentVm = (): AgentOsVm => {\n if (stopped)\n throw new SandboxError({\n code: \"terminated\",\n provider: \"local\",\n operation: \"sandbox\",\n message: \"Sandbox has stopped\",\n });\n if (!vm)\n throw new SandboxError({\n code: \"terminated\",\n provider: \"local\",\n operation: \"sandbox\",\n message: \"Sandbox is suspended; call sandbox.raw.resume() before using it\",\n });\n return vm;\n };\n\n const suspend = async () => {\n if (stopped || !vm) return;\n suspendedRoot = await vm.snapshotRootFilesystem();\n await vm.dispose();\n vm = null;\n };\n\n const resume = async () => {\n if (stopped)\n throw new SandboxError({\n code: \"terminated\",\n provider: \"local\",\n operation: \"sandbox.resume\",\n message: \"A stopped sandbox cannot be resumed\",\n });\n if (vm) return;\n vm = await createVm(suspendedRoot);\n suspendedRoot = undefined;\n };\n\n vm = await createVm();\n const raw: AgentOsSandbox = {\n get vm() {\n return currentVm();\n },\n suspend,\n resume,\n };\n\n const runtime: SandboxRuntime<AgentOsSandbox> = {\n id,\n raw,\n capabilities: localCapabilities,\n files: {\n write: async (path, value) => currentVm().writeFile(path, await toUint8Array(value)),\n read: (path) => currentVm().readFile(path),\n async list(path) {\n const entries = await currentVm().readdirRecursive(path, { maxDepth: 0 });\n return entries.map(\n (entry): SandboxDirectoryEntry => ({\n name: entry.path.slice(entry.path.lastIndexOf(\"/\") + 1),\n path: entry.path,\n type: entry.type,\n size: entry.type === \"file\" ? entry.size : undefined,\n }),\n );\n },\n mkdir: (path) => currentVm().mkdir(path, { recursive: true }),\n async remove(path) {\n if (path === \"/\")\n throw new SandboxError({\n code: \"invalid_input\",\n provider: \"local\",\n operation: \"files.remove\",\n message: \"Cannot remove the sandbox root\",\n });\n await currentVm().delete(path, { recursive: true });\n },\n exists: (path) => currentVm().exists(path),\n },\n run: (command, runOptions) =>\n runCommand(currentVm(), command, withEnv(createOptions, runOptions)),\n async start(command, runOptions) {\n return startProcess(currentVm(), command, withEnv(createOptions, runOptions));\n },\n async expose(port) {\n validatePort(port);\n const url = `http://agentos-${id}.internal:${port}`;\n return portResult(port, url, false, false, (path = \"/\", init) => {\n const request = new Request(new URL(path, url), init);\n return currentVm().fetch(port, request);\n });\n },\n snapshots: {\n async create(snapshotOptions) {\n const snapshot: SandboxSnapshot = {\n id: randomUUID(),\n name: snapshotOptions?.name,\n mode: \"filesystem\",\n createdAt: new Date(),\n };\n snapshots.set(snapshot.id, {\n metadata: snapshot,\n root: await currentVm().snapshotRootFilesystem(),\n });\n return snapshot;\n },\n async delete(snapshot) {\n const id = typeof snapshot === \"string\" ? snapshot : snapshot.id;\n if (!snapshots.delete(id)) throw snapshotNotFound(id, \"snapshot.delete\");\n },\n async restore(snapshot) {\n const id = typeof snapshot === \"string\" ? snapshot : snapshot.id;\n const stored = snapshots.get(id);\n if (!stored) throw snapshotNotFound(id, \"snapshot.restore\");\n const previous = currentVm();\n vm = null;\n await previous.dispose();\n try {\n vm = await createVm(stored.root);\n } catch (error) {\n stopped = true;\n throw error;\n }\n },\n },\n async stop() {\n if (stopped) return;\n stopped = true;\n suspendedRoot = undefined;\n snapshots.clear();\n const active = vm;\n vm = null;\n await active?.dispose();\n },\n };\n return runtime;\n },\n };\n\n return withManagedSessions(provider, [], {\n stop: (sandbox) => sandbox.raw.suspend(),\n resume: (sandbox) => sandbox.raw.resume(),\n });\n}\n\n/**\n * @deprecated AgentOS now powers `local()` under the hood. Import `local` from\n * `@opencoredev/sandbox-sdk/local` instead.\n */\nexport function agentos(options: AgentOsProviderOptions = {}): SandboxProvider<AgentOsSandbox> {\n return createAgentOsProvider(options);\n}\n\nfunction withEnv(\n createOptions: { env: Readonly<Record<string, string>> },\n runOptions: RunOptions,\n): RunOptions {\n return { ...runOptions, env: { ...createOptions.env, ...runOptions.env } };\n}\n\nfunction commandParts(command: CommandInput): [string, string[]] {\n return typeof command === \"string\"\n ? [\"sh\", [\"-lc\", command]]\n : [command.command, [...(command.args ?? [])]];\n}\n\nfunction startProcess(vm: AgentOsVm, command: CommandInput, options: RunOptions): SandboxProcess {\n if (options.signal?.aborted) throw interrupted(\"process.start\");\n const [executable, args] = commandParts(command);\n const history: ProcessOutputEvent[] = [];\n const waiting = new Set<() => void>();\n let state: ProcessStatus = \"running\";\n let exitCode: number | undefined;\n const push = (stream: \"stdout\" | \"stderr\", data: Uint8Array) => {\n const output = stream === \"stderr\" ? withoutInternalAgentOsWarnings(data) : data;\n if (output.byteLength === 0) return;\n history.push({ stream, data: new Uint8Array(output), timestamp: new Date() });\n for (const wake of waiting) wake();\n waiting.clear();\n };\n const process = vm.spawn(executable, args, {\n cwd: options.cwd,\n env: options.env ? { ...options.env } : undefined,\n streamStdin: true,\n onStdout: (data) => push(\"stdout\", data),\n onStderr: (data) => push(\"stderr\", data),\n });\n const completed = vm.waitProcess(process.pid).then((code) => {\n exitCode = code;\n state = code === 137 || code === 143 ? \"killed\" : \"exited\";\n for (const wake of waiting) wake();\n waiting.clear();\n return { exitCode: code };\n });\n const abort = () => vm.stopProcess(process.pid);\n options.signal?.addEventListener(\"abort\", abort, { once: true });\n void completed.finally(() => options.signal?.removeEventListener(\"abort\", abort));\n\n return {\n id: String(process.pid),\n async status() {\n return state;\n },\n async *output() {\n let index = 0;\n while (state === \"running\" || index < history.length) {\n while (index < history.length) yield history[index++]!;\n if (state !== \"running\") break;\n await new Promise<void>((resolve) => waiting.add(resolve));\n }\n },\n write: (value) => vm.writeProcessStdin(process.pid, value),\n wait: () => (exitCode === undefined ? completed : Promise.resolve({ exitCode })),\n async kill(signal = \"SIGTERM\") {\n if (state !== \"running\") return;\n if (signal === \"SIGKILL\" || signal === \"KILL\" || signal === \"9\") vm.killProcess(process.pid);\n else vm.stopProcess(process.pid);\n },\n };\n}\n\nfunction withoutInternalAgentOsWarnings(data: Uint8Array): Uint8Array {\n const value = new TextDecoder()\n .decode(data)\n .replaceAll(\"\\u001b[33m WARN\\u001b[0m could not retrieve pid for child process\\n\", \"\");\n return new TextEncoder().encode(value);\n}\n\nasync function runCommand(\n vm: AgentOsVm,\n command: CommandInput,\n options: RunOptions,\n): Promise<CommandResult> {\n const started = performance.now();\n const process = startProcess(vm, command, options);\n const stdout: Uint8Array[] = [];\n const stderr: Uint8Array[] = [];\n const collect = (async () => {\n for await (const event of process.output()) {\n const bytes =\n typeof event.data === \"string\" ? new TextEncoder().encode(event.data) : event.data;\n (event.stream === \"stdout\" ? stdout : stderr).push(bytes);\n }\n })();\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let removeAbort = () => {};\n const interruptions: Promise<never>[] = [];\n\n if (options.timeout && options.timeout > 0) {\n interruptions.push(\n new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n void process.kill(\"SIGKILL\");\n reject(\n new SandboxError({\n code: \"timeout\",\n provider: \"local\",\n operation: \"process.run\",\n message: `Command timed out after ${options.timeout}ms`,\n }),\n );\n }, options.timeout);\n }),\n );\n }\n if (options.signal) {\n interruptions.push(\n new Promise<never>((_, reject) => {\n const abort = () => {\n void process.kill(\"SIGKILL\");\n reject(interrupted(\"process.run\"));\n };\n options.signal!.addEventListener(\"abort\", abort, { once: true });\n removeAbort = () => options.signal!.removeEventListener(\"abort\", abort);\n }),\n );\n }\n\n try {\n const result = await Promise.race([process.wait(), ...interruptions]);\n await collect;\n return {\n stdout: decodeChunks(stdout),\n stderr: decodeChunks(stderr),\n exitCode: result.exitCode,\n success: result.exitCode === 0,\n durationMs: Math.round(performance.now() - started),\n };\n } catch (error) {\n await process.wait().catch(() => {});\n await collect.catch(() => {});\n throw error;\n } finally {\n if (timeout) clearTimeout(timeout);\n removeAbort();\n }\n}\n\nfunction decodeChunks(chunks: Uint8Array[]): string {\n const length = chunks.reduce((total, chunk) => total + chunk.byteLength, 0);\n const output = new Uint8Array(length);\n let offset = 0;\n for (const chunk of chunks) {\n output.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return new TextDecoder().decode(output);\n}\n\nfunction validatePort(port: number): void {\n if (!Number.isInteger(port) || port < 1 || port > 65_535)\n throw new SandboxError({\n code: \"invalid_input\",\n provider: \"local\",\n operation: \"ports.expose\",\n message: `Invalid port: ${port}`,\n });\n}\n\nfunction snapshotNotFound(id: string, operation: string): SandboxError {\n return new SandboxError({\n code: \"not_found\",\n provider: \"local\",\n operation,\n message: `Snapshot not found: ${id}`,\n });\n}\n\nfunction interrupted(operation: string): SandboxError {\n return new SandboxError({\n code: \"terminated\",\n provider: \"local\",\n operation,\n message: \"Operation was aborted\",\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import "../types-BTagTtsp.mjs";
2
+ import { o as SandboxProvider } from "../provider-_caCV8kk.mjs";
3
+ import { HarnessV1NetworkPolicy, HarnessV1NetworkSandboxSession, HarnessV1SandboxProvider, HarnessV1SandboxProvider as HarnessV1SandboxProvider$1 } from "@ai-sdk/harness";
4
+
5
+ //#region src/ai/harness.d.ts
6
+ interface CreateSandboxHarnessProviderOptions {
7
+ provider: SandboxProvider<unknown>;
8
+ ports?: ReadonlyArray<number>;
9
+ cwd?: string;
10
+ env?: Readonly<Record<string, string>>;
11
+ }
12
+ /** Create an AI SDK Harness sandbox provider backed by any managed sandbox-sdk provider. */
13
+ declare function createSandboxHarnessProvider(options: CreateSandboxHarnessProviderOptions): HarnessV1SandboxProvider$1;
14
+ //#endregion
15
+ export { CreateSandboxHarnessProviderOptions, type HarnessV1NetworkPolicy, type HarnessV1NetworkSandboxSession, type HarnessV1SandboxProvider, createSandboxHarnessProvider };
16
+ //# sourceMappingURL=harness.d.mts.map
@@ -0,0 +1,69 @@
1
+ import { t as SandboxError } from "../errors-Ch9PHKTd.mjs";
2
+ import { r as toAISandboxSession } from "../ai-DhfwIZdL.mjs";
3
+
4
+ //#region src/ai/harness.ts
5
+ /** Create an AI SDK Harness sandbox provider backed by any managed sandbox-sdk provider. */
6
+ function createSandboxHarnessProvider(options) {
7
+ const managed = requireManaged(options.provider);
8
+ return {
9
+ specificationVersion: "harness-sandbox-v1",
10
+ providerId: `sandbox-sdk:${options.provider.id}`,
11
+ async createSession(createOptions = {}) {
12
+ const sessionId = createOptions.sessionId ?? crypto.randomUUID();
13
+ return toHarnessSession(await managed.create({
14
+ sessionId,
15
+ identity: createOptions.identity,
16
+ cwd: options.cwd,
17
+ env: options.env,
18
+ ports: options.ports,
19
+ signal: createOptions.abortSignal,
20
+ onFirstCreate: createOptions.onFirstCreate ? (sandbox) => createOptions.onFirstCreate(toAISandboxSession(sandbox), { abortSignal: createOptions.abortSignal }) : void 0
21
+ }));
22
+ },
23
+ async resumeSession(resumeOptions) {
24
+ return toHarnessSession(await managed.resume({
25
+ sessionId: resumeOptions.sessionId,
26
+ signal: resumeOptions.abortSignal
27
+ }));
28
+ }
29
+ };
30
+ }
31
+ function toHarnessSession(session) {
32
+ const restricted = toAISandboxSession(session.sandbox);
33
+ return {
34
+ ...restricted,
35
+ id: session.id,
36
+ defaultWorkingDirectory: session.defaultWorkingDirectory,
37
+ get ports() {
38
+ return session.ports;
39
+ },
40
+ getPortUrl: (options) => session.getPortUrl(options),
41
+ stop: () => session.stop(),
42
+ destroy: () => session.destroy(),
43
+ ...session.setPorts ? { setPorts: (ports, options) => session.setPorts(ports, { signal: options?.abortSignal }) } : {},
44
+ ...session.setNetworkPolicy ? { setNetworkPolicy: (policy) => session.setNetworkPolicy(toCoreNetworkPolicy(policy)) } : {},
45
+ restricted: () => restricted
46
+ };
47
+ }
48
+ function toCoreNetworkPolicy(policy) {
49
+ if (policy.mode !== "custom") return policy;
50
+ return {
51
+ mode: "custom",
52
+ allowedHosts: policy.allowedHosts,
53
+ allowedCIDRs: policy.allowedCIDRs,
54
+ deniedCIDRs: policy.deniedCIDRs
55
+ };
56
+ }
57
+ function requireManaged(provider) {
58
+ if (!provider.managed) throw new SandboxError({
59
+ code: "unsupported",
60
+ provider: provider.id,
61
+ operation: "harness.createProvider",
62
+ message: `Provider ${provider.id} does not implement managed sandbox sessions`
63
+ });
64
+ return provider.managed;
65
+ }
66
+
67
+ //#endregion
68
+ export { createSandboxHarnessProvider };
69
+ //# sourceMappingURL=harness.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.mjs","names":[],"sources":["../../src/ai/harness.ts"],"sourcesContent":["import type {\n HarnessV1NetworkPolicy,\n HarnessV1NetworkSandboxSession,\n HarnessV1SandboxProvider,\n} from \"@ai-sdk/harness\";\nimport type { Experimental_SandboxSession } from \"ai\";\nimport { SandboxError } from \"../core/errors\";\nimport type {\n ManagedSandboxSession,\n SandboxNetworkPolicy,\n SandboxProvider,\n} from \"../core/provider\";\nimport { toAISandboxSession } from \"./index\";\n\nexport interface CreateSandboxHarnessProviderOptions {\n provider: SandboxProvider<unknown>;\n ports?: ReadonlyArray<number>;\n cwd?: string;\n env?: Readonly<Record<string, string>>;\n}\n\n/** Create an AI SDK Harness sandbox provider backed by any managed sandbox-sdk provider. */\nexport function createSandboxHarnessProvider(\n options: CreateSandboxHarnessProviderOptions,\n): HarnessV1SandboxProvider {\n const managed = requireManaged(options.provider);\n return {\n specificationVersion: \"harness-sandbox-v1\",\n providerId: `sandbox-sdk:${options.provider.id}`,\n async createSession(createOptions = {}) {\n const sessionId = createOptions.sessionId ?? crypto.randomUUID();\n const session = await managed.create({\n sessionId,\n identity: createOptions.identity,\n cwd: options.cwd,\n env: options.env,\n ports: options.ports,\n signal: createOptions.abortSignal,\n onFirstCreate: createOptions.onFirstCreate\n ? (sandbox) =>\n createOptions.onFirstCreate!(toAISandboxSession(sandbox), {\n abortSignal: createOptions.abortSignal,\n })\n : undefined,\n });\n return toHarnessSession(session);\n },\n async resumeSession(resumeOptions) {\n return toHarnessSession(\n await managed.resume({\n sessionId: resumeOptions.sessionId,\n signal: resumeOptions.abortSignal,\n }),\n );\n },\n };\n}\n\nfunction toHarnessSession(session: ManagedSandboxSession): HarnessV1NetworkSandboxSession {\n const restricted = toAISandboxSession(session.sandbox);\n return {\n ...restricted,\n id: session.id,\n defaultWorkingDirectory: session.defaultWorkingDirectory,\n get ports() {\n return session.ports;\n },\n getPortUrl: (options) => session.getPortUrl(options),\n stop: () => session.stop(),\n destroy: () => session.destroy(),\n ...(session.setPorts\n ? {\n setPorts: (ports: ReadonlyArray<number>, options?: { abortSignal?: AbortSignal }) =>\n session.setPorts!(ports, { signal: options?.abortSignal }),\n }\n : {}),\n ...(session.setNetworkPolicy\n ? {\n setNetworkPolicy: (policy: HarnessV1NetworkPolicy) =>\n session.setNetworkPolicy!(toCoreNetworkPolicy(policy)),\n }\n : {}),\n restricted: (): Experimental_SandboxSession => restricted,\n };\n}\n\nfunction toCoreNetworkPolicy(policy: HarnessV1NetworkPolicy): SandboxNetworkPolicy {\n if (policy.mode !== \"custom\") return policy;\n return {\n mode: \"custom\",\n allowedHosts: policy.allowedHosts,\n allowedCIDRs: policy.allowedCIDRs,\n deniedCIDRs: policy.deniedCIDRs,\n };\n}\n\nfunction requireManaged(provider: SandboxProvider<unknown>) {\n if (!provider.managed) {\n throw new SandboxError({\n code: \"unsupported\",\n provider: provider.id,\n operation: \"harness.createProvider\",\n message: `Provider ${provider.id} does not implement managed sandbox sessions`,\n });\n }\n return provider.managed;\n}\n\nexport type {\n HarnessV1NetworkPolicy,\n HarnessV1NetworkSandboxSession,\n HarnessV1SandboxProvider,\n} from \"@ai-sdk/harness\";\n"],"mappings":";;;;;AAsBA,SAAgB,6BACd,SAC0B;CAC1B,MAAM,UAAU,eAAe,QAAQ,SAAS;AAChD,QAAO;EACL,sBAAsB;EACtB,YAAY,eAAe,QAAQ,SAAS;EAC5C,MAAM,cAAc,gBAAgB,EAAE,EAAE;GACtC,MAAM,YAAY,cAAc,aAAa,OAAO,YAAY;AAehE,UAAO,iBAdS,MAAM,QAAQ,OAAO;IACnC;IACA,UAAU,cAAc;IACxB,KAAK,QAAQ;IACb,KAAK,QAAQ;IACb,OAAO,QAAQ;IACf,QAAQ,cAAc;IACtB,eAAe,cAAc,iBACxB,YACC,cAAc,cAAe,mBAAmB,QAAQ,EAAE,EACxD,aAAa,cAAc,aAC5B,CAAC,GACJ;IACL,CAAC,CAC8B;;EAElC,MAAM,cAAc,eAAe;AACjC,UAAO,iBACL,MAAM,QAAQ,OAAO;IACnB,WAAW,cAAc;IACzB,QAAQ,cAAc;IACvB,CAAC,CACH;;EAEJ;;AAGH,SAAS,iBAAiB,SAAgE;CACxF,MAAM,aAAa,mBAAmB,QAAQ,QAAQ;AACtD,QAAO;EACL,GAAG;EACH,IAAI,QAAQ;EACZ,yBAAyB,QAAQ;EACjC,IAAI,QAAQ;AACV,UAAO,QAAQ;;EAEjB,aAAa,YAAY,QAAQ,WAAW,QAAQ;EACpD,YAAY,QAAQ,MAAM;EAC1B,eAAe,QAAQ,SAAS;EAChC,GAAI,QAAQ,WACR,EACE,WAAW,OAA8B,YACvC,QAAQ,SAAU,OAAO,EAAE,QAAQ,SAAS,aAAa,CAAC,EAC7D,GACD,EAAE;EACN,GAAI,QAAQ,mBACR,EACE,mBAAmB,WACjB,QAAQ,iBAAkB,oBAAoB,OAAO,CAAC,EACzD,GACD,EAAE;EACN,kBAA+C;EAChD;;AAGH,SAAS,oBAAoB,QAAsD;AACjF,KAAI,OAAO,SAAS,SAAU,QAAO;AACrC,QAAO;EACL,MAAM;EACN,cAAc,OAAO;EACrB,cAAc,OAAO;EACrB,aAAa,OAAO;EACrB;;AAGH,SAAS,eAAe,UAAoC;AAC1D,KAAI,CAAC,SAAS,QACZ,OAAM,IAAI,aAAa;EACrB,MAAM;EACN,UAAU,SAAS;EACnB,WAAW;EACX,SAAS,YAAY,SAAS,GAAG;EAClC,CAAC;AAEJ,QAAO,SAAS"}
@@ -0,0 +1,54 @@
1
+ import { f as Sandbox } from "../types-BTagTtsp.mjs";
2
+ import { Experimental_SandboxSession, Tool, ToolSet } from "ai";
3
+
4
+ //#region src/ai/index.d.ts
5
+ interface AISandboxSessionOptions {
6
+ description?: string;
7
+ }
8
+ type SandboxToolApproval = "mutations" | "always" | "never";
9
+ type SandboxToolApprovalConfiguration = Readonly<{
10
+ bash: "user-approval" | "not-applicable";
11
+ read_file: "user-approval" | "not-applicable";
12
+ write_file: "user-approval" | "not-applicable";
13
+ }>;
14
+ /**
15
+ * Adapt a sandbox-sdk sandbox to AI SDK 7's experimental sandbox contract.
16
+ * The caller continues to own the original sandbox and must stop it.
17
+ */
18
+ declare function toAISandboxSession(sandbox: Sandbox, options?: AISandboxSessionOptions): Experimental_SandboxSession;
19
+ type BashInput = {
20
+ command: string;
21
+ workingDirectory?: string;
22
+ env?: Record<string, string>;
23
+ };
24
+ type ReadFileInput = {
25
+ path: string;
26
+ encoding?: string;
27
+ startLine?: number;
28
+ endLine?: number;
29
+ };
30
+ type WriteFileInput = {
31
+ path: string;
32
+ content: string;
33
+ encoding?: string;
34
+ };
35
+ type SandboxTools = ToolSet & {
36
+ bash: Tool<BashInput, {
37
+ exitCode: number;
38
+ stdout: string;
39
+ stderr: string;
40
+ }>;
41
+ read_file: Tool<ReadFileInput, {
42
+ content: string | null;
43
+ }>;
44
+ write_file: Tool<WriteFileInput, {
45
+ written: true;
46
+ }>;
47
+ };
48
+ /** Ready-made AI SDK tools that execute only through `experimental_sandbox`. */
49
+ declare function createSandboxTools(): SandboxTools;
50
+ /** Create the AI SDK 7 `toolApproval` policy for the ready-made sandbox tools. */
51
+ declare function createSandboxToolApproval(approval?: SandboxToolApproval): SandboxToolApprovalConfiguration;
52
+ //#endregion
53
+ export { AISandboxSessionOptions, SandboxToolApproval, SandboxToolApprovalConfiguration, SandboxTools, createSandboxToolApproval, createSandboxTools, toAISandboxSession };
54
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1,4 @@
1
+ import "../errors-Ch9PHKTd.mjs";
2
+ import { n as createSandboxTools, r as toAISandboxSession, t as createSandboxToolApproval } from "../ai-DhfwIZdL.mjs";
3
+
4
+ export { createSandboxToolApproval, createSandboxTools, toAISandboxSession };