fix: local generation, regenerate button, API via ?api=

This commit is contained in:
Dauren777 2026-06-19 06:28:35 +00:00
parent 43d99a9468
commit 2c520a96c0
2 changed files with 101 additions and 69 deletions

159
script.js
View File

@ -1,4 +1,6 @@
const API_URL = window.location.origin + '/api';
// Настройка: если запустили server.py на другом хосте/порте,
// укажите URL здесь или добавьте ?api=http://host:8000 к URL страницы
const API_URL = new URLSearchParams(window.location.search).get('api') || '';
const promptInput = document.getElementById('promptInput');
const tempSlider = document.getElementById('tempSlider');
@ -10,94 +12,113 @@ const generate5Btn = document.getElementById('generate5Btn');
const outputArea = document.getElementById('outputArea');
const statusMsg = document.getElementById('statusMsg');
tempSlider.addEventListener('input', () => {
tempVal.textContent = tempSlider.value;
});
topkSlider.addEventListener('input', () => {
topkVal.textContent = topkSlider.value;
});
tempSlider.addEventListener('input', () => { tempVal.textContent = tempSlider.value; });
topkSlider.addEventListener('input', () => { topkVal.textContent = topkSlider.value; });
generateBtn.addEventListener('click', () => generate(1));
generate5Btn.addEventListener('click', () => generate(5));
// ---------------------------------------------------------------------------
// Client-side clickbait generator (fallback / default)
// ---------------------------------------------------------------------------
const TEMPLATES = [
'этот секрет знают единицы',
'врачи в шоке от этого открытия',
'ты не поверишь что произошло дальше',
'всего один ингредиент меняет всё',
'вот почему никто не говорит об этом',
'результат превзошёл все ожидания',
'это должен знать каждый',
'никто не ожидал такого поворота',
'учёные озадачены этим феноменом',
'это изменит вашу жизнь навсегда',
'вы будете в шоке от правды',
'самое важное о чём молчат СМИ',
'это открытие перевернуло науку',
'простые вещи которые творят чудеса',
'теперь это знает весь мир',
'о чём вам не расскажут в школе',
'главный секрет успешных людей',
'это работает безотказно',
'вы упускаете это каждый день',
'пора узнать правду'
];
const PREFIXES = ['', 'невероятно но ', 'шокирующе но ', 'оказывается ', 'представьте себе '];
function pick(arr, seed) {
const idx = Math.abs(seed * 7 + seed * seed * 31) % arr.length;
return arr[idx];
}
function localGenerate(prompt, temperature, top_k, count) {
const now = Date.now();
const results = [];
for (let i = 0; i < count; i++) {
const seed = now + i * 137 + Math.floor(temperature * 100) + top_k;
const prefix = pick(PREFIXES, seed + 3);
const template = prompt
? `${prompt}${pick(TEMPLATES, seed + 7)}`
: pick(TEMPLATES, seed + 11);
const extra = temperature > 1.3
? (pick(['невероятно', 'шокирующе', 'фантастически'], seed + 19) + ' ')
: '';
results.push(prefix + extra + template);
}
return results;
}
// ---------------------------------------------------------------------------
// Main generation
// ---------------------------------------------------------------------------
async function generate(count) {
const prompt = promptInput.value.trim();
const temperature = parseFloat(tempSlider.value);
const top_k = parseInt(topkSlider.value);
outputArea.innerHTML = '';
statusMsg.textContent = 'Генерация...';
statusMsg.textContent = '⚡ Генерируем...';
statusMsg.className = 'status-msg';
try {
const res = await fetch(`${API_URL}/generate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt,
temperature,
top_k,
num_samples: count
})
});
let texts;
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err.detail || `Ошибка ${res.status}`);
if (API_URL) {
try {
const res = await fetch(`${API_URL}/generate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt, temperature, top_k, num_samples: count })
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
texts = data.texts;
} catch {
texts = localGenerate(prompt, temperature, top_k, count);
}
const data = await res.json();
statusMsg.textContent = '';
statusMsg.className = 'status-msg';
data.texts.forEach((text, i) => {
const div = document.createElement('div');
div.className = 'gen-output-item';
if (count > 1) {
div.innerHTML = `<span class="gen-badge">#${i + 1}</span>${text}...😱`;
} else {
div.textContent = `${text}...😱`;
}
outputArea.appendChild(div);
});
} catch (err) {
statusMsg.textContent = '❌ Сервер недоступен. Запустите API: python server.py';
statusMsg.className = 'status-msg error';
fallbackGenerate(count, prompt, temperature, top_k);
} else {
texts = localGenerate(prompt, temperature, top_k, count);
}
}
function fallbackGenerate(count, prompt, temperature, top_k) {
const templates = [
prompt
? `${prompt} — этот секрет знают единицы`
: 'Этот секрет знают единицы',
prompt
? `${prompt} — врачи в шоке от открытия`
: 'Врачи в шоке от этого открытия',
prompt
? `${prompt} — ты не поверишь что произошло`
: 'Ты не поверишь что произошло дальше',
prompt
? `${prompt} — всего один ингредиент меняет всё`
: 'Всего один ингредиент меняет всё',
prompt
? `${prompt} — вот почему никто не говорит об этом`
: 'Вот почему никто не говорит об этом'
];
statusMsg.textContent = '';
statusMsg.className = 'status-msg';
outputArea.innerHTML = '';
for (let i = 0; i < count && i < templates.length; i++) {
texts.forEach((text, i) => {
const div = document.createElement('div');
div.className = 'gen-output-item';
if (count > 1) {
div.innerHTML = `<span class="gen-badge">#${i + 1}</span>${templates[i]}...😱`;
} else {
div.textContent = `${templates[i]}...😱`;
}
div.style.animationDelay = `${i * 0.08}s`;
const label = count > 1 ? `<span class="gen-badge">#${i + 1}</span>` : '';
div.innerHTML = `${label}${text}...😱`;
outputArea.appendChild(div);
}
});
// Regenerate button
const reBtn = document.createElement('button');
reBtn.className = 'btn btn-secondary btn-regenerate';
reBtn.textContent = '🔄 Сгенерировать ещё';
reBtn.addEventListener('click', () => generate(count));
outputArea.appendChild(reBtn);
}
// Example tabs

View File

@ -127,6 +127,17 @@ body {
color: var(--cyan);
}
.btn-regenerate {
margin-top: 16px;
font-size: 14px;
padding: 10px 20px;
align-self: flex-start;
}
.gen-output .btn-regenerate {
align-self: flex-start;
}
/* Sections */
.section {
padding: 80px 0;