This commit is contained in:
Developers Digest
2025-08-08 09:04:33 -04:00
parent 0e883102ed
commit 1629e12079
73 changed files with 24502 additions and 0 deletions
+263
View File
@@ -0,0 +1,263 @@
# 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);
}
+63
View File
@@ -0,0 +1,63 @@
# Streaming API Fixes Summary
## Issues Fixed
### 1. "Cannot read properties of undefined (reading 'split')"
**Location**: `/api/install-packages/route.ts` line 119
**Cause**: `installResult.output` was undefined
**Fix**: Added fallback to handle different output formats:
```typescript
const output = installResult?.output || installResult?.logs?.stdout?.join('\n') || '';
```
### 2. "Cannot read properties of undefined (reading 'push')"
**Location**: `/api/apply-ai-code-stream/route.ts` various lines
**Causes**:
- Arrays not properly initialized
- Results object properties accessed without checks
**Fixes**:
- Added array checks before operations:
```typescript
const packagesArray = Array.isArray(packages) ? packages : [];
const parsedPackages = Array.isArray(parsed.packages) ? parsed.packages : [];
const filesArray = Array.isArray(parsed.files) ? parsed.files : [];
const commandsArray = Array.isArray(parsed.commands) ? parsed.commands : [];
```
- Added null checks before push operations:
```typescript
if (results.filesCreated) results.filesCreated.push(normalizedPath);
if (results.errors) results.errors.push(`Failed to create ${file.path}`);
```
### 3. Improved Error Handling
- Added checks for undefined chunks in streaming
- Added proper error messages for all failure cases
- Ensured all arrays are initialized before use
## Current Status
✅ Package detection working via XML tags
✅ Real-time streaming feedback operational
✅ File creation/update tracking functional
✅ Command execution with output streaming
✅ Error messages properly displayed
## Known Issues
1. **NPM Resolution Errors**: When packages have conflicting dependencies, npm may show ERESOLVE errors. This is expected behavior and doesn't break the functionality.
2. **Package Installation Verification**: The current implementation tries to verify package installation by checking the filesystem. This might not always work for all package types.
## UI Feedback Flow
Users now see:
1. 🔍 Analyzing code and detecting dependencies
2. 📦 Starting code application
3. Step 1: Installing X packages (with real-time npm output)
4. Step 2: Creating Y files (with progress indicators)
5. Step 3: Executing Z commands (with output streaming)
6. ✅ Success message with summary
All errors are displayed inline with context, making debugging easier.
+67
View File
@@ -0,0 +1,67 @@
# Tool Call Validation Fix Summary
## Issue
The error message "tool call validation failed: parameters for tool installPackage did not match schema" was occurring when the AI tried to install packages.
## Root Cause
The Groq models (including `moonshotai/kimi-k2-instruct`) do not support function/tool calling. This is a limitation of most Groq models - only specific models like `llama3-groq-70b-8192-tool-use-preview` support tools.
## Solution
Instead of using the Vercel AI SDK's tool calling feature, we switched to XML-based package detection:
### 1. Removed Tool Support
- Removed the `tool` import and `installPackage` tool definition
- Removed the `tools` configuration from the `streamText` call
### 2. Updated System Prompt
Changed from:
```
Use the installPackage tool with parameters: {name: "package-name", reason: "why you need it"}
```
To:
```
You MUST specify packages using <package> tags BEFORE using them in your code.
For example: <package>three</package> or <package>@heroicons/react</package>
```
### 3. Implemented XML Tag Detection
- Added streaming detection for `<package>` tags during response generation
- Implemented buffering to handle tags split across chunks
- Added support for both individual `<package>` tags and grouped `<packages>` tags
### 4. Real-time Package Detection
Packages are now detected in real-time as the AI generates the response:
```javascript
// Buffer incomplete tags across chunks
const searchText = tagBuffer + text;
const packageRegex = /<package>([^<]+)<\/package>/g;
while ((packageMatch = packageRegex.exec(searchText)) !== null) {
const packageName = packageMatch[1].trim();
if (packageName && !packagesToInstall.includes(packageName)) {
packagesToInstall.push(packageName);
await sendProgress({
type: 'package',
name: packageName,
message: `📦 Package detected: ${packageName}`
});
}
}
```
## Results
- ✅ Package detection now works reliably
- ✅ Real-time UI feedback shows packages as they're detected
- ✅ No more tool validation errors
- ✅ Compatible with all Groq models
## UI Feedback
Users now see:
```
📦 Package detected: three
📦 Package detected: @react-three/fiber
📦 Package detected: @react-three/drei
```
As packages are detected in the AI's response, providing immediate feedback about dependencies that will be installed.
+133
View File
@@ -0,0 +1,133 @@
# UI Feedback Demonstration
This document demonstrates the new real-time feedback mechanism for package installation and command execution in the E2B sandbox UI.
## What's New
### 1. Real-time Package Installation Feedback
When packages are detected and installed from XML tags, users now see:
- 🔍 **Initial Analysis**: "Analyzing code and detecting dependencies..."
- 📦 **Package Detection**: "Step 1: Installing X packages..."
- **NPM Output**: Real-time npm install output with proper formatting
- Blue text for commands (`$ npm install react-router-dom`)
- Gray text for standard output
- Red text for errors
-**Success Messages**: Clear confirmation when packages are installed
### 2. File Creation Progress
- 📝 **File Creation Start**: "Creating X files..."
- **Individual File Updates**: Progress for each file being created/updated
-**Completion Status**: Visual confirmation for each file
### 3. Command Execution Feedback
When `<command>` tags are executed:
-**Command Start**: Shows the command being executed
- **Real-time Output**: Displays stdout/stderr as it happens
- ✅/❌ **Exit Status**: Clear success/failure indicators
## Example Flow
Here's what users see when applying code with packages and commands:
```
🔍 Analyzing code and detecting dependencies...
📦 Starting code application...
Step 1: Installing 3 packages...
$ npm install react-router-dom
> added 3 packages in 2.3s
$ npm install axios
> added 1 package in 1.1s
$ npm install @heroicons/react
> added 1 package in 0.9s
✅ Successfully installed: react-router-dom, axios, @heroicons/react
Step 2: Creating 5 files...
📝 Creating 5 files...
Step 3: Executing 1 commands...
⚡ executing command: npm run dev
> app@0.0.0 dev
> vite
> VITE ready in 523ms
✅ Command completed successfully
```
## UI Components
### Chat Message Types
The UI now supports these message types with distinct styling:
1. **System Messages** (`bg-[#36322F] text-white text-sm`)
- General information and status updates
2. **Command Messages** (`bg-gray-100 text-gray-600 font-mono text-sm`)
- Input commands: Blue prefix (`$`)
- Output: Gray text
- Errors: Red text
- Success: Green text
3. **User Messages** (`bg-[#36322F] text-white`)
- User input and queries
4. **AI Messages** (`bg-secondary text-foreground`)
- AI responses
### Visual Indicators
- 🔍 Analyzing/Detection phase
- 📦 Package operations
- 📝 File operations
- ⚡ Command execution
- ✅ Success states
- ❌ Error states
- ⚠️ Warnings
## Implementation Details
### Streaming Response Format
The new `/api/apply-ai-code-stream` endpoint sends Server-Sent Events:
```typescript
data: {"type": "start", "message": "Starting code application...", "totalSteps": 3}
data: {"type": "step", "step": 1, "message": "Installing 3 packages..."}
data: {"type": "package-progress", "type": "output", "message": "added 3 packages"}
data: {"type": "file-progress", "current": 1, "total": 5, "fileName": "App.jsx"}
data: {"type": "command-output", "command": "npm run dev", "output": "VITE ready", "stream": "stdout"}
data: {"type": "complete", "results": {...}, "message": "Success"}
```
### Error Handling
Errors are displayed inline with context:
- Package installation failures
- File creation errors
- Command execution failures
Each error includes the specific operation that failed and helpful error messages.
## Benefits
1. **Transparency**: Users see exactly what's happening in real-time
2. **Debugging**: Easy to identify where issues occur
3. **Progress Tracking**: Clear indication of progress through multi-step operations
4. **Professional Feel**: Terminal-like output for technical operations
5. **Accessibility**: Color-coded output for quick scanning
## Usage
The feedback system automatically activates when:
1. Code with `<package>` or `<packages>` tags is applied
2. Files are created or updated
3. Commands from `<command>` tags are executed
4. Packages are auto-detected from import statements
No additional configuration is required - the UI automatically provides rich feedback for all operations.