Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>LaMini-LM Text Generator</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <style> | |
| .spinner { | |
| display: none; | |
| border: 4px solid rgba(0, 0, 0, 0.1); | |
| border-left-color: #3b82f6; | |
| border-radius: 50%; | |
| width: 24px; | |
| height: 24px; | |
| animation: spin 1s linear infinite; | |
| } | |
| @keyframes spin { | |
| to { transform: rotate(360deg); } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100 min-h-screen flex items-center justify-center px-4"> | |
| <div class="max-w-lg w-full bg-white rounded-xl shadow-lg p-6"> | |
| <h1 class="text-2xl font-bold text-center text-gray-800 mb-6">LaMini-LM Text Generator</h1> | |
| <form id="generate-form" class="space-y-4"> | |
| <div> | |
| <label for="instruction" class="block text-sm font-medium text-gray-700">Instruction</label> | |
| <textarea | |
| id="instruction" | |
| class="mt-1 w-full p-3 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" | |
| rows="4" | |
| placeholder="e.g., Tell me about camels" | |
| required | |
| ></textarea> | |
| </div> | |
| <div class="grid grid-cols-1 sm:grid-cols-3 gap-4"> | |
| <div> | |
| <label for="max-length" class="block text-sm font-medium text-gray-700">Max Length (10–500)</label> | |
| <input | |
| id="max-length" | |
| type="number" | |
| min="10" | |
| max="500" | |
| value="100" | |
| class="mt-1 w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" | |
| required | |
| /> | |
| </div> | |
| <div> | |
| <label for="temperature" class="block text-sm font-medium text-gray-700">Temperature (0–2)</label> | |
| <input | |
| id="temperature" | |
| type="number" | |
| step="0.1" | |
| min="0" | |
| max="2" | |
| value="1.0" | |
| class="mt-1 w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" | |
| required | |
| /> | |
| </div> | |
| <div> | |
| <label for="top-p" class="block text-sm font-medium text-gray-700">Top P (0–1)</label> | |
| <input | |
| id="top-p" | |
| type="number" | |
| step="0.1" | |
| min="0" | |
| max="1" | |
| value="0.9" | |
| class="mt-1 w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" | |
| required | |
| /> | |
| </div> | |
| </div> | |
| <button | |
| type="submit" | |
| class="w-full py-2 px-4 bg-gradient-to-r from-blue-500 to-indigo-600 text-white font-semibold rounded-md hover:from-blue-600 hover:to-indigo-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 flex items-center justify-center" | |
| > | |
| <span id="button-text">Generate Text</span> | |
| <span id="spinner" class="spinner ml-2"></span> | |
| </button> | |
| </form> | |
| <div id="error" class="mt-4 hidden p-3 bg-red-100 text-red-700 rounded-md"></div> | |
| <div id="result" class="mt-4 hidden p-4 bg-gray-50 rounded-md"> | |
| <h2 class="text-lg font-semibold text-gray-800">Generated Text:</h2> | |
| <p id="generated-text" class="mt-2 text-gray-600"></p> | |
| </div> | |
| </div> | |
| <script> | |
| const form = document.getElementById('generate-form'); | |
| const errorDiv = document.getElementById('error'); | |
| const resultDiv = document.getElementById('result'); | |
| const generatedText = document.getElementById('generated-text'); | |
| const buttonText = document.getElementById('button-text'); | |
| const spinner = document.getElementById('spinner'); | |
| form.addEventListener('submit', async (e) => { | |
| e.preventDefault(); | |
| errorDiv.classList.add('hidden'); | |
| resultDiv.classList.add('hidden'); | |
| buttonText.textContent = 'Generating...'; | |
| spinner.style.display = 'block'; | |
| const instruction = document.getElementById('instruction').value; | |
| const maxLength = Number(document.getElementById('max-length').value); | |
| const temperature = Number(document.getElementById('temperature').value); | |
| const topP = Number(document.getElementById('top-p').value); | |
| if (!instruction.trim()) { | |
| showError('Instruction cannot be empty.'); | |
| return; | |
| } | |
| if (maxLength < 10 || maxLength > 500) { | |
| showError('Max length must be between 10 and 500.'); | |
| return; | |
| } | |
| if (temperature <= 0 || temperature > 2) { | |
| showError('Temperature must be between 0 and 2.'); | |
| return; | |
| } | |
| if (topP <= 0 || topP > 1) { | |
| showError('Top P must be between 0 and 1.'); | |
| return; | |
| } | |
| try { | |
| const response = await fetch('/api/generate', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| // Add Authorization header if Space is private | |
| // 'Authorization': 'Bearer <your_hf_token>' | |
| }, | |
| body: JSON.stringify({ | |
| instruction, | |
| max_length: maxLength, | |
| temperature, | |
| top_p: topP, | |
| }), | |
| }); | |
| const data = await response.json(); | |
| if (response.ok) { | |
| resultDiv.classList.remove('hidden'); | |
| generatedText.textContent = data.generated_text; | |
| } else { | |
| showError(data.detail?.[0]?.msg || data.detail || 'Failed to generate text.'); | |
| } | |
| } catch (err) { | |
| showError('Error connecting to the API. Please try again.'); | |
| } finally { | |
| buttonText.textContent = 'Generate Text'; | |
| spinner.style.display = 'none'; | |
| } | |
| }); | |
| function showError(message) { | |
| errorDiv.textContent = message; | |
| errorDiv.classList.remove('hidden'); | |
| buttonText.textContent = 'Generate Text'; | |
| spinner.style.display = 'none'; | |
| } | |
| </script> | |
| </body> | |
| </html> | |