From 3adb5faab266e396ee6f594fdae27bfb46ec5286 Mon Sep 17 00:00:00 2001 From: mic Date: Sun, 28 Dec 2025 23:27:27 +0100 Subject: [PATCH 01/12] working on a dynamic special prompts settings managing system --- js/mzta-utils.js | 37 +++++++---- mzta-background.js | 16 +++-- options/mzta-options-default.js | 65 ++++++++++++------- options/mzta-options.js | 19 ++++-- pages/_lib/connection-ui.js | 99 +++++++++++++++++++++++++++++ pages/addtags/mzta-add-tags.js | 86 +++---------------------- pages/spamfilter/mzta-spamfilter.js | 90 ++++---------------------- 7 files changed, 207 insertions(+), 205 deletions(-) diff --git a/js/mzta-utils.js b/js/mzta-utils.js index 90a61123..16a639f3 100644 --- a/js/mzta-utils.js +++ b/js/mzta-utils.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -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 export const ChatGPTWeb_models = ['gpt-5','gpt-5-instant','gpt-5-t-mini','gpt-5-thinking']; // List of models available in ChatGPT Web @@ -626,16 +626,31 @@ export function isAPIKeyValue(id){ return id=="chatgpt_api_key" || id=="openai_comp_api_key" || id=="google_gemini_api_key" || id=="anthropic_api_key"; } -export function getConnectionType(conntype, prompt, use_promptspecific_api = true) { - if(!use_promptspecific_api) { - return conntype; - } - // console.log(">>>>>>>>>>> getConnectionType conntype: " + conntype + " prompt: " + JSON.stringify(prompt)); - if (prompt?.api != null && prompt.api !== '') { - return prompt.api; - } else { - return conntype; - } +export function getConnectionType(prefsOrType, prompt, prefixOrSpecific = null) { + let defaultType = ''; + let specificType = ''; + + if (typeof prefsOrType === 'object' && prefsOrType !== null) { + // Nuova firma: (prefs, prompt, prefix) + defaultType = prefsOrType.connection_type; + if (typeof prefixOrSpecific === 'string' && prefixOrSpecific) { + const prefix = prefixOrSpecific; + const useSpecific = getDynamicSettingValue(prefsOrType, prefix, 'use_specific_integration'); + if (useSpecific) { + specificType = getDynamicSettingValue(prefsOrType, prefix, 'connection_type'); + } + } + } else { + // Vecchia firma / Uso diretto: (connection_type_string, prompt, [specific_type_string]) + defaultType = prefsOrType; + 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() { diff --git a/mzta-background.js b/mzta-background.js index e1d63747..a29286e7 100644 --- a/mzta-background.js +++ b/mzta-background.js @@ -17,7 +17,11 @@ */ 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 { taLogger } from './js/mzta-logger.js'; import { @@ -799,10 +803,7 @@ async function reload_pref_init(){ dynamic_menu_force_enter: prefs_default.dynamic_menu_force_enter, add_tags_context_menu: prefs_default.add_tags_context_menu, spamfilter_context_menu: prefs_default.spamfilter_context_menu, - add_tags_use_specific_integration: prefs_default.add_tags_use_specific_integration, - 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 + ...getDynamicSettingsDefaults(['use_specific_integration', 'connection_type']) }); _process_incoming = prefs_init.add_tags_auto || prefs_init.spamfilter; _sparks_presence = await checkSparksPresence(); @@ -1034,8 +1035,7 @@ async function processEmails(messages, addTagsAuto, spamFilter) { add_tags_auto_uselist: prefs_default.add_tags_auto_uselist, add_tags_auto_uselist_list: prefs_default.add_tags_auto_uselist_list, spamfilter_enabled_accounts: prefs_default.spamfilter_enabled_accounts, - add_tags_use_specific_integration: prefs_default.add_tags_use_specific_integration, - spamfilter_use_specific_integration: prefs_default.spamfilter_use_specific_integration, + ...getDynamicSettingsDefaults(['use_specific_integration']), do_debug: prefs_default.do_debug, }); @@ -1083,6 +1083,7 @@ async function processEmails(messages, addTagsAuto, spamFilter) { let cmd_addTags = new mzta_specialCommand({ 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.connection_type, curr_prompt_add_tags, getDynamicSettingValue(prefs_aats, 'add_tags', 'use_specific_integration')), custom_model: curr_prompt_add_tags.model ? curr_prompt_add_tags.model : '', do_debug: prefs_aats.do_debug }); @@ -1122,6 +1123,7 @@ async function processEmails(messages, addTagsAuto, spamFilter) { let cmd_spamfilter = new mzta_specialCommand({ prompt: specialFullPrompt_spamfilter, llm: getConnectionType(prefs_aats.connection_type, curr_prompt_spamfilter, prefs_aats.spamfilter_use_specific_integration), + llm: getConnectionType(prefs_aats.connection_type, curr_prompt_spamfilter, getDynamicSettingValue(prefs_aats, 'spamfilter', 'use_specific_integration')), custom_model: curr_prompt_spamfilter.model ? curr_prompt_spamfilter.model : '', do_debug: prefs_aats.do_debug }); diff --git a/options/mzta-options-default.js b/options/mzta-options-default.js index 5cfc6e65..fada52a2 100644 --- a/options/mzta-options-default.js +++ b/options/mzta-options-default.js @@ -16,6 +16,46 @@ * along with this program. If not, see . */ +const special_prompts_with_integration = ['add_tags', 'spamfilter']; + +const integration_settings_template = { + use_specific_integration: false, + connection_type: 'chatgpt_api', + chatgpt_model: '', + ollama_model: '', + openai_comp_model: '', + google_gemini_model: '', + anthropic_model: '', + chatgpt_api_temperature: '', + ollama_temperature: '', + openai_comp_temperature: '', + google_gemini_temperature: '', + anthropic_temperature: '', +}; + +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 = { do_debug: false, chatgpt_win_height: 800, @@ -73,18 +113,6 @@ export const prefs_default = { add_tags_auto_uselist_list: '', add_tags_context_menu: true, 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: '', - add_tags_chatgpt_api_temperature: '', - add_tags_ollama_temperature: '', - add_tags_openai_comp_temperature: '', - add_tags_google_gemini_temperature: '', - add_tags_anthropic_temperature: '', get_calendar_event: true, get_task: true, calendar_enforce_timezone: false, @@ -93,16 +121,5 @@ export const prefs_default = { spamfilter_threshold: 70, spamfilter_context_menu: true, 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: '', - spamfilter_chatgpt_api_temperature: '', - spamfilter_ollama_temperature: '', - spamfilter_openai_comp_temperature: '', - spamfilter_google_gemini_temperature: '', - spamfilter_anthropic_temperature: '', + ...generated_prefs } diff --git a/options/mzta-options.js b/options/mzta-options.js index 92d2989a..2f8c4424 100644 --- a/options/mzta-options.js +++ b/options/mzta-options.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -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 { ChatGPTWeb_models, @@ -127,7 +127,11 @@ function disable_MaxPromptLength(){ function disable_AddTags(prefs_opt){ let add_tags = document.getElementById('add_tags'); 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); add_tags.checked = add_tags_disabled ? false : 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){ let spamfilter = document.getElementById('spamfilter'); 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; spamfilter.checked = spamfilter_disabled ? false : spamfilter.checked; if(!spamfilter.checked){ @@ -302,10 +310,7 @@ document.addEventListener('DOMContentLoaded', async () => { }); let prefs_opt = await browser.storage.sync.get({ - add_tags_use_specific_integration: prefs_default.add_tags_use_specific_integration, - 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, + ...getDynamicSettingsDefaults(['use_specific_integration', 'connection_type']) }); let conntype_select = document.getElementById("connection_type"); diff --git a/pages/_lib/connection-ui.js b/pages/_lib/connection-ui.js index f4179e02..b42382dc 100644 --- a/pages/_lib/connection-ui.js +++ b/pages/_lib/connection-ui.js @@ -28,6 +28,7 @@ import { sanitizeChatGPTWebCustomData } from '../../js/mzta-utils.js'; import { openAICompConfigs } from '../../js/api/openai_comp_configs.js'; +import { loadPrompt, savePrompt, clearPromptAPI } from '../../js/mzta-prompts.js'; export const varConnectionUI = { permission_all_urls: false @@ -944,6 +945,104 @@ export async function injectConnectionUI({ }; } +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 model_value = conntype.substring(0, conntype.length - 4) + '_model'; + let temperature_value = conntype.substring(0, conntype.length - 4) + '_temperature'; + + let prompt = await loadPrompt(promptId); + if(!prompt) return; + + prompt.api = conntype; + prompt.model = document.getElementById(model_prefix + model_value)?.value || ''; + prompt.temperature = document.getElementById(model_prefix + temperature_value)?.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(".option-input-specific").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 diff --git a/pages/addtags/mzta-add-tags.js b/pages/addtags/mzta-add-tags.js index b21d8671..e472370b 100644 --- a/pages/addtags/mzta-add-tags.js +++ b/pages/addtags/mzta-add-tags.js @@ -20,10 +20,7 @@ import { prefs_default } from '../../options/mzta-options-default.js'; import { taLogger } from '../../js/mzta-logger.js'; import { getSpecialPrompts, - setSpecialPrompts, - loadPrompt, - savePrompt, - clearPromptAPI + setSpecialPrompts } from "../../js/mzta-prompts.js"; import { getPlaceholders, @@ -40,76 +37,26 @@ import { isAPIKeyValue } from "../../js/mzta-utils.js"; import { - injectConnectionUI, - updateWarnings, - changeConnTypeRowColor + initializeSpecificIntegrationUI } from "../_lib/connection-ui.js"; let autocompleteSuggestions = []; 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 () => { - 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 (add-tags)', e); - } + await initializeSpecificIntegrationUI({ + prefix: 'add_tags', + promptId: 'prompt_add_tags', + taLog: taLog, + restoreOptionsCallback: restoreOptions + }); + i18n.updateDocument(); - await restoreOptions(); document.querySelectorAll(".option-input").forEach(element => { element.addEventListener("change", saveOptions); }); - - document.querySelectorAll(".option-input-specific").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' }); - 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_save_btn = document.getElementById('btn_save_prompt'); @@ -260,8 +207,6 @@ document.addEventListener('DOMContentLoaded', async () => { let checkboxes = document.querySelectorAll('.accountCheckbox'); checkboxes.forEach(checkbox => checkbox.checked = false); }); - - updateWarnings(model_prefix); }); @@ -293,19 +238,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 temperature_value = conntype.substring(0, conntype.length - 4) + '_temperature'; - // 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 = document.getElementById(model_prefix + model_value).value; - add_tags_prompt.temperature = document.getElementById(model_prefix + temperature_value).value; - // 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 diff --git a/pages/spamfilter/mzta-spamfilter.js b/pages/spamfilter/mzta-spamfilter.js index 5a7e3505..0e22f435 100644 --- a/pages/spamfilter/mzta-spamfilter.js +++ b/pages/spamfilter/mzta-spamfilter.js @@ -18,7 +18,10 @@ import { prefs_default } from '../../options/mzta-options-default.js'; import { taLogger } from '../../js/mzta-logger.js'; -import { getSpecialPrompts, setSpecialPrompts, loadPrompt, savePrompt, clearPromptAPI } from "../../js/mzta-prompts.js"; +import { + getSpecialPrompts, + setSpecialPrompts +} from "../../js/mzta-prompts.js"; import { getPlaceholders, mapPlaceholderToSuggestion @@ -27,35 +30,22 @@ import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js import { taSpamReport } from '../../js/mzta-spamreport.js'; import { getAccountsList, isAPIKeyValue } from "../../js/mzta-utils.js"; import { - injectConnectionUI, - updateWarnings, - changeConnTypeRowColor + initializeSpecificIntegrationUI } from "../_lib/connection-ui.js"; let autocompleteSuggestions = []; let taLog = new taLogger("mzta-spamfilter-page",true); taSpamReport.logger = taLog; -let conntype_select_id = 'spamfilter_connection_type'; -let model_prefix = 'spamfilter_'; - document.addEventListener('DOMContentLoaded', async () => { - - 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 (spamfilter)', e); - } + await initializeSpecificIntegrationUI({ + prefix: 'spamfilter', + promptId: 'prompt_spamfilter', + taLog: taLog, + restoreOptionsCallback: restoreOptions + }); i18n.updateDocument(); - await restoreOptions(); document.querySelectorAll(".option-input").forEach(element => { element.addEventListener("change", saveOptions); @@ -64,47 +54,6 @@ document.addEventListener('DOMContentLoaded', async () => { document.getElementById("spamfilter_threshold").addEventListener("input", check_spamfilter_threshold); check_spamfilter_threshold({target: document.getElementById("spamfilter_threshold")}); - // Bind prompt API updates to connection type and model selects - document.querySelectorAll(".option-input-specific").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_save_btn = document.getElementById('btn_save_prompt'); @@ -202,9 +151,6 @@ document.addEventListener('DOMContentLoaded', async () => { }); loadSpamReport(); - updateWarnings(model_prefix); - // Sync prompt API/model once on load - updatePromptAPIInfo(); }); function check_spamfilter_threshold(event) { @@ -234,20 +180,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 populateTable(data) { From 3ef13eec9b383693455c87238a119f394bfca4ea Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 11:20:11 +0100 Subject: [PATCH 02/12] using a dynamic generation for all integration settings --- options/mzta-options-default.js | 84 ++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/options/mzta-options-default.js b/options/mzta-options-default.js index fada52a2..968214b5 100644 --- a/options/mzta-options-default.js +++ b/options/mzta-options-default.js @@ -18,21 +18,57 @@ const special_prompts_with_integration = ['add_tags', 'spamfilter']; +export const integration_options_config = { + chatgpt: { + api_key: '', + model: '', + developer_messages: '', + api_temperature: '', + api_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', - chatgpt_model: '', - ollama_model: '', - openai_comp_model: '', - google_gemini_model: '', - anthropic_model: '', - chatgpt_api_temperature: '', - ollama_temperature: '', - openai_comp_temperature: '', - google_gemini_temperature: '', - anthropic_temperature: '', }; +for (const [integration, options] of Object.entries(integration_options_config)) { + for (const [key, value] of Object.entries(options)) { + integration_settings_template[`${integration}_${key}`] = value; + } +} + let generated_prefs = {}; special_prompts_with_integration.forEach(prompt_prefix => { @@ -57,6 +93,7 @@ export function getDynamicSettingValue(prefs, prefix, settingName) { } export const prefs_default = { + ...integration_settings_template, do_debug: false, chatgpt_win_height: 800, chatgpt_win_width: 700, @@ -69,33 +106,6 @@ export const prefs_default = { chatgpt_web_tempchat: false, chatgpt_web_project: '', chatgpt_web_custom_gpt: '', - chatgpt_api_key: '', - chatgpt_api_store: false, - chatgpt_model: '', - chatgpt_developer_messages: '', - chatgpt_api_temperature: '', - ollama_host: '', - ollama_model: '', - ollama_num_ctx: 0, - ollama_temperature: '', - 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', - openai_comp_temperature: '', - google_gemini_api_key: '', - google_gemini_model: '', - google_gemini_system_instruction: '', - google_gemini_thinking_budget: '', - google_gemini_temperature: '', - anthropic_api_key: '', - anthropic_model: '', - anthropic_version: '2023-06-01', - anthropic_max_tokens: 4096, - anthropic_system_prompt: '', - anthropic_temperature: '', dynamic_menu_force_enter: false, dynamic_menu_order_alphabet: true, placeholders_use_default_value: false, From 39a4cab4e2693a16999197ed3a2dda8e7699ebc8 Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 12:09:31 +0100 Subject: [PATCH 03/12] all integration settings are saved separately for the special prompts --- pages/_lib/connection-ui.js | 108 +++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 50 deletions(-) diff --git a/pages/_lib/connection-ui.js b/pages/_lib/connection-ui.js index b42382dc..fb4735d7 100644 --- a/pages/_lib/connection-ui.js +++ b/pages/_lib/connection-ui.js @@ -138,7 +138,7 @@ export async function injectConnectionUI({
@@ -178,7 +178,7 @@ export async function injectConnectionUI({ @@ -191,7 +191,7 @@ export async function injectConnectionUI({ @@ -203,7 +203,7 @@ export async function injectConnectionUI({
@@ -243,7 +243,7 @@ export async function injectConnectionUI({ @@ -257,7 +257,7 @@ export async function injectConnectionUI({ @@ -269,7 +269,7 @@ export async function injectConnectionUI({ @@ -313,7 +313,7 @@ export async function injectConnectionUI({ @@ -324,7 +324,7 @@ export async function injectConnectionUI({ @@ -347,7 +347,7 @@ export async function injectConnectionUI({ @@ -366,7 +366,7 @@ export async function injectConnectionUI({ @@ -379,7 +379,7 @@ export async function injectConnectionUI({
@@ -406,7 +406,7 @@ export async function injectConnectionUI({ @@ -431,7 +431,7 @@ export async function injectConnectionUI({
@@ -471,7 +471,7 @@ export async function injectConnectionUI({ @@ -484,7 +484,7 @@ export async function injectConnectionUI({ @@ -493,7 +493,7 @@ export async function injectConnectionUI({ __MSG_prefs_OptionText_anthropic_max_tokens__ @@ -514,6 +514,8 @@ export async function injectConnectionUI({ } }); + const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`; + // Bindings // 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); }; @@ -536,15 +538,15 @@ export async function injectConnectionUI({ conntype_select.addEventListener("change", (ev) => warn_Anthropic_VersionEmpty(modelId_prefix)); document.getElementById("chatgpt_web_project").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("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("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("anthropic_version").addEventListener("change", (ev) => warn_Anthropic_VersionEmpty(modelId_prefix)); - document.getElementById("openai_comp_host").addEventListener("input", resetOpenAICompConfigs); - document.getElementById("openai_comp_chat_name").addEventListener("input", resetOpenAICompConfigs); - document.getElementById("openai_comp_use_v1").addEventListener("input", resetOpenAICompConfigs); + document.getElementById(getPrefixedId("chatgpt_api_key")).addEventListener("change", (ev) => warn_ChatGPT_APIKeyEmpty(modelId_prefix)); + document.getElementById(getPrefixedId("ollama_host")).addEventListener("change", (ev) => warn_Ollama_HostEmpty(modelId_prefix)); + document.getElementById(getPrefixedId("openai_comp_host")).addEventListener("change", (ev) => warn_OpenAIComp_HostEmpty(modelId_prefix)); + document.getElementById(getPrefixedId("google_gemini_api_key")).addEventListener("change", (ev) => warn_GoogleGemini_APIKeyEmpty(modelId_prefix)); + document.getElementById(getPrefixedId("anthropic_api_key")).addEventListener("change", (ev) => warn_Anthropic_APIKeyEmpty(modelId_prefix)); + document.getElementById(getPrefixedId("anthropic_version")).addEventListener("change", (ev) => warn_Anthropic_VersionEmpty(modelId_prefix)); + document.getElementById(getPrefixedId("openai_comp_host")).addEventListener("input", () => resetOpenAICompConfigs(modelId_prefix)); + document.getElementById(getPrefixedId("openai_comp_chat_name")).addEventListener("input", () => resetOpenAICompConfigs(modelId_prefix)); + document.getElementById(getPrefixedId("openai_comp_use_v1")).addEventListener("input", () => resetOpenAICompConfigs(modelId_prefix)); showConnectionOptions(conntype_select); loadOpenAICompConfigs(); @@ -555,7 +557,7 @@ export async function injectConnectionUI({ warn_Anthropic_APIKeyEmpty(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 icon_img_chatgpt_api_key = document.getElementById('pwd-icon_chatgpt_api_key'); @@ -566,7 +568,7 @@ export async function injectConnectionUI({ 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 icon_img_google_gemini_api_key = document.getElementById('pwd-icon_google_gemini_api_key'); @@ -577,7 +579,7 @@ export async function injectConnectionUI({ 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 icon_img_openai_comp_api_key = document.getElementById('pwd-icon_openai_comp_api_key'); @@ -588,7 +590,7 @@ export async function injectConnectionUI({ 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 icon_img_anthropic_api_key = document.getElementById('pwd-icon_anthropic_api_key'); @@ -632,20 +634,20 @@ export async function injectConnectionUI({ if (!confirm(browser.i18n.getMessage('OpenAIComp_Configs_ConfirmApply', config.name))) { 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 const openaiCompModelSelect = getModelEl('openai_comp_model', modelId_prefix); openaiCompModelSelect.value = ''; while (openaiCompModelSelect.options.length > 0) { openaiCompModelSelect.remove(0); } - document.getElementById('openai_comp_use_v1').checked = !!config.use_v1; - document.getElementById('openai_comp_chat_name').value = config.chat_name || ''; + document.getElementById(getPrefixedId('openai_comp_use_v1')).checked = !!config.use_v1; + document.getElementById(getPrefixedId('openai_comp_chat_name')).value = config.chat_name || ''; // 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 })); - document.getElementById('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_use_v1')).dispatchEvent(new Event('change', { bubbles: true })); + document.getElementById(getPrefixedId('openai_comp_chat_name')).dispatchEvent(new Event('change', { bubbles: true })); } }); @@ -662,7 +664,7 @@ export async function injectConnectionUI({ document.getElementById('btnUpdateChatGPTModels').addEventListener('click', async () => { document.getElementById('chatgpt_model_fetch_loading').style.display = 'inline'; 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/*"] }); if(!granted){ @@ -711,7 +713,7 @@ export async function injectConnectionUI({ document.getElementById('btnUpdateGoogleGeminiModels').addEventListener('click', async () => { document.getElementById('google_gemini_model_fetch_loading').style.display = 'inline'; 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) => { if(!data.ok){ @@ -753,7 +755,7 @@ export async function injectConnectionUI({ document.getElementById('btnUpdateOllamaModels').addEventListener('click', async () => { document.getElementById('ollama_model_fetch_loading').style.display = 'inline'; let ollama = new Ollama({ - host: document.getElementById("ollama_host").value, + host: document.getElementById(getPrefixedId("ollama_host")).value, }); try { let data = await ollama.fetchModels(); @@ -812,9 +814,9 @@ export async function injectConnectionUI({ document.getElementById('btnUpdateOpenAICompModels').addEventListener('click', async () => { document.getElementById('openai_comp_model_fetch_loading').style.display = 'inline'; let openai_comp = new OpenAIComp({ - host: document.getElementById("openai_comp_host").value, - apiKey: document.getElementById("openai_comp_api_key").value, - use_v1: document.getElementById("openai_comp_use_v1").checked, + host: document.getElementById(getPrefixedId("openai_comp_host")).value, + apiKey: document.getElementById(getPrefixedId("openai_comp_api_key")).value, + use_v1: document.getElementById(getPrefixedId("openai_comp_use_v1")).checked, }); openai_comp.fetchModels().then((data) => { if(!data.ok){ @@ -857,8 +859,8 @@ export async function injectConnectionUI({ document.getElementById('btnUpdateAnthropicModels').addEventListener('click', async () => { document.getElementById('anthropic_model_fetch_loading').style.display = 'inline'; let anthropic = new Anthropic({ - apiKey: document.getElementById("anthropic_api_key").value, - version: document.getElementById("anthropic_version").value, + apiKey: document.getElementById(getPrefixedId("anthropic_api_key")).value, + version: document.getElementById(getPrefixedId("anthropic_version")).value, }); let granted = await messenger.permissions.request({ origins: ["https://*.anthropic.com/*"] }); if(!granted){ @@ -1164,7 +1166,8 @@ function populateConnectionTypeOptions(selectId, no_chatgpt_web = false) { } function warn_ChatGPT_APIKeyEmpty(modelId_prefix) { - let apiKeyInput = document.getElementById('chatgpt_api_key'); + const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`; + let apiKeyInput = document.getElementById(getPrefixedId('chatgpt_api_key')); let btnFetchChatGPTModels = document.getElementById('btnUpdateChatGPTModels'); let modelChatGPT = getModelEl('chatgpt_model', modelId_prefix); if(apiKeyInput.value === ''){ @@ -1186,7 +1189,8 @@ function warn_ChatGPT_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 apiKeyInput = document.getElementById(getPrefixedId('google_gemini_api_key')); let btnFetchGoogleGeminiModels = document.getElementById('btnUpdateGoogleGeminiModels'); let modelGoogleGemini = getModelEl('google_gemini_model', modelId_prefix); if(apiKeyInput.value === ''){ @@ -1208,7 +1212,8 @@ function warn_GoogleGemini_APIKeyEmpty(modelId_prefix) { } function warn_Ollama_HostEmpty(modelId_prefix) { - let hostInput = document.getElementById('ollama_host'); + const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`; + let hostInput = document.getElementById(getPrefixedId('ollama_host')); let btnFetchOllamaModels = document.getElementById('btnUpdateOllamaModels'); let modelOllama = getModelEl('ollama_model', modelId_prefix); if(hostInput.value === ''){ @@ -1230,7 +1235,8 @@ function warn_Ollama_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 hostInput = document.getElementById(getPrefixedId('openai_comp_host')); let btnUpdateOpenAICompModels = document.getElementById('btnUpdateOpenAICompModels'); let modelOpenAIComp = getModelEl('openai_comp_model', modelId_prefix); if(hostInput.value === ''){ @@ -1252,7 +1258,8 @@ function warn_OpenAIComp_HostEmpty(modelId_prefix) { } function warn_Anthropic_APIKeyEmpty(modelId_prefix) { - let apiKeyInput = document.getElementById('anthropic_api_key'); + const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`; + let apiKeyInput = document.getElementById(getPrefixedId('anthropic_api_key')); let btnFetchAnthropicModels = document.getElementById('btnUpdateAnthropicModels'); let modelAnthropic = getModelEl('anthropic_model', modelId_prefix); if(apiKeyInput.value === ''){ @@ -1274,7 +1281,8 @@ function warn_Anthropic_APIKeyEmpty(modelId_prefix) { } function warn_Anthropic_VersionEmpty(modelId_prefix) { - let versionInput = document.getElementById('anthropic_version'); + const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`; + let versionInput = document.getElementById(getPrefixedId('anthropic_version')); let btnFetchAnthropicModels = document.getElementById('btnUpdateAnthropicModels'); let modelAnthropic = getModelEl('anthropic_model', modelId_prefix); if(versionInput.value === ''){ From a7d42530fc67cae4886f1d8989ba8bc90cfe8b49 Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 21:31:31 +0100 Subject: [PATCH 04/12] improved isAPIKeyValue method --- js/mzta-utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/mzta-utils.js b/js/mzta-utils.js index 16a639f3..49abe49f 100644 --- a/js/mzta-utils.js +++ b/js/mzta-utils.js @@ -623,7 +623,7 @@ export function extractJsonObject(inputString) { } 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(prefsOrType, prompt, prefixOrSpecific = null) { From 2dcb661368049d8f2017cd8fd618863af9e7a62b Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 21:39:40 +0100 Subject: [PATCH 05/12] add_tags updating settings values from the special prompt --- pages/addtags/mzta-add-tags.js | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/pages/addtags/mzta-add-tags.js b/pages/addtags/mzta-add-tags.js index e472370b..17c3dffa 100644 --- a/pages/addtags/mzta-add-tags.js +++ b/pages/addtags/mzta-add-tags.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -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 { getSpecialPrompts, @@ -44,6 +44,25 @@ let autocompleteSuggestions = []; let taLog = new taLogger("mzta-addtags-page",true); document.addEventListener('DOMContentLoaded', async () => { + + let specialPrompts = await getSpecialPrompts(); + let addtags_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_add_tags'); + + if (addtags_prompt && addtags_prompt.api && addtags_prompt.api !== '') { + let update_prefs = {}; + update_prefs['add_tags_connection_type'] = addtags_prompt.api; + + let integration = addtags_prompt.api.replace('_api', ''); + if (integration_options_config && integration_options_config[integration]) { + 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', @@ -62,9 +81,6 @@ document.addEventListener('DOMContentLoaded', async () => { let addtags_save_btn = document.getElementById('btn_save_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_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_add_tags_full_text')); addtags_save_btn.disabled = (event.target.value === addtags_prompt.text); From 3816d89bd0d6f0b65b7318d55db2415d1974bf81 Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 21:41:31 +0100 Subject: [PATCH 06/12] dynamically saving special prompts api settings --- pages/_lib/connection-ui.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/pages/_lib/connection-ui.js b/pages/_lib/connection-ui.js index fb4735d7..af598c8c 100644 --- a/pages/_lib/connection-ui.js +++ b/pages/_lib/connection-ui.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import { prefs_default } from '../../options/mzta-options-default.js'; +import { 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 { OpenAIComp } from '../../js/api/openai_comp.js' @@ -985,15 +985,22 @@ export async function initializeSpecificIntegrationUI({ // Helper to update prompt const _updatePrompt = async () => { let conntype = conntype_el.value; - let model_value = conntype.substring(0, conntype.length - 4) + '_model'; - let temperature_value = conntype.substring(0, conntype.length - 4) + '_temperature'; + let integration = conntype.replace('_api', ''); let prompt = await loadPrompt(promptId); if(!prompt) return; prompt.api = conntype; - prompt.model = document.getElementById(model_prefix + model_value)?.value || ''; - prompt.temperature = document.getElementById(model_prefix + temperature_value)?.value || ''; + + if (integration_options_config[integration]) { + for (const key of Object.keys(integration_options_config[integration])) { + let elementId = `${model_prefix}${integration}_${key}`; + let element = document.getElementById(elementId); + if (element) { + prompt[key] = (element.type === 'checkbox') ? element.checked : element.value; + } + } + } await savePrompt(prompt); }; @@ -1031,7 +1038,7 @@ export async function initializeSpecificIntegrationUI({ if (use_specific_integration_el.checked) await _updatePrompt(); }); - document.querySelectorAll(".option-input-specific").forEach(element => { + document.querySelectorAll(".specific_integration_sub .option-input").forEach(element => { element.addEventListener("change", async () => { if (use_specific_integration_el.checked) await _updatePrompt(); }); From a436bd16b211c605714a1c5dad481b240a81b928 Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 21:58:09 +0100 Subject: [PATCH 07/12] chatgpt_api var names fixed --- options/mzta-options-default.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/options/mzta-options-default.js b/options/mzta-options-default.js index 968214b5..b297f225 100644 --- a/options/mzta-options-default.js +++ b/options/mzta-options-default.js @@ -23,8 +23,8 @@ export const integration_options_config = { api_key: '', model: '', developer_messages: '', - api_temperature: '', - api_store: false + temperature: '', + store: false }, ollama: { host: '', From 5893ee668c1e52ec8c5e6a44f2102f08befeb7e2 Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 22:02:33 +0100 Subject: [PATCH 08/12] fixed chatgpt_store and chatgpt_temperature var names --- api_webchat/controller.js | 14 +++++++------- pages/_lib/connection-ui.js | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/api_webchat/controller.js b/api_webchat/controller.js index 01737a91..5728f051 100644 --- a/api_webchat/controller.js +++ b/api_webchat/controller.js @@ -80,8 +80,8 @@ switch (llm) { 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, // Keep as boolean - chatgpt_api_temperature: prefs_default.chatgpt_api_temperature, + chatgpt_store: prefs_default.chatgpt_store, // Keep as boolean + chatgpt_temperature: prefs_default.chatgpt_temperature, do_debug: prefs_default.do_debug, }); let i18nStrings = {}; @@ -94,19 +94,19 @@ switch (llm) { 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, - chatgpt_api_temperature: prefs_api.chatgpt_api_temperature, + chatgpt_store: prefs_api.chatgpt_store, + chatgpt_temperature: prefs_api.chatgpt_temperature, do_debug: prefs_api.do_debug, i18nStrings: i18nStrings, }); let additional_text_elements = []; additional_text_elements.push({label: browser.i18n.getMessage("prompt_string"), value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)}); - additional_text_elements.push({label: 'OpenAI Store', value: (prefs_api.chatgpt_api_store ? 'Yes' : 'No')}); + additional_text_elements.push({label: 'OpenAI Store', value: (prefs_api.chatgpt_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}); } - if(prefs_api.chatgpt_api_temperature && prefs_api.chatgpt_api_temperature.length > 0){ - additional_text_elements.push({label: browser.i18n.getMessage("prefs_api_temperature"), value: prefs_api.chatgpt_api_temperature}); + if(prefs_api.chatgpt_temperature && prefs_api.chatgpt_temperature.length > 0){ + additional_text_elements.push({label: browser.i18n.getMessage("prefs_api_temperature"), value: prefs_api.chatgpt_temperature}); } messagesArea.appendUserMessage(getAPIsInitMessageString({ api_string: "ChatGPT API", diff --git a/pages/_lib/connection-ui.js b/pages/_lib/connection-ui.js index af598c8c..7a68d921 100644 --- a/pages/_lib/connection-ui.js +++ b/pages/_lib/connection-ui.js @@ -165,7 +165,7 @@ export async function injectConnectionUI({ @@ -178,7 +178,7 @@ export async function injectConnectionUI({ From f47b12946a676cd91aef932207dba1752b32ee65 Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 22:03:45 +0100 Subject: [PATCH 09/12] workers updated to use the new dynamic settings --- js/workers/model-worker-anthropic.js | 18 +++++++++--------- js/workers/model-worker-google_gemini.js | 17 +++++++++-------- js/workers/model-worker-ollama.js | 16 ++++++++-------- js/workers/model-worker-openai_comp.js | 17 +++++++++-------- js/workers/model-worker-openai_responses.js | 18 ++++++++++-------- 5 files changed, 45 insertions(+), 41 deletions(-) diff --git a/js/workers/model-worker-anthropic.js b/js/workers/model-worker-anthropic.js index ead40aff..9af3dc17 100644 --- a/js/workers/model-worker-anthropic.js +++ b/js/workers/model-worker-anthropic.js @@ -35,15 +35,15 @@ let assistantResponseAccumulator = ''; self.onmessage = async function(event) { if (event.data.type === 'init') { // console.log(">>>>>>>>>>>>>> event.data: " + JSON.stringify(event.data)); - anthropic = new Anthropic({ - apiKey: event.data.anthropic_api_key, - version: event.data.anthropic_version, - model: event.data.anthropic_model, - system_prompt: event.data.anthropic_system_prompt, - temperature: event.data.anthropic_temperature, - max_tokens: event.data.anthropic_max_tokens, - stream: true - }); + let config = { stream: true }; + for (const key in event.data) { + if (key.startsWith('anthropic_')) { + let newKey = key.replace('anthropic_', ''); + if (newKey === 'api_key') newKey = 'apiKey'; + config[newKey] = event.data[key]; + } + } + anthropic = new Anthropic(config); do_debug = event.data.do_debug; i18nStrings = event.data.i18nStrings; taLog = new taLogger('model-worker-anthropic', do_debug); diff --git a/js/workers/model-worker-google_gemini.js b/js/workers/model-worker-google_gemini.js index 359e0b20..4b6fc138 100644 --- a/js/workers/model-worker-google_gemini.js +++ b/js/workers/model-worker-google_gemini.js @@ -34,14 +34,15 @@ let assistantResponseAccumulator = ''; self.onmessage = async function(event) { if (event.data.type === 'init') { - google_gemini = new GoogleGemini({ - apiKey: event.data.google_gemini_api_key, - model: event.data.google_gemini_model, - system_instruction: event.data.google_gemini_system_instruction, - temperature: event.data.google_gemini_temperature, - thinking_budget: event.data.google_gemini_thinking_budget, - stream: true - }); + let config = { stream: true }; + for (const key in event.data) { + if (key.startsWith('google_gemini_')) { + let newKey = key.replace('google_gemini_', ''); + if (newKey === 'api_key') newKey = 'apiKey'; + config[newKey] = event.data[key]; + } + } + google_gemini = new GoogleGemini(config); do_debug = event.data.do_debug; i18nStrings = event.data.i18nStrings; taLog = new taLogger('model-worker-google_gemini', do_debug); diff --git a/js/workers/model-worker-ollama.js b/js/workers/model-worker-ollama.js index a3374eba..3987df33 100644 --- a/js/workers/model-worker-ollama.js +++ b/js/workers/model-worker-ollama.js @@ -35,14 +35,14 @@ let assistantResponseAccumulator = ''; self.onmessage = async function(event) { switch (event.data.type) { case 'init': - ollama = new Ollama({ - host: event.data.ollama_host, - model: event.data.ollama_model, - stream: true, - num_ctx: event.data.ollama_num_ctx, - temperature: event.data.ollama_temperature, - think: event.data.ollama_think - }); + let config = { stream: true }; + for (const key in event.data) { + if (key.startsWith('ollama_')) { + let newKey = key.replace('ollama_', ''); + config[newKey] = event.data[key]; + } + } + ollama = new Ollama(config); do_debug = event.data.do_debug; i18nStrings = event.data.i18nStrings; taLog = new taLogger('model-worker-ollama', do_debug); diff --git a/js/workers/model-worker-openai_comp.js b/js/workers/model-worker-openai_comp.js index 1e7b8aea..a541ffa8 100644 --- a/js/workers/model-worker-openai_comp.js +++ b/js/workers/model-worker-openai_comp.js @@ -34,14 +34,15 @@ let assistantResponseAccumulator = ''; self.onmessage = async function(event) { if (event.data.type === 'init') { - openai_comp = new OpenAIComp({ - host: event.data.openai_comp_host, - model: event.data.openai_comp_model, - apiKey: event.data.openai_comp_api_key, - stream: true, - use_v1: event.data.openai_comp_use_v1, - openai_comp_temperature: event.data.openai_comp_temperature - }); + let config = { stream: true }; + for (const key in event.data) { + if (key.startsWith('openai_comp_')) { + let newKey = key.replace('openai_comp_', ''); + if (newKey === 'api_key') newKey = 'apiKey'; + config[newKey] = event.data[key]; + } + } + openai_comp = new OpenAIComp(config); do_debug = event.data.do_debug; i18nStrings = event.data.i18nStrings; taLog = new taLogger('model-worker-openai_comp', do_debug); diff --git a/js/workers/model-worker-openai_responses.js b/js/workers/model-worker-openai_responses.js index 3189944d..89803673 100644 --- a/js/workers/model-worker-openai_responses.js +++ b/js/workers/model-worker-openai_responses.js @@ -35,14 +35,16 @@ let previous_response_id = null; self.onmessage = async function(event) { if (event.data.type === 'init') { - openai = new OpenAI({ - apiKey: event.data.chatgpt_api_key, - model: event.data.chatgpt_model, - developer_messages: event.data.chatgpt_developer_messages, - temperature: event.data.chatgpt_api_temperature, - stream: true, - store: event.data.chatgpt_api_store - }); + let config = { stream: true }; + for (const key in event.data) { + if (key.startsWith('chatgpt_')) { + if (key.startsWith('chatgpt_web_')) continue; // Exclude chatgpt_web_ prefixed keys + let newKey = key.replace('chatgpt_', ''); + if (newKey === 'api_key') newKey = 'apiKey'; + config[newKey] = event.data[key]; + } + } + openai = new OpenAI(config); do_debug = event.data.do_debug; i18nStrings = event.data.i18nStrings; taLog = new taLogger('model-worker-openai_responses', do_debug); From 285ee3a79edfcad7be99af2eb8c488bcbe4aa965 Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 22:22:45 +0100 Subject: [PATCH 10/12] the controller.js is now dynamic --- api_webchat/controller.js | 375 ++++++++++++++------------------------ 1 file changed, 138 insertions(+), 237 deletions(-) diff --git a/api_webchat/controller.js b/api_webchat/controller.js index 5728f051..050471d2 100644 --- a/api_webchat/controller.js +++ b/api_webchat/controller.js @@ -20,7 +20,7 @@ * 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 { getAPIsInitMessageString, convertNewlinesToBr } from '../js/mzta-utils.js'; @@ -46,260 +46,161 @@ const messagesArea = document.querySelector('messages-area'); // The controller wires up all the components and workers together, // managing the dependencies. A kind of "DI" class. 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) { - case "chatgpt_api": - worker = new Worker('../js/workers/model-worker-openai_responses.js', { type: 'module' }); - break; - case "google_gemini_api": - worker = new Worker('../js/workers/model-worker-google_gemini.js', { type: 'module' }); - 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; +const worker_path = worker_path_map[integration]; + +if (worker_path) { + worker = new Worker(worker_path, { type: 'module' }); +} else { + console.error('[ThunderAI] API WebChat Unknown LLM type:', llm); } -messagesArea.init(worker); +if (worker) { + messagesArea.init(worker); + messageInput.init(worker); + messageInput.setMessagesArea(messagesArea); -// Initialize the messageInput component and pass the worker to it -messageInput.init(worker); -messageInput.setMessagesArea(messagesArea); + if (integration_options_config[integration]) { + const integration_prefix = integration; + const options_config = integration_options_config[integration]; + + let prefsToGet = { do_debug: prefs_default.do_debug }; + for (const key in options_config) { + prefsToGet[`${integration_prefix}_${key}`] = prefs_default[`${integration_prefix}_${key}`]; + } + if (integration === 'openai_comp') { + prefsToGet.openai_comp_chat_name = prefs_default.openai_comp_chat_name; + } + + let prefs_api = await browser.storage.sync.get(prefsToGet); -switch (llm) { - case "chatgpt_api": { - let prefs_api = await browser.storage.sync.get({ - chatgpt_api_key: prefs_default.chatgpt_api_key, - chatgpt_model: prefs_default.chatgpt_model, - chatgpt_developer_messages: prefs_default.chatgpt_developer_messages, - chatgpt_store: prefs_default.chatgpt_store, // Keep as boolean - chatgpt_temperature: prefs_default.chatgpt_temperature, - do_debug: prefs_default.do_debug, - }); let i18nStrings = {}; - i18nStrings["chatgpt_api_request_failed"] = browser.i18n.getMessage('chatgpt_api_request_failed'); + 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.chatgpt_model); - messagesArea.setLLMName("ChatGPT"); - worker.postMessage({ + + 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', - chatgpt_api_key: prefs_api.chatgpt_api_key, - chatgpt_model: prefs_api.chatgpt_model, - chatgpt_developer_messages: prefs_api.chatgpt_developer_messages, - chatgpt_store: prefs_api.chatgpt_store, - chatgpt_temperature: prefs_api.chatgpt_temperature, do_debug: prefs_api.do_debug, i18nStrings: i18nStrings, - }); + }; + + for (const key in options_config) { + const prefKey = `${integration_prefix}_${key}`; + workerInitMessage[prefKey] = prefs_api[prefKey]; + } + + worker.postMessage(workerInitMessage); + + const additional_messages_config = { + chatgpt: [ + { key: 'store', labelKey: 'ChatGPT_chatgpt_api_store', type: 'boolean' }, + { key: 'developer_messages', labelKey: 'ChatGPT_Developer_Messages', type: 'string' }, + { key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' } + ], + google_gemini: [ + { key: 'system_instruction', labelKey: 'GoogleGemini_SystemInstruction', type: 'string' }, + { key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' }, + { key: 'thinking_budget', labelKey: 'prefs_google_gemini_thinking_budget', type: 'string' } + ], + ollama: [ + { key: 'think', labelKey: 'prefs_ollama_think', type: 'boolean' }, + { key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' }, + { key: 'num_ctx', labelKey: 'prefs_ollama_num_ctx', type: 'number_gt_zero' } + ], + openai_comp: [ + { key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' } + ], + anthropic: [ + { key: 'system_prompt', labelKey: 'Anthropic_System_Prompt', type: 'string' }, + { key: 'max_tokens', labelKey: 'prefs_OptionText_anthropic_max_tokens', type: 'number_gt_zero' }, + { key: 'temperature', labelKey: 'prefs_api_temperature', type: 'string' } + ] + }; + + const getAdditionalMessages = (integration, prefs) => { + 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 = []; additional_text_elements.push({label: browser.i18n.getMessage("prompt_string"), value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)}); - additional_text_elements.push({label: 'OpenAI Store', value: (prefs_api.chatgpt_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}); - } - if(prefs_api.chatgpt_temperature && prefs_api.chatgpt_temperature.length > 0){ - additional_text_elements.push({label: browser.i18n.getMessage("prefs_api_temperature"), value: prefs_api.chatgpt_temperature}); - } + 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({ - api_string: "ChatGPT API", - model_string: prefs_api.chatgpt_model, + api_string: api_strings[integration], + model_string: prefs_api[`${integration_prefix}_model`], + host_string: prefs_api[`${integration_prefix}_host`], + version_string: prefs_api[`${integration_prefix}_version`], additional_messages: additional_text_elements }), "info"); + browser.runtime.sendMessage({ - command: "openai_api_ready_" + call_id, + command: `${llm}_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_temperature: prefs_default.google_gemini_temperature, - 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 = []; - additional_text_elements.push({label: browser.i18n.getMessage("prompt_string"), value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)}); - 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}); - } - if(prefs_api.google_gemini_temperature.length > 0){ - additional_text_elements.push({label: browser.i18n.getMessage("prefs_api_temperature"), value: prefs_api.google_gemini_temperature}); - } - if(prefs_api.google_gemini_thinking_budget.length > 0){ - additional_text_elements.push({label: browser.i18n.getMessage("prefs_google_gemini_thinking_budget"), value: prefs_api.google_gemini_thinking_budget}); - } - worker.postMessage({ - 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, - google_gemini_temperature: prefs_api.google_gemini_temperature, - do_debug: prefs_api.do_debug, - i18nStrings: i18nStrings, - }); - messagesArea.appendUserMessage(getAPIsInitMessageString({ - api_string: "Google Gemini API", - model_string: prefs_api.google_gemini_model, - additional_messages: additional_text_elements - }), "info"); - browser.runtime.sendMessage({ - command: "google_gemini_api_ready_" + call_id, - window_id: (await browser.windows.getCurrent()).id - }); - break; - } - case "ollama_api": { - let prefs_api = await browser.storage.sync.get({ - ollama_host: prefs_default.ollama_host, - ollama_model: prefs_default.ollama_model, - ollama_num_ctx: prefs_default.ollama_num_ctx, - ollama_temperature: prefs_default.ollama_temperature, - ollama_think: prefs_default.ollama_think, - do_debug: prefs_default.do_debug, - }); - let i18nStrings = {}; - i18nStrings["ollama_api_request_failed"] = browser.i18n.getMessage('ollama_api_request_failed'); - i18nStrings["error_connection_interrupted"] = browser.i18n.getMessage('error_connection_interrupted'); - messageInput.setModel(prefs_api.ollama_model); - messagesArea.setLLMName("Ollama Local"); - worker.postMessage({ - type: 'init', - ollama_host: prefs_api.ollama_host, - ollama_model: prefs_api.ollama_model, - ollama_num_ctx: prefs_api.ollama_num_ctx, - ollama_temperature: prefs_api.ollama_temperature, - ollama_think: prefs_api.ollama_think, - do_debug: prefs_api.do_debug, - i18nStrings: i18nStrings - }); - browser.runtime.sendMessage({ - command: "ollama_api_ready_" + call_id, - window_id: (await browser.windows.getCurrent()).id - }); - let additional_text_elements = []; - additional_text_elements.push({label: browser.i18n.getMessage("prompt_string"), value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)}); - additional_text_elements.push({label: browser.i18n.getMessage("prefs_ollama_think"), value: (prefs_api.ollama_think ? 'Yes' : 'No')}); - if(prefs_api.ollama_temperature && prefs_api.ollama_temperature.length > 0){ - additional_text_elements.push({label: browser.i18n.getMessage("prefs_api_temperature"), value: prefs_api.ollama_temperature}); - } - if(prefs_api.ollama_num_ctx > 0){ - additional_text_elements.push({label: browser.i18n.getMessage("prefs_ollama_num_ctx"), value: prefs_api.ollama_num_ctx}); - } - messagesArea.appendUserMessage(getAPIsInitMessageString({ - api_string: "Ollama API", - model_string: prefs_api.ollama_model, - host_string: prefs_api.ollama_host, - additional_messages: additional_text_elements - }), "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, - openai_comp_temperature: prefs_default.openai_comp_temperature, - 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, - openai_comp_temperature: prefs_api.openai_comp_temperature, - do_debug: prefs_api.do_debug, - i18nStrings: i18nStrings, - }); - let additional_text_elements = []; - additional_text_elements.push({label: browser.i18n.getMessage("prompt_string"), value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)}); - if(prefs_api.openai_comp_temperature && prefs_api.openai_comp_temperature.length > 0){ - additional_text_elements.push({label: browser.i18n.getMessage("prefs_api_temperature"), value: prefs_api.openai_comp_temperature}); - } - 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 - }), "info"); - browser.runtime.sendMessage({ - command: "openai_comp_api_ready_" + call_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_temperature: prefs_default.anthropic_temperature, - 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_temperature: prefs_api.anthropic_temperature, - 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: browser.i18n.getMessage("prompt_string"), value: '[' + prompt_id + '] ' + decodeURIComponent(prompt_name)}); - if(prefs_api.anthropic_system_prompt && prefs_api.anthropic_system_prompt.length > 0){ - additional_text_elements.push({label: browser.i18n.getMessage("Anthropic_System_Prompt"), value: prefs_api.anthropic_system_prompt}); - } - if(prefs_api.anthropic_max_tokens > 0){ - additional_text_elements.push({label: browser.i18n.getMessage("prefs_OptionText_anthropic_max_tokens"), value: prefs_api.anthropic_max_tokens}); - } - if(prefs_api.anthropic_temperature && prefs_api.anthropic_temperature.length > 0){ - additional_text_elements.push({label: browser.i18n.getMessage("prefs_api_temperature"), value: prefs_api.anthropic_temperature}); - } - 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; } } From 154a0a981bac92e1b7cfe4bb5a913fa38ba37e5a Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 22:25:15 +0100 Subject: [PATCH 11/12] option-input-specific removed --- pages/_lib/connection-ui.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pages/_lib/connection-ui.js b/pages/_lib/connection-ui.js index 7a68d921..37c22001 100644 --- a/pages/_lib/connection-ui.js +++ b/pages/_lib/connection-ui.js @@ -153,7 +153,7 @@ export async function injectConnectionUI({ __MSG_Loading__
@@ -165,7 +165,7 @@ export async function injectConnectionUI({ @@ -218,7 +218,7 @@ export async function injectConnectionUI({ __MSG_Loading__
@@ -230,7 +230,7 @@ export async function injectConnectionUI({ @@ -290,7 +290,7 @@ export async function injectConnectionUI({ __MSG_Loading__
@@ -302,7 +302,7 @@ export async function injectConnectionUI({ @@ -396,7 +396,7 @@ export async function injectConnectionUI({ __MSG_Loading__
@@ -419,7 +419,7 @@ export async function injectConnectionUI({ @@ -446,7 +446,7 @@ export async function injectConnectionUI({ __MSG_Loading__
@@ -458,7 +458,7 @@ export async function injectConnectionUI({ From 168dd339a05235ced192675d457c2744238e3209 Mon Sep 17 00:00:00 2001 From: mic Date: Mon, 29 Dec 2025 22:28:30 +0100 Subject: [PATCH 12/12] spamfilter updated to use the new dynamic settings --- pages/spamfilter/mzta-spamfilter.js | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/pages/spamfilter/mzta-spamfilter.js b/pages/spamfilter/mzta-spamfilter.js index 0e22f435..5f3c2fe5 100644 --- a/pages/spamfilter/mzta-spamfilter.js +++ b/pages/spamfilter/mzta-spamfilter.js @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -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 { getSpecialPrompts, @@ -38,6 +38,25 @@ let taLog = new taLogger("mzta-spamfilter-page",true); taSpamReport.logger = taLog; document.addEventListener('DOMContentLoaded', async () => { + + let specialPrompts = await getSpecialPrompts(); + let spamfilter_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_spamfilter'); + + if (spamfilter_prompt && spamfilter_prompt.api && spamfilter_prompt.api !== '') { + let update_prefs = {}; + update_prefs['spamfilter_connection_type'] = spamfilter_prompt.api; + + let integration = spamfilter_prompt.api.replace('_api', ''); + if (integration_options_config && integration_options_config[integration]) { + for (const key of Object.keys(integration_options_config[integration])) { + if (spamfilter_prompt[key] !== undefined) { + update_prefs[`spamfilter_${integration}_${key}`] = spamfilter_prompt[key]; + } + } + } + await browser.storage.sync.set(update_prefs); + } + await initializeSpecificIntegrationUI({ prefix: 'spamfilter', promptId: 'prompt_spamfilter', @@ -59,9 +78,6 @@ document.addEventListener('DOMContentLoaded', async () => { let spamfilter_save_btn = document.getElementById('btn_save_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_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_spamfilter_full_text')); spamfilter_save_btn.disabled = (event.target.value === spamfilter_prompt.text);