diff --git a/docs.json b/docs.json index f1410c9..ef883d6 100644 --- a/docs.json +++ b/docs.json @@ -37,157 +37,60 @@ ] }, "docs/api-key", - "docs/cookbook", - "docs/support" + "docs/sdks-explained" ] }, { - "group": "Code Interpreting", + "group": "Use Case Examples", "pages": [ - { - "group": "Analyze data with AI", - "pages": [ - "docs/code-interpreting/analyze-data-with-ai", - "docs/code-interpreting/analyze-data-with-ai/pre-installed-libraries" - ] - }, - { - "group": "Charts & visualizations", - "pages": [ - "docs/code-interpreting/create-charts-visualizations", - "docs/code-interpreting/create-charts-visualizations/static-charts", - "docs/code-interpreting/create-charts-visualizations/interactive-charts" - ] - }, - "docs/code-interpreting/streaming", - { - "group": "Supported languages", - "pages": [ - "docs/code-interpreting/supported-languages", - "docs/code-interpreting/supported-languages/python", - "docs/code-interpreting/supported-languages/javascript", - "docs/code-interpreting/supported-languages/r", - "docs/code-interpreting/supported-languages/java", - "docs/code-interpreting/supported-languages/bash" - ] - } + "docs/use-cases/linux-desktop", + "docs/use-cases/deep-research-agents", + "docs/use-cases/ai-data-analysis-visualization", + "docs/use-cases/reinforcement-learning", + "docs/use-cases/vibe-coding" ] }, { - "group": "Sandbox", + "group": "Dashboard", "pages": [ - "docs/sandbox", - "docs/sandbox/lifecycle-events-api", - "docs/sandbox/lifecycle-events-webhooks", - "docs/sandbox/persistence", - "docs/sandbox/metrics", - "docs/sandbox/metadata", - "docs/sandbox/environment-variables", - "docs/sandbox/list", - "docs/sandbox/connect", - "docs/sandbox/internet-access", - "docs/sandbox/connect-bucket", - "docs/sandbox/rate-limits", - "docs/sandbox/secured-access" + "docs/dashboard/billing", + "docs/dashboard/usage", + "docs/dashboard/webhooks", + "docs/dashboard/templates" ] }, { - "group": "Templates", - "pages": [ - "docs/template/quickstart", - "docs/template/how-it-works", - "docs/template/user-and-workdir", - "docs/template/caching", - "docs/template/base-image", - "docs/template/private-registries", - "docs/template/defining-template", - "docs/template/start-ready-command", - "docs/template/build", - "docs/template/logging", - "docs/template/error-handling", - { - "group": "Examples", - "pages": [ - "docs/template/examples/nextjs", - "docs/template/examples/nextjs-bun", - "docs/template/examples/expo", - "docs/template/examples/desktop", - "docs/template/examples/claude-code" - ] - }, - "docs/template/migration-v2", - { - "group": "Legacy Docs", - "pages": [ - "docs/sandbox-template", - "docs/sandbox-template/start-cmd", - "docs/sandbox-template/ready-cmd", - "docs/sandbox-template/customize-cpu-ram" - ] - } - ] - }, - { - "group": "Filesystem", + "group": "Sandbox", "pages": [ - "docs/filesystem", - "docs/filesystem/read-write", - "docs/filesystem/info", - "docs/filesystem/watch", - "docs/filesystem/upload", - "docs/filesystem/download" + "docs/sandbox/intro", + "docs/sandbox/executing-code", + "docs/sandbox/reading-output", + "docs/sandbox/persistence", + "docs/sandbox/security" ] }, { - "group": "Commands", + "group": "Templates", "pages": [ - "docs/commands", - "docs/commands/streaming", - "docs/commands/background" + "docs/templates/intro" ] }, { - "group": "MCP Gateway", + "group": "Code Interpreter", "pages": [ - "docs/mcp", - "docs/mcp/quickstart", - "docs/mcp/available-servers", - "docs/mcp/custom-templates", - "docs/mcp/custom-servers", - "docs/mcp/examples" + "docs/code-interpreter" ] }, { - "group": "CLI", + "group": "Desktop", "pages": [ - "docs/cli", - "docs/cli/auth", - "docs/cli/list-sandboxes", - "docs/cli/shutdown-sandboxes" + "docs/desktop/intro" ] }, { - "group": "Deployment", - "pages": ["docs/byoc"] - }, - { - "group": "Migration", - "pages": ["docs/migration/v2"] - }, - { - "group": "Troubleshooting", + "group": "FAQ", "pages": [ - { - "group": "SDKs", - "pages": ["docs/troubleshooting/sdks/workers-edge-runtime"] - }, - { - "group": "Templates", - "pages": [ - "docs/troubleshooting/templates/build-authentication-error", - "docs/troubleshooting/templates/49999-port-not-open" - ] - } + "docs/faq" ] } ] diff --git a/docs.mdx b/docs.mdx index a330775..ec04f59 100644 --- a/docs.mdx +++ b/docs.mdx @@ -4,37 +4,41 @@ sidebarTitle: Home icon: house --- -import { Concepts } from '/snippets/Concepts.jsx'; -import { CodeInterpreting } from '/snippets/CodeInterpreting.jsx'; import { Quickstart } from '/snippets/Quickstart.jsx'; +import { CodeInterpreting } from '/snippets/CodeInterpreting.jsx'; -Here you'll find all the guides, concepts, and SDK references for developing with E2B. +## What is E2B? - -```bash JavaScript & TypeScript -npm i @e2b/code-interpreter -``` -```bash Python -pip install e2b-code-interpreter -``` - +E2B provides isolated sandboxes that let agents safely execute code, process data, and run tools. Our [SDKs](/docs/sdks-explained) make it easy to start and manage these environments. -## What is E2B? -E2B is an [open-source](https://github.com/e2b-dev) infrastructure that allows you to run AI-generated code in secure isolated sandboxes in the cloud. -To start and control sandboxes, use our [Python SDK](https://pypi.org/project/e2b/) or [JavaScript SDK](https://www.npmjs.com/package/e2b). +## E2B Building Blocks + +A quick overview of the core building blocks you'll interact with when using E2B. + +- [**Sandbox**]() — A fast, secure Linux VM created on demand for your agent + +- [**Template**]() — Defines what environment a sandbox starts with + +## How to use the docs + +The documentation is split into three main sections: + +- [**Quickstart**](#quickstart) — Step-by-step tutorials that walk you through spinning up your first E2B sandboxes. -Some of the typical use cases for E2B are AI data analysis or visualization, running AI-generated code of various languages, playground for coding agents, environment for codegen evals, or running full AI-generated apps like in [Fragments](https://github.com/e2b-dev/fragments). +- [**Examples**](#examples) — In-depth tutorials focused on specific use cases. Pick the topics that match what you're building. -### Under the hood -The E2B Sandbox is a small isolated VM the can be started very quickly (~150ms). You can think of it as a small computer for the AI model. You can run many sandboxes at once. Typically, you run separate sandbox for each LLM, user, or AI agent session in your app. -For example, if you were building an AI data analysis chatbot, you would start the sandbox for every user session. +- [**API/SDK Reference**](https://e2b.dev/docs/sdk-reference) — A complete technical reference for every feature, component, and configuration option. -## Quickstart - +## 🚀 Quickstart. -## Code interpreting with AI - + -## Learn the core concepts - +## 🧠 Examples + + + + + + + diff --git a/docs/code-interpreter.mdx b/docs/code-interpreter.mdx new file mode 100644 index 0000000..db68a6c --- /dev/null +++ b/docs/code-interpreter.mdx @@ -0,0 +1,213 @@ +--- +title: "Code Interpreter" +description: "Multi-language code execution with pre-installed data science libraries, visualization support, and built on top of the core E2B SDK." +icon: "code" +--- + +# Code Interpreter + +Built on top of `e2b` with added support for multi-language code execution (Python, JavaScript, R, Java, Bash), pre-installed data science libraries, and visualization capabilities. + + +Includes **all features from `e2b`** plus specialized code execution methods and pre-configured environment. + + +## Installation + + +```bash Python +pip install e2b-code-interpreter +``` + +```bash JavaScript +npm install @e2b/code-interpreter +``` + + +## Quick Start + + +```python Python +from e2b_code_interpreter import Sandbox + +# Create code interpreter +sbx = Sandbox() + +# Execute Python with visualization +execution = sbx.run_code(""" +import matplotlib.pyplot as plt +plt.plot([1, 2, 3, 4]) +plt.ylabel('some numbers') +plt.savefig('chart.png') +""") + +# Access results +for result in execution.results: + print(result) + +sbx.close() +``` + +```typescript JavaScript +import { Sandbox } from '@e2b/code-interpreter' + +// Create code interpreter +const sbx = await Sandbox.create() + +// Execute Python with visualization +const execution = await sbx.runCode(` +import matplotlib.pyplot as plt +plt.plot([1, 2, 3, 4]) +plt.ylabel('some numbers') +plt.savefig('chart.png') +`) + +// Access results +execution.results.forEach(result => console.log(result)) + +await sbx.close() +``` + + +## Supported Languages + + + + Full Python support with data science libraries + + + Node.js runtime for JavaScript execution + + + Statistical computing with R + + + Java code execution + + + Shell scripts and commands + + + +## Pre-installed Libraries + +The code interpreter comes with popular data science and visualization libraries: + + + + - **Data Analysis:** pandas, numpy, scipy + - **Visualization:** matplotlib, seaborn, plotly + - **Machine Learning:** scikit-learn + - **And many more...** + + [View full list →](/docs/code-interpreting/analyze-data-with-ai/pre-installed-libraries) + + + + - **Node.js built-in modules** + - **Popular npm packages** (install as needed) + + + +## Features + +### Code Execution Results + +Access execution results including stdout, stderr, charts, and data: + + +```python Python +execution = sbx.run_code("print('Hello'); 2 + 2") + +for result in execution.results: + if result.type == "stdout": + print(result.text) + elif result.type == "result": + print(result.data) +``` + +```typescript JavaScript +const execution = await sbx.runCode("console.log('Hello'); 2 + 2") + +execution.results.forEach(result => { + if (result.type === 'stdout') { + console.log(result.text) + } else if (result.type === 'result') { + console.log(result.data) + } +}) +``` + + +### Chart Generation + +Create and retrieve visualizations: + + +```python Python +execution = sbx.run_code(""" +import matplotlib.pyplot as plt +import numpy as np + +x = np.linspace(0, 10, 100) +plt.plot(x, np.sin(x)) +plt.title('Sine Wave') +plt.savefig('plot.png') +""") + +# Charts are available in results +for result in execution.results: + if result.type == "image": + print(f"Chart saved: {result.url}") +``` + +```typescript JavaScript +const execution = await sbx.runCode(` +import matplotlib.pyplot as plt +import numpy as np + +x = np.linspace(0, 10, 100) +plt.plot(x, np.sin(x)) +plt.title('Sine Wave') +plt.savefig('plot.png') +`) + +// Charts are available in results +execution.results.forEach(result => { + if (result.type === 'image') { + console.log(`Chart saved: ${result.url}`) + } +}) +``` + + +## Use Cases + + + + Build AI agents that analyze datasets and create visualizations + + + Create Jupyter-like environments for interactive coding + + + Generate reports with code, analysis, and charts + + + Run student code safely in sandboxed environments + + + +## Related Resources + + + + Full list of available libraries + + + Chart generation guide + + + Complete API documentation + + diff --git a/docs/dashboard/billing.mdx b/docs/dashboard/billing.mdx new file mode 100644 index 0000000..f317ad1 --- /dev/null +++ b/docs/dashboard/billing.mdx @@ -0,0 +1,9 @@ +--- +title: "Billing" +description: "Manage your E2B subscription, view pricing plans, and understand billing for sandbox usage, compute time, and storage." +icon: "credit-card" +--- + +# Billing + +Content coming soon. diff --git a/docs/dashboard/templates.mdx b/docs/dashboard/templates.mdx new file mode 100644 index 0000000..00a55e0 --- /dev/null +++ b/docs/dashboard/templates.mdx @@ -0,0 +1,9 @@ +--- +title: "Templates" +description: "Manage your custom sandbox templates in the E2B dashboard, including creating, editing, and deploying templates for your team." +icon: "layer-group" +--- + +# Templates + +Content coming soon. diff --git a/docs/dashboard/usage.mdx b/docs/dashboard/usage.mdx new file mode 100644 index 0000000..dcdd291 --- /dev/null +++ b/docs/dashboard/usage.mdx @@ -0,0 +1,9 @@ +--- +title: "Usage" +description: "Monitor your E2B usage metrics including active sandboxes, compute hours, API calls, and resource consumption across your projects." +icon: "chart-simple" +--- + +# Usage + +Content coming soon. diff --git a/docs/dashboard/webhooks.mdx b/docs/dashboard/webhooks.mdx new file mode 100644 index 0000000..1c0b72f --- /dev/null +++ b/docs/dashboard/webhooks.mdx @@ -0,0 +1,9 @@ +--- +title: "Webhooks" +description: "Configure webhooks to receive real-time notifications about sandbox events, lifecycle changes, and system updates from E2B." +icon: "webhook" +--- + +# Webhooks + +Content coming soon. diff --git a/docs/desktop/intro.mdx b/docs/desktop/intro.mdx new file mode 100644 index 0000000..33afe6f --- /dev/null +++ b/docs/desktop/intro.mdx @@ -0,0 +1,118 @@ +--- +title: "Desktop Intro" +description: "Full Linux desktop environment with GUI, browser automation, and window management built on top of the E2B SDK." +icon: "desktop" +--- + +# Desktop + +Built on top of `e2b` with a full Linux desktop environment including GUI, browser, and window management capabilities. + + +Includes **all features from `e2b`** plus desktop-specific methods like `getDesktopUrl()` and pre-configured GUI environment. + + +## Installation + + +```bash Python +pip install e2b-desktop +``` + +```bash JavaScript +npm install @e2b/desktop +``` + + +## Quick Start + + +```python Python +from e2b_desktop import Sandbox + +# Create desktop sandbox +sbx = Sandbox.create() + +# Get desktop URL +desktop_url = sbx.get_desktop_url() +print(f"Access desktop at: {desktop_url}") + +# Run GUI application +sbx.commands.run("firefox https://example.com") +``` + +```typescript JavaScript +import { Sandbox } from '@e2b/desktop' + +// Create desktop sandbox +const sbx = await Sandbox.create() + +// Get desktop URL +const desktopUrl = await sbx.getDesktopUrl() +console.log(`Access desktop at: ${desktopUrl}`) + +// Run GUI application +await sbx.commands.run('firefox https://example.com') +``` + + +## Features + +### Remote Desktop Access + +Access a full Linux desktop environment in your browser: + +- **Window Management:** Run multiple applications with full window controls +- **Browser Access:** Remote desktop URL for web-based access +- **Screen Resolution:** Configurable display settings +- **Clipboard Support:** Copy/paste between local and remote environments + +### Pre-installed Applications + +The desktop comes with common applications: + + + + Firefox, Chromium for browser automation + + + Text editors, terminals, and dev utilities + + + Image viewers and basic media players + + + File managers and system monitors + + + +## Use Cases + + + + Automate web interactions with visual feedback + + + Test applications requiring GUI in isolated environments + + + Record application behavior and workflows + + + Cloud-based development with full desktop access + + + +## Related Resources + + + + Complete walkthrough and examples + + + Complete API documentation + + + Customize your desktop environment + + diff --git a/docs/faq.mdx b/docs/faq.mdx new file mode 100644 index 0000000..15c02a2 --- /dev/null +++ b/docs/faq.mdx @@ -0,0 +1,9 @@ +--- +title: "FAQ" +description: "Frequently asked questions about E2B sandboxes, templates, pricing, security, performance, and common troubleshooting scenarios." +icon: "circle-question" +--- + +# FAQ + +Content coming soon. diff --git a/docs/sandbox/executing-code.mdx b/docs/sandbox/executing-code.mdx new file mode 100644 index 0000000..9af3719 --- /dev/null +++ b/docs/sandbox/executing-code.mdx @@ -0,0 +1,9 @@ +--- +title: "Executing Code" +description: "Run code and shell commands in E2B sandboxes with support for multiple languages, streaming output, background processes, and real-time execution control." +icon: "terminal" +--- + +# Executing Code + +Content coming soon. diff --git a/docs/sandbox/intro.mdx b/docs/sandbox/intro.mdx new file mode 100644 index 0000000..c543838 --- /dev/null +++ b/docs/sandbox/intro.mdx @@ -0,0 +1,9 @@ +--- +title: "Sandbox Intro" +description: "E2B sandboxes provide secure, isolated cloud environments for running untrusted code with full control over execution, filesystem, and networking." +icon: "cube" +--- + +# Sandbox Intro + +Content coming soon. diff --git a/docs/sandbox/persistence.mdx b/docs/sandbox/persistence.mdx index 29f3939..0f4bc88 100644 --- a/docs/sandbox/persistence.mdx +++ b/docs/sandbox/persistence.mdx @@ -1,295 +1,9 @@ --- -title: "Sandbox persistence" -sidebarTitle: Persistence +title: "Persistence" +description: "Manage persistent storage in E2B sandboxes with volumes that survive across sandbox sessions, enabling stateful workflows and long-term data retention." +icon: "database" --- - -Sandbox persistence is currently in public beta: -1. Consider [some limitations](#limitations-while-in-beta). -2. The persistence is free for all users during the beta. - +# Persistence -The sandbox persistence allows you to pause your sandbox and resume it later from the same state it was in when you paused it. - -This includes not only state of the sandbox's filesystem but also the sandbox's memory. This means all running processes, loaded variables, data, etc. - -## Sandbox State Transitions - -Understanding how sandboxes transition between different states is crucial for managing their lifecycle effectively. Here's a diagram showing the possible state transitions: - - - - - -### State descriptions - -- **Running**: The sandbox is actively running and can execute code. This is the initial state after creation. -- **Paused**: The sandbox execution is suspended but its state is preserved. -- **Killed**: The sandbox is terminated and all resources are released. This is a terminal state. - -### Changing sandbox's state - - -```js JavaScript & TypeScript -import { Sandbox } from '@e2b/code-interpreter' - -const sandbox = await Sandbox.create() // Starts in Running state - -// Pause the sandbox -await sandbox.betaPause() // Running → Paused - -// Resume the sandbox -await sandbox.connect() // Running/Paused → Running - -// Kill the sandbox (from any state) -await sandbox.kill() // Running/Paused → Killed -``` - -```python Python -from e2b_code_interpreter import Sandbox - -sandbox = Sandbox.create() # Starts in Running state - -# Pause the sandbox -sandbox.betaPause() # Running → Paused - -# Resume the sandbox -sandbox.connect() # Running/Paused → Running - -# Kill the sandbox (from any state) -sandbox.kill() # Running/Paused → Killed -``` - - -## Pausing sandbox -When you pause a sandbox, both the sandbox's filesystem and memory state will be saved. This includes all the files in the sandbox's filesystem and all the running processes, loaded variables, data, etc. - - -```js JavaScript & TypeScript highlight={8-9} -import { Sandbox } from '@e2b/code-interpreter' - -const sbx = await Sandbox.create() -console.log('Sandbox created', sbx.sandboxId) - -// Pause the sandbox -// You can save the sandbox ID in your database to resume the sandbox later -await sbx.betaPause() -console.log('Sandbox paused', sbx.sandboxId) -``` -```python Python highlight={8-9} -from e2b_code_interpreter import Sandbox - -sbx = Sandbox.create() -print('Sandbox created', sbx.sandbox_id) - -# Pause the sandbox -# You can save the sandbox ID in your database to resume the sandbox later -sbx.beta_pause() -print('Sandbox paused', sbx.sandbox_id) -``` - - - -## Resuming sandbox -When you resume a sandbox, it will be in the same state it was in when you paused it. -This means that all the files in the sandbox's filesystem will be restored and all the running processes, loaded variables, data, etc. will be restored. - - -```js JavaScript & TypeScript highlight={12-13} -import { Sandbox } from '@e2b/code-interpreter' - -const sbx = await Sandbox.create() -console.log('Sandbox created', sbx.sandboxId) - -// Pause the sandbox -// You can save the sandbox ID in your database to resume the sandbox later -await sbx.betaPause() -console.log('Sandbox paused', sbx.sandboxId) - -// Connect to the sandbox (it will automatically resume the sandbox, if paused) -const sameSbx = await sbx.connect() -console.log('Connected to the sandbox', sameSbx.sandboxId) -``` -```python Python highlight={12-13} -from e2b_code_interpreter import Sandbox - -sbx = Sandbox.create() -print('Sandbox created', sbx.sandbox_id) - -# Pause the sandbox -# You can save the sandbox ID in your database to resume the sandbox later -sbx.beta_pause() -print('Sandbox paused', sbx.sandbox_id) - -# Connect to the sandbox (it will automatically resume the sandbox, if paused) -same_sbx = sbx.connect() -print('Connected to the sandbox', same_sbx.sandbox_id) -``` - - -## Listing paused sandboxes -You can list all paused sandboxes by calling the `Sandbox.list` method and supplying the `state` query parameter. -More information about using the method can be found in [List Sandboxes](/docs/sandbox/list). - - -```js JavaScript & TypeScript highlight={4,7} -import { Sandbox, SandboxInfo } from '@e2b/code-interpreter' - -// List all paused sandboxes -const paginator = Sandbox.list({ query: { state: ['paused'] } }) - -// Get the first page of paused sandboxes -const sandboxes = await paginator.nextItems() - -// Get all paused sandboxes -while (paginator.hasNext) { - const items = await paginator.nextItems() - sandboxes.push(...items) -} -``` -```python Python highlight={4,7} -# List all paused sandboxes -from e2b_code_interpreter import Sandbox, SandboxQuery, SandboxState - -paginator = Sandbox.list(SandboxQuery(state=[SandboxState.PAUSED])) - -# Get the first page of paused sandboxes -sandboxes = paginator.next_items() - -# Get all paused sandboxes -while paginator.has_next: - items = paginator.next_items() - sandboxes.extend(items) -``` - - -## Removing paused sandboxes - -You can remove paused sandboxes by calling the `kill` method on the Sandbox instance. - - -```js JavaScript & TypeScript highlight={11,14} -import { Sandbox } from '@e2b/code-interpreter' - -const sbx = await Sandbox.create() -console.log('Sandbox created', sbx.sandboxId) - -// Pause the sandbox -// You can save the sandbox ID in your database to resume the sandbox later -await sbx.betaPause() - -// Remove the sandbox -await sbx.kill() - -// Remove sandbox by id -await Sandbox.kill(sbx.sandboxId) -``` -```python Python highlight={9,12} -from e2b_code_interpreter import Sandbox - -sbx = Sandbox.create() - -# Pause the sandbox -sbx.beta_pause() - -# Remove the sandbox -sbx.kill() - -# Remove sandbox by id -Sandbox.kill(sbx.sandbox_id) -``` - - -## Sandbox's timeout -When you connect to a sandbox, the sandbox's timeout is reset to the default timeout of an E2B sandbox - 5 minutes. - -You can pass a custom timeout to the `Sandbox.connect()`/`Sandbox.connect()` method like this: - - -```js JavaScript & TypeScript -import { Sandbox } from '@e2b/code-interpreter' - -const sbx = await Sandbox.connect(sandboxId, { timeoutMs: 60 * 1000 }) // 60 seconds -``` -```python Python -from e2b_code_interpreter import Sandbox - -sbx = Sandbox.connect(sandbox_id, timeout=60) # 60 seconds -``` - - - -### Auto-pause (beta) - -**Note: Auto-pause is currently in beta and available through `Sandbox.betaCreate()`/`Sandbox.beta_create()` method.** - -Sandboxes can now automatically pause after they time out. When a sandbox is paused, it stops consuming compute but preserves its state. The default inactivity timeout is 10 minutes. You can change the timeout by passing the `timeoutMs`/`timeout` parameter to the `Sandbox.connect()`/`Sandbox.connect()` method. - - -```js JavaScript & TypeScript -import { Sandbox } from '@e2b/code-interpreter' - -// Create sandbox with auto-pause enabled -const sandbox = await Sandbox.betaCreate({ - autoPause: true, - timeoutMs: 10 * 60 * 1000 // Optional: change the default timeout (10 minutes) -}) -``` -```python Python -from e2b_code_interpreter import Sandbox - -# Create sandbox with auto-pause enabled (Beta) -sandbox = Sandbox.beta_create( - auto_pause=True, # Auto-pause after the sandbox times out - timeout=10 * 60, # Optional: change the default timeout (10 minutes) -) -``` - - -The auto-pause is persistent, meaning that if your sandbox resumes and it times out, it will be automatically paused again. - -If you `.kill()` the sandbox, it will be permanently deleted and you won't be able to resume it. - - -```js JavaScript & TypeScript -import { Sandbox } from '@e2b/code-interpreter' - -// Create sandbox with auto-pause enabled (Beta) -const sandbox = await Sandbox.betaCreate({ - autoPause: true // Auto-pause after the sandbox times out -}) -``` -```python Python -from e2b_code_interpreter import Sandbox - -# Create sandbox with auto-pause enabled (Beta) -sandbox = Sandbox.beta_create( - auto_pause=True # Auto-pause after the sandbox times out -) -``` - - -## Network -If you have a service (for example a server) running inside your sandbox and you pause the sandbox, the service won't be accessible from the outside and all the clients will be disconnected. -If you resume the sandbox, the service will be accessible again but you need to connect clients again. - - -## Limitations while in beta - -### Lifecycle duration -- A sandbox can exist for **up to 30 days** from the initial `create` call. -- After 30 days, sandbox data **may be deleted** and the sandbox can no longer be resumed. -- Attempting to resume a deleted or non-existent sandbox will result in: - - `NotFoundError` in the JavaScript SDK - - `NotFoundException` in the Python SDK - -### Pause and resume performance -- Pausing a sandbox takes approximately **4 seconds per 1 GiB of RAM** -- Resuming a sandbox takes approximately **1 second** - -### Continuous runtime limits -- A sandbox can remain running (without being paused) for: - - **24 hours** on the **Pro tier** - - **1 hour** on the **Base tier** -- After a sandbox is paused and resumed, the continuous runtime limit is **reset** -- The **30-day total lifetime limit** still applies regardless of how many times the sandbox is paused or resumed +Content coming soon. diff --git a/docs/sandbox/reading-output.mdx b/docs/sandbox/reading-output.mdx new file mode 100644 index 0000000..66e7384 --- /dev/null +++ b/docs/sandbox/reading-output.mdx @@ -0,0 +1,9 @@ +--- +title: "Reading Output" +description: "Capture stdout, stderr, and exit codes from code execution in E2B sandboxes with support for real-time streaming, line-by-line processing, and buffered output handling." +icon: "scroll" +--- + +# Reading Output + +Content coming soon. diff --git a/docs/sandbox/security.mdx b/docs/sandbox/security.mdx new file mode 100644 index 0000000..50ee389 --- /dev/null +++ b/docs/sandbox/security.mdx @@ -0,0 +1,9 @@ +--- +title: "Security" +description: "Learn about E2B's security model including sandbox isolation, network policies, resource limits, and best practices for running untrusted code safely in production environments." +icon: "shield-halved" +--- + +# Security + +Content coming soon. diff --git a/docs/sdks-explained.mdx b/docs/sdks-explained.mdx new file mode 100644 index 0000000..8e90fdb --- /dev/null +++ b/docs/sdks-explained.mdx @@ -0,0 +1,228 @@ +--- +title: "SDKs Explained" +description: "E2B offers three SDK packages, each available in **Python** and **JavaScript/TypeScript**." +icon: "code" +--- + + +**Architecture:** `e2b-code-interpreter` and `e2b-desktop` are built on top of the core `e2b` SDK. All classes, methods, and features from `e2b` are available in the specialized SDKs. + + + + + Core SDK - Foundation + + + e2b + code execution environment + + + e2b + Linux desktop GUI + + + +--- + + +## e2b + +General-purpose sandboxes for running any code, commands, or processes. + +**Use when:** Building custom AI agents, running untrusted code, or need full control over the environment. + +### Installation + + +```bash Python +pip install e2b +``` + +```bash JavaScript +npm install e2b +``` + + +### Quick Start + + +```python Python +from e2b import Sandbox + +# Create sandbox +sbx = Sandbox.create() + +# Run command +result = sbx.commands.run("echo 'Hello from E2B'") +print(result.stdout) + +# Run Python code +result = sbx.commands.run("whoami") +print(result.stdout) +``` + +```typescript JavaScript +import { Sandbox } from 'e2b' + +// Create sandbox +const sbx = await Sandbox.create() + +// Run command +const result = await sbx.commands.run("echo 'Hello from E2B'") +console.log(result.stdout) + +// Run Node.js code +const result2 = await sbx.commands.run("whoami") +console.log(result2.stdout) +``` + + + + Complete API documentation + + +--- + + +## e2b-code-interpreter + +Built on top of `e2b` with added support for multi-language code execution (Python, JavaScript, R, Java, Bash), pre-installed data science libraries, and visualization capabilities. + + +Includes **all features from `e2b`** plus specialized code execution methods and pre-configured environment. + + +**Use when:** Building AI data analysts, code execution environments, or need chart generation. + +### Installation + + +```bash Python +pip install e2b-code-interpreter +``` + +```bash JavaScript +npm install @e2b/code-interpreter +``` + + +### Quick Start + + +```python Python +from e2b_code_interpreter import Sandbox + +# Create code interpreter +sbx = Sandbox.create() + +# Execute code with results +execution = sbx.run_code("print('Hello from E2B'); 2 + 2") + +# Access results +for result in execution.results: + print(result) +``` + +```typescript JavaScript +import { Sandbox } from '@e2b/code-interpreter' + +// Create code interpreter +const sbx = await Sandbox.create() + +// Execute code with results +const execution = await sbx.runCode("console.log('Hello from E2B'); 2 + 2") + +// Access results +execution.results.forEach(result => console.log(result)) +``` + + + + Detailed documentation, examples, and supported languages + + +--- + + +## e2b-desktop + +Built on top of `e2b` with a full Linux desktop environment including GUI, browser, and window management. + + +Includes **all features from `e2b`** plus desktop-specific methods like `getDesktopUrl()` and pre-configured GUI environment. + + +**Use when:** Browser automation, visual testing, or applications requiring a desktop UI. + +### Installation + + +```bash Python +pip install e2b-desktop +``` + +```bash JavaScript +npm install @e2b/desktop +``` + + +### Quick Start + + +```python Python +from e2b_desktop import Sandbox + +# Create desktop sandbox +sbx = Sandbox.create() + +# Get desktop URL +desktop_url = sbx.get_desktop_url() +print(f"Access desktop at: {desktop_url}") + +# Run GUI application +sbx.commands.run("firefox https://example.com") +``` + +```typescript JavaScript +import { Sandbox } from '@e2b/desktop' + +// Create desktop sandbox +const sbx = await Sandbox.create() + +// Get desktop URL +const desktopUrl = await sbx.getDesktopUrl() +console.log(`Access desktop at: ${desktopUrl}`) + +// Run GUI application +await sbx.commands.run('firefox https://example.com') +``` + + + + Full walkthrough and examples + + +--- + +## Choosing the Right SDK + + + + - Want default Ubuntu VM + - Want to use [MCP-Gateway]() + - Do not need to use code [interpreter specific functions]() + + + + - AI data analysis and visualization + - Multi-language code execution (Python, JavaScript, R, Java, Bash) + - Need data science libraries pre-installed + - Generating charts, plots, or reports + - Jupyter-like code execution environment + + + + - Browser automation with visual feedback + - Testing applications that require a GUI + - Screen recording or screenshots + - Running desktop applications in the cloud + + diff --git a/docs/templates/intro.mdx b/docs/templates/intro.mdx new file mode 100644 index 0000000..f6ca82b --- /dev/null +++ b/docs/templates/intro.mdx @@ -0,0 +1,9 @@ +--- +title: "Templates Intro" +description: "Create custom sandbox templates with pre-installed dependencies, configurations, and tools to quickly spin up consistent development environments for your AI agents." +icon: "layer-group" +--- + +# Templates Intro + +Content coming soon. diff --git a/docs/use-cases/ai-data-analysis-visualization.mdx b/docs/use-cases/ai-data-analysis-visualization.mdx new file mode 100644 index 0000000..2b885e9 --- /dev/null +++ b/docs/use-cases/ai-data-analysis-visualization.mdx @@ -0,0 +1,9 @@ +--- +title: "AI Data Analysis & Visualization" +description: "Enable AI agents to analyze datasets, generate insights, create charts and visualizations, and perform statistical analysis using Python libraries like pandas, matplotlib, and seaborn." +icon: "chart-line" +--- + +# AI Data Analysis & Visualization + +Content coming soon. diff --git a/docs/use-cases/deep-research-agents.mdx b/docs/use-cases/deep-research-agents.mdx new file mode 100644 index 0000000..71f5e8e --- /dev/null +++ b/docs/use-cases/deep-research-agents.mdx @@ -0,0 +1,62 @@ +--- +title: "Deep Research Agents" +description: "Build AI agents that perform comprehensive research by executing code, analyzing data, running experiments, and iterating on findings in isolated sandbox environments." +icon: "magnifying-glass-chart" +--- + +## Related Guides + + + + Create and manage E2B sandboxes + + + Run code in sandboxes + + + Capture execution results + + + Save data across sessions + + + Create charts from findings + + + Custom sandbox templates + + + +## Project Structure + + +```ts JavaScript && TypeScript +research-agent/ +├── agent/ +│ ├── orchestrator.py // Main agent logic +│ ├── tools.py // Research tools (web search, code execution) +│ └── memory.py // Research state management +├── sandbox/ +│ ├── setup.py // Sandbox initialization +│ └── analysis.py // Data analysis helpers +├── config.py // Configuration (API keys, models) +└── main.py // Entry point +``` +```python Python +research-agent/ +├── agent/ +│ ├── orchestrator.py # Main agent logic +│ ├── tools.py # Research tools (web search, code execution) +│ └── memory.py # Research state management +├── sandbox/ +│ ├── setup.py # Sandbox initialization +│ └── analysis.py # Data analysis helpers +├── config.py # Configuration (API keys, models) +└── main.py # Entry point +``` + +--- + +## Implementation + +Content coming soon. diff --git a/docs/use-cases/linux-desktop.mdx b/docs/use-cases/linux-desktop.mdx new file mode 100644 index 0000000..5022b3c --- /dev/null +++ b/docs/use-cases/linux-desktop.mdx @@ -0,0 +1,1156 @@ +--- +title: "AI-Powered Desktop Control" +description: "Build AI agents that control virtual Linux desktops using OpenAI Computer Use API and E2B Desktop sandboxes with real-time visual feedback." +icon: "desktop" +--- + +## Related Guides + + + + Create virtual Linux desktops + + + Integrate AI models with sandboxes + + + Customize sandbox environments + + + Stream execution results in real-time + + + Manage sandbox files and directories + + + Configure environment and authentication + + + +## Project Structure + + +```ts TypeScript +surf-starter/ +├── app/ +│ ├── api/chat/ +│ │ └── route.ts // SSE endpoint - handles AI loop + sandbox +│ ├── actions.ts // Server actions for sandbox management +│ ├── layout.tsx // Root layout with metadata +│ └── page.tsx // Main UI - chat interface + VNC viewer +├── lib/ +│ ├── ai/ +│ │ └── instructions.ts // System prompt for AI agent +│ ├── services/ +│ │ └── openai.ts // Computer use loop with OpenAI +│ ├── utils/ +│ │ ├── actions.ts // Execute computer actions on sandbox +│ │ ├── screenshot.ts // Process and resize screenshots +│ │ └── stream.ts // SSE streaming utilities +│ ├── constants.ts // Configuration constants +│ └── env.ts // Environment validation +├── styles/ +│ └── globals.css // Application styling +├── types/ +│ └── index.ts // TypeScript types and interfaces +├── .env // API keys (E2B, OpenAI) +├── package.json // Dependencies +└── tsconfig.json // TypeScript configuration +``` + + +--- + +## How It Works + +This application creates an autonomous AI loop that enables natural language control of a virtual Linux desktop: + +1. **User Input** - You send a natural language command like "Open Firefox and search for AI news" +2. **Sandbox Creation** - E2B spins up an Ubuntu 22.04 desktop environment (if not already running) +3. **Visual Analysis** - The AI receives a screenshot of the current desktop state +4. **Action Planning** - OpenAI Computer Use API analyzes the screenshot and decides what action to take +5. **Action Execution** - The action (click, type, scroll, etc.) is executed on the desktop via E2B SDK +6. **Feedback Loop** - A new screenshot is taken and sent back to the AI +7. **Iteration** - The loop continues until the task is complete (maximum 15 iterations) + +All updates stream to your browser in real-time via Server-Sent Events (SSE), giving you live visibility into what the AI is thinking and doing. + +--- + +## Implementation + +### Step 1: Project Setup + +Initialize a new Next.js project and install the required dependencies. + + + + ```bash + npx create-next-app@latest surf-starter --typescript --app --no-tailwind + cd surf-starter + ``` + + + + ```bash + npm install @e2b/desktop openai sharp + ``` + + **Dependencies explained:** + - `@e2b/desktop` - E2B Desktop SDK for controlling virtual Linux desktops + - `openai` - OpenAI SDK for Computer Use API integration + - `sharp` - Fast image processing library for screenshot optimization + + + +### Step 2: Environment Configuration + +Set up your API keys and create environment validation utilities. + + + + Create a `.env` file in your project root: + + ```env + E2B_API_KEY=your_e2b_api_key_here + OPENAI_API_KEY=your_openai_api_key_here + ``` + + Get your API keys: + - E2B API Key: [https://e2b.dev/docs/api-key](https://e2b.dev/docs/api-key) + - OpenAI API Key: [https://platform.openai.com/api-keys](https://platform.openai.com/api-keys) + + + + Create `lib/env.ts` to validate environment variables: + + ```typescript + // lib/env.ts + export function getEnv() { + const E2B_API_KEY = process.env.E2B_API_KEY; + const OPENAI_API_KEY = process.env.OPENAI_API_KEY; + + if (!E2B_API_KEY || !OPENAI_API_KEY) { + throw new Error('Missing required environment variables'); + } + + return { E2B_API_KEY, OPENAI_API_KEY }; + } + + export function isEnvironmentConfigured(): boolean { + return !!(process.env.E2B_API_KEY && process.env.OPENAI_API_KEY); + } + ``` + + + +### Step 3: Type Definitions + +Define TypeScript interfaces for type safety throughout the application. + + + + Create `types/index.ts` with core application types: + + ```typescript + // types/index.ts + + // Message structure for chat interface + export interface ChatMessage { + role: 'user' | 'assistant' | 'system' | 'action'; + content: string; + } + + // Computer actions the AI can execute + export type ComputerAction = + | { type: 'click'; x: number; y: number; button: 'left' | 'right' | 'wheel' } + | { type: 'double_click'; x: number; y: number } + | { type: 'type'; text: string } + | { type: 'key' | 'keypress'; keys?: string[]; key?: string } + | { type: 'move'; x: number; y: number } + | { type: 'drag'; start_x: number; start_y: number; x: number; y: number } + | { type: 'scroll'; amount: number } + | { type: 'wait'; duration?: number } + | { type: 'screenshot' }; + + // SSE events for real-time updates + export interface SSEEvent { + type: 'sandbox_created' | 'reasoning' | 'action' | 'action_completed' | 'done' | 'error'; + content?: string; + action?: string; + sandboxId?: string; + url?: string; + message?: string; + } + + // Conversation tracking for context + export interface ConversationTurn { + userMessage: string; + aiResponse: string; + timestamp: number; + } + ``` + + The `ComputerAction` discriminated union ensures type-safe action handling throughout the application. + + + +### Step 4: Configuration Constants + +Centralize all configuration values for easy management. + + + + Create `lib/constants.ts` with application-wide constants: + + ```typescript + // lib/constants.ts + + // Sandbox configuration + export const SANDBOX_CONFIG = { + TIMEOUT_MS: 300_000, // 5 minutes initial timeout + TIMEOUT_SECONDS: 300, + AUTO_EXTEND_THRESHOLD: 10, + ACTIVE_WORK_TIMEOUT_MS: 600_000, // 10 minutes during active work + MIN_EXTEND_INTERVAL_MS: 30_000, // Minimum 30s between extensions + } as const; + + // Screenshot processing + export const SCREENSHOT_CONFIG = { + MAX_WIDTH: 1024, + MAX_HEIGHT: 768, + MIN_WIDTH: 640, + MIN_HEIGHT: 480, + } as const; + + // AI model configuration + export const AI_CONFIG = { + MODEL: 'computer-use-preview', // OpenAI computer use model + MAX_ITERATIONS: 15, // Maximum loop iterations + MAX_WAIT_DURATION: 1500, // Maximum wait time (ms) + REASONING_EFFORT: 'medium', // AI reasoning level + } as const; + + // API configuration + export const API_CONFIG = { + MAX_DURATION: 300, // 5 minutes per request + RUNTIME: 'nodejs', + } as const; + ``` + + These constants make it easy to adjust timeouts, screenshot sizes, and AI behavior without hunting through code. + + + +### Step 5: Utility Functions + +Build helper functions for screenshot processing, streaming, and action execution. + + + + Create `lib/utils/screenshot.ts` to optimize screenshots: + + ```typescript + // lib/utils/screenshot.ts + import sharp from 'sharp'; + import { SCREENSHOT_CONFIG } from '@/lib/constants'; + + export async function processScreenshot( + screenshotBuffer: Uint8Array | Buffer + ): Promise { + const processedBuffer = await sharp(screenshotBuffer) + .resize(SCREENSHOT_CONFIG.MAX_WIDTH, SCREENSHOT_CONFIG.MAX_HEIGHT, { + fit: 'contain', + background: { r: 0, g: 0, b: 0, alpha: 1 }, + }) + .png() + .toBuffer(); + + return processedBuffer.toString('base64'); + } + ``` + + This function resizes screenshots to optimal dimensions and converts them to base64 for API transmission. + + + + Create `lib/utils/stream.ts` for SSE streaming: + + ```typescript + // lib/utils/stream.ts + export function createSafeStreamController( + controller: ReadableStreamDefaultController + ) { + let isControllerClosed = false; + + const safeEnqueue = (data: Uint8Array): void => { + if (!isControllerClosed) { + try { + controller.enqueue(data); + } catch (error) { + isControllerClosed = true; + } + } + }; + + const safeClose = (): void => { + if (!isControllerClosed) { + try { + controller.close(); + isControllerClosed = true; + } catch (error) { + isControllerClosed = true; + } + } + }; + + return { enqueue: safeEnqueue, close: safeClose }; + } + + export function createSSEEvent(event: object): string { + return `data: ${JSON.stringify(event)}\n\n`; + } + ``` + + The safe stream controller prevents "already closed" errors during SSE streaming. + + + + Create `lib/utils/actions.ts` to map AI actions to E2B SDK calls: + + ```typescript + // lib/utils/actions.ts + import type { Sandbox } from '@e2b/desktop'; + import type { ComputerAction } from '@/types'; + + export async function executeComputerAction( + sandbox: Sandbox, + action: ComputerAction + ): Promise { + switch (action.type) { + case 'click': + if (action.button === 'left') { + await sandbox.leftClick(action.x, action.y); + } else if (action.button === 'right') { + await sandbox.rightClick(action.x, action.y); + } + break; + + case 'double_click': + await sandbox.doubleClick(action.x, action.y); + break; + + case 'type': + await sandbox.write(action.text); + break; + + case 'key': + case 'keypress': + const key = action.keys?.[0] || action.key; + if (key) await sandbox.press(key); + break; + + case 'move': + await sandbox.moveMouse(action.x, action.y); + break; + + case 'scroll': + await sandbox.scroll(action.amount < 0 ? 'up' : 'down'); + break; + + case 'wait': + await new Promise(resolve => + setTimeout(resolve, Math.min(action.duration || 1000, 3000)) + ); + break; + } + } + + export function formatActionForDisplay(action: ComputerAction): string { + switch (action.type) { + case 'click': + return `Click ${action.button} at (${action.x}, ${action.y})`; + case 'type': + return `Type: "${action.text}"`; + case 'key': + case 'keypress': + return `Press key: ${action.keys?.[0] || action.key}`; + default: + return `Action: ${action.type}`; + } + } + ``` + + This utility translates OpenAI Computer Use actions into E2B Desktop SDK method calls. + + + +### Step 6: AI System Prompt + +Define the system instructions that guide the AI agent's behavior. + + + + Create `lib/ai/instructions.ts` with the AI agent prompt: + + ```typescript + // lib/ai/instructions.ts + export const SYSTEM_INSTRUCTIONS = `You are Surf, an AI assistant that controls a Linux desktop to help users with tasks. + +ENVIRONMENT: +- Ubuntu 22.04 desktop with Firefox, VS Code, LibreOffice, Terminal, File Manager, Text Editor +- Desktop has bottom taskbar with application launchers +- Desktop is ready - you can start immediately + +AVAILABLE ACTIONS: +- screenshot: View current desktop state +- click/double_click: Click at coordinates (left/right/middle button) +- type: Type text into focused field +- key: Press keyboard keys (ENTER, ESCAPE, TAB, BACKSPACE, etc.) +- move: Move mouse cursor +- drag: Drag between two positions +- scroll: Scroll up or down +- wait: Pause briefly (use only after opening apps or loading pages) + +EXECUTION GUIDELINES: +1. Take screenshots to see the current state +2. Identify UI elements using coordinates from screenshots +3. Execute actions precisely +4. After opening applications or loading pages, wait 1-2 seconds for them to load +5. After terminal commands, press ENTER to execute +6. Complete tasks efficiently with minimal delays + +AUTONOMY: +- Execute tasks directly when intent is clear +- Ask clarifying questions only when there's genuine ambiguity +- When user confirms ("yes", "proceed", "do it"), take the next action immediately + +COMPLETION: +- When done, explain what you accomplished +- Stop taking actions once the goal is achieved + +Be helpful, precise, and efficient.`; + ``` + + This prompt is crucial for effective agent behavior. It teaches the AI about the environment, available actions, and expected execution patterns. + + + +### Step 7: Computer Use Loop + +Implement the core AI execution loop that powers desktop control. + + + + Create `lib/services/openai.ts` with the computer use loop: + + ```typescript + // lib/services/openai.ts + import OpenAI from 'openai'; + import type { Sandbox } from '@e2b/desktop'; + import { AI_CONFIG, SCREENSHOT_CONFIG } from '@/lib/constants'; + import { SYSTEM_INSTRUCTIONS } from '@/lib/ai/instructions'; + import { processScreenshot } from '@/lib/utils/screenshot'; + import { executeComputerAction, formatActionForDisplay } from '@/lib/utils/actions'; + import { getEnv } from '@/lib/env'; + + export async function runComputerUseLoop( + sandbox: Sandbox, + userMessage: string, + sendEvent: (data: Uint8Array) => void + ): Promise { + const { OPENAI_API_KEY } = getEnv(); + const openai = new OpenAI({ apiKey: OPENAI_API_KEY }); + const encoder = new TextEncoder(); + + // Take initial screenshot + const screenshotBuffer = await sandbox.screenshot(); + const screenshotBase64 = await processScreenshot(screenshotBuffer); + + // Define computer tool + const computerTool = { + type: 'computer_use_preview' as const, + display_width: SCREENSHOT_CONFIG.MAX_WIDTH, + display_height: SCREENSHOT_CONFIG.MAX_HEIGHT, + environment: 'linux' as const, + }; + + // Create initial request with screenshot + let response = await openai.responses.create({ + model: AI_CONFIG.MODEL, + tools: [computerTool], + input: [{ + type: 'message', + role: 'user', + content: [ + { type: 'input_text', text: userMessage }, + { type: 'input_image', image_url: `data:image/png;base64,${screenshotBase64}`, detail: 'high' }, + ], + }], + instructions: SYSTEM_INSTRUCTIONS, + truncation: 'auto', + reasoning: { effort: AI_CONFIG.REASONING_EFFORT, generate_summary: 'concise' }, + }); + + let iterations = 0; + + // Main execution loop + while (iterations < AI_CONFIG.MAX_ITERATIONS) { + iterations++; + + // Extract computer actions from AI response + const computerCalls = response.output.filter( + (item: any) => item.type === 'computer_call' + ); + + // If no actions, task is complete + if (computerCalls.length === 0) { + sendEvent(encoder.encode(`data: ${JSON.stringify({ + type: 'reasoning', + content: response.output_text || 'Task complete!' + })}\n\n`)); + break; + } + + const computerCall = computerCalls[0] as any; + const action = computerCall.action; + + // Send action to client + sendEvent(encoder.encode(`data: ${JSON.stringify({ + type: 'action', + action: formatActionForDisplay(action) + })}\n\n`)); + + // Execute action on sandbox + await executeComputerAction(sandbox, action); + + sendEvent(encoder.encode(`data: ${JSON.stringify({ + type: 'action_completed' + })}\n\n`)); + + // Take new screenshot + const newScreenshotBuffer = await sandbox.screenshot(); + const newScreenshotBase64 = await processScreenshot(newScreenshotBuffer); + + // Continue conversation with new screenshot + response = await openai.responses.create({ + model: AI_CONFIG.MODEL, + previous_response_id: response.id, + instructions: SYSTEM_INSTRUCTIONS, + tools: [computerTool], + input: [{ + call_id: computerCall.call_id, + type: 'computer_call_output', + output: { + type: 'computer_screenshot', + image_url: `data:image/png;base64,${newScreenshotBase64}`, + }, + }], + truncation: 'auto', + reasoning: { effort: AI_CONFIG.REASONING_EFFORT, generate_summary: 'concise' }, + }); + } + } + ``` + + This is the heart of the application. The loop continuously: + 1. Takes screenshots of the desktop + 2. Sends them to OpenAI with context + 3. Receives structured computer actions + 4. Executes actions via E2B + 5. Repeats until the task is complete + + + +### Step 8: API Endpoint + +Create the backend API endpoint that orchestrates sandbox creation and AI execution. + + + + Create `app/api/chat/route.ts` for the SSE streaming endpoint: + + ```typescript + // app/api/chat/route.ts + import { Sandbox } from '@e2b/desktop'; + import { NextRequest } from 'next/server'; + import { getEnv, isEnvironmentConfigured } from '@/lib/env'; + import { SANDBOX_CONFIG } from '@/lib/constants'; + import { createSafeStreamController, createSSEEvent } from '@/lib/utils/stream'; + import { runComputerUseLoop } from '@/lib/services/openai'; + + // In-memory store for active sandboxes + const sandboxes = new Map(); + + export async function POST(req: NextRequest) { + try { + const { message, sandboxId } = await req.json(); + + if (!message) { + return new Response(JSON.stringify({ error: 'Message required' }), { status: 400 }); + } + + if (!isEnvironmentConfigured()) { + return new Response(createSSEEvent({ type: 'error', message: 'Missing API keys' }), { + headers: { 'Content-Type': 'text/event-stream' }, + }); + } + + const { E2B_API_KEY } = getEnv(); + const encoder = new TextEncoder(); + + // Create SSE stream + const stream = new ReadableStream({ + async start(controller) { + const safeController = createSafeStreamController(controller); + + try { + // Reuse existing sandbox or create new one + let sandbox = sandboxId ? sandboxes.get(sandboxId) : null; + + if (!sandbox) { + safeController.enqueue(encoder.encode(createSSEEvent({ + type: 'reasoning', + content: 'Creating sandbox...', + }))); + + sandbox = await Sandbox.create({ + apiKey: E2B_API_KEY, + timeoutMs: SANDBOX_CONFIG.TIMEOUT_MS, + }); + + await sandbox.stream.start(); + sandboxes.set(sandbox.sandboxId, sandbox); + + safeController.enqueue(encoder.encode(createSSEEvent({ + type: 'sandbox_created', + sandboxId: sandbox.sandboxId, + url: sandbox.stream.getUrl(), + }))); + } else { + await sandbox.setTimeout(SANDBOX_CONFIG.TIMEOUT_MS); + } + + // Run the AI loop + await runComputerUseLoop(sandbox, message, safeController.enqueue); + + safeController.enqueue(encoder.encode(createSSEEvent({ type: 'done' }))); + safeController.close(); + } catch (error) { + safeController.enqueue(encoder.encode(createSSEEvent({ + type: 'error', + message: error instanceof Error ? error.message : 'Unknown error', + }))); + safeController.close(); + } + }, + }); + + return new Response(stream, { + headers: { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + 'Connection': 'keep-alive', + }, + }); + } catch (error) { + return new Response( + JSON.stringify({ error: error instanceof Error ? error.message : 'Internal error' }), + { status: 500 } + ); + } + } + + export const runtime = 'nodejs'; + export const maxDuration = 300; + ``` + + The endpoint: + - Validates environment and request + - Creates or reuses E2B sandboxes + - Starts VNC streaming + - Runs the computer use loop + - Streams events back to the client in real-time + + + +### Step 9: Server Actions + +Add Next.js server actions for sandbox management from the client. + + + + Create `app/actions.ts` for server-side operations: + + ```typescript + // app/actions.ts + 'use server'; + + import { Sandbox } from '@e2b/desktop'; + import { getEnv } from '@/lib/env'; + import { SANDBOX_CONFIG } from '@/lib/constants'; + + export async function extendSandboxTimeout(sandboxId: string) { + try { + if (!sandboxId) { + return { success: false, error: 'Sandbox ID required' }; + } + + const { E2B_API_KEY } = getEnv(); + const sandbox = await Sandbox.connect(sandboxId, { apiKey: E2B_API_KEY }); + await sandbox.setTimeout(SANDBOX_CONFIG.TIMEOUT_MS); + + return { success: true }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error', + }; + } + } + + export async function stopSandbox(sandboxId: string) { + try { + if (!sandboxId) { + return { success: false, error: 'Sandbox ID required' }; + } + + const { E2B_API_KEY } = getEnv(); + const sandbox = await Sandbox.connect(sandboxId, { apiKey: E2B_API_KEY }); + await sandbox.kill(); + + return { success: true }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : 'Unknown error', + }; + } + } + ``` + + These server actions allow the client to: + - **Extend timeout**: Add 5 more minutes to prevent sandbox from expiring + - **Stop sandbox**: Immediately terminate and clean up resources + + + +### Step 10: Chat Interface + +Build the React frontend with sophisticated UI, status tracking, and real-time event handling. + + + + Create `app/page.tsx` with the full-featured interface. This is a comprehensive implementation with status tracking, timeout management, and conversation history. See the surf-starter_olddd directory for the complete 422-line implementation. + + **Key features implemented:** + - Real-time status bar showing AI activity (thinking, executing, etc.) + - Countdown timer with color-coded urgency (green → yellow → red) + - Automatic timeout extension during active work + - Conversation history tracking for multi-turn context + - Welcome message with example prompts + - Typing indicators with animated dots + - Action pills for executed commands + - Sandbox status badge with pulsing animation + - Auto-scrolling to latest messages + - Comprehensive error handling + + **The implementation includes:** + - Header with gradient "🏄 Surf Demo" title + - Status bar that slides down when active + - Desktop viewer with floating timeout overlay + - Chat container with header, messages area, and input form + - Multiple state hooks for managing UI, sandbox, and conversation + - SSE event parsing with buffer handling + - Formatted time display (MM:SS) + - Color transitions based on time remaining + + Refer to `/surf-starter_olddd/app/page.tsx` for the complete 422-line implementation with all handlers and UI logic. + + + +### Step 11: Desktop Viewer + +The desktop viewer includes a sophisticated timeout overlay with visual feedback. + + + + The desktop viewer features: + - **VNC iframe**: Live desktop stream from E2B (`sandbox.stream.getUrl()`) + - **Timeout overlay**: Floating widget positioned absolutely at top-right + - **Progress bar**: Visual countdown with smooth color transitions + - **Control buttons**: "+5 min" extend button and "⏹️" stop button + - **Placeholder state**: Helpful message with example prompt when no sandbox exists + - **Backdrop blur**: Glassmorphism effect on the timeout overlay + + The overlay sits on top of the iframe using `position: absolute` with `z-index: 10` and uses `backdrop-filter: blur(8px)` for a modern glass effect. + + + +### Step 12: Styling + +Create a polished, professional interface with E2B branding and smooth animations. + + + + Create `styles/globals.css` with the complete 606-line styling. Key features: + + **Typography & Theme:** + ```css + @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap'); + + :root { + --e2b-orange: hsl(32 100% 50%); + --e2b-orange-dark: hsl(32 100% 45%); + --e2b-orange-light: hsl(32 95% 55%); + --e2b-bg: hsl(0 0% 7%); + --e2b-bg-elevated: hsl(0 0% 10%); + --e2b-border: hsl(0 0% 15%); + --e2b-text: hsl(0 0% 98%); + --e2b-text-muted: hsl(0 0% 70%); + } + ``` + + **Key Animations:** + - `slideDown`: Status bar entrance animation + - `spin`: Loading spinner rotation + - `pulse`: Sandbox badge dot pulsing + - `fadeIn`: Message appearance with slide up + - `bounce`: Typing indicator dots + + **Major Components:** + - **Header**: 3em gradient title with orange-to-light gradient + - **Status Bar**: Elevated background with animated spinner + - **Desktop View**: 2fr grid column with shadow and rounded corners + - **Timeout Overlay**: Dark translucent with backdrop blur + - **Chat Container**: 1fr grid column with header, messages, input + - **Messages**: Flex column with role-based colors and styles + - **Welcome Message**: Orange-bordered info panel with examples + - **Action Pills**: Rounded orange badges for executed actions + - **Typing Indicator**: Three bouncing dots with staggered animation + - **Send Button**: Orange with hover lift effect and shadow + + **Responsive Grid:** + ```css + main { + display: grid; + grid-template-columns: 2fr 1fr; + gap: 20px; + height: calc(100vh - 220px); + } + ``` + + **Custom Scrollbar:** + ```css + .messages::-webkit-scrollbar { + width: 8px; + } + .messages::-webkit-scrollbar-thumb { + background: var(--e2b-border); + border-radius: 4px; + } + .messages::-webkit-scrollbar-thumb:hover { + background: rgba(255, 140, 0, 0.5); + } + ``` + + The complete 606-line stylesheet is available in `/surf-starter_olddd/styles/globals.css` with all animations, hover states, and responsive breakpoints. + + + +### Step 13: Running the Application + +Start the development server and test your AI desktop control application. + + + + ```bash + npm run dev + ``` + + Visit [http://localhost:3000](http://localhost:3000) in your browser. + + + + Try these commands to test the application: + + - "Open Firefox and search for E2B documentation" + - "Open VS Code and create a new file called hello.py" + - "Open Terminal and run 'ls -la'" + - "Take a screenshot of the desktop" + - "Open File Manager and navigate to the Documents folder" + + **What to expect:** + 1. Sandbox creation (takes 5-10 seconds on first request) + 2. VNC desktop viewer appears showing Ubuntu desktop + 3. AI reasoning messages appear in chat + 4. Actions execute in real-time on the desktop + 5. You see live feedback of mouse clicks, typing, and application launches + + + + When ready to deploy: + + ```bash + npm run build + npm start + ``` + + Deploy to platforms like Vercel, Railway, or any Node.js hosting provider. Make sure to set environment variables in your deployment platform. + + + +--- + +## Key Concepts + +### E2B Desktop Sandbox +An isolated Ubuntu 22.04 environment running in the cloud: +- **Pre-installed apps**: Firefox, VS Code, LibreOffice, Terminal, File Manager, Text Editor +- **VNC access**: Real-time desktop streaming via iframe +- **Resolution**: 1024x768 by default (configurable) +- **Ephemeral**: Each sandbox is temporary unless you configure persistent storage +- **On-demand**: Created in seconds, destroyed automatically after timeout + +### OpenAI Computer Use API +A vision-enabled AI model that can control computers: +- **Vision capabilities**: Analyzes desktop screenshots to understand UI state +- **Structured actions**: Returns computer actions like click, type, scroll +- **Reasoning**: Uses chain-of-thought to plan multi-step tasks +- **Context preservation**: Maintains conversation history across actions +- **Model**: Uses `computer-use-preview` model optimized for GUI interaction + +### Computer Actions +The AI can execute these actions on the desktop: + +| Action | Parameters | E2B SDK Method | Purpose | +|--------|-----------|----------------|---------| +| `click` | x, y, button | `sandbox.leftClick()`, `sandbox.rightClick()` | Click at coordinates | +| `double_click` | x, y | `sandbox.doubleClick()` | Double-click at position | +| `type` | text | `sandbox.write()` | Type text into focused field | +| `key` | key name | `sandbox.press()` | Press keyboard keys (ENTER, ESC, etc.) | +| `move` | x, y | `sandbox.moveMouse()` | Move cursor without clicking | +| `drag` | start_x, start_y, x, y | `sandbox.drag()` | Drag between positions | +| `scroll` | amount | `sandbox.scroll()` | Scroll up or down | +| `wait` | duration (ms) | `setTimeout()` | Pause for UI to load | + +### Streaming Architecture +Real-time updates using Server-Sent Events (SSE): + +- **Event types**: + - `sandbox_created` - New sandbox initialized with VNC URL + - `reasoning` - AI thinking/planning message + - `action` - About to execute action + - `action_completed` - Action finished successfully + - `done` - Task complete + - `error` - Error occurred + +- **Benefits**: + - Live progress visibility + - Responsive user experience + - Works over standard HTTP (no WebSocket needed) + - Automatic reconnection in modern browsers + +--- + +## Best Practices + +### Prompt Engineering +- **Be specific**: "Open Firefox and go to github.com" is better than "Open a browser" +- **Use action verbs**: "Click the Submit button" rather than "I want to submit" +- **Mention UI elements**: Reference specific buttons, fields, or menu items +- **Break down complex tasks**: Give the AI clear steps for multi-part operations + +### Performance Optimization +- **Reuse sandboxes**: Keep sandbox alive across multiple related tasks to avoid creation overhead +- **Extend timeouts proactively**: Use the +5 min button before timeout expires +- **Optimize screenshots**: Balance resolution with API cost (1024x768 is a good default) +- **Set reasonable iteration limits**: 15 iterations handles most tasks; increase only if needed + +### Security Considerations +- **Never commit API keys**: Always use environment variables +- **Validate user input**: Sanitize input before sending to AI to prevent prompt injection +- **Use environment variables**: Store all secrets in `.env` files (not in code) +- **Rate limiting**: In production, add rate limits to prevent API abuse +- **Sandbox isolation**: E2B sandboxes are isolated - they can't access your local machine + +### Production Readiness +- **Persistent storage**: Store sandbox IDs in Redis or database instead of in-memory Map +- **Authentication**: Add user authentication (NextAuth, Clerk, etc.) +- **Error boundaries**: Implement React error boundaries for graceful failure handling +- **Logging**: Add structured logging for debugging and monitoring +- **Cost monitoring**: Track E2B and OpenAI API usage to control costs +- **Webhooks**: Use E2B webhooks to track sandbox lifecycle events + +--- + +## Troubleshooting + +### Sandbox Not Appearing + +**Problem**: Desktop viewer doesn't show or sandbox creation fails + +**Solutions**: +- Verify both `E2B_API_KEY` and `OPENAI_API_KEY` are set in `.env` +- Check E2B dashboard to ensure you have available credits +- Open browser DevTools Console and check for errors +- Review server terminal logs for backend errors +- Ensure you're using Node.js 18 or higher + +### AI Not Taking Actions + +**Problem**: AI responds but doesn't execute computer actions + +**Solutions**: +- Confirm you have access to OpenAI's `computer-use-preview` model +- Try more specific instructions with clear action verbs +- Ensure desktop has fully loaded before issuing commands +- Check if `MAX_ITERATIONS` limit was reached (increase if needed) +- Review AI reasoning messages to understand its decision-making + +### Actions Failing + +**Problem**: Actions execute but don't work as expected + +**Solutions**: +- **Wait times**: Applications need time to load - AI should use `wait` action after opening apps +- **Coordinates**: Click actions depend on 1024x768 resolution - ensure screenshots match +- **Keyboard keys**: Use standard key names from E2B docs (e.g., "Return" not "Enter") +- **UI timing**: Some UI elements appear after animation - add appropriate waits +- **Focus issues**: Ensure input fields are focused before typing + +### Timeout Issues + +**Problem**: Sandbox expires during long tasks + +**Solutions**: +- Server automatically extends timeout to 10 minutes during active AI work +- Use the manual "+5 min" button before timeout expires +- Increase `ACTIVE_WORK_TIMEOUT_MS` in constants for longer tasks +- Monitor timeout countdown in UI +- Consider breaking very long tasks into smaller steps + +### SSE Connection Problems + +**Problem**: Events stop streaming or connection drops + +**Solutions**: +- Check network connectivity and firewall settings +- Verify SSE headers are correctly set (Content-Type: text/event-stream) +- Ensure safe stream controller is being used to prevent double-close errors +- Review browser console for SSE-related errors +- Test with a simple SSE client to isolate frontend vs backend issues + +--- + +## Next Steps + + + + Add support for Anthropic Claude or Google Gemini with computer use capabilities + + + Pre-install specific software or configure the desktop environment for your use case + + + Add file upload/download, implement clipboard operations, and export screenshots + + + Add authentication, database persistence, monitoring, and deploy to cloud platforms + + + Implement session management, sandbox pooling, and user isolation for SaaS applications + + + Optimize screenshot compression, implement caching, and choose cost-effective AI models + + + Extend with custom tools, web scraping, data extraction, and complex workflows + + + Track usage patterns, measure task success rates, and optimize agent performance + + + +--- + +## Build the Complete Project + +Now that you understand how everything works, you can build and run the complete working application from the `surf-starter_olddd` directory. + + + + ```bash + cd surf-starter_olddd + ``` + + + + ```bash + npm install + ``` + + This installs all required packages including: + - `@e2b/desktop` - E2B Desktop SDK + - `openai` - OpenAI SDK + - `sharp` - Image processing + - `next` - Next.js framework + - `react` & `react-dom` - React libraries + + + + Copy the example environment file and add your API keys: + + ```bash + cp .env.example .env + ``` + + Edit the `.env` file with your actual API keys: + + ```env + E2B_API_KEY=your_e2b_api_key_here + OPENAI_API_KEY=your_openai_api_key_here + ``` + + **Get your API keys:** + - E2B API Key: [https://e2b.dev/docs/api-key](https://e2b.dev/docs/api-key) + - OpenAI API Key: [https://platform.openai.com/api-keys](https://platform.openai.com/api-keys) + + + + Start the application in development mode: + + ```bash + npm run dev + ``` + + Open [http://localhost:3000](http://localhost:3000) in your browser to see the live application. + + **Try these example prompts:** + - "Open Firefox and search for E2B documentation" + - "Open VS Code and create a new file" + - "Open Terminal and run 'ls -la'" + - "Take a screenshot of the desktop" + + + + When ready to deploy, create a production build: + + ```bash + npm run build + npm start + ``` + + Deploy to platforms like Vercel, Railway, or any Node.js hosting provider. Make sure to configure environment variables in your deployment platform's settings. + + + +### What You'll See + +1. **Sandbox Creation** - Takes 5-10 seconds on first request +2. **Desktop Viewer** - Live VNC stream showing Ubuntu desktop +3. **AI Reasoning** - Real-time messages showing AI's thought process +4. **Action Execution** - Watch as the AI clicks, types, and navigates the desktop +5. **Timeout Management** - Use the "+5 min" button to extend session time + +The complete source code is in the [surf-starter_olddd](../surf-starter_olddd/) directory with all files discussed in this guide. diff --git a/docs/use-cases/reinforcement-learning.mdx b/docs/use-cases/reinforcement-learning.mdx new file mode 100644 index 0000000..8040ebd --- /dev/null +++ b/docs/use-cases/reinforcement-learning.mdx @@ -0,0 +1,9 @@ +--- +title: "Reinforcement Learning" +description: "Train and evaluate reinforcement learning agents in secure sandbox environments with support for simulation frameworks, custom environments, and parallel training workflows." +icon: "brain-circuit" +--- + +# Reinforcement Learning + +Content coming soon. diff --git a/docs/use-cases/vibe-coding.mdx b/docs/use-cases/vibe-coding.mdx new file mode 100644 index 0000000..363fb86 --- /dev/null +++ b/docs/use-cases/vibe-coding.mdx @@ -0,0 +1,9 @@ +--- +title: "Vibe Coding" +description: "Experience AI-powered coding with real-time code execution, instant feedback, and interactive development where AI agents write, test, and iterate on code in live sandbox environments." +icon: "wand-magic-sparkles" +--- + +# Vibe Coding + +Content coming soon.