Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>API Ingestion Tool for LLMs</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .animate-pulse-slow { | |
| animation: pulse 2.5s cubic-bezier(0.4, 0, 0.6, 1) infinite; | |
| } | |
| @keyframes pulse { | |
| 0%, 100% { opacity: 1; } | |
| 50% { opacity: 0.5; } | |
| } | |
| .scrollbar-hide::-webkit-scrollbar { | |
| display: none; | |
| } | |
| .json-viewer { | |
| font-family: 'Courier New', monospace; | |
| font-size: 0.9rem; | |
| background-color: #111827; | |
| border-radius: 0.5rem; | |
| } | |
| body { | |
| background-color: #181818; | |
| color: #e5e7eb; | |
| } | |
| .bg-white { | |
| background-color: #1f2937; | |
| } | |
| .text-gray-800 { | |
| color: #e5e7eb; | |
| } | |
| .text-gray-700 { | |
| color: #d1d5db; | |
| } | |
| .text-gray-600 { | |
| color: #9ca3af; | |
| } | |
| .border-gray-200, .border-gray-300 { | |
| border-color: #374151; | |
| } | |
| .bg-gray-100 { | |
| background-color: #111827; | |
| } | |
| .bg-gray-50 { | |
| background-color: #1f2937; | |
| } | |
| .bg-blue-50 { | |
| background-color: #1e3a8a; | |
| } | |
| .bg-indigo-50 { | |
| background-color: #3730a3; | |
| } | |
| .bg-purple-50 { | |
| background-color: #5b21b6; | |
| } | |
| .bg-pink-50 { | |
| background-color: #9d174d; | |
| } | |
| .bg-amber-50 { | |
| background-color: #78350f; | |
| } | |
| .bg-yellow-100 { | |
| background-color: #854d0e; | |
| } | |
| .bg-indigo-100 { | |
| background-color: #3730a3; | |
| } | |
| .bg-indigo-50 { | |
| background-color: #312e81; | |
| } | |
| .text-blue-700, .text-purple-700, .text-indigo-700, .text-pink-700, .text-yellow-800 { | |
| color: #e5e7eb; | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen"> | |
| <div class="container mx-auto px-4 py-8 max-w-5xl"> | |
| <!-- Header --> | |
| <header class="mb-8 text-center"> | |
| <h1 class="text-3xl font-bold"> | |
| <span class="text-blue-400">API</span> Ingestion Tool <span class="text-gray-400">for LLMs</span> | |
| </h1> | |
| <p class="text-gray-400 mt-2">Automate API documentation ingestion for your large language models</p> | |
| </header> | |
| <!-- Main Content --> | |
| <div class="grid grid-cols-1 md:grid-cols-5 gap-6"> | |
| <!-- Left Panel - API Configuration --> | |
| <div class="md:col-span-3 space-y-6"> | |
| <!-- API URL Input --> | |
| <div class="rounded-lg shadow p-6 bg-gray-800"> | |
| <h2 class="text-xl font-semibold mb-4 flex items-center"> | |
| <i class="fas fa-link mr-2 text-blue-400"></i> | |
| API Configuration | |
| </h2> | |
| <div class="space-y-4"> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">API Endpoint URL</label> | |
| <div class="flex"> | |
| <input | |
| type="text" | |
| placeholder="https://api.example.com/v1" | |
| class="flex-grow px-4 py-2 border border-gray-600 rounded-l-md focus:ring-blue-500 focus:border-blue-500 bg-gray-700 text-white" | |
| id="apiUrl"> | |
| <button | |
| class="px-4 py-2 bg-blue-600 text-white rounded-r-md hover:bg-blue-700 transition" | |
| id="detectBtn"> | |
| <i class="fas fa-search mr-1"></i> Detect | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Authentication Section --> | |
| <div class="pt-4 border-t border-gray-600"> | |
| <h3 class="text-lg font-medium mb-3 flex items-center"> | |
| <i class="fas fa-key mr-2 text-yellow-400"></i> | |
| Authentication | |
| </h3> | |
| <div class="space-y-4"> | |
| <button id="detectAuthBtn" class="w-full py-2 px-4 bg-yellow-800 text-yellow-100 rounded-md hover:bg-yellow-700 transition flex items-center justify-center"> | |
| <i class="fas fa-search mr-2"></i> Detect Authentication Method | |
| </button> | |
| <div id="authOptions" class="hidden space-y-3"> | |
| <div class="flex items-center"> | |
| <input type="radio" name="authType" id="noAuth" value="none" class="focus:ring-blue-500 h-4 w-4 text-blue-600 border-gray-500"> | |
| <label for="noAuth" class="ml-2 block text-sm">No Authentication</label> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="radio" name="authType" id="apiKey" value="apiKey" class="focus:ring-blue-500 h-4 w-4 text-blue-600 border-gray-500"> | |
| <label for="apiKey" class="ml-2 block text-sm">API Key</label> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="radio" name="authType" id="oauth" value="oauth" class="focus:ring-blue-500 h-4 w-4 text-blue-600 border-gray-500"> | |
| <label for="oauth" class="ml-2 block text-sm">OAuth</label> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="radio" name="authType" id="basic" value="basic" class="focus:ring-blue-500 h-4 w-4 text-blue-600 border-gray-500"> | |
| <label for="basic" class="ml-2 block text-sm">Basic Auth</label> | |
| </div> | |
| </div> | |
| <div id="authDetails" class="hidden space-y-4"> | |
| <!-- API Key Auth --> | |
| <div id="apiKeyAuth" class="hidden space-y-2"> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Key Name</label> | |
| <input type="text" placeholder="X-API-KEY" class="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-700 text-white"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">API Key</label> | |
| <input type="password" placeholder="Your API Key" class="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-700 text-white"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Location</label> | |
| <select class="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-700 text-white"> | |
| <option>Header</option> | |
| <option>Query Parameter</option> | |
| </select> | |
| </div> | |
| </div> | |
| <!-- OAuth Auth --> | |
| <div id="oauthAuth" class="hidden space-y-2"> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Client ID</label> | |
| <input type="text" placeholder="Your Client ID" class="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-700 text-white"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Client Secret</label> | |
| <input type="password" placeholder="Your Client Secret" class="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-700 text-white"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Token URL</label> | |
| <input type="text" placeholder="https://api.example.com/oauth/token" class="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-700 text-white"> | |
| </div> | |
| </div> | |
| <!-- Basic Auth --> | |
| <div id="basicAuth" class="hidden space-y-2"> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Username</label> | |
| <input type="text" placeholder="Your username" class="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-700 text-white"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Password</label> | |
| <input type="password" placeholder="Your password" class="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-700 text-white"> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- API Options --> | |
| <div class="pt-4 border-t border-gray-600"> | |
| <h3 class="text-lg font-medium mb-3 flex items-center"> | |
| <i class="fas fa-cog mr-2 text-purple-400"></i> | |
| API Options | |
| </h3> | |
| <div class="space-y-4"> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Maximum Depth</label> | |
| <select class="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-700 text-white"> | |
| <option value="1">Shallow (1 level)</option> | |
| <option value="2" selected>Standard (2 levels)</option> | |
| <option value="3">Deep (3 levels)</option> | |
| <option value="0">Complete (all levels)</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium mb-1">Ingestion Approach</label> | |
| <select class="w-full px-4 py-2 border border-gray-600 rounded-md bg-gray-700 text-white"> | |
| <option value="documentation">Documentation Only</option> | |
| <option value="documentation+examples" selected>Documentation + Examples</option> | |
| <option value="documentation+examples+code">Plus Source Code Analysis</option> | |
| </select> | |
| </div> | |
| <div class="flex items-center"> | |
| <input type="checkbox" id="paginationCheck" class="focus:ring-blue-500 h-4 w-4 text-blue-600 border-gray-500"> | |
| <label for="paginationCheck" class="ml-2 block text-sm">Include Pagination Logic</label> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Detection Buttons --> | |
| <div class="rounded-lg shadow p-6 bg-gray-800"> | |
| <h2 class="text-xl font-semibold mb-4 flex items-center"> | |
| <i class="fas fa-magic mr-2 text-green-400"></i> | |
| Auto-Detection | |
| </h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-3"> | |
| <button id="detectMethodsBtn" class="flex items-center justify-center px-4 py-3 bg-blue-900 text-blue-100 rounded-md hover:bg-blue-800 transition"> | |
| <i class="fas fa-random mr-2"></i> Detect Call Methods | |
| </button> | |
| <button id="detectProtocolBtn" class="flex items-center justify-center px-4 py-3 bg-purple-900 text-purple-100 rounded-md hover:bg-purple-800 transition"> | |
| <i class="fas fa-plug mr-2"></i> Detect Protocol | |
| </button> | |
| <button id="detectStructureBtn" class="flex items-center justify-center px-4 py-3 bg-indigo-900 text-indigo-100 rounded-md hover:bg-indigo-800 transition"> | |
| <i class="fas fa-sitemap mr-2"></i> Detect Structure | |
| </button> | |
| <button id="detectPaginationBtn" class="flex items-center justify-center px-4 py-3 bg-pink-900 text-pink-100 rounded-md hover:bg-pink-800 transition"> | |
| <i class="fas fa-copy mr-2"></i> Detect Pagination | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Right Panel - Results and Helper Mode --> | |
| <div class="md:col-span-2 space-y-6"> | |
| <!-- Output Console --> | |
| <div class="rounded-lg shadow h-full bg-gray-800"> | |
| <div class="p-4 border-b border-gray-600"> | |
| <h2 class="text-xl font-semibold flex items-center"> | |
| <i class="fas fa-terminal mr-2 text-gray-400"></i> | |
| Ingestion Console | |
| </h2> | |
| </div> | |
| <div class="p-4"> | |
| <div id="consoleOutput" class="h-64 overflow-y-auto scrollbar-hide bg-gray-700 rounded-md p-3 text-sm font-mono space-y-2"> | |
| <div class="text-gray-400">Ready to begin API ingestion process...</div> | |
| </div> | |
| </div> | |
| <div class="p-4 border-t border-gray-600 flex justify-between"> | |
| <button id="startIngestionBtn" class="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition flex items-center"> | |
| <i class="fas fa-play mr-2"></i> Start Ingestion | |
| </button> | |
| <button id="helperModeBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 transition hidden flex items-center"> | |
| <i class="fas fa-robot mr-2"></i> Enter Helper Mode | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Detected Information --> | |
| <div id="detectedInfo" class="rounded-lg shadow hidden overflow-hidden bg-gray-800"> | |
| <div class="p-4 border-b border-gray-600 bg-amber-900"> | |
| <h2 class="text-xl font-semibold flex items-center justify-between"> | |
| <span><i class="fas fa-info-circle mr-2 text-amber-400"></i> Detected Information</span> | |
| <button id="closeDetectedInfo" class="text-gray-400 hover:text-gray-200"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </h2> | |
| </div> | |
| <div class="p-4"> | |
| <div class="json-viewer text-gray-300 p-4 overflow-auto max-h-60"> | |
| <pre id="detectedJson">No information detected yet.</pre> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Helper Mode Modal --> | |
| <div id="helperModal" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center z-50 hidden"> | |
| <div class="bg-gray-800 rounded-lg shadow-xl w-full max-w-4xl max-h-[90vh] flex flex-col"> | |
| <div class="p-4 border-b border-gray-600 bg-indigo-900"> | |
| <h2 class="text-xl font-semibold"> | |
| <i class="fas fa-robot mr-2 text-indigo-400"></i> API Helper Mode | |
| </h2> | |
| </div> | |
| <div class="flex-1 overflow-hidden flex flex-col"> | |
| <div id="chatContainer" class="flex-1 overflow-y-auto p-4 space-y-4 scrollbar-hide bg-gray-700"> | |
| <div class="flex justify-start"> | |
| <div class="max-w-[80%] bg-indigo-800 p-3 rounded-lg"> | |
| I've successfully ingested the API documentation. How can I help you work with this API? | |
| </div> | |
| </div> | |
| </div> | |
| <div class="p-4 border-t border-gray-600"> | |
| <div class="flex"> | |
| <input type="text" id="userQuery" placeholder="Ask me anything about this API..." class="flex-grow px-4 py-2 border border-gray-600 rounded-l-md focus:ring-indigo-500 focus:border-indigo-500 bg-gray-700 text-white"> | |
| <button id="sendQueryBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-r-md hover:bg-indigo-700 transition"> | |
| <i class="fas fa-paper-plane"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="p-4 border-t border-gray-600 flex justify-end"> | |
| <button id="exitHelperBtn" class="px-4 py-2 bg-gray-700 text-white rounded-md hover:bg-gray-600 transition"> | |
| Exit Helper Mode | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // DOM Elements | |
| const apiUrlInput = document.getElementById('apiUrl'); | |
| const detectBtn = document.getElementById('detectBtn'); | |
| const detectAuthBtn = document.getElementById('detectAuthBtn'); | |
| const authOptions = document.getElementById('authOptions'); | |
| const authDetails = document.getElementById('authDetails'); | |
| const consoleOutput = document.getElementById('consoleOutput'); | |
| const startIngestionBtn = document.getElementById('startIngestionBtn'); | |
| const helperModeBtn = document.getElementById('helperModeBtn'); | |
| const detectedInfo = document.getElementById('detectedInfo'); | |
| const detectedJson = document.getElementById('detectedJson'); | |
| const closeDetectedInfo = document.getElementById('closeDetectedInfo'); | |
| const helperModal = document.getElementById('helperModal'); | |
| const exitHelperBtn = document.getElementById('exitHelperBtn'); | |
| const userQuery = document.getElementById('userQuery'); | |
| const sendQueryBtn = document.getElementById('sendQueryBtn'); | |
| const chatContainer = document.getElementById('chatContainer'); | |
| // Detection buttons | |
| const detectMethodsBtn = document.getElementById('detectMethodsBtn'); | |
| const detectProtocolBtn = document.getElementById('detectProtocolBtn'); | |
| const detectStructureBtn = document.getElementById('detectStructureBtn'); | |
| const detectPaginationBtn = document.getElementById('detectPaginationBtn'); | |
| // Auth type radio buttons | |
| const authRadios = document.querySelectorAll('input[name="authType"]'); | |
| const apiKeyAuth = document.getElementById('apiKeyAuth'); | |
| const oauthAuth = document.getElementById('oauthAuth'); | |
| const basicAuth = document.getElementById('basicAuth'); | |
| // Detect API URL | |
| detectBtn.addEventListener('click', () => { | |
| const url = apiUrlInput.value.trim(); | |
| if (!url) { | |
| logToConsole('Please enter a valid API URL', 'error'); | |
| return; | |
| } | |
| logToConsole(`Detecting API at: ${url}`, 'info'); | |
| apiUrlInput.disabled = true; | |
| detectBtn.disabled = true; | |
| detectBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i> Detecting...'; | |
| // Simulate API detection | |
| setTimeout(() => { | |
| logToConsole('API endpoint detected successfully', 'success'); | |
| detectBtn.innerHTML = '<i class="fas fa-check mr-1"></i> Detected'; | |
| detectAuthBtn.disabled = false; | |
| authOptions.classList.remove('hidden'); | |
| // Enable all detection buttons | |
| [detectMethodsBtn, detectProtocolBtn, detectStructureBtn, detectPaginationBtn].forEach(btn => { | |
| btn.disabled = false; | |
| }); | |
| }, 2000); | |
| }); | |
| // Detect authentication type | |
| detectAuthBtn.addEventListener('click', () => { | |
| logToConsole('Detecting authentication method...', 'info'); | |
| detectAuthBtn.disabled = true; | |
| detectAuthBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Detecting...'; | |
| // Simulate auth detection | |
| setTimeout(() => { | |
| logToConsole('Authentication method detected: API Key', 'success'); | |
| detectAuthBtn.classList.add('hidden'); | |
| authOptions.classList.remove('hidden'); | |
| authDetails.classList.remove('hidden'); | |
| document.getElementById('apiKey').checked = true; | |
| apiKeyAuth.classList.remove('hidden'); | |
| }, 1500); | |
| }); | |
| // Handle auth type selection | |
| authRadios.forEach(radio => { | |
| radio.addEventListener('change', () => { | |
| apiKeyAuth.classList.add('hidden'); | |
| oauthAuth.classList.add('hidden'); | |
| basicAuth.classList.add('hidden'); | |
| if (radio.value === 'apiKey') { | |
| apiKeyAuth.classList.remove('hidden'); | |
| } else if (radio.value === 'oauth') { | |
| oauthAuth.classList.remove('hidden'); | |
| } else if (radio.value === 'basic') { | |
| basicAuth.classList.remove('hidden'); | |
| } | |
| }); | |
| }); | |
| // Detection buttons | |
| detectMethodsBtn.addEventListener('click', () => simulateDetection('API call methods', 'GET, POST, PUT, DELETE available')); | |
| detectProtocolBtn.addEventListener('click', () => simulateDetection('API protocol', 'REST API detected')); | |
| detectStructureBtn.addEventListener('click', () => simulateDetection('API structure', 'Hierarchical resource structure detected')); | |
| detectPaginationBtn.addEventListener('click', () => simulateDetection('Pagination method', 'Offset-based pagination detected')); | |
| // Start ingestion process | |
| startIngestionBtn.addEventListener('click', () => { | |
| const url = apiUrlInput.value.trim(); | |
| if (!url) { | |
| logToConsole('Please configure the API first', 'error'); | |
| return; | |
| } | |
| logToConsole('Starting API ingestion process...', 'info'); | |
| startIngestionBtn.disabled = true; | |
| startIngestionBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Processing...'; | |
| // Simulate ingestion process | |
| setTimeout(() => { | |
| logToConsole('Discovering API endpoints...', 'processing'); | |
| }, 1000); | |
| setTimeout(() => { | |
| logToConsole('Analyzing request/response patterns...', 'processing'); | |
| }, 3000); | |
| setTimeout(() => { | |
| logToConsole('Extracting documentation...', 'processing'); | |
| ], 5000); | |
| setTimeout(() => { | |
| logToConsole('Identifying relationships between endpoints...', 'processing'); | |
| }, 8000); | |
| setTimeout(() => { | |
| logToConsole('Successfully ingested API documentation!', 'success'); | |
| startIngestionBtn.classList.add('hidden'); | |
| helperModeBtn.classList.remove('hidden'); | |
| // Show sample detected info | |
| const sampleData = { | |
| api: { | |
| baseUrl: url, | |
| authentication: "API Key (X-API-KEY in header)", | |
| endpoints: [ | |
| { | |
| path: "/users", | |
| methods: ["GET", "POST"], | |
| description: "Manage user accounts", | |
| parameters: { | |
| GET: { | |
| limit: "number", | |
| offset: "number" | |
| }, | |
| POST: { | |
| name: "string", | |
| email: "string" | |
| } | |
| } | |
| }, | |
| { | |
| path: "/users/{id}", | |
| methods: ["GET", "PUT", "DELETE"], | |
| description: "Specific user operations" | |
| } | |
| ], | |
| pagination: "offset-based (limit/offset)", | |
| rateLimiting: "100 requests/minute" | |
| } | |
| }; | |
| detectedJson.textContent = JSON.stringify(sampleData, null, 2); | |
| showDetectedInfo(); | |
| }, 10000); | |
| }); | |
| // Helper mode | |
| helperModeBtn.addEventListener('click', () => { | |
| helperModal.classList.remove('hidden'); | |
| }); | |
| exitHelperBtn.addEventListener('click', () => { | |
| helperModal.classList.add('hidden'); | |
| }); | |
| // Close detected info | |
| closeDetectedInfo.addEventListener('click', () => { | |
| detectedInfo.classList.add('hidden'); | |
| }); | |
| // Chat functionality | |
| sendQueryBtn.addEventListener('click', sendMessage); | |
| userQuery.addEventListener('keypress', (e) => { | |
| if (e.key === 'Enter') sendMessage(); | |
| }); | |
| function sendMessage() { | |
| const message = userQuery.value.trim(); | |
| if (!message) return; | |
| // Add user message | |
| addMessage('user', message); | |
| userQuery.value = ''; | |
| // Simulate AI response | |
| setTimeout(() => { | |
| const responses = [ | |
| "For that functionality, you'll want to use the /users endpoint with a POST method.", | |
| "The API documentation shows that you can use pagination with limit and offset parameters.", | |
| "I can generate sample code for you to call this endpoint in JavaScript." | |
| ]; | |
| const randomResponse = responses[Math.floor(Math.random() * responses.length)]; | |
| addMessage('ai', randomResponse); | |
| }, 1000); | |
| } | |
| // Utility functions | |
| function simulateDetection(name, result) { | |
| const btn = event.target; | |
| btn.disabled = true; | |
| const originalText = btn.innerHTML; | |
| btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>'; | |
| setTimeout(() => { | |
| logToConsole(`${name} detected: ${result}`, 'success'); | |
| btn.innerHTML = originalText; | |
| }, 2000); | |
| } | |
| function logToConsole(message, type = 'info') { | |
| const timestamp = new Date().toLocaleTimeString(); | |
| let icon, color; | |
| switch(type) { | |
| case 'error': | |
| icon = '<i class="fas fa-exclamation-circle text-red-400 mr-2"></i>'; | |
| color = 'text-red-400'; | |
| break; | |
| case 'success': | |
| icon = '<i class="fas fa-check-circle text-green-400 mr-2"></i>'; | |
| color = 'text-green-400'; | |
| break; | |
| case 'processing': | |
| icon = '<i class="fas fa-spinner fa-spin text-blue-400 mr-2"></i>'; | |
| color = 'text-blue-400'; | |
| break; | |
| default: | |
| icon = '<i class="fas fa-info-circle text-gray-400 mr-2"></i>'; | |
| color = 'text-gray-400'; | |
| } | |
| const entry = document.createElement('div'); | |
| entry.className = 'flex items-start'; | |
| entry.innerHTML = ` | |
| <span class="text-xs text-gray-500 mr-2">[${timestamp}]</span> | |
| <span class="${color}">${icon}</span> | |
| <span class="${color} flex-1">${message}</span> | |
| `; | |
| consoleOutput.appendChild(entry); | |
| consoleOutput.scrollTop = consoleOutput.scrollHeight; | |
| } | |
| function showDetectedInfo() { | |
| detectedInfo.classList.remove('hidden'); | |
| } | |
| function addMessage(sender, text) { | |
| const messageDiv = document.createElement('div'); | |
| if (sender === 'user') { | |
| messageDiv.className = 'flex justify-end'; | |
| messageDiv.innerHTML = ` | |
| <div class="max_w-[80%] bg-blue-600 text-white p-3 rounded-lg"> | |
| ${text} | |
| </div> | |
| `; | |
| } else { | |
| messageDiv.className = 'flex justify-start'; | |
| messageDiv.innerHTML = ` | |
| <div class="max-w-[80%] bg-indigo-800 text-gray-200 p-3 rounded-lg"> | |
| ${text} | |
| </div> | |
| `; | |
| } | |
| chatContainer.appendChild(messageDiv); | |
| chatContainer.scrollTop = chatContainer.scrollHeight; | |
| } | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=aegisceo/apiingest-lite" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |