Spaces:
Running
Running
| <html> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width" /> | |
| <title>AI Database Generator</title> | |
| <link rel="stylesheet" href="style.css" /> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <style> | |
| :root { | |
| --primary: #6366f1; | |
| --primary-dark: #4f46e5; | |
| } | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background-color: #f9fafb; | |
| } | |
| .sidebar { | |
| width: 350px; | |
| height: 100vh; | |
| position: fixed; | |
| right: 0; | |
| top: 0; | |
| background: white; | |
| padding: 1.5rem; | |
| border-left: 1px solid #e5e7eb; | |
| overflow-y: auto; | |
| box-shadow: -2px 0 10px rgba(0,0,0,0.05); | |
| } | |
| .main-content { | |
| margin-right: 370px; | |
| padding: 2rem; | |
| } | |
| .chat-message { | |
| margin-bottom: 1rem; | |
| padding: 0.75rem 1rem; | |
| border-radius: 0.5rem; | |
| font-size: 0.9rem; | |
| line-height: 1.5; | |
| } | |
| .user-message { | |
| background: #eef2ff; | |
| color: var(--primary-dark); | |
| } | |
| .ai-message { | |
| background: #f8fafc; | |
| border: 1px solid #e5e7eb; | |
| } | |
| .api-key-input { | |
| margin-bottom: 1.5rem; | |
| padding: 1rem; | |
| background: #f8fafc; | |
| border-radius: 0.5rem; | |
| } | |
| .card { | |
| background: white; | |
| border-radius: 0.75rem; | |
| padding: 1.5rem; | |
| margin-bottom: 1.5rem; | |
| box-shadow: 0 1px 3px rgba(0,0,0,0.1); | |
| border: 1px solid #e5e7eb; | |
| } | |
| button { | |
| background: var(--primary); | |
| color: white; | |
| padding: 0.5rem 1rem; | |
| border-radius: 0.375rem; | |
| font-weight: 500; | |
| transition: all 0.2s; | |
| border: none; | |
| cursor: pointer; | |
| } | |
| button:hover { | |
| background: var(--primary-dark); | |
| } | |
| input, textarea, select { | |
| width: 100%; | |
| padding: 0.5rem 0.75rem; | |
| border-radius: 0.375rem; | |
| border: 1px solid #e5e7eb; | |
| margin-bottom: 1rem; | |
| } | |
| .file-explorer { | |
| border: 1px dashed #e5e7eb; | |
| border-radius: 0.5rem; | |
| padding: 1rem; | |
| background: #f8fafc; | |
| min-height: 200px; | |
| } | |
| .file-item { | |
| display: flex; | |
| align-items: center; | |
| padding: 0.5rem; | |
| border-radius: 0.25rem; | |
| margin-bottom: 0.25rem; | |
| } | |
| .file-item:hover { | |
| background: #eef2ff; | |
| } | |
| @keyframes bounce { | |
| 0%, 100% { transform: translateY(0); } | |
| 50% { transform: translateY(-3px); } | |
| } | |
| .animate-bounce { | |
| animation: bounce 0.6s infinite; | |
| } | |
| .file-icon { | |
| margin-right: 0.5rem; | |
| color: #6b7280; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="sidebar"> | |
| <h2>AI Assistant</h2> | |
| <div class="api-key-input"> | |
| <label for="api-key">Enter Gemini API Key:</label> | |
| <input type="password" id="api-key" placeholder="Your Gemini API key"> | |
| <button id="save-key">Save</button> | |
| </div> | |
| <div id="chat-container"> | |
| <div class="chat-message ai-message"> | |
| Hello! I'm here to help you build your AI training dataset. What would you like to generate today? | |
| </div> | |
| </div> | |
| <div class="chat-input"> | |
| <input type="text" id="user-input" placeholder="Ask me anything..."> | |
| <button id="send-message">Send</button> | |
| </div> | |
| </div> | |
| <div class="main-content"> | |
| <h1 class="text-3xl font-bold text-gray-800 mb-6">AI Dataset Generator</h1> | |
| <div class="card"> | |
| <h2 class="text-xl font-semibold mb-4">Configuration</h2> | |
| <div class="form-group"> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Dataset Type:</label> | |
| <select id="dataset-type" class="focus:ring-indigo-500 focus:border-indigo-500"> | |
| <option value="conversational">Conversational</option> | |
| <option value="qna">Q&A</option> | |
| <option value="code">Code Examples</option> | |
| <option value="database">AI Database</option> | |
| </select> | |
| </div> | |
| <div class="form-group"> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">Prompt:</label> | |
| <textarea id="dataset-prompt" rows="4" class="focus:ring-indigo-500 focus:border-indigo-500" | |
| placeholder="Describe what you want in your dataset..."></textarea> | |
| </div> | |
| <button id="generate-btn" class="flex items-center"> | |
| <i data-feather="zap" class="mr-2 w-4 h-4"></i> Generate Dataset | |
| </button> | |
| </div> | |
| <div class="card" id="output-section" style="display:none;"> | |
| <h2 class="text-xl font-semibold mb-4">Generated Output</h2> | |
| <div class="file-explorer mb-4" id="file-explorer"> | |
| <div class="file-item"> | |
| <i data-feather="folder" class="file-icon"></i> | |
| <span>dataset/</span> | |
| </div> | |
| <div class="file-item"> | |
| <i data-feather="file-text" class="file-icon"></i> | |
| <span>train.py</span> | |
| </div> | |
| <div class="file-item"> | |
| <i data-feather="file-text" class="file-icon"></i> | |
| <span>requirements.txt</span> | |
| </div> | |
| <div class="file-item"> | |
| <i data-feather="file-text" class="file-icon"></i> | |
| <span>config.json</span> | |
| </div> | |
| <div class="file-item"> | |
| <i data-feather="file-text" class="file-icon"></i> | |
| <span>dataset.json</span> | |
| </div> | |
| <div class="file-item"> | |
| <i data-feather="file-text" class="file-icon"></i> | |
| <span>notebook.ipynb</span> | |
| </div> | |
| </div> | |
| <div class="flex gap-2 mb-4"> | |
| <button id="export-ipynb" class="flex items-center"> | |
| <i data-feather="download" class="mr-2 w-4 h-4"></i> Export as Jupyter Notebook | |
| </button> | |
| <button id="export-zip" class="flex items-center"> | |
| <i data-feather="download" class="mr-2 w-4 h-4"></i> Export as ZIP | |
| </button> | |
| </div> | |
| <div class="training-instructions bg-gray-50 p-4 rounded-lg"> | |
| <h3 class="font-medium text-gray-800 mb-2">Training Instructions</h3> | |
| <div class="bg-gray-800 text-white p-3 rounded-md font-mono text-sm overflow-x-auto"> | |
| <p># Install dependencies</p> | |
| <p class="text-green-400">pip install -r requirements.txt</p> | |
| <p class="mt-2"># Start training</p> | |
| <p class="text-green-400">python train.py</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Initialize feather icons | |
| document.addEventListener('DOMContentLoaded', function() { | |
| feather.replace(); | |
| // Export handlers | |
| document.getElementById('export-ipynb').addEventListener('click', async function() { | |
| const apiKey = document.getElementById('api-key').value; | |
| if (!apiKey) { | |
| alert('Please enter your Gemini API key first'); | |
| return; | |
| } | |
| const btn = this; | |
| btn.disabled = true; | |
| btn.innerHTML = '<i data-feather="loader" class="mr-2 w-4 h-4 animate-spin"></i> Preparing...'; | |
| feather.replace(); | |
| // Simulate file generation and download | |
| await new Promise(resolve => setTimeout(resolve, 1000)); | |
| const datasetType = document.getElementById('dataset-type').value; | |
| const content = `# AI Dataset Notebook (${datasetType})\n` + | |
| `# Generated by AI Dataset Generator\n\n` + | |
| `!pip install -r requirements.txt\n\n` + | |
| `import json\n` + | |
| `from train import train_model\n\n` + | |
| `# Load your dataset\n` + | |
| `with open('dataset/${datasetType}_dataset.json') as f:\n` + | |
| ` data = json.load(f)\n\n` + | |
| `# Start training\n` + | |
| `train_model(data)`; | |
| const blob = new Blob([content], { type: 'text/x-python' | |
| }); | |
| // Helper function to download individual files | |
| function downloadFile(filename, content) { | |
| const blob = new Blob([decodeURIComponent(content)], { type: 'text/plain' }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = filename; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| } | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = `${datasetType}_notebook.ipynb`; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| btn.disabled = false; | |
| btn.innerHTML = '<i data-feather="download" class="mr-2 w-4 h-4"></i> Export as Jupyter Notebook'; | |
| feather.replace(); | |
| }); | |
| document.getElementById('export-zip').addEventListener('click', async function() { | |
| const apiKey = document.getElementById('api-key').value; | |
| if (!apiKey) { | |
| alert('Please enter your Gemini API key first'); | |
| return; | |
| } | |
| const btn = this; | |
| btn.disabled = true; | |
| btn.innerHTML = '<i data-feather="loader" class="mr-2 w-4 h-4 animate-spin"></i> Packaging...'; | |
| feather.replace(); | |
| // Simulate ZIP generation (would use JSZip in real implementation) | |
| await new Promise(resolve => setTimeout(resolve, 1500)); | |
| const datasetType = document.getElementById('dataset-type').value; | |
| alert(`Your ${datasetType} dataset and training scripts have been packaged as ZIP.\n` + | |
| `To use: \n1. Unzip the package\n` + | |
| `2. Run: pip install -r requirements.txt\n` + | |
| `3. Run: python train.py`); | |
| btn.disabled = false; | |
| btn.innerHTML = '<i data-feather="download" class="mr-2 w-4 h-4"></i> Export as ZIP'; | |
| feather.replace(); | |
| }); | |
| }); | |
| document.getElementById('generate-btn').addEventListener('click', async function() { | |
| const apiKey = document.getElementById('api-key').value; | |
| if (!apiKey) { | |
| alert('Please enter your Gemini API key first'); | |
| return; | |
| } | |
| const btn = this; | |
| btn.disabled = true; | |
| btn.innerHTML = '<i data-feather="loader" class="mr-2 w-4 h-4 animate-spin"></i> Generating...'; | |
| feather.replace(); | |
| const datasetType = document.getElementById('dataset-type').value; | |
| const prompt = document.getElementById('dataset-prompt').value; | |
| // Show output section immediately with loading state | |
| document.getElementById('output-section').style.display = 'block'; | |
| document.getElementById('file-explorer').innerHTML = ` | |
| <div class="file-item"> | |
| <i data-feather="loader" class="file-icon animate-spin"></i> | |
| <span>Generating files...</span> | |
| </div> | |
| `; | |
| feather.replace(); | |
| try { | |
| // Show progress bar | |
| const progressBar = document.createElement('div'); | |
| progressBar.className = 'w-full bg-gray-200 rounded-full h-2.5 mb-4'; | |
| progressBar.innerHTML = ` | |
| <div id="generation-progress" class="bg-indigo-600 h-2.5 rounded-full" style="width: 0%"></div> | |
| `; | |
| document.getElementById('output-section').prepend(progressBar); | |
| // Simulate progress updates | |
| let progress = 0; | |
| const progressInterval = setInterval(() => { | |
| progress += 5; | |
| document.getElementById('generation-progress').style.width = `${progress}%`; | |
| if (progress >= 100) { | |
| clearInterval(progressInterval); | |
| } | |
| }, 150); | |
| // Call Gemini API to generate the dataset | |
| const response = await fetch('https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=' + apiKey, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ | |
| contents: [{ | |
| parts: [{ | |
| text: `Generate a ${datasetType} AI training dataset about: ${prompt}.\n` + | |
| `Provide Python code for training this dataset in a structured format.\n` + | |
| `Include all necessary files structure.\n` + | |
| `Output should be in JSON format with files and content.\n` + | |
| `For AI Database type, include SQL schema, sample queries and data generation scripts.\n` + | |
| `Example format: {"files": {"train.py": "python code...", "dataset.json": "json content...", "schema.sql": "SQL schema..."}}` | |
| }] | |
| }] | |
| }) | |
| }); | |
| const data = await response.json(); | |
| if (!response.ok) throw new Error(data.error?.message || 'Failed to generate dataset'); | |
| // Process the API response | |
| let generatedContent; | |
| try { | |
| if (data.candidates && data.candidates[0].content.parts[0].text) { | |
| generatedContent = JSON.parse(data.candidates[0].content.parts[0].text); | |
| } else { | |
| throw new Error('Invalid API response format'); | |
| } | |
| } catch (e) { | |
| console.error('Error parsing response:', e); | |
| throw new Error('Failed to parse generated content'); | |
| } | |
| // Build files list | |
| let filesHTML = ''; | |
| if (generatedContent && generatedContent.files) { | |
| for (const [file, content] of Object.entries(generatedContent.files)) { | |
| filesHTML += ` | |
| <div class="file-item" data-file="${file}" data-content="${encodeURIComponent(content)}"> | |
| <i data-feather="${file.endsWith('/') ? 'folder' : 'file-text'}" class="file-icon"></i> | |
| <span>${file}</span> | |
| <span class="ml-auto text-xs text-green-500">✓ Generated</span> | |
| </div> | |
| `; | |
| } | |
| // Update UI with generated files | |
| document.getElementById('file-explorer').innerHTML = filesHTML; | |
| // Add file click handlers | |
| document.querySelectorAll('.file-item').forEach(item => { | |
| item.addEventListener('click', function() { | |
| const file = this.getAttribute('data-file'); | |
| const content = decodeURIComponent(this.getAttribute('data-content')); | |
| // Create a modal to show file content | |
| const modal = document.createElement('div'); | |
| modal.className = 'fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4'; | |
| modal.innerHTML = ` | |
| <div class="bg-white rounded-lg w-full max-w-2xl max-h-[80vh] overflow-hidden flex flex-col"> | |
| <div class="p-4 border-b flex justify-between items-center"> | |
| <h3 class="font-medium">${file}</h3> | |
| <button class="text-gray-500 hover:text-gray-700" onclick="this.parentElement.parentElement.parentElement.remove()"> | |
| <i data-feather="x"></i> | |
| </button> | |
| </div> | |
| <pre class="p-4 bg-gray-50 text-sm overflow-auto flex-1">${content}</pre> | |
| <div class="p-4 border-t flex justify-end"> | |
| <button class="bg-indigo-600 text-white px-4 py-2 rounded" | |
| onclick="downloadFile('${file}', '${encodeURIComponent(content)}')"> | |
| <i data-feather="download" class="mr-2"></i> Download | |
| </button> | |
| </div> | |
| </div> | |
| `; | |
| document.body.appendChild(modal); | |
| feather.replace(); | |
| }); | |
| }); | |
| // Add to chat | |
| const chatContainer = document.getElementById('chat-container'); | |
| const userMessage = document.createElement('div'); | |
| userMessage.className = 'chat-message user-message'; | |
| userMessage.innerHTML = `I want to generate a <strong>${datasetType}</strong> dataset about: <em>${prompt}</em>`; | |
| chatContainer.appendChild(userMessage); | |
| const aiMessage = document.createElement('div'); | |
| aiMessage.className = 'chat-message ai-message'; | |
| aiMessage.innerHTML = ` | |
| <div class="flex items-start mb-2"> | |
| <i data-feather="check-circle" class="text-green-500 mr-2 w-4 h-4"></i> | |
| <span>Successfully generated ${datasetType} dataset!</span> | |
| </div> | |
| <p>You can now explore the generated files and export them for training.</p> | |
| `; | |
| chatContainer.appendChild(aiMessage); | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| } else { | |
| throw new Error('No files were generated'); | |
| } | |
| } catch (error) { | |
| console.error('Generation error:', error); | |
| alert(`Error generating dataset: ${error.message}`); | |
| } finally { | |
| btn.disabled = false; | |
| btn.innerHTML = '<i data-feather="zap" class="mr-2 w-4 h-4"></i> Generate Dataset'; | |
| feather.replace(); | |
| } | |
| }); | |
| document.getElementById('send-message').addEventListener('click', async function() { | |
| const apiKey = document.getElementById('api-key').value; | |
| if (!apiKey) { | |
| alert('Please enter your Gemini API key first'); | |
| return; | |
| } | |
| const input = document.getElementById('user-input').value; | |
| if (!input) return; | |
| const btn = this; | |
| btn.disabled = true; | |
| const chatContainer = document.getElementById('chat-container'); | |
| const userMessage = document.createElement('div'); | |
| userMessage.className = 'chat-message user-message'; | |
| userMessage.textContent = input; | |
| chatContainer.appendChild(userMessage); | |
| document.getElementById('user-input').value = ''; | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| // Call Gemini API for AI response | |
| // Show typing indicator | |
| const typingIndicator = document.createElement('div'); | |
| typingIndicator.className = 'chat-message ai-message flex items-center'; | |
| typingIndicator.innerHTML = ` | |
| <div class="flex space-x-1"> | |
| <div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div> | |
| <div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style="animation-delay: 0.2s"></div> | |
| <div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style="animation-delay: 0.4s"></div> | |
| </div> | |
| <span class="ml-2 text-sm text-gray-500">Generating response...</span> | |
| `; | |
| chatContainer.appendChild(typingIndicator); | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| try { | |
| const aiResponse = await fetch('https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=' + apiKey, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify({ | |
| contents: [{ | |
| parts: [{ | |
| text: `The user requested a ${datasetType} dataset about: ${prompt}.\n` + | |
| `You have generated the dataset successfully.\n` + | |
| `Provide a helpful response explaining how to use this dataset for AI training,\n` + | |
| `including any important notes about the data structure and training parameters.` | |
| }] | |
| }] | |
| }) | |
| }); | |
| const aiData = await aiResponse.json(); | |
| if (!aiResponse.ok) throw new Error(aiData.error?.message || 'Failed to get AI response'); | |
| const aiMessageContent = aiData.candidates[0].content.parts[0].text; | |
| chatContainer.appendChild(typingIndicator); | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| // Simulate response delay | |
| await new Promise(resolve => setTimeout(resolve, 1500)); | |
| chatContainer.removeChild(typingIndicator); | |
| const aiMessage = document.createElement('div'); | |
| aiMessage.className = 'chat-message ai-message'; | |
| aiMessage.innerHTML = aiMessageContent; | |
| chatContainer.appendChild(aiMessage); | |
| feather.replace(); | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| btn.disabled = false; | |
| }); | |
| </script> | |
| </body> | |
| </html> |