Spaces:
Paused
Paused
File size: 8,904 Bytes
123428d 1d0e0ac 123428d b842db9 1d0e0ac 123428d 1d0e0ac 682e491 1d0e0ac 123428d 682e491 1d0e0ac 123428d 0b19b33 5171cc2 0b19b33 123428d 0b19b33 123428d 1d0e0ac 123428d 0b19b33 123428d 1d0e0ac 123428d c75af14 682e491 1d0e0ac 682e491 e93b7d1 682e491 806be1c e93b7d1 806be1c e93b7d1 682e491 e93b7d1 1d0e0ac 682e491 1d0e0ac e93b7d1 682e491 e93b7d1 b842db9 e93b7d1 682e491 e93b7d1 682e491 e93b7d1 c75af14 b842db9 e93b7d1 b842db9 1d0e0ac 123428d c75af14 e93b7d1 682e491 e93b7d1 682e491 e93b7d1 682e491 e93b7d1 123428d c75af14 c91dd81 123428d 1d0e0ac 123428d 1d0e0ac 123428d 1d0e0ac 123428d 1d0e0ac 123428d | 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 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | 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 = {};
// 1. Load the single file and automatically parse [TOPIC: XXX] blocks
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);
}
}
// 2. 100% Automated Router - Searches user prompt against loaded keys
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..." }));
}
// Run prompt router to fetch targeted text injection
const localizedContext = getRelevantContext(prompt);
// Detect if it is a programming/coding request
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;
// Core base prompt with static company identity and localized file data
let systemPrompt = `You are Gini AI, an AI full-stack development 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, not a human.
REFERENCE KNOWLEDGE BASE:
Use the following official documentation to accurately answer any user questions about operations or topics:
${localizedContext}`;
// Inject dynamic behavior rules dependent on the intent type
if (isCodingRequest) {
systemPrompt += `
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 web development or script building is ALWAYS answered with complete working code blocks.
3. You guide users step by step, one step at a time, with complete copy-paste ready code.
4. 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."
5. NEVER use placeholders like '// add your logic here'. Write the actual working logic.
6. NEVER combine steps. One step per response only.
7. 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 \`\`\``;
} else {
systemPrompt += `
RULES FOR GENERAL ASSISTANCE:
1. Answer the user's question clearly, helpfully, and accurately using facts from the REFERENCE KNOWLEDGE BASE block above.
2. DO NOT write or generate programming code (like JavaScript, HTML, or Node.js scripts) unless explicitly requested by the user.
3. Keep your formatting clean using concise paragraphs or scannable bullet points.`;
}
const messages = [
{ role: 'system', content: systemPrompt },
{ 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;
// Safety fallback mechanism for false refusal flags on coding inputs
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.`
},
{
role: 'user',
content: `Write complete working code for: ${prompt}. Include all elements required.`
}
];
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}`);
});
}); |