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:

<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):

<packages>
react-router-dom
axios
@heroicons/react
framer-motion
</packages>

Or comma-separated:

<packages>react-router-dom, axios, @heroicons/react, framer-motion</packages>

Command Execution

Use <command> tags to execute shell commands in the sandbox:

<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:

<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:

{
  "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:

{
  "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:

{
  "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

// 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)

// 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()

// 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);
}