BOLT / docs /PACKAGE_DETECTION_GUIDE.md
legends810's picture
Upload folder using huggingface_hub
d83e271 verified
# 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);
}