code refactored to have one method to calculate the final prompt. see #580
This commit is contained in:
parent
a505f22261
commit
b08b8563d0
5 changed files with 67 additions and 104 deletions
|
|
@ -1900,9 +1900,6 @@
|
|||
"auto_summary_failed": {
|
||||
"message": "Failed to generate AI summary. Please confirm your settings and try again."
|
||||
},
|
||||
"auto_summary_prompt": {
|
||||
"message": "Please provide a concise summary of the following email message. The summary should be 3-5 sentences maximum and capture the main points:\n\n"
|
||||
},
|
||||
"customPrompts_export_include_api_settings": {
|
||||
"message": "Do you want to include the API settings in the export? Be aware that also the API Key will be saved in the file!",
|
||||
"description": ""
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ mzta-background.js (checks summarize_auto + summarize_display_mode prefs)
|
|||
| `js/mzta-prompts.js` | Prompt definitions (built-in) and custom prompt loading |
|
||||
| `js/mzta-placeholders.js` | Placeholder definitions and resolution logic |
|
||||
| `js/mzta-utils.js` | General utilities (email parsing, storage helpers, etc.) |
|
||||
| `js/mzta-utils-prompt.js` | Prompt-specific utilities (text truncation, lang injection) |
|
||||
| `js/mzta-utils-prompt.js` | Prompt-specific utilities (text truncation, lang injection, `buildSummaryPrompt()` for unified summary prompt assembly) |
|
||||
| `js/mzta-compose-script.js` | Content script for compose and message display: injects AI response into compose window, renders summary/spam banners in message display |
|
||||
| `js/mzta-chatgpt.js` | ChatGPT Web integration (opens browser window, reads DOM) |
|
||||
| `js/mzta-special-commands.js` | Handles special prompt actions (add_tags, calendar, task) |
|
||||
|
|
|
|||
|
|
@ -74,13 +74,17 @@ The summarize feature uses two distinct prompt pathways:
|
|||
- Default prompt texts are stored as i18n keys: `prompt_summarize_full_text`, `prompt_summarize_email_template_full_text`, `prompt_summarize_email_separator_full_text`
|
||||
|
||||
**Inline Summary on Message Display** (automatic or manual per `summarize_auto` pref):
|
||||
- Uses a single i18n string `auto_summary_prompt` concatenated with the message body text
|
||||
- Does **not** use the 3 special prompts above
|
||||
- Uses the same 3 special prompts as webchat mode, via `taPromptUtils.buildSummaryPrompt()` in `js/mzta-utils-prompt.js`
|
||||
- Does **not** support `chatgpt_web` connection type (shows error if configured)
|
||||
- Result is rendered as a styled banner at the top of the message body via `mzta-compose-script.js`
|
||||
- Banner includes a refresh button (↻) to regenerate the summary
|
||||
- Cached per-message via `taSummaryStore` / `taStorage` (max 100 entries)
|
||||
|
||||
**Unified Prompt Building** — `taPromptUtils.buildSummaryPrompt(messageDataArray)`:
|
||||
- All summary paths (inline, webchat single, webchat multi) use this single method
|
||||
- Accepts an array of `{ message, fullMessage }` entries
|
||||
- Returns `{ promptText, promptInfo }` where `promptInfo` is the `prompt_summarize` prompt object
|
||||
|
||||
## Prompt Types Reference
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -17,7 +17,12 @@
|
|||
*/
|
||||
|
||||
import { placeholdersUtils } from './mzta-placeholders.js';
|
||||
import { extractJsonObject } from './mzta-utils.js';
|
||||
import {
|
||||
extractJsonObject,
|
||||
getMailBody,
|
||||
htmlBodyToPlainText
|
||||
} from './mzta-utils.js';
|
||||
import { getSpecialPrompts } from './mzta-prompts.js';
|
||||
import { prefs_default } from '../options/mzta-options-default.js';
|
||||
|
||||
export const taPromptUtils = {
|
||||
|
|
@ -126,6 +131,48 @@ export const taPromptUtils = {
|
|||
return chatgpt_lang;
|
||||
},
|
||||
|
||||
|
||||
async buildSummaryPrompt(messageDataArray) {
|
||||
const specialPrompts = await getSpecialPrompts();
|
||||
const prompt = specialPrompts.find(p => p.id === 'prompt_summarize');
|
||||
const prompt_email = specialPrompts.find(p => p.id === 'prompt_summarize_email_template');
|
||||
const prompt_email_separator = specialPrompts.find(p => p.id === 'prompt_summarize_email_separator');
|
||||
|
||||
const chatgpt_lang = await taPromptUtils.getDefaultLang(prompt);
|
||||
|
||||
const prompt_string = await taPromptUtils.preparePrompt({
|
||||
curr_prompt: prompt,
|
||||
chatgpt_lang: chatgpt_lang,
|
||||
});
|
||||
const prompt_email_separator_string = await taPromptUtils.preparePrompt({
|
||||
curr_prompt: prompt_email_separator,
|
||||
chatgpt_lang: chatgpt_lang,
|
||||
});
|
||||
|
||||
const messages_list = [];
|
||||
for (let entry of messageDataArray) {
|
||||
const bodyHtml = getMailBody(entry.fullMessage);
|
||||
let bodyText = htmlBodyToPlainText(bodyHtml.html);
|
||||
if (bodyText.length === 0) {
|
||||
bodyText = bodyHtml.text || '';
|
||||
}
|
||||
|
||||
messages_list.push(await taPromptUtils.preparePrompt({
|
||||
curr_prompt: prompt_email,
|
||||
curr_message: entry.message,
|
||||
chatgpt_lang: chatgpt_lang,
|
||||
body_text: bodyText,
|
||||
subject_text: entry.fullMessage.headers.subject,
|
||||
msg_text: bodyHtml,
|
||||
}));
|
||||
}
|
||||
|
||||
const messages_string = messages_list.join(prompt_email_separator_string);
|
||||
const promptText = prompt_string + prompt_email_separator_string + messages_string;
|
||||
|
||||
return { promptText, promptInfo: prompt };
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts tags from the response text.
|
||||
* @param {string} response_text - The response text from which to extract tags.
|
||||
|
|
|
|||
|
|
@ -58,8 +58,7 @@ import {
|
|||
import { taPromptUtils } from './js/mzta-utils-prompt.js';
|
||||
import { mzta_specialCommand } from './js/mzta-special-commands.js';
|
||||
import {
|
||||
getSpamFilterPrompt,
|
||||
getSpecialPrompts
|
||||
getSpamFilterPrompt
|
||||
} from './js/mzta-prompts.js';
|
||||
import { taSpamReport } from './js/mzta-spamreport.js';
|
||||
import { taSummaryStore } from './js/mzta-summarystore.js';
|
||||
|
|
@ -484,13 +483,6 @@ async function _generateSummaryForMessage(headerMessageId, tabId) {
|
|||
}
|
||||
|
||||
const fullMessage = await browser.messages.getFull(messageResult.messages[0].id);
|
||||
const mailBody = getMailBody(fullMessage);
|
||||
let bodyText = htmlBodyToPlainText(mailBody.html);
|
||||
if (bodyText.length === 0) {
|
||||
bodyText = mailBody.text.replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
|
||||
const promptText = browser.i18n.getMessage('auto_summary_prompt') + bodyText;
|
||||
|
||||
const connectionType = getConnectionType(prefs, {}, 'summarize');
|
||||
|
||||
|
|
@ -501,6 +493,8 @@ async function _generateSummaryForMessage(headerMessageId, tabId) {
|
|||
return;
|
||||
}
|
||||
|
||||
const { promptText } = await taPromptUtils.buildSummaryPrompt([{ message: messageResult.messages[0], fullMessage }]);
|
||||
|
||||
const cmd = new mzta_specialCommand({
|
||||
prompt: promptText,
|
||||
llm: connectionType,
|
||||
|
|
@ -532,22 +526,6 @@ async function _generateSummaryForMessage(headerMessageId, tabId) {
|
|||
|
||||
async function _openSummaryWebchat(headerMessageId, tabId) {
|
||||
try {
|
||||
const specialPrompts = await getSpecialPrompts();
|
||||
const prompt = specialPrompts.find(p => p.id === 'prompt_summarize');
|
||||
const prompt_email = specialPrompts.find(p => p.id === 'prompt_summarize_email_template');
|
||||
const prompt_email_separator = specialPrompts.find(p => p.id === 'prompt_summarize_email_separator');
|
||||
|
||||
const chatgpt_lang = await taPromptUtils.getDefaultLang(prompt);
|
||||
|
||||
const prompt_string = await taPromptUtils.preparePrompt({
|
||||
curr_prompt: prompt,
|
||||
chatgpt_lang: chatgpt_lang,
|
||||
});
|
||||
const prompt_email_separator_string = await taPromptUtils.preparePrompt({
|
||||
curr_prompt: prompt_email_separator,
|
||||
chatgpt_lang: chatgpt_lang,
|
||||
});
|
||||
|
||||
const messageResult = await browser.messages.query({ headerMessageId: headerMessageId });
|
||||
if (!messageResult || messageResult.messages.length === 0) {
|
||||
console.error("[ThunderAI] _openSummaryWebchat: Message not found for headerMessageId:", headerMessageId);
|
||||
|
|
@ -556,24 +534,10 @@ async function _openSummaryWebchat(headerMessageId, tabId) {
|
|||
|
||||
const curr_message = messageResult.messages[0];
|
||||
const curr_message_full = await browser.messages.getFull(curr_message.id);
|
||||
const curr_body_full_html = getMailBody(curr_message_full);
|
||||
let curr_body_full_text = htmlBodyToPlainText(curr_body_full_html.html);
|
||||
if (curr_body_full_text.length === 0) {
|
||||
curr_body_full_text = curr_body_full_html.text;
|
||||
}
|
||||
|
||||
const email_text = await taPromptUtils.preparePrompt({
|
||||
curr_prompt: prompt_email,
|
||||
curr_message: curr_message,
|
||||
chatgpt_lang: chatgpt_lang,
|
||||
body_text: curr_body_full_text,
|
||||
subject_text: curr_message_full.headers.subject,
|
||||
msg_text: curr_body_full_html,
|
||||
});
|
||||
const { promptText, promptInfo } = await taPromptUtils.buildSummaryPrompt([{ message: curr_message, fullMessage: curr_message_full }]);
|
||||
|
||||
const full_prompt = prompt_string + prompt_email_separator_string + email_text;
|
||||
|
||||
openChatGPT(full_prompt, prompt.action, tabId, prompt.name, prompt.need_custom_text, prompt);
|
||||
openChatGPT(promptText, promptInfo.action, tabId, promptInfo.name, promptInfo.need_custom_text, promptInfo);
|
||||
} catch (error) {
|
||||
console.error("[ThunderAI] Error opening summary webchat:", error);
|
||||
}
|
||||
|
|
@ -1464,63 +1428,14 @@ async function processEmails(args) {
|
|||
await _generateSummaryForMessage(messageArray[0].headerMessageId, tabId);
|
||||
} else {
|
||||
// Webchat mode, or inline with multiple messages (fallback to webchat)
|
||||
// we have three prompts, the actual assignment for the LLM, the email
|
||||
// template prompt, and the email separator prompt
|
||||
const specialPrompts = await getSpecialPrompts();
|
||||
const prompt = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize');
|
||||
const prompt_email = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize_email_template');
|
||||
const prompt_email_separator = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize_email_separator');
|
||||
|
||||
const chatgpt_lang = await taPromptUtils.getDefaultLang(prompt);
|
||||
|
||||
// replace placeholders in the prompts the assignment prompt and email
|
||||
// separator prompt do not have a message as context, so there is only
|
||||
// limited things to replace
|
||||
const prompt_string = await taPromptUtils.preparePrompt({
|
||||
curr_prompt: prompt,
|
||||
chatgpt_lang: chatgpt_lang,
|
||||
});
|
||||
const prompt_email_separator_string = await taPromptUtils.preparePrompt({
|
||||
curr_prompt: prompt_email_separator,
|
||||
chatgpt_lang: chatgpt_lang,
|
||||
});
|
||||
|
||||
|
||||
// assemble all email messages into one string and add the assignment prompt
|
||||
const messages_list = [];
|
||||
const messageDataArray = [];
|
||||
for (let curr_message of messageArray) {
|
||||
const fullMessage = await browser.messages.getFull(curr_message.id);
|
||||
messageDataArray.push({ message: curr_message, fullMessage });
|
||||
}
|
||||
const { promptText, promptInfo } = await taPromptUtils.buildSummaryPrompt(messageDataArray);
|
||||
|
||||
// extract body of current message as text
|
||||
const curr_message_full = await browser.messages.getFull(curr_message.id);
|
||||
const curr_body_full_html = getMailBody(curr_message_full);
|
||||
let curr_body_full_text = htmlBodyToPlainText(curr_body_full_html.html);
|
||||
if( curr_body_full_text.length === 0) {
|
||||
taLog.log("No HTML found in the message body, using plain text...");
|
||||
curr_body_full_text = curr_message_full.text;
|
||||
}
|
||||
|
||||
messages_list.push(await taPromptUtils.preparePrompt({
|
||||
curr_prompt: prompt_email,
|
||||
curr_message: curr_message,
|
||||
chatgpt_lang: chatgpt_lang,
|
||||
body_text: curr_body_full_text,
|
||||
subject_text: curr_message_full.headers.subject,
|
||||
msg_text: curr_body_full_html,
|
||||
}));
|
||||
};
|
||||
const messages_string = messages_list.join(prompt_email_separator_string);
|
||||
|
||||
const full_prompt = prompt_string + prompt_email_separator_string + messages_string;
|
||||
|
||||
// send the prompt to the chat interface
|
||||
openChatGPT(
|
||||
full_prompt,
|
||||
prompt.action,
|
||||
tabId,
|
||||
prompt.name,
|
||||
prompt.need_custom_text,
|
||||
prompt
|
||||
);
|
||||
openChatGPT(promptText, promptInfo.action, tabId, promptInfo.name, promptInfo.need_custom_text, promptInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue