Skip to content

Commit 58a6427

Browse files
committed
adding sandbox example
1 parent 04d9ec7 commit 58a6427

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* @title Spin up a sandbox to run untrusted code
3+
* @difficulty beginner
4+
* @tags sandbox
5+
* @run -A --env-file <url>
6+
* @resource {https://docs.deno.com/sandbox/} Deno Deploy Sandbox
7+
* @group Deno Deploy
8+
*
9+
* Deno Deploy's Sandbox API lets you create secure microVMs to run untrusted code safely.
10+
* In this example, we ask Claude to generate a Deno script that fetches the current Bitcoin price,
11+
* then run that script inside a sandbox with strict resource limits and no access to the host environment.
12+
*/
13+
14+
// Import the Anthropic SDK and the Deno Sandbox SDK.
15+
import Anthropic from "npm:@anthropic-ai/sdk";
16+
import { Sandbox } from "jsr:@deno/sandbox";
17+
18+
// Create an Anthropic client.
19+
// It automatically picks up ANTHROPIC_API_KEY from your environment.
20+
const client = new Anthropic();
21+
22+
// Ask Claude to write some code for us wrapped in a markdown code block.
23+
const response = await client.messages.create({
24+
model: "claude-opus-4-6",
25+
max_tokens: 1024,
26+
messages: [{
27+
role: "user",
28+
content:
29+
"Write a Deno script that fetches the current Bitcoin price from the CoinGecko API and prints it.",
30+
}],
31+
});
32+
33+
// Take the generated code out of Claude's response.
34+
// Check it's a text block, then strip the markdown
35+
// fences to get the raw source.
36+
const firstBlock = response.content[0];
37+
if (firstBlock.type !== "text") {
38+
throw new Error(`Unexpected content type: ${firstBlock.type}`);
39+
}
40+
const generatedCode = extractCode(firstBlock.text);
41+
42+
// Create a sandbox .
43+
await using sandbox = await Sandbox.create();
44+
45+
// Write the AI-generated code into the sandbox filesystem.
46+
await sandbox.fs.writeTextFile("/tmp/generated.ts", generatedCode);
47+
48+
// Run the code inside the sandbox with Deno.
49+
// stdout and stderr are piped so we can capture and display them.
50+
const child = await sandbox.spawn("deno", {
51+
args: [
52+
"run",
53+
"--allow-net=api.coingecko.com", // Only the specific host we expect
54+
"/tmp/generated.ts",
55+
],
56+
stdout: "piped",
57+
stderr: "piped",
58+
});
59+
60+
// AI-generated code could accidentally (or maliciously) loop forever —
61+
// this ensures we kill the process after 10 seconds no matter what.
62+
const timeout = setTimeout(() => child.kill(), 10_000);
63+
64+
// Wait for the process to finish and print the results.
65+
// output.stdoutText / stderrText are pre-decoded UTF-8 strings.
66+
// output.status.success is true only if the exit code was 0.
67+
try {
68+
const output = await child.output();
69+
console.log("Output:\n", output.stdoutText ?? "No output");
70+
if (!output.status.success) {
71+
console.error("Error:\n", output.stderrText ?? "No error output");
72+
}
73+
} finally {
74+
clearTimeout(timeout);
75+
}
76+
77+
// Helper: extract the first code block from a markdown string.
78+
// Falls back to returning the raw text if no fences are found.
79+
function extractCode(text: string): string {
80+
const match = text.match(
81+
/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)```/,
82+
);
83+
return match ? match[1] : text;
84+
}

0 commit comments

Comments
 (0)