обавлен перевод промптов через 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) {
|
||||
setNotificationTitle('Ошибка перевода');
|
||||
setNotificationMessage('Не удалось перевести промпт. Генерация отменена.');
|
||||
setNotificationMessage('Не удалось перевести промпт. Генерация отменена. Пожалуйста, попробуйте другой промпт или повторите попытку позже.');
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -149,8 +149,8 @@ async generateImage(imageData: string, style?: string, promptId?: string, userPr
|
||||
if (userPrompt && promptId === 'customPrompt') {
|
||||
console.log('Переводим пользовательский промпт:', userPrompt);
|
||||
|
||||
// Переводим промпт с 3 попытками
|
||||
const translationResult = await translateService.translateToEnglish(userPrompt, 3);
|
||||
// Используем новый метод перевода через LLM
|
||||
const translationResult = await translateService.translateWithLLM(userPrompt);
|
||||
|
||||
if (translationResult.success) {
|
||||
// Успешный перевод
|
||||
@ -159,7 +159,7 @@ async generateImage(imageData: string, style?: string, promptId?: string, userPr
|
||||
usedPrompt = translationResult.text;
|
||||
} else {
|
||||
// Перевод не удался после всех попыток
|
||||
console.error('Не удалось перевести промпт после нескольких попыток');
|
||||
console.error('Не удалось перевести промпт ни через одну из моделей');
|
||||
translationFailed = true;
|
||||
|
||||
// Не продолжаем генерацию, возвращаем ошибку
|
||||
|
||||
@ -1,5 +1,17 @@
|
||||
// URL для LibreTranslate API (сохраняем, но не используем)
|
||||
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 {
|
||||
translatedText: string;
|
||||
detectedLanguage: {
|
||||
@ -9,7 +21,28 @@ interface TranslateResponse {
|
||||
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 = {
|
||||
// Старый метод перевода через LibreTranslate (сохраняем, но не используем)
|
||||
async translateToEnglish(text: string, maxRetries = 3): Promise<{ success: boolean; text: string }> {
|
||||
let retries = 0;
|
||||
|
||||
@ -50,6 +83,91 @@ const translateService = {
|
||||
// Все попытки исчерпаны, возвращаем исходный текст с флагом неудачи
|
||||
console.error(`All ${maxRetries} translation attempts failed`);
|
||||
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