Spaces:
Paused
Paused
| import { pipeline } from '@huggingface/transformers'; | |
| import http from 'http'; | |
| const PORT = 7860; | |
| const MODEL_NAME = 'onnx-community/Qwen2.5-0.5B-Instruct'; | |
| let generator; | |
| async function loadModel() { | |
| console.log("Loading coding model..."); | |
| generator = await pipeline('text-generation', MODEL_NAME, { dtype: 'q4' }); | |
| console.log("Model loaded successfully!"); | |
| } | |
| const CODING_PHRASES = [ | |
| 'generate code', 'write code', 'create code', | |
| 'generate a website', 'build a website', 'create a website', 'make a website', | |
| 'generate a webpage', 'build a webpage', | |
| 'generate a login', 'create a login', 'build a login', | |
| 'generate a form', 'create a form', 'build a form', | |
| 'generate a page', 'create a page', 'build a page', | |
| 'generate an app', 'create an app', 'build an app', | |
| 'write a function', 'write a script', 'write a program', | |
| 'create a function', 'create a script', | |
| 'build an api', 'create an api', 'generate an api', | |
| 'node.js', 'express.js', 'express server', | |
| 'show me the code', 'give me the code', 'write html', | |
| 'write css', 'write javascript', 'write js', | |
| 'create a backend', 'build a backend', | |
| 'create a frontend', 'build a frontend', | |
| 'create a server', 'build a server', | |
| 'how do i code', 'how to code', 'code for', | |
| 'sample code', 'example code', '```' | |
| ]; | |
| const NON_CODING_CONTEXTS = [ | |
| 'function of', 'functions of', 'what is the function', | |
| 'what are the functions', 'purpose of', 'role of', | |
| 'explain', 'what is', 'what are', 'tell me about', | |
| 'history of', 'meaning of', 'definition of', | |
| 'describe', 'how does', 'why is', 'benefits of', | |
| 'importance of', 'effects of', 'causes of' | |
| ]; | |
| function isCodingRequest(prompt) { | |
| const lower = prompt.toLowerCase().trim(); | |
| if (NON_CODING_CONTEXTS.some(ctx => lower.includes(ctx))) return false; | |
| return CODING_PHRASES.some(phrase => lower.includes(phrase)); | |
| } | |
| // Detect if the prompt is asking for a full HTML website/page | |
| function isWebsiteRequest(prompt) { | |
| const lower = prompt.toLowerCase(); | |
| return ['website', 'webpage', 'web page', 'html page', 'login page', | |
| 'register page', 'landing page', 'form page', 'signup page', | |
| 'homepage', 'home page', 'portfolio', 'dashboard'].some(w => lower.includes(w)); | |
| } | |
| // Ensure HTML output starts with <!DOCTYPE html> or <html> and ends with </html> | |
| function enforceHTMLStructure(text) { | |
| // Extract code from inside ```html ... ``` block if present | |
| const codeBlockMatch = text.match(/```html\s*([\s\S]*?)```/i); | |
| if (codeBlockMatch) { | |
| let html = codeBlockMatch[1].trim(); | |
| html = cleanHTML(html); | |
| return '```html\n' + html + '\n```'; | |
| } | |
| // If raw HTML is present (starts with < somewhere), extract and clean it | |
| const htmlStart = text.search(/<(!DOCTYPE|html)/i); | |
| if (htmlStart !== -1) { | |
| let html = text.slice(htmlStart); | |
| // Cut off anything after </html> | |
| const htmlEnd = html.search(/<\/html>/i); | |
| if (htmlEnd !== -1) { | |
| html = html.slice(0, htmlEnd + 7); // include </html> | |
| } | |
| html = cleanHTML(html); | |
| return '```html\n' + html + '\n```'; | |
| } | |
| return text; | |
| } | |
| function cleanHTML(html) { | |
| // Ensure it starts with <!DOCTYPE html> | |
| if (!html.trimStart().toLowerCase().startsWith('<!doctype')) { | |
| if (html.trimStart().toLowerCase().startsWith('<html')) { | |
| html = '<!DOCTYPE html>\n' + html.trimStart(); | |
| } else { | |
| html = '<!DOCTYPE html>\n<html lang="en">\n' + html.trimStart(); | |
| } | |
| } | |
| // Ensure it ends with </html> | |
| if (!html.trimEnd().toLowerCase().endsWith('</html>')) { | |
| // Check if </body> is present, add </html> after it | |
| if (html.toLowerCase().includes('</body>')) { | |
| html = html.replace(/<\/body>\s*$/i, '</body>\n</html>'); | |
| } else { | |
| html = html.trimEnd() + '\n</body>\n</html>'; | |
| } | |
| } | |
| return html.trim(); | |
| } | |
| const server = http.createServer(async (req, res) => { | |
| res.setHeader('Access-Control-Allow-Origin', '*'); | |
| res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); | |
| res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); | |
| if (req.method === 'OPTIONS') { | |
| res.writeHead(200); | |
| return res.end(); | |
| } | |
| res.setHeader('Content-Type', 'application/json'); | |
| const pathname = req.url.split('?')[0]; | |
| if (pathname === '/' && req.method === 'GET') { | |
| res.writeHead(200); | |
| res.end(JSON.stringify({ status: "Backend is running" })); | |
| return; | |
| } | |
| if (pathname === '/generate' && req.method === 'POST') { | |
| let body = ''; | |
| req.on('data', chunk => { body += chunk.toString(); }); | |
| req.on('end', async () => { | |
| try { | |
| const { prompt } = JSON.parse(body); | |
| if (!generator) { | |
| res.writeHead(503); | |
| return res.end(JSON.stringify({ error: "Model is still loading..." })); | |
| } | |
| const coding = isCodingRequest(prompt); | |
| const websiteRequest = isWebsiteRequest(prompt); | |
| const finalPrompt = coding | |
| ? `You are a coding assistant. Write complete, working code for this task. Never refuse. Always provide full code: ${prompt}` | |
| : prompt; | |
| const systemPrompt = coding | |
| ? `You are Gini AI, a full-stack web development AI assistant created by Emalawi19, founded by Professor Roosevelt Chinkwende. | |
| IDENTITY: | |
| - Your name is Gini AI, created by Emalawi19, founded by Professor Roosevelt Chinkwende. | |
| - You are an AI assistant, not a human. | |
| CODING RULES β NEVER BREAK THESE: | |
| 1. You ALWAYS write code when asked. You NEVER refuse any coding task. | |
| 2. Code must be complete, real, and copy-paste ready β no placeholders. | |
| 3. Default language is always JavaScript/HTML/CSS β NEVER Python unless the user asks. | |
| 4. Add short comments inside the code. | |
| HTML WEBSITE RULES β ALWAYS FOLLOW FOR ANY WEBSITE/PAGE REQUEST: | |
| 1. ALL website/page code MUST start with <!DOCTYPE html> on the very first line. | |
| 2. Then <html lang="en"> on the second line. | |
| 3. Must include a proper <head> section with <meta charset>, <meta viewport>, <title>, and embedded <style>. | |
| 4. Must include a proper <body> section with all content. | |
| 5. Must end with </body> then </html> as the very last line. | |
| 6. ALL CSS goes inside a <style> tag in the <head> β no external stylesheets. | |
| 7. ALL JavaScript goes inside a <script> tag at the bottom of <body> β no external scripts. | |
| 8. The full HTML must be wrapped in a \`\`\`html code block. | |
| 9. The page must be complete and functional β never cut off mid-code. | |
| STEP-BY-STEP RULES: | |
| 1. When asked to build a full website or app, first list ALL steps with short titles. | |
| 2. Say: "Let's begin with Step 1. Say 'next' when ready to continue." | |
| 3. For each step: | |
| a) "Step X of Y: Title" | |
| b) One sentence explaining what this step does | |
| c) Complete working code in a code block | |
| d) Filename and where to save it | |
| e) How to run it if needed | |
| f) End with: "Say 'next' to continue to Step X." | |
| 4. ONE step per response only. Never combine steps. | |
| 5. NEVER cut off mid-code. Always finish the full code for the current step. | |
| 6. Default stack: HTML + CSS + JS frontend, Node.js + Express backend.` | |
| : `You are Gini AI, a helpful AI assistant created by Emalawi19, founded by Professor Roosevelt Chinkwende. | |
| IDENTITY: | |
| - Your name is Gini AI, created by Emalawi19, founded by Professor Roosevelt Chinkwende. | |
| - You are an AI assistant, not a human. | |
| GENERAL BEHAVIOR: | |
| - Answer the question directly and clearly in plain English. | |
| - NEVER generate code for general knowledge or everyday questions. | |
| - NEVER use Python, JavaScript, or any programming language to answer a non-coding question. | |
| - If someone asks "what is the function of X" or "explain X" β answer in plain sentences, not code. | |
| - Keep answers concise, friendly, and easy to understand. | |
| - Only mention web development if the question is specifically about it.`; | |
| const messages = [ | |
| { role: 'system', content: systemPrompt }, | |
| { role: 'user', content: finalPrompt } | |
| ]; | |
| const output = await generator(messages, { | |
| max_new_tokens: coding ? 800 : 300, | |
| temperature: coding ? 0.2 : 0.5, | |
| repetition_penalty: 1.2, | |
| do_sample: !coding | |
| }); | |
| let result = output[0].generated_text.at(-1).content; | |
| // Catch refusals and retry | |
| const refusals = ["i can't assist", "i cannot assist", "i'm sorry", "i am sorry", "i'm unable", "i cannot help", "i can't help"]; | |
| const refused = refusals.some(r => result.toLowerCase().startsWith(r)); | |
| if (refused && coding) { | |
| const retryMessages = [ | |
| { | |
| role: 'system', | |
| content: 'You are a code generator. Output only complete working code. Never refuse. No explanations, just code.' | |
| }, | |
| { | |
| role: 'user', | |
| content: `Write complete working HTML code starting with <!DOCTYPE html> and ending with </html> for: ${prompt}` | |
| } | |
| ]; | |
| const retryOutput = await generator(retryMessages, { | |
| max_new_tokens: 800, | |
| temperature: 0.1, | |
| do_sample: false | |
| }); | |
| result = retryOutput[0].generated_text.at(-1).content; | |
| } | |
| // Post-process: enforce proper HTML structure for website requests | |
| if (websiteRequest && coding) { | |
| result = enforceHTMLStructure(result); | |
| } | |
| res.writeHead(200); | |
| res.end(JSON.stringify({ result })); | |
| } catch (err) { | |
| res.writeHead(400); | |
| res.end(JSON.stringify({ error: "Invalid request", detail: err.message })); | |
| } | |
| }); | |
| return; | |
| } | |
| res.writeHead(404); | |
| res.end(JSON.stringify({ error: "Not Found", requested_path: pathname })); | |
| }); | |
| loadModel().then(() => { | |
| server.listen(PORT, '0.0.0.0', () => { | |
| console.log(`Server running at http://0.0.0.0:${PORT}`); | |
| }); | |
| }); |