import { pipeline } from '@huggingface/transformers'; import http from 'http'; import crypto from 'crypto'; import fs from 'fs'; const PORT = 7860; const MODEL_NAME = 'onnx-community/Qwen2.5-0.5B-Instruct'; let generator; let modelReady = false; // ── SYSTEM STATE ────────────────────────────────────────────────────────────── const queue = []; const jobs = new Map(); const rateLimits = new Map(); const MAX_PARALLEL = 1; let activeCount = 0; // ── UTILITIES ───────────────────────────────────────────────────────────────── function generateId() { return crypto.randomBytes(8).toString('hex'); } function log(event, details = {}) { const timestamp = new Date().toISOString(); const logEntry = `[${timestamp}] ${event.toUpperCase()} - ${JSON.stringify(details)}\n`; process.stdout.write(logEntry); fs.appendFileSync('generation_logs.txt', logEntry); } function setCORS(res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); } function sendJSON(res, status, data) { setCORS(res); res.setHeader('Content-Type', 'application/json'); res.writeHead(status); res.end(JSON.stringify(data)); } // ── RATE LIMITING ───────────────────────────────────────────────────────────── function checkRateLimit(ip) { const now = Date.now(); const limit = rateLimits.get(ip) || { count: 0, resetTime: now + 60000 }; if (now > limit.resetTime) { limit.count = 0; limit.resetTime = now + 60000; } if (limit.count >= 10) return false; limit.count++; rateLimits.set(ip, limit); return true; } // ── QUEUE ───────────────────────────────────────────────────────────────────── function enqueue(jobId, task) { return new Promise((resolve, reject) => { queue.push({ jobId, task, resolve, reject }); processQueue(); }); } async function processQueue() { if (activeCount >= MAX_PARALLEL || queue.length === 0) return; activeCount++; const { jobId, task, resolve, reject } = queue.shift(); if (jobs.get(jobId)?.status === 'cancelled') { activeCount--; return processQueue(); } try { jobs.get(jobId).status = 'processing'; resolve(await task()); } catch (err) { reject(err); } finally { activeCount--; processQueue(); } } // ── MODEL ───────────────────────────────────────────────────────────────────── async function loadModel() { log('system', { message: "Loading model..." }); generator = await pipeline('text-generation', MODEL_NAME, { dtype: 'q4' }); modelReady = true; log('system', { message: "Model ready!" }); } // ── CHUNK GENERATION WITH RETRY ─────────────────────────────────────────────── async function generateChunk(messages, maxTokens, attempt = 0) { const startTime = Date.now(); try { const output = await generator(messages, { max_new_tokens: maxTokens, temperature: 0.2, repetition_penalty: 1.15, do_sample: false }); const generated = output[0].generated_text; let text = Array.isArray(generated) ? generated.at(-1)?.content || '' : String(generated || ''); // Repair unclosed code blocks const openBlocks = (text.match(/```/g) || []).length; if (openBlocks % 2 !== 0) text += '\n```'; return { text, duration: Date.now() - startTime }; } catch (err) { if (attempt < 3) { log('retry', { attempt: attempt + 1, error: err.message }); await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000)); return generateChunk(messages, maxTokens, attempt + 1); } throw err; } } // ── PROMPT CLASSIFIER ───────────────────────────────────────────────────────── function classifyPrompt(prompt) { const lower = prompt.toLowerCase(); // Identity questions const identityWords = ['who are you','what are you','your name','who made you', 'who created you','your company','your founder','about you','introduce yourself']; if (identityWords.some(w => lower.includes(w))) return 'identity'; // Non-coding general questions const generalWords = ['what is','what are','explain','describe','tell me about', 'history of','meaning of','definition','how does','why is','who is','who was', 'when did','where is','function of','functions of']; if (generalWords.some(w => lower.includes(w))) return 'general'; // Coding / website / app requests const codingWords = ['generate','create','build','make','write','code','website', 'webpage','page','app','application','login','register','form','html','css', 'javascript','js','node','express','backend','frontend','server','api', 'function','script','component','template','dashboard','portfolio','ecommerce', 'shop','blog','landing page','navbar','footer','button','database']; if (codingWords.some(w => lower.includes(w))) return 'coding'; return 'general'; } // ── SYSTEM PROMPT BUILDER ───────────────────────────────────────────────────── function buildSystemPrompt(type) { const IDENTITY = `You are Gini AI, a full-stack web development AI assistant. - Created by Emalawi19. - Founded by Professor Roosevelt Chinkwende. - You are an AI assistant, not a human. - When asked your name: "I am Gini AI." - When asked who made you: "I was created by Emalawi19." - When asked about the founder: "Emalawi19 was founded by Professor Roosevelt Chinkwende."`; if (type === 'identity') { return `${IDENTITY} Introduce yourself clearly and warmly. State your name, your purpose, your company, and your founder.`; } if (type === 'general') { return `${IDENTITY} GENERAL BEHAVIOR: - Answer the question directly and clearly in plain English. - Be concise and helpful. - Do NOT generate any code for non-coding questions. - Do NOT use programming languages to answer everyday questions.`; } // type === 'coding' return `${IDENTITY} YOU ARE A FULL-STACK WEB DEVELOPER AI. FOLLOW THESE RULES STRICTLY: RULE 1 — SINGLE FILE OUTPUT (MOST IMPORTANT): When asked to build any website, webpage, app, or UI component: - ALWAYS output ONE single complete HTML file. - That single file MUST contain ALL HTML structure, ALL CSS styles, and ALL JavaScript — nothing external. - ALL CSS goes inside a