Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>DeepSeek AI Server</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://js.puter.com/v2/"></script> | |
| <style> | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background-color: #f3f4f6; | |
| } | |
| #output { | |
| white-space: pre-wrap; | |
| word-wrap: break-word; | |
| } | |
| #apiResponse { | |
| font-family: monospace; | |
| white-space: pre; | |
| overflow-x: auto; | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen flex flex-col items-center justify-center p-4"> | |
| <div class="w-full max-w-4xl bg-white shadow-lg rounded-lg p-6"> | |
| <h1 class="text-2xl font-bold text-gray-800 mb-4 text-center">DeepSeek AI Server</h1> | |
| <!-- Web Interface Tab --> | |
| <div class="mb-6" id="webInterface"> | |
| <div class="mb-4"> | |
| <input | |
| type="text" | |
| id="query" | |
| placeholder="Enter your query (e.g., Explain dark matter)" | |
| class="w-full p-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" | |
| > | |
| <button | |
| id="submit" | |
| class="mt-2 w-full bg-blue-600 text-white p-3 rounded-lg hover:bg-blue-700 transition" | |
| > | |
| Get AI Response | |
| </button> | |
| </div> | |
| <div id="output" class="bg-gray-100 p-4 rounded-lg text-gray-800 min-h-32"></div> | |
| </div> | |
| <!-- API Tester Tab --> | |
| <div class="mb-6 hidden" id="apiTester"> | |
| <div class="mb-4"> | |
| <h2 class="text-lg font-semibold mb-2">Test API Endpoint</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">API Request</label> | |
| <textarea | |
| id="apiRequest" | |
| class="w-full p-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 h-32" | |
| placeholder='{"query": "Your question here", "model": "gpt-4o"}' | |
| ></textarea> | |
| <button | |
| id="apiSubmit" | |
| class="mt-2 w-full bg-green-600 text-white p-3 rounded-lg hover:bg-green-700 transition" | |
| > | |
| Send API Request | |
| </button> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-gray-700 mb-1">API Response</label> | |
| <div id="apiResponse" class="w-full p-3 border rounded-lg bg-gray-100 h-32 overflow-auto"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-100 p-4 rounded-lg"> | |
| <h2 class="text-lg font-semibold mb-2">API Documentation</h2> | |
| <div class="space-y-3"> | |
| <div> | |
| <h3 class="font-medium">Endpoint</h3> | |
| <code class="bg-gray-200 p-1 rounded text-sm">POST /api/ask</code> | |
| </div> | |
| <div> | |
| <h3 class="font-medium">Request Body</h3> | |
| <pre class="bg-gray-200 p-2 rounded text-sm overflow-x-auto"> | |
| { | |
| "query": "string", // Required | |
| "model": "string" // Optional (default: "gpt-4o") | |
| }</pre> | |
| </div> | |
| <div> | |
| <h3 class="font-medium">Example Usage</h3> | |
| <pre class="bg-gray-200 p-2 rounded text-sm overflow-x-auto"> | |
| fetch('/api/ask', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify({ | |
| query: "Explain quantum computing", | |
| model: "gpt-4o" | |
| }) | |
| }) | |
| .then(response => response.text()) | |
| .then(data => console.log(data));</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Tab Navigation --> | |
| <div class="flex border-b"> | |
| <button | |
| class="px-4 py-2 font-medium text-blue-600 border-b-2 border-blue-600" | |
| onclick="showTab('webInterface')" | |
| > | |
| Web Interface | |
| </button> | |
| <button | |
| class="px-4 py-2 font-medium text-gray-500 hover:text-gray-700" | |
| onclick="showTab('apiTester')" | |
| > | |
| API Tester | |
| </button> | |
| </div> | |
| </div> | |
| <script> | |
| // Tab navigation | |
| function showTab(tabId) { | |
| document.getElementById('webInterface').classList.add('hidden'); | |
| document.getElementById('apiTester').classList.add('hidden'); | |
| document.getElementById(tabId).classList.remove('hidden'); | |
| // Update active tab styling | |
| const tabs = document.querySelectorAll('.flex.border-b button'); | |
| tabs.forEach(tab => { | |
| tab.classList.remove('text-blue-600', 'border-b-2', 'border-blue-600'); | |
| tab.classList.add('text-gray-500', 'hover:text-gray-700'); | |
| }); | |
| event.currentTarget.classList.add('text-blue-600', 'border-b-2', 'border-blue-600'); | |
| event.currentTarget.classList.remove('text-gray-500', 'hover:text-gray-700'); | |
| } | |
| // Web Interface Functionality | |
| async function streamResponse(query) { | |
| const outputDiv = document.getElementById('output'); | |
| outputDiv.innerHTML = ''; // Clear previous output | |
| const submitButton = document.getElementById('submit'); | |
| submitButton.disabled = true; // Disable button during processing | |
| try { | |
| outputDiv.innerHTML += '<h2 class="text-lg font-semibold text-blue-600">AI Response:</h2>'; | |
| // Using Puter SDK directly (client-side) | |
| const chatResponse = await puter.ai.chat( | |
| query, | |
| { | |
| model: 'gpt-4o', | |
| stream: true | |
| } | |
| ); | |
| for await (const part of chatResponse) { | |
| if (part?.text) { | |
| outputDiv.innerHTML += part.text; | |
| outputDiv.scrollTop = outputDiv.scrollHeight; // Auto-scroll to bottom | |
| } | |
| } | |
| } catch (error) { | |
| outputDiv.innerHTML += `<p class="text-red-600">Error: ${error.message}</p>`; | |
| } finally { | |
| submitButton.disabled = false; // Re-enable button | |
| } | |
| } | |
| // API Tester Functionality | |
| async function testApi() { | |
| const apiRequest = document.getElementById('apiRequest').value.trim(); | |
| const apiResponseDiv = document.getElementById('apiResponse'); | |
| const apiSubmitButton = document.getElementById('apiSubmit'); | |
| apiResponseDiv.textContent = ''; | |
| apiSubmitButton.disabled = true; | |
| try { | |
| if (!apiRequest) { | |
| throw new Error('Please enter a valid JSON request'); | |
| } | |
| const requestObj = JSON.parse(apiRequest); | |
| if (!requestObj.query) { | |
| throw new Error('Request must include a "query" field'); | |
| } | |
| // Using Puter SDK directly (client-side) | |
| const response = await puter.ai.chat( | |
| requestObj.query, | |
| { | |
| model: requestObj.model || 'gpt-4o', | |
| stream: false | |
| } | |
| ); | |
| apiResponseDiv.textContent = JSON.stringify(response, null, 2); | |
| } catch (error) { | |
| apiResponseDiv.textContent = `Error: ${error.message}`; | |
| } finally { | |
| apiSubmitButton.disabled = false; | |
| } | |
| } | |
| // Event listeners | |
| document.getElementById('submit').addEventListener('click', () => { | |
| const query = document.getElementById('query').value.trim(); | |
| if (query) { | |
| streamResponse(query); | |
| } else { | |
| document.getElementById('output').innerHTML = '<p class="text-red-600">Please enter a query.</p>'; | |
| } | |
| }); | |
| document.getElementById('query').addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') { | |
| document.getElementById('submit').click(); | |
| } | |
| }); | |
| document.getElementById('apiSubmit').addEventListener('click', testApi); | |
| document.getElementById('apiRequest').addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter' && e.ctrlKey) { | |
| testApi(); | |
| } | |
| }); | |
| // Initialize with web interface shown | |
| showTab('webInterface'); | |
| </script> | |
| </body> | |
| </html> |