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 });
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
/* 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 (показывать кнопки или нет) */
|
||||
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: 'Дневной лимит генераций исчерпан, попробуй завтра' });
|
||||
_cooldown.set(uid, now);
|
||||
|
||||
const enPrompt = await _toEnglish(prompt);
|
||||
|
||||
const ctrl = new AbortController();
|
||||
const timer = setTimeout(() => ctrl.abort(), 30000);
|
||||
try {
|
||||
const r = await fetch(`https://api.cloudflare.com/client/v4/accounts/${cfg.accountId}/ai/run/${cfg.model}`, {
|
||||
method: 'POST',
|
||||
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,
|
||||
});
|
||||
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