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