the translation prompt now returns a JSON. see #247
This commit is contained in:
parent
894d3475dd
commit
38f6b1987d
6 changed files with 63 additions and 12 deletions
|
|
@ -821,7 +821,7 @@
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"prompt_translate_this_full_text": {
|
"prompt_translate_this_full_text": {
|
||||||
"message": "Translate the following email in",
|
"message": "Translate the email below into {%thunderai_translate_lang%}.\n\nRules:\n- Translate both the subject and the body.\n- Return the result as a JSON object with three fields: \"subject\", \"body\" and \"status\".\n- If the translation has been done the status is equal to 1.\n- If the email is written in one of these languages \"{%thunderai_translate_exclude_lang%}\" or in the {%thunderai_translate_lang%} language, return an empty string for the body and the subject and set the status to -1.\n- Do not add explanations, notes, or any text outside the JSON.\n\nMail subject: {%mail_subject%}\n\nMail body: {%mail_html_body%}\n\nGenerate a response in JSON format only. The output should be only a JSON object. Here is an example of the JSON format to be used:\n{\n\"subject\": \"subject translation\",\n\"body\": \"body translation\",\n\"status\": \"status result\"\n}",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"prompt_this_full_text": {
|
"prompt_this_full_text": {
|
||||||
|
|
@ -2189,6 +2189,10 @@
|
||||||
"message": "Translation language is not configured. Please set a language in the Translation settings or set a default language in the General settings.",
|
"message": "Translation language is not configured. Please set a language in the Translation settings or set a default language in the General settings.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"translate_skipped": {
|
||||||
|
"message": "Translation skipped: Language excluded or identical to target.",
|
||||||
|
"description": "Shown in the translation banner when the email language matches the excluded or target language"
|
||||||
|
},
|
||||||
"antispam_by": {
|
"antispam_by": {
|
||||||
"message": "Antispam by",
|
"message": "Antispam by",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
|
||||||
|
|
@ -1255,14 +1255,22 @@ switch (message.command) {
|
||||||
translationText.style.cssText = 'white-space: pre-wrap; line-height: 1.5;';
|
translationText.style.cssText = 'white-space: pre-wrap; line-height: 1.5;';
|
||||||
if (translationData.error) {
|
if (translationData.error) {
|
||||||
translationText.textContent = translationData.message || browser.i18n.getMessage("translate_error");
|
translationText.textContent = translationData.message || browser.i18n.getMessage("translate_error");
|
||||||
|
} else if (translationData.translation_status === '-1') {
|
||||||
|
translationText.textContent = browser.i18n.getMessage("translate_skipped");
|
||||||
} else {
|
} else {
|
||||||
|
if (translationData.translated_subject) {
|
||||||
|
const subjectEl = document.createElement('div');
|
||||||
|
subjectEl.style.cssText = 'font-weight: bold; margin-bottom: 4px;';
|
||||||
|
subjectEl.textContent = translationData.translated_subject;
|
||||||
|
translationTextWrapper.appendChild(subjectEl);
|
||||||
|
}
|
||||||
translationText.textContent = translationData.translated_text || '';
|
translationText.textContent = translationData.translated_text || '';
|
||||||
}
|
}
|
||||||
translationTextWrapper.appendChild(translationText);
|
translationTextWrapper.appendChild(translationText);
|
||||||
|
|
||||||
const maxLenTranslation = translationData.maxDisplayLength || 0;
|
const maxLenTranslation = translationData.maxDisplayLength || 0;
|
||||||
const fullTranslationText = translationData.translated_text || '';
|
const fullTranslationText = translationData.translated_text || '';
|
||||||
if (!translationData.error && maxLenTranslation > 0 && fullTranslationText.length > maxLenTranslation) {
|
if (!translationData.error && translationData.translation_status !== '-1' && maxLenTranslation > 0 && fullTranslationText.length > maxLenTranslation) {
|
||||||
translationText.style.overflow = 'hidden';
|
translationText.style.overflow = 'hidden';
|
||||||
translationText.style.transition = 'max-height 0.2s ease';
|
translationText.style.transition = 'max-height 0.2s ease';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,15 @@ export class taStorage {
|
||||||
* @param {string} lang - Target language code.
|
* @param {string} lang - Target language code.
|
||||||
* @param {boolean} [force=true] - If true, overwrite existing translation data.
|
* @param {boolean} [force=true] - If true, overwrite existing translation data.
|
||||||
*/
|
*/
|
||||||
async writeTranslation(messageId, translated_text, lang, force = true, error = false, error_message = '') {
|
async writeTranslation(messageId, data, force = true) {
|
||||||
|
const {
|
||||||
|
translated_text = '',
|
||||||
|
translated_subject = '',
|
||||||
|
translation_status = '',
|
||||||
|
lang = '',
|
||||||
|
error = false,
|
||||||
|
message = '',
|
||||||
|
} = data || {};
|
||||||
this.taLog.log('[writeTranslation] messageId: ' + messageId + ', lang: ' + lang + ', force: ' + force);
|
this.taLog.log('[writeTranslation] messageId: ' + messageId + ', lang: ' + lang + ', force: ' + force);
|
||||||
try {
|
try {
|
||||||
let key = this._buildKey(messageId);
|
let key = this._buildKey(messageId);
|
||||||
|
|
@ -288,7 +296,15 @@ export class taStorage {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let now = Date.now();
|
let now = Date.now();
|
||||||
record[taStorage.FIELD_TRANSLATION] = { translated_text: translated_text, lang: lang, error: error, message: error_message, ts: now };
|
record[taStorage.FIELD_TRANSLATION] = {
|
||||||
|
translated_text,
|
||||||
|
translated_subject,
|
||||||
|
translation_status,
|
||||||
|
lang,
|
||||||
|
error,
|
||||||
|
message,
|
||||||
|
ts: now
|
||||||
|
};
|
||||||
record.ts = now;
|
record.ts = now;
|
||||||
await messenger.storage.local.set({ [key]: record });
|
await messenger.storage.local.set({ [key]: record });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ export class taTranslationStore {
|
||||||
async saveTranslation(data, data_id) {
|
async saveTranslation(data, data_id) {
|
||||||
this.taLog.log("[saveTranslation] data_id: " + data_id);
|
this.taLog.log("[saveTranslation] data_id: " + data_id);
|
||||||
try {
|
try {
|
||||||
await this._storage.writeTranslation(data_id, data.translated_text || '', data.lang || '', true, data.error || false, data.message || '');
|
await this._storage.writeTranslation(data_id, data, true);
|
||||||
await browser.storage.session.remove(this._processing_prefix + data_id);
|
await browser.storage.session.remove(this._processing_prefix + data_id);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.taLog.error("[saveTranslation] error: " + e);
|
this.taLog.error("[saveTranslation] error: " + e);
|
||||||
|
|
@ -81,6 +81,8 @@ export class taTranslationStore {
|
||||||
return {
|
return {
|
||||||
headerMessageId: data_id,
|
headerMessageId: data_id,
|
||||||
translated_text: translation.translated_text || '',
|
translated_text: translation.translated_text || '',
|
||||||
|
translated_subject: translation.translated_subject || '',
|
||||||
|
translation_status: translation.translation_status || '',
|
||||||
lang: translation.lang || '',
|
lang: translation.lang || '',
|
||||||
error: translation.error || false,
|
error: translation.error || false,
|
||||||
message: translation.message || '',
|
message: translation.message || '',
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ export const taPromptUtils = {
|
||||||
return { promptText, promptInfo: prompt };
|
return { promptText, promptInfo: prompt };
|
||||||
},
|
},
|
||||||
|
|
||||||
async buildTranslationPrompt(fullMessage, lang) {
|
async buildTranslationPrompt(fullMessage) {
|
||||||
const specialPrompts = await getSpecialPrompts();
|
const specialPrompts = await getSpecialPrompts();
|
||||||
const prompt = specialPrompts.find(p => p.id === 'prompt_translate_this');
|
const prompt = specialPrompts.find(p => p.id === 'prompt_translate_this');
|
||||||
|
|
||||||
|
|
@ -183,12 +183,19 @@ export const taPromptUtils = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const bodyHtml = getMailBody(fullMessage);
|
const bodyHtml = getMailBody(fullMessage);
|
||||||
let bodyText = htmlBodyToPlainText(bodyHtml.html);
|
const mailSubject = fullMessage.headers?.subject?.[0] || '';
|
||||||
if (bodyText.length === 0) {
|
|
||||||
bodyText = bodyHtml.text || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const fullPrompt = promptText + " " + lang + ". \"" + bodyText + "\"";
|
const finalSubs = await placeholdersUtils.getPlaceholdersValues({
|
||||||
|
prompt_text: promptText,
|
||||||
|
msg_text: { html: bodyHtml.html, text: bodyHtml.text },
|
||||||
|
mail_subject: mailSubject,
|
||||||
|
});
|
||||||
|
|
||||||
|
const fullPrompt = placeholdersUtils.replacePlaceholders({
|
||||||
|
text: promptText,
|
||||||
|
replacements: finalSubs,
|
||||||
|
use_default_value: false,
|
||||||
|
});
|
||||||
|
|
||||||
return { promptText: fullPrompt, promptInfo: prompt };
|
return { promptText: fullPrompt, promptInfo: prompt };
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -789,8 +789,22 @@ async function _generateTranslationForMessage(headerMessageId, tabId = null, opt
|
||||||
await cmd.initWorker();
|
await cmd.initWorker();
|
||||||
const aiResponse = await cmd.sendPrompt();
|
const aiResponse = await cmd.sendPrompt();
|
||||||
|
|
||||||
|
let translatedBody = '';
|
||||||
|
let translatedSubject = '';
|
||||||
|
let translationStatus = '';
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(aiResponse);
|
||||||
|
translatedBody = parsed.body || '';
|
||||||
|
translatedSubject = parsed.subject || '';
|
||||||
|
translationStatus = String(parsed.status || '');
|
||||||
|
} catch (e) {
|
||||||
|
translatedBody = aiResponse;
|
||||||
|
}
|
||||||
|
|
||||||
const translationData = {
|
const translationData = {
|
||||||
translated_text: aiResponse,
|
translated_text: translatedBody,
|
||||||
|
translated_subject: translatedSubject,
|
||||||
|
translation_status: translationStatus,
|
||||||
lang: lang,
|
lang: lang,
|
||||||
headerMessageId: headerMessageId
|
headerMessageId: headerMessageId
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue