console.log("--> SERVER STARTING..."); import express from 'express'; // --- DYNAMIC IMPORT --- let SystemMessage, HumanMessage, AIMessage, LlamaCppLLM; try { const module = await import('./src/index.js'); SystemMessage = module.SystemMessage; HumanMessage = module.HumanMessage; AIMessage = module.AIMessage; LlamaCppLLM = module.LlamaCppLLM; console.log("--> Modules loaded successfully"); } catch (e) { console.error("--> FATAL IMPORT ERROR:", e); } import bodyParser from 'body-parser'; import fs from 'fs'; import path from 'path'; // --- CONFIGURATION --- const PORT = 7860; const MODEL_PATH = './models/Qwen3-1.7B-Q8_0.gguf'; const MODEL_NAME = "dahanhstd-1.0"; // Tên model tùy chỉnh // --- LOAD PROMPTS --- const PROMPTS = { "default": "You are a helpful AI assistant. Answer concisely.", "talk2people": fs.existsSync('MasterPrompt_Talk2People.txt') ? fs.readFileSync('MasterPrompt_Talk2People.txt', 'utf-8') : "You are a creative Video Director specializing in realistic Vietnamese scenes.", "coder": "You are an expert programmer." }; // --- HTML TEMPLATE (GIAO DIỆN CHAT) --- const HTML_PAGE = ` Dạ Hành AI Studio
`; // --- AI ENGINE --- let llm = null; async function initModel() { if (!LlamaCppLLM) return; try { console.log('--> Loading model...'); if (!fs.existsSync(MODEL_PATH)) { console.error(`--> Model not found at ${MODEL_PATH}`); // Fallback: check if we are in /app return; } llm = new LlamaCppLLM({ modelPath: MODEL_PATH, temperature: 0.7, maxTokens: 1024, contextSize: 4096, // Limit context for speed threads: 4, // Maximize CPU usage (HF Space usually has 2-4 vCPU) batchSize: 512, // Process inputs faster f16Kv: true // Faster KV cache }); await llm.invoke("Hello"); console.log('--> Model loaded successfully.'); } catch (err) { console.error('--> FATAL MODEL ERROR:', err.message); } } // --- SERVER SETUP --- const app = express(); app.use(bodyParser.json()); // 1. API: CHAT (Public API for other apps) app.post('/chat', async (req, res) => { // API Response Format const apiResponse = { model: MODEL_NAME, created: Date.now(), reply: "", error: null }; if (!llm) { apiResponse.error = "System initializing or Model missing"; return res.status(503).json(apiResponse); } try { const { message, history = [], role = 'default' } = req.body; const systemInstruction = PROMPTS[role] || PROMPTS['default']; const messages = [new SystemMessage(systemInstruction)]; history.forEach(msg => { if (msg.role === 'user') messages.push(new HumanMessage(msg.content)); if (msg.role === 'ai') messages.push(new AIMessage(msg.content)); }); messages.push(new HumanMessage(message)); const response = await llm.invoke(messages); apiResponse.reply = response.content; res.json(apiResponse); } catch (error) { apiResponse.error = error.message; res.status(500).json(apiResponse); } }); // 2. API: INFO app.get('/info', (req, res) => { res.json({ model: MODEL_NAME, status: llm ? "ready" : "loading", roles: Object.keys(PROMPTS) }); }); // 3. UI: HOME PAGE (Direct HTML Render) app.get('/', (req, res) => { res.send(HTML_PAGE); }); app.listen(PORT, '0.0.0.0', () => { console.log(`--> Server listening on ${PORT}`); initModel(); });