const http = require('http'); const fs = require('fs'); const path = require('path'); const url = require('url'); const PORT = process.env.PORT || 3000; function serveStatic(filePath, res) { if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) { res.writeHead(404, {'Content-Type':'text/plain'}); return res.end('Not found'); } const ext = path.extname(filePath).toLowerCase(); const map = {'.html':'text/html', '.css':'text/css', '.js':'application/javascript'}; res.writeHead(200, {'Content-Type': (map[ext]||'text/plain') + '; charset=utf-8'}); res.end(fs.readFileSync(filePath)); } async function fetchAlemTest() { // Expected env vars from Alem integration const base = process.env.ALEM_BASE_URL; const key = process.env.ALEM_API_KEY; const tmpl = process.env.ALEM_TEMPLATE_ID; if (!base || !key || !tmpl) return {error:'Alem not configured'}; // Create session const sessResp = await fetch(`${base}/api/v1/open-api/conversation`, { method:'POST', headers:{'Content-Type':'application/json','Authorization':'Bearer '+key}, body:JSON.stringify({template_id:tmpl,title:'SafetyTest',user_id:'vibe42_user'}) }); if (!sessResp.ok) return {error:'Alem session error'}; const sessBody = await sessResp.json(); const sid = sessBody && sessBody.data && sessBody.data.session_id; if (!sid) return {error:'No session_id'}; // Ask prompt const askResp = await fetch(`${base}/api/v1/open-api/conversation/${sid}/send`, { method:'POST', headers:{'Content-Type':'application/json','Authorization':'Bearer '+key}, body:JSON.stringify({content:'Сгенерируй тест из 10 вопросов по технике безопасности монтеров в Казахстане. Верни JSON массив вопросов с вариантами и правильным индексом.',user_id:'vibe42_user',model_api_key:key}) }); if (!askResp.ok) return {error:'Alem ask error'}; const raw = await askResp.text(); let answer = null; for (const line of raw.split('\n')) { const s = line.trim(); if (!s.startsWith('data:')) continue; const payload = s.slice(5).trim(); if (!payload || payload === '[DONE]') continue; try { const ev = JSON.parse(payload); if (ev && ev.detail && ev.detail.full_content) answer = ev.detail.full_content; } catch(e) {} } if (!answer) return {error:'No answer'}; // Expect answer to be JSON try { return JSON.parse(answer); } catch(e) { return {error:'Parse error',raw:answer}; } } http.createServer(async (req, res) => { const parsed = url.parse(req.url, true); if (parsed.pathname === '/api/generate') { const data = await fetchAlemTest(); res.writeHead(200, {'Content-Type':'application/json'}); return res.end(JSON.stringify(data)); } // static files let file = parsed.pathname === '/' ? '/index.html' : parsed.pathname; serveStatic(path.join(__dirname, file), res); }).listen(PORT, () => console.log('Server listening on '+PORT));