Spaces:
Sleeping
Sleeping
File size: 9,166 Bytes
8f40d24 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Code Completion AI</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
html {
scroll-behavior: smooth;
}
body {
font-family: 'Inter', sans-serif;
background-color: #0f172a; /* slate-900 */
background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.05) 1px, transparent 0);
background-size: 2rem 2rem;
}
.suggestion-item {
transition: all 0.2s ease-in-out;
}
.info-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 1rem;
}
</style>
</head>
<body class="text-gray-200 min-h-screen flex flex-col items-center justify-center p-4">
<main class="w-full max-w-5xl mx-auto grid grid-cols-1 lg:grid-cols-5 gap-8 lg:gap-12">
<!-- Left Column: Interaction -->
<div class="lg:col-span-3 bg-slate-900/50 backdrop-blur-sm border border-slate-700 rounded-2xl shadow-2xl p-6 md:p-8">
<div class="text-left mb-8">
<h1 class="text-4xl font-bold text-white tracking-tight">Code Completion AI</h1>
<p class="text-slate-400 mt-2">Enter a Python code snippet to get AI-powered suggestions.</p>
</div>
<div>
<label for="code-input" class="block text-sm font-medium text-slate-300 mb-2">Python Snippet</label>
<textarea id="code-input"
class="w-full h-48 p-4 bg-slate-900 border border-slate-700 rounded-lg text-slate-200 focus:ring-2 focus:ring-sky-500 focus:border-sky-500 transition duration-200 resize-none font-mono text-sm"
placeholder="e.g., import numpy as"></textarea>
</div>
<div class="mt-6 text-left">
<button id="predict-btn"
class="bg-sky-600 hover:bg-sky-700 text-white font-bold py-3 px-6 rounded-lg transition duration-300 ease-in-out transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-slate-900 focus:ring-sky-500 flex items-center justify-center">
<span id="btn-text">Get Suggestions</span>
<span id="spinner" class="hidden">
<svg class="animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</span>
</button>
</div>
<div id="results-container" class="mt-8">
<h2 class="text-lg font-semibold text-white mb-3">Top 5 Suggestions</h2>
<div id="suggestions" class="bg-slate-900 p-3 rounded-lg min-h-[160px] border border-slate-700 space-y-1">
<p id="placeholder-text" class="text-slate-500 p-2">Suggestions will appear here...</p>
</div>
</div>
</div>
<!-- Right Column: Model Info -->
<div class="lg:col-span-2 space-y-6">
<div class="bg-slate-900/50 backdrop-blur-sm border border-slate-700 rounded-2xl shadow-xl p-6">
<h3 class="text-2xl font-bold text-white mb-4">Model Details</h3>
<p class="text-slate-400 mb-6">
This app uses a <span class="text-sky-400 font-semibold">Residual LSTM</span> model with two LSTM layers and a skip connection. It was trained on the Python subset of the <span class="text-sky-400">CodeXGlue</span> dataset to predict the next token in a sequence.
</p>
<div class="info-card-grid">
<div class="bg-slate-800 p-4 rounded-lg border border-slate-700">
<p class="text-sm text-slate-400">Top-5 Accuracy</p>
<p class="text-xl font-semibold text-white">86.82%</p>
</div>
<div class="bg-slate-800 p-4 rounded-lg border border-slate-700">
<p class="text-sm text-slate-400">Perplexity</p>
<p class="text-xl font-semibold text-white">4.19</p>
</div>
<div class="bg-slate-800 p-4 rounded-lg border border-slate-700">
<p class="text-sm text-slate-400">Embedding Dim</p>
<p class="text-xl font-semibold text-white">256</p>
</div>
<div class="bg-slate-800 p-4 rounded-lg border border-slate-700">
<p class="text-sm text-slate-400">Hidden Units</p>
<p class="text-xl font-semibold text-white">512</p>
</div>
<div class="bg-slate-800 p-4 rounded-lg border border-slate-700">
<p class="text-sm text-slate-400">Vocab Size</p>
<p class="text-xl font-semibold text-white">10,002</p>
</div>
<div class="bg-slate-800 p-4 rounded-lg border border-slate-700">
<p class="text-sm text-slate-400">Parameters</p>
<p class="text-xl font-semibold text-white">~15.5 M</p>
</div>
</div>
</div>
</div>
</main>
<footer class="w-full max-w-5xl mx-auto text-center text-slate-500 py-8 mt-4">
<p>Made with ❤️ by Ayush</p>
</footer>
<script>
const codeInput = document.getElementById('code-input');
const predictBtn = document.getElementById('predict-btn');
const suggestionsDiv = document.getElementById('suggestions');
const placeholderText = document.getElementById('placeholder-text');
const btnText = document.getElementById('btn-text');
const spinner = document.getElementById('spinner');
let debounceTimer;
const getPredictions = async () => {
const code = codeInput.value;
if (code.trim() === '') {
suggestionsDiv.innerHTML = '<p id="placeholder-text" class="text-slate-500 p-2">Suggestions will appear here...</p>';
return;
}
btnText.classList.add('hidden');
spinner.classList.remove('hidden');
predictBtn.disabled = true;
try {
const response = await fetch('/predict', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code: code }),
});
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
const data = await response.json();
if (data.error) {
suggestionsDiv.innerHTML = `<p class="text-red-400 p-2">${data.error}</p>`;
return;
}
if (data.suggestions && data.suggestions.length > 0) {
suggestionsDiv.innerHTML = '';
data.suggestions.forEach(suggestion => {
const p = document.createElement('p');
p.textContent = suggestion;
p.className = 'suggestion-item p-2 rounded hover:bg-slate-700 cursor-pointer text-slate-300';
p.onclick = () => {
const lastCharIsSpace = codeInput.value.slice(-1) === ' ';
codeInput.value += (lastCharIsSpace ? '' : ' ') + suggestion;
codeInput.focus();
getPredictions();
};
suggestionsDiv.appendChild(p);
});
} else {
suggestionsDiv.innerHTML = '<p class="text-slate-500 p-2">No suggestions found.</p>';
}
} catch (error) {
console.error('Error:', error);
suggestionsDiv.innerHTML = '<p class="text-red-400 p-2">An error occurred. Check server logs.</p>';
} finally {
btnText.classList.remove('hidden');
spinner.classList.add('hidden');
predictBtn.disabled = false;
}
};
predictBtn.addEventListener('click', getPredictions);
codeInput.addEventListener('input', () => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(getPredictions, 500); // 500ms debounce
});
</script>
</body>
</html>
|