67 lines
2.9 KiB
JavaScript
67 lines
2.9 KiB
JavaScript
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));
|