feat(imggen): авто-перевод промпта на английский перед FLUX
FLUX лучше понимает английский. Если в промпте есть кириллица — прогоняем через тот же LLM-провайдер ассистента (callLLMFailover, с failover) и отправляем перевод. При сбое перевода — исходный текст. callLLMFailover теперь экспортируется из assistantController. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -616,4 +616,4 @@ async function flashcardsFromText(req, res) {
|
|||||||
res.json({ title, cards });
|
res.json({ title, cards });
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { getContext, markSeen, dismiss, setSettings, ask, flashcardsFromText, feedback, getMemory, clearMemory, getStudentProfile, llmConfig, pingLLM, clearFailover: _clearFailover };
|
module.exports = { getContext, markSeen, dismiss, setSettings, ask, flashcardsFromText, feedback, getMemory, clearMemory, getStudentProfile, llmConfig, pingLLM, clearFailover: _clearFailover, callLLMFailover };
|
||||||
|
|||||||
@@ -17,6 +17,23 @@ function _cfg() {
|
|||||||
}
|
}
|
||||||
function _enabled() { const c = _cfg(); return !!(c && c.provider === 'cloudflare' && c.accountId && c.token); }
|
function _enabled() { const c = _cfg(); return !!(c && c.provider === 'cloudflare' && c.accountId && c.token); }
|
||||||
|
|
||||||
|
/* FLUX лучше понимает английский. Если в промпте есть кириллица — переводим
|
||||||
|
* через тот же LLM-провайдер, что и ассистент (с failover). При сбое — исходный текст. */
|
||||||
|
async function _toEnglish(prompt) {
|
||||||
|
if (!/[Ѐ-ӿ]/.test(prompt)) return prompt;
|
||||||
|
try {
|
||||||
|
const { callLLMFailover } = require('./assistantController');
|
||||||
|
const sys = 'You translate image-generation prompts into concise, vivid English. ' +
|
||||||
|
'Output ONLY the English prompt — no quotes, no notes, no preamble. Keep it short and descriptive.';
|
||||||
|
const r = await callLLMFailover([{ role: 'system', content: sys }, { role: 'user', content: prompt }], 120);
|
||||||
|
if (r && r.text) {
|
||||||
|
const en = String(r.text).replace(/^["'«»\s]+|["'«»\s]+$/g, '').replace(/\s+/g, ' ').trim();
|
||||||
|
if (en && !/[Ѐ-ӿ]/.test(en)) return en.slice(0, 500);
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
return prompt; // перевод не удался — отправим как есть
|
||||||
|
}
|
||||||
|
|
||||||
/* GET /api/imggen/status — для UI (показывать кнопки или нет) */
|
/* GET /api/imggen/status — для UI (показывать кнопки или нет) */
|
||||||
function status(req, res) { res.json({ enabled: _enabled() }); }
|
function status(req, res) { res.json({ enabled: _enabled() }); }
|
||||||
|
|
||||||
@@ -35,13 +52,15 @@ async function generate(req, res) {
|
|||||||
if (d && d.day === today && d.count >= DAILY_CAP) return res.status(429).json({ error: 'Дневной лимит генераций исчерпан, попробуй завтра' });
|
if (d && d.day === today && d.count >= DAILY_CAP) return res.status(429).json({ error: 'Дневной лимит генераций исчерпан, попробуй завтра' });
|
||||||
_cooldown.set(uid, now);
|
_cooldown.set(uid, now);
|
||||||
|
|
||||||
|
const enPrompt = await _toEnglish(prompt);
|
||||||
|
|
||||||
const ctrl = new AbortController();
|
const ctrl = new AbortController();
|
||||||
const timer = setTimeout(() => ctrl.abort(), 30000);
|
const timer = setTimeout(() => ctrl.abort(), 30000);
|
||||||
try {
|
try {
|
||||||
const r = await fetch(`https://api.cloudflare.com/client/v4/accounts/${cfg.accountId}/ai/run/${cfg.model}`, {
|
const r = await fetch(`https://api.cloudflare.com/client/v4/accounts/${cfg.accountId}/ai/run/${cfg.model}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { Authorization: 'Bearer ' + cfg.token, 'Content-Type': 'application/json' },
|
headers: { Authorization: 'Bearer ' + cfg.token, 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ prompt, steps: 4 }),
|
body: JSON.stringify({ prompt: enPrompt, steps: 4 }),
|
||||||
signal: ctrl.signal,
|
signal: ctrl.signal,
|
||||||
});
|
});
|
||||||
if (!r.ok) { const t = await r.text(); return res.status(502).json({ error: 'Сервис картинок ответил ошибкой (' + r.status + ')', detail: t.slice(0, 120) }); }
|
if (!r.ok) { const t = await r.text(); return res.status(502).json({ error: 'Сервис картинок ответил ошибкой (' + r.status + ')', detail: t.slice(0, 120) }); }
|
||||||
|
|||||||
Reference in New Issue
Block a user