Ayush
Added the code files
8f40d24
<!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>