обавлен перевод промптов через OpenRouter API с использованием моделей LLM: 1) сновная модель: meta-llama/llama-3.3-70b-instruct:free 2) езервная модель: openchat/openchat-7b:free
This commit is contained in:
parent
7a58f26ead
commit
b18acdbad5
@ -70,7 +70,7 @@ const Home: React.FC = () => {
|
|||||||
// Проверяем, была ли ошибка перевода
|
// Проверяем, была ли ошибка перевода
|
||||||
if (response.translationFailed) {
|
if (response.translationFailed) {
|
||||||
setNotificationTitle('Ошибка перевода');
|
setNotificationTitle('Ошибка перевода');
|
||||||
setNotificationMessage('Не удалось перевести промпт. Генерация отменена.');
|
setNotificationMessage('Не удалось перевести промпт. Генерация отменена. Пожалуйста, попробуйте другой промпт или повторите попытку позже.');
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -149,8 +149,8 @@ async generateImage(imageData: string, style?: string, promptId?: string, userPr
|
|||||||
if (userPrompt && promptId === 'customPrompt') {
|
if (userPrompt && promptId === 'customPrompt') {
|
||||||
console.log('Переводим пользовательский промпт:', userPrompt);
|
console.log('Переводим пользовательский промпт:', userPrompt);
|
||||||
|
|
||||||
// Переводим промпт с 3 попытками
|
// Используем новый метод перевода через LLM
|
||||||
const translationResult = await translateService.translateToEnglish(userPrompt, 3);
|
const translationResult = await translateService.translateWithLLM(userPrompt);
|
||||||
|
|
||||||
if (translationResult.success) {
|
if (translationResult.success) {
|
||||||
// Успешный перевод
|
// Успешный перевод
|
||||||
@ -159,7 +159,7 @@ async generateImage(imageData: string, style?: string, promptId?: string, userPr
|
|||||||
usedPrompt = translationResult.text;
|
usedPrompt = translationResult.text;
|
||||||
} else {
|
} else {
|
||||||
// Перевод не удался после всех попыток
|
// Перевод не удался после всех попыток
|
||||||
console.error('Не удалось перевести промпт после нескольких попыток');
|
console.error('Не удалось перевести промпт ни через одну из моделей');
|
||||||
translationFailed = true;
|
translationFailed = true;
|
||||||
|
|
||||||
// Не продолжаем генерацию, возвращаем ошибку
|
// Не продолжаем генерацию, возвращаем ошибку
|
||||||
|
|||||||
@ -1,5 +1,17 @@
|
|||||||
|
// URL для LibreTranslate API (сохраняем, но не используем)
|
||||||
const TRANSLATE_API_URL = 'https://translate.maxdev.keenetic.pro/translate';
|
const TRANSLATE_API_URL = 'https://translate.maxdev.keenetic.pro/translate';
|
||||||
|
|
||||||
|
// URL и ключ для OpenRouter API
|
||||||
|
const OPENROUTER_API_URL = 'https://openrouter.ai/api/v1/chat/completions';
|
||||||
|
const OPENROUTER_API_KEY = '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';
|
||||||
|
|
||||||
|
// Модели для перевода
|
||||||
|
const TRANSLATION_MODELS = {
|
||||||
|
PRIMARY: 'meta-llama/llama-3.3-70b-instruct:free', // Основная модель
|
||||||
|
FALLBACK: 'openchat/openchat-7b:free', // Резервная модель
|
||||||
|
};
|
||||||
|
|
||||||
|
// Интерфейс для ответа от LibreTranslate API
|
||||||
interface TranslateResponse {
|
interface TranslateResponse {
|
||||||
translatedText: string;
|
translatedText: string;
|
||||||
detectedLanguage: {
|
detectedLanguage: {
|
||||||
@ -9,7 +21,28 @@ interface TranslateResponse {
|
|||||||
alternatives: string[];
|
alternatives: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Интерфейс для ответа от OpenRouter API
|
||||||
|
interface OpenRouterResponse {
|
||||||
|
choices: {
|
||||||
|
message: {
|
||||||
|
content: string;
|
||||||
|
role: string;
|
||||||
|
};
|
||||||
|
index: number;
|
||||||
|
finish_reason: string;
|
||||||
|
}[];
|
||||||
|
id: string;
|
||||||
|
model: string;
|
||||||
|
object: string;
|
||||||
|
usage: {
|
||||||
|
prompt_tokens: number;
|
||||||
|
completion_tokens: number;
|
||||||
|
total_tokens: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const translateService = {
|
const translateService = {
|
||||||
|
// Старый метод перевода через LibreTranslate (сохраняем, но не используем)
|
||||||
async translateToEnglish(text: string, maxRetries = 3): Promise<{ success: boolean; text: string }> {
|
async translateToEnglish(text: string, maxRetries = 3): Promise<{ success: boolean; text: string }> {
|
||||||
let retries = 0;
|
let retries = 0;
|
||||||
|
|
||||||
@ -50,6 +83,91 @@ const translateService = {
|
|||||||
// Все попытки исчерпаны, возвращаем исходный текст с флагом неудачи
|
// Все попытки исчерпаны, возвращаем исходный текст с флагом неудачи
|
||||||
console.error(`All ${maxRetries} translation attempts failed`);
|
console.error(`All ${maxRetries} translation attempts failed`);
|
||||||
return { success: false, text: text };
|
return { success: false, text: text };
|
||||||
|
},
|
||||||
|
|
||||||
|
// Новый метод перевода через OpenRouter API
|
||||||
|
async translateWithLLM(text: string): Promise<{ success: boolean; text: string }> {
|
||||||
|
// Массив моделей для последовательных попыток
|
||||||
|
const models = [
|
||||||
|
TRANSLATION_MODELS.PRIMARY,
|
||||||
|
TRANSLATION_MODELS.FALLBACK
|
||||||
|
];
|
||||||
|
|
||||||
|
// Проверка, что текст не пустой
|
||||||
|
if (!text || text.trim() === '') {
|
||||||
|
console.error('Пустой текст для перевода');
|
||||||
|
return { success: false, text };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка, что текст не на английском языке
|
||||||
|
const isAlreadyEnglish = /^[a-zA-Z0-9\s.,!?;:()\-"']+$/.test(text.trim());
|
||||||
|
if (isAlreadyEnglish) {
|
||||||
|
console.log('Текст уже на английском языке, перевод не требуется');
|
||||||
|
return { success: true, text };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Последовательно пробуем каждую модель
|
||||||
|
for (let i = 0; i < models.length; i++) {
|
||||||
|
const model = models[i];
|
||||||
|
console.log(`Попытка перевода через модель ${model} (${i + 1}/${models.length})`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(OPENROUTER_API_URL, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `Bearer ${OPENROUTER_API_KEY}`,
|
||||||
|
'HTTP-Referer': window.location.origin,
|
||||||
|
'X-Title': 'Sticker Generator App'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
model: model,
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
role: 'system',
|
||||||
|
content: 'You are a professional translator. Translate the following text from any language to English. Preserve the meaning and style. Only return the translated text without any additional comments or explanations.'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: 'user',
|
||||||
|
content: text
|
||||||
|
}
|
||||||
|
],
|
||||||
|
temperature: 0.3,
|
||||||
|
max_tokens: 200
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json().catch(() => ({}));
|
||||||
|
console.error(`Ошибка API для модели ${model}:`, errorData);
|
||||||
|
throw new Error(`OpenRouter API failed with status: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data: OpenRouterResponse = await response.json();
|
||||||
|
const translatedText = data.choices[0].message.content.trim();
|
||||||
|
|
||||||
|
// Проверка, что получили непустой ответ
|
||||||
|
if (!translatedText) {
|
||||||
|
throw new Error('Empty translation result');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка, что перевод отличается от исходного текста
|
||||||
|
if (translatedText.toLowerCase().trim() === text.toLowerCase().trim()) {
|
||||||
|
console.warn(`Модель ${model} вернула исходный текст без перевода`);
|
||||||
|
throw new Error('Translation returned original text');
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Успешный перевод через модель ${model}:`, translatedText);
|
||||||
|
return { success: true, text: translatedText };
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Ошибка перевода через модель ${model}:`, error);
|
||||||
|
// Продолжаем со следующей моделью, если она есть
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Если все модели не сработали
|
||||||
|
console.error('Все попытки перевода через LLM не удались');
|
||||||
|
return { success: false, text };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user