fix: память только в браузере, сервер ничего не хранит

This commit is contained in:
2026-06-01 23:09:18 +03:00
parent edbcde0dcc
commit 55fb1f658b
2 changed files with 12 additions and 40 deletions
+7 -6
View File
@@ -52,7 +52,7 @@
let mediaRecorder, chunks = [], userBlob = null; let mediaRecorder, chunks = [], userBlob = null;
let isRecording = false, micAnalyser = null, micAnimId = null; let isRecording = false, micAnalyser = null, micAnimId = null;
let audioContext = null, sessionSid = null; let audioContext = null, chatHistory = [];
let thinkStart = 0, thinkTimer = null; let thinkStart = 0, thinkTimer = null;
// История — массив {q, a, time} // История — массив {q, a, time}
@@ -191,13 +191,15 @@
const cRes = await fetch('/api/chat', { const cRes = await fetch('/api/chat', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ model: 'gpt-oss-120b', message: text, sid: sessionSid }), body: JSON.stringify({ model: 'gpt-oss-120b', message: text, history: chatHistory }),
signal: (() => { const a = new AbortController(); setTimeout(() => a.abort(), 120000); return a.signal; })(), signal: (() => { const a = new AbortController(); setTimeout(() => a.abort(), 120000); return a.signal; })(),
}); });
stopThinkTimer(); stopThinkTimer();
const cData = await cRes.json(); const cData = await cRes.json();
if (cData.sid) sessionSid = cData.sid;
const resp = cData.response || cData.error || 'Ошибка'; const resp = cData.response || cData.error || 'Ошибка';
chatHistory.push({ role: 'user', content: text });
chatHistory.push({ role: 'assistant', content: resp });
if (chatHistory.length > 40) chatHistory = chatHistory.slice(-40);
chat.innerHTML += '<div class="bot">🤖 ' + fmt(resp) + '</div>'; chat.innerHTML += '<div class="bot">🤖 ' + fmt(resp) + '</div>';
chat.scrollTop = chat.scrollHeight; chat.scrollTop = chat.scrollHeight;
setStatus('✅ Готово — ' + ((Date.now() - thinkStart) / 1000).toFixed(1) + 'с'); setStatus('✅ Готово — ' + ((Date.now() - thinkStart) / 1000).toFixed(1) + 'с');
@@ -223,9 +225,8 @@
} }
function stopThinkTimer() { if (thinkTimer) { clearInterval(thinkTimer); thinkTimer = null; } } function stopThinkTimer() { if (thinkTimer) { clearInterval(thinkTimer); thinkTimer = null; } }
document.getElementById('btnReset').onclick = async () => { document.getElementById('btnReset').onclick = () => {
await fetch('/api/reset', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ sid: sessionSid }) }); chatHistory = []; chat.innerHTML = ''; setStatus('🧹 Очищено');
sessionSid = null; chat.innerHTML = ''; setStatus('🧹 Очищено');
}; };
</script> </script>
</body> </body>
+5 -34
View File
@@ -40,63 +40,34 @@ app.post('/api/whisper', upload.single('audio'), async (req, res) => {
} }
}); });
// ====== Session memory ======
const sessions = {}; // sessionId → messages[]
app.get('/api/history', (req, res) => {
const sid = req.query.sid || 'default';
res.json({ messages: sessions[sid] || [] });
});
app.post('/api/chat', async (req, res) => { app.post('/api/chat', async (req, res) => {
try { try {
const { model, message, sid, history } = req.body; const { model, message, history } = req.body;
const m = MODELS[model]; const m = MODELS[model];
if (!m) return res.status(400).json({ error: 'Неизвестная модель' }); if (!m) return res.status(400).json({ error: 'Неизвестная модель' });
// Собираем историю: system + предыдущие сообщения + новое
const id = sid || 'default';
const msgs = history || sessions[id] || [];
const fullMessages = [ const fullMessages = [
{ role: 'system', content: m.system }, { role: 'system', content: m.system },
...msgs, ...(history || []),
{ role: 'user', content: message || 'Привет' }, { role: 'user', content: message || 'Привет' },
]; ];
// Обрезаем чтобы не выйти за лимит токенов // Обрезаем чтобы не выйти за лимит
while (JSON.stringify(fullMessages).length > 32000 && fullMessages.length > 2) while (JSON.stringify(fullMessages).length > 32000 && fullMessages.length > 2)
fullMessages.splice(1, 2); fullMessages.splice(1, 2);
const r = await fetch(`${API_BASE}/v1/chat/completions`, { const r = await fetch(`${API_BASE}/v1/chat/completions`, {
method: 'POST', method: 'POST',
headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }, headers: { Authorization: `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({ model: m.id, temperature: m.temp, max_tokens: m.tokens, messages: fullMessages }),
model: m.id, temperature: m.temp, max_tokens: m.tokens,
messages: fullMessages,
}),
}); });
const data = await r.json(); const data = await r.json();
const response = data.choices?.[0]?.message?.content || 'Нет ответа'; res.json({ response: data.choices?.[0]?.message?.content || 'Нет ответа' });
// Сохраняем историю
sessions[id] = [
...msgs,
{ role: 'user', content: message },
{ role: 'assistant', content: response },
];
res.json({ response, sid: id });
} catch (e) { } catch (e) {
res.status(500).json({ error: e.message }); res.status(500).json({ error: e.message });
} }
}); });
app.post('/api/reset', (req, res) => {
const sid = req.body.sid || 'default';
delete sessions[sid];
res.json({ ok: true });
});
app.get('/', (_req, res) => res.sendFile(path.join(__dirname, 'public', 'index.html'))); app.get('/', (_req, res) => res.sendFile(path.join(__dirname, 'public', 'index.html')));
app.listen(PORT, () => console.log(`Say:${PORT}`)); app.listen(PORT, () => console.log(`Say:${PORT}`));