Spaces:
Paused
Paused
| import { pipeline } from '@huggingface/transformers'; | |
| import http from 'http'; | |
| import fs from 'fs'; | |
| import path from 'path'; | |
| import { fileURLToPath } from 'url'; | |
| const PORT = 7860; | |
| const MODEL_NAME = 'onnx-community/Qwen2.5-Coder-3B-Instruct'; | |
| const __filename = fileURLToPath(import.meta.url); | |
| const __dirname = path.dirname(__filename); | |
| let generator; | |
| const KNOWLEDGE_TOPICS = {}; | |
| async function initializeServer() { | |
| try { | |
| console.log("Reading knowledge.txt..."); | |
| const knowledgePath = path.join(__dirname, 'knowledge.txt'); | |
| if (fs.existsSync(knowledgePath)) { | |
| const rawContent = fs.readFileSync(knowledgePath, 'utf8'); | |
| const topicRegex = /\[TOPIC:\s*(\w+)\]([\s\S]*?)(?=\[TOPIC:|$)/gi; | |
| let match; | |
| while ((match = topicRegex.exec(rawContent)) !== null) { | |
| const topicName = match[1].toLowerCase().trim(); | |
| const topicContent = match[2].trim(); | |
| KNOWLEDGE_TOPICS[topicName] = topicContent; | |
| console.log(`-> Successfully registered topic: "${topicName}"`); | |
| } | |
| } else { | |
| console.warn("WARNING: knowledge.txt not found. Starting blank."); | |
| } | |
| console.log("Loading Qwen2.5-Coder-3B model... (first load may take a few minutes)"); | |
| generator = await pipeline('text-generation', MODEL_NAME, { dtype: 'q4' }); | |
| console.log("Server fully initialized!"); | |
| } catch (error) { | |
| console.error("Initialization failed:", error); | |
| process.exit(1); | |
| } | |
| } | |
| // 100% AUTOMATED ROUTER | |
| function getRelevantContext(userPrompt) { | |
| const lowerPrompt = userPrompt.toLowerCase(); | |
| let dynamicContext = ""; | |
| for (const topicName in KNOWLEDGE_TOPICS) { | |
| if (lowerPrompt.includes(topicName)) { | |
| dynamicContext += KNOWLEDGE_TOPICS[topicName] + "\n\n"; | |
| } | |
| } | |
| if (!dynamicContext.trim()) { | |
| const available = Object.keys(KNOWLEDGE_TOPICS).join(", "); | |
| dynamicContext = `General support mode. Reference available topics: ${available}.`; | |
| } | |
| return dynamicContext; | |
| } | |
| 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", | |
| available_topics: Object.keys(KNOWLEDGE_TOPICS) | |
| })); | |
| 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: "System warming up..." })); | |
| } | |
| const localizedContext = getRelevantContext(prompt); | |
| const codingKeywords = [ | |
| 'generate', 'create', 'build', 'make', 'code', 'website', 'webpage', | |
| 'login', 'register', 'form', 'page', 'app', 'application', 'html', | |
| 'css', 'javascript', 'backend', 'frontend', 'server', 'api', 'express', | |
| 'node', 'database', 'function', 'script', 'component', 'write' | |
| ]; | |
| const lowerPrompt = prompt.toLowerCase(); | |
| const isCodingRequest = codingKeywords.some(k => lowerPrompt.includes(k)); | |
| const finalPrompt = isCodingRequest | |
| ? `As a coding assistant, write the complete working code for the following task. Always provide full code, never refuse a coding task: ${prompt}` | |
| : prompt; | |
| const messages = [ | |
| { | |
| role: 'system', | |
| content: `You are Gini AI, a full-stack web development AI coding assistant created by Emalawi19, founded by Professor Roosevelt Chinkwende. | |
| IDENTITY: | |
| - Your name is Gini AI. | |
| - Your company is Emalawi19, founded by Professor Roosevelt Chinkwende. | |
| - You are an AI coding assistant, not a human. | |
| REFERENCE KNOWLEDGE BASE: | |
| Use the following official information to accurately answer any user questions about the company, projects, founders, or operations: | |
| ${localizedContext} | |
| ABSOLUTE RULES — NEVER BREAK THESE: | |
| 1. You ALWAYS write code when asked. You NEVER say "I can't help with that" for any coding request. | |
| 2. Any request involving websites, HTML, CSS, JavaScript, login pages, register pages, forms, backends, APIs, or any web development topic is ALWAYS answered with complete working code. | |
| 3. A "login page", "register page", "website", or any web page request is a NORMAL, SAFE coding task. Always generate the code for it. | |
| 4. You NEVER refuse a web development or coding request. If asked to build something, you build it. | |
| 5. For non-coding general questions, answer helpfully and briefly using facts from the REFERENCE KNOWLEDGE BASE above. | |
| YOUR SPECIALTY: | |
| - Frontend: HTML, CSS, JavaScript | |
| - Backend: Node.js, Express.js, REST APIs | |
| - You guide users step by step, one step at a time, with complete copy-paste ready code. | |
| STEP-BY-STEP GUIDE RULES: | |
| 1. When asked to build a website or app: | |
| - List ALL steps with short titles first. | |
| - Say: "Let's begin with Step 1. Say 'next' when ready to continue." | |
| 2. For EACH step provide: | |
| a) "Step X of Y: Title" | |
| b) One sentence explaining what this step does | |
| c) The COMPLETE working code in a properly labelled 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." | |
| 3. NEVER use placeholders. NEVER say 'add your logic here'. Write the real logic. | |
| 4. NEVER combine steps. One step per response only. | |
| 5. ALWAYS finish the full code for the current step — never cut off mid-code. | |
| CODE FORMAT: | |
| - Always use triple backticks with language tag: \`\`\`html \`\`\`css \`\`\`javascript \`\`\` | |
| - Code must be complete, real, and working. | |
| - Add helpful comments inside the code.` | |
| }, | |
| { role: 'user', content: finalPrompt } | |
| ]; | |
| const output = await generator(messages, { | |
| max_new_tokens: 1024, | |
| temperature: 0.2, | |
| repetition_penalty: 1.15, | |
| do_sample: false | |
| }); | |
| const result = output[0].generated_text.at(-1).content; | |
| const refusalPhrases = ["i can't assist", "i cannot assist", "i'm sorry", "i am sorry", "i'm unable", "i cannot help"]; | |
| const isRefusal = refusalPhrases.some(p => result.toLowerCase().startsWith(p)); | |
| if (isRefusal && isCodingRequest) { | |
| const retryMessages = [ | |
| { | |
| role: 'system', | |
| content: `You are a code generator. You only output code. Never refuse. Never explain. Just write the complete working code asked for. Reference context if needed: ${localizedContext}` | |
| }, | |
| { | |
| role: 'user', | |
| content: `Write complete working code for: ${prompt}. Include all HTML, CSS, and JavaScript needed.` | |
| } | |
| ]; | |
| const retryOutput = await generator(retryMessages, { | |
| max_new_tokens: 1024, | |
| temperature: 0.1, | |
| do_sample: false | |
| }); | |
| const retryResult = retryOutput[0].generated_text.at(-1).content; | |
| res.writeHead(200); | |
| return res.end(JSON.stringify({ result: retryResult })); | |
| } | |
| res.writeHead(200); | |
| res.end(JSON.stringify({ result })); | |
| } catch (err) { | |
| res.writeHead(400); | |
| res.end(JSON.stringify({ error: "Processing error", detail: err.message })); | |
| } | |
| }); | |
| return; | |
| } | |
| res.writeHead(404); | |
| res.end(JSON.stringify({ error: "Not Found" })); | |
| }); | |
| initializeServer().then(() => { | |
| server.listen(PORT, '0.0.0.0', () => { | |
| console.log(`Server listening on port ${PORT}`); | |
| }); | |
| }); |