Merge upstream v3.8.0 changes, preserving auto_summary_enabled setting
This commit is contained in:
commit
ea402a688b
37 changed files with 2678 additions and 922 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
|
@ -4,6 +4,18 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Version 3.8.0 - ??/??/2025</h2>
|
||||||
|
<ul>
|
||||||
|
<li><i>[All APIs]</i> When using special prompts (like automatically adding tags or the spam filter) with a specific API integration, all the settings for that integration can be specific. In this way you can use different api keys for the same integration, or different system prompt or temperature [<a href="https://github.com/micz/ThunderAI/pull/590">#590</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> Added the temperature parameter [<a href="https://github.com/micz/ThunderAI/issues/561">#561</a>].</li>
|
||||||
|
<li><i>[OpenAI API]</i> Model filtering improved when choosing a model in the options page.</li>
|
||||||
|
<li><i>[OpenAI API]</i> Now using the new Responses API [<a href="https://github.com/micz/ThunderAI/issues/407">#407</a>].</li>
|
||||||
|
<li>It is now possible to define a custom placeholder with dynamic data to retrieve any header present in the current email [<a href="https://github.com/micz/ThunderAI/issues/527">#527</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> The configuration information reported in the webchat API has been improved for all integrations.</li>
|
||||||
|
<li>Spanish (es) translation added, thanks to <a href="https://hosted.weblate.org/user/gerardo.sobarzo/">Gerardo Sobarzo</a>, <a href="https://hosted.weblate.org/user/arendon/">Andrés Rendón Hernández</a>, <a href="https://hosted.weblate.org/user/ErickLimonG/">Erick Limon</a>.</li>
|
||||||
|
<li>Various fixes.</li>
|
||||||
|
<li>...</li>
|
||||||
|
</ul>
|
||||||
<h2>Version 3.7.8 - 18/12/2025</h2>
|
<h2>Version 3.7.8 - 18/12/2025</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Greek (el) translation added, thanks to <a href="https://github.com/christoskaterini">ChristosK.</a>.</li>
|
<li>Greek (el) translation added, thanks to <a href="https://github.com/christoskaterini">ChristosK.</a>.</li>
|
||||||
|
|
|
||||||
1
LANG.md
1
LANG.md
|
|
@ -2,6 +2,7 @@ cs
|
||||||
de
|
de
|
||||||
el
|
el
|
||||||
en
|
en
|
||||||
|
es
|
||||||
fr
|
fr
|
||||||
hr
|
hr
|
||||||
it
|
it
|
||||||
|
|
|
||||||
|
|
@ -90,8 +90,9 @@ Are you using this addon in your Thunderbird?
|
||||||
- Greek (el): [ChristosK.](https://github.com/christoskaterini) <img src="https://micz.it/weblate/thunderai/el.svg">
|
- Greek (el): [ChristosK.](https://github.com/christoskaterini) <img src="https://micz.it/weblate/thunderai/el.svg">
|
||||||
- Italian (it): [Mic](https://github.com/micz) <img src="https://micz.it/weblate/thunderai/it.svg">
|
- Italian (it): [Mic](https://github.com/micz) <img src="https://micz.it/weblate/thunderai/it.svg">
|
||||||
- Polski (pl): [neexpl](https://github.com/neexpl), [makkacprzak](https://github.com/makkacprzak) <img src="https://micz.it/weblate/thunderai/pl.svg">
|
- Polski (pl): [neexpl](https://github.com/neexpl), [makkacprzak](https://github.com/makkacprzak) <img src="https://micz.it/weblate/thunderai/pl.svg">
|
||||||
- Russian (ru): [Maksim](https://hosted.weblate.org/user/law820314/) <img src="https://micz.it/weblate/thunderai/ru.svg">
|
|
||||||
- Português Brasileiro (pt-br): Bruno Pereira de Souza <img src="https://micz.it/weblate/thunderai/pt-br.svg">
|
- Português Brasileiro (pt-br): Bruno Pereira de Souza <img src="https://micz.it/weblate/thunderai/pt-br.svg">
|
||||||
|
- Russian (ru): [Maksim](https://hosted.weblate.org/user/law820314/) <img src="https://micz.it/weblate/thunderai/ru.svg">
|
||||||
|
- Spanish (es): [Gerardo Sobarzo](https://hosted.weblate.org/user/gerardo.sobarzo/), [Andrés Rendón Hernández](https://hosted.weblate.org/user/arendon/), [Erick Limon](https://hosted.weblate.org/user/ErickLimonG/) <img src="https://micz.it/weblate/thunderai/es.svg">
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
Do you want to help translate this addon? [Find out how!](https://micz.it/thunderbird-addon-thunderai/translate/) <br>
|
Do you want to help translate this addon? [Find out how!](https://micz.it/thunderbird-addon-thunderai/translate/) <br>
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,10 @@
|
||||||
"message": "More info",
|
"message": "More info",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"prompt_string":{
|
||||||
|
"message": "Prompt",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"customPrompts_managePrompts_info_default": {
|
"customPrompts_managePrompts_info_default": {
|
||||||
"message": "The default prompts are not editable. You can disable them, then copy the prompt text and paste it into a new one to create a modified version.",
|
"message": "The default prompts are not editable. You can disable them, then copy the prompt text and paste it into a new one to create a modified version.",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -619,6 +623,10 @@
|
||||||
"message": "Folder path",
|
"message": "Folder path",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"placeholder_mail_headers": {
|
||||||
|
"message": "Mail headers",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"placeholder_selected_text": {
|
"placeholder_selected_text": {
|
||||||
"message": "Selected text",
|
"message": "Selected text",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -855,6 +863,10 @@
|
||||||
"message": "Reset to default",
|
"message": "Reset to default",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"reset": {
|
||||||
|
"message": "Reset",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"addtags_excl_list_infoline2": {
|
"addtags_excl_list_infoline2": {
|
||||||
"message": "Add a word per line, or separated by a comma.",
|
"message": "Add a word per line, or separated by a comma.",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1492,7 +1504,7 @@
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_anthropic_max_tokens": {
|
"prefs_OptionText_anthropic_max_tokens": {
|
||||||
"message": "Claude Max Tokens",
|
"message": "Max Tokens",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_anthropic_max_tokens_Info": {
|
"prefs_OptionText_anthropic_max_tokens_Info": {
|
||||||
|
|
@ -1569,6 +1581,14 @@
|
||||||
"message": "If checked, your chats will be stored by OpenAI.",
|
"message": "If checked, your chats will be stored by OpenAI.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"prefs_chatgpt_api_temperature_Info": {
|
||||||
|
"message": "What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_ollama_temperature_Info": {
|
||||||
|
"message": "The temperature of the model. Increasing the temperature will make the model answer more creatively. The default value is 0.8. It is recommended to use values between 0 and 1.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"prefs_ollama_think": {
|
"prefs_ollama_think": {
|
||||||
"message": "Enable thinking",
|
"message": "Enable thinking",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1665,6 +1685,14 @@
|
||||||
"message": "Are you sure you want to clear the Models List? This action cannot be undone.",
|
"message": "Are you sure you want to clear the Models List? This action cannot be undone.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"prefs_api_temperature": {
|
||||||
|
"message": "Temperature",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_openai_comp_temperature_Info": {
|
||||||
|
"message": "What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"chatgpt_click_force_completion": {
|
"chatgpt_click_force_completion": {
|
||||||
"message": "It seems that it's not possible to get if ChatGPT has finished. Click here to force the completion of the job.",
|
"message": "It seems that it's not possible to get if ChatGPT has finished. Click here to force the completion of the job.",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1681,6 +1709,10 @@
|
||||||
"message": "Define the number of tokens to be used for thinking. Leave this field blank if the selected model does not support thinking or if you want to use the default method. Enter 0 to disable thinking, or -1 to enable dynamic thinking.",
|
"message": "Define the number of tokens to be used for thinking. Leave this field blank if the selected model does not support thinking or if you want to use the default method. Enter 0 to disable thinking, or -1 to enable dynamic thinking.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"prefs_google_gemini_temperature_Info": {
|
||||||
|
"message": "This parameter must be a number between 0.0 and 2.0. It controls the randomness of the output. The default value varies depending on the model. Leave it empty to avoid setting the parameter in the API call.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"SelectAll": {
|
"SelectAll": {
|
||||||
"message": "Select All",
|
"message": "Select All",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1697,6 +1729,10 @@
|
||||||
"message": "You can improve Claude performance by using a System Prompt to give it a role. This technique, known as role prompting, is the most powerful way to use system prompts with Claude. The right role can turn Claude from a general assistant into your virtual domain expert.",
|
"message": "You can improve Claude performance by using a System Prompt to give it a role. This technique, known as role prompting, is the most powerful way to use system prompts with Claude. The right role can turn Claude from a general assistant into your virtual domain expert.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"prefs_anthropic_temperature_Info": {
|
||||||
|
"message": "Amount of randomness injected into the response. Defaults to 1.0. Ranges from 0.0 to 1.0. Use temperature closer to 0.0 for analytical / multiple choice, and closer to 1.0 for creative and generative tasks. Note that even with temperature of 0.0, the results will not be fully deterministic.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"Optional_Permission_Denied_Model_Fetching": {
|
"Optional_Permission_Denied_Model_Fetching": {
|
||||||
"message": "You have denied the optional permission needed to fetch models for this integration.",
|
"message": "You have denied the optional permission needed to fetch models for this integration.",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1107,7 +1107,7 @@
|
||||||
"message": "Version de l’API Claude"
|
"message": "Version de l’API Claude"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_anthropic_max_tokens": {
|
"prefs_OptionText_anthropic_max_tokens": {
|
||||||
"message": "Nombre maximum de jetons Claude"
|
"message": "Nombre maximum de jetons"
|
||||||
},
|
},
|
||||||
"anthropic_api_request_failed": {
|
"anthropic_api_request_failed": {
|
||||||
"message": "Échec de la requête à l'API Claude"
|
"message": "Échec de la requête à l'API Claude"
|
||||||
|
|
@ -1312,12 +1312,28 @@
|
||||||
"Optional_Permission_Denied_Model_Fetching": {
|
"Optional_Permission_Denied_Model_Fetching": {
|
||||||
"message": "Vous avez refusé l’autorisation facultative nécessaire pour récupérer les modèles pour cette intégration."
|
"message": "Vous avez refusé l’autorisation facultative nécessaire pour récupérer les modèles pour cette intégration."
|
||||||
},
|
},
|
||||||
"prefs_OptionText_auto_summary": {
|
"prompt_string": {
|
||||||
"message": "Activer la synthèse automatique par IA pour les aperçus de messages",
|
"message": "Prompt"
|
||||||
"description": ""
|
|
||||||
},
|
},
|
||||||
"prefs_OptionText_auto_summary_Info": {
|
"placeholder_mail_headers": {
|
||||||
"message": "Si cette option est cochée, ThunderAI générera et affichera automatiquement des synthèses par IA au-dessus des messages électroniques lorsqu'ils sont ouverts. Notez que cela signifie que tous les messages que vous prévisualisez seront immédiatement envoyés au service IA configuré.",
|
"message": "En-têtes d'e-mail"
|
||||||
"description": ""
|
},
|
||||||
|
"prefs_chatgpt_api_temperature_Info": {
|
||||||
|
"message": "Quelle température d'échantillonnage utiliser, entre 0 et 2. Des valeurs plus élevées comme 0,8 rendront le résultat plus aléatoire, tandis que des valeurs plus basses comme 0,2 le rendront plus ciblé et déterministe."
|
||||||
|
},
|
||||||
|
"prefs_ollama_temperature_Info": {
|
||||||
|
"message": "La température du modèle. Augmenter la température rendra les réponses du modèle plus créatives. La valeur par défaut est 0,8. Il est recommandé d'utiliser des valeurs comprises entre 0 et 1."
|
||||||
|
},
|
||||||
|
"prefs_api_temperature": {
|
||||||
|
"message": "Température"
|
||||||
|
},
|
||||||
|
"prefs_openai_comp_temperature_Info": {
|
||||||
|
"message": "Quelle température d'échantillonnage utiliser, entre 0 et 2. Des valeurs plus élevées, comme 0,8, rendront le résultat plus aléatoire, tandis que des valeurs plus basses, comme 0,2, le rendront plus ciblé et déterministe."
|
||||||
|
},
|
||||||
|
"prefs_google_gemini_temperature_Info": {
|
||||||
|
"message": "Ce paramètre doit être un nombre compris entre 0,0 et 2,0. Il contrôle le caractère aléatoire du résultat. La valeur par défaut varie selon le modèle. Laissez ce champ vide pour ne pas définir le paramètre dans l'appel d'API."
|
||||||
|
},
|
||||||
|
"prefs_anthropic_temperature_Info": {
|
||||||
|
"message": "Degré d'aléa injecté dans la réponse. La valeur par défaut est 1,0. La plage de valeurs s'étend di 0,0 à 1,0. Utilisez une température proche de 0,0 pour des tâches analytiques ou des choix multiples, et proche de 1,0 pour des tâches créatives et génératives. Notez que même avec une température de 0,0, les résultats ne seront pas totalement déterministes."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
71
_locales/sv/messages.json
Normal file
71
_locales/sv/messages.json
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
{
|
||||||
|
"extensionDescription": {
|
||||||
|
"message": "Använd ChatGPT, Google Gemini, Claude eller Ollama för att förbättra dina e-postmeddelanden!"
|
||||||
|
},
|
||||||
|
"menu_title": {
|
||||||
|
"message": "AI"
|
||||||
|
},
|
||||||
|
"customPrompts_btnEdit": {
|
||||||
|
"message": "Redigera"
|
||||||
|
},
|
||||||
|
"customPrompts_btnCancel": {
|
||||||
|
"message": "Avbryt"
|
||||||
|
},
|
||||||
|
"customPrompts_btnOK": {
|
||||||
|
"message": "Ok"
|
||||||
|
},
|
||||||
|
"customPrompts_btnDelete": {
|
||||||
|
"message": "Ta bort"
|
||||||
|
},
|
||||||
|
"customPrompts_btnDelete_confirmText": {
|
||||||
|
"message": "Är du säker på att du vill ta bort det här objektet?"
|
||||||
|
},
|
||||||
|
"customPrompts_unsaved_changes": {
|
||||||
|
"message": "Det finns osparade ändringar!"
|
||||||
|
},
|
||||||
|
"btnSaveAll_string": {
|
||||||
|
"message": "Spara alla"
|
||||||
|
},
|
||||||
|
"chatgpt_win_close": {
|
||||||
|
"message": "Stäng"
|
||||||
|
},
|
||||||
|
"customPrompts_add_to_menu_always": {
|
||||||
|
"message": "Alltid"
|
||||||
|
},
|
||||||
|
"Date": {
|
||||||
|
"message": "Datum"
|
||||||
|
},
|
||||||
|
"prompt_selection_needed": {
|
||||||
|
"message": "För att fortsätta måste du markera lite text!"
|
||||||
|
},
|
||||||
|
"customPrompts_form_label_Name": {
|
||||||
|
"message": "Namn"
|
||||||
|
},
|
||||||
|
"customPrompts_form_label_Action": {
|
||||||
|
"message": "Åtgärd"
|
||||||
|
},
|
||||||
|
"customPrompts_form_label_enabled": {
|
||||||
|
"message": "Aktiverad"
|
||||||
|
},
|
||||||
|
"btnNew_string": {
|
||||||
|
"message": "Lägg till ny"
|
||||||
|
},
|
||||||
|
"chatgpt_btn_retry": {
|
||||||
|
"message": "Försöka igen"
|
||||||
|
},
|
||||||
|
"placeholder_selected_html": {
|
||||||
|
"message": "Vald HTML"
|
||||||
|
},
|
||||||
|
"placeholder_additional_text": {
|
||||||
|
"message": "Ytterligare text"
|
||||||
|
},
|
||||||
|
"chatgpt_win_send": {
|
||||||
|
"message": "Skicka"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_chatgpt_win_height": {
|
||||||
|
"message": "Höjd"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_chatgpt_win_width": {
|
||||||
|
"message": "Bredd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
* The original code has been released under the Apache License, Version 2.0.
|
* The original code has been released under the Apache License, Version 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from '../options/mzta-options-default.js';
|
import { prefs_default, integration_options_config } from '../options/mzta-options-default.js';
|
||||||
import { placeholdersUtils } from '../js/mzta-placeholders.js';
|
import { placeholdersUtils } from '../js/mzta-placeholders.js';
|
||||||
import { getAPIsInitMessageString, convertNewlinesToBr } from '../js/mzta-utils.js';
|
import { getAPIsInitMessageString, convertNewlinesToBr } from '../js/mzta-utils.js';
|
||||||
|
|
||||||
|
|
@ -46,224 +46,161 @@ const messagesArea = document.querySelector('messages-area');
|
||||||
// The controller wires up all the components and workers together,
|
// The controller wires up all the components and workers together,
|
||||||
// managing the dependencies. A kind of "DI" class.
|
// managing the dependencies. A kind of "DI" class.
|
||||||
let worker = null;
|
let worker = null;
|
||||||
|
const integration = llm.replace('_api', '');
|
||||||
|
const worker_path_map = {
|
||||||
|
chatgpt: '../js/workers/model-worker-openai_responses.js',
|
||||||
|
google_gemini: '../js/workers/model-worker-google_gemini.js',
|
||||||
|
ollama: '../js/workers/model-worker-ollama.js',
|
||||||
|
openai_comp: '../js/workers/model-worker-openai_comp.js',
|
||||||
|
anthropic: '../js/workers/model-worker-anthropic.js',
|
||||||
|
};
|
||||||
|
|
||||||
switch (llm) {
|
const worker_path = worker_path_map[integration];
|
||||||
case "chatgpt_api":
|
|
||||||
worker = new Worker('../js/workers/model-worker-openai.js', { type: 'module' });
|
if (worker_path) {
|
||||||
break;
|
worker = new Worker(worker_path, { type: 'module' });
|
||||||
case "google_gemini_api":
|
} else {
|
||||||
worker = new Worker('../js/workers/model-worker-google_gemini.js', { type: 'module' });
|
console.error('[ThunderAI] API WebChat Unknown LLM type:', llm);
|
||||||
break;
|
|
||||||
case "ollama_api":
|
|
||||||
worker = new Worker('../js/workers/model-worker-ollama.js', { type: 'module' });
|
|
||||||
break;
|
|
||||||
case "openai_comp_api":
|
|
||||||
worker = new Worker('../js/workers/model-worker-openai_comp.js', { type: 'module' });
|
|
||||||
break;
|
|
||||||
case "anthropic_api":
|
|
||||||
worker = new Worker('../js/workers/model-worker-anthropic.js', { type: 'module' });
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.error('[ThunderAI] API WebChat Unknown LLM type:', llm);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
messagesArea.init(worker);
|
if (worker) {
|
||||||
|
messagesArea.init(worker);
|
||||||
|
messageInput.init(worker);
|
||||||
|
messageInput.setMessagesArea(messagesArea);
|
||||||
|
|
||||||
// Initialize the messageInput component and pass the worker to it
|
if (integration_options_config[integration]) {
|
||||||
messageInput.init(worker);
|
const integration_prefix = integration;
|
||||||
messageInput.setMessagesArea(messagesArea);
|
const options_config = integration_options_config[integration];
|
||||||
|
|
||||||
switch (llm) {
|
let prefsToGet = { do_debug: prefs_default.do_debug };
|
||||||
case "chatgpt_api": {
|
for (const key in options_config) {
|
||||||
let prefs_api = await browser.storage.sync.get({
|
prefsToGet[`${integration_prefix}_${key}`] = prefs_default[`${integration_prefix}_${key}`];
|
||||||
chatgpt_api_key: prefs_default.chatgpt_api_key,
|
|
||||||
chatgpt_model: prefs_default.chatgpt_model,
|
|
||||||
chatgpt_developer_messages: prefs_default.chatgpt_developer_messages,
|
|
||||||
chatgpt_api_store: prefs_default.chatgpt_api_store,
|
|
||||||
do_debug: prefs_default.do_debug,
|
|
||||||
});
|
|
||||||
let i18nStrings = {};
|
|
||||||
i18nStrings["chatgpt_api_request_failed"] = browser.i18n.getMessage('chatgpt_api_request_failed');
|
|
||||||
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
|
|
||||||
messageInput.setModel(prefs_api.chatgpt_model);
|
|
||||||
messagesArea.setLLMName("ChatGPT");
|
|
||||||
worker.postMessage({
|
|
||||||
type: 'init',
|
|
||||||
chatgpt_api_key: prefs_api.chatgpt_api_key,
|
|
||||||
chatgpt_model: prefs_api.chatgpt_model,
|
|
||||||
chatgpt_developer_messages: prefs_api.chatgpt_developer_messages,
|
|
||||||
chatgpt_api_store: prefs_api.chatgpt_api_store,
|
|
||||||
do_debug: prefs_api.do_debug,
|
|
||||||
i18nStrings: i18nStrings,
|
|
||||||
});
|
|
||||||
let additional_text_elements = [];
|
|
||||||
additional_text_elements.push({label: 'OpenAI Store', value: (prefs_api.chatgpt_api_store ? 'Yes' : 'No')});
|
|
||||||
if(prefs_api.chatgpt_developer_messages && prefs_api.chatgpt_developer_messages.length > 0) {
|
|
||||||
additional_text_elements.push({label: browser.i18n.getMessage("ChatGPT_Developer_Messages"), value: prefs_api.chatgpt_developer_messages});
|
|
||||||
}
|
}
|
||||||
additional_text_elements.push({label: "Prompt", value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)});
|
if (integration === 'openai_comp') {
|
||||||
messagesArea.appendUserMessage(getAPIsInitMessageString({
|
prefsToGet.openai_comp_chat_name = prefs_default.openai_comp_chat_name;
|
||||||
api_string: "ChatGPT API",
|
|
||||||
model_string: prefs_api.chatgpt_model,
|
|
||||||
additional_messages: additional_text_elements
|
|
||||||
}), "info");
|
|
||||||
browser.runtime.sendMessage({
|
|
||||||
command: "openai_api_ready_" + call_id,
|
|
||||||
window_id: (await browser.windows.getCurrent()).id
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "google_gemini_api": {
|
|
||||||
let prefs_api = await browser.storage.sync.get({
|
|
||||||
google_gemini_api_key: prefs_default.google_gemini_api_key,
|
|
||||||
google_gemini_model: prefs_default.google_gemini_model,
|
|
||||||
google_gemini_system_instruction: prefs_default.google_gemini_system_instruction,
|
|
||||||
google_gemini_thinking_budget: prefs_default.google_gemini_thinking_budget,
|
|
||||||
do_debug: prefs_default.do_debug,
|
|
||||||
});
|
|
||||||
let i18nStrings = {};
|
|
||||||
i18nStrings["google_gemini_api_request_failed"] = browser.i18n.getMessage('google_gemini_api_request_failed');
|
|
||||||
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
|
|
||||||
messageInput.setModel(prefs_api.google_gemini_model);
|
|
||||||
messagesArea.setLLMName("Google Gemini");
|
|
||||||
let additional_text_elements = [];
|
|
||||||
if(prefs_api.google_gemini_system_instruction && prefs_api.google_gemini_system_instruction.length > 0) {
|
|
||||||
additional_text_elements.push({label: browser.i18n.getMessage("GoogleGemini_SystemInstruction"), value: prefs_api.google_gemini_system_instruction});
|
|
||||||
}
|
}
|
||||||
additional_text_elements.push({label: 'Thinking Budget', value: prefs_api.google_gemini_thinking_budget});
|
|
||||||
additional_text_elements.push({label: "Prompt", value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)});
|
let prefs_api = await browser.storage.sync.get(prefsToGet);
|
||||||
worker.postMessage({
|
|
||||||
|
let i18nStrings = {};
|
||||||
|
const i18n_msg_key = integration === 'openai_comp' ? 'OpenAIComp_api_request_failed' : `${integration}_api_request_failed`;
|
||||||
|
i18nStrings[i18n_msg_key] = browser.i18n.getMessage(i18n_msg_key);
|
||||||
|
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
|
||||||
|
|
||||||
|
messageInput.setModel(prefs_api[`${integration_prefix}_model`]);
|
||||||
|
|
||||||
|
let llmName = "API";
|
||||||
|
switch(integration) {
|
||||||
|
case 'chatgpt': llmName = "ChatGPT"; break;
|
||||||
|
case 'google_gemini': llmName = "Google Gemini"; break;
|
||||||
|
case 'ollama': llmName = "Ollama Local"; break;
|
||||||
|
case 'openai_comp': llmName = prefs_api.openai_comp_chat_name || "OpenAI Comp"; break;
|
||||||
|
case 'anthropic': llmName = "Claude"; break;
|
||||||
|
}
|
||||||
|
messagesArea.setLLMName(llmName);
|
||||||
|
|
||||||
|
let workerInitMessage = {
|
||||||
type: 'init',
|
type: 'init',
|
||||||
google_gemini_api_key: prefs_api.google_gemini_api_key,
|
|
||||||
google_gemini_model: prefs_api.google_gemini_model,
|
|
||||||
google_gemini_system_instruction: prefs_api.google_gemini_system_instruction,
|
|
||||||
google_gemini_thinking_budget: prefs_api.google_gemini_thinking_budget,
|
|
||||||
do_debug: prefs_api.do_debug,
|
do_debug: prefs_api.do_debug,
|
||||||
i18nStrings: i18nStrings,
|
i18nStrings: i18nStrings,
|
||||||
});
|
};
|
||||||
messagesArea.appendUserMessage(getAPIsInitMessageString({
|
|
||||||
api_string: "Google Gemini API",
|
for (const key in options_config) {
|
||||||
model_string: prefs_api.google_gemini_model,
|
const prefKey = `${integration_prefix}_${key}`;
|
||||||
additional_messages: additional_text_elements
|
workerInitMessage[prefKey] = prefs_api[prefKey];
|
||||||
}), "info");
|
}
|
||||||
browser.runtime.sendMessage({
|
|
||||||
command: "google_gemini_api_ready_" + call_id,
|
worker.postMessage(workerInitMessage);
|
||||||
window_id: (await browser.windows.getCurrent()).id
|
|
||||||
});
|
const additional_messages_config = {
|
||||||
break;
|
chatgpt: [
|
||||||
}
|
{ key: 'store', labelKey: 'ChatGPT_chatgpt_api_store', type: 'boolean' },
|
||||||
case "ollama_api": {
|
{ key: 'developer_messages', labelKey: 'ChatGPT_Developer_Messages', type: 'string' },
|
||||||
let prefs_api = await browser.storage.sync.get({
|
{ key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' }
|
||||||
ollama_host: prefs_default.ollama_host,
|
],
|
||||||
ollama_model: prefs_default.ollama_model,
|
google_gemini: [
|
||||||
ollama_num_ctx: prefs_default.ollama_num_ctx,
|
{ key: 'system_instruction', labelKey: 'GoogleGemini_SystemInstruction', type: 'string' },
|
||||||
ollama_think: prefs_default.ollama_think,
|
{ key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' },
|
||||||
do_debug: prefs_default.do_debug,
|
{ key: 'thinking_budget', labelKey: 'prefs_google_gemini_thinking_budget', type: 'string' }
|
||||||
});
|
],
|
||||||
let i18nStrings = {};
|
ollama: [
|
||||||
i18nStrings["ollama_api_request_failed"] = browser.i18n.getMessage('ollama_api_request_failed');
|
{ key: 'think', labelKey: 'prefs_ollama_think', type: 'boolean' },
|
||||||
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
|
{ key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' },
|
||||||
messageInput.setModel(prefs_api.ollama_model);
|
{ key: 'num_ctx', labelKey: 'prefs_ollama_num_ctx', type: 'number_gt_zero' }
|
||||||
messagesArea.setLLMName("Ollama Local");
|
],
|
||||||
worker.postMessage({
|
openai_comp: [
|
||||||
type: 'init',
|
{ key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' }
|
||||||
ollama_host: prefs_api.ollama_host,
|
],
|
||||||
ollama_model: prefs_api.ollama_model,
|
anthropic: [
|
||||||
ollama_num_ctx: prefs_api.ollama_num_ctx,
|
{ key: 'system_prompt', labelKey: 'Anthropic_System_Prompt', type: 'string' },
|
||||||
ollama_think: prefs_api.ollama_think,
|
{ key: 'max_tokens', labelKey: 'prefs_OptionText_anthropic_max_tokens', type: 'number_gt_zero' },
|
||||||
do_debug: prefs_api.do_debug,
|
{ key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' }
|
||||||
i18nStrings: i18nStrings
|
]
|
||||||
});
|
};
|
||||||
browser.runtime.sendMessage({
|
|
||||||
command: "ollama_api_ready_" + call_id,
|
const getAdditionalMessages = (integration, prefs) => {
|
||||||
window_id: (await browser.windows.getCurrent()).id
|
const messages = [];
|
||||||
});
|
const config = additional_messages_config[integration];
|
||||||
|
if (!config) return messages;
|
||||||
|
|
||||||
|
for (const item of config) {
|
||||||
|
const prefKey = `${integration}_${item.key}`;
|
||||||
|
const value = prefs[prefKey];
|
||||||
|
|
||||||
|
if (value !== undefined && value !== null && value !== '') {
|
||||||
|
let displayValue;
|
||||||
|
let shouldAdd = false;
|
||||||
|
|
||||||
|
switch (item.type) {
|
||||||
|
case 'boolean':
|
||||||
|
displayValue = value ? 'Yes' : 'No';
|
||||||
|
shouldAdd = true;
|
||||||
|
break;
|
||||||
|
case 'string':
|
||||||
|
if (value.length > 0) {
|
||||||
|
displayValue = value;
|
||||||
|
shouldAdd = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'number_gt_zero':
|
||||||
|
if (value > 0) {
|
||||||
|
displayValue = value;
|
||||||
|
shouldAdd = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (shouldAdd) {
|
||||||
|
messages.push({ label: browser.i18n.getMessage(item.labelKey), value: displayValue });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return messages;
|
||||||
|
};
|
||||||
|
|
||||||
let additional_text_elements = [];
|
let additional_text_elements = [];
|
||||||
additional_text_elements.push({label: "Prompt", value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)});
|
additional_text_elements.push({label: browser.i18n.getMessage("prompt_string"), value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)});
|
||||||
|
additional_text_elements.push(...getAdditionalMessages(integration, prefs_api));
|
||||||
|
|
||||||
|
const api_strings = {
|
||||||
|
chatgpt: "ChatGPT API",
|
||||||
|
google_gemini: "Google Gemini API",
|
||||||
|
ollama: "Ollama API",
|
||||||
|
openai_comp: "OpenAI Compatible API",
|
||||||
|
anthropic: "Claude API"
|
||||||
|
};
|
||||||
|
|
||||||
messagesArea.appendUserMessage(getAPIsInitMessageString({
|
messagesArea.appendUserMessage(getAPIsInitMessageString({
|
||||||
api_string: "Ollama API",
|
api_string: api_strings[integration],
|
||||||
model_string: prefs_api.ollama_model,
|
model_string: prefs_api[`${integration_prefix}_model`],
|
||||||
host_string: prefs_api.ollama_host,
|
host_string: prefs_api[`${integration_prefix}_host`],
|
||||||
additional_messages: additional_text_elements
|
version_string: prefs_api[`${integration_prefix}_version`],
|
||||||
}), "info");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "openai_comp_api": {
|
|
||||||
let prefs_api = await browser.storage.sync.get({
|
|
||||||
openai_comp_host: prefs_default.openai_comp_host,
|
|
||||||
openai_comp_model: prefs_default.openai_comp_model,
|
|
||||||
openai_comp_api_key: prefs_default.openai_comp_api_key,
|
|
||||||
openai_comp_use_v1: prefs_default.openai_comp_use_v1,
|
|
||||||
openai_comp_chat_name: prefs_default.openai_comp_chat_name,
|
|
||||||
do_debug: prefs_default.do_debug,
|
|
||||||
});
|
|
||||||
let i18nStrings = {};
|
|
||||||
i18nStrings["OpenAIComp_api_request_failed"] = browser.i18n.getMessage('OpenAIComp_api_request_failed');
|
|
||||||
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
|
|
||||||
messageInput.setModel(prefs_api.openai_comp_model);
|
|
||||||
messagesArea.setLLMName(prefs_api.openai_comp_chat_name);
|
|
||||||
worker.postMessage({
|
|
||||||
type: 'init',
|
|
||||||
openai_comp_host: prefs_api.openai_comp_host,
|
|
||||||
openai_comp_model: prefs_api.openai_comp_model,
|
|
||||||
openai_comp_api_key: prefs_api.openai_comp_api_key,
|
|
||||||
openai_comp_use_v1: prefs_api.openai_comp_use_v1,
|
|
||||||
do_debug: prefs_api.do_debug,
|
|
||||||
i18nStrings: i18nStrings,
|
|
||||||
});
|
|
||||||
let additional_text_elements = [];
|
|
||||||
additional_text_elements.push({label: "Prompt", value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)});
|
|
||||||
messagesArea.appendUserMessage(getAPIsInitMessageString({
|
|
||||||
api_string: "OpenAI Compatible API",
|
|
||||||
model_string: prefs_api.openai_comp_model,
|
|
||||||
host_string: prefs_api.openai_comp_host,
|
|
||||||
additional_messages: additional_text_elements
|
additional_messages: additional_text_elements
|
||||||
}), "info");
|
}), "info");
|
||||||
|
|
||||||
browser.runtime.sendMessage({
|
browser.runtime.sendMessage({
|
||||||
command: "openai_comp_api_ready_" + call_id,
|
command: `${llm}_ready_${call_id}`,
|
||||||
window_id: (await browser.windows.getCurrent()).id
|
window_id: (await browser.windows.getCurrent()).id
|
||||||
});
|
});
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "anthropic_api": {
|
|
||||||
let prefs_api = await browser.storage.sync.get({
|
|
||||||
anthropic_api_key: prefs_default.anthropic_api_key,
|
|
||||||
anthropic_model: prefs_default.anthropic_model,
|
|
||||||
anthropic_system_prompt: prefs_default.anthropic_system_prompt,
|
|
||||||
anthropic_version: prefs_default.anthropic_version,
|
|
||||||
anthropic_max_tokens: prefs_default.anthropic_max_tokens,
|
|
||||||
do_debug: prefs_default.do_debug,
|
|
||||||
});
|
|
||||||
let i18nStrings = {};
|
|
||||||
i18nStrings["anthropic_api_request_failed"] = browser.i18n.getMessage('anthropic_api_request_failed');
|
|
||||||
i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted');
|
|
||||||
messageInput.setModel(prefs_api.anthropic_model);
|
|
||||||
messagesArea.setLLMName("Claude");
|
|
||||||
worker.postMessage({
|
|
||||||
type: 'init',
|
|
||||||
anthropic_api_key: prefs_api.anthropic_api_key,
|
|
||||||
anthropic_model: prefs_api.anthropic_model,
|
|
||||||
anthropic_system_prompt: prefs_api.anthropic_system_prompt,
|
|
||||||
anthropic_version: prefs_api.anthropic_version,
|
|
||||||
anthropic_max_tokens: prefs_api.anthropic_max_tokens,
|
|
||||||
do_debug: prefs_api.do_debug,
|
|
||||||
i18nStrings: i18nStrings,
|
|
||||||
});
|
|
||||||
let additional_text_elements = [];
|
|
||||||
additional_text_elements.push({label: "Prompt", value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)});
|
|
||||||
additional_text_elements.push({label: "System Prompt", value: prefs_api.anthropic_system_prompt});
|
|
||||||
messagesArea.appendUserMessage(getAPIsInitMessageString({
|
|
||||||
api_string: "Claude API",
|
|
||||||
model_string: prefs_api.anthropic_model,
|
|
||||||
version_string: prefs_api.anthropic_version,
|
|
||||||
additional_messages: additional_text_elements
|
|
||||||
}), "info");
|
|
||||||
browser.runtime.sendMessage({
|
|
||||||
command: "anthropic_api_ready_" + call_id,
|
|
||||||
window_id: (await browser.windows.getCurrent()).id
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ export class Anthropic {
|
||||||
version = '';
|
version = '';
|
||||||
model = '';
|
model = '';
|
||||||
system_prompt = '';
|
system_prompt = '';
|
||||||
|
temperature = '';
|
||||||
max_tokens = 4096;
|
max_tokens = 4096;
|
||||||
stream = false;
|
stream = false;
|
||||||
|
|
||||||
|
|
@ -33,6 +34,7 @@ export class Anthropic {
|
||||||
version = '',
|
version = '',
|
||||||
model = '',
|
model = '',
|
||||||
system_prompt = '',
|
system_prompt = '',
|
||||||
|
temperature = '',
|
||||||
max_tokens = 4096,
|
max_tokens = 4096,
|
||||||
stream = false,
|
stream = false,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
|
|
@ -40,6 +42,7 @@ export class Anthropic {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.system_prompt = system_prompt;
|
this.system_prompt = system_prompt;
|
||||||
|
this.temperature = temperature;
|
||||||
this.max_tokens = max_tokens > 0 ? max_tokens : 4096;
|
this.max_tokens = max_tokens > 0 ? max_tokens : 4096;
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
}
|
}
|
||||||
|
|
@ -87,6 +90,19 @@ export class Anthropic {
|
||||||
// console.log(">>>>>>>>>>> Anthropic API request: " + JSON.stringify(messages));
|
// console.log(">>>>>>>>>>> Anthropic API request: " + JSON.stringify(messages));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
let claude_body = {
|
||||||
|
model: this.model,
|
||||||
|
max_tokens: parseInt(this.max_tokens),
|
||||||
|
system: this.system_prompt,
|
||||||
|
messages: messages,
|
||||||
|
stream: this.stream,
|
||||||
|
};
|
||||||
|
|
||||||
|
const tempFloat = parseFloat(this.temperature);
|
||||||
|
|
||||||
|
if(this.temperature != '' && !Number.isNaN(tempFloat)) claude_body.temperature = tempFloat;
|
||||||
|
|
||||||
const response = await fetch("https://api.anthropic.com/v1/messages", {
|
const response = await fetch("https://api.anthropic.com/v1/messages", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
|
|
@ -95,13 +111,7 @@ export class Anthropic {
|
||||||
"anthropic-version": this.version,
|
"anthropic-version": this.version,
|
||||||
"anthropic-dangerous-direct-browser-access": "true",
|
"anthropic-dangerous-direct-browser-access": "true",
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify(claude_body),
|
||||||
model: this.model,
|
|
||||||
max_tokens: this.max_tokens,
|
|
||||||
system: this.system_prompt,
|
|
||||||
messages: messages,
|
|
||||||
stream: this.stream,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
return response;
|
return response;
|
||||||
}catch (error) {
|
}catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ export class GoogleGemini {
|
||||||
system_instruction = '';
|
system_instruction = '';
|
||||||
stream = false;
|
stream = false;
|
||||||
thinking_budget = ''; // Model default
|
thinking_budget = ''; // Model default
|
||||||
|
temperature = ''; // no temperature defined
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
apiKey = '',
|
apiKey = '',
|
||||||
|
|
@ -32,12 +33,14 @@ export class GoogleGemini {
|
||||||
system_instruction = '',
|
system_instruction = '',
|
||||||
stream = false,
|
stream = false,
|
||||||
thinking_budget = '',
|
thinking_budget = '',
|
||||||
|
temperature = '',
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.apiKey = apiKey;
|
this.apiKey = apiKey;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.system_instruction = system_instruction;
|
this.system_instruction = system_instruction;
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.thinking_budget = String(thinking_budget ?? '').trim();
|
this.thinking_budget = String(thinking_budget ?? '').trim();
|
||||||
|
this.temperature = String(temperature ?? '').trim();
|
||||||
/* Info from: https://ai.google.dev/gemini-api/docs/thinking?#set-budget
|
/* Info from: https://ai.google.dev/gemini-api/docs/thinking?#set-budget
|
||||||
# Turn on thinking with a specific token limit: "thinking_budget": 1024
|
# Turn on thinking with a specific token limit: "thinking_budget": 1024
|
||||||
# Thinking off: "thinking_budget": 0
|
# Thinking off: "thinking_budget": 0
|
||||||
|
|
@ -87,7 +90,8 @@ export class GoogleGemini {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
let google_gemini_body = {
|
let google_gemini_body = {
|
||||||
contents:messages
|
contents: messages,
|
||||||
|
generationConfig: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
// console.log("[ThunderAI] Google Gemini API system_instruction: " + JSON.stringify(this.system_instruction));
|
// console.log("[ThunderAI] Google Gemini API system_instruction: " + JSON.stringify(this.system_instruction));
|
||||||
|
|
@ -101,13 +105,17 @@ export class GoogleGemini {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.thinking_budget !== '') {
|
if(this.thinking_budget !== '') {
|
||||||
google_gemini_body.generationConfig = {
|
google_gemini_body.generationConfig.thinkingConfig = {
|
||||||
thinkingConfig: {
|
|
||||||
thinking_budget: this.thinking_budget,
|
thinking_budget: this.thinking_budget,
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tempFloat = parseFloat(this.temperature);
|
||||||
|
|
||||||
|
if(this.temperature != '' && !Number.isNaN(tempFloat)) {
|
||||||
|
google_gemini_body.generationConfig.temperature = tempFloat;
|
||||||
|
}
|
||||||
|
|
||||||
// console.log("[ThunderAI] Google Gemini API request: " + JSON.stringify(google_gemini_body));
|
// console.log("[ThunderAI] Google Gemini API request: " + JSON.stringify(google_gemini_body));
|
||||||
|
|
||||||
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/models/" + this.model + ":" + (this.stream ? 'streamGenerateContent?alt=sse&' : 'generateContent?') + "key=" + this.apiKey, {
|
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/models/" + this.model + ":" + (this.stream ? 'streamGenerateContent?alt=sse&' : 'generateContent?') + "key=" + this.apiKey, {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ export class Ollama {
|
||||||
model = '';
|
model = '';
|
||||||
stream = false;
|
stream = false;
|
||||||
num_ctx = 0;
|
num_ctx = 0;
|
||||||
|
temperature = '';
|
||||||
think = false;
|
think = false;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
|
|
@ -29,12 +30,14 @@ export class Ollama {
|
||||||
model = '',
|
model = '',
|
||||||
stream = false,
|
stream = false,
|
||||||
num_ctx = 0,
|
num_ctx = 0,
|
||||||
|
temperature = '',
|
||||||
think = false,
|
think = false,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.host = (host || '').trim().replace(/\/+$/, "");
|
this.host = (host || '').trim().replace(/\/+$/, "");
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.num_ctx = num_ctx;
|
this.num_ctx = num_ctx;
|
||||||
|
this.temperature = temperature;
|
||||||
this.think = think;
|
this.think = think;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,6 +81,7 @@ export class Ollama {
|
||||||
|
|
||||||
fetchResponse = async (messages) => {
|
fetchResponse = async (messages) => {
|
||||||
try {
|
try {
|
||||||
|
const tempFloat = parseFloat(this.temperature);
|
||||||
//console.log(">>>>>>>>>> messages: " +JSON.stringify(messages));
|
//console.log(">>>>>>>>>> messages: " +JSON.stringify(messages));
|
||||||
const response = await fetch(this.host + "/api/chat", {
|
const response = await fetch(this.host + "/api/chat", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|
@ -90,6 +94,7 @@ export class Ollama {
|
||||||
stream: this.stream,
|
stream: this.stream,
|
||||||
think: this.think,
|
think: this.think,
|
||||||
...(this.num_ctx > 0 ? { options: { num_ctx: parseInt(this.num_ctx) } } : {}),
|
...(this.num_ctx > 0 ? { options: { num_ctx: parseInt(this.num_ctx) } } : {}),
|
||||||
|
...(this.temperature != '' && !Number.isNaN(tempFloat) ? { options: { temperature: tempFloat } } : {}),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
return response;
|
return response;
|
||||||
|
|
@ -103,30 +108,4 @@ export class Ollama {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// fetchResponse = async (messages) => {
|
|
||||||
// try {
|
|
||||||
// let sending = messages.join(' ');
|
|
||||||
// console.log(">>>>>>>>>> sending: " + sending);
|
|
||||||
// const response = await fetch(this.host + "/api/generate", {
|
|
||||||
// method: "POST",
|
|
||||||
// headers: {
|
|
||||||
// "Content-Type": "application/json",
|
|
||||||
// },
|
|
||||||
// body: JSON.stringify({
|
|
||||||
// model: this.model,
|
|
||||||
// prompt: sending,
|
|
||||||
// stream: this.stream,
|
|
||||||
// }),
|
|
||||||
// });
|
|
||||||
// return response;
|
|
||||||
// }catch (error) {
|
|
||||||
// console.error("[ThunderAI] Ollama API request failed: " + error);
|
|
||||||
// let output = {};
|
|
||||||
// output.is_exception = true;
|
|
||||||
// output.ok = false;
|
|
||||||
// output.error = "Ollama API request failed: " + error;
|
|
||||||
// return output;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ export class OpenAIComp {
|
||||||
apiKey = '';
|
apiKey = '';
|
||||||
use_v1 = true;
|
use_v1 = true;
|
||||||
stream = false;
|
stream = false;
|
||||||
|
temperature = '';
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
host = '',
|
host = '',
|
||||||
|
|
@ -33,12 +34,14 @@ export class OpenAIComp {
|
||||||
apiKey = '',
|
apiKey = '',
|
||||||
stream = false,
|
stream = false,
|
||||||
use_v1 = true,
|
use_v1 = true,
|
||||||
|
temperature = '',
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.host = (host || '').trim().replace(/\/+$/, "");
|
this.host = (host || '').trim().replace(/\/+$/, "");
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.apiKey = apiKey;
|
this.apiKey = apiKey;
|
||||||
this.use_v1 = use_v1;
|
this.use_v1 = use_v1;
|
||||||
|
this.temperature = temperature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,6 +81,7 @@ export class OpenAIComp {
|
||||||
|
|
||||||
fetchResponse = async (messages, maxTokens = 0) => {
|
fetchResponse = async (messages, maxTokens = 0) => {
|
||||||
try{
|
try{
|
||||||
|
const tempFloat = parseFloat(this.temperature);
|
||||||
const curr_headers = {
|
const curr_headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
};
|
};
|
||||||
|
|
@ -91,7 +95,8 @@ export class OpenAIComp {
|
||||||
model: this.model,
|
model: this.model,
|
||||||
messages: messages,
|
messages: messages,
|
||||||
stream: this.stream,
|
stream: this.stream,
|
||||||
...(maxTokens > 0 ? { 'max_tokens': parseInt(maxTokens) } : {})
|
...(maxTokens > 0 ? { 'max_tokens': parseInt(maxTokens) } : {}),
|
||||||
|
...(this.temperature != '' && !Number.isNaN(tempFloat) ? { 'temperature': tempFloat } : {})
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
return response;
|
return response;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ export class OpenAI {
|
||||||
apiKey = '';
|
apiKey = '';
|
||||||
model = '';
|
model = '';
|
||||||
developer_messages = '';
|
developer_messages = '';
|
||||||
|
temperature = '';
|
||||||
stream = false;
|
stream = false;
|
||||||
store = false;
|
store = false;
|
||||||
|
|
||||||
|
|
@ -31,12 +32,14 @@ export class OpenAI {
|
||||||
apiKey = '',
|
apiKey = '',
|
||||||
model = '',
|
model = '',
|
||||||
developer_messages = '',
|
developer_messages = '',
|
||||||
|
temperature = '',
|
||||||
stream = false,
|
stream = false,
|
||||||
store = false
|
store = false
|
||||||
} = {}) {
|
} = {}) {
|
||||||
this.apiKey = apiKey;
|
this.apiKey = apiKey;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.developer_messages = developer_messages;
|
this.developer_messages = developer_messages;
|
||||||
|
this.temperature = temperature;
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.store = store;
|
this.store = store;
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +68,7 @@ export class OpenAI {
|
||||||
let output = {};
|
let output = {};
|
||||||
output.ok = true;
|
output.ok = true;
|
||||||
let output_response = await response.json();
|
let output_response = await response.json();
|
||||||
output.response = output_response.data.filter(item => item.id.startsWith('gpt-')).sort((a, b) => b.id.localeCompare(a.id));
|
output.response = output_response.data.filter(item => item.id.startsWith('gpt-') || item.id.startsWith('o1-') || item.id.startsWith('o4-') || item.id.startsWith('o3-')).sort((a, b) => b.id.localeCompare(a.id));
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}catch (error) {
|
}catch (error) {
|
||||||
|
|
@ -78,52 +81,49 @@ export class OpenAI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchResponse = async (messages, maxTokens = 0) => {
|
fetchResponse = async (messages, maxTokens = 0, previous_response_id = null) => {
|
||||||
|
|
||||||
|
const input = messages.map(msg => ({
|
||||||
|
role: msg.role,
|
||||||
|
content: [{ type: "input_text", text: msg.content }]
|
||||||
|
}));
|
||||||
|
|
||||||
|
const tempFloat = parseFloat(this.temperature);
|
||||||
|
|
||||||
|
let request_body = {
|
||||||
|
model: this.model,
|
||||||
|
input: input,
|
||||||
|
stream: this.stream,
|
||||||
|
store: this.store,
|
||||||
|
...(this.temperature != '' && !Number.isNaN(tempFloat) ? { 'temperature': tempFloat } : {}),
|
||||||
|
...(maxTokens > 0 ? { 'max_output_tokens': parseInt(maxTokens) } : {}),
|
||||||
|
...(previous_response_id && this.store ? { 'previous_response_id': previous_response_id } : {})
|
||||||
|
}
|
||||||
|
|
||||||
if(this.developer_messages !== ''){
|
if(this.developer_messages !== ''){
|
||||||
messages.push({role: "developer", content: [{"type": "text", "text": this.developer_messages}]});
|
request_body.instructions = this.developer_messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log(">>>>>>>>>>> OpenAI API request: " + JSON.stringify(messages));
|
// console.log(">>>>>>>>>>> OpenAI API request: " + JSON.stringify(messages));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
const response = await fetch("https://api.openai.com/v1/responses", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
Authorization: "Bearer "+ this.apiKey
|
Authorization: "Bearer "+ this.apiKey
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify(request_body),
|
||||||
model: this.model,
|
|
||||||
messages: messages,
|
|
||||||
stream: this.stream,
|
|
||||||
store: this.store,
|
|
||||||
...(maxTokens > 0 ? { 'max_tokens': parseInt(maxTokens) } : {})
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
return response;
|
return response;
|
||||||
}catch (error) {
|
}catch (error) {
|
||||||
console.error("[ThunderAI] OpenAI API request failed: " + error);
|
console.error("[ThunderAI] OpenAI Responses API request failed: " + error);
|
||||||
let output = {};
|
let output = {};
|
||||||
output.is_exception = true;
|
output.is_exception = true;
|
||||||
output.ok = false;
|
output.ok = false;
|
||||||
output.error = "OpenAI API request failed: " + error;
|
output.error = "OpenAI Responses API request failed: " + error;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async countTokensUsingAPI(model, text) {
|
|
||||||
const response = await fetch('https://api.openai.com/v1/engines/'+model+'/tokenizer', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Authorization': 'Bearer ' + this.apiKey
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ text })
|
|
||||||
});
|
|
||||||
|
|
||||||
const data = await response.json();
|
|
||||||
return data.token_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,10 @@
|
||||||
// Some original methods are derived from https://github.com/ali-raheem/Aify/blob/cfadf52f576b7be3720b5b73af7c8d3129c054da/plugin/html/actions.js
|
// Some original methods are derived from https://github.com/ali-raheem/Aify/blob/cfadf52f576b7be3720b5b73af7c8d3129c054da/plugin/html/actions.js
|
||||||
|
|
||||||
import { getPrompts } from './mzta-prompts.js';
|
import { getPrompts } from './mzta-prompts.js';
|
||||||
import { prefs_default } from '../options/mzta-options-default.js';
|
import {
|
||||||
|
prefs_default,
|
||||||
|
getDynamicSettingsDefaults
|
||||||
|
} from '../options/mzta-options-default.js';
|
||||||
import {
|
import {
|
||||||
getLanguageDisplayName,
|
getLanguageDisplayName,
|
||||||
getMenuContextCompose,
|
getMenuContextCompose,
|
||||||
|
|
@ -222,7 +225,8 @@ export class mzta_Menus {
|
||||||
prompt: fullPrompt,
|
prompt: fullPrompt,
|
||||||
llm: def_conntype,
|
llm: def_conntype,
|
||||||
custom_model: curr_prompt.model ? curr_prompt.model : '',
|
custom_model: curr_prompt.model ? curr_prompt.model : '',
|
||||||
do_debug: prefs_at.do_debug
|
do_debug: prefs_at.do_debug,
|
||||||
|
config: curr_prompt
|
||||||
});
|
});
|
||||||
await cmd_addTags.initWorker();
|
await cmd_addTags.initWorker();
|
||||||
try{
|
try{
|
||||||
|
|
@ -258,9 +262,11 @@ export class mzta_Menus {
|
||||||
connection_type: prefs_default.connection_type,
|
connection_type: prefs_default.connection_type,
|
||||||
calendar_enforce_timezone: prefs_default.calendar_enforce_timezone,
|
calendar_enforce_timezone: prefs_default.calendar_enforce_timezone,
|
||||||
calendar_timezone: prefs_default.calendar_timezone,
|
calendar_timezone: prefs_default.calendar_timezone,
|
||||||
|
...getDynamicSettingsDefaults(['use_specific_integration', 'connection_type'])
|
||||||
});
|
});
|
||||||
if((prefs_at.connection_type === '')||(prefs_at.connection_type === null)||(prefs_at.connection_type === undefined)||(prefs_at.connection_type === 'chatgpt_web')){
|
let def_conntype = getConnectionType(prefs_at, curr_prompt, 'get_calendar_event');
|
||||||
console.error("[ThunderAI | GetCalendarEvent] Invalid connection type: " + prefs_at.connection_type);
|
if((def_conntype === '')||(def_conntype === null)||(def_conntype === undefined)||(def_conntype === 'chatgpt_web')){
|
||||||
|
console.error("[ThunderAI | GetCalendarEvent] Invalid connection type: " + def_conntype);
|
||||||
taWorkingStatus.stopWorking();
|
taWorkingStatus.stopWorking();
|
||||||
return {ok:'0'};
|
return {ok:'0'};
|
||||||
}
|
}
|
||||||
|
|
@ -277,8 +283,9 @@ export class mzta_Menus {
|
||||||
this.logger.log("fullPrompt: " + fullPrompt);
|
this.logger.log("fullPrompt: " + fullPrompt);
|
||||||
let cmd_GetCalendarEvent = new mzta_specialCommand({
|
let cmd_GetCalendarEvent = new mzta_specialCommand({
|
||||||
prompt: fullPrompt,
|
prompt: fullPrompt,
|
||||||
llm: prefs_at.connection_type,
|
llm: def_conntype,
|
||||||
do_debug: true
|
do_debug: true,
|
||||||
|
config: curr_prompt
|
||||||
});
|
});
|
||||||
await cmd_GetCalendarEvent.initWorker();
|
await cmd_GetCalendarEvent.initWorker();
|
||||||
try{
|
try{
|
||||||
|
|
@ -333,9 +340,14 @@ export class mzta_Menus {
|
||||||
}
|
}
|
||||||
case 'prompt_get_task': { // Get a task info
|
case 'prompt_get_task': { // Get a task info
|
||||||
let task_data = '';
|
let task_data = '';
|
||||||
let prefs_at = await browser.storage.sync.get({connection_type: '', calendar_enforce_timezone: false, calendar_timezone: '',});
|
let prefs_at = await browser.storage.sync.get({
|
||||||
if((prefs_at.connection_type === '')||(prefs_at.connection_type === null)||(prefs_at.connection_type === undefined)||(prefs_at.connection_type === 'chatgpt_web')){
|
connection_type: '',
|
||||||
console.error("[ThunderAI | GetTask] Invalid connection type: " + prefs_at.connection_type);
|
calendar_enforce_timezone: false,
|
||||||
|
calendar_timezone: '',
|
||||||
|
...getDynamicSettingsDefaults(['use_specific_integration', 'connection_type'])});
|
||||||
|
let def_conntype = getConnectionType(prefs_at, curr_prompt, 'get_task');
|
||||||
|
if((def_conntype === '')||(def_conntype === null)||(def_conntype === undefined)||(def_conntype === 'chatgpt_web')){
|
||||||
|
console.error("[ThunderAI | GetTask] Invalid connection type: " + def_conntype);
|
||||||
taWorkingStatus.stopWorking();
|
taWorkingStatus.stopWorking();
|
||||||
return {ok:'0'};
|
return {ok:'0'};
|
||||||
}
|
}
|
||||||
|
|
@ -349,8 +361,9 @@ export class mzta_Menus {
|
||||||
this.logger.log("fullPrompt: " + fullPrompt);
|
this.logger.log("fullPrompt: " + fullPrompt);
|
||||||
let cmd_GetTask = new mzta_specialCommand({
|
let cmd_GetTask = new mzta_specialCommand({
|
||||||
prompt: fullPrompt,
|
prompt: fullPrompt,
|
||||||
llm: prefs_at.connection_type,
|
llm: def_conntype,
|
||||||
do_debug: true
|
do_debug: true,
|
||||||
|
config: curr_prompt
|
||||||
});
|
});
|
||||||
await cmd_GetTask.initWorker();
|
await cmd_GetTask.initWorker();
|
||||||
try{
|
try{
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export function textareaAutocomplete(textarea, suggestions, type_value = -1) {
|
||||||
type = tr.querySelector('.type_output').value
|
type = tr.querySelector('.type_output').value
|
||||||
}
|
}
|
||||||
// console.log(">>>>>>>>> type: " + type);
|
// console.log(">>>>>>>>> type: " + type);
|
||||||
// console.log(">>>>>>>>> suggestions: " + JSON.stringify(suggestions));
|
// console.log(">>>>>>>>> suggestions: " + JSON.stringify(suggestions));
|
||||||
// console.log(">>>>>>>>> lastWord: " + lastWord);
|
// console.log(">>>>>>>>> lastWord: " + lastWord);
|
||||||
const matches = suggestions.filter(s => s.command.startsWith(lastWord) && (String(s.type) == String(type) || String(s.type) == '0' )).map(s => s.command);
|
const matches = suggestions.filter(s => s.command.startsWith(lastWord) && (String(s.type) == String(type) || String(s.type) == '0' )).map(s => s.command);
|
||||||
// console.log(">>>>>>>>> matches: " + JSON.stringify(matches));
|
// console.log(">>>>>>>>> matches: " + JSON.stringify(matches));
|
||||||
|
|
@ -106,6 +106,7 @@ export function textareaAutocomplete(textarea, suggestions, type_value = -1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function insertAutocomplete(suggestion, textarea) {
|
function insertAutocomplete(suggestion, textarea) {
|
||||||
|
// console.log(">>>>>>>>> insertAutocomplete suggestion: " + JSON.stringify(suggestion));
|
||||||
const cursorPosition = textarea.selectionStart;
|
const cursorPosition = textarea.selectionStart;
|
||||||
const textBefore = textarea.value.substring(0, cursorPosition);
|
const textBefore = textarea.value.substring(0, cursorPosition);
|
||||||
const textAfter = textarea.value.substring(cursorPosition);
|
const textAfter = textarea.value.substring(cursorPosition);
|
||||||
|
|
@ -115,7 +116,7 @@ export function textareaAutocomplete(textarea, suggestions, type_value = -1) {
|
||||||
const completion = suggestion.substring(lastWord.length);
|
const completion = suggestion.substring(lastWord.length);
|
||||||
const newText = textBefore + completion + textAfter;
|
const newText = textBefore + completion + textAfter;
|
||||||
textarea.value = newText;
|
textarea.value = newText;
|
||||||
const newCursorPosition = cursorPosition + completion.length;
|
const newCursorPosition = cursorPosition + completion.length - (suggestion.endsWith(':%}') ? 2 : 0);
|
||||||
textarea.setSelectionRange(newCursorPosition, newCursorPosition);
|
textarea.setSelectionRange(newCursorPosition, newCursorPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from '../options/mzta-options-default.js';
|
import { prefs_default } from '../options/mzta-options-default.js';
|
||||||
|
import { getMailHeader } from './mzta-utils.js';
|
||||||
|
|
||||||
/* ================= PLACEHOLDERS PROPERTIES ========================================
|
/* ================= PLACEHOLDERS PROPERTIES ========================================
|
||||||
|
|
||||||
|
|
@ -35,6 +36,10 @@ import { prefs_default } from '../options/mzta-options-default.js';
|
||||||
0: Custom placeholder
|
0: Custom placeholder
|
||||||
1: Default placeholder (not editable, cannot be deleted)
|
1: Default placeholder (not editable, cannot be deleted)
|
||||||
|
|
||||||
|
is_dynamic attribute:
|
||||||
|
0: it's a fixed placeholder
|
||||||
|
1: it's a dynamic placehoder (it means that it will have a : and then a value, like {%my_placeholder:test_value%})
|
||||||
|
|
||||||
================ USER PROPERTIES
|
================ USER PROPERTIES
|
||||||
enabled attribute:
|
enabled attribute:
|
||||||
0: Disabled
|
0: Disabled
|
||||||
|
|
@ -53,6 +58,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -61,6 +67,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -69,6 +76,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 2,
|
type: 2,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -77,6 +85,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 2,
|
type: 2,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -85,6 +94,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -93,6 +103,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 1,
|
type: 1,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -101,6 +112,16 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 1,
|
type: 1,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
|
enabled: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mail_headers',
|
||||||
|
name: "__MSG_placeholder_mail_headers__",
|
||||||
|
default_value: "",
|
||||||
|
type: 1,
|
||||||
|
is_default: "1",
|
||||||
|
is_dynamic: "1",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -109,6 +130,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -117,6 +139,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -125,6 +148,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -133,6 +157,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "0",
|
default_value: "0",
|
||||||
type: 1,
|
type: 1,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -141,6 +166,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -149,6 +175,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -157,6 +184,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -165,6 +193,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 1,
|
type: 1,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -173,6 +202,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -181,6 +211,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -189,6 +220,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -197,6 +229,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -205,6 +238,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -213,6 +247,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -221,6 +256,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -229,6 +265,7 @@ const defaultPlaceholders = [
|
||||||
default_value: "",
|
default_value: "",
|
||||||
type: 1,
|
type: 1,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
@ -269,6 +306,7 @@ export async function setCustomPlaceholders(placeholders) {
|
||||||
placeholders.forEach(ph => {
|
placeholders.forEach(ph => {
|
||||||
ph.id = placeholdersUtils.validateCustomDataPH_ID(ph.id);
|
ph.id = placeholdersUtils.validateCustomDataPH_ID(ph.id);
|
||||||
ph.is_default = "0";
|
ph.is_default = "0";
|
||||||
|
ph.is_dynamic = "0";
|
||||||
});
|
});
|
||||||
await browser.storage.local.set({_custom_placeholder: placeholders});
|
await browser.storage.local.set({_custom_placeholder: placeholders});
|
||||||
}
|
}
|
||||||
|
|
@ -301,6 +339,14 @@ export async function prepareCustomDataPHsForImport(placeholders){
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function mapPlaceholderToSuggestion(p) {
|
||||||
|
// console.log(">>>>>>>>>> mapPlaceholderToSuggestion p" + JSON.stringify(p));
|
||||||
|
return {
|
||||||
|
command: '{%' + p.id + (p.is_dynamic == 1 ? ':' : '') + '%}',
|
||||||
|
type: p.type,
|
||||||
|
is_dynamic: p.is_dynamic,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export const placeholdersUtils = {
|
export const placeholdersUtils = {
|
||||||
|
|
||||||
|
|
@ -330,10 +376,21 @@ export const placeholdersUtils = {
|
||||||
|
|
||||||
// Use exec to find all matches
|
// Use exec to find all matches
|
||||||
while ((match = regex.exec(text)) !== null) {
|
while ((match = regex.exec(text)) !== null) {
|
||||||
const foundPH = activePHs.find(ph => ph.id === match[1].trim());
|
// console.log(">>>>>>>>>> extractPlaceholders match: " + JSON.stringify(match));
|
||||||
if (foundPH) {
|
const foundPH = activePHs.find(ph => ph.id === match[1].trim() || (ph.is_dynamic == 1 && match[1].startsWith(ph.id + ':')));
|
||||||
matches.push(foundPH);
|
if (foundPH) {
|
||||||
}
|
if (foundPH.is_dynamic == 1 && match[1].includes(':')) {
|
||||||
|
const [id, custom_value] = match[1].split(':', 2);
|
||||||
|
const dynamicPH = { ...foundPH }; // Create a copy to avoid modifying the original
|
||||||
|
dynamicPH.id = id.trim();
|
||||||
|
dynamicPH.custom_value = custom_value.trim();
|
||||||
|
matches.push(dynamicPH);
|
||||||
|
// console.log(">>>>>>>>>> extractPlaceholders dynamicPH: " + JSON.stringify(dynamicPH));
|
||||||
|
} else {
|
||||||
|
matches.push(foundPH);
|
||||||
|
// console.log(">>>>>>>>>> extractPlaceholders foundPH: " + JSON.stringify(foundPH));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return matches;
|
return matches;
|
||||||
|
|
@ -346,13 +403,17 @@ export const placeholdersUtils = {
|
||||||
use_default_value = false,
|
use_default_value = false,
|
||||||
skip_additional_text = false
|
skip_additional_text = false
|
||||||
} = args || {};
|
} = args || {};
|
||||||
|
// console.log(">>>>>>>>>> replacePlaceholders replacements: " + JSON.stringify(replacements));
|
||||||
// Regular expression to match patterns like {%...%}
|
// Regular expression to match patterns like {%...%}
|
||||||
return text.replace(/{%\s*(.*?)\s*%}/g, function(match, p1) {
|
return text.replace(/{%\s*(.*?)\s*%}/g, function(match, p1) {
|
||||||
|
// console.log(">>>>>>>>>> replacePlaceholders match: " + JSON.stringify(match));
|
||||||
|
// console.log(">>>>>>>>>> replacePlaceholders p1: " + JSON.stringify(p1));
|
||||||
// p1 contains the key inside {% %}
|
// p1 contains the key inside {% %}
|
||||||
if (skip_additional_text && (p1 === 'additional_text')) {
|
if (skip_additional_text && (p1 === 'additional_text')) {
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
const currPlaceholder = defaultPlaceholders.find(ph => ph.id === p1);
|
const currPlaceholder = defaultPlaceholders.find(ph => (ph.id === p1) || (ph.is_dynamic == 1 && p1.startsWith(ph.id + ':')));
|
||||||
|
// console.log(">>>>>>>>>> replacePlaceholders currPlaceholder: " + JSON.stringify(currPlaceholder));
|
||||||
if (!currPlaceholder) {
|
if (!currPlaceholder) {
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
@ -424,6 +485,7 @@ export const placeholdersUtils = {
|
||||||
// console.log(">>>>>>>>>> curr_message: " + JSON.stringify(curr_message));
|
// console.log(">>>>>>>>>> curr_message: " + JSON.stringify(curr_message));
|
||||||
let finalSubs = {};
|
let finalSubs = {};
|
||||||
for(let currPH of currPHs){
|
for(let currPH of currPHs){
|
||||||
|
// console.log(">>>>>>>>>> currPH: " + JSON.stringify(currPH));
|
||||||
switch(currPH.id){
|
switch(currPH.id){
|
||||||
case 'mail_text_body':
|
case 'mail_text_body':
|
||||||
finalSubs['mail_text_body'] = placeholdersUtils.failSafePlaceholders(body_text);
|
finalSubs['mail_text_body'] = placeholdersUtils.failSafePlaceholders(body_text);
|
||||||
|
|
@ -446,6 +508,9 @@ export const placeholdersUtils = {
|
||||||
case 'mail_folder_path':
|
case 'mail_folder_path':
|
||||||
finalSubs['mail_folder_path'] = placeholdersUtils.failSafePlaceholders(curr_message.folder?.path);
|
finalSubs['mail_folder_path'] = placeholdersUtils.failSafePlaceholders(curr_message.folder?.path);
|
||||||
break;
|
break;
|
||||||
|
case 'mail_headers':
|
||||||
|
finalSubs['mail_headers:' + currPH.custom_value] = placeholdersUtils.failSafePlaceholders(await getMailHeader(curr_message, currPH.custom_value));
|
||||||
|
break;
|
||||||
case 'selected_text':
|
case 'selected_text':
|
||||||
finalSubs['selected_text'] = placeholdersUtils.failSafePlaceholders(selection_text);
|
finalSubs['selected_text'] = placeholdersUtils.failSafePlaceholders(selection_text);
|
||||||
break;
|
break;
|
||||||
|
|
@ -506,7 +571,7 @@ export const placeholdersUtils = {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// console.log(">>>>>>>>>> finalSubs: " + JSON.stringify(finalSubs));
|
||||||
return finalSubs;
|
return finalSubs;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -516,6 +581,6 @@ export const placeholdersUtils = {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
return element;
|
return element;
|
||||||
}
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -17,7 +17,10 @@
|
||||||
*/
|
*/
|
||||||
// Call the API to use a special prompt
|
// Call the API to use a special prompt
|
||||||
|
|
||||||
import { prefs_default } from "../options/mzta-options-default.js";
|
import {
|
||||||
|
prefs_default,
|
||||||
|
integration_options_config
|
||||||
|
} from "../options/mzta-options-default.js";
|
||||||
import { taLogger } from './mzta-logger.js';
|
import { taLogger } from './mzta-logger.js';
|
||||||
|
|
||||||
export class mzta_specialCommand {
|
export class mzta_specialCommand {
|
||||||
|
|
@ -29,131 +32,84 @@
|
||||||
full_message = "";
|
full_message = "";
|
||||||
logger = null;
|
logger = null;
|
||||||
do_debug = false;
|
do_debug = false;
|
||||||
|
config = {};
|
||||||
|
|
||||||
constructor(args = {}) {
|
constructor(args = {}) {
|
||||||
let {
|
let {
|
||||||
prompt = '',
|
prompt = '',
|
||||||
llm = '',
|
llm = '',
|
||||||
custom_model = '',
|
custom_model = '',
|
||||||
do_debug = false
|
do_debug = false,
|
||||||
|
config = {}
|
||||||
} = args;
|
} = args;
|
||||||
this.prompt = prompt;
|
this.prompt = prompt;
|
||||||
this.llm = llm;
|
this.llm = llm;
|
||||||
this.custom_model = custom_model;
|
this.custom_model = custom_model;
|
||||||
|
this.config = config;
|
||||||
this.logger = new taLogger('mzta_specialCommand', do_debug);
|
this.logger = new taLogger('mzta_specialCommand', do_debug);
|
||||||
this.do_debug = do_debug;
|
this.do_debug = do_debug;
|
||||||
switch (this.llm) {
|
|
||||||
case "chatgpt_api":
|
const worker_path_map = {
|
||||||
this.worker = new Worker(new URL('./workers/model-worker-openai.js', import.meta.url), { type: 'module' });
|
chatgpt_api: './workers/model-worker-openai_responses.js',
|
||||||
break;
|
google_gemini_api: './workers/model-worker-google_gemini.js',
|
||||||
case "google_gemini_api":
|
ollama_api: './workers/model-worker-ollama.js',
|
||||||
this.worker = new Worker(new URL('./workers/model-worker-google_gemini.js', import.meta.url), { type: 'module' });
|
openai_comp_api: './workers/model-worker-openai_comp.js',
|
||||||
break;
|
anthropic_api: './workers/model-worker-anthropic.js',
|
||||||
case "ollama_api":
|
};
|
||||||
this.worker = new Worker(new URL('./workers/model-worker-ollama.js', import.meta.url), { type: 'module' });
|
|
||||||
break;
|
const worker_path = worker_path_map[this.llm];
|
||||||
case "openai_comp_api":
|
if (worker_path) {
|
||||||
this.worker = new Worker(new URL('./workers/model-worker-openai_comp.js', import.meta.url), { type: 'module' });
|
this.worker = new Worker(new URL(worker_path, import.meta.url), { type: 'module' });
|
||||||
break;
|
} else {
|
||||||
case "anthropic_api":
|
this.logger.log("Invalid LLM type: " + this.llm);
|
||||||
this.worker = new Worker(new URL('./workers/model-worker-anthropic.js', import.meta.url), { type: 'module' });
|
throw new Error("Invalid LLM type: " + this.llm);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.logger.log("Invalid LLM type: " + this.llm);
|
|
||||||
throw new Error("Invalid LLM type: " + this.llm);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async initWorker() {
|
async initWorker() {
|
||||||
// console.log((">>>>>>>>>>>> this.custom_model: " + this.custom_model));
|
const integration = this.llm.replace('_api', '');
|
||||||
switch (this.llm) {
|
const options_config = integration_options_config[integration];
|
||||||
case "chatgpt_api": {
|
|
||||||
let prefs_api = await browser.storage.sync.get({
|
if (!options_config) {
|
||||||
chatgpt_api_key: prefs_default.chatgpt_api_key,
|
this.logger.error("Invalid integration type: " + integration);
|
||||||
chatgpt_model: prefs_default.chatgpt_model,
|
throw new Error("Invalid integration type: " + integration);
|
||||||
chatgpt_developer_messages: prefs_default.chatgpt_developer_messages,
|
}
|
||||||
});
|
|
||||||
this.worker.postMessage({
|
let prefsToGet = {};
|
||||||
type: 'init',
|
for (const key in options_config) {
|
||||||
chatgpt_api_key: prefs_api.chatgpt_api_key,
|
const prefKey = `${integration}_${key}`;
|
||||||
chatgpt_model: this.custom_model != '' ? this.custom_model : prefs_api.chatgpt_model,
|
prefsToGet[prefKey] = prefs_default[prefKey];
|
||||||
chatgpt_developer_messages: prefs_api.chatgpt_developer_messages,
|
}
|
||||||
do_debug: this.do_debug,
|
|
||||||
i18nStrings: ''
|
let prefs_api = await browser.storage.sync.get(prefsToGet);
|
||||||
});
|
|
||||||
break;
|
let workerInitMessage = {
|
||||||
|
type: 'init',
|
||||||
|
do_debug: this.do_debug,
|
||||||
|
i18nStrings: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const key in options_config) {
|
||||||
|
const prefKey = `${integration}_${key}`;
|
||||||
|
|
||||||
|
const configValue = this.config[prefKey];
|
||||||
|
|
||||||
|
if (configValue !== undefined) {
|
||||||
|
if (typeof options_config[key] === 'boolean') {
|
||||||
|
prefs_api[prefKey] = (configValue === true || configValue === 'true' || configValue === 1);
|
||||||
|
} else {
|
||||||
|
prefs_api[prefKey] = configValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case "google_gemini_api": {
|
|
||||||
let prefs_api = await browser.storage.sync.get({
|
if (key === 'model') {
|
||||||
google_gemini_api_key: prefs_default.google_gemini_api_key,
|
workerInitMessage[prefKey] = this.custom_model !== '' ? this.custom_model : prefs_api[prefKey];
|
||||||
google_gemini_model: prefs_default.google_gemini_model,
|
} else {
|
||||||
google_gemini_system_instruction: prefs_default.google_gemini_system_instruction,
|
workerInitMessage[prefKey] = prefs_api[prefKey];
|
||||||
google_gemini_thinking_budget: prefs_default.google_gemini_thinking_budget,
|
|
||||||
});
|
|
||||||
this.worker.postMessage({
|
|
||||||
type: 'init',
|
|
||||||
google_gemini_api_key: prefs_api.google_gemini_api_key,
|
|
||||||
google_gemini_model: this.custom_model != '' ? this.custom_model : prefs_api.google_gemini_model,
|
|
||||||
google_gemini_system_instruction: prefs_api.google_gemini_system_instruction,
|
|
||||||
google_gemini_thinking_budget: prefs_api.google_gemini_thinking_budget,
|
|
||||||
do_debug: this.do_debug,
|
|
||||||
i18nStrings: ''
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "ollama_api": {
|
|
||||||
let prefs_api = await browser.storage.sync.get({
|
|
||||||
ollama_host: prefs_default.ollama_host,
|
|
||||||
ollama_model: prefs_default.ollama_model,
|
|
||||||
});
|
|
||||||
this.worker.postMessage({
|
|
||||||
type: 'init',
|
|
||||||
ollama_host: prefs_api.ollama_host,
|
|
||||||
ollama_model: this.custom_model != '' ? this.custom_model : prefs_api.ollama_model,
|
|
||||||
do_debug: this.do_debug,
|
|
||||||
i18nStrings: ''
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "openai_comp_api": {
|
|
||||||
let prefs_api = await browser.storage.sync.get({
|
|
||||||
openai_comp_host: prefs_default.openai_comp_host,
|
|
||||||
openai_comp_model: prefs_default.openai_comp_model,
|
|
||||||
openai_comp_api_key: prefs_default.openai_comp_api_key,
|
|
||||||
openai_comp_use_v1: prefs_default.openai_comp_use_v1,
|
|
||||||
openai_comp_chat_name: prefs_default.openai_comp_chat_name,
|
|
||||||
do_debug: prefs_default.do_debug,
|
|
||||||
});
|
|
||||||
this.worker.postMessage({
|
|
||||||
type: 'init',
|
|
||||||
openai_comp_host: prefs_api.openai_comp_host,
|
|
||||||
openai_comp_model: this.custom_model != '' ? this.custom_model : prefs_api.openai_comp_model,
|
|
||||||
openai_comp_api_key: prefs_api.openai_comp_api_key,
|
|
||||||
openai_comp_use_v1: prefs_api.openai_comp_use_v1,
|
|
||||||
do_debug: this.do_debug,
|
|
||||||
i18nStrings: ''
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "anthropic_api": {
|
|
||||||
let prefs_api = await browser.storage.sync.get({
|
|
||||||
anthropic_api_key: prefs_default.anthropic_api_key,
|
|
||||||
anthropic_model: prefs_default.anthropic_model,
|
|
||||||
anthropic_version: prefs_default.anthropic_version,
|
|
||||||
anthropic_max_tokens: prefs_default.anthropic_max_tokens,
|
|
||||||
});
|
|
||||||
this.worker.postMessage({
|
|
||||||
type: 'init',
|
|
||||||
anthropic_api_key: prefs_api.anthropic_api_key,
|
|
||||||
anthropic_model: this.custom_model != '' ? this.custom_model : prefs_api.anthropic_model,
|
|
||||||
anthropic_version: prefs_api.anthropic_version,
|
|
||||||
anthropic_max_tokens: prefs_api.anthropic_max_tokens,
|
|
||||||
do_debug: this.do_debug,
|
|
||||||
i18nStrings: ''
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.worker.postMessage(workerInitMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendPrompt(){
|
sendPrompt(){
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from '../options/mzta-options-default.js';
|
import { prefs_default, getDynamicSettingValue } from '../options/mzta-options-default.js';
|
||||||
const sparks_min = '1.2.0'; // Minimum version of ThunderAI-Sparks required for the add-on to work
|
const sparks_min = '1.2.0'; // Minimum version of ThunderAI-Sparks required for the add-on to work
|
||||||
export const ChatGPTWeb_models = ['gpt-5','gpt-5-instant','gpt-5-t-mini','gpt-5-thinking']; // List of models available in ChatGPT Web
|
export const ChatGPTWeb_models = ['gpt-5','gpt-5-instant','gpt-5-t-mini','gpt-5-thinking']; // List of models available in ChatGPT Web
|
||||||
|
|
||||||
|
|
@ -189,6 +189,17 @@ export async function replaceBody(tabId, replyHtml) {
|
||||||
await messenger.compose.setComposeDetails(tabId, {body: fullBody});
|
await messenger.compose.setComposeDetails(tabId, {body: fullBody});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getMailHeader(curr_message, mail_header_id) {
|
||||||
|
let mail_header_value = "";
|
||||||
|
let full_message = await browser.messages.getFull(curr_message.id);
|
||||||
|
// console.log(">>>>>>>>>>>> getMailHeader full_message: " + JSON.stringify(full_message));
|
||||||
|
if(full_message.hasOwnProperty("headers") && Object.keys(full_message.headers).some(header => header.toLowerCase() === mail_header_id.toLowerCase())){
|
||||||
|
mail_header_value = full_message.headers[Object.keys(full_message.headers).find(header => header.toLowerCase() === mail_header_id.toLowerCase())];
|
||||||
|
}
|
||||||
|
// console.log(">>>>>>>>>>>> getMailHeader mail_header_value: " + mail_header_value)
|
||||||
|
return mail_header_value;
|
||||||
|
}
|
||||||
|
|
||||||
export function sanitizeHtml(input) {
|
export function sanitizeHtml(input) {
|
||||||
// Keep only <br> tags and remove all other HTML tags
|
// Keep only <br> tags and remove all other HTML tags
|
||||||
return input.replace(/<(?!br\s*\/?)[^>]+>/gi, '');
|
return input.replace(/<(?!br\s*\/?)[^>]+>/gi, '');
|
||||||
|
|
@ -612,19 +623,33 @@ export function extractJsonObject(inputString) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isAPIKeyValue(id){
|
export function isAPIKeyValue(id){
|
||||||
return id=="chatgpt_api_key" || id=="openai_comp_api_key" || id=="google_gemini_api_key" || id=="anthropic_api_key";
|
return id.endsWith('_api_key');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getConnectionType(conntype, prompt, use_promptspecific_api = true) {
|
export function getConnectionType(prefsOrType, prompt, prefixOrSpecific = null) {
|
||||||
if(!use_promptspecific_api) {
|
let defaultType = '';
|
||||||
return conntype;
|
let specificType = '';
|
||||||
}
|
|
||||||
// console.log(">>>>>>>>>>> getConnectionType conntype: " + conntype + " prompt: " + JSON.stringify(prompt));
|
if (typeof prefsOrType === 'object' && prefsOrType !== null) {
|
||||||
if (prompt?.api != null && prompt.api !== '') {
|
// New signature: (prefs, prompt, prefix)
|
||||||
return prompt.api;
|
defaultType = prefsOrType.connection_type;
|
||||||
} else {
|
if (typeof prefixOrSpecific === 'string' && prefixOrSpecific) {
|
||||||
return conntype;
|
const prefix = prefixOrSpecific;
|
||||||
}
|
const useSpecific = getDynamicSettingValue(prefsOrType, prefix, 'use_specific_integration');
|
||||||
|
if (useSpecific) {
|
||||||
|
specificType = getDynamicSettingValue(prefsOrType, prefix, 'connection_type');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Old signature / Direct usage: (connection_type_string, prompt, [specific_type_string])
|
||||||
|
if (typeof prefixOrSpecific === 'string') {
|
||||||
|
specificType = prefixOrSpecific;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (specificType && specificType !== '') return specificType;
|
||||||
|
if (prompt && prompt.api && prompt.api !== '') return prompt.api;
|
||||||
|
return defaultType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkSparksPresence() {
|
export async function checkSparksPresence() {
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@
|
||||||
import { Anthropic } from '../api/anthropic.js';
|
import { Anthropic } from '../api/anthropic.js';
|
||||||
import { taLogger } from '../mzta-logger.js';
|
import { taLogger } from '../mzta-logger.js';
|
||||||
|
|
||||||
let anthropic_api_key = null;
|
|
||||||
let anthropic_model = '';
|
|
||||||
let anthropic = null;
|
let anthropic = null;
|
||||||
let stopStreaming = false;
|
let stopStreaming = false;
|
||||||
let i18nStrings = null;
|
let i18nStrings = null;
|
||||||
|
|
@ -37,16 +35,15 @@ let assistantResponseAccumulator = '';
|
||||||
self.onmessage = async function(event) {
|
self.onmessage = async function(event) {
|
||||||
if (event.data.type === 'init') {
|
if (event.data.type === 'init') {
|
||||||
// console.log(">>>>>>>>>>>>>> event.data: " + JSON.stringify(event.data));
|
// console.log(">>>>>>>>>>>>>> event.data: " + JSON.stringify(event.data));
|
||||||
anthropic_api_key = event.data.anthropic_api_key;
|
let config = { stream: true };
|
||||||
anthropic_model = event.data.anthropic_model;
|
for (const key in event.data) {
|
||||||
anthropic = new Anthropic({
|
if (key.startsWith('anthropic_')) {
|
||||||
apiKey: anthropic_api_key,
|
let newKey = key.replace('anthropic_', '');
|
||||||
version: event.data.anthropic_version,
|
if (newKey === 'api_key') newKey = 'apiKey';
|
||||||
model: anthropic_model,
|
config[newKey] = event.data[key];
|
||||||
system_prompt: event.data.anthropic_system_prompt,
|
}
|
||||||
max_tokens: event.data.anthropic_max_tokens,
|
}
|
||||||
stream: true
|
anthropic = new Anthropic(config);
|
||||||
});
|
|
||||||
do_debug = event.data.do_debug;
|
do_debug = event.data.do_debug;
|
||||||
i18nStrings = event.data.i18nStrings;
|
i18nStrings = event.data.i18nStrings;
|
||||||
taLog = new taLogger('model-worker-anthropic', do_debug);
|
taLog = new taLogger('model-worker-anthropic', do_debug);
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@
|
||||||
import { GoogleGemini } from '../api/google_gemini.js';
|
import { GoogleGemini } from '../api/google_gemini.js';
|
||||||
import { taLogger } from '../mzta-logger.js';
|
import { taLogger } from '../mzta-logger.js';
|
||||||
|
|
||||||
let google_gemini_api_key = null;
|
|
||||||
let google_gemini_model = '';
|
|
||||||
let google_gemini = null;
|
let google_gemini = null;
|
||||||
let stopStreaming = false;
|
let stopStreaming = false;
|
||||||
let i18nStrings = null;
|
let i18nStrings = null;
|
||||||
|
|
@ -36,15 +34,15 @@ let assistantResponseAccumulator = '';
|
||||||
|
|
||||||
self.onmessage = async function(event) {
|
self.onmessage = async function(event) {
|
||||||
if (event.data.type === 'init') {
|
if (event.data.type === 'init') {
|
||||||
google_gemini_api_key = event.data.google_gemini_api_key;
|
let config = { stream: true };
|
||||||
google_gemini_model = event.data.google_gemini_model;
|
for (const key in event.data) {
|
||||||
google_gemini = new GoogleGemini({
|
if (key.startsWith('google_gemini_')) {
|
||||||
apiKey: google_gemini_api_key,
|
let newKey = key.replace('google_gemini_', '');
|
||||||
model: google_gemini_model,
|
if (newKey === 'api_key') newKey = 'apiKey';
|
||||||
system_instruction: event.data.google_gemini_system_instruction,
|
config[newKey] = event.data[key];
|
||||||
thinking_budget: event.data.google_gemini_thinking_budget,
|
}
|
||||||
stream: true
|
}
|
||||||
});
|
google_gemini = new GoogleGemini(config);
|
||||||
do_debug = event.data.do_debug;
|
do_debug = event.data.do_debug;
|
||||||
i18nStrings = event.data.i18nStrings;
|
i18nStrings = event.data.i18nStrings;
|
||||||
taLog = new taLogger('model-worker-google_gemini', do_debug);
|
taLog = new taLogger('model-worker-google_gemini', do_debug);
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,6 @@
|
||||||
import { Ollama } from '../api/ollama.js';
|
import { Ollama } from '../api/ollama.js';
|
||||||
import { taLogger } from '../mzta-logger.js';
|
import { taLogger } from '../mzta-logger.js';
|
||||||
|
|
||||||
let ollama_host = null;
|
|
||||||
let ollama_model = '';
|
|
||||||
let ollama_num_ctx = 0;
|
|
||||||
let ollama = null;
|
let ollama = null;
|
||||||
let stopStreaming = false;
|
let stopStreaming = false;
|
||||||
let i18nStrings = null;
|
let i18nStrings = null;
|
||||||
|
|
@ -38,16 +35,14 @@ let assistantResponseAccumulator = '';
|
||||||
self.onmessage = async function(event) {
|
self.onmessage = async function(event) {
|
||||||
switch (event.data.type) {
|
switch (event.data.type) {
|
||||||
case 'init':
|
case 'init':
|
||||||
ollama_host = event.data.ollama_host;
|
let config = { stream: true };
|
||||||
ollama_model = event.data.ollama_model;
|
for (const key in event.data) {
|
||||||
ollama_num_ctx = event.data.ollama_num_ctx;
|
if (key.startsWith('ollama_')) {
|
||||||
//console.log(">>>>>>>>>>> ollama_host: " + ollama_host);
|
let newKey = key.replace('ollama_', '');
|
||||||
ollama = new Ollama({
|
config[newKey] = event.data[key];
|
||||||
host: ollama_host,
|
}
|
||||||
model: ollama_model,
|
}
|
||||||
stream: true,
|
ollama = new Ollama(config);
|
||||||
num_ctx: ollama_num_ctx
|
|
||||||
});
|
|
||||||
do_debug = event.data.do_debug;
|
do_debug = event.data.do_debug;
|
||||||
i18nStrings = event.data.i18nStrings;
|
i18nStrings = event.data.i18nStrings;
|
||||||
taLog = new taLogger('model-worker-ollama', do_debug);
|
taLog = new taLogger('model-worker-ollama', do_debug);
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,6 @@
|
||||||
import { OpenAIComp } from '../api/openai_comp.js';
|
import { OpenAIComp } from '../api/openai_comp.js';
|
||||||
import { taLogger } from '../mzta-logger.js';
|
import { taLogger } from '../mzta-logger.js';
|
||||||
|
|
||||||
let openai_comp_host = null;
|
|
||||||
let openai_comp_model = '';
|
|
||||||
let openai_comp_api_key = '';
|
|
||||||
let openai_comp_use_v1 = true;
|
|
||||||
let openai_comp = null;
|
let openai_comp = null;
|
||||||
let stopStreaming = false;
|
let stopStreaming = false;
|
||||||
let i18nStrings = null;
|
let i18nStrings = null;
|
||||||
|
|
@ -38,17 +34,15 @@ let assistantResponseAccumulator = '';
|
||||||
|
|
||||||
self.onmessage = async function(event) {
|
self.onmessage = async function(event) {
|
||||||
if (event.data.type === 'init') {
|
if (event.data.type === 'init') {
|
||||||
openai_comp_host = event.data.openai_comp_host;
|
let config = { stream: true };
|
||||||
openai_comp_model = event.data.openai_comp_model;
|
for (const key in event.data) {
|
||||||
openai_comp_api_key = event.data.openai_comp_api_key;
|
if (key.startsWith('openai_comp_')) {
|
||||||
openai_comp_use_v1 = event.data.openai_comp_use_v1;
|
let newKey = key.replace('openai_comp_', '');
|
||||||
openai_comp = new OpenAIComp({
|
if (newKey === 'api_key') newKey = 'apiKey';
|
||||||
host: openai_comp_host,
|
config[newKey] = event.data[key];
|
||||||
model: openai_comp_model,
|
}
|
||||||
apiKey: openai_comp_api_key,
|
}
|
||||||
stream: true,
|
openai_comp = new OpenAIComp(config);
|
||||||
use_v1: openai_comp_use_v1
|
|
||||||
});
|
|
||||||
do_debug = event.data.do_debug;
|
do_debug = event.data.do_debug;
|
||||||
i18nStrings = event.data.i18nStrings;
|
i18nStrings = event.data.i18nStrings;
|
||||||
taLog = new taLogger('model-worker-openai_comp', do_debug);
|
taLog = new taLogger('model-worker-openai_comp', do_debug);
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,9 @@
|
||||||
* The original code has been released under the Apache License, Version 2.0.
|
* The original code has been released under the Apache License, Version 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { OpenAI } from '../api/openai.js';
|
import { OpenAI } from '../api/openai_responses.js';
|
||||||
import { taLogger } from '../mzta-logger.js';
|
import { taLogger } from '../mzta-logger.js';
|
||||||
|
|
||||||
let chatgpt_api_key = null;
|
|
||||||
let chatgpt_model = '';
|
|
||||||
let openai = null;
|
let openai = null;
|
||||||
let stopStreaming = false;
|
let stopStreaming = false;
|
||||||
let i18nStrings = null;
|
let i18nStrings = null;
|
||||||
|
|
@ -33,25 +31,36 @@ let taLog = null;
|
||||||
|
|
||||||
let conversationHistory = [];
|
let conversationHistory = [];
|
||||||
let assistantResponseAccumulator = '';
|
let assistantResponseAccumulator = '';
|
||||||
|
let previous_response_id = null;
|
||||||
|
|
||||||
self.onmessage = async function(event) {
|
self.onmessage = async function(event) {
|
||||||
if (event.data.type === 'init') {
|
if (event.data.type === 'init') {
|
||||||
chatgpt_api_key = event.data.chatgpt_api_key;
|
let config = { stream: true };
|
||||||
chatgpt_model = event.data.chatgpt_model;
|
for (const key in event.data) {
|
||||||
openai = new OpenAI({
|
if (key.startsWith('chatgpt_')) {
|
||||||
apiKey: chatgpt_api_key,
|
if (key.startsWith('chatgpt_web_')) continue; // Exclude chatgpt_web_ prefixed keys
|
||||||
model: chatgpt_model,
|
let newKey = key.replace('chatgpt_', '');
|
||||||
developer_messages: event.data.chatgpt_developer_messages,
|
if (newKey === 'api_key') newKey = 'apiKey';
|
||||||
stream: true,
|
config[newKey] = event.data[key];
|
||||||
store: event.data.chatgpt_api_store
|
}
|
||||||
});
|
}
|
||||||
|
openai = new OpenAI(config);
|
||||||
do_debug = event.data.do_debug;
|
do_debug = event.data.do_debug;
|
||||||
i18nStrings = event.data.i18nStrings;
|
i18nStrings = event.data.i18nStrings;
|
||||||
taLog = new taLogger('model-worker-openai', do_debug);
|
taLog = new taLogger('model-worker-openai_responses', do_debug);
|
||||||
|
previous_response_id = null;
|
||||||
} else if (event.data.type === 'chatMessage') {
|
} else if (event.data.type === 'chatMessage') {
|
||||||
conversationHistory.push({ role: 'user', content: event.data.message });
|
conversationHistory.push({ role: 'user', content: event.data.message });
|
||||||
|
|
||||||
const response = await openai.fetchResponse(conversationHistory); //4096);
|
let messagesToSend = conversationHistory;
|
||||||
|
if (previous_response_id) {
|
||||||
|
messagesToSend = [conversationHistory[conversationHistory.length - 1]];
|
||||||
|
taLog.log("previous_response_id: " + previous_response_id);
|
||||||
|
} else {
|
||||||
|
taLog.log("no previous_response_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await openai.fetchResponse(messagesToSend, 0, previous_response_id);
|
||||||
postMessage({ type: 'messageSent' });
|
postMessage({ type: 'messageSent' });
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
|
|
@ -102,9 +111,10 @@ self.onmessage = async function(event) {
|
||||||
let parsedLines = [];
|
let parsedLines = [];
|
||||||
try{
|
try{
|
||||||
parsedLines = lines
|
parsedLines = lines
|
||||||
|
.map((line) => line.trim())
|
||||||
|
.filter((line) => line.startsWith("data:"))
|
||||||
.map((line) => line.replace(/^data: /, "").trim()) // Remove the "data: " prefix
|
.map((line) => line.replace(/^data: /, "").trim()) // Remove the "data: " prefix
|
||||||
.filter((line) => line !== "" && line !== "[DONE]") // Remove empty lines and "[DONE]"
|
.filter((line) => line !== "" && line !== "[DONE]") // Remove empty lines and "[DONE]"
|
||||||
// .map((line) => JSON.parse(line)); // Parse the JSON string
|
|
||||||
.map((line) => {
|
.map((line) => {
|
||||||
try {
|
try {
|
||||||
taLog.log("line: " + JSON.stringify(line));
|
taLog.log("line: " + JSON.stringify(line));
|
||||||
|
|
@ -120,13 +130,13 @@ self.onmessage = async function(event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const parsedLine of parsedLines) {
|
for (const parsedLine of parsedLines) {
|
||||||
const { choices } = parsedLine;
|
if (parsedLine.type === 'response.created' && parsedLine.response && parsedLine.response.id){
|
||||||
const { delta } = choices[0];
|
previous_response_id = parsedLine.response.id;
|
||||||
const { content } = delta;
|
} else if (parsedLine.type === 'response.output_text.delta' && parsedLine.delta) {
|
||||||
// Update the UI with the new content
|
assistantResponseAccumulator += parsedLine.delta;
|
||||||
if (content) {
|
postMessage({ type: 'newToken', payload: { token: parsedLine.delta } });
|
||||||
assistantResponseAccumulator += content;
|
// } else if (parsedLine.type === 'response.completed' && parsedLine.response && parsedLine.response.id) {
|
||||||
postMessage({ type: 'newToken', payload: { token: content } });
|
// previous_response_id = parsedLine.response.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "ThunderAI",
|
"name": "ThunderAI",
|
||||||
"description": "__MSG_extensionDescription__",
|
"description": "__MSG_extensionDescription__",
|
||||||
"version": "3.7.8",
|
"version": "3.8.0pre3",
|
||||||
"author": "Mic (m@micz.it)",
|
"author": "Mic (m@micz.it)",
|
||||||
"homepage_url": "https://micz.it/thunderbird-addon-thunderai/",
|
"homepage_url": "https://micz.it/thunderbird-addon-thunderai/",
|
||||||
"browser_specific_settings": {
|
"browser_specific_settings": {
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { mzta_script } from './js/mzta-chatgpt.js';
|
import { mzta_script } from './js/mzta-chatgpt.js';
|
||||||
import { prefs_default } from './options/mzta-options-default.js';
|
import {
|
||||||
|
prefs_default,
|
||||||
|
getDynamicSettingValue,
|
||||||
|
getDynamicSettingsDefaults
|
||||||
|
} from './options/mzta-options-default.js';
|
||||||
import { mzta_Menus } from './js/mzta-menus.js';
|
import { mzta_Menus } from './js/mzta-menus.js';
|
||||||
import { taLogger } from './js/mzta-logger.js';
|
import { taLogger } from './js/mzta-logger.js';
|
||||||
import {
|
import {
|
||||||
|
|
@ -838,10 +842,7 @@ async function reload_pref_init(){
|
||||||
dynamic_menu_force_enter: prefs_default.dynamic_menu_force_enter,
|
dynamic_menu_force_enter: prefs_default.dynamic_menu_force_enter,
|
||||||
add_tags_context_menu: prefs_default.add_tags_context_menu,
|
add_tags_context_menu: prefs_default.add_tags_context_menu,
|
||||||
spamfilter_context_menu: prefs_default.spamfilter_context_menu,
|
spamfilter_context_menu: prefs_default.spamfilter_context_menu,
|
||||||
add_tags_use_specific_integration: prefs_default.add_tags_use_specific_integration,
|
...getDynamicSettingsDefaults(['use_specific_integration', 'connection_type'])
|
||||||
add_tags_connection_type: prefs_default.add_tags_connection_type,
|
|
||||||
spamfilter_use_specific_integration: prefs_default.spamfilter_use_specific_integration,
|
|
||||||
spamfilter_connection_type: prefs_default.spamfilter_connection_type
|
|
||||||
});
|
});
|
||||||
_process_incoming = prefs_init.add_tags_auto || prefs_init.spamfilter;
|
_process_incoming = prefs_init.add_tags_auto || prefs_init.spamfilter;
|
||||||
_sparks_presence = await checkSparksPresence();
|
_sparks_presence = await checkSparksPresence();
|
||||||
|
|
@ -1073,8 +1074,7 @@ async function processEmails(messages, addTagsAuto, spamFilter) {
|
||||||
add_tags_auto_uselist: prefs_default.add_tags_auto_uselist,
|
add_tags_auto_uselist: prefs_default.add_tags_auto_uselist,
|
||||||
add_tags_auto_uselist_list: prefs_default.add_tags_auto_uselist_list,
|
add_tags_auto_uselist_list: prefs_default.add_tags_auto_uselist_list,
|
||||||
spamfilter_enabled_accounts: prefs_default.spamfilter_enabled_accounts,
|
spamfilter_enabled_accounts: prefs_default.spamfilter_enabled_accounts,
|
||||||
add_tags_use_specific_integration: prefs_default.add_tags_use_specific_integration,
|
...getDynamicSettingsDefaults(['use_specific_integration', 'connection_type']),
|
||||||
spamfilter_use_specific_integration: prefs_default.spamfilter_use_specific_integration,
|
|
||||||
do_debug: prefs_default.do_debug,
|
do_debug: prefs_default.do_debug,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1121,9 +1121,10 @@ async function processEmails(messages, addTagsAuto, spamFilter) {
|
||||||
// console.log(">>>>>>>>>> curr_prompt_add_tags.model: " + curr_prompt_add_tags.model);
|
// console.log(">>>>>>>>>> curr_prompt_add_tags.model: " + curr_prompt_add_tags.model);
|
||||||
let cmd_addTags = new mzta_specialCommand({
|
let cmd_addTags = new mzta_specialCommand({
|
||||||
prompt: specialFullPrompt_add_tags,
|
prompt: specialFullPrompt_add_tags,
|
||||||
llm: getConnectionType(prefs_aats.connection_type, curr_prompt_add_tags, prefs_aats.add_tags_use_specific_integration),
|
llm: getConnectionType(prefs_aats, curr_prompt_add_tags, 'add_tags'),
|
||||||
custom_model: curr_prompt_add_tags.model ? curr_prompt_add_tags.model : '',
|
custom_model: curr_prompt_add_tags.model ? curr_prompt_add_tags.model : '',
|
||||||
do_debug: prefs_aats.do_debug
|
do_debug: prefs_aats.do_debug,
|
||||||
|
config: curr_prompt_add_tags
|
||||||
});
|
});
|
||||||
await cmd_addTags.initWorker();
|
await cmd_addTags.initWorker();
|
||||||
let tags_current_email = [];
|
let tags_current_email = [];
|
||||||
|
|
@ -1160,9 +1161,10 @@ async function processEmails(messages, addTagsAuto, spamFilter) {
|
||||||
// console.log(">>>>>>>> Special prompt for spamfilter: " + specialFullPrompt_spamfilter);
|
// console.log(">>>>>>>> Special prompt for spamfilter: " + specialFullPrompt_spamfilter);
|
||||||
let cmd_spamfilter = new mzta_specialCommand({
|
let cmd_spamfilter = new mzta_specialCommand({
|
||||||
prompt: specialFullPrompt_spamfilter,
|
prompt: specialFullPrompt_spamfilter,
|
||||||
llm: getConnectionType(prefs_aats.connection_type, curr_prompt_spamfilter, prefs_aats.spamfilter_use_specific_integration),
|
llm: getConnectionType(prefs_aats, curr_prompt_spamfilter, 'spamfilter'),
|
||||||
custom_model: curr_prompt_spamfilter.model ? curr_prompt_spamfilter.model : '',
|
custom_model: curr_prompt_spamfilter.model ? curr_prompt_spamfilter.model : '',
|
||||||
do_debug: prefs_aats.do_debug
|
do_debug: prefs_aats.do_debug,
|
||||||
|
config: curr_prompt_spamfilter
|
||||||
});
|
});
|
||||||
await cmd_spamfilter.initWorker();
|
await cmd_spamfilter.initWorker();
|
||||||
let spamfilter_result = '';
|
let spamfilter_result = '';
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,86 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const special_prompts_with_integration = ['add_tags', 'spamfilter'];
|
||||||
|
|
||||||
|
export const integration_options_config = {
|
||||||
|
chatgpt: {
|
||||||
|
api_key: '',
|
||||||
|
model: '',
|
||||||
|
developer_messages: '',
|
||||||
|
temperature: '',
|
||||||
|
store: false
|
||||||
|
},
|
||||||
|
ollama: {
|
||||||
|
host: '',
|
||||||
|
model: '',
|
||||||
|
num_ctx: 0,
|
||||||
|
temperature: '',
|
||||||
|
think: false
|
||||||
|
},
|
||||||
|
openai_comp: {
|
||||||
|
host: '',
|
||||||
|
model: '',
|
||||||
|
api_key: '',
|
||||||
|
use_v1: true,
|
||||||
|
chat_name: 'OpenAI Comp',
|
||||||
|
temperature: ''
|
||||||
|
},
|
||||||
|
google_gemini: {
|
||||||
|
api_key: '',
|
||||||
|
model: '',
|
||||||
|
system_instruction: '',
|
||||||
|
thinking_budget: '',
|
||||||
|
temperature: ''
|
||||||
|
},
|
||||||
|
anthropic: {
|
||||||
|
api_key: '',
|
||||||
|
model: '',
|
||||||
|
version: '2023-06-01',
|
||||||
|
max_tokens: 4096,
|
||||||
|
system_prompt: '',
|
||||||
|
temperature: ''
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const integration_settings_template = {
|
||||||
|
use_specific_integration: false,
|
||||||
|
connection_type: 'chatgpt_api',
|
||||||
|
};
|
||||||
|
|
||||||
|
const global_integration_settings = { ...integration_settings_template };
|
||||||
|
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const [key, value] of Object.entries(options)) {
|
||||||
|
global_integration_settings[`${integration}_${key}`] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let generated_prefs = {};
|
||||||
|
|
||||||
|
special_prompts_with_integration.forEach(prompt_prefix => {
|
||||||
|
for (const [key, value] of Object.entries(integration_settings_template)) {
|
||||||
|
generated_prefs[`${prompt_prefix}_${key}`] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export function getDynamicSettingsDefaults(keysFilter = []) {
|
||||||
|
let defaults = {};
|
||||||
|
special_prompts_with_integration.forEach(prefix => {
|
||||||
|
const keys = keysFilter.length > 0 ? keysFilter : Object.keys(integration_settings_template);
|
||||||
|
keys.forEach(key => {
|
||||||
|
defaults[`${prefix}_${key}`] = prefs_default[`${prefix}_${key}`];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDynamicSettingValue(prefs, prefix, settingName) {
|
||||||
|
return prefs[`${prefix}_${settingName}`];
|
||||||
|
}
|
||||||
|
|
||||||
export const prefs_default = {
|
export const prefs_default = {
|
||||||
|
...global_integration_settings,
|
||||||
do_debug: false,
|
do_debug: false,
|
||||||
chatgpt_win_height: 800,
|
chatgpt_win_height: 800,
|
||||||
chatgpt_win_width: 700,
|
chatgpt_win_width: 700,
|
||||||
|
|
@ -29,28 +108,6 @@ export const prefs_default = {
|
||||||
chatgpt_web_tempchat: false,
|
chatgpt_web_tempchat: false,
|
||||||
chatgpt_web_project: '',
|
chatgpt_web_project: '',
|
||||||
chatgpt_web_custom_gpt: '',
|
chatgpt_web_custom_gpt: '',
|
||||||
chatgpt_api_key: '',
|
|
||||||
chatgpt_api_store: false,
|
|
||||||
chatgpt_model: '',
|
|
||||||
chatgpt_developer_messages: '',
|
|
||||||
ollama_host: '',
|
|
||||||
ollama_model: '',
|
|
||||||
ollama_num_ctx: 0,
|
|
||||||
ollama_think: false,
|
|
||||||
openai_comp_host: '', // For OpenAI Compatible API as LM-Studio
|
|
||||||
openai_comp_model: '',
|
|
||||||
openai_comp_api_key: '',
|
|
||||||
openai_comp_use_v1: true,
|
|
||||||
openai_comp_chat_name: 'OpenAI Comp',
|
|
||||||
google_gemini_api_key: '',
|
|
||||||
google_gemini_model: '',
|
|
||||||
google_gemini_system_instruction: '',
|
|
||||||
google_gemini_thinking_budget: '',
|
|
||||||
anthropic_api_key: '',
|
|
||||||
anthropic_model: '',
|
|
||||||
anthropic_version: '2023-06-01',
|
|
||||||
anthropic_max_tokens: 4096,
|
|
||||||
anthropic_system_prompt: '',
|
|
||||||
dynamic_menu_force_enter: false,
|
dynamic_menu_force_enter: false,
|
||||||
dynamic_menu_order_alphabet: true,
|
dynamic_menu_order_alphabet: true,
|
||||||
placeholders_use_default_value: false,
|
placeholders_use_default_value: false,
|
||||||
|
|
@ -68,13 +125,6 @@ export const prefs_default = {
|
||||||
add_tags_auto_uselist_list: '',
|
add_tags_auto_uselist_list: '',
|
||||||
add_tags_context_menu: true,
|
add_tags_context_menu: true,
|
||||||
add_tags_enabled_accounts: [],
|
add_tags_enabled_accounts: [],
|
||||||
add_tags_use_specific_integration: false,
|
|
||||||
add_tags_connection_type: 'chatgpt_api',
|
|
||||||
add_tags_chatgpt_model: '',
|
|
||||||
add_tags_ollama_model: '',
|
|
||||||
add_tags_openai_comp_model: '',
|
|
||||||
add_tags_google_gemini_model: '',
|
|
||||||
add_tags_anthropic_model: '',
|
|
||||||
get_calendar_event: true,
|
get_calendar_event: true,
|
||||||
get_task: true,
|
get_task: true,
|
||||||
calendar_enforce_timezone: false,
|
calendar_enforce_timezone: false,
|
||||||
|
|
@ -83,12 +133,6 @@ export const prefs_default = {
|
||||||
spamfilter_threshold: 70,
|
spamfilter_threshold: 70,
|
||||||
spamfilter_context_menu: true,
|
spamfilter_context_menu: true,
|
||||||
spamfilter_enabled_accounts: [],
|
spamfilter_enabled_accounts: [],
|
||||||
spamfilter_use_specific_integration: false,
|
|
||||||
spamfilter_connection_type: 'chatgpt_api',
|
|
||||||
spamfilter_chatgpt_model: '',
|
|
||||||
spamfilter_ollama_model: '',
|
|
||||||
spamfilter_openai_comp_model: '',
|
|
||||||
spamfilter_google_gemini_model: '',
|
|
||||||
spamfilter_anthropic_model: '',
|
|
||||||
auto_summary_enabled: false, // Enable automatic AI summarization for message previews
|
auto_summary_enabled: false, // Enable automatic AI summarization for message previews
|
||||||
|
...generated_prefs
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from './mzta-options-default.js';
|
import { prefs_default, getDynamicSettingsDefaults } from './mzta-options-default.js';
|
||||||
import { taLogger } from '../js/mzta-logger.js';
|
import { taLogger } from '../js/mzta-logger.js';
|
||||||
import {
|
import {
|
||||||
ChatGPTWeb_models,
|
ChatGPTWeb_models,
|
||||||
|
|
@ -127,7 +127,11 @@ function disable_MaxPromptLength(){
|
||||||
function disable_AddTags(prefs_opt){
|
function disable_AddTags(prefs_opt){
|
||||||
let add_tags = document.getElementById('add_tags');
|
let add_tags = document.getElementById('add_tags');
|
||||||
let conntype_select = document.getElementById("connection_type");
|
let conntype_select = document.getElementById("connection_type");
|
||||||
let add_tags_disabled = (getConnectionType(conntype_select.value, {api: prefs_opt.add_tags_use_specific_integration ? prefs_opt.add_tags_connection_type : ''}) === "chatgpt_web");
|
const tempPrefs = {
|
||||||
|
connection_type: conntype_select.value,
|
||||||
|
...prefs_opt
|
||||||
|
};
|
||||||
|
let add_tags_disabled = (getConnectionType(tempPrefs, null, 'add_tags') === "chatgpt_web");
|
||||||
// console.log('>>>>>>>>>>>>> add_tags_disabled: ' + add_tags_disabled);
|
// console.log('>>>>>>>>>>>>> add_tags_disabled: ' + add_tags_disabled);
|
||||||
add_tags.checked = add_tags_disabled ? false : add_tags.checked;
|
add_tags.checked = add_tags_disabled ? false : add_tags.checked;
|
||||||
let add_tags_checked_original = add_tags.checked;
|
let add_tags_checked_original = add_tags.checked;
|
||||||
|
|
@ -145,7 +149,11 @@ function disable_AddTags(prefs_opt){
|
||||||
function disable_SpamFilter(prefs_opt){
|
function disable_SpamFilter(prefs_opt){
|
||||||
let spamfilter = document.getElementById('spamfilter');
|
let spamfilter = document.getElementById('spamfilter');
|
||||||
let conntype_select = document.getElementById("connection_type");
|
let conntype_select = document.getElementById("connection_type");
|
||||||
let spamfilter_disabled = (getConnectionType(conntype_select.value, {api: prefs_opt.spamfilter_use_specific_integration ? prefs_opt.spamfilter_connection_type : ''}) === "chatgpt_web");;
|
const tempPrefs = {
|
||||||
|
connection_type: conntype_select.value,
|
||||||
|
...prefs_opt
|
||||||
|
};
|
||||||
|
let spamfilter_disabled = (getConnectionType(tempPrefs, null, 'spamfilter') === "chatgpt_web");
|
||||||
let spamfilter_checked_original = spamfilter.checked;
|
let spamfilter_checked_original = spamfilter.checked;
|
||||||
spamfilter.checked = spamfilter_disabled ? false : spamfilter.checked;
|
spamfilter.checked = spamfilter_disabled ? false : spamfilter.checked;
|
||||||
if(!spamfilter.checked){
|
if(!spamfilter.checked){
|
||||||
|
|
@ -302,10 +310,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
let prefs_opt = await browser.storage.sync.get({
|
let prefs_opt = await browser.storage.sync.get({
|
||||||
add_tags_use_specific_integration: prefs_default.add_tags_use_specific_integration,
|
...getDynamicSettingsDefaults(['use_specific_integration', 'connection_type'])
|
||||||
add_tags_connection_type: prefs_default.add_tags_connection_type,
|
|
||||||
spamfilter_use_specific_integration: prefs_default.spamfilter_use_specific_integration,
|
|
||||||
spamfilter_connection_type: prefs_default.spamfilter_connection_type,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let conntype_select = document.getElementById("connection_type");
|
let conntype_select = document.getElementById("connection_type");
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,18 @@
|
||||||
<body>
|
<body>
|
||||||
<div id="miczBackPrefs"><a href="mzta-options.html">__MSG_backToOptionsText__</a></div>
|
<div id="miczBackPrefs"><a href="mzta-options.html">__MSG_backToOptionsText__</a></div>
|
||||||
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
||||||
|
<h2>Version 3.8.0 - ??/??/2025</h2>
|
||||||
|
<ul>
|
||||||
|
<li><i>[All APIs]</i> When using special prompts (like automatically adding tags or the spam filter) with a specific API integration, all the settings for that integration can be specific. In this way you can use different api keys for the same integration, or different system prompt or temperature [<a href="https://github.com/micz/ThunderAI/pull/590">#590</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> Added the temperature parameter [<a href="https://github.com/micz/ThunderAI/issues/561">#561</a>].</li>
|
||||||
|
<li><i>[OpenAI API]</i> Model filtering improved when choosing a model in the options page.</li>
|
||||||
|
<li><i>[OpenAI API]</i> Now using the new Responses API [<a href="https://github.com/micz/ThunderAI/issues/407">#407</a>].</li>
|
||||||
|
<li>It is now possible to define a custom placeholder with dynamic data to retrieve any header present in the current email [<a href="https://github.com/micz/ThunderAI/issues/527">#527</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> The configuration information reported in the webchat API has been improved for all integrations.</li>
|
||||||
|
<li>Spanish (es) translation added, thanks to <a href="https://hosted.weblate.org/user/gerardo.sobarzo/">Gerardo Sobarzo</a>, <a href="https://hosted.weblate.org/user/arendon/">Andrés Rendón Hernández</a>, <a href="https://hosted.weblate.org/user/ErickLimonG/">Erick Limon</a>.</li>
|
||||||
|
<li>Various fixes.</li>
|
||||||
|
<li>...</li>
|
||||||
|
</ul>
|
||||||
<h2>Version 3.7.8 - 18/12/2025</h2>
|
<h2>Version 3.7.8 - 18/12/2025</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Greek (el) translation added, thanks to <a href="https://github.com/christoskaterini">ChristosK.</a>.</li>
|
<li>Greek (el) translation added, thanks to <a href="https://github.com/christoskaterini">ChristosK.</a>.</li>
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,25 @@
|
||||||
tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
|
tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
|
||||||
background-color: rgb(185, 220, 252);
|
background-color: rgb(185, 220, 252) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.conntype_chatgpt_web, tr.conntype_chatgpt_web2{
|
tr.conntype_chatgpt_web, tr.conntype_chatgpt_web2{
|
||||||
background-color: rgb(255, 209, 183);
|
background-color: rgb(255, 209, 183) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.conntype_ollama_api, tr.conntype_ollama_api2{
|
tr.conntype_ollama_api, tr.conntype_ollama_api2{
|
||||||
background-color: rgb(177, 238, 169);
|
background-color: rgb(177, 238, 169) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.conntype_openai_comp_api, tr.conntype_openai_comp_api2{
|
tr.conntype_openai_comp_api, tr.conntype_openai_comp_api2{
|
||||||
background-color: rgb(213, 169, 238);
|
background-color: rgb(213, 169, 238) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.conntype_google_gemini_api, tr.conntype_google_gemini_api2{
|
tr.conntype_google_gemini_api, tr.conntype_google_gemini_api2{
|
||||||
background-color: rgb(233, 238, 169);
|
background-color: rgb(233, 238, 169) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.conntype_anthropic_api, tr.conntype_anthropic_api2{
|
tr.conntype_anthropic_api, tr.conntype_anthropic_api2{
|
||||||
background-color: rgb(255, 168, 204);
|
background-color: rgb(255, 168, 204) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chatgpt_model_fetch_loading{
|
#chatgpt_model_fetch_loading{
|
||||||
|
|
@ -37,6 +37,10 @@ textarea.option-textarea{
|
||||||
height: 10em;
|
height: 10em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label{
|
||||||
|
width: -moz-available;
|
||||||
|
}
|
||||||
|
|
||||||
.api_key-container {
|
.api_key-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -89,27 +93,27 @@ span.opt_title{
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
|
tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
|
||||||
background-color: rgb(0, 0, 58);
|
background-color: rgb(0, 0, 58) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.conntype_chatgpt_web,tr.conntype_chatgpt_web2{
|
tr.conntype_chatgpt_web,tr.conntype_chatgpt_web2{
|
||||||
background-color: rgb(39, 11, 0);
|
background-color: rgb(39, 11, 0) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.conntype_ollama_api, tr.conntype_ollama_api2{
|
tr.conntype_ollama_api, tr.conntype_ollama_api2{
|
||||||
background-color: rgb(7, 58, 0);
|
background-color: rgb(7, 58, 0) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.conntype_openai_comp_api, tr.conntype_openai_comp_api2{
|
tr.conntype_openai_comp_api, tr.conntype_openai_comp_api2{
|
||||||
background-color: rgb(89, 20, 129);
|
background-color: rgb(89, 20, 129) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.conntype_google_gemini_api, tr.conntype_google_gemini_api2{
|
tr.conntype_google_gemini_api, tr.conntype_google_gemini_api2{
|
||||||
background-color: rgb(72, 77, 3);
|
background-color: rgb(72, 77, 3) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
tr.conntype_anthropic_api, tr.conntype_anthropic_api2{
|
tr.conntype_anthropic_api, tr.conntype_anthropic_api2{
|
||||||
background-color: rgb(83, 0, 35);
|
background-color: rgb(83, 0, 35) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.api_key-container .toggle-icon img {
|
.api_key-container .toggle-icon img {
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,11 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from '../../options/mzta-options-default.js';
|
import {
|
||||||
import { OpenAI } from '../../js/api/openai.js';
|
prefs_default,
|
||||||
|
integration_options_config
|
||||||
|
} from '../../options/mzta-options-default.js';
|
||||||
|
import { OpenAI } from '../../js/api/openai_responses.js';
|
||||||
import { Ollama } from '../../js/api/ollama.js';
|
import { Ollama } from '../../js/api/ollama.js';
|
||||||
import { OpenAIComp } from '../../js/api/openai_comp.js'
|
import { OpenAIComp } from '../../js/api/openai_comp.js'
|
||||||
import { GoogleGemini } from '../../js/api/google_gemini.js';
|
import { GoogleGemini } from '../../js/api/google_gemini.js';
|
||||||
|
|
@ -28,6 +31,7 @@ import {
|
||||||
sanitizeChatGPTWebCustomData
|
sanitizeChatGPTWebCustomData
|
||||||
} from '../../js/mzta-utils.js';
|
} from '../../js/mzta-utils.js';
|
||||||
import { openAICompConfigs } from '../../js/api/openai_comp_configs.js';
|
import { openAICompConfigs } from '../../js/api/openai_comp_configs.js';
|
||||||
|
import { loadPrompt, savePrompt, clearPromptAPI } from '../../js/mzta-prompts.js';
|
||||||
|
|
||||||
export const varConnectionUI = {
|
export const varConnectionUI = {
|
||||||
permission_all_urls: false
|
permission_all_urls: false
|
||||||
|
|
@ -40,7 +44,9 @@ export async function injectConnectionUI({
|
||||||
no_chatgpt_web = false,
|
no_chatgpt_web = false,
|
||||||
defaultType = '',
|
defaultType = '',
|
||||||
tr_class = '',
|
tr_class = '',
|
||||||
taLog = console
|
taLog = console,
|
||||||
|
customButtonLabel = '',
|
||||||
|
customButtonCallback = null
|
||||||
} = {}) {
|
} = {}) {
|
||||||
|
|
||||||
const anchorTr = document.getElementById(afterTrId);
|
const anchorTr = document.getElementById(afterTrId);
|
||||||
|
|
@ -49,6 +55,19 @@ export async function injectConnectionUI({
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inject CSS if not present
|
||||||
|
if (!document.getElementById('mzta-connection-ui-style')) {
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.id = 'mzta-connection-ui-style';
|
||||||
|
style.textContent = `
|
||||||
|
.api_key-container { position: relative; display: flex; align-items: center; }
|
||||||
|
.toggle-icon { cursor: pointer; margin-left: 5px; }
|
||||||
|
.toggle-icon img { width: 16px; height: 16px; vertical-align: middle; }
|
||||||
|
.option-input { flex-grow: 1; }
|
||||||
|
`;
|
||||||
|
document.head.appendChild(style);
|
||||||
|
}
|
||||||
|
|
||||||
let tpl = `
|
let tpl = `
|
||||||
<tr id="${selectId}_tr"${tr_class ? ` class="${tr_class}"` : ''}>
|
<tr id="${selectId}_tr"${tr_class ? ` class="${tr_class}"` : ''}>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -57,8 +76,9 @@ export async function injectConnectionUI({
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label style="display: flex; align-items: center;">
|
||||||
<select id="${selectId}" name="${selectId}" class="option-input"></select>
|
<select id="${selectId}" name="${selectId}" class="option-input"></select>
|
||||||
|
${customButtonLabel ? `<button id="${modelId_prefix}customButton" style="margin-left: 10px;">${customButtonLabel}</button>` : ''}
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -137,9 +157,9 @@ export async function injectConnectionUI({
|
||||||
<td>
|
<td>
|
||||||
<div class="api_key-container">
|
<div class="api_key-container">
|
||||||
<label>
|
<label>
|
||||||
<input type="password" id="chatgpt_api_key" name="chatgpt_api_key" class="option-input"/>
|
<input type="password" id="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_api_key" name="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_api_key" class="option-input"/>
|
||||||
</label>
|
</label>
|
||||||
<span class="toggle-icon" id="toggle_chatgpt_api_key"><img src="/images/pwd-show.png" id="pwd-icon_chatgpt_api_key"></span>
|
<span class="toggle-icon" id="${modelId_prefix ? `${modelId_prefix}` : ''}toggle_chatgpt_api_key"><img src="/images/pwd-show.png" id="${modelId_prefix ? `${modelId_prefix}` : ''}pwd-icon_chatgpt_api_key"></span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -150,9 +170,22 @@ export async function injectConnectionUI({
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button id="btnUpdateChatGPTModels">__MSG_ChatGPT_Models_Fetch__</button> <span id="chatgpt_model_fetch_loading">__MSG_Loading__</span><br>
|
<button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnUpdateChatGPTModels">__MSG_ChatGPT_Models_Fetch__</button> <span id="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_model_fetch_loading" style="display:none">__MSG_Loading__</span><br>
|
||||||
<label>
|
<label>
|
||||||
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_model" name="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_model" class="option-input option-input-model"></select>
|
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_model" name="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_model" class="option-input"></select>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="conntype_chatgpt_api${tr_class ? ` ${tr_class}` : ''}">
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<span class="opt_title">__MSG_prefs_api_temperature__</span>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="text" id="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_temperature" name="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_temperature" class="option-input check-number" />
|
||||||
|
<br>__MSG_prefs_chatgpt_api_temperature_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -164,7 +197,7 @@ export async function injectConnectionUI({
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="chatgpt_api_store" name="chatgpt_api_store" class="option-input" />
|
<input type="checkbox" id="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_store" name="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_store" class="option-input" />
|
||||||
<span>__MSG_ChatGPT_chatgpt_api_store_info__</span>
|
<span>__MSG_ChatGPT_chatgpt_api_store_info__</span>
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -177,7 +210,7 @@ export async function injectConnectionUI({
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<textarea id="chatgpt_developer_messages" name="chatgpt_developer_messages" class="option-input option-textarea"></textarea>
|
<textarea id="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_developer_messages" name="${modelId_prefix ? `${modelId_prefix}` : ''}chatgpt_developer_messages" class="option-input option-textarea"></textarea>
|
||||||
<br>__MSG_ChatGPT_Developer_Messages_Info__
|
<br>__MSG_ChatGPT_Developer_Messages_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -189,9 +222,9 @@ export async function injectConnectionUI({
|
||||||
<td>
|
<td>
|
||||||
<div class="api_key-container">
|
<div class="api_key-container">
|
||||||
<label>
|
<label>
|
||||||
<input type="password" id="google_gemini_api_key" name="google_gemini_api_key" class="option-input"/>
|
<input type="password" id="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_api_key" name="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_api_key" class="option-input"/>
|
||||||
</label>
|
</label>
|
||||||
<span class="toggle-icon" id="toggle_google_gemini_api_key"><img src="/images/pwd-show.png" id="pwd-icon_google_gemini_api_key"></span>
|
<span class="toggle-icon" id="${modelId_prefix ? `${modelId_prefix}` : ''}toggle_google_gemini_api_key"><img src="/images/pwd-show.png" id="${modelId_prefix ? `${modelId_prefix}` : ''}pwd-icon_google_gemini_api_key"></span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -202,9 +235,22 @@ export async function injectConnectionUI({
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button id="btnUpdateGoogleGeminiModels">__MSG_GoogleGemini_Models_Fetch__</button> <span id="google_gemini_model_fetch_loading">__MSG_Loading__</span><br>
|
<button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnUpdateGoogleGeminiModels">__MSG_GoogleGemini_Models_Fetch__</button> <span id="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_model_fetch_loading" style="display:none">__MSG_Loading__</span><br>
|
||||||
<label>
|
<label>
|
||||||
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_model" name="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_model" class="option-input option-input-model"></select>
|
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_model" name="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_model" class="option-input"></select>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="conntype_google_gemini_api${tr_class ? ` ${tr_class}` : ''}">
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<span class="opt_title">__MSG_prefs_api_temperature__</span>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="text" id="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_temperature" name="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_temperature" class="option-input check-number"/>
|
||||||
|
<br>__MSG_prefs_google_gemini_temperature_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -216,7 +262,7 @@ export async function injectConnectionUI({
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="text" id="google_gemini_thinking_budget" name="google_gemini_thinking_budget" class="option-input"/>
|
<input type="text" id="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_thinking_budget" name="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_thinking_budget" class="option-input"/>
|
||||||
<br>__MSG_prefs_google_gemini_thinking_budget_Info__
|
<br>__MSG_prefs_google_gemini_thinking_budget_Info__
|
||||||
<br><a href="https://ai.google.dev/gemini-api/docs/thinking#set-budget">__MSG_more_info_string__</a>
|
<br><a href="https://ai.google.dev/gemini-api/docs/thinking#set-budget">__MSG_more_info_string__</a>
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -230,7 +276,7 @@ export async function injectConnectionUI({
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<textarea id="google_gemini_system_instruction" name="google_gemini_system_instruction" class="option-input option-textarea"></textarea>
|
<textarea id="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_system_instruction" name="${modelId_prefix ? `${modelId_prefix}` : ''}google_gemini_system_instruction" class="option-input option-textarea"></textarea>
|
||||||
<br>__MSG_GoogleGemini_SystemInstruction_Info__
|
<br>__MSG_GoogleGemini_SystemInstruction_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -242,16 +288,16 @@ export async function injectConnectionUI({
|
||||||
</label></td>
|
</label></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="text" id="ollama_host" name="ollama_host" class="option-input"/>
|
<input type="text" id="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_host" name="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_host" class="option-input"/>
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="conntype_ollama_api${tr_class ? ` ${tr_class}` : ''}" id="ollama_api_cors_warning">
|
<tr class="conntype_ollama_api${tr_class ? ` ${tr_class}` : ''}" id="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_api_cors_warning">
|
||||||
<td colspan="2" style="text-align:center;">
|
<td colspan="2" style="text-align:center;">
|
||||||
__MSG_remember_CORS__ [<a href="https://micz.it/thunderbird-addon-thunderai/ollama-cors-information/">__MSG_more_info_string__</a>]
|
__MSG_remember_CORS__ [<a href="https://micz.it/thunderbird-addon-thunderai/ollama-cors-information/">__MSG_more_info_string__</a>]
|
||||||
<br><br><b>__MSG_CORS_alternative_1__</b>
|
<br><br><b>__MSG_CORS_alternative_1__</b>
|
||||||
<br>__MSG_CORS_alternative_2__
|
<br>__MSG_CORS_alternative_2__
|
||||||
<br><br><button id="btnGiveAllUrlsPermission_ollama_api">__MSG_CORS_give_allurls_perm__</button>
|
<br><br><button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnGiveAllUrlsPermission_ollama_api">__MSG_CORS_give_allurls_perm__</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="conntype_ollama_api${tr_class ? ` ${tr_class}` : ''}">
|
<tr class="conntype_ollama_api${tr_class ? ` ${tr_class}` : ''}">
|
||||||
|
|
@ -261,9 +307,22 @@ export async function injectConnectionUI({
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button id="btnUpdateOllamaModels">__MSG_Ollama_Models_Fetch__</button> <span id="ollama_model_fetch_loading">__MSG_Loading__</span><br>
|
<button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnUpdateOllamaModels">__MSG_Ollama_Models_Fetch__</button> <span id="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_model_fetch_loading" style="display:none">__MSG_Loading__</span><br>
|
||||||
<label>
|
<label>
|
||||||
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_model" name="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_model" class="option-input option-input-model"></select>
|
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_model" name="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_model" class="option-input"></select>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="conntype_ollama_api${tr_class ? ` ${tr_class}` : ''}">
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<span class="opt_title">__MSG_prefs_api_temperature__</span>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="text" id="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_temperature" name="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_temperature" class="option-input check-number" />
|
||||||
|
<br>__MSG_prefs_ollama_temperature_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -273,7 +332,7 @@ export async function injectConnectionUI({
|
||||||
</label></td>
|
</label></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="ollama_think" name="ollama_think" class="option-input"/>
|
<input type="checkbox" id="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_think" name="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_think" class="option-input"/>
|
||||||
__MSG_prefs_ollama_think_Info__
|
__MSG_prefs_ollama_think_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -284,7 +343,7 @@ export async function injectConnectionUI({
|
||||||
</label></td>
|
</label></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="number" id="ollama_num_ctx" name="ollama_num_ctx" class="option-input"/>
|
<input type="number" id="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_num_ctx" name="${modelId_prefix ? `${modelId_prefix}` : ''}ollama_num_ctx" class="option-input"/>
|
||||||
<br>__MSG_prefs_ollama_num_ctx_Info__
|
<br>__MSG_prefs_ollama_num_ctx_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -295,7 +354,7 @@ export async function injectConnectionUI({
|
||||||
</label></td>
|
</label></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<select id="openai_comp_services_shortcut"></select>
|
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_services_shortcut"></select>
|
||||||
<br>__MSG_prefs_OpenAIComp_AvailableServices_Info__
|
<br>__MSG_prefs_OpenAIComp_AvailableServices_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -307,17 +366,17 @@ export async function injectConnectionUI({
|
||||||
</label></td>
|
</label></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="text" id="openai_comp_host" name="openai_comp_host" class="option-input" />
|
<input type="text" id="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_host" name="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_host" class="option-input" />
|
||||||
<br>__MSG_prefs_OptionText_openai_comp_info_remote__
|
<br>__MSG_prefs_OptionText_openai_comp_info_remote__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="conntype_openai_comp_api${tr_class ? ` ${tr_class}` : ''}" id="openai_comp_api_cors_warning">
|
<tr class="conntype_openai_comp_api${tr_class ? ` ${tr_class}` : ''}" id="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_api_cors_warning">
|
||||||
<td colspan="2" style="text-align:center;">
|
<td colspan="2" style="text-align:center;">
|
||||||
__MSG_maybe_CORS_openai_comp__ [<a href="https://micz.it/thunderbird-addon-thunderai/ollama-cors-information/">__MSG_more_info_string__</a>]
|
__MSG_maybe_CORS_openai_comp__ [<a href="https://micz.it/thunderbird-addon-thunderai/ollama-cors-information/">__MSG_more_info_string__</a>]
|
||||||
<br><br><b>__MSG_CORS_alternative_1__</b>
|
<br><br><b>__MSG_CORS_alternative_1__</b>
|
||||||
<br>__MSG_CORS_alternative_2__
|
<br>__MSG_CORS_alternative_2__
|
||||||
<br><br><button id="btnGiveAllUrlsPermission_openai_comp_api">__MSG_CORS_give_allurls_perm__</button>
|
<br><br><button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnGiveAllUrlsPermission_openai_comp_api">__MSG_CORS_give_allurls_perm__</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="conntype_openai_comp_api${tr_class ? ` ${tr_class}` : ''}">
|
<tr class="conntype_openai_comp_api${tr_class ? ` ${tr_class}` : ''}">
|
||||||
|
|
@ -326,7 +385,7 @@ export async function injectConnectionUI({
|
||||||
</label></td>
|
</label></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="openai_comp_use_v1" name="openai_comp_use_v1" class="option-input" />
|
<input type="checkbox" id="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_use_v1" name="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_use_v1" class="option-input" />
|
||||||
<span>__MSG_prefs_OptionText_openai_comp_use_v1_info__</span>
|
<span>__MSG_prefs_OptionText_openai_comp_use_v1_info__</span>
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -339,9 +398,9 @@ export async function injectConnectionUI({
|
||||||
<td>
|
<td>
|
||||||
<div class="api_key-container">
|
<div class="api_key-container">
|
||||||
<label>
|
<label>
|
||||||
<input type="password" id="openai_comp_api_key" name="openai_comp_api_key" class="option-input"/>
|
<input type="password" id="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_api_key" name="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_api_key" class="option-input"/>
|
||||||
</label>
|
</label>
|
||||||
<span class="toggle-icon" id="toggle_openai_comp_api_key"><img src="/images/pwd-show.png" id="pwd-icon_openai_comp_api_key"></span>
|
<span class="toggle-icon" id="${modelId_prefix ? `${modelId_prefix}` : ''}toggle_openai_comp_api_key"><img src="/images/pwd-show.png" id="${modelId_prefix ? `${modelId_prefix}` : ''}pwd-icon_openai_comp_api_key"></span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -349,14 +408,14 @@ export async function injectConnectionUI({
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<span class="opt_title">__MSG_OpenAIComp_Models__</span>
|
<span class="opt_title">__MSG_OpenAIComp_Models__</span>
|
||||||
<br><button id="btnOpenAICompForceModel" class="btn_small">__MSG_prefs_OpenAIComp_ForceModel__</button>
|
<br><button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnOpenAICompForceModel" class="btn_small">__MSG_prefs_OpenAIComp_ForceModel__</button>
|
||||||
<br><button id="btnOpenAICompClearModelsList" class="btn_small">__MSG_prefs_OpenAIComp_ClearModelsList__</button></td>
|
<br><button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnOpenAICompClearModelsList" class="btn_small">__MSG_prefs_OpenAIComp_ClearModelsList__</button></td>
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button id="btnUpdateOpenAICompModels">__MSG_OpenAIComp_Models_Fetch__</button> <span id="openai_comp_model_fetch_loading">__MSG_Loading__</span><br>
|
<button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnUpdateOpenAICompModels">__MSG_OpenAIComp_Models_Fetch__</button> <span id="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_model_fetch_loading" style="display:none">__MSG_Loading__</span><br>
|
||||||
<label>
|
<label>
|
||||||
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_model" name="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_model" class="option-input option-input-model"></select>
|
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_model" name="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_model" class="option-input"></select>
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -366,11 +425,24 @@ export async function injectConnectionUI({
|
||||||
</label></td>
|
</label></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="text" id="openai_comp_chat_name" name="openai_comp_chat_name" class="option-input" />
|
<input type="text" id="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_chat_name" name="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_chat_name" class="option-input" />
|
||||||
<br>__MSG_prefs_OpenAIComp_ChatName_Info__
|
<br>__MSG_prefs_OpenAIComp_ChatName_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr class="conntype_openai_comp_api${tr_class ? ` ${tr_class}` : ''}">
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<span class="opt_title">__MSG_prefs_api_temperature__</span>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="text" id="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_temperature" name="${modelId_prefix ? `${modelId_prefix}` : ''}openai_comp_temperature" class="option-input check-number" />
|
||||||
|
<br>__MSG_prefs_openai_comp_temperature_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr class="conntype_anthropic_api${tr_class ? ` ${tr_class}` : ''}">
|
<tr class="conntype_anthropic_api${tr_class ? ` ${tr_class}` : ''}">
|
||||||
<td><label>
|
<td><label>
|
||||||
<span class="opt_title">__MSG_prefs_Anthropic_API_Key__</span>
|
<span class="opt_title">__MSG_prefs_Anthropic_API_Key__</span>
|
||||||
|
|
@ -378,9 +450,9 @@ export async function injectConnectionUI({
|
||||||
<td>
|
<td>
|
||||||
<div class="api_key-container">
|
<div class="api_key-container">
|
||||||
<label>
|
<label>
|
||||||
<input type="password" id="anthropic_api_key" name="anthropic_api_key" class="option-input"/>
|
<input type="password" id="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_api_key" name="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_api_key" class="option-input"/>
|
||||||
</label>
|
</label>
|
||||||
<span class="toggle-icon" id="toggle_anthropic_api_key"><img src="/images/pwd-show.png" id="pwd-icon_anthropic_api_key"></span>
|
<span class="toggle-icon" id="${modelId_prefix ? `${modelId_prefix}` : ''}toggle_anthropic_api_key"><img src="/images/pwd-show.png" id="${modelId_prefix ? `${modelId_prefix}` : ''}pwd-icon_anthropic_api_key"></span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -391,9 +463,22 @@ export async function injectConnectionUI({
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button id="btnUpdateAnthropicModels">__MSG_Anthropic_Models_Fetch__</button> <span id="anthropic_model_fetch_loading">__MSG_Loading__</span><br>
|
<button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnUpdateAnthropicModels">__MSG_Anthropic_Models_Fetch__</button> <span id="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_model_fetch_loading" style="display:none">__MSG_Loading__</span><br>
|
||||||
<label>
|
<label>
|
||||||
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_model" name="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_model" class="option-input option-input-model"></select>
|
<select id="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_model" name="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_model" class="option-input"></select>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="conntype_anthropic_api${tr_class ? ` ${tr_class}` : ''}">
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<span class="opt_title">__MSG_prefs_api_temperature__</span>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="text" id="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_temperature" name="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_temperature" class="option-input check-number" />
|
||||||
|
<br>__MSG_prefs_anthropic_temperature_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -405,7 +490,7 @@ export async function injectConnectionUI({
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<textarea id="anthropic_system_prompt" name="anthropic_system_prompt" class="option-input option-textarea"></textarea>
|
<textarea id="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_system_prompt" name="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_system_prompt" class="option-input option-textarea"></textarea>
|
||||||
<br>__MSG_Anthropic_System_Prompt_Info__
|
<br>__MSG_Anthropic_System_Prompt_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -418,7 +503,7 @@ export async function injectConnectionUI({
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="text" id="anthropic_version" name="anthropic_version" class="option-input" />
|
<input type="text" id="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_version" name="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_version" class="option-input" />
|
||||||
<br>__MSG_Anthropic_Version_Info__ <a href="https://docs.anthropic.com/en/api/versioning">https://docs.anthropic.com/en/api/versioning</a>
|
<br>__MSG_Anthropic_Version_Info__ <a href="https://docs.anthropic.com/en/api/versioning">https://docs.anthropic.com/en/api/versioning</a>
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -427,7 +512,7 @@ export async function injectConnectionUI({
|
||||||
<td><span class="opt_title">__MSG_prefs_OptionText_anthropic_max_tokens__</span></td>
|
<td><span class="opt_title">__MSG_prefs_OptionText_anthropic_max_tokens__</span></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="number" id="anthropic_max_tokens" name="anthropic_max_tokens" class="option-input" />
|
<input type="number" id="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_max_tokens" name="${modelId_prefix ? `${modelId_prefix}` : ''}anthropic_max_tokens" class="option-input" />
|
||||||
<br>__MSG_prefs_OptionText_anthropic_max_tokens_Info__
|
<br>__MSG_prefs_OptionText_anthropic_max_tokens_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
@ -448,6 +533,8 @@ export async function injectConnectionUI({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
||||||
|
|
||||||
// Bindings
|
// Bindings
|
||||||
// const bindClick = (id, cb) => { const el = document.getElementById(id); if (el && typeof cb === 'function') el.addEventListener('click', cb); };
|
// const bindClick = (id, cb) => { const el = document.getElementById(id); if (el && typeof cb === 'function') el.addEventListener('click', cb); };
|
||||||
// const bindChange = (id, cb) => { const el = document.getElementById(id); if (el && typeof cb === 'function') el.addEventListener('change', cb); };
|
// const bindChange = (id, cb) => { const el = document.getElementById(id); if (el && typeof cb === 'function') el.addEventListener('change', cb); };
|
||||||
|
|
@ -470,18 +557,18 @@ export async function injectConnectionUI({
|
||||||
conntype_select.addEventListener("change", (ev) => warn_Anthropic_VersionEmpty(modelId_prefix));
|
conntype_select.addEventListener("change", (ev) => warn_Anthropic_VersionEmpty(modelId_prefix));
|
||||||
document.getElementById("chatgpt_web_project").addEventListener("input", validateCustomData_ChatGPTWeb);
|
document.getElementById("chatgpt_web_project").addEventListener("input", validateCustomData_ChatGPTWeb);
|
||||||
document.getElementById("chatgpt_web_custom_gpt").addEventListener("input", validateCustomData_ChatGPTWeb);
|
document.getElementById("chatgpt_web_custom_gpt").addEventListener("input", validateCustomData_ChatGPTWeb);
|
||||||
document.getElementById("chatgpt_api_key").addEventListener("change", (ev) => warn_ChatGPT_APIKeyEmpty(modelId_prefix));
|
document.getElementById(getPrefixedId("chatgpt_api_key")).addEventListener("change", (ev) => warn_ChatGPT_APIKeyEmpty(modelId_prefix));
|
||||||
document.getElementById("ollama_host").addEventListener("change", (ev) => warn_Ollama_HostEmpty(modelId_prefix));
|
document.getElementById(getPrefixedId("ollama_host")).addEventListener("change", (ev) => warn_Ollama_HostEmpty(modelId_prefix));
|
||||||
document.getElementById("openai_comp_host").addEventListener("change", (ev) => warn_OpenAIComp_HostEmpty(modelId_prefix));
|
document.getElementById(getPrefixedId("openai_comp_host")).addEventListener("change", (ev) => warn_OpenAIComp_HostEmpty(modelId_prefix));
|
||||||
document.getElementById("google_gemini_api_key").addEventListener("change", (ev) => warn_GoogleGemini_APIKeyEmpty(modelId_prefix));
|
document.getElementById(getPrefixedId("google_gemini_api_key")).addEventListener("change", (ev) => warn_GoogleGemini_APIKeyEmpty(modelId_prefix));
|
||||||
document.getElementById("anthropic_api_key").addEventListener("change", (ev) => warn_Anthropic_APIKeyEmpty(modelId_prefix));
|
document.getElementById(getPrefixedId("anthropic_api_key")).addEventListener("change", (ev) => warn_Anthropic_APIKeyEmpty(modelId_prefix));
|
||||||
document.getElementById("anthropic_version").addEventListener("change", (ev) => warn_Anthropic_VersionEmpty(modelId_prefix));
|
document.getElementById(getPrefixedId("anthropic_version")).addEventListener("change", (ev) => warn_Anthropic_VersionEmpty(modelId_prefix));
|
||||||
document.getElementById("openai_comp_host").addEventListener("input", resetOpenAICompConfigs);
|
document.getElementById(getPrefixedId("openai_comp_host")).addEventListener("input", () => resetOpenAICompConfigs(modelId_prefix));
|
||||||
document.getElementById("openai_comp_chat_name").addEventListener("input", resetOpenAICompConfigs);
|
document.getElementById(getPrefixedId("openai_comp_chat_name")).addEventListener("input", () => resetOpenAICompConfigs(modelId_prefix));
|
||||||
document.getElementById("openai_comp_use_v1").addEventListener("input", resetOpenAICompConfigs);
|
document.getElementById(getPrefixedId("openai_comp_use_v1")).addEventListener("input", () => resetOpenAICompConfigs(modelId_prefix));
|
||||||
|
|
||||||
showConnectionOptions(conntype_select);
|
showConnectionOptions(conntype_select);
|
||||||
loadOpenAICompConfigs();
|
loadOpenAICompConfigs(modelId_prefix);
|
||||||
warn_ChatGPT_APIKeyEmpty(modelId_prefix);
|
warn_ChatGPT_APIKeyEmpty(modelId_prefix);
|
||||||
warn_Ollama_HostEmpty(modelId_prefix);
|
warn_Ollama_HostEmpty(modelId_prefix);
|
||||||
warn_OpenAIComp_HostEmpty(modelId_prefix);
|
warn_OpenAIComp_HostEmpty(modelId_prefix);
|
||||||
|
|
@ -489,9 +576,9 @@ export async function injectConnectionUI({
|
||||||
warn_Anthropic_APIKeyEmpty(modelId_prefix);
|
warn_Anthropic_APIKeyEmpty(modelId_prefix);
|
||||||
warn_Anthropic_VersionEmpty(modelId_prefix);
|
warn_Anthropic_VersionEmpty(modelId_prefix);
|
||||||
|
|
||||||
const passwordField_chatgpt_api_key = document.getElementById('chatgpt_api_key');
|
const passwordField_chatgpt_api_key = document.getElementById(getPrefixedId('chatgpt_api_key'));
|
||||||
const toggleIcon_chatgpt_api_key = document.getElementById('toggle_chatgpt_api_key');
|
const toggleIcon_chatgpt_api_key = document.getElementById(getPrefixedId('toggle_chatgpt_api_key'));
|
||||||
const icon_img_chatgpt_api_key = document.getElementById('pwd-icon_chatgpt_api_key');
|
const icon_img_chatgpt_api_key = document.getElementById(getPrefixedId('pwd-icon_chatgpt_api_key'));
|
||||||
|
|
||||||
toggleIcon_chatgpt_api_key.addEventListener('click', () => {
|
toggleIcon_chatgpt_api_key.addEventListener('click', () => {
|
||||||
const type = passwordField_chatgpt_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
|
const type = passwordField_chatgpt_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
|
||||||
|
|
@ -500,9 +587,9 @@ export async function injectConnectionUI({
|
||||||
icon_img_chatgpt_api_key.src = type === 'password' ? "/images/pwd-show.png" : "/images/pwd-hide.png";
|
icon_img_chatgpt_api_key.src = type === 'password' ? "/images/pwd-show.png" : "/images/pwd-hide.png";
|
||||||
});
|
});
|
||||||
|
|
||||||
const passwordField_google_gemini_api_key = document.getElementById('google_gemini_api_key');
|
const passwordField_google_gemini_api_key = document.getElementById(getPrefixedId('google_gemini_api_key'));
|
||||||
const toggleIcon_google_gemini_api_key = document.getElementById('toggle_google_gemini_api_key');
|
const toggleIcon_google_gemini_api_key = document.getElementById(getPrefixedId('toggle_google_gemini_api_key'));
|
||||||
const icon_img_google_gemini_api_key = document.getElementById('pwd-icon_google_gemini_api_key');
|
const icon_img_google_gemini_api_key = document.getElementById(getPrefixedId('pwd-icon_google_gemini_api_key'));
|
||||||
|
|
||||||
toggleIcon_google_gemini_api_key.addEventListener('click', () => {
|
toggleIcon_google_gemini_api_key.addEventListener('click', () => {
|
||||||
const type = passwordField_google_gemini_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
|
const type = passwordField_google_gemini_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
|
||||||
|
|
@ -511,9 +598,9 @@ export async function injectConnectionUI({
|
||||||
icon_img_google_gemini_api_key.src = type === 'password' ? "/images/pwd-show.png" : "/images/pwd-hide.png";
|
icon_img_google_gemini_api_key.src = type === 'password' ? "/images/pwd-show.png" : "/images/pwd-hide.png";
|
||||||
});
|
});
|
||||||
|
|
||||||
const passwordField_openai_comp_api_key = document.getElementById('openai_comp_api_key');
|
const passwordField_openai_comp_api_key = document.getElementById(getPrefixedId('openai_comp_api_key'));
|
||||||
const toggleIcon_openai_comp_api_key = document.getElementById('toggle_openai_comp_api_key');
|
const toggleIcon_openai_comp_api_key = document.getElementById(getPrefixedId('toggle_openai_comp_api_key'));
|
||||||
const icon_img_openai_comp_api_key = document.getElementById('pwd-icon_openai_comp_api_key');
|
const icon_img_openai_comp_api_key = document.getElementById(getPrefixedId('pwd-icon_openai_comp_api_key'));
|
||||||
|
|
||||||
toggleIcon_openai_comp_api_key.addEventListener('click', () => {
|
toggleIcon_openai_comp_api_key.addEventListener('click', () => {
|
||||||
const type = passwordField_openai_comp_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
|
const type = passwordField_openai_comp_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
|
||||||
|
|
@ -522,9 +609,9 @@ export async function injectConnectionUI({
|
||||||
icon_img_openai_comp_api_key.src = type === 'password' ? "/images/pwd-show.png" : "/images/pwd-hide.png";
|
icon_img_openai_comp_api_key.src = type === 'password' ? "/images/pwd-show.png" : "/images/pwd-hide.png";
|
||||||
});
|
});
|
||||||
|
|
||||||
const passwordField_anthropic_api_key = document.getElementById('anthropic_api_key');
|
const passwordField_anthropic_api_key = document.getElementById(getPrefixedId('anthropic_api_key'));
|
||||||
const toggleIcon_anthropic_api_key = document.getElementById('toggle_anthropic_api_key');
|
const toggleIcon_anthropic_api_key = document.getElementById(getPrefixedId('toggle_anthropic_api_key'));
|
||||||
const icon_img_anthropic_api_key = document.getElementById('pwd-icon_anthropic_api_key');
|
const icon_img_anthropic_api_key = document.getElementById(getPrefixedId('pwd-icon_anthropic_api_key'));
|
||||||
|
|
||||||
toggleIcon_anthropic_api_key.addEventListener('click', () => {
|
toggleIcon_anthropic_api_key.addEventListener('click', () => {
|
||||||
const type = passwordField_anthropic_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
|
const type = passwordField_anthropic_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
|
||||||
|
|
@ -558,7 +645,7 @@ export async function injectConnectionUI({
|
||||||
browser.tabs.create({ url: base_url + model_opt });
|
browser.tabs.create({ url: base_url + model_opt });
|
||||||
});
|
});
|
||||||
|
|
||||||
let select_openai_comp_services_shortcut = document.getElementById('openai_comp_services_shortcut');
|
let select_openai_comp_services_shortcut = document.getElementById(getPrefixedId('openai_comp_services_shortcut'));
|
||||||
select_openai_comp_services_shortcut.addEventListener("change", () => {
|
select_openai_comp_services_shortcut.addEventListener("change", () => {
|
||||||
let selectedOption = select_openai_comp_services_shortcut.options[select_openai_comp_services_shortcut.selectedIndex];
|
let selectedOption = select_openai_comp_services_shortcut.options[select_openai_comp_services_shortcut.selectedIndex];
|
||||||
const config = openAICompConfigs.find(cfg => cfg.id === selectedOption.value);
|
const config = openAICompConfigs.find(cfg => cfg.id === selectedOption.value);
|
||||||
|
|
@ -566,20 +653,20 @@ export async function injectConnectionUI({
|
||||||
if (!confirm(browser.i18n.getMessage('OpenAIComp_Configs_ConfirmApply', config.name))) {
|
if (!confirm(browser.i18n.getMessage('OpenAIComp_Configs_ConfirmApply', config.name))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
document.getElementById('openai_comp_host').value = config.host || '';
|
document.getElementById(getPrefixedId('openai_comp_host')).value = config.host || '';
|
||||||
// Clear all options from the select except the first (placeholder) one
|
// Clear all options from the select except the first (placeholder) one
|
||||||
const openaiCompModelSelect = getModelEl('openai_comp_model', modelId_prefix);
|
const openaiCompModelSelect = getModelEl('openai_comp_model', modelId_prefix);
|
||||||
openaiCompModelSelect.value = '';
|
openaiCompModelSelect.value = '';
|
||||||
while (openaiCompModelSelect.options.length > 0) {
|
while (openaiCompModelSelect.options.length > 0) {
|
||||||
openaiCompModelSelect.remove(0);
|
openaiCompModelSelect.remove(0);
|
||||||
}
|
}
|
||||||
document.getElementById('openai_comp_use_v1').checked = !!config.use_v1;
|
document.getElementById(getPrefixedId('openai_comp_use_v1')).checked = !!config.use_v1;
|
||||||
document.getElementById('openai_comp_chat_name').value = config.chat_name || '';
|
document.getElementById(getPrefixedId('openai_comp_chat_name')).value = config.chat_name || '';
|
||||||
// Trigger change events if needed
|
// Trigger change events if needed
|
||||||
document.getElementById('openai_comp_host').dispatchEvent(new Event('change', { bubbles: true }));
|
document.getElementById(getPrefixedId('openai_comp_host')).dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
getModelEl('openai_comp_model', modelId_prefix).dispatchEvent(new Event('change', { bubbles: true }));
|
getModelEl('openai_comp_model', modelId_prefix).dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
document.getElementById('openai_comp_use_v1').dispatchEvent(new Event('change', { bubbles: true }));
|
document.getElementById(getPrefixedId('openai_comp_use_v1')).dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
document.getElementById('openai_comp_chat_name').dispatchEvent(new Event('change', { bubbles: true }));
|
document.getElementById(getPrefixedId('openai_comp_chat_name')).dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -593,14 +680,14 @@ export async function injectConnectionUI({
|
||||||
select_chatgpt_model.appendChild(chatgpt_option);
|
select_chatgpt_model.appendChild(chatgpt_option);
|
||||||
select_chatgpt_model.addEventListener("change", () => warn_ChatGPT_APIKeyEmpty(modelId_prefix));
|
select_chatgpt_model.addEventListener("change", () => warn_ChatGPT_APIKeyEmpty(modelId_prefix));
|
||||||
|
|
||||||
document.getElementById('btnUpdateChatGPTModels').addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnUpdateChatGPTModels')).addEventListener('click', async () => {
|
||||||
document.getElementById('chatgpt_model_fetch_loading').style.display = 'inline';
|
document.getElementById(getPrefixedId('chatgpt_model_fetch_loading')).style.display = 'inline';
|
||||||
let openai = new OpenAI({
|
let openai = new OpenAI({
|
||||||
apiKey: document.getElementById("chatgpt_api_key").value,
|
apiKey: document.getElementById(getPrefixedId("chatgpt_api_key")).value,
|
||||||
});
|
});
|
||||||
let granted = await messenger.permissions.request({ origins: ["https://*.openai.com/*"] });
|
let granted = await messenger.permissions.request({ origins: ["https://*.openai.com/*"] });
|
||||||
if(!granted){
|
if(!granted){
|
||||||
document.getElementById('chatgpt_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('chatgpt_model_fetch_loading')).style.display = 'none';
|
||||||
taLog.log("OpenAI API permission denied");
|
taLog.log("OpenAI API permission denied");
|
||||||
alert(browser.i18n.getMessage("Optional_Permission_Denied_Model_Fetching"));
|
alert(browser.i18n.getMessage("Optional_Permission_Denied_Model_Fetching"));
|
||||||
return;
|
return;
|
||||||
|
|
@ -614,7 +701,7 @@ export async function injectConnectionUI({
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorDetail = data.error;
|
errorDetail = data.error;
|
||||||
}
|
}
|
||||||
document.getElementById('chatgpt_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('chatgpt_model_fetch_loading')).style.display = 'none';
|
||||||
console.error("[ThunderAI] " + browser.i18n.getMessage("ChatGPT_Models_Error_fetching"));
|
console.error("[ThunderAI] " + browser.i18n.getMessage("ChatGPT_Models_Error_fetching"));
|
||||||
alert(browser.i18n.getMessage("ChatGPT_Models_Error_fetching")+": " + errorDetail);
|
alert(browser.i18n.getMessage("ChatGPT_Models_Error_fetching")+": " + errorDetail);
|
||||||
return;
|
return;
|
||||||
|
|
@ -628,7 +715,7 @@ export async function injectConnectionUI({
|
||||||
select_chatgpt_model.appendChild(option);
|
select_chatgpt_model.appendChild(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.getElementById('chatgpt_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('chatgpt_model_fetch_loading')).style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
warn_ChatGPT_APIKeyEmpty(modelId_prefix);
|
warn_ChatGPT_APIKeyEmpty(modelId_prefix);
|
||||||
|
|
@ -642,10 +729,10 @@ export async function injectConnectionUI({
|
||||||
select_google_gemini_model.appendChild(google_gemini_option);
|
select_google_gemini_model.appendChild(google_gemini_option);
|
||||||
select_google_gemini_model.addEventListener("change", () => warn_GoogleGemini_APIKeyEmpty(modelId_prefix));
|
select_google_gemini_model.addEventListener("change", () => warn_GoogleGemini_APIKeyEmpty(modelId_prefix));
|
||||||
|
|
||||||
document.getElementById('btnUpdateGoogleGeminiModels').addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnUpdateGoogleGeminiModels')).addEventListener('click', async () => {
|
||||||
document.getElementById('google_gemini_model_fetch_loading').style.display = 'inline';
|
document.getElementById(getPrefixedId('google_gemini_model_fetch_loading')).style.display = 'inline';
|
||||||
let google_gemini = new GoogleGemini({
|
let google_gemini = new GoogleGemini({
|
||||||
apiKey: document.getElementById("google_gemini_api_key").value,
|
apiKey: document.getElementById(getPrefixedId("google_gemini_api_key")).value,
|
||||||
});
|
});
|
||||||
google_gemini.fetchModels().then((data) => {
|
google_gemini.fetchModels().then((data) => {
|
||||||
if(!data.ok){
|
if(!data.ok){
|
||||||
|
|
@ -656,7 +743,7 @@ export async function injectConnectionUI({
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorDetail = data.error;
|
errorDetail = data.error;
|
||||||
}
|
}
|
||||||
document.getElementById('google_gemini_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('google_gemini_model_fetch_loading')).style.display = 'none';
|
||||||
console.error("[ThunderAI] " + browser.i18n.getMessage("GoogleGemini_Models_Error_fetching"));
|
console.error("[ThunderAI] " + browser.i18n.getMessage("GoogleGemini_Models_Error_fetching"));
|
||||||
alert(browser.i18n.getMessage("GoogleGemini_Models_Error_fetching")+": " + errorDetail);
|
alert(browser.i18n.getMessage("GoogleGemini_Models_Error_fetching")+": " + errorDetail);
|
||||||
return;
|
return;
|
||||||
|
|
@ -670,7 +757,7 @@ export async function injectConnectionUI({
|
||||||
select_google_gemini_model.appendChild(option);
|
select_google_gemini_model.appendChild(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.getElementById('google_gemini_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('google_gemini_model_fetch_loading')).style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
warn_GoogleGemini_APIKeyEmpty(modelId_prefix);
|
warn_GoogleGemini_APIKeyEmpty(modelId_prefix);
|
||||||
|
|
@ -684,15 +771,15 @@ export async function injectConnectionUI({
|
||||||
select_ollama_model.appendChild(ollama_option);
|
select_ollama_model.appendChild(ollama_option);
|
||||||
select_ollama_model.addEventListener("change", () => warn_Ollama_HostEmpty(modelId_prefix));
|
select_ollama_model.addEventListener("change", () => warn_Ollama_HostEmpty(modelId_prefix));
|
||||||
|
|
||||||
document.getElementById('btnUpdateOllamaModels').addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnUpdateOllamaModels')).addEventListener('click', async () => {
|
||||||
document.getElementById('ollama_model_fetch_loading').style.display = 'inline';
|
document.getElementById(getPrefixedId('ollama_model_fetch_loading')).style.display = 'inline';
|
||||||
let ollama = new Ollama({
|
let ollama = new Ollama({
|
||||||
host: document.getElementById("ollama_host").value,
|
host: document.getElementById(getPrefixedId("ollama_host")).value,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
let data = await ollama.fetchModels();
|
let data = await ollama.fetchModels();
|
||||||
if(!data){
|
if(!data){
|
||||||
document.getElementById('ollama_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('ollama_model_fetch_loading')).style.display = 'none';
|
||||||
console.error("[ThunderAI] " + browser.i18n.getMessage("Ollama_Models_Error_fetching"));
|
console.error("[ThunderAI] " + browser.i18n.getMessage("Ollama_Models_Error_fetching"));
|
||||||
alert(browser.i18n.getMessage("Ollama_Models_Error_fetching"));
|
alert(browser.i18n.getMessage("Ollama_Models_Error_fetching"));
|
||||||
return;
|
return;
|
||||||
|
|
@ -705,13 +792,13 @@ export async function injectConnectionUI({
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorDetail = data.error;
|
errorDetail = data.error;
|
||||||
}
|
}
|
||||||
document.getElementById('ollama_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('ollama_model_fetch_loading')).style.display = 'none';
|
||||||
console.error("[ThunderAI] " + browser.i18n.getMessage("Ollama_Models_Error_fetching"));
|
console.error("[ThunderAI] " + browser.i18n.getMessage("Ollama_Models_Error_fetching"));
|
||||||
alert(browser.i18n.getMessage("Ollama_Models_Error_fetching")+": " + errorDetail);
|
alert(browser.i18n.getMessage("Ollama_Models_Error_fetching")+": " + errorDetail);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(data.response.models.length == 0){
|
if(data.response.models.length == 0){
|
||||||
document.getElementById('ollama_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('ollama_model_fetch_loading')).style.display = 'none';
|
||||||
console.error("[ThunderAI] " + browser.i18n.getMessage("Ollama_Models_Error_fetching"));
|
console.error("[ThunderAI] " + browser.i18n.getMessage("Ollama_Models_Error_fetching"));
|
||||||
alert(browser.i18n.getMessage("Ollama_Models_Error_fetching")+": " + browser.i18n.getMessage("API_Models_Error_NoModels"));
|
alert(browser.i18n.getMessage("Ollama_Models_Error_fetching")+": " + browser.i18n.getMessage("API_Models_Error_NoModels"));
|
||||||
return;
|
return;
|
||||||
|
|
@ -725,9 +812,9 @@ export async function injectConnectionUI({
|
||||||
select_ollama_model.appendChild(option);
|
select_ollama_model.appendChild(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.getElementById('ollama_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('ollama_model_fetch_loading')).style.display = 'none';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
document.getElementById('ollama_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('ollama_model_fetch_loading')).style.display = 'none';
|
||||||
taLog.error(browser.i18n.getMessage("Ollama_Models_Error_fetching"));
|
taLog.error(browser.i18n.getMessage("Ollama_Models_Error_fetching"));
|
||||||
alert(browser.i18n.getMessage("Ollama_Models_Error_fetching")+": " + error.message);
|
alert(browser.i18n.getMessage("Ollama_Models_Error_fetching")+": " + error.message);
|
||||||
}
|
}
|
||||||
|
|
@ -743,12 +830,12 @@ export async function injectConnectionUI({
|
||||||
select_openai_comp_model.appendChild(openai_comp_option);
|
select_openai_comp_model.appendChild(openai_comp_option);
|
||||||
select_openai_comp_model.addEventListener("change", () => warn_OpenAIComp_HostEmpty(modelId_prefix));
|
select_openai_comp_model.addEventListener("change", () => warn_OpenAIComp_HostEmpty(modelId_prefix));
|
||||||
|
|
||||||
document.getElementById('btnUpdateOpenAICompModels').addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnUpdateOpenAICompModels')).addEventListener('click', async () => {
|
||||||
document.getElementById('openai_comp_model_fetch_loading').style.display = 'inline';
|
document.getElementById(getPrefixedId('openai_comp_model_fetch_loading')).style.display = 'inline';
|
||||||
let openai_comp = new OpenAIComp({
|
let openai_comp = new OpenAIComp({
|
||||||
host: document.getElementById("openai_comp_host").value,
|
host: document.getElementById(getPrefixedId("openai_comp_host")).value,
|
||||||
apiKey: document.getElementById("openai_comp_api_key").value,
|
apiKey: document.getElementById(getPrefixedId("openai_comp_api_key")).value,
|
||||||
use_v1: document.getElementById("openai_comp_use_v1").checked,
|
use_v1: document.getElementById(getPrefixedId("openai_comp_use_v1")).checked,
|
||||||
});
|
});
|
||||||
openai_comp.fetchModels().then((data) => {
|
openai_comp.fetchModels().then((data) => {
|
||||||
if(!data.ok){
|
if(!data.ok){
|
||||||
|
|
@ -759,7 +846,7 @@ export async function injectConnectionUI({
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorDetail = data.error;
|
errorDetail = data.error;
|
||||||
}
|
}
|
||||||
document.getElementById('openai_comp_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('openai_comp_model_fetch_loading')).style.display = 'none';
|
||||||
console.error("[ThunderAI] " + browser.i18n.getMessage("OpenAIComp_Models_Error_fetching"));
|
console.error("[ThunderAI] " + browser.i18n.getMessage("OpenAIComp_Models_Error_fetching"));
|
||||||
alert(browser.i18n.getMessage("OpenAIComp_Models_Error_fetching")+": " + errorDetail);
|
alert(browser.i18n.getMessage("OpenAIComp_Models_Error_fetching")+": " + errorDetail);
|
||||||
return;
|
return;
|
||||||
|
|
@ -773,7 +860,7 @@ export async function injectConnectionUI({
|
||||||
select_openai_comp_model.appendChild(option);
|
select_openai_comp_model.appendChild(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.getElementById('openai_comp_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('openai_comp_model_fetch_loading')).style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
warn_OpenAIComp_HostEmpty(modelId_prefix);
|
warn_OpenAIComp_HostEmpty(modelId_prefix);
|
||||||
|
|
@ -788,15 +875,15 @@ export async function injectConnectionUI({
|
||||||
select_anthropic_model.addEventListener("change", () => warn_Anthropic_APIKeyEmpty(modelId_prefix));
|
select_anthropic_model.addEventListener("change", () => warn_Anthropic_APIKeyEmpty(modelId_prefix));
|
||||||
select_anthropic_model.addEventListener("change", () => warn_Anthropic_VersionEmpty(modelId_prefix));
|
select_anthropic_model.addEventListener("change", () => warn_Anthropic_VersionEmpty(modelId_prefix));
|
||||||
|
|
||||||
document.getElementById('btnUpdateAnthropicModels').addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnUpdateAnthropicModels')).addEventListener('click', async () => {
|
||||||
document.getElementById('anthropic_model_fetch_loading').style.display = 'inline';
|
document.getElementById(getPrefixedId('anthropic_model_fetch_loading')).style.display = 'inline';
|
||||||
let anthropic = new Anthropic({
|
let anthropic = new Anthropic({
|
||||||
apiKey: document.getElementById("anthropic_api_key").value,
|
apiKey: document.getElementById(getPrefixedId("anthropic_api_key")).value,
|
||||||
version: document.getElementById("anthropic_version").value,
|
version: document.getElementById(getPrefixedId("anthropic_version")).value,
|
||||||
});
|
});
|
||||||
let granted = await messenger.permissions.request({ origins: ["https://*.anthropic.com/*"] });
|
let granted = await messenger.permissions.request({ origins: ["https://*.anthropic.com/*"] });
|
||||||
if(!granted){
|
if(!granted){
|
||||||
document.getElementById('anthropic_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('anthropic_model_fetch_loading')).style.display = 'none';
|
||||||
taLog.warn("Claude API web permission denied");
|
taLog.warn("Claude API web permission denied");
|
||||||
alert(browser.i18n.getMessage("Optional_Permission_Denied_Model_Fetching"));
|
alert(browser.i18n.getMessage("Optional_Permission_Denied_Model_Fetching"));
|
||||||
return;
|
return;
|
||||||
|
|
@ -810,7 +897,7 @@ export async function injectConnectionUI({
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorDetail = data.error;
|
errorDetail = data.error;
|
||||||
}
|
}
|
||||||
document.getElementById('anthropic_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('anthropic_model_fetch_loading')).style.display = 'none';
|
||||||
console.error("[ThunderAI] " + browser.i18n.getMessage("Anthropic_Models_Error_fetching"));
|
console.error("[ThunderAI] " + browser.i18n.getMessage("Anthropic_Models_Error_fetching"));
|
||||||
alert(browser.i18n.getMessage("Anthropic_Models_Error_fetching")+": " + errorDetail);
|
alert(browser.i18n.getMessage("Anthropic_Models_Error_fetching")+": " + errorDetail);
|
||||||
return;
|
return;
|
||||||
|
|
@ -827,13 +914,13 @@ export async function injectConnectionUI({
|
||||||
select_anthropic_model.appendChild(option);
|
select_anthropic_model.appendChild(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.getElementById('anthropic_model_fetch_loading').style.display = 'none';
|
document.getElementById(getPrefixedId('anthropic_model_fetch_loading')).style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
warn_Anthropic_APIKeyEmpty(modelId_prefix);
|
warn_Anthropic_APIKeyEmpty(modelId_prefix);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('btnOpenAICompForceModel').addEventListener('click', () => {
|
document.getElementById(getPrefixedId('btnOpenAICompForceModel')).addEventListener('click', () => {
|
||||||
let modelName = prompt(browser.i18n.getMessage('OpenAIComp_force_model_ask')).trim();
|
let modelName = prompt(browser.i18n.getMessage('OpenAIComp_force_model_ask')).trim();
|
||||||
if ((modelName !== null) && (modelName !== undefined) && (modelName !== '')) {
|
if ((modelName !== null) && (modelName !== undefined) && (modelName !== '')) {
|
||||||
let select_openai_comp_model = getModelEl('openai_comp_model', modelId_prefix);
|
let select_openai_comp_model = getModelEl('openai_comp_model', modelId_prefix);
|
||||||
|
|
@ -846,7 +933,7 @@ export async function injectConnectionUI({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('btnOpenAICompClearModelsList').addEventListener('click', () => {
|
document.getElementById(getPrefixedId('btnOpenAICompClearModelsList')).addEventListener('click', () => {
|
||||||
if (!confirm(browser.i18n.getMessage('OpenAIComp_ClearModelsList_Confirm'))) {
|
if (!confirm(browser.i18n.getMessage('OpenAIComp_ClearModelsList_Confirm'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -858,14 +945,18 @@ export async function injectConnectionUI({
|
||||||
select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
|
select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('btnGiveAllUrlsPermission_ollama_api').addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnGiveAllUrlsPermission_ollama_api')).addEventListener('click', async () => {
|
||||||
varConnectionUI.permission_all_urls = await messenger.permissions.request({ origins: ["<all_urls>"] });
|
varConnectionUI.permission_all_urls = await messenger.permissions.request({ origins: ["<all_urls>"] });
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('btnGiveAllUrlsPermission_openai_comp_api').addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnGiveAllUrlsPermission_openai_comp_api')).addEventListener('click', async () => {
|
||||||
varConnectionUI.permission_all_urls = await messenger.permissions.request({ origins: ["<all_urls>"] });
|
varConnectionUI.permission_all_urls = await messenger.permissions.request({ origins: ["<all_urls>"] });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('.check-number').forEach(input => {
|
||||||
|
input.addEventListener('input', warn_InvalidNumber);
|
||||||
|
});
|
||||||
|
|
||||||
warn_ChatGPT_APIKeyEmpty(modelId_prefix);
|
warn_ChatGPT_APIKeyEmpty(modelId_prefix);
|
||||||
warn_Ollama_HostEmpty(modelId_prefix);
|
warn_Ollama_HostEmpty(modelId_prefix);
|
||||||
warn_OpenAIComp_HostEmpty(modelId_prefix);
|
warn_OpenAIComp_HostEmpty(modelId_prefix);
|
||||||
|
|
@ -873,12 +964,127 @@ export async function injectConnectionUI({
|
||||||
warn_Anthropic_APIKeyEmpty(modelId_prefix);
|
warn_Anthropic_APIKeyEmpty(modelId_prefix);
|
||||||
warn_Anthropic_VersionEmpty(modelId_prefix);
|
warn_Anthropic_VersionEmpty(modelId_prefix);
|
||||||
|
|
||||||
|
if (customButtonLabel && customButtonCallback) {
|
||||||
|
const btn = document.getElementById(`${modelId_prefix}customButton`);
|
||||||
|
if (btn) {
|
||||||
|
btn.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
customButtonCallback(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
select: conntype_select,
|
select: conntype_select,
|
||||||
onTypeChange: (fn) => { onTypeChange = fn; fn(conntype_select.value, { select: conntype_select }); }
|
onTypeChange: (fn) => { onTypeChange = fn; fn(conntype_select.value, { select: conntype_select }); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function initializeSpecificIntegrationUI({
|
||||||
|
prefix,
|
||||||
|
promptId,
|
||||||
|
taLog,
|
||||||
|
restoreOptionsCallback
|
||||||
|
}) {
|
||||||
|
const conntype_select_id = `${prefix}_connection_type`;
|
||||||
|
const model_prefix = `${prefix}_`;
|
||||||
|
const use_specific_integration_id = `${prefix}_use_specific_integration`;
|
||||||
|
|
||||||
|
// 1. Inject UI
|
||||||
|
try {
|
||||||
|
await injectConnectionUI({
|
||||||
|
afterTrId: 'connection_ui_anchor',
|
||||||
|
tr_class: 'specific_integration_sub',
|
||||||
|
selectId: conntype_select_id,
|
||||||
|
modelId_prefix: model_prefix,
|
||||||
|
no_chatgpt_web: true,
|
||||||
|
taLog: taLog
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Failed to inject connection UI (${prefix})`, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Restore Options
|
||||||
|
if (restoreOptionsCallback) {
|
||||||
|
await restoreOptionsCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Setup Logic
|
||||||
|
const use_specific_integration_el = document.getElementById(use_specific_integration_id);
|
||||||
|
const conntype_el = document.getElementById(conntype_select_id);
|
||||||
|
const conntype_row = document.getElementById(conntype_select_id + '_tr');
|
||||||
|
const conntype_end_el = document.getElementById('connection_ui_end');
|
||||||
|
|
||||||
|
// Helper to update prompt
|
||||||
|
const _updatePrompt = async () => {
|
||||||
|
let conntype = conntype_el.value;
|
||||||
|
|
||||||
|
let prompt = await loadPrompt(promptId);
|
||||||
|
if(!prompt) return;
|
||||||
|
|
||||||
|
prompt.api = conntype;
|
||||||
|
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
let propName = `${integration}_${key}`;
|
||||||
|
let elementId = `${model_prefix}${propName}`;
|
||||||
|
let element = document.getElementById(elementId);
|
||||||
|
if (element) {
|
||||||
|
prompt[propName] = (element.type === 'checkbox') ? element.checked : element.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await savePrompt(prompt);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper for visibility
|
||||||
|
const _updateVisibility = (checked) => {
|
||||||
|
document.querySelectorAll(".specific_integration_sub").forEach(tr => {
|
||||||
|
tr.style.display = checked && tr.classList.contains('conntype_' + conntype_el.value) ? 'table-row' : 'none';
|
||||||
|
});
|
||||||
|
if (conntype_row) conntype_row.style.display = checked ? 'table-row' : 'none';
|
||||||
|
if (conntype_end_el) conntype_end_el.style.display = checked ? 'table-row' : 'none';
|
||||||
|
if (conntype_row) changeConnTypeRowColor(conntype_row, conntype_el);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check global connection type
|
||||||
|
let globalPrefs = await browser.storage.sync.get({ connection_type: 'chatgpt_web' });
|
||||||
|
if (globalPrefs.connection_type === 'chatgpt_web') {
|
||||||
|
use_specific_integration_el.checked = true;
|
||||||
|
use_specific_integration_el.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event Listener for Checkbox
|
||||||
|
use_specific_integration_el.addEventListener('change', async (event) => {
|
||||||
|
_updateVisibility(event.target.checked);
|
||||||
|
if (!event.target.checked) {
|
||||||
|
await clearPromptAPI(promptId);
|
||||||
|
} else {
|
||||||
|
await _updatePrompt();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Event Listeners for Inputs
|
||||||
|
conntype_el.addEventListener('change', async () => {
|
||||||
|
_updateVisibility(use_specific_integration_el.checked);
|
||||||
|
if (use_specific_integration_el.checked) await _updatePrompt();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll(".specific_integration_sub .option-input").forEach(element => {
|
||||||
|
element.addEventListener("change", async () => {
|
||||||
|
if (use_specific_integration_el.checked) await _updatePrompt();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial State Apply
|
||||||
|
_updateVisibility(use_specific_integration_el.checked);
|
||||||
|
if (use_specific_integration_el.checked) {
|
||||||
|
await _updatePrompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateWarnings(model_prefix);
|
||||||
|
}
|
||||||
|
|
||||||
// From here there are exported functions
|
// From here there are exported functions
|
||||||
|
|
||||||
|
|
@ -900,7 +1106,7 @@ export function changeConnTypeRowColor(conntype_row, conntype_select) {
|
||||||
conntype_row.classList.toggle("conntype_anthropic_api", (conntype_select.value === "anthropic_api"));
|
conntype_row.classList.toggle("conntype_anthropic_api", (conntype_select.value === "anthropic_api"));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showConnectionOptions(conntype_select) {
|
export function showConnectionOptions(conntype_select, modelId_prefix = '') {
|
||||||
let chatgpt_web_display = 'table-row';
|
let chatgpt_web_display = 'table-row';
|
||||||
let chatgpt_api_display = 'none';
|
let chatgpt_api_display = 'none';
|
||||||
let ollama_api_display = 'none';
|
let ollama_api_display = 'none';
|
||||||
|
|
@ -939,27 +1145,29 @@ export function showConnectionOptions(conntype_select) {
|
||||||
}else{
|
}else{
|
||||||
anthropic_api_display = 'none';
|
anthropic_api_display = 'none';
|
||||||
}
|
}
|
||||||
document.querySelectorAll(".conntype_chatgpt_web").forEach(element => {
|
parent.parentElement.querySelectorAll(".conntype_chatgpt_web").forEach(element => {
|
||||||
element.style.display = chatgpt_web_display;
|
element.style.display = chatgpt_web_display;
|
||||||
});
|
});
|
||||||
document.querySelectorAll(".conntype_chatgpt_api").forEach(element => {
|
parent.parentElement.querySelectorAll(".conntype_chatgpt_api").forEach(element => {
|
||||||
element.style.display = chatgpt_api_display;
|
element.style.display = chatgpt_api_display;
|
||||||
});
|
});
|
||||||
document.querySelectorAll(".conntype_ollama_api").forEach(element => {
|
parent.parentElement.querySelectorAll(".conntype_ollama_api").forEach(element => {
|
||||||
element.style.display = ollama_api_display;
|
element.style.display = ollama_api_display;
|
||||||
});
|
});
|
||||||
document.querySelectorAll(".conntype_openai_comp_api").forEach(element => {
|
parent.parentElement.querySelectorAll(".conntype_openai_comp_api").forEach(element => {
|
||||||
element.style.display = openai_comp_api_display;
|
element.style.display = openai_comp_api_display;
|
||||||
});
|
});
|
||||||
document.querySelectorAll(".conntype_google_gemini_api").forEach(element => {
|
parent.parentElement.querySelectorAll(".conntype_google_gemini_api").forEach(element => {
|
||||||
element.style.display = google_gemini_api_display;
|
element.style.display = google_gemini_api_display;
|
||||||
});
|
});
|
||||||
document.querySelectorAll(".conntype_anthropic_api").forEach(element => {
|
parent.parentElement.querySelectorAll(".conntype_anthropic_api").forEach(element => {
|
||||||
element.style.display = anthropic_api_display;
|
element.style.display = anthropic_api_display;
|
||||||
});
|
});
|
||||||
if (varConnectionUI.permission_all_urls) {
|
if (varConnectionUI.permission_all_urls) {
|
||||||
document.getElementById('openai_comp_api_cors_warning').style.display = 'none';
|
const openaiCompWarning = parent.parentElement.getElementById((modelId_prefix ? modelId_prefix : '') + 'openai_comp_api_cors_warning');
|
||||||
document.getElementById('ollama_api_cors_warning').style.display = 'none';
|
if (openaiCompWarning) openaiCompWarning.style.display = 'none';
|
||||||
|
const ollamaWarning = parent.parentElement.getElementById((modelId_prefix ? modelId_prefix : '') + 'ollama_api_cors_warning');
|
||||||
|
if (ollamaWarning) ollamaWarning.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -999,9 +1207,21 @@ function populateConnectionTypeOptions(selectId, no_chatgpt_web = false) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function warn_InvalidNumber(event){
|
||||||
|
const elementValue = event.target.value;
|
||||||
|
// console.log(">>>>>>>>>>> warn_InvalidNumber: " + event.target.id + ": " + elementValue)
|
||||||
|
if (elementValue != '' && isNaN(parseFloat(elementValue))) {
|
||||||
|
// Handle invalid number case, e.g., set border to red
|
||||||
|
event.target.style.border = '2px solid red';
|
||||||
|
} else {
|
||||||
|
event.target.style.border = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function warn_ChatGPT_APIKeyEmpty(modelId_prefix) {
|
function warn_ChatGPT_APIKeyEmpty(modelId_prefix) {
|
||||||
let apiKeyInput = document.getElementById('chatgpt_api_key');
|
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
||||||
let btnFetchChatGPTModels = document.getElementById('btnUpdateChatGPTModels');
|
let apiKeyInput = document.getElementById(getPrefixedId('chatgpt_api_key'));
|
||||||
|
let btnFetchChatGPTModels = document.getElementById(getPrefixedId('btnUpdateChatGPTModels'));
|
||||||
let modelChatGPT = getModelEl('chatgpt_model', modelId_prefix);
|
let modelChatGPT = getModelEl('chatgpt_model', modelId_prefix);
|
||||||
if(apiKeyInput.value === ''){
|
if(apiKeyInput.value === ''){
|
||||||
apiKeyInput.style.border = '2px solid red';
|
apiKeyInput.style.border = '2px solid red';
|
||||||
|
|
@ -1022,8 +1242,9 @@ function warn_ChatGPT_APIKeyEmpty(modelId_prefix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function warn_GoogleGemini_APIKeyEmpty(modelId_prefix) {
|
function warn_GoogleGemini_APIKeyEmpty(modelId_prefix) {
|
||||||
let apiKeyInput = document.getElementById('google_gemini_api_key');
|
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
||||||
let btnFetchGoogleGeminiModels = document.getElementById('btnUpdateGoogleGeminiModels');
|
let apiKeyInput = document.getElementById(getPrefixedId('google_gemini_api_key'));
|
||||||
|
let btnFetchGoogleGeminiModels = document.getElementById(getPrefixedId('btnUpdateGoogleGeminiModels'));
|
||||||
let modelGoogleGemini = getModelEl('google_gemini_model', modelId_prefix);
|
let modelGoogleGemini = getModelEl('google_gemini_model', modelId_prefix);
|
||||||
if(apiKeyInput.value === ''){
|
if(apiKeyInput.value === ''){
|
||||||
apiKeyInput.style.border = '2px solid red';
|
apiKeyInput.style.border = '2px solid red';
|
||||||
|
|
@ -1044,8 +1265,9 @@ function warn_GoogleGemini_APIKeyEmpty(modelId_prefix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function warn_Ollama_HostEmpty(modelId_prefix) {
|
function warn_Ollama_HostEmpty(modelId_prefix) {
|
||||||
let hostInput = document.getElementById('ollama_host');
|
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
||||||
let btnFetchOllamaModels = document.getElementById('btnUpdateOllamaModels');
|
let hostInput = document.getElementById(getPrefixedId('ollama_host'));
|
||||||
|
let btnFetchOllamaModels = document.getElementById(getPrefixedId('btnUpdateOllamaModels'));
|
||||||
let modelOllama = getModelEl('ollama_model', modelId_prefix);
|
let modelOllama = getModelEl('ollama_model', modelId_prefix);
|
||||||
if(hostInput.value === ''){
|
if(hostInput.value === ''){
|
||||||
hostInput.style.border = '2px solid red';
|
hostInput.style.border = '2px solid red';
|
||||||
|
|
@ -1066,8 +1288,9 @@ function warn_Ollama_HostEmpty(modelId_prefix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function warn_OpenAIComp_HostEmpty(modelId_prefix) {
|
function warn_OpenAIComp_HostEmpty(modelId_prefix) {
|
||||||
let hostInput = document.getElementById('openai_comp_host');
|
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
||||||
let btnUpdateOpenAICompModels = document.getElementById('btnUpdateOpenAICompModels');
|
let hostInput = document.getElementById(getPrefixedId('openai_comp_host'));
|
||||||
|
let btnUpdateOpenAICompModels = document.getElementById(getPrefixedId('btnUpdateOpenAICompModels'));
|
||||||
let modelOpenAIComp = getModelEl('openai_comp_model', modelId_prefix);
|
let modelOpenAIComp = getModelEl('openai_comp_model', modelId_prefix);
|
||||||
if(hostInput.value === ''){
|
if(hostInput.value === ''){
|
||||||
hostInput.style.border = '2px solid red';
|
hostInput.style.border = '2px solid red';
|
||||||
|
|
@ -1088,8 +1311,9 @@ function warn_OpenAIComp_HostEmpty(modelId_prefix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function warn_Anthropic_APIKeyEmpty(modelId_prefix) {
|
function warn_Anthropic_APIKeyEmpty(modelId_prefix) {
|
||||||
let apiKeyInput = document.getElementById('anthropic_api_key');
|
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
||||||
let btnFetchAnthropicModels = document.getElementById('btnUpdateAnthropicModels');
|
let apiKeyInput = document.getElementById(getPrefixedId('anthropic_api_key'));
|
||||||
|
let btnFetchAnthropicModels = document.getElementById(getPrefixedId('btnUpdateAnthropicModels'));
|
||||||
let modelAnthropic = getModelEl('anthropic_model', modelId_prefix);
|
let modelAnthropic = getModelEl('anthropic_model', modelId_prefix);
|
||||||
if(apiKeyInput.value === ''){
|
if(apiKeyInput.value === ''){
|
||||||
apiKeyInput.style.border = '2px solid red';
|
apiKeyInput.style.border = '2px solid red';
|
||||||
|
|
@ -1110,8 +1334,9 @@ function warn_Anthropic_APIKeyEmpty(modelId_prefix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function warn_Anthropic_VersionEmpty(modelId_prefix) {
|
function warn_Anthropic_VersionEmpty(modelId_prefix) {
|
||||||
let versionInput = document.getElementById('anthropic_version');
|
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
||||||
let btnFetchAnthropicModels = document.getElementById('btnUpdateAnthropicModels');
|
let versionInput = document.getElementById(getPrefixedId('anthropic_version'));
|
||||||
|
let btnFetchAnthropicModels = document.getElementById(getPrefixedId('btnUpdateAnthropicModels'));
|
||||||
let modelAnthropic = getModelEl('anthropic_model', modelId_prefix);
|
let modelAnthropic = getModelEl('anthropic_model', modelId_prefix);
|
||||||
if(versionInput.value === ''){
|
if(versionInput.value === ''){
|
||||||
versionInput.style.border = '2px solid red';
|
versionInput.style.border = '2px solid red';
|
||||||
|
|
@ -1131,13 +1356,13 @@ function warn_Anthropic_VersionEmpty(modelId_prefix) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetOpenAICompConfigs(){
|
function resetOpenAICompConfigs(modelId_prefix = ''){
|
||||||
let select_openai_comp_model = document.getElementById('openai_comp_services_shortcut');
|
let select_openai_comp_model = document.getElementById((modelId_prefix ? modelId_prefix : '') + 'openai_comp_services_shortcut');
|
||||||
select_openai_comp_model.value = 'custom';
|
select_openai_comp_model.value = 'custom';
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadOpenAICompConfigs(){
|
function loadOpenAICompConfigs(modelId_prefix = ''){
|
||||||
let select_openai_comp_model = document.getElementById('openai_comp_services_shortcut');
|
let select_openai_comp_model = document.getElementById((modelId_prefix ? modelId_prefix : '') + 'openai_comp_services_shortcut');
|
||||||
openAICompConfigs.forEach(config => {
|
openAICompConfigs.forEach(config => {
|
||||||
const option = document.createElement('option');
|
const option = document.createElement('option');
|
||||||
option.value = config.id;
|
option.value = config.id;
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,16 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from '../../options/mzta-options-default.js';
|
import { prefs_default, integration_options_config } from '../../options/mzta-options-default.js';
|
||||||
import { taLogger } from '../../js/mzta-logger.js';
|
import { taLogger } from '../../js/mzta-logger.js';
|
||||||
import {
|
import {
|
||||||
getSpecialPrompts,
|
getSpecialPrompts,
|
||||||
setSpecialPrompts,
|
setSpecialPrompts
|
||||||
loadPrompt,
|
|
||||||
savePrompt,
|
|
||||||
clearPromptAPI
|
|
||||||
} from "../../js/mzta-prompts.js";
|
} from "../../js/mzta-prompts.js";
|
||||||
import { getPlaceholders } from "../../js/mzta-placeholders.js";
|
import {
|
||||||
|
getPlaceholders,
|
||||||
|
mapPlaceholderToSuggestion
|
||||||
|
} from "../../js/mzta-placeholders.js";
|
||||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
import {
|
import {
|
||||||
addTags_getExclusionList,
|
addTags_getExclusionList,
|
||||||
|
|
@ -37,84 +37,50 @@ import {
|
||||||
isAPIKeyValue
|
isAPIKeyValue
|
||||||
} from "../../js/mzta-utils.js";
|
} from "../../js/mzta-utils.js";
|
||||||
import {
|
import {
|
||||||
injectConnectionUI,
|
initializeSpecificIntegrationUI
|
||||||
updateWarnings,
|
|
||||||
changeConnTypeRowColor
|
|
||||||
} from "../_lib/connection-ui.js";
|
} from "../_lib/connection-ui.js";
|
||||||
|
|
||||||
let autocompleteSuggestions = [];
|
let autocompleteSuggestions = [];
|
||||||
let taLog = new taLogger("mzta-addtags-page",true);
|
let taLog = new taLogger("mzta-addtags-page",true);
|
||||||
let conntype_select_id = 'add_tags_connection_type';
|
|
||||||
let model_prefix = 'add_tags_';
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
try {
|
|
||||||
await injectConnectionUI({
|
let specialPrompts = await getSpecialPrompts();
|
||||||
afterTrId: 'connection_ui_anchor',
|
let addtags_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_add_tags');
|
||||||
tr_class: 'specific_integration_sub',
|
|
||||||
selectId: conntype_select_id,
|
if (addtags_prompt && addtags_prompt.api && addtags_prompt.api !== '') {
|
||||||
modelId_prefix: model_prefix,
|
let update_prefs = {};
|
||||||
no_chatgpt_web: true,
|
update_prefs['add_tags_connection_type'] = addtags_prompt.api;
|
||||||
taLog: taLog
|
|
||||||
});
|
let integration = addtags_prompt.api.replace('_api', '');
|
||||||
} catch (e) {
|
if (integration_options_config && integration_options_config[integration]) {
|
||||||
console.error('Failed to inject connection UI (add-tags)', e);
|
for (const key of Object.keys(integration_options_config[integration])) {
|
||||||
|
if (addtags_prompt[key] !== undefined) {
|
||||||
|
update_prefs[`add_tags_${integration}_${key}`] = addtags_prompt[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await browser.storage.sync.set(update_prefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await initializeSpecificIntegrationUI({
|
||||||
|
prefix: 'add_tags',
|
||||||
|
promptId: 'prompt_add_tags',
|
||||||
|
taLog: taLog,
|
||||||
|
restoreOptionsCallback: restoreOptions
|
||||||
|
});
|
||||||
|
|
||||||
i18n.updateDocument();
|
i18n.updateDocument();
|
||||||
await restoreOptions();
|
|
||||||
|
|
||||||
document.querySelectorAll(".option-input").forEach(element => {
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
element.addEventListener("change", saveOptions);
|
element.addEventListener("change", saveOptions);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.querySelectorAll(".option-input-model").forEach(element => {
|
|
||||||
element.addEventListener("change", updatePromptAPIInfo);
|
|
||||||
});
|
|
||||||
|
|
||||||
let conntype_el = document.getElementById(conntype_select_id);
|
|
||||||
let conntype_end_el = document.getElementById('connection_ui_end');
|
|
||||||
|
|
||||||
conntype_el.addEventListener('change', updatePromptAPIInfo);
|
|
||||||
|
|
||||||
let add_tags_use_specific_integration_el = document.getElementById('add_tags_use_specific_integration');
|
|
||||||
let prefs_add_tags = await browser.storage.sync.get({ add_tags_enabled_accounts: [], connection_type: 'chatgpt_web' });
|
let prefs_add_tags = await browser.storage.sync.get({ add_tags_enabled_accounts: [], connection_type: 'chatgpt_web' });
|
||||||
if(prefs_add_tags.connection_type == 'chatgpt_web'){
|
|
||||||
add_tags_use_specific_integration_el.checked = true;
|
|
||||||
add_tags_use_specific_integration_el.dispatchEvent(new Event('change'));
|
|
||||||
add_tags_use_specific_integration_el.disabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let conntype_row = document.getElementById(conntype_select_id + '_tr');
|
|
||||||
add_tags_use_specific_integration_el.addEventListener('change', (event) => {
|
|
||||||
// console.log(">>>>>>>>>>>>> conntype_el.value: " + conntype_el.value);
|
|
||||||
document.querySelectorAll(".specific_integration_sub").forEach(tr => {
|
|
||||||
tr.style.display = event.target.checked && tr.classList.contains('conntype_' + conntype_el.value) ? 'table-row' : 'none';
|
|
||||||
});
|
|
||||||
conntype_el.style.display = event.target.checked ? 'table-row' : 'none';
|
|
||||||
conntype_end_el.style.display = event.target.checked ? 'table-row' : 'none';
|
|
||||||
changeConnTypeRowColor(conntype_row, conntype_el);
|
|
||||||
if(!event.target.checked){
|
|
||||||
clearPromptAPI('prompt_add_tags');
|
|
||||||
}else{
|
|
||||||
updatePromptAPIInfo();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// console.log(">>>>>>>>>>>>> conntype_el.value: " + conntype_el.value);
|
|
||||||
document.querySelectorAll(".specific_integration_sub").forEach(tr => {
|
|
||||||
tr.style.display = add_tags_use_specific_integration_el.checked && tr.classList.contains('conntype_' + conntype_el.value) ? 'table-row' : 'none';
|
|
||||||
});
|
|
||||||
document.getElementById(conntype_select_id + '_tr').style.display = add_tags_use_specific_integration_el.checked ? 'table-row' : 'none';
|
|
||||||
conntype_end_el.style.display = add_tags_use_specific_integration_el.checked ? 'table-row' : 'none';
|
|
||||||
changeConnTypeRowColor(conntype_row, conntype_el);
|
|
||||||
|
|
||||||
let addtags_textarea = document.getElementById('addtags_prompt_text');
|
let addtags_textarea = document.getElementById('addtags_prompt_text');
|
||||||
let addtags_save_btn = document.getElementById('btn_save_prompt');
|
let addtags_save_btn = document.getElementById('btn_save_prompt');
|
||||||
let addtags_reset_btn = document.getElementById('btn_reset_prompt');
|
let addtags_reset_btn = document.getElementById('btn_reset_prompt');
|
||||||
|
|
||||||
let specialPrompts = await getSpecialPrompts();
|
|
||||||
let addtags_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_add_tags');
|
|
||||||
|
|
||||||
addtags_textarea.addEventListener('input', (event) => {
|
addtags_textarea.addEventListener('input', (event) => {
|
||||||
addtags_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_add_tags_full_text'));
|
addtags_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_add_tags_full_text'));
|
||||||
addtags_save_btn.disabled = (event.target.value === addtags_prompt.text);
|
addtags_save_btn.disabled = (event.target.value === addtags_prompt.text);
|
||||||
|
|
@ -177,7 +143,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
updateAdditionalPromptStatements();
|
updateAdditionalPromptStatements();
|
||||||
|
|
||||||
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(p => ({command: '{%'+p.id+'%}', type: p.type}));
|
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(mapPlaceholderToSuggestion);
|
||||||
textareaAutocomplete(addtags_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
textareaAutocomplete(addtags_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
||||||
|
|
||||||
let excl_list_textarea = document.getElementById('addtags_excl_list');
|
let excl_list_textarea = document.getElementById('addtags_excl_list');
|
||||||
|
|
@ -257,8 +223,6 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
let checkboxes = document.querySelectorAll('.accountCheckbox');
|
let checkboxes = document.querySelectorAll('.accountCheckbox');
|
||||||
checkboxes.forEach(checkbox => checkbox.checked = false);
|
checkboxes.forEach(checkbox => checkbox.checked = false);
|
||||||
});
|
});
|
||||||
|
|
||||||
updateWarnings(model_prefix);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -290,18 +254,6 @@ async function updateAdditionalPromptStatements(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updatePromptAPIInfo(){
|
|
||||||
let conntype = document.getElementById(conntype_select_id).value;
|
|
||||||
let model_value = conntype.substring(0, conntype.length - 4) + '_model';
|
|
||||||
let model = document.getElementById(model_prefix + model_value).value;
|
|
||||||
// console.log(">>>>>>>>>>> updatePromptAPIInfo: conntype: " + conntype + " - model: " + model + " - model_value: " + model_value);
|
|
||||||
let add_tags_prompt = await loadPrompt('prompt_add_tags');
|
|
||||||
// console.log(">>>>>>>>>>> updatePromptAPIInfo: BEFORE add_tags_prompt: " + JSON.stringify(add_tags_prompt));
|
|
||||||
add_tags_prompt.api = conntype;
|
|
||||||
add_tags_prompt.model = model;
|
|
||||||
// console.log(">>>>>>>>>>> updatePromptAPIInfo: AFTER add_tags_prompt: " + JSON.stringify(add_tags_prompt));
|
|
||||||
await savePrompt(add_tags_prompt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Methods to manage options, derived from: /options/mzta-options.js
|
// Methods to manage options, derived from: /options/mzta-options.js
|
||||||
|
|
@ -387,5 +339,23 @@ async function restoreOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let getting = await browser.storage.sync.get(prefs_default);
|
let getting = await browser.storage.sync.get(prefs_default);
|
||||||
|
|
||||||
|
let specialPrompts = await getSpecialPrompts();
|
||||||
|
let addtags_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_add_tags');
|
||||||
|
|
||||||
|
if (addtags_prompt) {
|
||||||
|
if (addtags_prompt.api && addtags_prompt.api !== '') {
|
||||||
|
getting['add_tags_connection_type'] = addtags_prompt.api;
|
||||||
|
}
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
const propName = `${integration}_${key}`;
|
||||||
|
if (addtags_prompt[propName] !== undefined) {
|
||||||
|
getting[`add_tags_${propName}`] = addtags_prompt[propName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setCurrentChoice(getting);
|
setCurrentChoice(getting);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ table.prompts_list th {
|
||||||
|
|
||||||
table td {
|
table td {
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
padding: 8px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table td.w08{
|
table td.w08{
|
||||||
|
|
@ -228,11 +228,6 @@ label, .id_show, .text_show, .name_show, .type_show, .action_show{
|
||||||
padding-right: 2px;
|
padding-right: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chatgpt_web_additional_info_toggle td{
|
|
||||||
padding:0px 5px;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
#chatgpt_web_additional_info, #chatgpt_web_additional_info_toggle, .chatgpt_web_additional_info, .chatgpt_web_additional_info_toggle, .chatgpt_web_additional_info_show{
|
#chatgpt_web_additional_info, #chatgpt_web_additional_info_toggle, .chatgpt_web_additional_info, .chatgpt_web_additional_info_toggle, .chatgpt_web_additional_info_show{
|
||||||
background-color: rgb(255, 209, 183);
|
background-color: rgb(255, 209, 183);
|
||||||
display:none;
|
display:none;
|
||||||
|
|
@ -271,7 +266,7 @@ label, .id_show, .text_show, .name_show, .type_show, .action_show{
|
||||||
.chatgpt_web_additional_info_toggle{
|
.chatgpt_web_additional_info_toggle{
|
||||||
width: -moz-available;
|
width: -moz-available;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 10px;
|
padding:5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chatgpt_web_additional_info_show{
|
.chatgpt_web_additional_info_show{
|
||||||
|
|
@ -302,6 +297,35 @@ input.input_additional[type="text"]{
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.api_additional_info{
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #409df3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api_additional_info_toggle{
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px;
|
||||||
|
background-color: #409df3;
|
||||||
|
cursor: pointer;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.api_additional_info_show{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 100%;
|
||||||
|
padding: 3px;
|
||||||
|
margin-top: 5px;
|
||||||
|
background-color: rgb(64, 157, 243);
|
||||||
|
}
|
||||||
|
|
||||||
|
#api_additional_info_toggle:hover, .api_additional_info_toggle:hover{
|
||||||
|
background-color: rgb(64, 137, 213);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
body {
|
body {
|
||||||
background-color: #1C1B22;
|
background-color: #1C1B22;
|
||||||
|
|
@ -351,10 +375,17 @@ input.input_additional[type="text"]{
|
||||||
|
|
||||||
#chatgpt_web_additional_info, #chatgpt_web_additional_info_toggle, .chatgpt_web_additional_info, .chatgpt_web_additional_info_toggle, .chatgpt_web_additional_info_show, .chatgpt_web_models_list_table{
|
#chatgpt_web_additional_info, #chatgpt_web_additional_info_toggle, .chatgpt_web_additional_info, .chatgpt_web_additional_info_toggle, .chatgpt_web_additional_info_show, .chatgpt_web_models_list_table{
|
||||||
background-color: rgb(39, 11, 0);
|
background-color: rgb(39, 11, 0);
|
||||||
color: rgb(182, 182, 182);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#chatgpt_web_additional_info_toggle:hover, .chatgpt_web_additional_info_toggle:hover{
|
#chatgpt_web_additional_info_toggle:hover, .chatgpt_web_additional_info_toggle:hover{
|
||||||
background-color: rgb(88, 25, 0);
|
background-color: rgb(88, 25, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.api_additional_info, .api_additional_info_toggle, .api_additional_info_show{
|
||||||
|
background-color: #0f2437;
|
||||||
|
}
|
||||||
|
|
||||||
|
#api_additional_info_toggle:hover, .api_additional_info_toggle:hover{
|
||||||
|
background-color: #1b456d
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>ThunderAI - __MSG_customPrompts_managePrompts__</title>
|
<title>ThunderAI - __MSG_customPrompts_managePrompts__</title>
|
||||||
<link rel="stylesheet" href="mzta-custom-prompts.css">
|
<link rel="stylesheet" href="mzta-custom-prompts.css">
|
||||||
|
<link rel="stylesheet" href="../_lib/connection-ui.css">
|
||||||
<link rel="icon" href="../../images/icon-16px.png">
|
<link rel="icon" href="../../images/icon-16px.png">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -79,7 +80,7 @@
|
||||||
<input type="text" id="txtNameNew" name="name" class="input_new" tabindex="2">
|
<input type="text" id="txtNameNew" name="name" class="input_new" tabindex="2">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr id="chatgpt_web_additional_info_toggle"><td colspan="4"><span class="small_info">__MSG_customPrompts_show_additional_info__</span></td></tr>
|
<tr id="chatgpt_web_additional_info_toggle"><td colspan="4"><span class="small_info">__MSG_customPrompts_show_additional_info__ [ChatGPT Web]</span></td></tr>
|
||||||
<tr id="chatgpt_web_additional_info"><!-- ChatGPT Web additional info -->
|
<tr id="chatgpt_web_additional_info"><!-- ChatGPT Web additional info -->
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<label for="chatGPTWebModelNew" class="field_title">__MSG_prefs_OptionText_chatgpt_web_model__:</label>
|
<label for="chatGPTWebModelNew" class="field_title">__MSG_prefs_OptionText_chatgpt_web_model__:</label>
|
||||||
|
|
@ -101,6 +102,19 @@
|
||||||
<br>__MSG_prefs_OptionText_chatgpt_web_custom_data_info2__</i>
|
<br>__MSG_prefs_OptionText_chatgpt_web_custom_data_info2__</i>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr id="api_additional_info_toggle" class="small_info api_additional_info"><!-- API settings additional info toggle-->
|
||||||
|
<td colspan="5">
|
||||||
|
<span>__MSG_customPrompts_show_additional_info__ [API]</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="api_additional_info" style="display: none;"><!-- API settings additional info -->
|
||||||
|
<td colspan="5" id="api_ui_container">
|
||||||
|
<table style="width: 100%; text-align: left;">
|
||||||
|
<tr id="api_ui_anchor">
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<div class="go_right_float">* __MSG_customPrompts_form_required_fields__</div>
|
<div class="go_right_float">* __MSG_customPrompts_form_required_fields__</div>
|
||||||
<br>
|
<br>
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,37 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from "../../options/mzta-options-default.js";
|
import {
|
||||||
import { getPrompts, setDefaultPromptsProperties, setCustomPrompts, preparePromptsForExport, preparePromptsForImport } from "../../js/mzta-prompts.js";
|
prefs_default,
|
||||||
import { ChatGPTWeb_models, isThunderbird128OrGreater, getLocalStorageUsedSpace, sanitizeHtml, validateCustomData_ChatGPTWeb, getChatGPTWebModelsList_HTML, openTab } from "../../js/mzta-utils.js";
|
integration_options_config
|
||||||
|
} from "../../options/mzta-options-default.js";
|
||||||
|
import {
|
||||||
|
getPrompts,
|
||||||
|
setDefaultPromptsProperties,
|
||||||
|
setCustomPrompts,
|
||||||
|
preparePromptsForExport,
|
||||||
|
preparePromptsForImport
|
||||||
|
} from "../../js/mzta-prompts.js";
|
||||||
|
import {
|
||||||
|
injectConnectionUI,
|
||||||
|
showConnectionOptions,
|
||||||
|
updateWarnings
|
||||||
|
} from "../../pages/_lib/connection-ui.js";
|
||||||
|
import {
|
||||||
|
ChatGPTWeb_models,
|
||||||
|
isThunderbird128OrGreater,
|
||||||
|
getLocalStorageUsedSpace,
|
||||||
|
sanitizeHtml,
|
||||||
|
validateCustomData_ChatGPTWeb,
|
||||||
|
getChatGPTWebModelsList_HTML,
|
||||||
|
openTab
|
||||||
|
} from "../../js/mzta-utils.js";
|
||||||
import { taLogger } from "../../js/mzta-logger.js";
|
import { taLogger } from "../../js/mzta-logger.js";
|
||||||
import { getPlaceholders, placeholdersUtils } from "../../js/mzta-placeholders.js";
|
import {
|
||||||
|
getPlaceholders,
|
||||||
|
placeholdersUtils,
|
||||||
|
mapPlaceholderToSuggestion
|
||||||
|
} from "../../js/mzta-placeholders.js";
|
||||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
|
|
||||||
let prefs = null;
|
let prefs = null;
|
||||||
|
|
@ -35,7 +61,8 @@ let autocompleteSuggestions = [];
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
prefs = await browser.storage.sync.get({ connection_type:prefs_default.connection_type, do_debug: prefs_default.do_debug });
|
let storedPrefs = await browser.storage.sync.get(null);
|
||||||
|
prefs = { ...prefs_default, ...storedPrefs };
|
||||||
taLog = new taLogger("mzta-custom-prompts", prefs.do_debug);
|
taLog = new taLogger("mzta-custom-prompts", prefs.do_debug);
|
||||||
|
|
||||||
setStorageSpace();
|
setStorageSpace();
|
||||||
|
|
@ -86,7 +113,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const textareas = document.querySelectorAll('.editor');
|
const textareas = document.querySelectorAll('.editor');
|
||||||
autocompleteSuggestions = (await getPlaceholders(true)).map(p => ({command: '{%'+p.id+'%}', type: p.type}));
|
autocompleteSuggestions = (await getPlaceholders(true)).map(mapPlaceholderToSuggestion);
|
||||||
|
|
||||||
// console.log('>>>>>>>>>>> autocompleteSuggestions: ' + JSON.stringify(autocompleteSuggestions));
|
// console.log('>>>>>>>>>>> autocompleteSuggestions: ' + JSON.stringify(autocompleteSuggestions));
|
||||||
|
|
||||||
|
|
@ -100,34 +127,98 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const apiSettingsToggle = document.getElementById('api_additional_info_toggle');
|
||||||
|
const apiSettingsRow = document.getElementById('api_additional_info');
|
||||||
|
|
||||||
|
apiSettingsToggle.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (apiSettingsRow.style.display === 'none') {
|
||||||
|
apiSettingsRow.style.display = 'table-row';
|
||||||
|
apiSettingsToggle.querySelector('span').innerText = browser.i18n.getMessage('customPrompts_hide_additional_info') + ' [API]';
|
||||||
|
} else {
|
||||||
|
apiSettingsRow.style.display = 'none';
|
||||||
|
apiSettingsToggle.querySelector('span').innerText = browser.i18n.getMessage('customPrompts_show_additional_info') + ' [API]';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await injectConnectionUI({
|
||||||
|
afterTrId: 'api_ui_anchor',
|
||||||
|
selectId: 'new_prompt_api_type',
|
||||||
|
no_chatgpt_web: true,
|
||||||
|
taLog: taLog
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fill defaults for new prompt form
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
const propName = `${integration}_${key}`;
|
||||||
|
const inputEl = document.getElementById(propName);
|
||||||
|
if (inputEl && prefs[propName] !== undefined) {
|
||||||
|
if (inputEl.type === 'checkbox') {
|
||||||
|
inputEl.checked = (prefs[propName] === true || prefs[propName] === 'true');
|
||||||
|
} else {
|
||||||
|
inputEl.value = prefs[propName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
i18n.updateDocument();
|
i18n.updateDocument();
|
||||||
|
|
||||||
switch(prefs.connection_type) {
|
const apiSelect = document.getElementById('new_prompt_api_type');
|
||||||
case 'chatgpt_web': {
|
// Remove chatgpt_web
|
||||||
// for the new item form
|
// for (let i = 0; i < apiSelect.options.length; i++) {
|
||||||
document.getElementById('chatgpt_web_additional_info_toggle').style.display = 'table-row';
|
// if (apiSelect.options[i].value === 'chatgpt_web') {
|
||||||
// for the edit list items form
|
// apiSelect.remove(i);
|
||||||
document.querySelectorAll('.chatgpt_web_additional_info_toggle').forEach(element => {
|
// break;
|
||||||
element.addEventListener('click', (e) => {
|
// }
|
||||||
e.preventDefault();
|
// }
|
||||||
let additionalInfoRow = e.target.closest('td').querySelector('.chatgpt_web_additional_info');
|
apiSelect.addEventListener('change', () => {
|
||||||
if (additionalInfoRow.style.display === 'none' || additionalInfoRow.style.display === '') {
|
showConnectionOptions(apiSelect);
|
||||||
additionalInfoRow.style.display = 'block';
|
});
|
||||||
e.target.innerText = browser.i18n.getMessage('customPrompts_hide_additional_info');
|
showConnectionOptions(apiSelect);
|
||||||
} else {
|
|
||||||
additionalInfoRow.style.display = 'none';
|
if(prefs.connection_type == 'chatgpt_web') {
|
||||||
e.target.innerText = browser.i18n.getMessage('customPrompts_show_additional_info');
|
// for the new item form
|
||||||
}
|
document.getElementById('chatgpt_web_additional_info_toggle').style.display = 'table-row';
|
||||||
});
|
// for the edit list items form
|
||||||
|
document.querySelectorAll('.chatgpt_web_additional_info_toggle').forEach(element => {
|
||||||
|
element.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
let additionalInfoRow = e.target.closest('td').querySelector('.chatgpt_web_additional_info');
|
||||||
|
if (additionalInfoRow.style.display === 'none' || additionalInfoRow.style.display === '') {
|
||||||
|
additionalInfoRow.style.display = 'block';
|
||||||
|
e.target.innerText = browser.i18n.getMessage('customPrompts_hide_additional_info') + ' [ChatGPT Web]';
|
||||||
|
} else {
|
||||||
|
additionalInfoRow.style.display = 'none';
|
||||||
|
e.target.innerText = browser.i18n.getMessage('customPrompts_show_additional_info') + ' [ChatGPT Web]';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
document.querySelectorAll('input.chatgpt_web_project_output').forEach(element => {
|
});
|
||||||
element.addEventListener("input", validateCustomData_ChatGPTWeb);
|
document.querySelectorAll('input.chatgpt_web_project_output').forEach(element => {
|
||||||
});
|
element.addEventListener("input", validateCustomData_ChatGPTWeb);
|
||||||
document.querySelectorAll('input.chatgpt_web_custom_gpt_output').forEach(element => {
|
});
|
||||||
element.addEventListener("input", validateCustomData_ChatGPTWeb);
|
document.querySelectorAll('input.chatgpt_web_custom_gpt_output').forEach(element => {
|
||||||
});
|
element.addEventListener("input", validateCustomData_ChatGPTWeb);
|
||||||
break;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for the edit list items form [API]
|
||||||
|
document.querySelectorAll('.api_additional_info_toggle').forEach(element => {
|
||||||
|
element.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
let additionalInfoRow = element.nextElementSibling;
|
||||||
|
if (additionalInfoRow.style.display === 'none' || additionalInfoRow.style.display === '') {
|
||||||
|
additionalInfoRow.style.display = 'block';
|
||||||
|
element.innerText = browser.i18n.getMessage('customPrompts_hide_additional_info') + ' [API]';
|
||||||
|
} else {
|
||||||
|
additionalInfoRow.style.display = 'none';
|
||||||
|
element.innerText = browser.i18n.getMessage('customPrompts_show_additional_info') + ' [API]';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// switch(prefs.connection_type) {
|
||||||
// case 'chatgpt_api':
|
// case 'chatgpt_api':
|
||||||
// document.getElementById('chatgpt_api').style.display = 'block';
|
// document.getElementById('chatgpt_api').style.display = 'block';
|
||||||
// break;
|
// break;
|
||||||
|
|
@ -140,7 +231,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
// case 'google_gemini_api':
|
// case 'google_gemini_api':
|
||||||
// document.getElementById('google_gemini_api').style.display = 'block';
|
// document.getElementById('google_gemini_api').style.display = 'block';
|
||||||
// break;
|
// break;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const chatgptWebAdditionalPropToggle = document.getElementById('chatgpt_web_additional_info_toggle');
|
const chatgptWebAdditionalPropToggle = document.getElementById('chatgpt_web_additional_info_toggle');
|
||||||
chatgptWebAdditionalPropToggle.addEventListener('click', (e) => {
|
chatgptWebAdditionalPropToggle.addEventListener('click', (e) => {
|
||||||
|
|
@ -150,13 +241,13 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
additionalInfoRow.style.display = 'table-row';
|
additionalInfoRow.style.display = 'table-row';
|
||||||
let subspan = chatgptWebAdditionalPropToggle.querySelector('td span');
|
let subspan = chatgptWebAdditionalPropToggle.querySelector('td span');
|
||||||
if (subspan) {
|
if (subspan) {
|
||||||
subspan.innerText = browser.i18n.getMessage('customPrompts_hide_additional_info');
|
subspan.innerText = browser.i18n.getMessage('customPrompts_hide_additional_info') + ' [ChatGPT Web]';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
additionalInfoRow.style.display = 'none';
|
additionalInfoRow.style.display = 'none';
|
||||||
let subspan = chatgptWebAdditionalPropToggle.querySelector('td span');
|
let subspan = chatgptWebAdditionalPropToggle.querySelector('td span');
|
||||||
if (subspan) {
|
if (subspan) {
|
||||||
subspan.innerText = browser.i18n.getMessage('customPrompts_show_additional_info');
|
subspan.innerText = browser.i18n.getMessage('customPrompts_show_additional_info') + ' [ChatGPT Web]';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -210,6 +301,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
position_display: positionMax_display + 1,
|
position_display: positionMax_display + 1,
|
||||||
is_default: 0,
|
is_default: 0,
|
||||||
idnum: idnumMax + 1,
|
idnum: idnumMax + 1,
|
||||||
|
api_type: document.getElementById('new_prompt_api_type').value
|
||||||
};
|
};
|
||||||
|
|
||||||
switch(prefs.connection_type) {
|
switch(prefs.connection_type) {
|
||||||
|
|
@ -232,6 +324,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const apiValues = getAPIValuesFromUI();
|
||||||
|
Object.assign(newItemData, apiValues);
|
||||||
|
|
||||||
let newItem = promptsList.add(newItemData);
|
let newItem = promptsList.add(newItemData);
|
||||||
idnumMax++;
|
idnumMax++;
|
||||||
let curr_idnum = newItem[0].values().idnum;
|
let curr_idnum = newItem[0].values().idnum;
|
||||||
|
|
@ -345,6 +440,10 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
toggleAdditionalPropertiesShow(element.closest('tr'));
|
toggleAdditionalPropertiesShow(element.closest('tr'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('.api_additional_info_show').forEach(element => {
|
||||||
|
toggleApiPropertiesShow(element.closest('tr'));
|
||||||
|
});
|
||||||
|
|
||||||
getChatGPTWebModelsList_HTML(ChatGPTWeb_models, 'chatgpt_web_models_list');
|
getChatGPTWebModelsList_HTML(ChatGPTWeb_models, 'chatgpt_web_models_list');
|
||||||
let formNewWebModelList = document.getElementById('chatgpt_web_models_list');
|
let formNewWebModelList = document.getElementById('chatgpt_web_models_list');
|
||||||
formNewWebModelList.querySelectorAll('.conntype_chatgpt_web_option').forEach(element => {
|
formNewWebModelList.querySelectorAll('.conntype_chatgpt_web_option').forEach(element => {
|
||||||
|
|
@ -377,6 +476,38 @@ document.getElementById('btnManageCustomDataPH').addEventListener('click', () =>
|
||||||
function handleEditClick(e) {
|
function handleEditClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const tr = e.target.parentNode.parentNode;
|
const tr = e.target.parentNode.parentNode;
|
||||||
|
const id = tr.querySelector('.id_output').value;
|
||||||
|
|
||||||
|
// Inject Connection UI if needed
|
||||||
|
const anchorId = `api_ui_anchor_${id}`;
|
||||||
|
const selectId = `api_type_${id}`;
|
||||||
|
const prefix = `prompt_${id}_`;
|
||||||
|
|
||||||
|
if (!document.getElementById(selectId)) {
|
||||||
|
injectConnectionUI({
|
||||||
|
afterTrId: anchorId,
|
||||||
|
selectId: selectId,
|
||||||
|
modelId_prefix: prefix,
|
||||||
|
no_chatgpt_web: true,
|
||||||
|
taLog: taLog,
|
||||||
|
customButtonLabel: browser.i18n.getMessage("Reset"),
|
||||||
|
customButtonCallback: () => {
|
||||||
|
const selectEl = document.getElementById(selectId);
|
||||||
|
if (selectEl) {
|
||||||
|
selectEl.value = '';
|
||||||
|
selectEl.dispatchEvent(new Event('change'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
|
populateConnectionUI(tr, id, prefix, selectId);
|
||||||
|
updateWarnings(prefix);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
populateConnectionUI(tr, id, prefix, selectId);
|
||||||
|
updateWarnings(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show/Hide buttons
|
||||||
//console.log('>>>>>>>> tr: ' + tr.getAttribute('data-idnum'));
|
//console.log('>>>>>>>> tr: ' + tr.getAttribute('data-idnum'));
|
||||||
e.target.style.display = 'none'; // Edit btn
|
e.target.style.display = 'none'; // Edit btn
|
||||||
tr.querySelector('.btnConfirmItem').style.display = 'inline'; // Save btn
|
tr.querySelector('.btnConfirmItem').style.display = 'inline'; // Save btn
|
||||||
|
|
@ -387,6 +518,36 @@ function handleEditClick(e) {
|
||||||
toggleDiffviewer(e);
|
toggleDiffviewer(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function populateConnectionUI(tr, id, prefix, selectId) {
|
||||||
|
const item = promptsList.get('id', id)[0];
|
||||||
|
const itemValues = item.values();
|
||||||
|
|
||||||
|
const selectEl = document.getElementById(selectId);
|
||||||
|
if (selectEl) {
|
||||||
|
selectEl.value = itemValues.api_type || '';
|
||||||
|
showConnectionOptions(selectEl);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
const propName = `${integration}_${key}`;
|
||||||
|
const inputId = `${prefix}${propName}`;
|
||||||
|
const inputEl = document.getElementById(inputId);
|
||||||
|
if (inputEl) {
|
||||||
|
let val = itemValues[propName];
|
||||||
|
// Use default if undefined or empty string (for text inputs)
|
||||||
|
if (val === undefined || (inputEl.type !== 'checkbox' && val === '')) {
|
||||||
|
if (prefs[propName] !== undefined) {
|
||||||
|
val = prefs[propName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inputEl.type === 'checkbox' ? inputEl.checked = (val === true || val === 'true') : inputEl.value = val || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i18n.updateDocument();
|
||||||
|
}
|
||||||
|
|
||||||
function showItemRowEditor(tr) {
|
function showItemRowEditor(tr) {
|
||||||
tr.querySelector('.id_output').style.display = 'inline';
|
tr.querySelector('.id_output').style.display = 'inline';
|
||||||
tr.querySelector('.id_show').style.display = 'none';
|
tr.querySelector('.id_show').style.display = 'none';
|
||||||
|
|
@ -398,6 +559,7 @@ function showItemRowEditor(tr) {
|
||||||
tr.querySelector('.text_show').style.display = 'none';
|
tr.querySelector('.text_show').style.display = 'none';
|
||||||
toggleAdditionalPropertiesEditor(tr);
|
toggleAdditionalPropertiesEditor(tr);
|
||||||
tr.querySelector('.chatgpt_web_additional_info_show').style.display = 'none';
|
tr.querySelector('.chatgpt_web_additional_info_show').style.display = 'none';
|
||||||
|
tr.querySelector('.api_additional_info_show').style.display = 'none';
|
||||||
tr.querySelector('.type_output').style.display = 'inline';
|
tr.querySelector('.type_output').style.display = 'inline';
|
||||||
tr.querySelector('.type_show').style.display = 'none';
|
tr.querySelector('.type_show').style.display = 'none';
|
||||||
const action_output = tr.querySelector('.action_output')
|
const action_output = tr.querySelector('.action_output')
|
||||||
|
|
@ -420,6 +582,8 @@ function hideItemRowEditor(tr) {
|
||||||
tr.querySelector('.text_show').style.display = 'inline';
|
tr.querySelector('.text_show').style.display = 'inline';
|
||||||
tr.querySelector('.chatgpt_web_additional_info_toggle').style.display = 'none';
|
tr.querySelector('.chatgpt_web_additional_info_toggle').style.display = 'none';
|
||||||
tr.querySelector('.chatgpt_web_additional_info').style.display = 'none';
|
tr.querySelector('.chatgpt_web_additional_info').style.display = 'none';
|
||||||
|
tr.querySelector('.api_additional_info_toggle').style.display = 'none';
|
||||||
|
tr.querySelector('.api_additional_info').style.display = 'none';
|
||||||
toggleAdditionalPropertiesShow(tr);
|
toggleAdditionalPropertiesShow(tr);
|
||||||
tr.querySelector('.type_output').style.display = 'none';
|
tr.querySelector('.type_output').style.display = 'none';
|
||||||
tr.querySelector('.type_show').style.display = 'inline';
|
tr.querySelector('.type_show').style.display = 'inline';
|
||||||
|
|
@ -482,6 +646,23 @@ function toggleAdditionalPropertiesShow(tr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleApiPropertiesShow(tr) {
|
||||||
|
let element = tr.querySelector('.api_additional_info_show');
|
||||||
|
let api_type_show = tr.querySelector('.api_type_show');
|
||||||
|
|
||||||
|
if (api_type_show.innerText !== '' && api_type_show.innerText !== 'undefined') {
|
||||||
|
element.style.display = 'flex';
|
||||||
|
} else {
|
||||||
|
element.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(api_type_show.innerText === '' || api_type_show.innerText === 'undefined') {
|
||||||
|
api_type_show.parentNode.style.display = 'none';
|
||||||
|
} else {
|
||||||
|
api_type_show.parentNode.style.display = 'inline';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function toggleAdditionalPropertiesEditor(tr) {
|
function toggleAdditionalPropertiesEditor(tr) {
|
||||||
switch(prefs.connection_type) {
|
switch(prefs.connection_type) {
|
||||||
case 'chatgpt_web': {
|
case 'chatgpt_web': {
|
||||||
|
|
@ -511,6 +692,14 @@ function toggleAdditionalPropertiesEditor(tr) {
|
||||||
// document.getElementById('google_gemini_api').style.display = 'block';
|
// document.getElementById('google_gemini_api').style.display = 'block';
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let api_info_toggle = tr.querySelector('.api_additional_info_toggle');
|
||||||
|
api_info_toggle.style.display = 'block';
|
||||||
|
let api_type_show = tr.querySelector('.api_type_show').innerText;
|
||||||
|
|
||||||
|
if (api_type_show !== '' && api_type_show !== 'undefined') {
|
||||||
|
api_info_toggle.click();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleDiffviewer(e) {
|
function toggleDiffviewer(e) {
|
||||||
|
|
@ -563,6 +752,9 @@ function handleCancelClick(e) {
|
||||||
tr.querySelector('.chatgpt_web_model_output').value = tr.querySelector('.chatgpt_web_model_show').innerText;
|
tr.querySelector('.chatgpt_web_model_output').value = tr.querySelector('.chatgpt_web_model_show').innerText;
|
||||||
tr.querySelector('.chatgpt_web_project_output').value = tr.querySelector('.chatgpt_web_project_show').innerText;
|
tr.querySelector('.chatgpt_web_project_output').value = tr.querySelector('.chatgpt_web_project_show').innerText;
|
||||||
tr.querySelector('.chatgpt_web_custom_gpt_output').value = tr.querySelector('.chatgpt_web_custom_gpt_show').innerText;
|
tr.querySelector('.chatgpt_web_custom_gpt_output').value = tr.querySelector('.chatgpt_web_custom_gpt_show').innerText;
|
||||||
|
tr.querySelector('.api_additional_info_toggle').innerText = browser.i18n.getMessage('customPrompts_show_additional_info') + ' [API]';
|
||||||
|
tr.querySelector('.api_additional_info_show').style.display = 'block';
|
||||||
|
|
||||||
hideItemRowEditor(tr);
|
hideItemRowEditor(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -570,21 +762,51 @@ function handleConfirmClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const tr = e.target.parentNode.parentNode;
|
const tr = e.target.parentNode.parentNode;
|
||||||
e.target.style.display = 'none'; // Ok btn
|
e.target.style.display = 'none'; // Ok btn
|
||||||
|
|
||||||
|
const oldId = tr.querySelector('.id_show').innerText;
|
||||||
|
const prefix = `prompt_${oldId}_`;
|
||||||
|
const selectId = `api_type_${oldId}`;
|
||||||
|
|
||||||
|
let newValues = {};
|
||||||
|
|
||||||
|
// Standard fields
|
||||||
|
newValues.id = tr.querySelector('.id_output').value.trim().toLowerCase();
|
||||||
|
newValues.name = tr.querySelector('.name_output').value.trim();
|
||||||
|
newValues.text = tr.querySelector('.text_output').value;
|
||||||
|
newValues.type = tr.querySelector('.type_output').value;
|
||||||
|
newValues.action = tr.querySelector('.action_output').value;
|
||||||
|
newValues.need_selected = tr.querySelector('.need_selected').checked ? 1 : 0;
|
||||||
|
newValues.need_signature = tr.querySelector('.need_signature').checked ? 1 : 0;
|
||||||
|
newValues.need_custom_text = tr.querySelector('.need_custom_text').checked ? 1 : 0;
|
||||||
|
newValues.define_response_lang = tr.querySelector('.define_response_lang').checked ? 1 : 0;
|
||||||
|
newValues.use_diff_viewer = tr.querySelector('.use_diff_viewer').checked ? 1 : 0;
|
||||||
|
newValues.enabled = tr.querySelector('.enabled').checked ? 1 : 0;
|
||||||
|
newValues.chatgpt_web_model = tr.querySelector('.chatgpt_web_model_output').value.trim();
|
||||||
|
newValues.chatgpt_web_project = tr.querySelector('.chatgpt_web_project_output').value.trim();
|
||||||
|
newValues.chatgpt_web_custom_gpt = tr.querySelector('.chatgpt_web_custom_gpt_output').value.trim();
|
||||||
|
|
||||||
|
const selectEl = document.getElementById(selectId);
|
||||||
|
if(selectEl) newValues.api_type = selectEl.value;
|
||||||
|
|
||||||
|
const apiValues = getAPIValuesFromUI(prefix);
|
||||||
|
Object.assign(newValues, apiValues);
|
||||||
|
promptsList.get('id', oldId)[0].values(newValues);
|
||||||
|
|
||||||
// tr.querySelector('.btnConfirmItem').style.display = 'none'; // Ok btn
|
// tr.querySelector('.btnConfirmItem').style.display = 'none'; // Ok btn
|
||||||
tr.querySelector('.btnCancelItem').style.display = 'none'; // Cancel btn
|
tr.querySelector('.btnCancelItem').style.display = 'none'; // Cancel btn
|
||||||
tr.querySelector('.btnEditItem').style.display = 'inline'; // Edit btn
|
tr.querySelector('.btnEditItem').style.display = 'inline'; // Edit btn
|
||||||
tr.querySelector('.btnDeleteItem').style.display = 'inline'; // Delete btn
|
tr.querySelector('.btnDeleteItem').style.display = 'inline'; // Delete btn
|
||||||
// Update item data
|
// Update item data
|
||||||
tr.querySelector('.id_show').innerText = String(tr.querySelector('.id_output').value).toLocaleLowerCase();
|
|
||||||
tr.querySelector('.name_show').innerText = tr.querySelector('.name_output').value;
|
|
||||||
tr.querySelector('.text_show').innerText = tr.querySelector('.text_output').value;
|
|
||||||
tr.querySelector('.chatgpt_web_model_show').innerText = tr.querySelector('.chatgpt_web_model_output').value;
|
|
||||||
tr.querySelector('.chatgpt_web_project_show').innerText = tr.querySelector('.chatgpt_web_project_output').value;
|
|
||||||
tr.querySelector('.chatgpt_web_custom_gpt_show').innerText = tr.querySelector('.chatgpt_web_custom_gpt_output').value;
|
|
||||||
tr.querySelector('.type').innerText = tr.querySelector('.type_output').value;
|
tr.querySelector('.type').innerText = tr.querySelector('.type_output').value;
|
||||||
tr.querySelector('.type_show').innerText = tr.querySelector('.type_output').selectedOptions[0].text;
|
tr.querySelector('.type_show').innerText = tr.querySelector('.type_output').selectedOptions[0].text;
|
||||||
tr.querySelector('.action').innerText = tr.querySelector('.action_output').value;
|
tr.querySelector('.action').innerText = tr.querySelector('.action_output').value;
|
||||||
tr.querySelector('.action_show').innerText = tr.querySelector('.action_output').selectedOptions[0].text;
|
tr.querySelector('.action_show').innerText = tr.querySelector('.action_output').selectedOptions[0].text;
|
||||||
|
if (newValues.api_type !== '') {
|
||||||
|
tr.querySelector('.api_type_show').innerText = newValues.api_type;
|
||||||
|
tr.querySelector('.api_additional_info_show').style.display = 'block';
|
||||||
|
tr.querySelector('.api_additional_info_row').style.display = 'block';
|
||||||
|
|
||||||
|
}
|
||||||
// the checkboxes update is handled directly by themselves
|
// the checkboxes update is handled directly by themselves
|
||||||
hideItemRowEditor(tr);
|
hideItemRowEditor(tr);
|
||||||
setSomethingChanged();
|
setSomethingChanged();
|
||||||
|
|
@ -613,8 +835,15 @@ function handleInputChange(e) {
|
||||||
|
|
||||||
function loadPromptsList(values){
|
function loadPromptsList(values){
|
||||||
// console.log('>>>>>>>> loadPromptsList values: ' + JSON.stringify(values));
|
// console.log('>>>>>>>> loadPromptsList values: ' + JSON.stringify(values));
|
||||||
|
let api_fields = [];
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
api_fields.push(`${integration}_${key}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
valueNames: [ { data: ['idnum'] }, 'is_default', 'id', 'name', 'text', 'type', 'action', 'position_compose', 'position_display', { name: 'need_selected', attr: 'checked_val'}, { name: 'need_signature', attr: 'checked_val'}, { name: 'need_custom_text', attr: 'checked_val'}, { name: 'define_response_lang', attr: 'checked_val'}, { name: 'use_diff_viewer', attr: 'checked_val'}, { name: 'enabled', attr: 'checked_val'} ],
|
valueNames: [ { data: ['idnum'] }, 'is_default', 'id', 'name', 'text', 'type', 'action', 'position_compose', 'position_display', { name: 'need_selected', attr: 'checked_val'}, { name: 'need_signature', attr: 'checked_val'}, { name: 'need_custom_text', attr: 'checked_val'}, { name: 'define_response_lang', attr: 'checked_val'}, { name: 'use_diff_viewer', attr: 'checked_val'}, { name: 'enabled', attr: 'checked_val'}, 'api_type', ...api_fields ],
|
||||||
item: function(values) {
|
item: function(values) {
|
||||||
let type_output = '';
|
let type_output = '';
|
||||||
switch(String(values.type)){
|
switch(String(values.type)){
|
||||||
|
|
@ -652,7 +881,7 @@ function loadPromptsList(values){
|
||||||
<textarea class="hiddendata text_output editor">` + values.text.replace(/<br\s*\/?>/gi, "\n") + `</textarea>
|
<textarea class="hiddendata text_output editor">` + values.text.replace(/<br\s*\/?>/gi, "\n") + `</textarea>
|
||||||
<ul class="autocomplete-list hidden"></ul>
|
<ul class="autocomplete-list hidden"></ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="chatgpt_web_additional_info_toggle small_info">__MSG_customPrompts_show_additional_info__</div>
|
<div class="chatgpt_web_additional_info_toggle small_info">__MSG_customPrompts_show_additional_info__ [ChatGPT Web]</div>
|
||||||
<div class="chatgpt_web_additional_info">
|
<div class="chatgpt_web_additional_info">
|
||||||
<span class="field_title_us">__MSG_prefs_OptionText_chatgpt_web_model__:</span>
|
<span class="field_title_us">__MSG_prefs_OptionText_chatgpt_web_model__:</span>
|
||||||
<br>
|
<br>
|
||||||
|
|
@ -672,6 +901,14 @@ function loadPromptsList(values){
|
||||||
<br>__MSG_prefs_OptionText_chatgpt_web_custom_data_info2__
|
<br>__MSG_prefs_OptionText_chatgpt_web_custom_data_info2__
|
||||||
<br>__MSG_prefs_OptionText_CustomGPT_Warn__</i>
|
<br>__MSG_prefs_OptionText_CustomGPT_Warn__</i>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="api_additional_info_toggle small_info">__MSG_customPrompts_show_additional_info__ [API]</div>
|
||||||
|
<div class="api_additional_info" style="display:none">
|
||||||
|
<table style="width:100%; text-align:left;">
|
||||||
|
<tbody id="api_ui_container_` + values.id + `">
|
||||||
|
<tr id="api_ui_anchor_` + values.id + `"><td style="display:none"></td></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="w08"><span class="field_title_s">__MSG_customPrompts_add_to_menu__:</span>
|
<td class="w08"><span class="field_title_s">__MSG_customPrompts_add_to_menu__:</span>
|
||||||
<br>
|
<br>
|
||||||
|
|
@ -707,11 +944,14 @@ function loadPromptsList(values){
|
||||||
<span class="is_default hiddendata"></span>
|
<span class="is_default hiddendata"></span>
|
||||||
<span class="position_compose hiddendata"></span>
|
<span class="position_compose hiddendata"></span>
|
||||||
<span class="position_display hiddendata"></span>
|
<span class="position_display hiddendata"></span>
|
||||||
<div class="chatgpt_web_additional_info_show small_info"><span class="chatgpt_web_additional_info_row field_title"><i>__MSG_customPrompts_show_additional_info_show__</i></span>
|
<div class="chatgpt_web_additional_info_show small_info"><span class="chatgpt_web_additional_info_row field_title"><i>__MSG_customPrompts_show_additional_info_show__ [ChatGPT Web]</i></span>
|
||||||
<div class="chatgpt_web_additional_info_row"><span class="field_title">__MSG_prefs_OptionText_chatgpt_web_model__:</span><span class="chatgpt_web_model chatgpt_web_model_show">` + values.chatgpt_web_model + `</span></div>
|
<div class="chatgpt_web_additional_info_row"><span class="field_title">__MSG_prefs_OptionText_chatgpt_web_model__:</span><span class="chatgpt_web_model chatgpt_web_model_show">` + values.chatgpt_web_model + `</span></div>
|
||||||
<div class="chatgpt_web_additional_info_row"><span class="field_title">__MSG_prefs_OptionText_chatgpt_web_project__:</span><span class="chatgpt_web_project chatgpt_web_project_show">` + values.chatgpt_web_project + `</span></div>
|
<div class="chatgpt_web_additional_info_row"><span class="field_title">__MSG_prefs_OptionText_chatgpt_web_project__:</span><span class="chatgpt_web_project chatgpt_web_project_show">` + values.chatgpt_web_project + `</span></div>
|
||||||
<div class="chatgpt_web_additional_info_row"><span class="field_title">__MSG_prefs_OptionText_chatgpt_web_custom_gpt__:</span><span class="chatgpt_web_custom_gpt chatgpt_web_custom_gpt_show">` + values.chatgpt_web_custom_gpt + `</span></div>
|
<div class="chatgpt_web_additional_info_row"><span class="field_title">__MSG_prefs_OptionText_chatgpt_web_custom_gpt__:</span><span class="chatgpt_web_custom_gpt chatgpt_web_custom_gpt_show">` + values.chatgpt_web_custom_gpt + `</span></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="api_additional_info_show small_info">
|
||||||
|
<div class="api_additional_info_row"><span class="field_title">__MSG_prefs_Connection_type__:</span><br/><span class="api_type api_type_show">` + values.api_type + `</span></div>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btnEditItem"` + ((values.is_default == 1) ? ' disabled':'') + `>__MSG_customPrompts_btnEdit__</button>
|
<button class="btnEditItem"` + ((values.is_default == 1) ? ' disabled':'') + `>__MSG_customPrompts_btnEdit__</button>
|
||||||
|
|
@ -836,6 +1076,21 @@ function clearFields() {
|
||||||
document.getElementById('formNew').style.display = 'none';
|
document.getElementById('formNew').style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAPIValuesFromUI(prefix = '') {
|
||||||
|
let values = {};
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
const propName = `${integration}_${key}`;
|
||||||
|
const inputId = `${prefix}${propName}`;
|
||||||
|
const inputEl = document.getElementById(inputId);
|
||||||
|
if (inputEl) {
|
||||||
|
values[propName] = (inputEl.type === 'checkbox') ? inputEl.checked : inputEl.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
function inputSetError(input) {
|
function inputSetError(input) {
|
||||||
document.getElementById(input).style.borderColor = 'red';
|
document.getElementById(input).style.borderColor = 'red';
|
||||||
}
|
}
|
||||||
|
|
@ -893,8 +1148,6 @@ async function saveAll() {
|
||||||
setMessage(browser.i18n.getMessage('customPrompts_start_saving'));
|
setMessage(browser.i18n.getMessage('customPrompts_start_saving'));
|
||||||
setNothingChanged();
|
setNothingChanged();
|
||||||
if(promptsList != null) {
|
if(promptsList != null) {
|
||||||
setMessage(browser.i18n.getMessage('customPrompts_reindexing_list'));
|
|
||||||
promptsList.reIndex();
|
|
||||||
let newPrompts = promptsList.items.map(item => {
|
let newPrompts = promptsList.items.map(item => {
|
||||||
// For each item in the array, return only the '_values' part
|
// For each item in the array, return only the '_values' part
|
||||||
// console.log(">>>>>>>>>>>>>>>> item: " + JSON.stringify(item))
|
// console.log(">>>>>>>>>>>>>>>> item: " + JSON.stringify(item))
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@
|
||||||
import { prefs_default } from '../../options/mzta-options-default.js';
|
import { prefs_default } from '../../options/mzta-options-default.js';
|
||||||
import { taLogger } from '../../js/mzta-logger.js';
|
import { taLogger } from '../../js/mzta-logger.js';
|
||||||
import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
|
import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
|
||||||
import { getPlaceholders } from "../../js/mzta-placeholders.js";
|
import {
|
||||||
|
getPlaceholders,
|
||||||
|
mapPlaceholderToSuggestion
|
||||||
|
} from "../../js/mzta-placeholders.js";
|
||||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
import { isAPIKeyValue } from "../../js/mzta-utils.js";
|
import { isAPIKeyValue } from "../../js/mzta-utils.js";
|
||||||
|
|
||||||
|
|
@ -73,7 +76,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
get_calendar_event_textarea.value = get_calendar_event_prompt.text;
|
get_calendar_event_textarea.value = get_calendar_event_prompt.text;
|
||||||
get_calendar_event_reset_btn.disabled = (get_calendar_event_textarea.value === browser.i18n.getMessage('prompt_get_calendar_event_full_text'));
|
get_calendar_event_reset_btn.disabled = (get_calendar_event_textarea.value === browser.i18n.getMessage('prompt_get_calendar_event_full_text'));
|
||||||
|
|
||||||
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(p => ({command: '{%'+p.id+'%}', type: p.type}));
|
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(mapPlaceholderToSuggestion);
|
||||||
textareaAutocomplete(get_calendar_event_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
textareaAutocomplete(get_calendar_event_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@
|
||||||
import { prefs_default } from '../../options/mzta-options-default.js';
|
import { prefs_default } from '../../options/mzta-options-default.js';
|
||||||
import { taLogger } from '../../js/mzta-logger.js';
|
import { taLogger } from '../../js/mzta-logger.js';
|
||||||
import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
|
import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
|
||||||
import { getPlaceholders } from "../../js/mzta-placeholders.js";
|
import {
|
||||||
|
getPlaceholders,
|
||||||
|
mapPlaceholderToSuggestion
|
||||||
|
} from "../../js/mzta-placeholders.js";
|
||||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
import { isAPIKeyValue } from "../../js/mzta-utils.js";
|
import { isAPIKeyValue } from "../../js/mzta-utils.js";
|
||||||
|
|
||||||
|
|
@ -73,7 +76,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
get_calendar_event_textarea.value = get_calendar_event_prompt.text;
|
get_calendar_event_textarea.value = get_calendar_event_prompt.text;
|
||||||
get_calendar_event_reset_btn.disabled = (get_calendar_event_textarea.value === browser.i18n.getMessage('prompt_get_task_full_text'));
|
get_calendar_event_reset_btn.disabled = (get_calendar_event_textarea.value === browser.i18n.getMessage('prompt_get_task_full_text'));
|
||||||
|
|
||||||
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(p => ({command: '{%'+p.id+'%}', type: p.type}));
|
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(mapPlaceholderToSuggestion);
|
||||||
textareaAutocomplete(get_calendar_event_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
textareaAutocomplete(get_calendar_event_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,43 +16,40 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from '../../options/mzta-options-default.js';
|
import { prefs_default, integration_options_config } from '../../options/mzta-options-default.js';
|
||||||
import { taLogger } from '../../js/mzta-logger.js';
|
import { taLogger } from '../../js/mzta-logger.js';
|
||||||
import { getSpecialPrompts, setSpecialPrompts, loadPrompt, savePrompt, clearPromptAPI } from "../../js/mzta-prompts.js";
|
import {
|
||||||
import { getPlaceholders } from "../../js/mzta-placeholders.js";
|
getSpecialPrompts,
|
||||||
|
setSpecialPrompts
|
||||||
|
} from "../../js/mzta-prompts.js";
|
||||||
|
import {
|
||||||
|
getPlaceholders,
|
||||||
|
mapPlaceholderToSuggestion
|
||||||
|
} from "../../js/mzta-placeholders.js";
|
||||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
import { taSpamReport } from '../../js/mzta-spamreport.js';
|
import { taSpamReport } from '../../js/mzta-spamreport.js';
|
||||||
import { getAccountsList, isAPIKeyValue } from "../../js/mzta-utils.js";
|
import { getAccountsList, isAPIKeyValue } from "../../js/mzta-utils.js";
|
||||||
import {
|
import {
|
||||||
injectConnectionUI,
|
initializeSpecificIntegrationUI
|
||||||
updateWarnings,
|
|
||||||
changeConnTypeRowColor
|
|
||||||
} from "../_lib/connection-ui.js";
|
} from "../_lib/connection-ui.js";
|
||||||
|
|
||||||
let autocompleteSuggestions = [];
|
let autocompleteSuggestions = [];
|
||||||
let taLog = new taLogger("mzta-spamfilter-page",true);
|
let taLog = new taLogger("mzta-spamfilter-page",true);
|
||||||
taSpamReport.logger = taLog;
|
taSpamReport.logger = taLog;
|
||||||
|
|
||||||
let conntype_select_id = 'spamfilter_connection_type';
|
|
||||||
let model_prefix = 'spamfilter_';
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
try {
|
let specialPrompts = await getSpecialPrompts();
|
||||||
await injectConnectionUI({
|
let spamfilter_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_spamfilter');
|
||||||
afterTrId: 'connection_ui_anchor',
|
|
||||||
tr_class: 'specific_integration_sub',
|
await initializeSpecificIntegrationUI({
|
||||||
selectId: conntype_select_id,
|
prefix: 'spamfilter',
|
||||||
modelId_prefix: model_prefix,
|
promptId: 'prompt_spamfilter',
|
||||||
no_chatgpt_web: true,
|
taLog: taLog,
|
||||||
taLog: taLog
|
restoreOptionsCallback: restoreOptions
|
||||||
});
|
});
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to inject connection UI (spamfilter)', e);
|
|
||||||
}
|
|
||||||
|
|
||||||
i18n.updateDocument();
|
i18n.updateDocument();
|
||||||
await restoreOptions();
|
|
||||||
|
|
||||||
document.querySelectorAll(".option-input").forEach(element => {
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
element.addEventListener("change", saveOptions);
|
element.addEventListener("change", saveOptions);
|
||||||
|
|
@ -61,55 +58,11 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
document.getElementById("spamfilter_threshold").addEventListener("input", check_spamfilter_threshold);
|
document.getElementById("spamfilter_threshold").addEventListener("input", check_spamfilter_threshold);
|
||||||
check_spamfilter_threshold({target: document.getElementById("spamfilter_threshold")});
|
check_spamfilter_threshold({target: document.getElementById("spamfilter_threshold")});
|
||||||
|
|
||||||
// Bind prompt API updates to connection type and model selects
|
|
||||||
document.querySelectorAll(".option-input-model").forEach(element => {
|
|
||||||
element.addEventListener("change", updatePromptAPIInfo);
|
|
||||||
});
|
|
||||||
const conntype_el = document.getElementById(conntype_select_id);
|
|
||||||
if (conntype_el) {
|
|
||||||
conntype_el.addEventListener('change', updatePromptAPIInfo);
|
|
||||||
const conntype_row = document.getElementById(conntype_select_id + '_tr');
|
|
||||||
if (conntype_row) changeConnTypeRowColor(conntype_row, conntype_el);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Specific integration toggle behavior
|
|
||||||
const spamfilter_use_specific_integration_el = document.getElementById('spamfilter_use_specific_integration');
|
|
||||||
let prefs_spamfilter_init = await browser.storage.sync.get({ spamfilter_enabled_accounts: [], connection_type: 'chatgpt_web' });
|
|
||||||
if(prefs_spamfilter_init.connection_type == 'chatgpt_web'){
|
|
||||||
spamfilter_use_specific_integration_el.checked = true;
|
|
||||||
spamfilter_use_specific_integration_el.dispatchEvent(new Event('change'));
|
|
||||||
spamfilter_use_specific_integration_el.disabled = true;
|
|
||||||
}
|
|
||||||
const conntype_end_el = document.getElementById('connection_ui_end');
|
|
||||||
const conntype_row = document.getElementById(conntype_select_id + '_tr');
|
|
||||||
spamfilter_use_specific_integration_el.addEventListener('change', async (event) => {
|
|
||||||
document.querySelectorAll('.specific_integration_sub').forEach(tr => {
|
|
||||||
tr.style.display = event.target.checked && tr.classList.contains('conntype_' + conntype_el.value) ? 'table-row' : 'none';
|
|
||||||
});
|
|
||||||
if (conntype_row) conntype_row.style.display = event.target.checked ? 'table-row' : 'none';
|
|
||||||
if (conntype_end_el) conntype_end_el.style.display = event.target.checked ? 'table-row' : 'none';
|
|
||||||
if(!event.target.checked){
|
|
||||||
await clearPromptAPI('prompt_spamfilter');
|
|
||||||
}else{
|
|
||||||
updatePromptAPIInfo();
|
|
||||||
}
|
|
||||||
if (conntype_row) changeConnTypeRowColor(conntype_row, conntype_el);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Initialize visibility per current toggle value
|
|
||||||
document.querySelectorAll('.specific_integration_sub').forEach(tr => {
|
|
||||||
tr.style.display = spamfilter_use_specific_integration_el.checked && tr.classList.contains('conntype_' + conntype_el.value) ? 'table-row' : 'none';
|
|
||||||
});
|
|
||||||
if (conntype_row) conntype_row.style.display = spamfilter_use_specific_integration_el.checked ? 'table-row' : 'none';
|
|
||||||
if (conntype_end_el) conntype_end_el.style.display = spamfilter_use_specific_integration_el.checked ? 'table-row' : 'none';
|
|
||||||
|
|
||||||
let spamfilter_textarea = document.getElementById('spamfilter_prompt_text');
|
let spamfilter_textarea = document.getElementById('spamfilter_prompt_text');
|
||||||
let spamfilter_save_btn = document.getElementById('btn_save_prompt');
|
let spamfilter_save_btn = document.getElementById('btn_save_prompt');
|
||||||
let spamfilter_reset_btn = document.getElementById('btn_reset_prompt');
|
let spamfilter_reset_btn = document.getElementById('btn_reset_prompt');
|
||||||
|
|
||||||
let specialPrompts = await getSpecialPrompts();
|
|
||||||
let spamfilter_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_spamfilter');
|
|
||||||
|
|
||||||
spamfilter_textarea.addEventListener('input', (event) => {
|
spamfilter_textarea.addEventListener('input', (event) => {
|
||||||
spamfilter_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_spamfilter_full_text'));
|
spamfilter_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_spamfilter_full_text'));
|
||||||
spamfilter_save_btn.disabled = (event.target.value === spamfilter_prompt.text);
|
spamfilter_save_btn.disabled = (event.target.value === spamfilter_prompt.text);
|
||||||
|
|
@ -141,7 +94,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
spamfilter_textarea.value = spamfilter_prompt.text;
|
spamfilter_textarea.value = spamfilter_prompt.text;
|
||||||
spamfilter_reset_btn.disabled = (spamfilter_textarea.value === browser.i18n.getMessage('prompt_spamfilter_full_text'));
|
spamfilter_reset_btn.disabled = (spamfilter_textarea.value === browser.i18n.getMessage('prompt_spamfilter_full_text'));
|
||||||
|
|
||||||
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(p => ({command: '{%'+p.id+'%}', type: p.type}));
|
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(mapPlaceholderToSuggestion);
|
||||||
textareaAutocomplete(spamfilter_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
textareaAutocomplete(spamfilter_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
||||||
|
|
||||||
//Accounts manager
|
//Accounts manager
|
||||||
|
|
@ -199,9 +152,6 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
loadSpamReport();
|
loadSpamReport();
|
||||||
updateWarnings(model_prefix);
|
|
||||||
// Sync prompt API/model once on load
|
|
||||||
updatePromptAPIInfo();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function check_spamfilter_threshold(event) {
|
function check_spamfilter_threshold(event) {
|
||||||
|
|
@ -231,20 +181,6 @@ async function loadSpamReport(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updatePromptAPIInfo(){
|
|
||||||
const conntypeEl = document.getElementById(conntype_select_id);
|
|
||||||
if (!conntypeEl || !conntypeEl.value) return;
|
|
||||||
const conntype = conntypeEl.value;
|
|
||||||
const model_value = conntype.substring(0, conntype.length - 4) + '_model';
|
|
||||||
const modelEl = document.getElementById(model_prefix + model_value);
|
|
||||||
if (!modelEl) return;
|
|
||||||
const model = modelEl.value;
|
|
||||||
let spamfilter_prompt = await loadPrompt('prompt_spamfilter');
|
|
||||||
if (!spamfilter_prompt) return;
|
|
||||||
spamfilter_prompt.api = conntype;
|
|
||||||
spamfilter_prompt.model = model;
|
|
||||||
await savePrompt(spamfilter_prompt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to populate the table
|
// Function to populate the table
|
||||||
function populateTable(data) {
|
function populateTable(data) {
|
||||||
|
|
@ -372,5 +308,23 @@ async function restoreOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let getting = await browser.storage.sync.get(prefs_default);
|
let getting = await browser.storage.sync.get(prefs_default);
|
||||||
|
|
||||||
|
let specialPrompts = await getSpecialPrompts();
|
||||||
|
let spamfilter_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_spamfilter');
|
||||||
|
|
||||||
|
if (spamfilter_prompt) {
|
||||||
|
if (spamfilter_prompt.api && spamfilter_prompt.api !== '') {
|
||||||
|
getting['spamfilter_connection_type'] = spamfilter_prompt.api;
|
||||||
|
}
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
const propName = `${integration}_${key}`;
|
||||||
|
if (spamfilter_prompt[propName] !== undefined) {
|
||||||
|
getting[`spamfilter_${propName}`] = spamfilter_prompt[propName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setCurrentChoice(getting);
|
setCurrentChoice(getting);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue