initial
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user