sbox-sdk 0.0.2
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/LICENSE +21 -0
- package/README.md +137 -0
- package/dist/adapter/index.d.ts +22 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/index.js +16 -0
- package/dist/agent-tools/index.d.ts +13 -0
- package/dist/agent-tools/index.d.ts.map +1 -0
- package/dist/agent-tools/index.js +9 -0
- package/dist/agent-tools/policy.d.ts +48 -0
- package/dist/agent-tools/policy.d.ts.map +1 -0
- package/dist/agent-tools/policy.js +51 -0
- package/dist/agent-tools/registry.d.ts +9 -0
- package/dist/agent-tools/registry.d.ts.map +1 -0
- package/dist/agent-tools/registry.js +412 -0
- package/dist/agent-tools/result.d.ts +32 -0
- package/dist/agent-tools/result.d.ts.map +1 -0
- package/dist/agent-tools/result.js +14 -0
- package/dist/agent-tools/types.d.ts +76 -0
- package/dist/agent-tools/types.d.ts.map +1 -0
- package/dist/agent-tools/types.js +1 -0
- package/dist/ai/index.d.ts +36 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +40 -0
- package/dist/ai-sdk/index.d.ts +31 -0
- package/dist/ai-sdk/index.d.ts.map +1 -0
- package/dist/ai-sdk/index.js +80 -0
- package/dist/anthropic/index.d.ts +42 -0
- package/dist/anthropic/index.d.ts.map +1 -0
- package/dist/anthropic/index.js +64 -0
- package/dist/aws-lambda/index.d.ts +87 -0
- package/dist/aws-lambda/index.d.ts.map +1 -0
- package/dist/aws-lambda/index.js +290 -0
- package/dist/beam/index.d.ts +92 -0
- package/dist/beam/index.d.ts.map +1 -0
- package/dist/beam/index.js +222 -0
- package/dist/blaxel/index.d.ts +125 -0
- package/dist/blaxel/index.d.ts.map +1 -0
- package/dist/blaxel/index.js +220 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +249 -0
- package/dist/cloudflare/index.d.ts +64 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +259 -0
- package/dist/codesandbox/index.d.ts +100 -0
- package/dist/codesandbox/index.d.ts.map +1 -0
- package/dist/codesandbox/index.js +227 -0
- package/dist/conformance/index.d.ts +20 -0
- package/dist/conformance/index.d.ts.map +1 -0
- package/dist/conformance/index.js +189 -0
- package/dist/daytona/index.d.ts +64 -0
- package/dist/daytona/index.d.ts.map +1 -0
- package/dist/daytona/index.js +258 -0
- package/dist/e2b/index.d.ts +63 -0
- package/dist/e2b/index.d.ts.map +1 -0
- package/dist/e2b/index.js +411 -0
- package/dist/fly/index.d.ts +75 -0
- package/dist/fly/index.d.ts.map +1 -0
- package/dist/fly/index.js +222 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/internal/capabilities.d.ts +57 -0
- package/dist/internal/capabilities.d.ts.map +1 -0
- package/dist/internal/capabilities.js +68 -0
- package/dist/internal/client.d.ts +9 -0
- package/dist/internal/client.d.ts.map +1 -0
- package/dist/internal/client.js +126 -0
- package/dist/internal/encoding.d.ts +8 -0
- package/dist/internal/encoding.d.ts.map +1 -0
- package/dist/internal/encoding.js +20 -0
- package/dist/internal/errors.d.ts +45 -0
- package/dist/internal/errors.d.ts.map +1 -0
- package/dist/internal/errors.js +79 -0
- package/dist/internal/exec.d.ts +19 -0
- package/dist/internal/exec.d.ts.map +1 -0
- package/dist/internal/exec.js +208 -0
- package/dist/internal/plugin.d.ts +38 -0
- package/dist/internal/plugin.d.ts.map +1 -0
- package/dist/internal/plugin.js +1 -0
- package/dist/internal/runtime.d.ts +8 -0
- package/dist/internal/runtime.d.ts.map +1 -0
- package/dist/internal/runtime.js +21 -0
- package/dist/internal/sandbox.d.ts +12 -0
- package/dist/internal/sandbox.d.ts.map +1 -0
- package/dist/internal/sandbox.js +438 -0
- package/dist/internal/shell.d.ts +36 -0
- package/dist/internal/shell.d.ts.map +1 -0
- package/dist/internal/shell.js +88 -0
- package/dist/internal/stream.d.ts +15 -0
- package/dist/internal/stream.d.ts.map +1 -0
- package/dist/internal/stream.js +58 -0
- package/dist/internal/types.d.ts +381 -0
- package/dist/internal/types.d.ts.map +1 -0
- package/dist/internal/types.js +1 -0
- package/dist/langchain/index.d.ts +25 -0
- package/dist/langchain/index.d.ts.map +1 -0
- package/dist/langchain/index.js +61 -0
- package/dist/mastra/index.d.ts +43 -0
- package/dist/mastra/index.d.ts.map +1 -0
- package/dist/mastra/index.js +69 -0
- package/dist/memory/index.d.ts +57 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +573 -0
- package/dist/modal/index.d.ts +67 -0
- package/dist/modal/index.d.ts.map +1 -0
- package/dist/modal/index.js +223 -0
- package/dist/morph/index.d.ts +91 -0
- package/dist/morph/index.d.ts.map +1 -0
- package/dist/morph/index.js +221 -0
- package/dist/northflank/index.d.ts +74 -0
- package/dist/northflank/index.d.ts.map +1 -0
- package/dist/northflank/index.js +265 -0
- package/dist/openai/index.d.ts +25 -0
- package/dist/openai/index.d.ts.map +1 -0
- package/dist/openai/index.js +71 -0
- package/dist/railway/index.d.ts +109 -0
- package/dist/railway/index.d.ts.map +1 -0
- package/dist/railway/index.js +219 -0
- package/dist/runloop/index.d.ts +69 -0
- package/dist/runloop/index.d.ts.map +1 -0
- package/dist/runloop/index.js +226 -0
- package/dist/testing/index.d.ts +44 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +61 -0
- package/dist/vercel/index.d.ts +63 -0
- package/dist/vercel/index.d.ts.map +1 -0
- package/dist/vercel/index.js +241 -0
- package/package.json +252 -0
- package/src/aws-lambda/runner/Dockerfile +15 -0
- package/src/aws-lambda/runner/README.md +59 -0
- package/src/aws-lambda/runner/server.mjs +91 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 10 canonical sandbox tools, each mapped to the real core `Sandbox` API,
|
|
3
|
+
* plus `createSandboxTools` — the resolver that gates them by the sandbox's
|
|
4
|
+
* capabilities and applies `only` / `forbid`. This is the single source of
|
|
5
|
+
* truth every framework adapter projects from.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { err, ok } from "./result.js";
|
|
9
|
+
// --------------------------------------------------------------------------
|
|
10
|
+
// annotation presets (MCP-aligned)
|
|
11
|
+
// --------------------------------------------------------------------------
|
|
12
|
+
const READ_ONLY = {
|
|
13
|
+
destructiveHint: false,
|
|
14
|
+
idempotentHint: true,
|
|
15
|
+
openWorldHint: false,
|
|
16
|
+
readOnlyHint: true,
|
|
17
|
+
};
|
|
18
|
+
const MUTATING = {
|
|
19
|
+
destructiveHint: false,
|
|
20
|
+
idempotentHint: false,
|
|
21
|
+
openWorldHint: false,
|
|
22
|
+
readOnlyHint: false,
|
|
23
|
+
};
|
|
24
|
+
const DESTRUCTIVE = {
|
|
25
|
+
destructiveHint: true,
|
|
26
|
+
idempotentHint: false,
|
|
27
|
+
openWorldHint: false,
|
|
28
|
+
readOnlyHint: false,
|
|
29
|
+
};
|
|
30
|
+
const EXEC = {
|
|
31
|
+
destructiveHint: false,
|
|
32
|
+
idempotentHint: false,
|
|
33
|
+
openWorldHint: true,
|
|
34
|
+
readOnlyHint: false,
|
|
35
|
+
};
|
|
36
|
+
// --------------------------------------------------------------------------
|
|
37
|
+
// authoring helper — gives type-safe execute, returns a homogeneous ToolSpec
|
|
38
|
+
// --------------------------------------------------------------------------
|
|
39
|
+
function errMsg(e) {
|
|
40
|
+
return e instanceof Error ? e.message : String(e);
|
|
41
|
+
}
|
|
42
|
+
function defineTool(def) {
|
|
43
|
+
const parse = (raw) => def.inputSchema.parse(raw);
|
|
44
|
+
const { riskFor } = def;
|
|
45
|
+
return {
|
|
46
|
+
annotations: def.annotations,
|
|
47
|
+
description: def.description,
|
|
48
|
+
async execute(raw, ctx) {
|
|
49
|
+
let input;
|
|
50
|
+
try {
|
|
51
|
+
input = parse(raw);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
return err(`invalid input for ${def.name}: ${errMsg(error)}`);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
return await def.run(input, ctx);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
return err(`${def.name} failed: ${errMsg(error)}`);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
inputSchema: def.inputSchema,
|
|
64
|
+
name: def.name,
|
|
65
|
+
outputSchema: def.outputSchema,
|
|
66
|
+
risk: def.risk,
|
|
67
|
+
riskFor: riskFor ? (raw) => riskFor(parse(raw)) : undefined,
|
|
68
|
+
title: def.title,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// --------------------------------------------------------------------------
|
|
72
|
+
// the 10 tools — each builder closes over the live sandbox
|
|
73
|
+
// --------------------------------------------------------------------------
|
|
74
|
+
const buildExec = (sandbox) => defineTool({
|
|
75
|
+
annotations: EXEC,
|
|
76
|
+
description: "Run a shell command in the sandbox and return its stdout, stderr, and exit code. Use for installing packages, running scripts, inspecting files, and general shell work.",
|
|
77
|
+
inputSchema: z.object({
|
|
78
|
+
command: z
|
|
79
|
+
.string()
|
|
80
|
+
.describe("The shell command to run, e.g. 'ls -la /app'"),
|
|
81
|
+
cwd: z.string().optional().describe("Working directory for the command"),
|
|
82
|
+
timeoutMs: z
|
|
83
|
+
.number()
|
|
84
|
+
.int()
|
|
85
|
+
.positive()
|
|
86
|
+
.optional()
|
|
87
|
+
.describe("Abort the command after this many milliseconds"),
|
|
88
|
+
}),
|
|
89
|
+
name: "sbox_exec",
|
|
90
|
+
risk: "mutating",
|
|
91
|
+
run: async ({ command, cwd, timeoutMs }, ctx) => {
|
|
92
|
+
const res = await sandbox.commands.run(command, {
|
|
93
|
+
cwd,
|
|
94
|
+
signal: ctx.signal,
|
|
95
|
+
timeoutMs,
|
|
96
|
+
});
|
|
97
|
+
const parts = [];
|
|
98
|
+
if (res.stdout) {
|
|
99
|
+
parts.push(res.stdout.replace(/\s+$/, ""));
|
|
100
|
+
}
|
|
101
|
+
if (res.stderr) {
|
|
102
|
+
parts.push(`[stderr]\n${res.stderr.replace(/\s+$/, "")}`);
|
|
103
|
+
}
|
|
104
|
+
parts.push(`[exit ${res.exitCode}]`);
|
|
105
|
+
return ok(parts.join("\n"), {
|
|
106
|
+
exitCode: res.exitCode,
|
|
107
|
+
stderr: res.stderr,
|
|
108
|
+
stdout: res.stdout,
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
title: "Run shell command",
|
|
112
|
+
});
|
|
113
|
+
const buildRunCode = (sandbox) => defineTool({
|
|
114
|
+
annotations: MUTATING,
|
|
115
|
+
description: "Execute a snippet of code in the sandbox's stateful interpreter (e.g. Python/Node) and return its output, rich results, and any error/traceback.",
|
|
116
|
+
inputSchema: z.object({
|
|
117
|
+
code: z.string().describe("The source code to execute"),
|
|
118
|
+
language: z
|
|
119
|
+
.string()
|
|
120
|
+
.optional()
|
|
121
|
+
.describe("Language id, e.g. 'python' or 'javascript'"),
|
|
122
|
+
}),
|
|
123
|
+
name: "sbox_run_code",
|
|
124
|
+
risk: "mutating",
|
|
125
|
+
run: async ({ code, language }) => {
|
|
126
|
+
if (!sandbox.code) {
|
|
127
|
+
return err("code interpreter is not available");
|
|
128
|
+
}
|
|
129
|
+
const ex = await sandbox.code.runCode(code, { language });
|
|
130
|
+
if (ex.error) {
|
|
131
|
+
return err(`${ex.error.name}: ${ex.error.value}${ex.error.traceback ? `\n${ex.error.traceback}` : ""}`);
|
|
132
|
+
}
|
|
133
|
+
const stdout = ex.logs.stdout.join("").replace(/\s+$/, "");
|
|
134
|
+
const stderr = ex.logs.stderr.join("").replace(/\s+$/, "");
|
|
135
|
+
const rich = ex.results
|
|
136
|
+
.map((r) => r.text ?? "")
|
|
137
|
+
.filter(Boolean)
|
|
138
|
+
.join("\n");
|
|
139
|
+
const text = [stdout, stderr, rich].filter(Boolean).join("\n") || "(no output)";
|
|
140
|
+
return ok(text, ex);
|
|
141
|
+
},
|
|
142
|
+
title: "Run code in interpreter",
|
|
143
|
+
});
|
|
144
|
+
const buildFsRead = (sandbox) => defineTool({
|
|
145
|
+
annotations: READ_ONLY,
|
|
146
|
+
description: "Read and return the UTF-8 text contents of a file in the sandbox.",
|
|
147
|
+
inputSchema: z.object({
|
|
148
|
+
path: z
|
|
149
|
+
.string()
|
|
150
|
+
.describe("Absolute or relative path of the file to read"),
|
|
151
|
+
}),
|
|
152
|
+
name: "sbox_fs_read",
|
|
153
|
+
risk: "safe",
|
|
154
|
+
run: async ({ path }) => {
|
|
155
|
+
const file = await sandbox.files.read(path);
|
|
156
|
+
const content = await file.text();
|
|
157
|
+
return ok(content, { content, path });
|
|
158
|
+
},
|
|
159
|
+
title: "Read file",
|
|
160
|
+
});
|
|
161
|
+
const buildFsWrite = (sandbox) => defineTool({
|
|
162
|
+
annotations: MUTATING,
|
|
163
|
+
description: "Create or overwrite a file in the sandbox with the given UTF-8 text content.",
|
|
164
|
+
inputSchema: z.object({
|
|
165
|
+
content: z.string().describe("The full text content to write"),
|
|
166
|
+
path: z.string().describe("Path of the file to write"),
|
|
167
|
+
}),
|
|
168
|
+
name: "sbox_fs_write",
|
|
169
|
+
risk: "mutating",
|
|
170
|
+
run: async ({ path, content }) => {
|
|
171
|
+
await sandbox.files.write(path, content);
|
|
172
|
+
return ok(`Wrote ${content.length} bytes to ${path}`, {
|
|
173
|
+
bytes: content.length,
|
|
174
|
+
path,
|
|
175
|
+
});
|
|
176
|
+
},
|
|
177
|
+
title: "Write file",
|
|
178
|
+
});
|
|
179
|
+
const buildFsList = (sandbox) => defineTool({
|
|
180
|
+
annotations: READ_ONLY,
|
|
181
|
+
description: "List the entries (files and directories) of a directory in the sandbox.",
|
|
182
|
+
inputSchema: z.object({
|
|
183
|
+
path: z.string().describe("Path of the directory to list"),
|
|
184
|
+
}),
|
|
185
|
+
name: "sbox_fs_list",
|
|
186
|
+
risk: "safe",
|
|
187
|
+
run: async ({ path }) => {
|
|
188
|
+
const entries = await sandbox.files.list(path);
|
|
189
|
+
const text = entries
|
|
190
|
+
.map((e) => `${e.type === "dir" ? "d" : e.type === "symlink" ? "l" : "-"} ${e.name}`)
|
|
191
|
+
.join("\n") || "(empty)";
|
|
192
|
+
return ok(text, { entries });
|
|
193
|
+
},
|
|
194
|
+
title: "List directory",
|
|
195
|
+
});
|
|
196
|
+
const buildFsRemove = (sandbox) => defineTool({
|
|
197
|
+
annotations: DESTRUCTIVE,
|
|
198
|
+
description: "Delete a file or directory in the sandbox. Set recursive=true to remove a non-empty directory. This is destructive.",
|
|
199
|
+
inputSchema: z.object({
|
|
200
|
+
path: z.string().describe("Path to delete"),
|
|
201
|
+
recursive: z
|
|
202
|
+
.boolean()
|
|
203
|
+
.optional()
|
|
204
|
+
.describe("Remove directories and their contents recursively"),
|
|
205
|
+
}),
|
|
206
|
+
name: "sbox_fs_remove",
|
|
207
|
+
risk: "destructive",
|
|
208
|
+
run: async ({ path, recursive }) => {
|
|
209
|
+
await sandbox.files.remove(path, { recursive });
|
|
210
|
+
return ok(`Removed ${path}`, { path });
|
|
211
|
+
},
|
|
212
|
+
title: "Remove file or directory",
|
|
213
|
+
});
|
|
214
|
+
const buildExposePort = (sandbox) => defineTool({
|
|
215
|
+
annotations: EXEC,
|
|
216
|
+
description: "Expose a port running inside the sandbox and return a public preview URL the model (or user) can open.",
|
|
217
|
+
inputSchema: z.object({
|
|
218
|
+
port: z.number().int().positive().describe("The port number to expose"),
|
|
219
|
+
private: z
|
|
220
|
+
.boolean()
|
|
221
|
+
.optional()
|
|
222
|
+
.describe("If true, require an access token instead of being public"),
|
|
223
|
+
}),
|
|
224
|
+
name: "sbox_expose_port",
|
|
225
|
+
risk: "mutating",
|
|
226
|
+
run: async ({ port, private: isPrivate }) => {
|
|
227
|
+
if (!sandbox.ports) {
|
|
228
|
+
return err("port exposure is not available");
|
|
229
|
+
}
|
|
230
|
+
const preview = await sandbox.ports.expose(port, { private: isPrivate });
|
|
231
|
+
return ok(`Exposed port ${port} at ${preview.url}`, preview);
|
|
232
|
+
},
|
|
233
|
+
title: "Expose port",
|
|
234
|
+
});
|
|
235
|
+
const buildSnapshot = (sandbox) => defineTool({
|
|
236
|
+
annotations: MUTATING,
|
|
237
|
+
description: "Create, restore, list, or delete sandbox snapshots. 'restore' overwrites the sandbox's current state; 'delete' removes a snapshot — both are destructive.",
|
|
238
|
+
inputSchema: z.object({
|
|
239
|
+
action: z.enum(["create", "restore", "list", "delete"]),
|
|
240
|
+
name: z
|
|
241
|
+
.string()
|
|
242
|
+
.optional()
|
|
243
|
+
.describe("Optional name when creating a snapshot"),
|
|
244
|
+
ref: z
|
|
245
|
+
.string()
|
|
246
|
+
.optional()
|
|
247
|
+
.describe("Snapshot id — required for 'restore' and 'delete'"),
|
|
248
|
+
}),
|
|
249
|
+
name: "sbox_snapshot",
|
|
250
|
+
risk: "mutating",
|
|
251
|
+
riskFor: ({ action }) => action === "restore" || action === "delete"
|
|
252
|
+
? "destructive"
|
|
253
|
+
: action === "create"
|
|
254
|
+
? "mutating"
|
|
255
|
+
: "safe",
|
|
256
|
+
run: async ({ action, ref, name }) => {
|
|
257
|
+
const snaps = sandbox.snapshots;
|
|
258
|
+
if (!snaps) {
|
|
259
|
+
return err("snapshots are not supported");
|
|
260
|
+
}
|
|
261
|
+
switch (action) {
|
|
262
|
+
case "create": {
|
|
263
|
+
const created = await snaps.create({ name });
|
|
264
|
+
return ok(`Created snapshot ${created.id}`, created);
|
|
265
|
+
}
|
|
266
|
+
case "restore": {
|
|
267
|
+
if (!ref) {
|
|
268
|
+
return err("'ref' is required to restore a snapshot");
|
|
269
|
+
}
|
|
270
|
+
await snaps.restore(ref);
|
|
271
|
+
return ok(`Restored snapshot ${ref}`);
|
|
272
|
+
}
|
|
273
|
+
case "list": {
|
|
274
|
+
const list = await snaps.list();
|
|
275
|
+
return ok(list.map((s) => s.id).join("\n") || "(no snapshots)", list);
|
|
276
|
+
}
|
|
277
|
+
case "delete": {
|
|
278
|
+
if (!ref) {
|
|
279
|
+
return err("'ref' is required to delete a snapshot");
|
|
280
|
+
}
|
|
281
|
+
await snaps.delete(ref);
|
|
282
|
+
return ok(`Deleted snapshot ${ref}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
title: "Manage snapshots",
|
|
287
|
+
});
|
|
288
|
+
const buildLifecycle = (sandbox) => defineTool({
|
|
289
|
+
annotations: MUTATING,
|
|
290
|
+
description: "Inspect or change the sandbox lifecycle: getInfo, setTimeout, stop, pause, resume, or destroy. 'stop' and 'destroy' tear the sandbox down and are destructive.",
|
|
291
|
+
inputSchema: z.object({
|
|
292
|
+
action: z.enum([
|
|
293
|
+
"getInfo",
|
|
294
|
+
"setTimeout",
|
|
295
|
+
"stop",
|
|
296
|
+
"pause",
|
|
297
|
+
"resume",
|
|
298
|
+
"destroy",
|
|
299
|
+
]),
|
|
300
|
+
ttlMs: z
|
|
301
|
+
.number()
|
|
302
|
+
.int()
|
|
303
|
+
.positive()
|
|
304
|
+
.optional()
|
|
305
|
+
.describe("New time-to-live in ms — required for 'setTimeout'"),
|
|
306
|
+
}),
|
|
307
|
+
name: "sbox_lifecycle",
|
|
308
|
+
risk: "mutating",
|
|
309
|
+
riskFor: ({ action }) => action === "stop" || action === "destroy"
|
|
310
|
+
? "destructive"
|
|
311
|
+
: action === "getInfo"
|
|
312
|
+
? "safe"
|
|
313
|
+
: "mutating",
|
|
314
|
+
run: async ({ action, ttlMs }) => {
|
|
315
|
+
switch (action) {
|
|
316
|
+
case "getInfo": {
|
|
317
|
+
const info = await sandbox.getInfo();
|
|
318
|
+
return ok(`state=${info.state} id=${info.id} provider=${info.provider}`, info);
|
|
319
|
+
}
|
|
320
|
+
case "setTimeout": {
|
|
321
|
+
if (ttlMs === undefined || ttlMs === null) {
|
|
322
|
+
return err("'ttlMs' is required for setTimeout");
|
|
323
|
+
}
|
|
324
|
+
await sandbox.setTimeout(ttlMs);
|
|
325
|
+
return ok(`Timeout set to ${ttlMs}ms`);
|
|
326
|
+
}
|
|
327
|
+
case "stop": {
|
|
328
|
+
await sandbox.stop();
|
|
329
|
+
return ok("Sandbox stopped");
|
|
330
|
+
}
|
|
331
|
+
case "pause": {
|
|
332
|
+
await sandbox.pause();
|
|
333
|
+
return ok("Sandbox paused");
|
|
334
|
+
}
|
|
335
|
+
case "resume": {
|
|
336
|
+
await sandbox.resume();
|
|
337
|
+
return ok("Sandbox resumed");
|
|
338
|
+
}
|
|
339
|
+
case "destroy": {
|
|
340
|
+
await sandbox.destroy();
|
|
341
|
+
return ok("Sandbox destroyed");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
title: "Sandbox lifecycle",
|
|
346
|
+
});
|
|
347
|
+
const buildSetEgress = (sandbox) => defineTool({
|
|
348
|
+
annotations: MUTATING,
|
|
349
|
+
description: "Set the sandbox's outbound network policy: allow all, block all, or allow only specific domains/CIDRs.",
|
|
350
|
+
inputSchema: z.object({
|
|
351
|
+
cidrs: z
|
|
352
|
+
.array(z.string())
|
|
353
|
+
.optional()
|
|
354
|
+
.describe("Allowed CIDR ranges when mode is 'allow-list'"),
|
|
355
|
+
domains: z
|
|
356
|
+
.array(z.string())
|
|
357
|
+
.optional()
|
|
358
|
+
.describe("Allowed domains when mode is 'allow-list'"),
|
|
359
|
+
mode: z.enum(["allow-all", "block-all", "allow-list"]),
|
|
360
|
+
}),
|
|
361
|
+
name: "sbox_set_egress",
|
|
362
|
+
risk: "mutating",
|
|
363
|
+
run: async ({ mode, domains, cidrs }) => {
|
|
364
|
+
if (!sandbox.network) {
|
|
365
|
+
return err("egress control is not supported");
|
|
366
|
+
}
|
|
367
|
+
await sandbox.network.setEgressPolicy({ cidrs, domains, mode });
|
|
368
|
+
return ok(`Egress policy set to ${mode}`);
|
|
369
|
+
},
|
|
370
|
+
title: "Set egress policy",
|
|
371
|
+
});
|
|
372
|
+
const ENTRIES = [
|
|
373
|
+
{ build: buildExec, gate: () => true, name: "sbox_exec" },
|
|
374
|
+
{
|
|
375
|
+
build: buildRunCode,
|
|
376
|
+
gate: (s) => s.can("codeInterpreter"),
|
|
377
|
+
name: "sbox_run_code",
|
|
378
|
+
},
|
|
379
|
+
{ build: buildFsRead, gate: () => true, name: "sbox_fs_read" },
|
|
380
|
+
{ build: buildFsWrite, gate: () => true, name: "sbox_fs_write" },
|
|
381
|
+
{ build: buildFsList, gate: () => true, name: "sbox_fs_list" },
|
|
382
|
+
{ build: buildFsRemove, gate: () => true, name: "sbox_fs_remove" },
|
|
383
|
+
{
|
|
384
|
+
build: buildExposePort,
|
|
385
|
+
gate: (s) => s.can("exposePort"),
|
|
386
|
+
name: "sbox_expose_port",
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
build: buildSnapshot,
|
|
390
|
+
gate: (s) => s.can("snapshot"),
|
|
391
|
+
name: "sbox_snapshot",
|
|
392
|
+
},
|
|
393
|
+
{ build: buildLifecycle, gate: () => true, name: "sbox_lifecycle" },
|
|
394
|
+
{
|
|
395
|
+
build: buildSetEgress,
|
|
396
|
+
gate: (s) => s.can("egressControl"),
|
|
397
|
+
name: "sbox_set_egress",
|
|
398
|
+
},
|
|
399
|
+
];
|
|
400
|
+
/**
|
|
401
|
+
* Build the provider-neutral tool set for a sandbox: only the tools whose
|
|
402
|
+
* capabilities the provider supports, minus `forbid`, intersected with `only`.
|
|
403
|
+
* This `ToolSpec[]` is the input to every `toXTools` adapter.
|
|
404
|
+
*/
|
|
405
|
+
export function createSandboxTools(sandbox, opts = {}) {
|
|
406
|
+
const only = opts.only ? new Set(opts.only) : undefined;
|
|
407
|
+
const forbid = new Set([
|
|
408
|
+
...(opts.policy?.forbid ?? []),
|
|
409
|
+
...(opts.forbid ?? []),
|
|
410
|
+
]);
|
|
411
|
+
return ENTRIES.filter((e) => e.gate(sandbox) && (!only || only.has(e.name)) && !forbid.has(e.name)).map((e) => e.build(sandbox));
|
|
412
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The normalized result every tool returns. `text` is always the model-facing
|
|
3
|
+
* rendering; `output` is the optional structured value. Each framework adapter
|
|
4
|
+
* serializes ONE of these into its own tool-result shape (AI SDK value,
|
|
5
|
+
* Anthropic `tool_result` block, OpenAI string, Mastra output object).
|
|
6
|
+
*/
|
|
7
|
+
export interface ToolResultContent {
|
|
8
|
+
type: "text" | "image";
|
|
9
|
+
/** present when type === "text" */
|
|
10
|
+
text?: string;
|
|
11
|
+
/** base64-encoded payload, present when type === "image" */
|
|
12
|
+
data?: string;
|
|
13
|
+
/** e.g. "image/png", present when type === "image" */
|
|
14
|
+
mediaType?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ToolResult<O = unknown> {
|
|
17
|
+
/** false signals a tool-level failure (non-zero exit, denied, provider error). */
|
|
18
|
+
ok: boolean;
|
|
19
|
+
/** Always present — what the model reads. */
|
|
20
|
+
text: string;
|
|
21
|
+
/** Structured, machine-readable result (when the tool produces one). */
|
|
22
|
+
output?: O;
|
|
23
|
+
/** Mirrors `ok === false`; surfaced as `is_error` by adapters that support it. */
|
|
24
|
+
isError?: boolean;
|
|
25
|
+
/** Optional rich blocks for adapters that accept them (e.g. Anthropic images). */
|
|
26
|
+
content?: ToolResultContent[];
|
|
27
|
+
}
|
|
28
|
+
/** A successful result. */
|
|
29
|
+
export declare function ok<O>(text: string, output?: O): ToolResult<O>;
|
|
30
|
+
/** A tool-level failure — never thrown, always returned so the agent can react. */
|
|
31
|
+
export declare function err(text: string): ToolResult<never>;
|
|
32
|
+
//# sourceMappingURL=result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../src/agent-tools/result.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,OAAO;IACrC,kFAAkF;IAClF,EAAE,EAAE,OAAO,CAAC;IACZ,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kFAAkF;IAClF,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,2BAA2B;AAC3B,wBAAgB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAE7D;AAED,mFAAmF;AACnF,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAEnD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The normalized result every tool returns. `text` is always the model-facing
|
|
3
|
+
* rendering; `output` is the optional structured value. Each framework adapter
|
|
4
|
+
* serializes ONE of these into its own tool-result shape (AI SDK value,
|
|
5
|
+
* Anthropic `tool_result` block, OpenAI string, Mastra output object).
|
|
6
|
+
*/
|
|
7
|
+
/** A successful result. */
|
|
8
|
+
export function ok(text, output) {
|
|
9
|
+
return { ok: true, output, text };
|
|
10
|
+
}
|
|
11
|
+
/** A tool-level failure — never thrown, always returned so the agent can react. */
|
|
12
|
+
export function err(text) {
|
|
13
|
+
return { isError: true, ok: false, text };
|
|
14
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The provider- AND framework-agnostic tool model. A `ToolSpec` is the single
|
|
3
|
+
* source of truth for one sandbox tool; every framework adapter is a pure
|
|
4
|
+
* projection `ToolSpec -> that framework's tool object`, and the (future) MCP
|
|
5
|
+
* server + Agent Skills read from the very same specs.
|
|
6
|
+
*/
|
|
7
|
+
import type { z } from "zod";
|
|
8
|
+
import type { Sandbox } from "../internal/types.js";
|
|
9
|
+
import type { ToolResult } from "./result.js";
|
|
10
|
+
/** The fixed set of canonical sandbox tools. */
|
|
11
|
+
export type ToolName = "sbox_exec" | "sbox_run_code" | "sbox_fs_read" | "sbox_fs_write" | "sbox_fs_list" | "sbox_fs_remove" | "sbox_expose_port" | "sbox_snapshot" | "sbox_lifecycle" | "sbox_set_egress";
|
|
12
|
+
/** Drives the default approval posture (see SandboxPolicy). */
|
|
13
|
+
export type Risk = "safe" | "mutating" | "destructive";
|
|
14
|
+
/** MCP-aligned behavioral hints, reused verbatim by the future MCP server. */
|
|
15
|
+
export interface ToolAnnotations {
|
|
16
|
+
readOnlyHint: boolean;
|
|
17
|
+
destructiveHint: boolean;
|
|
18
|
+
idempotentHint: boolean;
|
|
19
|
+
openWorldHint: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** Threaded into every tool execution and policy rule. `sandbox` is optional:
|
|
22
|
+
* a spec's `execute` closes over its own sandbox, so it is only needed by
|
|
23
|
+
* policy rules that introspect the sandbox (absent when adapters are handed a
|
|
24
|
+
* pre-built `ToolSpec[]` rather than a live sandbox). */
|
|
25
|
+
export interface ToolRunContext {
|
|
26
|
+
readonly sandbox?: Sandbox;
|
|
27
|
+
readonly signal?: AbortSignal;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* One canonical tool. Homogeneous (input typed `unknown`) so the registry can
|
|
31
|
+
* hold `ToolSpec[]`; `execute` validates its input against `inputSchema` before
|
|
32
|
+
* running, so adapters may forward framework-parsed args as-is.
|
|
33
|
+
*/
|
|
34
|
+
export interface ToolSpec {
|
|
35
|
+
readonly name: ToolName;
|
|
36
|
+
/** Short human label (not shown to the model). */
|
|
37
|
+
readonly title: string;
|
|
38
|
+
/** Model-facing description — written for an agent, not a human reader. */
|
|
39
|
+
readonly description: string;
|
|
40
|
+
/** Zod is the lingua franca: AI SDK / Mastra / OpenAI / LangChain take it
|
|
41
|
+
* directly; the Anthropic adapter converts it to JSON Schema. */
|
|
42
|
+
readonly inputSchema: z.ZodType;
|
|
43
|
+
/** Optional structured-output schema (consumed by e.g. Mastra). */
|
|
44
|
+
readonly outputSchema?: z.ZodType;
|
|
45
|
+
/** Declared (base) risk; refine per-input via `riskFor`. */
|
|
46
|
+
readonly risk: Risk;
|
|
47
|
+
readonly annotations: ToolAnnotations;
|
|
48
|
+
/** Per-input risk refinement for multi-verb tools (lifecycle, snapshot). */
|
|
49
|
+
riskFor?(input: unknown): Risk;
|
|
50
|
+
/** Runs the operation. MUST resolve a ToolResult — never throw for tool-level
|
|
51
|
+
* failure (return `err(...)`); may throw only on truly unexpected errors. */
|
|
52
|
+
execute(input: unknown, ctx: ToolRunContext): Promise<ToolResult>;
|
|
53
|
+
}
|
|
54
|
+
/** Options accepted by `createSandboxTools` and every `toXTools` adapter. */
|
|
55
|
+
export interface ToolSetOptions {
|
|
56
|
+
/** Approval policy (also carries `forbid`). */
|
|
57
|
+
policy?: import("./policy.js").SandboxPolicy;
|
|
58
|
+
/** Allow-list: when set, only these tools are produced. */
|
|
59
|
+
only?: ToolName[];
|
|
60
|
+
/** Removed entirely from the produced set (merged with `policy.forbid`). */
|
|
61
|
+
forbid?: ToolName[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A framework "provider" for the `ai()` plugin: knows how to turn a sandbox into
|
|
65
|
+
* one agent framework's tool objects. Returned by the framework subpaths
|
|
66
|
+
* (`aiSdk()`, `mastra()`, `openaiAgents()`, `anthropic()`, `langchain()`) and
|
|
67
|
+
* passed to `ai({ framework })`. `TTools` is the framework's tool shape, so
|
|
68
|
+
* `sandbox.tools` stays correctly typed.
|
|
69
|
+
*/
|
|
70
|
+
export interface FrameworkAdapter<TTools = unknown> {
|
|
71
|
+
/** Stable id, e.g. "ai-sdk" or "openai". */
|
|
72
|
+
readonly name: string;
|
|
73
|
+
/** Project the sandbox's (capability-gated, policy-aware) tools. */
|
|
74
|
+
build(sandbox: Sandbox, opts: ToolSetOptions): TTools;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agent-tools/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,gDAAgD;AAChD,MAAM,MAAM,QAAQ,GAChB,WAAW,GACX,eAAe,GACf,cAAc,GACd,eAAe,GACf,cAAc,GACd,gBAAgB,GAChB,kBAAkB,GAClB,eAAe,GACf,gBAAgB,GAChB,iBAAiB,CAAC;AAEtB,+DAA+D;AAC/D,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,UAAU,GAAG,aAAa,CAAC;AAEvD,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;0DAG0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;sEACkE;IAClE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;IAClC,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC;IACtC,4EAA4E;IAC5E,OAAO,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B;kFAC8E;IAC9E,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACnE;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,MAAM,CAAC,EAAE,OAAO,aAAa,EAAE,aAAa,CAAC;IAC7C,2DAA2D;IAC3D,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC;IAClB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;CACrB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB,CAAC,MAAM,GAAG,OAAO;IAChD,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM,CAAC;CACvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sbox-sdk/ai` — the umbrella AI-provider plugin. Pick a framework adapter from
|
|
3
|
+
* its subpath (`aiSdk()`, `mastra()`, `openaiAgents()`, `anthropic()`,
|
|
4
|
+
* `langchain()`) and pass it in; `ai()` grafts the framework-shaped tools onto
|
|
5
|
+
* `sandbox.tools`. Core-only — no framework SDK is imported here, so this stays
|
|
6
|
+
* dependency-free; the framework you import decides what gets bundled.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { createSandboxClient } from "sbox-sdk";
|
|
10
|
+
* import { e2b } from "sbox-sdk/e2b";
|
|
11
|
+
* import { ai } from "sbox-sdk/ai";
|
|
12
|
+
* import { aiSdk } from "sbox-sdk/ai-sdk";
|
|
13
|
+
*
|
|
14
|
+
* const client = createSandboxClient({
|
|
15
|
+
* provider: e2b(),
|
|
16
|
+
* plugins: [ai({ framework: aiSdk(), policy })],
|
|
17
|
+
* });
|
|
18
|
+
* const sandbox = await client.create();
|
|
19
|
+
* await generateText({ model, prompt, tools: sandbox.tools });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
import type { FrameworkAdapter, ToolSetOptions } from "../agent-tools/index.js";
|
|
23
|
+
import type { SandboxPlugin } from "../internal/plugin.js";
|
|
24
|
+
export interface AIOptions<TTools> extends ToolSetOptions {
|
|
25
|
+
/** The agent framework to target — `aiSdk()`, `openaiAgents()`, … */
|
|
26
|
+
framework: FrameworkAdapter<TTools>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The single AI-provider plugin. Shapes `sandbox.tools` for the given framework,
|
|
30
|
+
* capability-gated to the provider and gated by the optional `policy`. Per-sandbox
|
|
31
|
+
* overrides passed to `client.create(spec, options)` are merged over the defaults.
|
|
32
|
+
*/
|
|
33
|
+
export declare function ai<TTools>(opts: AIOptions<TTools>): SandboxPlugin<{
|
|
34
|
+
tools: TTools;
|
|
35
|
+
}>;
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAsB,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE/E,MAAM,WAAW,SAAS,CAAC,MAAM,CAAE,SAAQ,cAAc;IACvD,qEAAqE;IACrE,SAAS,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;CACrC;AA+BD;;;;GAIG;AACH,wBAAgB,EAAE,CAAC,MAAM,EACvB,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,GACtB,aAAa,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAYlC"}
|
package/dist/ai/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merge per-sandbox overrides from `client.create(spec, options)` over the
|
|
3
|
+
* plugin's client-wide defaults. Only `policy`, `only`, and `forbid` are honored
|
|
4
|
+
* — never the framework. `policy` is shallow-merged so a single sandbox can
|
|
5
|
+
* tighten its trust posture; `only`/`forbid` are replaced when provided. This is
|
|
6
|
+
* what makes an untrusted sandbox's policy actually take effect rather than
|
|
7
|
+
* silently inheriting the laxer client default.
|
|
8
|
+
*/
|
|
9
|
+
function resolveToolOptions(base, createOptions) {
|
|
10
|
+
if (!createOptions) {
|
|
11
|
+
return base;
|
|
12
|
+
}
|
|
13
|
+
const override = createOptions;
|
|
14
|
+
const merged = { ...base };
|
|
15
|
+
if (override.policy) {
|
|
16
|
+
merged.policy = { ...base.policy, ...override.policy };
|
|
17
|
+
}
|
|
18
|
+
if (override.only) {
|
|
19
|
+
merged.only = override.only;
|
|
20
|
+
}
|
|
21
|
+
if (override.forbid) {
|
|
22
|
+
merged.forbid = override.forbid;
|
|
23
|
+
}
|
|
24
|
+
return merged;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The single AI-provider plugin. Shapes `sandbox.tools` for the given framework,
|
|
28
|
+
* capability-gated to the provider and gated by the optional `policy`. Per-sandbox
|
|
29
|
+
* overrides passed to `client.create(spec, options)` are merged over the defaults.
|
|
30
|
+
*/
|
|
31
|
+
export function ai(opts) {
|
|
32
|
+
const { framework, ...toolOptions } = opts;
|
|
33
|
+
return {
|
|
34
|
+
extend: (sandbox, ctx) => ({
|
|
35
|
+
tools: framework.build(sandbox, resolveToolOptions(toolOptions, ctx.createOptions)),
|
|
36
|
+
}),
|
|
37
|
+
kind: "ai-provider",
|
|
38
|
+
name: `ai:${framework.name}`,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Tool } from "ai";
|
|
2
|
+
import type { FrameworkAdapter, ToolSetOptions, ToolSpec } from "../agent-tools/types.js";
|
|
3
|
+
import type { Sandbox } from "../internal/types.js";
|
|
4
|
+
export type AISDKToolOptions = ToolSetOptions;
|
|
5
|
+
/** The AI SDK tool map: `{ [toolName]: Tool }`. */
|
|
6
|
+
export type AISDKToolSet = Record<string, Tool>;
|
|
7
|
+
/**
|
|
8
|
+
* Build AI SDK tools from a live sandbox (capability-gated) or a pre-built
|
|
9
|
+
* `ToolSpec[]`. Hand the result to `generateText({ tools })`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function toAISDKTools(source: Sandbox | ToolSpec[], opts?: AISDKToolOptions): AISDKToolSet;
|
|
12
|
+
/**
|
|
13
|
+
* The Vercel AI SDK framework adapter for the `ai()` plugin:
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { ai } from "sbox-sdk/ai";
|
|
17
|
+
* import { aiSdk } from "sbox-sdk/ai-sdk";
|
|
18
|
+
*
|
|
19
|
+
* const client = createSandboxClient({ provider: e2b(), plugins: [ai({ framework: aiSdk() })] });
|
|
20
|
+
* const sandbox = await client.create();
|
|
21
|
+
* await generateText({ model, prompt, tools: sandbox.tools });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function aiSdk(): FrameworkAdapter<AISDKToolSet>;
|
|
25
|
+
/**
|
|
26
|
+
* AI SDK v7 forward-compat: build the call-site `toolApproval` map
|
|
27
|
+
* (`generateText({ tools, toolApproval })`) from the same policy. Each entry
|
|
28
|
+
* returns `"user-approval"` when the policy says "ask", else `undefined`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function toolApproval(source: Sandbox | ToolSpec[], opts?: AISDKToolOptions): Record<string, (input: unknown) => Promise<"user-approval" | undefined>>;
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ai-sdk/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAI/B,OAAO,KAAK,EACV,gBAAgB,EAEhB,cAAc,EACd,QAAQ,EACT,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAE9C,mDAAmD;AACnD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAahD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,OAAO,GAAG,QAAQ,EAAE,EAC5B,IAAI,GAAE,gBAAqB,GAC1B,YAAY,CAoBd;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,IAAI,gBAAgB,CAAC,YAAY,CAAC,CAKtD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,OAAO,GAAG,QAAQ,EAAE,EAC5B,IAAI,GAAE,gBAAqB,GAC1B,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC,CAc1E"}
|