Spaces:
Build error
Build error
| # Package Detection and Installation Guide | |
| This document explains how to use the XML-based package detection and installation mechanism in the E2B sandbox environment. | |
| ## Overview | |
| The E2B sandbox can automatically detect and install packages from XML tags in AI-generated code responses. This mechanism works alongside the existing file detection system. | |
| ## XML Tag Formats | |
| ### Individual Package Tags | |
| Use `<package>` tags for individual packages: | |
| ```xml | |
| <package>react-router-dom</package> | |
| <package>axios</package> | |
| <package>@heroicons/react</package> | |
| ``` | |
| ### Multiple Packages Tag | |
| Use `<packages>` tag for multiple packages (comma or newline separated): | |
| ```xml | |
| <packages> | |
| react-router-dom | |
| axios | |
| @heroicons/react | |
| framer-motion | |
| </packages> | |
| ``` | |
| Or comma-separated: | |
| ```xml | |
| <packages>react-router-dom, axios, @heroicons/react, framer-motion</packages> | |
| ``` | |
| ### Command Execution | |
| Use `<command>` tags to execute shell commands in the sandbox: | |
| ```xml | |
| <command>npm run build</command> | |
| <command>npm run test</command> | |
| ``` | |
| ## Complete Example | |
| Here's a complete example of an AI response with files, packages, and commands: | |
| ```xml | |
| <explanation> | |
| Creating a React application with routing and API integration. | |
| </explanation> | |
| <packages> | |
| react-router-dom | |
| axios | |
| @heroicons/react | |
| </packages> | |
| <file path="src/App.jsx"> | |
| import React from 'react'; | |
| import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; | |
| import { HomeIcon } from '@heroicons/react/24/solid'; | |
| import HomePage from './pages/HomePage'; | |
| import AboutPage from './pages/AboutPage'; | |
| function App() { | |
| return ( | |
| <Router> | |
| <div className="min-h-screen bg-gray-100"> | |
| <nav className="bg-white shadow-lg p-4"> | |
| <HomeIcon className="h-6 w-6" /> | |
| </nav> | |
| <Routes> | |
| <Route path="/" element={<HomePage />} /> | |
| <Route path="/about" element={<AboutPage />} /> | |
| </Routes> | |
| </div> | |
| </Router> | |
| ); | |
| } | |
| export default App; | |
| </file> | |
| <file path="src/pages/HomePage.jsx"> | |
| import React, { useEffect, useState } from 'react'; | |
| import axios from 'axios'; | |
| function HomePage() { | |
| const [data, setData] = useState(null); | |
| useEffect(() => { | |
| axios.get('/api/data') | |
| .then(response => setData(response.data)) | |
| .catch(error => console.error('Error fetching data:', error)); | |
| }, []); | |
| return ( | |
| <div className="container mx-auto p-8"> | |
| <h1 className="text-3xl font-bold">Home Page</h1> | |
| {data && <pre>{JSON.stringify(data, null, 2)}</pre>} | |
| </div> | |
| ); | |
| } | |
| export default HomePage; | |
| </file> | |
| <file path="src/pages/AboutPage.jsx"> | |
| import React from 'react'; | |
| function AboutPage() { | |
| return ( | |
| <div className="container mx-auto p-8"> | |
| <h1 className="text-3xl font-bold">About Page</h1> | |
| <p>This is the about page of our application.</p> | |
| </div> | |
| ); | |
| } | |
| export default AboutPage; | |
| </file> | |
| <command>npm run dev</command> | |
| </xml> | |
| ``` | |
| ## How It Works | |
| 1. **Parsing**: The `parseAIResponse` function in `/app/api/apply-ai-code/route.ts` extracts: | |
| - Files from `<file>` tags | |
| - Packages from `<package>` and `<packages>` tags | |
| - Commands from `<command>` tags | |
| 2. **Package Installation**: | |
| - Packages are automatically installed using npm | |
| - Both scoped packages (e.g., `@heroicons/react`) and regular packages are supported | |
| - The system checks if packages are already installed to avoid redundant installations | |
| 3. **File Creation**: Files are created in the sandbox after packages are installed | |
| 4. **Command Execution**: Commands are executed in the sandbox environment | |
| ## API Endpoints | |
| ### `/api/apply-ai-code` | |
| Main endpoint that processes AI responses containing XML tags. | |
| **Request body:** | |
| ```json | |
| { | |
| "response": "<AI response with XML tags>", | |
| "isEdit": false, | |
| "packages": [] // Optional array of packages | |
| } | |
| ``` | |
| ### `/api/detect-and-install-packages` | |
| Detects packages from import statements in code files. | |
| **Request body:** | |
| ```json | |
| { | |
| "files": { | |
| "src/App.jsx": "import React from 'react'...", | |
| "src/utils.js": "import axios from 'axios'..." | |
| } | |
| } | |
| ``` | |
| ### `/api/install-packages` | |
| Directly installs packages in the sandbox. | |
| **Request body:** | |
| ```json | |
| { | |
| "packages": ["react-router-dom", "axios", "@heroicons/react"] | |
| } | |
| ``` | |
| ## Features | |
| - **Automatic Package Detection**: Extracts packages from import statements | |
| - **Duplicate Prevention**: Avoids installing already-installed packages | |
| - **Scoped Package Support**: Handles packages like `@heroicons/react` | |
| - **Built-in Module Filtering**: Skips Node.js built-in modules | |
| - **Real-time Feedback**: Provides installation progress updates | |
| - **Error Handling**: Reports failed installations | |
| ## Best Practices | |
| 1. **Specify packages explicitly** using XML tags when possible | |
| 2. **Group related packages** in a single `<packages>` tag | |
| 3. **Order matters**: Packages are installed before files are created | |
| 4. **Use commands** for post-installation tasks like building or testing | |
| ## Integration with E2B Sandbox | |
| The package detection mechanism integrates seamlessly with the E2B sandbox: | |
| 1. Packages are installed in `/home/user/app/node_modules` | |
| 2. The Vite dev server is automatically restarted after package installation | |
| 3. All npm operations run within the sandbox environment | |
| 4. Package.json is automatically updated with new dependencies | |
| ## E2B Command Execution Methods | |
| ### Method 1: Using runCode() with Python subprocess | |
| ```javascript | |
| // Current implementation pattern | |
| await global.activeSandbox.runCode(` | |
| import subprocess | |
| import os | |
| os.chdir('/home/user/app') | |
| result = subprocess.run(['npm', 'install', 'axios'], capture_output=True, text=True) | |
| print(result.stdout) | |
| `); | |
| ``` | |
| ### Method 2: Using commands.run() directly (Recommended) | |
| ```javascript | |
| // Direct command execution - cleaner approach | |
| const result = await global.activeSandbox.commands.run('npm install axios', { | |
| cwd: '/home/user/app', | |
| timeout: 60000 | |
| }); | |
| console.log(result.stdout); | |
| ``` | |
| ### Command Execution Options | |
| When using `sandbox.commands.run()`, you can specify: | |
| - `cmd`: Command string to execute | |
| - `background`: Run in background (true) or wait for completion (false) | |
| - `envs`: Environment variables as key-value pairs | |
| - `user`: User to run command as (default: "user") | |
| - `cwd`: Working directory | |
| - `on_stdout`: Callback for stdout output | |
| - `on_stderr`: Callback for stderr output | |
| - `timeout`: Command timeout in seconds (default: 60) | |
| ### Example: Installing packages with commands.run() | |
| ```javascript | |
| // Install multiple packages | |
| const packages = ['react-router-dom', 'axios', '@heroicons/react']; | |
| const result = await global.activeSandbox.commands.run( | |
| `npm install ${packages.join(' ')}`, | |
| { | |
| cwd: '/home/user/app', | |
| timeout: 120, | |
| on_stdout: (data) => console.log('npm:', data), | |
| on_stderr: (data) => console.error('npm error:', data) | |
| } | |
| ); | |
| if (result.exitCode === 0) { | |
| console.log('Packages installed successfully'); | |
| } else { | |
| console.error('Installation failed:', result.stderr); | |
| } |