Spaces:
Paused
Paused
| import { NextRequest, NextResponse } from 'next/server'; | |
| import { SandboxFactory } from '@/lib/sandbox/factory'; | |
| // SandboxProvider type is used through SandboxFactory | |
| import type { SandboxState } from '@/types/sandbox'; | |
| import { sandboxManager } from '@/lib/sandbox/sandbox-manager'; | |
| // Store active sandbox globally | |
| declare global { | |
| var activeSandboxProvider: any; | |
| var sandboxData: any; | |
| var existingFiles: Set<string>; | |
| var sandboxState: SandboxState; | |
| } | |
| export async function POST(request: NextRequest) { | |
| try { | |
| const { runtime = 'react' } = await request.json() || {}; | |
| console.log(`[create-ai-sandbox-v2] Creating sandbox for ${runtime}...`); | |
| // Clean up all existing sandboxes | |
| console.log('[create-ai-sandbox-v2] Cleaning up existing sandboxes...'); | |
| await sandboxManager.terminateAll(); | |
| // Also clean up legacy global state | |
| if (global.activeSandboxProvider) { | |
| try { | |
| await global.activeSandboxProvider.terminate(); | |
| } catch (e) { | |
| console.error('Failed to terminate legacy global sandbox:', e); | |
| } | |
| global.activeSandboxProvider = null; | |
| } | |
| // Clear existing files tracking | |
| if (global.existingFiles) { | |
| global.existingFiles.clear(); | |
| } else { | |
| global.existingFiles = new Set<string>(); | |
| } | |
| // Create new sandbox using factory | |
| const provider = SandboxFactory.create(); | |
| const sandboxInfo = await provider.createSandbox(); | |
| if (runtime === 'python') { | |
| console.log('[create-ai-sandbox-v2] Setting up Python environment...'); | |
| await provider.setupPythonEnv(); | |
| } else { | |
| console.log('[create-ai-sandbox-v2] Setting up Vite React app...'); | |
| await provider.setupViteApp(); | |
| } | |
| // Register with sandbox manager | |
| sandboxManager.registerSandbox(sandboxInfo.sandboxId, provider); | |
| // Also store in legacy global state for backward compatibility | |
| global.activeSandboxProvider = provider; | |
| global.sandboxData = { | |
| sandboxId: sandboxInfo.sandboxId, | |
| url: sandboxInfo.url | |
| }; | |
| // Initialize sandbox state | |
| global.sandboxState = { | |
| fileCache: { | |
| files: {}, | |
| lastSync: Date.now(), | |
| sandboxId: sandboxInfo.sandboxId | |
| }, | |
| sandbox: provider, // Store the provider instead of raw sandbox | |
| sandboxData: { | |
| sandboxId: sandboxInfo.sandboxId, | |
| url: sandboxInfo.url | |
| } | |
| }; | |
| console.log('[create-ai-sandbox-v2] Sandbox ready at:', sandboxInfo.url); | |
| return NextResponse.json({ | |
| success: true, | |
| sandboxId: sandboxInfo.sandboxId, | |
| url: sandboxInfo.url, | |
| provider: sandboxInfo.provider, | |
| message: `Sandbox created and ${runtime} initialized` | |
| }); | |
| } catch (error) { | |
| console.error('[create-ai-sandbox-v2] Error:', error); | |
| // Clean up on error | |
| await sandboxManager.terminateAll(); | |
| if (global.activeSandboxProvider) { | |
| try { | |
| await global.activeSandboxProvider.terminate(); | |
| } catch (e) { | |
| console.error('Failed to terminate sandbox on error:', e); | |
| } | |
| global.activeSandboxProvider = null; | |
| } | |
| return NextResponse.json( | |
| { | |
| error: error instanceof Error ? error.message : 'Failed to create sandbox', | |
| details: error instanceof Error ? error.stack : undefined | |
| }, | |
| { status: 500 } | |
| ); | |
| } | |
| } |