: api model
+
*/
const defaultPrompts = [
@@ -89,6 +95,8 @@ const defaultPrompts = [
chatgpt_web_model: '',
chatgpt_web_project: '',
chatgpt_web_custom_gpt: '',
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "0",
},
@@ -106,6 +114,8 @@ const defaultPrompts = [
chatgpt_web_model: '',
chatgpt_web_project: '',
chatgpt_web_custom_gpt: '',
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "0",
},
@@ -123,6 +133,8 @@ const defaultPrompts = [
chatgpt_web_model: '',
chatgpt_web_project: '',
chatgpt_web_custom_gpt: '',
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "0",
},
@@ -140,6 +152,8 @@ const defaultPrompts = [
chatgpt_web_model: '',
chatgpt_web_project: '',
chatgpt_web_custom_gpt: '',
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "0",
},
@@ -157,6 +171,8 @@ const defaultPrompts = [
chatgpt_web_model: '',
chatgpt_web_project: '',
chatgpt_web_custom_gpt: '',
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "0",
},
@@ -174,6 +190,8 @@ const defaultPrompts = [
chatgpt_web_model: '',
chatgpt_web_project: '',
chatgpt_web_custom_gpt: '',
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "0",
},
@@ -191,6 +209,8 @@ const defaultPrompts = [
chatgpt_web_model: '',
chatgpt_web_project: '',
chatgpt_web_custom_gpt: '',
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "0",
},
@@ -208,6 +228,8 @@ const defaultPrompts = [
chatgpt_web_model: '',
chatgpt_web_project: '',
chatgpt_web_custom_gpt: '',
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "0",
},
@@ -225,6 +247,8 @@ const defaultPrompts = [
chatgpt_web_model: '',
chatgpt_web_project: '',
chatgpt_web_custom_gpt: '',
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "0",
},
@@ -242,6 +266,8 @@ const defaultPrompts = [
chatgpt_web_model: '',
chatgpt_web_project: '',
chatgpt_web_custom_gpt: '',
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "0",
},
@@ -259,6 +285,8 @@ const specialPrompts = [
need_custom_text: "0",
define_response_lang: "0",
use_diff_viewer: "0",
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "1",
},
@@ -273,6 +301,8 @@ const specialPrompts = [
need_custom_text: "0",
define_response_lang: "0",
use_diff_viewer: "0",
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "1",
},
@@ -287,6 +317,8 @@ const specialPrompts = [
need_custom_text: "0",
define_response_lang: "0",
use_diff_viewer: "0",
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "1",
},
@@ -301,24 +333,26 @@ const specialPrompts = [
need_custom_text: "0",
define_response_lang: "0",
use_diff_viewer: "0",
+ api_type: '',
+ api_model: '',
is_default: "1",
is_special: "1",
},
];
-export async function getPrompts(onlyEnabled = false, includeSpecial = []){ // includeSpecial is an array of active special prompts ids
+export async function getPrompts(onlyEnabled = false, includeSpecial = [], allSpecial = false){ // includeSpecial is an array of active special prompts ids
const _defaultPrompts = await getDefaultPrompts_withProps();
// console.log('>>>>>>>>>>>> getPrompts _defaultPrompts: ' + JSON.stringify(_defaultPrompts));
const customPrompts = await getCustomPrompts();
// console.log('>>>>>>>>>>>> getPrompts customPrompts: ' + JSON.stringify(customPrompts));
const specialPrompts = await getSpecialPrompts();
let output = specialPrompts.concat(_defaultPrompts).concat(customPrompts);
- if(includeSpecial.length == 0){
+ if((includeSpecial.length == 0) && !allSpecial){
output = output.filter(obj => obj.is_special != 1); // we do not want special prompts
}else{
// console.log(">>>>>>>>>> getPrompts includeSpecial: " + JSON.stringify(includeSpecial));
- output = output.filter(obj => includeSpecial.includes(obj.id) || obj.is_special != 1);
+ output = output.filter(obj => includeSpecial.includes(obj.id) || obj.is_special != 1 || allSpecial);
// output = output.filter(obj => {
// const isIncluded = includeSpecial.includes(obj.id);
// const isNotSpecial = obj.is_special != 1;
@@ -402,6 +436,11 @@ async function getDefaultPrompts_withProps() {
prompt.position_display = prefs._default_prompts_properties[prompt.id].position_display;
prompt.enabled = prefs._default_prompts_properties[prompt.id].enabled;
prompt.need_custom_text = prefs._default_prompts_properties[prompt.id].need_custom_text;
+ prompt.chatgpt_web_model = prefs._default_prompts_properties[prompt.id].chatgpt_web_model;
+ prompt.chatgpt_web_project = prefs._default_prompts_properties[prompt.id].chatgpt_web_project;
+ prompt.chatgpt_web_custom_gpt = prefs._default_prompts_properties[prompt.id].chatgpt_web_custom_gpt;
+ prompt.api_type = prefs._default_prompts_properties[prompt.id].api_type;
+ prompt.api_model = prefs._default_prompts_properties[prompt.id].api_model;
}else{
prompt.position_display = pos;
prompt.position_compose = pos;
@@ -433,6 +472,12 @@ async function getCustomPrompts() {
if(prompt.chatgpt_web_custom_gpt === undefined){
prompt.chatgpt_web_custom_gpt = "";
}
+ if(prompt.api_type === undefined){
+ prompt.api_type = "";
+ }
+ if(prompt.api_model === undefined){
+ prompt.api_model = "";
+ }
});
return prefs._custom_prompt;
}
@@ -441,7 +486,17 @@ async function getCustomPrompts() {
export async function setDefaultPromptsProperties(prompts) {
let default_prompts_properties = {};
prompts.forEach((prompt) => {
- default_prompts_properties[prompt.id] = {position_compose: prompt.position_compose, position_display: prompt.position_display, enabled: prompt.enabled, need_custom_text: prompt.need_custom_text};
+ default_prompts_properties[prompt.id] = {
+ position_compose: prompt.position_compose,
+ position_display: prompt.position_display,
+ enabled: prompt.enabled,
+ need_custom_text: prompt.need_custom_text,
+ chatgpt_web_model: prompt.chatgpt_web_model,
+ chatgpt_web_project: prompt.chatgpt_web_project,
+ chatgpt_web_custom_gpt: prompt.chatgpt_web_custom_gpt,
+ api_type: prompt.api_type,
+ api_model: prompt.api_model
+ };
});
//console.log('>>>>>>>>>>>>>> default_prompts_properties: ' + JSON.stringify(default_prompts_properties));
await browser.storage.local.set({_default_prompts_properties: default_prompts_properties});
@@ -486,4 +541,56 @@ export async function setSpecialPrompts(prompts) {
export async function getSpamFilterPrompt(){
return (await getSpecialPrompts()).find(prompt => prompt.id == 'prompt_spamfilter');
+}
+
+export async function loadPrompt(id) {
+ let allPrompts = await getPrompts(false,[],true);
+ // console.log(">>>>>>>>>>>> loadPrompt id: " + id + " - allPrompts: " + JSON.stringify(allPrompts));
+ return allPrompts.find(prompt => prompt.id === id);
+}
+
+export async function savePrompt(prompt) {
+ // console.log(">>>>>>>>>>>>> savePrompt prompt: " + JSON.stringify(prompt));
+ if (prompt.id === undefined) {
+ throw new Error("Invalid prompt: " + JSON.stringify(prompt));
+ }
+ // Special Prompt
+ if (prompt.is_special === "1") {
+ let specialPrompts = await getSpecialPrompts();
+ let index = specialPrompts.findIndex(p => p.id === prompt.id);
+ if (index === -1) {
+ specialPrompts.push(prompt);
+ } else {
+ specialPrompts[index] = prompt;
+ }
+ await setSpecialPrompts(specialPrompts);
+ return;
+ }
+ // Custom Prompt
+ if (prompt.is_default === "0") {
+ let customPrompts = await getCustomPrompts();
+ let index = customPrompts.findIndex(p => p.id === prompt.id);
+ if (index === -1) {
+ customPrompts.push(prompt);
+ } else {
+ customPrompts[index] = prompt;
+ }
+ await setCustomPrompts(customPrompts);
+ } else { // Default Prompt
+ let defaultPrompts = getDefaultPrompts_withProps();
+ let index = defaultPrompts.findIndex(p => p.id === prompt.id);
+ if (index === -1) {
+ defaultPrompts.push(prompt);
+ } else {
+ defaultPrompts[index] = prompt;
+ }
+ await setDefaultPromptsProperties(defaultPrompts);
+ }
+}
+
+export async function clearPromptAPI(id){
+ let _prompt = await loadPrompt(id);
+ _prompt.api = "";
+ _prompt.model = "";
+ await savePrompt(_prompt);
}
\ No newline at end of file
diff --git a/js/mzta-special-commands.js b/js/mzta-special-commands.js
index 2734f2ce..e23618da 100644
--- a/js/mzta-special-commands.js
+++ b/js/mzta-special-commands.js
@@ -17,7 +17,7 @@
*/
// Call the API to use a special prompt
-
+ import { prefs_default } from "../options/mzta-options-default.js";
import { taLogger } from './mzta-logger.js';
import { prefs_default } from '../options/mzta-options-default.js';
@@ -27,13 +27,21 @@
prompt = "";
worker = null;
llm = "";
+ custom_model = "";
full_message = "";
logger = null;
do_debug = false;
- constructor(prompt, llm, do_debug = false) {
+ constructor(args = {}) {
+ let {
+ prompt = '',
+ llm = '',
+ custom_model = '',
+ do_debug = false
+ } = args;
this.prompt = prompt;
this.llm = llm;
+ this.custom_model = custom_model;
this.logger = new taLogger('mzta_specialCommand', do_debug);
this.do_debug = do_debug;
switch (this.llm) {
@@ -59,6 +67,7 @@
}
async initWorker() {
+ // console.log((">>>>>>>>>>>> this.custom_model: " + this.custom_model));
switch (this.llm) {
case "chatgpt_api": {
let prefs_api = await browser.storage.sync.get({
@@ -69,7 +78,7 @@
this.worker.postMessage({
type: 'init',
chatgpt_api_key: prefs_api.chatgpt_api_key,
- chatgpt_model: prefs_api.chatgpt_model,
+ chatgpt_model: this.custom_model != '' ? this.custom_model : prefs_api.chatgpt_model,
chatgpt_developer_messages: prefs_api.chatgpt_developer_messages,
do_debug: this.do_debug,
i18nStrings: ''
@@ -86,7 +95,7 @@
this.worker.postMessage({
type: 'init',
google_gemini_api_key: prefs_api.google_gemini_api_key,
- google_gemini_model: prefs_api.google_gemini_model,
+ 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,
@@ -102,7 +111,7 @@
this.worker.postMessage({
type: 'init',
ollama_host: prefs_api.ollama_host,
- ollama_model: prefs_api.ollama_model,
+ ollama_model: this.custom_model != '' ? this.custom_model : prefs_api.ollama_model,
do_debug: this.do_debug,
i18nStrings: ''
});
@@ -120,7 +129,7 @@
this.worker.postMessage({
type: 'init',
openai_comp_host: prefs_api.openai_comp_host,
- openai_comp_model: prefs_api.openai_comp_model,
+ 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,
@@ -138,7 +147,7 @@
this.worker.postMessage({
type: 'init',
anthropic_api_key: prefs_api.anthropic_api_key,
- anthropic_model: prefs_api.anthropic_model,
+ 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,
diff --git a/js/mzta-utils-prompt.js b/js/mzta-utils-prompt.js
index 03f29c53..896f6406 100644
--- a/js/mzta-utils-prompt.js
+++ b/js/mzta-utils-prompt.js
@@ -89,7 +89,7 @@ export const taPromptUtils = {
fullPrompt += " \n" + browser.i18n.getMessage("prompt_add_tags_force_lang") + " " + default_chatgpt_lang + ".";
}
if(add_tags_auto_uselist && add_tags_auto_uselist_list && add_tags_auto_uselist_list.length > 0){
- fullPrompt += " \n" + browser.i18n.getMessage("prompt_add_tags_use_list") + " " + add_tags_auto_uselist_list + ".";
+ fullPrompt += " \n" + browser.i18n.getMessage("prompt_add_tags_use_list") + ": " + add_tags_auto_uselist_list + ".";
}
return fullPrompt;
diff --git a/js/mzta-utils.js b/js/mzta-utils.js
index af6e82fc..b486f343 100644
--- a/js/mzta-utils.js
+++ b/js/mzta-utils.js
@@ -549,10 +549,21 @@ export function getAPIsInitMessageString(args = {}) {
}
export function getActiveSpecialPromptsIDs(args = {}) {
- const { addtags = false, get_calendar_event = false, get_task = false, is_chatgpt_web = false } = args;
+ const {
+ addtags = false,
+ addtags_api = false,
+ get_calendar_event = false,
+ get_task = false,
+ is_chatgpt_web = false
+ } = args;
+ // The Antispam filter is not here, because this method is used only
+ // to reload the ThunderAI button menu, not the context menu
let output = [];
// console.log(">>>>>>>>>> getActiveSpecialPromptsIDs args: " + JSON.stringify(args));
if (is_chatgpt_web) {
+ if (addtags_api && addtags) {
+ output.push('prompt_add_tags');
+ }
return output;
}
if (addtags) {
@@ -568,6 +579,10 @@ export function getActiveSpecialPromptsIDs(args = {}) {
return output;
}
+export function checkSpecificIntegration(use, conntype){
+ return use && (conntype != null) && (conntype !== '');
+}
+
export function extractJsonObject(inputString) {
try {
const jsonMatch = inputString.match(/\{[\s\S]*\}/);
@@ -587,6 +602,22 @@ 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";
+}
+
+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 async function checkSparksPresence() {
try {
let sparks_current = await browser.runtime.sendMessage('thunderai-sparks@micz.it',{action: "checkPresence"});
diff --git a/js/workers/model-worker-anthropic.js b/js/workers/model-worker-anthropic.js
index 9f311e7d..39cc136f 100644
--- a/js/workers/model-worker-anthropic.js
+++ b/js/workers/model-worker-anthropic.js
@@ -36,6 +36,7 @@ let assistantResponseAccumulator = '';
self.onmessage = async function(event) {
if (event.data.type === 'init') {
+ // console.log(">>>>>>>>>>>>>> event.data: " + JSON.stringify(event.data));
anthropic_api_key = event.data.anthropic_api_key;
anthropic_model = event.data.anthropic_model;
anthropic = new Anthropic({
diff --git a/mzta-background.js b/mzta-background.js
index c3c9c290..e5f0f42c 100644
--- a/mzta-background.js
+++ b/mzta-background.js
@@ -20,7 +20,35 @@ import { mzta_script } from './js/mzta-chatgpt.js';
import { prefs_default } from './options/mzta-options-default.js';
import { mzta_Menus } from './js/mzta-menus.js';
import { taLogger } from './js/mzta-logger.js';
-import { getCurrentIdentity, getOriginalBody, replaceBody, setBody, i18nConditionalGet, generateCallID, migrateCustomPromptsStorage, migrateDefaultPromptsPropStorage, getGPTWebModelString, getTagsList, createTag, assignTagsToMessage, checkIfTagLabelExists, getActiveSpecialPromptsIDs, checkSparksPresence, getMessages, getMailBody, extractJsonObject, contextMenuID_AddTags, contextMenuID_Spamfilter, sanitizeChatGPTModelData, sanitizeChatGPTWebCustomData, stripHtmlKeepLines, htmlBodyToPlainText, convertNewlinesToParagraphs } from './js/mzta-utils.js';
+import {
+ getCurrentIdentity,
+ getOriginalBody,
+ replaceBody,
+ setBody,
+ i18nConditionalGet,
+ generateCallID,
+ migrateCustomPromptsStorage,
+ migrateDefaultPromptsPropStorage,
+ getGPTWebModelString,
+ getTagsList,
+ createTag,
+ assignTagsToMessage,
+ checkIfTagLabelExists,
+ getActiveSpecialPromptsIDs,
+ checkSparksPresence,
+ getMessages,
+ getMailBody,
+ extractJsonObject,
+ contextMenuID_AddTags,
+ contextMenuID_Spamfilter,
+ sanitizeChatGPTModelData,
+ sanitizeChatGPTWebCustomData,
+ stripHtmlKeepLines,
+ htmlBodyToPlainText,
+ convertNewlinesToParagraphs,
+ getConnectionType,
+ checkSpecificIntegration,
+ } from './js/mzta-utils.js';
import { taPromptUtils } from './js/mzta-utils-prompt.js';
import { mzta_specialCommand } from './js/mzta-special-commands.js';
import { getSpamFilterPrompt } from './js/mzta-prompts.js';
@@ -56,6 +84,7 @@ taWorkingStatus.taLog = taLog;
let special_prompts_ids = getActiveSpecialPromptsIDs({
addtags: prefs_init.add_tags,
+ addtags_api: checkSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
get_calendar_event: doGetSparkFeature(prefs_init.get_calendar_event),
get_task: doGetSparkFeature(prefs_init.get_task),
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
@@ -146,6 +175,7 @@ async function _reload_menus() {
let getTask = doGetSparkFeature(prefs_reload.get_task);
const special_prompts_ids = getActiveSpecialPromptsIDs({
addtags: prefs_reload.add_tags,
+ addtags_api: checkSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
get_calendar_event: getCalendarEvent,
get_task: getTask,
is_chatgpt_web: (prefs_reload.connection_type === "chatgpt_web")
@@ -749,7 +779,25 @@ function doGetSparkFeature(spark_feature_active) {
}
async function reload_pref_init(){
- prefs_init = await browser.storage.sync.get({do_debug: prefs_default.do_debug, add_tags: prefs_default.add_tags, get_calendar_event: prefs_default.get_calendar_event, get_task: prefs_default.get_task, connection_type: prefs_default.connection_type, add_tags_auto: prefs_default.add_tags_auto, add_tags_auto_force_existing: prefs_default.add_tags_auto_force_existing, add_tags_auto_only_inbox: prefs_default.add_tags_auto_only_inbox, spamfilter: prefs_default.spamfilter, spamfilter_threshold: prefs_default.spamfilter_threshold, 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});
+ prefs_init = await browser.storage.sync.get({
+ do_debug: prefs_default.do_debug,
+ add_tags: prefs_default.add_tags,
+ get_calendar_event: prefs_default.get_calendar_event,
+ get_task: prefs_default.get_task,
+ connection_type: prefs_default.connection_type,
+ add_tags_auto: prefs_default.add_tags_auto,
+ add_tags_auto_force_existing: prefs_default.add_tags_auto_force_existing,
+ add_tags_auto_only_inbox: prefs_default.add_tags_auto_only_inbox,
+ spamfilter: prefs_default.spamfilter,
+ spamfilter_threshold: prefs_default.spamfilter_threshold,
+ 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
+ });
_process_incoming = prefs_init.add_tags_auto || prefs_init.spamfilter;
_sparks_presence = await checkSparksPresence();
}
@@ -767,6 +815,7 @@ function setupStorageChangeListener() {
let getTask = doGetSparkFeature(prefs_init.get_task);
const special_prompts_ids = getActiveSpecialPromptsIDs({
addtags: newTags,
+ addtags_api: checkSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
get_calendar_event: getCalendarEvent,
get_task: getTask,
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
@@ -781,6 +830,7 @@ function setupStorageChangeListener() {
let getTask = doGetSparkFeature(prefs_init.get_task);
const special_prompts_ids = getActiveSpecialPromptsIDs({
addtags: prefs_init.add_tags,
+ addtags_api: checkSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
get_calendar_event: getCalendarEvent,
get_task: getTask,
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
@@ -795,6 +845,7 @@ function setupStorageChangeListener() {
let getTask = doGetSparkFeature(newTask);
const special_prompts_ids = getActiveSpecialPromptsIDs({
addtags: prefs_init.add_tags,
+ addtags_api: checkSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
get_calendar_event: getCalendarEvent,
get_task: getTask,
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
@@ -809,6 +860,7 @@ function setupStorageChangeListener() {
let getTask = doGetSparkFeature(prefs_init.get_task);
const special_prompts_ids = getActiveSpecialPromptsIDs({
addtags: prefs_init.add_tags,
+ addtags_api: checkSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
get_calendar_event: getCalendarEvent,
get_task: getTask,
is_chatgpt_web: (newConnectionType === "chatgpt_web")
@@ -895,6 +947,7 @@ menus.loadMenus(special_prompts_ids);
// Context Menus
function addContextMenu(menu_id) {
+ browser.menus.remove(menu_id);
browser.menus.create({
id: menu_id,
title: browser.i18n.getMessage("context_menu_" + menu_id),
@@ -909,12 +962,12 @@ function removeContextMenu(menu_id) {
}
// Add Context menu: Add tags
-if(prefs_init.add_tags && prefs_init.add_tags_context_menu && (prefs_init.connection_type !== "chatgpt_web")){
+if(prefs_init.add_tags && prefs_init.add_tags_context_menu && ((prefs_init.connection_type !== "chatgpt_web")||checkSpecificIntegration(prefs_init.add_tags_use_specific_integration,prefs_init.add_tags_connection_type))){
addContextMenu(contextMenuID_AddTags);
}
// Add Context menu: Spamfilter
-if(prefs_init.spamfilter && prefs_init.spamfilter_context_menu && (prefs_init.connection_type !== "chatgpt_web")){
+if(prefs_init.spamfilter && prefs_init.spamfilter_context_menu && ((prefs_init.connection_type !== "chatgpt_web")||checkSpecificIntegration(prefs_init.spamfilter_use_specific_integration,prefs_init.spamfilter_connection_type))){
addContextMenu(contextMenuID_Spamfilter);
}
@@ -976,6 +1029,9 @@ 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,
+ do_debug: prefs_default.do_debug,
});
for await (let message of messages) {
@@ -1005,7 +1061,7 @@ async function processEmails(messages, addTagsAuto, spamFilter) {
let specialFullPrompt_add_tags = '';
let curr_prompt_add_tags = menus.allPrompts.find(p => p.id === 'prompt_add_tags');
let tags_full_list = await getTagsList();
- // console.log(">>>>>>>>>>>>> curr_prompt_add_tags: " + curr_prompt_add_tags);
+ // console.log(">>>>>>>>>>>>> curr_prompt_add_tags: " + JSON.stringify(curr_prompt_add_tags));
let chatgpt_lang = await taPromptUtils.getDefaultLang(curr_prompt_add_tags);
specialFullPrompt_add_tags = await taPromptUtils.preparePrompt({
curr_prompt: curr_prompt_add_tags,
@@ -1018,7 +1074,13 @@ async function processEmails(messages, addTagsAuto, spamFilter) {
});
specialFullPrompt_add_tags = taPromptUtils.finalizePrompt_add_tags(specialFullPrompt_add_tags, prefs_aats.add_tags_maxnum, prefs_aats.add_tags_force_lang, prefs_aats.default_chatgpt_lang, prefs_aats.add_tags_auto_uselist, prefs_aats.add_tags_auto_uselist_list);
taLog.log("Special prompt: " + specialFullPrompt_add_tags);
- let cmd_addTags = new mzta_specialCommand(specialFullPrompt_add_tags, prefs_aats.connection_type, prefs_init.do_debug);
+ // console.log(">>>>>>>>>> curr_prompt_add_tags.model: " + curr_prompt_add_tags.model);
+ 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),
+ custom_model: curr_prompt_add_tags.model ? curr_prompt_add_tags.model : '',
+ do_debug: prefs_aats.do_debug
+ });
await cmd_addTags.initWorker();
let tags_current_email = [];
try {
@@ -1052,7 +1114,12 @@ async function processEmails(messages, addTagsAuto, spamFilter) {
});
taLog.log("Special prompt: " + specialFullPrompt_spamfilter);
// console.log(">>>>>>>> Special prompt for spamfilter: " + specialFullPrompt_spamfilter);
- let cmd_spamfilter = new mzta_specialCommand(specialFullPrompt_spamfilter, prefs_init.connection_type, prefs_init.do_debug);
+ let cmd_spamfilter = new mzta_specialCommand({
+ prompt: specialFullPrompt_spamfilter,
+ llm: getConnectionType(prefs_aats.connection_type, curr_prompt_spamfilter, prefs_aats.spamfilter_use_specific_integration),
+ custom_model: curr_prompt_spamfilter.model ? curr_prompt_spamfilter.model : '',
+ do_debug: prefs_aats.do_debug
+ });
await cmd_spamfilter.initWorker();
let spamfilter_result = '';
taLog.log("Sending the prompt...");
diff --git a/options/mzta-options-default.js b/options/mzta-options-default.js
index 94d7ebec..6efc2cfa 100644
--- a/options/mzta-options-default.js
+++ b/options/mzta-options-default.js
@@ -67,6 +67,13 @@ 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: '',
get_calendar_event: true,
get_task: true,
calendar_enforce_timezone: false,
@@ -75,4 +82,11 @@ export const prefs_default = {
spamfilter_threshold: 70,
spamfilter_context_menu: true,
spamfilter_enabled_accounts: [],
-}
\ No newline at end of file
+ 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: '',
+}
diff --git a/options/mzta-options.css b/options/mzta-options.css
index 280c5bcf..f0c21d66 100644
--- a/options/mzta-options.css
+++ b/options/mzta-options.css
@@ -82,10 +82,6 @@ span.dims_label{
display: inline-block;
}
-span.opt_title{
- font-weight: bold;
-}
-
#btn_custom_prompts{
text-align: center;
width: 100%;
@@ -104,38 +100,9 @@ div#miczTranslate{
font-size:smaller;
}
-tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
- background-color: rgb(185, 220, 252);
-}
-
-tr.conntype_chatgpt_web, tr.conntype_chatgpt_web2{
- background-color: rgb(255, 209, 183);
-}
-
-tr.conntype_ollama_api, tr.conntype_ollama_api2{
- background-color: rgb(177, 238, 169);
-}
-
-tr.conntype_openai_comp_api, tr.conntype_openai_comp_api2{
- background-color: rgb(213, 169, 238);
-}
-
-tr.conntype_google_gemini_api, tr.conntype_google_gemini_api2{
- background-color: rgb(233, 238, 169);
-}
-
-tr.conntype_anthropic_api, tr.conntype_anthropic_api2{
- background-color: rgb(255, 168, 204);
-}
-
-#chatgpt_model_fetch_loading{
+.warn_API_needed{
display: none;
- font-style: italic;
-}
-
-#google_gemini_model_fetch_loading{
- display: none;
- font-style: italic;
+ font-weight: bold;
}
#no_sparks td{
@@ -144,53 +111,6 @@ tr.conntype_anthropic_api, tr.conntype_anthropic_api2{
background: #bbf7f1;
}
-textarea.option-textarea{
- width: -moz-available;
- height: 10em;
-}
-
-.api_key-container {
- position: relative;
- width: 100%;
-}
-
-.api_key-container input {
- width: -moz-available;
- margin-right: 25px;
-}
-
-input[type="text"], input[type="password"]{
- border-radius: 4px;
- padding: 2px;
-}
-
-input.option-input[type="text"]{
- width: -moz-available;
-}
-
-.api_key-container .toggle-icon {
- position: absolute;
- right: 0px;
- top: 50%;
- transform: translateY(-50%);
- cursor: pointer;
-}
-
-#ollama_model_fetch_loading{
- display: none;
- font-style: italic;
-}
-
-#openai_comp_model_fetch_loading{
- display: none;
- font-style: italic;
-}
-
-#anthropic_model_fetch_loading{
- display: none;
- font-style: italic;
-}
-
#owl_warning{
display: none;
}
@@ -235,10 +155,6 @@ input.option-input[type="text"]{
color: #FF6600;
}
-.conntype_chatgpt_web_option{
- cursor: pointer;
-}
-
.btn_small{
font-size: 0.8em;
}
diff --git a/options/mzta-options.html b/options/mzta-options.html
index f8c12e4b..0e24f172 100644
--- a/options/mzta-options.html
+++ b/options/mzta-options.html
@@ -3,6 +3,7 @@
+
@@ -113,375 +114,7 @@
-
- |
-
- |
-
-
- |
-
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- __MSG_OpenChatGPTTab_Info__
-
-
__MSG_OpenChatGPTTab_Info2__
- |
-
-
- |
-
-
-
- 
-
- |
-
-
- |
-
- |
-
- __MSG_Loading__
-
- |
-
-
- |
-
- |
-
-
- |
-
-
- |
-
- |
-
-
- |
-
-
- |
-
-
-
- 
-
- |
-
-
- |
-
- |
-
- __MSG_Loading__
-
- |
-
-
- |
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
-
- __MSG_remember_CORS__ [__MSG_more_info_string__]
-
__MSG_CORS_alternative_1__
- __MSG_CORS_alternative_2__
-
- |
-
-
- |
-
- |
-
- __MSG_Loading__
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
-
- __MSG_maybe_CORS_openai_comp__ [__MSG_more_info_string__]
-
__MSG_CORS_alternative_1__
- __MSG_CORS_alternative_2__
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
-
- 
-
- |
-
-
- |
- |
-
-
-
- __MSG_Loading__
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
-
- 
-
- |
-
-
- |
-
- |
-
- __MSG_Loading__
-
- |
-
-
- |
-
- |
-
-
- |
-
-
- | __MSG_prefs_OptionText_anthropic_max_tokens__ |
-
-
- |
-
+
| __MSG_prefs_OptionText_max_prompt_length__ |
@@ -499,6 +132,7 @@
|
@@ -509,6 +143,7 @@
diff --git a/options/mzta-options.js b/options/mzta-options.js
index 21e42863..aeb16f64 100644
--- a/options/mzta-options.js
+++ b/options/mzta-options.js
@@ -18,17 +18,24 @@
import { prefs_default } from './mzta-options-default.js';
import { taLogger } from '../js/mzta-logger.js';
-import { OpenAI } from '../js/api/openai.js';
-import { Ollama } from '../js/api/ollama.js';
-import { OpenAIComp } from '../js/api/openai_comp.js'
-import { GoogleGemini } from '../js/api/google_gemini.js';
-import { Anthropic } from '../js/api/anthropic.js';
-import { ChatGPTWeb_models, checkSparksPresence, isThunderbird128OrGreater, openTab, sanitizeChatGPTModelData, sanitizeChatGPTWebCustomData, validateCustomData_ChatGPTWeb, getChatGPTWebModelsList_HTML } from '../js/mzta-utils.js';
-import { openAICompConfigs } from '../js/api/openai_comp_configs.js';
+import {
+ ChatGPTWeb_models,
+ checkSparksPresence,
+ isThunderbird128OrGreater,
+ openTab,
+ getChatGPTWebModelsList_HTML,
+ isAPIKeyValue,
+ getConnectionType,
+} from '../js/mzta-utils.js';
+import {
+ injectConnectionUI,
+ varConnectionUI,
+ showConnectionOptions,
+ updateWarnings
+} from '../pages/_lib/connection-ui.js';
let taLog = new taLogger("mzta-options",true);
let _isThunderbird128OrGreater = true;
-let permission_all_urls = false;
function saveOptions(e) {
e.preventDefault();
@@ -70,7 +77,7 @@ function saveOptions(e) {
async function restoreOptions() {
function setCurrentChoice(result) {
document.querySelectorAll(".option-input").forEach(element => {
- taLog.log("Options restoring " + element.id + " = " + (element.id=="chatgpt_api_key" || element.id=="openai_comp_api_key" || element.id=="google_gemini_api_key" || element.id=="anthropic_api_key" ? "****************" : result[element.id]));
+ taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
switch (element.type) {
case 'checkbox':
element.checked = result[element.id] || false;
@@ -109,211 +116,6 @@ async function restoreOptions() {
setCurrentChoice(getting);
}
-function showConnectionOptions() {
- disable_MaxPromptLength();
- disable_AddTags();
- disable_SpamFilter();
- disable_GetCalendarEvent();
- let chatgpt_web_display = 'table-row';
- let chatgpt_api_display = 'none';
- let ollama_api_display = 'none';
- let openai_comp_api_display = 'none';
- let google_gemini_api_display = 'none';
- let anthropic_api_display = 'none';
- let conntype_select = document.getElementById("connection_type");
- let parent = conntype_select.parentElement.parentElement.parentElement;
- parent.classList.toggle("conntype_chatgpt_web", (conntype_select.value === "chatgpt_web"));
- parent.classList.toggle("conntype_chatgpt_api", (conntype_select.value === "chatgpt_api"));
- parent.classList.toggle("conntype_ollama_api", (conntype_select.value === "ollama_api"));
- parent.classList.toggle("conntype_openai_comp_api", (conntype_select.value === "openai_comp_api"));
- parent.classList.toggle("conntype_google_gemini_api", (conntype_select.value === "google_gemini_api"));
- parent.classList.toggle("conntype_anthropic_api", (conntype_select.value === "anthropic_api"));
- if (conntype_select.value === "chatgpt_web") {
- chatgpt_web_display = 'table-row';
- }else{
- chatgpt_web_display = 'none';
- }
- if (conntype_select.value === "chatgpt_api") {
- chatgpt_api_display = 'table-row';
- }else{
- chatgpt_api_display = 'none';
- }
- if (conntype_select.value === "ollama_api") {
- ollama_api_display = 'table-row';
- }else{
- ollama_api_display = 'none';
- }
- if (conntype_select.value === "openai_comp_api") {
- openai_comp_api_display = 'table-row';
- }else{
- openai_comp_api_display = 'none';
- }
- if (conntype_select.value === "google_gemini_api") {
- google_gemini_api_display = 'table-row';
- }else{
- google_gemini_api_display = 'none';
- }
- if (conntype_select.value === "anthropic_api") {
- anthropic_api_display = 'table-row';
- }else{
- anthropic_api_display = 'none';
- }
- document.querySelectorAll(".conntype_chatgpt_web").forEach(element => {
- element.style.display = chatgpt_web_display;
- });
- document.querySelectorAll(".conntype_chatgpt_api").forEach(element => {
- element.style.display = chatgpt_api_display;
- });
- document.querySelectorAll(".conntype_ollama_api").forEach(element => {
- element.style.display = ollama_api_display;
- });
- document.querySelectorAll(".conntype_openai_comp_api").forEach(element => {
- element.style.display = openai_comp_api_display;
- });
- document.querySelectorAll(".conntype_google_gemini_api").forEach(element => {
- element.style.display = google_gemini_api_display;
- });
- document.querySelectorAll(".conntype_anthropic_api").forEach(element => {
- element.style.display = anthropic_api_display;
- });
- if (permission_all_urls) {
- document.getElementById('openai_comp_api_cors_warning').style.display = 'none';
- document.getElementById('ollama_api_cors_warning').style.display = 'none';
- }
-}
-
-function warn_ChatGPT_APIKeyEmpty() {
- let apiKeyInput = document.getElementById('chatgpt_api_key');
- let btnFetchChatGPTModels = document.getElementById('btnUpdateChatGPTModels');
- let modelChatGPT = document.getElementById('chatgpt_model');
- if(apiKeyInput.value === ''){
- apiKeyInput.style.border = '2px solid red';
- btnFetchChatGPTModels.disabled = true;
- modelChatGPT.disabled = true;
- modelChatGPT.selectedIndex = -1;
- modelChatGPT.style.border = '';
- }else{
- apiKeyInput.style.border = '';
- btnFetchChatGPTModels.disabled = false;
- modelChatGPT.disabled = false;
- if((modelChatGPT.selectedIndex === -1)||(modelChatGPT.value === '')){
- modelChatGPT.style.border = '2px solid red';
- }else{
- modelChatGPT.style.border = '';
- }
- }
-}
-
-function warn_GoogleGemini_APIKeyEmpty() {
- let apiKeyInput = document.getElementById('google_gemini_api_key');
- let btnFetchGoogleGeminiModels = document.getElementById('btnUpdateGoogleGeminiModels');
- let modelGoogleGemini = document.getElementById('google_gemini_model');
- if(apiKeyInput.value === ''){
- apiKeyInput.style.border = '2px solid red';
- btnFetchGoogleGeminiModels.disabled = true;
- modelGoogleGemini.disabled = true;
- modelGoogleGemini.selectedIndex = -1;
- modelGoogleGemini.style.border = '';
- }else{
- apiKeyInput.style.border = '';
- btnFetchGoogleGeminiModels.disabled = false;
- modelGoogleGemini.disabled = false;
- if((modelGoogleGemini.selectedIndex === -1)||(modelGoogleGemini.value === '')){
- modelGoogleGemini.style.border = '2px solid red';
- }else{
- modelGoogleGemini.style.border = '';
- }
- }
-}
-
-function warn_Ollama_HostEmpty() {
- let hostInput = document.getElementById('ollama_host');
- let btnFetchOllamaModels = document.getElementById('btnUpdateOllamaModels');
- let modelOllama = document.getElementById('ollama_model');
- if(hostInput.value === ''){
- hostInput.style.border = '2px solid red';
- btnFetchOllamaModels.disabled = true;
- modelOllama.disabled = true;
- modelOllama.selectedIndex = -1;
- modelOllama.style.border = '';
- }else{
- hostInput.style.border = '';
- btnFetchOllamaModels.disabled = false;
- modelOllama.disabled = false;
- if((modelOllama.selectedIndex === -1)||(modelOllama.value === '')){
- modelOllama.style.border = '2px solid red';
- }else{
- modelOllama.style.border = '';
- }
- }
-}
-
-function warn_OpenAIComp_HostEmpty() {
- let hostInput = document.getElementById('openai_comp_host');
- let btnUpdateOpenAICompModels = document.getElementById('btnUpdateOpenAICompModels');
- let modelOpenAIComp = document.getElementById('openai_comp_model');
- if(hostInput.value === ''){
- hostInput.style.border = '2px solid red';
- btnUpdateOpenAICompModels.disabled = true;
- modelOpenAIComp.disabled = true;
- modelOpenAIComp.selectedIndex = -1;
- modelOpenAIComp.style.border = '';
- }else{
- hostInput.style.border = '';
- btnUpdateOpenAICompModels.disabled = false;
- modelOpenAIComp.disabled = false;
- if((modelOpenAIComp.selectedIndex === -1)||(modelOpenAIComp.value === '')){
- modelOpenAIComp.style.border = '2px solid red';
- }else{
- modelOpenAIComp.style.border = '';
- }
- }
-}
-
-function warn_Anthropic_APIKeyEmpty() {
- let apiKeyInput = document.getElementById('anthropic_api_key');
- let btnFetchAnthropicModels = document.getElementById('btnUpdateAnthropicModels');
- let modelAnthropic = document.getElementById('anthropic_model');
- if(apiKeyInput.value === ''){
- apiKeyInput.style.border = '2px solid red';
- btnFetchAnthropicModels.disabled = true;
- modelAnthropic.disabled = true;
- modelAnthropic.selectedIndex = -1;
- modelAnthropic.style.border = '';
- }else{
- apiKeyInput.style.border = '';
- btnFetchAnthropicModels.disabled = false;
- modelAnthropic.disabled = false;
- if((modelAnthropic.selectedIndex === -1)||(modelAnthropic.value === '')){
- modelAnthropic.style.border = '2px solid red';
- }else{
- modelAnthropic.style.border = '';
- }
- }
-}
-
-function warn_Anthropic_VersionEmpty() {
- let versionInput = document.getElementById('anthropic_version');
- let btnFetchAnthropicModels = document.getElementById('btnUpdateAnthropicModels');
- let modelAnthropic = document.getElementById('anthropic_model');
- if(versionInput.value === ''){
- versionInput.style.border = '2px solid red';
- btnFetchAnthropicModels.disabled = true;
- modelAnthropic.disabled = true;
- modelAnthropic.selectedIndex = -1;
- modelAnthropic.style.border = '';
- }else{
- versionInput.style.border = '';
- btnFetchAnthropicModels.disabled = false;
- modelAnthropic.disabled = false;
- if((modelAnthropic.selectedIndex === -1)||(modelAnthropic.value === '')){
- modelAnthropic.style.border = '2px solid red';
- }else{
- modelAnthropic.style.border = '';
- }
- }
-}
-
function disable_MaxPromptLength(){
let maxPromptLength = document.getElementById('max_prompt_length');
let conntype_select = document.getElementById("connection_type");
@@ -322,39 +124,36 @@ function disable_MaxPromptLength(){
maxPromptLength_tr.style.display = (maxPromptLength.disabled) ? 'none' : 'table-row';
}
-function disable_AddTags(){
+function disable_AddTags(prefs_opt){
let add_tags = document.getElementById('add_tags');
let conntype_select = document.getElementById("connection_type");
- add_tags.disabled = (conntype_select.value === "chatgpt_web");
- add_tags.checked = add_tags.disabled ? false : add_tags.checked;
+ let add_tags_disabled = (getConnectionType(conntype_select.value, {api: prefs_opt.add_tags_use_specific_integration ? prefs_opt.add_tags_connection_type : ''}) === "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;
if(!add_tags.checked){
let add_tags_info_btn = document.getElementById('btnManageTagsInfo');
add_tags_info_btn.disabled = 'disabled';
}
- let add_tags_tr_elements = document.querySelectorAll('.add_tags_tr');
- add_tags_tr_elements.forEach(add_tags_tr => {
- add_tags_tr.style.display = (add_tags.disabled) ? 'none' : 'table-row';
- });
+ let add_tags_warn_API_needed = document.getElementById('add_tags_warn_API_needed');
+ add_tags_warn_API_needed.style.display = (add_tags_disabled) ? 'inline-block' : 'none';
if(add_tags_checked_original != add_tags.checked){
browser.storage.sync.set({add_tags: add_tags.checked});
}
}
-function disable_SpamFilter(){
+function disable_SpamFilter(prefs_opt){
let spamfilter = document.getElementById('spamfilter');
let conntype_select = document.getElementById("connection_type");
- spamfilter.disabled = (conntype_select.value === "chatgpt_web");
+ let spamfilter_disabled = (getConnectionType(conntype_select.value, {api: prefs_opt.spamfilter_use_specific_integration ? prefs_opt.spamfilter_connection_type : ''}) === "chatgpt_web");;
let spamfilter_checked_original = spamfilter.checked;
- spamfilter.checked = spamfilter.disabled ? false : spamfilter.checked;
+ spamfilter.checked = spamfilter_disabled ? false : spamfilter.checked;
if(!spamfilter.checked){
let spamfilter_info_btn = document.getElementById('btnManageSpamFilterInfo');
spamfilter_info_btn.disabled = 'disabled';
}
- let spamfilter_tr_elements = document.querySelectorAll('.spamfilter_tr');
- spamfilter_tr_elements.forEach(spamfilter_tr => {
- spamfilter_tr.style.display = (spamfilter.disabled) ? 'none' : 'table-row';
- });
+ let spamfilter_warn_API_needed = document.getElementById('spamfilter_warn_API_needed');
+ spamfilter_warn_API_needed.style.display = (spamfilter_disabled) ? 'inline-block' : 'none';
if(spamfilter_checked_original != spamfilter.checked){
browser.storage.sync.set({spamfilter: spamfilter.checked});
}
@@ -383,21 +182,6 @@ async function disable_GetCalendarEvent(){
wrong_sparks_text.style.display = (is_spark_present == 0) ? 'inline' : 'none';
}
-function loadOpenAICompConfigs(){
- let select_openai_comp_model = document.getElementById('openai_comp_services_shortcut');
- openAICompConfigs.forEach(config => {
- const option = document.createElement('option');
- option.value = config.id;
- option.text = config.name;
- select_openai_comp_model.appendChild(option);
- });
-}
-
-function resetOpenAICompConfigs(){
- let select_openai_comp_model = document.getElementById('openai_comp_services_shortcut');
- select_openai_comp_model.value = 'custom';
-}
-
function resetMaxPromptLength(){
let maxPromptLength = document.getElementById('max_prompt_length');
maxPromptLength.value = prefs_default.max_prompt_length;
@@ -405,9 +189,15 @@ function resetMaxPromptLength(){
}
document.addEventListener('DOMContentLoaded', async () => {
+ await injectConnectionUI({
+ afterTrId: 'connection_ui_anchor',
+ selectId: 'connection_type',
+ taLog: taLog
+ });
+
await restoreOptions();
- permission_all_urls = await messenger.permissions.contains({ origins: [""] })
+ varConnectionUI.permission_all_urls = await messenger.permissions.contains({ origins: [""] })
_isThunderbird128OrGreater = await isThunderbird128OrGreater();
@@ -502,39 +292,6 @@ document.addEventListener('DOMContentLoaded', async () => {
openTab('/pages/get-task/mzta-get-task.html');
});
- document.getElementById('btnOpenAICompForceModel').addEventListener('click', () => {
- let modelName = prompt(browser.i18n.getMessage('OpenAIComp_force_model_ask')).trim();
- if ((modelName !== null) && (modelName !== undefined) && (modelName !== '')) {
- let select_openai_comp_model = document.getElementById('openai_comp_model');
- let option = document.createElement('option');
- option.value = modelName;
- option.text = modelName;
- select_openai_comp_model.appendChild(option);
- select_openai_comp_model.value = modelName;
- select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
- }
- });
-
- document.getElementById('btnOpenAICompClearModelsList').addEventListener('click', () => {
- if (!confirm(browser.i18n.getMessage('OpenAIComp_ClearModelsList_Confirm'))) {
- return;
- }
- let select_openai_comp_model = document.getElementById('openai_comp_model');
- while (select_openai_comp_model.options.length > 0) {
- select_openai_comp_model.remove(0);
- }
- select_openai_comp_model.value = '';
- select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
- });
-
- document.getElementById('btnGiveAllUrlsPermission_ollama_api').addEventListener('click', async () => {
- permission_all_urls = await messenger.permissions.request({ origins: [""] });
- });
-
- document.getElementById('btnGiveAllUrlsPermission_openai_comp_api').addEventListener('click', async () => {
- permission_all_urls = await messenger.permissions.request({ origins: [""] });
- });
-
getChatGPTWebModelsList_HTML(ChatGPTWeb_models, 'chatgpt_web_models_list');
document.querySelectorAll(".conntype_chatgpt_web_option").forEach(element => {
element.addEventListener("click", () => {
@@ -544,348 +301,26 @@ 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,
+ });
+
let conntype_select = document.getElementById("connection_type");
- conntype_select.addEventListener("change", showConnectionOptions);
- conntype_select.addEventListener("change", warn_ChatGPT_APIKeyEmpty);
- conntype_select.addEventListener("change", warn_Ollama_HostEmpty);
- conntype_select.addEventListener("change", warn_OpenAIComp_HostEmpty);
- conntype_select.addEventListener("change", warn_GoogleGemini_APIKeyEmpty);
- conntype_select.addEventListener("change", warn_Anthropic_APIKeyEmpty);
- conntype_select.addEventListener("change", warn_Anthropic_VersionEmpty);
- conntype_select.addEventListener("change", disable_AddTags);
- conntype_select.addEventListener("change", disable_SpamFilter);
+ conntype_select.addEventListener("change", disable_MaxPromptLength);
+ conntype_select.addEventListener("change", () => disable_AddTags(prefs_opt));
+ conntype_select.addEventListener("change", () => disable_SpamFilter(prefs_opt));
conntype_select.addEventListener("change", disable_GetCalendarEvent);
- document.getElementById("chatgpt_api_key").addEventListener("change", warn_ChatGPT_APIKeyEmpty);
- document.getElementById("ollama_host").addEventListener("change", warn_Ollama_HostEmpty);
- document.getElementById("openai_comp_host").addEventListener("change", warn_OpenAIComp_HostEmpty);
- document.getElementById("google_gemini_api_key").addEventListener("change", warn_GoogleGemini_APIKeyEmpty);
- document.getElementById("chatgpt_web_project").addEventListener("input", validateCustomData_ChatGPTWeb);
- document.getElementById("chatgpt_web_custom_gpt").addEventListener("input", validateCustomData_ChatGPTWeb);
- document.getElementById("anthropic_api_key").addEventListener("change", warn_Anthropic_APIKeyEmpty);
- document.getElementById("anthropic_version").addEventListener("change", warn_Anthropic_VersionEmpty);
- 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);
-
- let prefs = await browser.storage.sync.get({chatgpt_web_model: '', chatgpt_model: '', ollama_model: '', openai_comp_model: '', google_gemini_model: '', anthropic_model: '', anthropic_version: '', chatgpt_win_height: 0, chatgpt_win_width: 0 });
-
- // OpenAI API ChatGPT model fetching
- let select_chatgpt_model = document.getElementById('chatgpt_model');
- const chatgpt_option = document.createElement('option');
- chatgpt_option.value = prefs.chatgpt_model;
- chatgpt_option.text = prefs.chatgpt_model;
- select_chatgpt_model.appendChild(chatgpt_option);
- select_chatgpt_model.addEventListener("change", warn_ChatGPT_APIKeyEmpty);
-
- 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,
- stream: true
- });
- openai.fetchModels().then((data) => {
- if(!data.ok){
- let errorDetail;
- try {
- errorDetail = JSON.parse(data.error);
- errorDetail = errorDetail.error.message;
- } catch (e) {
- errorDetail = data.error;
- }
- document.getElementById('chatgpt_model_fetch_loading').style.display = 'none';
- console.error("[ThunderAI] " + browser.i18n.getMessage("ChatGPT_Models_Error_fetching"));
- alert(browser.i18n.getMessage("ChatGPT_Models_Error_fetching")+": " + errorDetail);
- return;
- }
- taLog.log("ChatGPT models: " + JSON.stringify(data));
- data.response.forEach(model => {
- if (!Array.from(select_chatgpt_model.options).some(option => option.value === model.id)) {
- const option = document.createElement('option');
- option.value = model.id;
- option.text = model.id;
- select_chatgpt_model.appendChild(option);
- }
- });
- document.getElementById('chatgpt_model_fetch_loading').style.display = 'none';
- });
-
- warn_ChatGPT_APIKeyEmpty();
- });
-
- // Google Gemini API model fetching
- let select_google_gemini_model = document.getElementById('google_gemini_model');
- const google_gemini_option = document.createElement('option');
- google_gemini_option.value = prefs.google_gemini_model;
- google_gemini_option.text = prefs.google_gemini_model;
- select_google_gemini_model.appendChild(google_gemini_option);
- select_google_gemini_model.addEventListener("change", warn_GoogleGemini_APIKeyEmpty);
-
- 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,
- stream: true
- });
- google_gemini.fetchModels().then((data) => {
- if(!data.ok){
- let errorDetail;
- try {
- errorDetail = JSON.parse(data.error);
- errorDetail = errorDetail.error.message;
- } catch (e) {
- errorDetail = data.error;
- }
- document.getElementById('google_gemini_model_fetch_loading').style.display = 'none';
- console.error("[ThunderAI] " + browser.i18n.getMessage("GoogleGemini_Models_Error_fetching"));
- alert(browser.i18n.getMessage("GoogleGemini_Models_Error_fetching")+": " + errorDetail);
- return;
- }
- taLog.log("GoogleGemini models: " + JSON.stringify(data));
- data.response.forEach(model => {
- if (!Array.from(select_google_gemini_model.options).some(option => option.value === model.name.substring(model.name.lastIndexOf("/") + 1))) {
- const option = document.createElement('option');
- option.value = model.name.substring(model.name.lastIndexOf("/") + 1);
- option.text = model.displayName;
- select_google_gemini_model.appendChild(option);
- }
- });
- document.getElementById('google_gemini_model_fetch_loading').style.display = 'none';
- });
-
- warn_GoogleGemini_APIKeyEmpty();
- });
-
- // Ollama API Model fetching
- let select_ollama_model = document.getElementById('ollama_model');
- const ollama_option = document.createElement('option');
- ollama_option.value = prefs.ollama_model;
- ollama_option.text = prefs.ollama_model;
- select_ollama_model.appendChild(ollama_option);
- select_ollama_model.addEventListener("change", warn_Ollama_HostEmpty);
-
- 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,
- stream: true
- });
- try {
- let data = await ollama.fetchModels();
- if(!data){
- document.getElementById('ollama_model_fetch_loading').style.display = 'none';
- console.error("[ThunderAI] " + browser.i18n.getMessage("Ollama_Models_Error_fetching"));
- alert(browser.i18n.getMessage("Ollama_Models_Error_fetching"));
- return;
- }
- if(!data.ok){
- let errorDetail;
- try {
- errorDetail = JSON.parse(data.error);
- errorDetail = errorDetail.error.message;
- } catch (e) {
- errorDetail = data.error;
- }
- document.getElementById('ollama_model_fetch_loading').style.display = 'none';
- console.error("[ThunderAI] " + browser.i18n.getMessage("Ollama_Models_Error_fetching"));
- alert(browser.i18n.getMessage("Ollama_Models_Error_fetching")+": " + errorDetail);
- return;
- }
- if(data.response.models.length == 0){
- document.getElementById('ollama_model_fetch_loading').style.display = 'none';
- 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"));
- return;
- }
- taLog.log("Ollama models: " + JSON.stringify(data));
- data.response.models.forEach(model => {
- if (!Array.from(select_ollama_model.options).some(option => option.value === model.model)) {
- const option = document.createElement('option');
- option.value = model.model;
- option.text = model.name + " (" + model.model + ")";
- select_ollama_model.appendChild(option);
- }
- });
- document.getElementById('ollama_model_fetch_loading').style.display = 'none';
- } catch (error) {
- document.getElementById('ollama_model_fetch_loading').style.display = 'none';
- taLog.error(browser.i18n.getMessage("Ollama_Models_Error_fetching"));
- alert(browser.i18n.getMessage("Ollama_Models_Error_fetching")+": " + error.message);
- }
-
- warn_Ollama_HostEmpty();
- });
-
-
- // OpenAI Comp API Model fetching
- let select_openai_comp_model = document.getElementById('openai_comp_model');
- const openai_comp_option = document.createElement('option');
- openai_comp_option.value = prefs.openai_comp_model;
- openai_comp_option.text = prefs.openai_comp_model;
- select_openai_comp_model.appendChild(openai_comp_option);
- select_openai_comp_model.addEventListener("change", warn_OpenAIComp_HostEmpty);
-
- 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,
- model: null,
- apiKey: document.getElementById("openai_comp_api_key").value,
- stream: true,
- use_v1: document.getElementById("openai_comp_use_v1").checked
- });
- openai_comp.fetchModels().then((data) => {
- if(!data.ok){
- let errorDetail;
- try {
- errorDetail = JSON.parse(data.error);
- errorDetail = errorDetail.error.message;
- } catch (e) {
- errorDetail = data.error;
- }
- document.getElementById('openai_comp_model_fetch_loading').style.display = 'none';
- console.error("[ThunderAI] " + browser.i18n.getMessage("OpenAIComp_Models_Error_fetching"));
- alert(browser.i18n.getMessage("OpenAIComp_Models_Error_fetching")+": " + errorDetail);
- return;
- }
- taLog.log("OpenAIComp models: " + JSON.stringify(data));
- data.response.forEach(model => {
- if (!Array.from(select_openai_comp_model.options).some(option => option.value === model.id)) {
- const option = document.createElement('option');
- option.value = model.id;
- option.text = model.id;
- select_openai_comp_model.appendChild(option);
- }
- });
- document.getElementById('openai_comp_model_fetch_loading').style.display = 'none';
- });
-
- warn_OpenAIComp_HostEmpty();
- });
-
- // Anthropic API model fetching
- let select_anthropic_model = document.getElementById('anthropic_model');
- const anthropic_option = document.createElement('option');
- anthropic_option.value = prefs.anthropic_model;
- anthropic_option.text = prefs.anthropic_model;
- select_anthropic_model.appendChild(anthropic_option);
- select_anthropic_model.addEventListener("change", warn_Anthropic_APIKeyEmpty);
- select_anthropic_model.addEventListener("change", warn_Anthropic_VersionEmpty);
-
- 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
- });
- anthropic.fetchModels().then((data) => {
- if(!data.ok){
- let errorDetail;
- try {
- errorDetail = JSON.parse(data.error);
- errorDetail = errorDetail.error.message;
- } catch (e) {
- errorDetail = data.error;
- }
- document.getElementById('anthropic_model_fetch_loading').style.display = 'none';
- console.error("[ThunderAI] " + browser.i18n.getMessage("Anthropic_Models_Error_fetching"));
- alert(browser.i18n.getMessage("Anthropic_Models_Error_fetching")+": " + errorDetail);
- return;
- }
- taLog.log("Anthropic models: " + JSON.stringify(data));
- data.response.forEach(model => {
- const existingOption = Array.from(select_anthropic_model.options).find(option => option.value === model.id);
- if (existingOption) {
- existingOption.text = model.display_name + " (" + model.id + ")";
- } else {
- const option = document.createElement('option');
- option.value = model.id;
- option.text = model.display_name + " (" + model.id + ")";
- select_anthropic_model.appendChild(option);
- }
- });
- document.getElementById('anthropic_model_fetch_loading').style.display = 'none';
- });
-
- warn_Anthropic_APIKeyEmpty();
- });
-
- showConnectionOptions();
- warn_ChatGPT_APIKeyEmpty();
- warn_Ollama_HostEmpty();
- warn_OpenAIComp_HostEmpty();
- warn_GoogleGemini_APIKeyEmpty();
- warn_Anthropic_APIKeyEmpty();
- warn_Anthropic_VersionEmpty();
+ showConnectionOptions(conntype_select);
disable_MaxPromptLength();
- disable_AddTags();
- disable_SpamFilter();
+ disable_AddTags(prefs_opt);
+ disable_SpamFilter(prefs_opt);
disable_GetCalendarEvent();
- const passwordField_chatgpt_api_key = document.getElementById('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');
-
- toggleIcon_chatgpt_api_key.addEventListener('click', () => {
- const type = passwordField_chatgpt_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
- passwordField_chatgpt_api_key.setAttribute('type', type);
-
- 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 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');
-
- toggleIcon_google_gemini_api_key.addEventListener('click', () => {
- const type = passwordField_google_gemini_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
- passwordField_google_gemini_api_key.setAttribute('type', type);
-
- 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 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');
-
- toggleIcon_openai_comp_api_key.addEventListener('click', () => {
- const type = passwordField_openai_comp_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
- passwordField_openai_comp_api_key.setAttribute('type', type);
-
- 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 toggleIcon_anthropic_api_key = document.getElementById('toggle_anthropic_api_key');
- const icon_img_anthropic_api_key = document.getElementById('pwd-icon_anthropic_api_key');
-
- toggleIcon_anthropic_api_key.addEventListener('click', () => {
- const type = passwordField_anthropic_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
- passwordField_anthropic_api_key.setAttribute('type', type);
-
- icon_img_anthropic_api_key.src = type === 'password' ? "../images/pwd-show.png" : "../images/pwd-hide.png";
- });
-
- const btnChatGPTWeb_Tab = document.getElementById('btnChatGPTWeb_Tab');
- btnChatGPTWeb_Tab.addEventListener('click', async () => {
- let prefs_mod = await browser.storage.sync.get({chatgpt_web_model: prefs_default.chatgpt_web_model, chatgpt_web_project: prefs_default.chatgpt_web_project, chatgpt_web_custom_gpt: prefs_default.chatgpt_web_custom_gpt});
-
- let base_url = 'https://chatgpt.com';
- let model_opt = '';
- let webproject_set = false;
-
- if((prefs_mod.chatgpt_web_model != '') && (prefs_mod.chatgpt_web_model != undefined)){
- model_opt = '?model=' + sanitizeChatGPTModelData(prefs_mod.chatgpt_web_model);
- }
- if((prefs_mod.chatgpt_web_project != '') && (prefs_mod.chatgpt_web_project != undefined)){
- base_url += sanitizeChatGPTWebCustomData(prefs_mod.chatgpt_web_project);
- webproject_set = true;
- }
- if(!webproject_set && (prefs_mod.chatgpt_web_custom_gpt != '') && (prefs_mod.chatgpt_web_custom_gpt != undefined)){
- base_url += sanitizeChatGPTWebCustomData(prefs_mod.chatgpt_web_custom_gpt);
- }
- browser.tabs.create({ url: base_url + model_opt });
- });
+ document.getElementById('reset_max_prompt_length').addEventListener('click', resetMaxPromptLength);
browser.runtime.getPlatformInfo().then(info => {
taLog.log("OS: " + info.os);
@@ -894,32 +329,6 @@ document.addEventListener('DOMContentLoaded', async () => {
}
});
- loadOpenAICompConfigs();
- let select_openai_comp_services_shortcut = document.getElementById('openai_comp_services_shortcut');
- select_openai_comp_services_shortcut.addEventListener("change", () => {
- let selectedOption = select_openai_comp_services_shortcut.options[select_openai_comp_services_shortcut.selectedIndex];
- const config = openAICompConfigs.find(cfg => cfg.id === selectedOption.value);
- if (config) {
- if (!confirm(browser.i18n.getMessage('OpenAIComp_Configs_ConfirmApply', config.name))) {
- return;
- }
- document.getElementById('openai_comp_host').value = config.host || '';
- // Clear all options from the select except the first (placeholder) one
- const openaiCompModelSelect = document.getElementById('openai_comp_model');
- 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 || '';
- // Trigger change events if needed
- document.getElementById('openai_comp_host').dispatchEvent(new Event('change', { bubbles: true }));
- document.getElementById('openai_comp_model').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('reset_max_prompt_length').addEventListener('click', resetMaxPromptLength);
+ updateWarnings();
}, { once: true });
diff --git a/options/mzta-release-notes.html b/options/mzta-release-notes.html
index f883c3ff..151b870b 100644
--- a/options/mzta-release-notes.html
+++ b/options/mzta-release-notes.html
@@ -13,6 +13,7 @@
[ChatGPT Web] Added a message to explain to click on "Force completion" if the ChatGPT job is not done after 7 seconds [#419].
[All APIs] The prompt id and name are now shown in the information header in the AI API chat [#436].
[Google Gemini API]Support for the thinkingBudget parameter has been added [#494].
+ Various code improvements and minor bugs fixed.
...
Version 3.6.1 - 23/08/2025
diff --git a/pages/_lib/connection-ui.css b/pages/_lib/connection-ui.css
new file mode 100644
index 00000000..5b63569d
--- /dev/null
+++ b/pages/_lib/connection-ui.css
@@ -0,0 +1,118 @@
+tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
+ background-color: rgb(185, 220, 252);
+}
+
+tr.conntype_chatgpt_web, tr.conntype_chatgpt_web2{
+ background-color: rgb(255, 209, 183);
+}
+
+tr.conntype_ollama_api, tr.conntype_ollama_api2{
+ background-color: rgb(177, 238, 169);
+}
+
+tr.conntype_openai_comp_api, tr.conntype_openai_comp_api2{
+ background-color: rgb(213, 169, 238);
+}
+
+tr.conntype_google_gemini_api, tr.conntype_google_gemini_api2{
+ background-color: rgb(233, 238, 169);
+}
+
+tr.conntype_anthropic_api, tr.conntype_anthropic_api2{
+ background-color: rgb(255, 168, 204);
+}
+
+#chatgpt_model_fetch_loading{
+ display: none;
+ font-style: italic;
+}
+
+#google_gemini_model_fetch_loading{
+ display: none;
+ font-style: italic;
+}
+
+textarea.option-textarea{
+ width: -moz-available;
+ height: 10em;
+}
+
+.api_key-container {
+ position: relative;
+ width: 100%;
+}
+
+.api_key-container input {
+ width: -moz-available;
+ margin-right: 25px;
+}
+
+input[type="text"], input[type="password"]{
+ border-radius: 4px;
+ padding: 2px;
+}
+
+input.option-input[type="text"]{
+ width: -moz-available;
+}
+
+.api_key-container .toggle-icon {
+ position: absolute;
+ right: 0px;
+ top: 50%;
+ transform: translateY(-50%);
+ cursor: pointer;
+}
+
+#ollama_model_fetch_loading{
+ display: none;
+ font-style: italic;
+}
+
+#openai_comp_model_fetch_loading{
+ display: none;
+ font-style: italic;
+}
+
+#anthropic_model_fetch_loading{
+ display: none;
+ font-style: italic;
+}
+
+.conntype_chatgpt_web_option{
+ cursor: pointer;
+}
+
+span.opt_title{
+ font-weight: bold;
+}
+
+@media (prefers-color-scheme: dark) {
+ tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
+ background-color: rgb(0, 0, 58);
+ }
+
+ tr.conntype_chatgpt_web,tr.conntype_chatgpt_web2{
+ background-color: rgb(39, 11, 0);
+ }
+
+ tr.conntype_ollama_api, tr.conntype_ollama_api2{
+ background-color: rgb(7, 58, 0);
+ }
+
+ tr.conntype_openai_comp_api, tr.conntype_openai_comp_api2{
+ background-color: rgb(89, 20, 129);
+ }
+
+ tr.conntype_google_gemini_api, tr.conntype_google_gemini_api2{
+ background-color: rgb(72, 77, 3);
+ }
+
+ tr.conntype_anthropic_api, tr.conntype_anthropic_api2{
+ background-color: rgb(83, 0, 35);
+ }
+
+ .api_key-container .toggle-icon img {
+ filter: invert(1);
+ }
+}
\ No newline at end of file
diff --git a/pages/_lib/connection-ui.js b/pages/_lib/connection-ui.js
new file mode 100644
index 00000000..eaee61bf
--- /dev/null
+++ b/pages/_lib/connection-ui.js
@@ -0,0 +1,1103 @@
+/*
+ * ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
+ * Copyright (C) 2024 - 2025 Mic (m@micz.it)
+
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+import { OpenAI } from '../../js/api/openai.js';
+import { Ollama } from '../../js/api/ollama.js';
+import { OpenAIComp } from '../../js/api/openai_comp.js'
+import { GoogleGemini } from '../../js/api/google_gemini.js';
+import { Anthropic } from '../../js/api/anthropic.js';
+import {
+ validateCustomData_ChatGPTWeb,
+ sanitizeChatGPTModelData,
+ sanitizeChatGPTWebCustomData
+} from '../../js/mzta-utils.js';
+import { openAICompConfigs } from '../../js/api/openai_comp_configs.js';
+
+export const varConnectionUI = {
+ permission_all_urls: false
+}
+
+export async function injectConnectionUI({
+ afterTrId = '',
+ selectId = '',
+ modelId_prefix = '',
+ no_chatgpt_web = false,
+ defaultType = '',
+ tr_class = '',
+ taLog = console
+ } = {}) {
+
+ const anchorTr = document.getElementById(afterTrId);
+ if (!anchorTr) {
+ console.error(`[ThuderAI | injectConnectionUI] Can't find tr#${afterTrId}`);
+ return null;
+ }
+
+ let tpl = `
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ __MSG_OpenChatGPTTab_Info__
+
+
__MSG_OpenChatGPTTab_Info2__
+ |
+
+
+ |
+
+
+
+ 
+
+ |
+
+
+ |
+
+ |
+
+ __MSG_Loading__
+
+ |
+
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+ 
+
+ |
+
+
+ |
+
+ |
+
+ __MSG_Loading__
+
+ |
+
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+ __MSG_remember_CORS__ [__MSG_more_info_string__]
+
__MSG_CORS_alternative_1__
+ __MSG_CORS_alternative_2__
+
+ |
+
+
+ |
+
+ |
+
+ __MSG_Loading__
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+ __MSG_maybe_CORS_openai_comp__ [__MSG_more_info_string__]
+
__MSG_CORS_alternative_1__
+ __MSG_CORS_alternative_2__
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+ 
+
+ |
+
+
+ |
+ |
+
+
+
+ __MSG_Loading__
+
+ |
+
+
+ |
+
+
+ |
+
+
+ |
+
+
+
+ 
+
+ |
+
+
+ |
+
+ |
+
+ __MSG_Loading__
+
+ |
+
+
+ |
+
+ |
+
+
+ |
+
+
+ | __MSG_prefs_OptionText_anthropic_max_tokens__ |
+
+
+ |
+
+ `;
+
+ const template = document.createElement('template');
+ template.innerHTML = tpl.trim();
+ const frag = template.content;
+
+ const parent = anchorTr.parentElement;
+ const nodes = Array.from(frag.childNodes);
+ let last = anchorTr;
+ nodes.forEach(node => {
+ if (node.nodeType === Node.ELEMENT_NODE) {
+ parent.insertBefore(node, last.nextSibling);
+ last = node;
+ }
+ });
+
+ // 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); };
+ // const bindInput = (id, cb) => { const el = document.getElementById(id); if (el && typeof cb === 'function') el.addEventListener('input', cb); };
+
+ populateConnectionTypeOptions(selectId, no_chatgpt_web);
+
+ let conntype_select = document.getElementById(selectId);
+
+ if (!conntype_select) {
+ console.error('[ThuderAI | injectConnectionUI] Select not found after insertion.');
+ }
+
+ conntype_select.addEventListener("change", () => showConnectionOptions(conntype_select));
+ conntype_select.addEventListener("change", (ev) => warn_ChatGPT_APIKeyEmpty(modelId_prefix));
+ conntype_select.addEventListener("change", (ev) => warn_Ollama_HostEmpty(modelId_prefix));
+ conntype_select.addEventListener("change", (ev) => warn_OpenAIComp_HostEmpty(modelId_prefix));
+ conntype_select.addEventListener("change", (ev) => warn_GoogleGemini_APIKeyEmpty(modelId_prefix));
+ conntype_select.addEventListener("change", (ev) => warn_Anthropic_APIKeyEmpty(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_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);
+
+ showConnectionOptions(conntype_select);
+ loadOpenAICompConfigs();
+ warn_ChatGPT_APIKeyEmpty(modelId_prefix);
+ warn_Ollama_HostEmpty(modelId_prefix);
+ warn_OpenAIComp_HostEmpty(modelId_prefix);
+ warn_GoogleGemini_APIKeyEmpty(modelId_prefix);
+ warn_Anthropic_APIKeyEmpty(modelId_prefix);
+ warn_Anthropic_VersionEmpty(modelId_prefix);
+
+ const passwordField_chatgpt_api_key = document.getElementById('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');
+
+ toggleIcon_chatgpt_api_key.addEventListener('click', () => {
+ const type = passwordField_chatgpt_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
+ passwordField_chatgpt_api_key.setAttribute('type', type);
+
+ 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 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');
+
+ toggleIcon_google_gemini_api_key.addEventListener('click', () => {
+ const type = passwordField_google_gemini_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
+ passwordField_google_gemini_api_key.setAttribute('type', type);
+
+ 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 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');
+
+ toggleIcon_openai_comp_api_key.addEventListener('click', () => {
+ const type = passwordField_openai_comp_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
+ passwordField_openai_comp_api_key.setAttribute('type', type);
+
+ 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 toggleIcon_anthropic_api_key = document.getElementById('toggle_anthropic_api_key');
+ const icon_img_anthropic_api_key = document.getElementById('pwd-icon_anthropic_api_key');
+
+ toggleIcon_anthropic_api_key.addEventListener('click', () => {
+ const type = passwordField_anthropic_api_key.getAttribute('type') === 'password' ? 'text' : 'password';
+ passwordField_anthropic_api_key.setAttribute('type', type);
+
+ icon_img_anthropic_api_key.src = type === 'password' ? "/images/pwd-show.png" : "/images/pwd-hide.png";
+ });
+
+ const btnChatGPTWeb_Tab = document.getElementById('btnChatGPTWeb_Tab');
+ btnChatGPTWeb_Tab.addEventListener('click', async () => {
+ let prefs_mod = await browser.storage.sync.get({chatgpt_web_model: prefs_default.chatgpt_web_model, chatgpt_web_project: prefs_default.chatgpt_web_project, chatgpt_web_custom_gpt: prefs_default.chatgpt_web_custom_gpt});
+
+ let base_url = 'https://chatgpt.com';
+ let model_opt = '';
+ let webproject_set = false;
+
+ if((prefs_mod.chatgpt_web_model != '') && (prefs_mod.chatgpt_web_model != undefined)){
+ model_opt = '?model=' + sanitizeChatGPTModelData(prefs_mod.chatgpt_web_model);
+ }
+ if((prefs_mod.chatgpt_web_project != '') && (prefs_mod.chatgpt_web_project != undefined)){
+ base_url += sanitizeChatGPTWebCustomData(prefs_mod.chatgpt_web_project);
+ webproject_set = true;
+ }
+ if(!webproject_set && (prefs_mod.chatgpt_web_custom_gpt != '') && (prefs_mod.chatgpt_web_custom_gpt != undefined)){
+ base_url += sanitizeChatGPTWebCustomData(prefs_mod.chatgpt_web_custom_gpt);
+ }
+ browser.tabs.create({ url: base_url + model_opt });
+ });
+
+ let select_openai_comp_services_shortcut = document.getElementById('openai_comp_services_shortcut');
+ select_openai_comp_services_shortcut.addEventListener("change", () => {
+ let selectedOption = select_openai_comp_services_shortcut.options[select_openai_comp_services_shortcut.selectedIndex];
+ const config = openAICompConfigs.find(cfg => cfg.id === selectedOption.value);
+ if (config) {
+ if (!confirm(browser.i18n.getMessage('OpenAIComp_Configs_ConfirmApply', config.name))) {
+ return;
+ }
+ document.getElementById('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 || '';
+ // Trigger change events if needed
+ document.getElementById('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 }));
+ }
+ });
+
+ let prefs = await browser.storage.sync.get({chatgpt_web_model: '', chatgpt_model: '', ollama_model: '', openai_comp_model: '', google_gemini_model: '', anthropic_model: '', anthropic_version: '', chatgpt_win_height: 0, chatgpt_win_width: 0 });
+
+ // OpenAI API ChatGPT model fetching
+ let select_chatgpt_model = getModelEl('chatgpt_model', modelId_prefix);
+ const chatgpt_option = document.createElement('option');
+ chatgpt_option.value = prefs.chatgpt_model;
+ chatgpt_option.text = prefs.chatgpt_model;
+ select_chatgpt_model.appendChild(chatgpt_option);
+ select_chatgpt_model.addEventListener("change", () => warn_ChatGPT_APIKeyEmpty(modelId_prefix));
+
+ document.getElementById('btnUpdateChatGPTModels').addEventListener('click', async () => {
+ document.getElementById('chatgpt_model_fetch_loading').style.display = 'inline';
+ let openai = new OpenAI(document.getElementById("chatgpt_api_key").value, '', true);
+ openai.fetchModels().then((data) => {
+ if(!data.ok){
+ let errorDetail;
+ try {
+ errorDetail = JSON.parse(data.error);
+ errorDetail = errorDetail.error.message;
+ } catch (e) {
+ errorDetail = data.error;
+ }
+ document.getElementById('chatgpt_model_fetch_loading').style.display = 'none';
+ console.error("[ThunderAI] " + browser.i18n.getMessage("ChatGPT_Models_Error_fetching"));
+ alert(browser.i18n.getMessage("ChatGPT_Models_Error_fetching")+": " + errorDetail);
+ return;
+ }
+ taLog.log("ChatGPT models: " + JSON.stringify(data));
+ data.response.forEach(model => {
+ if (!Array.from(select_chatgpt_model.options).some(option => option.value === model.id)) {
+ const option = document.createElement('option');
+ option.value = model.id;
+ option.text = model.id;
+ select_chatgpt_model.appendChild(option);
+ }
+ });
+ document.getElementById('chatgpt_model_fetch_loading').style.display = 'none';
+ });
+
+ warn_ChatGPT_APIKeyEmpty(modelId_prefix);
+ });
+
+ // Google Gemini API model fetching
+ let select_google_gemini_model = getModelEl('google_gemini_model', modelId_prefix);
+ const google_gemini_option = document.createElement('option');
+ google_gemini_option.value = prefs.google_gemini_model;
+ google_gemini_option.text = prefs.google_gemini_model;
+ select_google_gemini_model.appendChild(google_gemini_option);
+ select_google_gemini_model.addEventListener("change", () => warn_GoogleGemini_APIKeyEmpty(modelId_prefix));
+
+ document.getElementById('btnUpdateGoogleGeminiModels').addEventListener('click', async () => {
+ document.getElementById('google_gemini_model_fetch_loading').style.display = 'inline';
+ let google_gemini = new GoogleGemini(document.getElementById("google_gemini_api_key").value, '', true);
+ google_gemini.fetchModels().then((data) => {
+ if(!data.ok){
+ let errorDetail;
+ try {
+ errorDetail = JSON.parse(data.error);
+ errorDetail = errorDetail.error.message;
+ } catch (e) {
+ errorDetail = data.error;
+ }
+ document.getElementById('google_gemini_model_fetch_loading').style.display = 'none';
+ console.error("[ThunderAI] " + browser.i18n.getMessage("GoogleGemini_Models_Error_fetching"));
+ alert(browser.i18n.getMessage("GoogleGemini_Models_Error_fetching")+": " + errorDetail);
+ return;
+ }
+ taLog.log("GoogleGemini models: " + JSON.stringify(data));
+ data.response.forEach(model => {
+ if (!Array.from(select_google_gemini_model.options).some(option => option.value === model.name.substring(model.name.lastIndexOf("/") + 1))) {
+ const option = document.createElement('option');
+ option.value = model.name.substring(model.name.lastIndexOf("/") + 1);
+ option.text = model.displayName;
+ select_google_gemini_model.appendChild(option);
+ }
+ });
+ document.getElementById('google_gemini_model_fetch_loading').style.display = 'none';
+ });
+
+ warn_GoogleGemini_APIKeyEmpty(modelId_prefix);
+ });
+
+ // Ollama API Model fetching
+ let select_ollama_model = getModelEl('ollama_model', modelId_prefix);
+ const ollama_option = document.createElement('option');
+ ollama_option.value = prefs.ollama_model;
+ ollama_option.text = prefs.ollama_model;
+ select_ollama_model.appendChild(ollama_option);
+ select_ollama_model.addEventListener("change", () => warn_Ollama_HostEmpty(modelId_prefix));
+
+ document.getElementById('btnUpdateOllamaModels').addEventListener('click', async () => {
+ document.getElementById('ollama_model_fetch_loading').style.display = 'inline';
+ let ollama = new Ollama(document.getElementById("ollama_host").value, true);
+ try {
+ let data = await ollama.fetchModels();
+ if(!data){
+ document.getElementById('ollama_model_fetch_loading').style.display = 'none';
+ console.error("[ThunderAI] " + browser.i18n.getMessage("Ollama_Models_Error_fetching"));
+ alert(browser.i18n.getMessage("Ollama_Models_Error_fetching"));
+ return;
+ }
+ if(!data.ok){
+ let errorDetail;
+ try {
+ errorDetail = JSON.parse(data.error);
+ errorDetail = errorDetail.error.message;
+ } catch (e) {
+ errorDetail = data.error;
+ }
+ document.getElementById('ollama_model_fetch_loading').style.display = 'none';
+ console.error("[ThunderAI] " + browser.i18n.getMessage("Ollama_Models_Error_fetching"));
+ alert(browser.i18n.getMessage("Ollama_Models_Error_fetching")+": " + errorDetail);
+ return;
+ }
+ if(data.response.models.length == 0){
+ document.getElementById('ollama_model_fetch_loading').style.display = 'none';
+ 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"));
+ return;
+ }
+ taLog.log("Ollama models: " + JSON.stringify(data));
+ data.response.models.forEach(model => {
+ if (!Array.from(select_ollama_model.options).some(option => option.value === model.model)) {
+ const option = document.createElement('option');
+ option.value = model.model;
+ option.text = model.name + " (" + model.model + ")";
+ select_ollama_model.appendChild(option);
+ }
+ });
+ document.getElementById('ollama_model_fetch_loading').style.display = 'none';
+ } catch (error) {
+ document.getElementById('ollama_model_fetch_loading').style.display = 'none';
+ taLog.error(browser.i18n.getMessage("Ollama_Models_Error_fetching"));
+ alert(browser.i18n.getMessage("Ollama_Models_Error_fetching")+": " + error.message);
+ }
+
+ warn_Ollama_HostEmpty(modelId_prefix);
+ });
+
+ // OpenAI Comp API Model fetching
+ let select_openai_comp_model = getModelEl('openai_comp_model', modelId_prefix);
+ const openai_comp_option = document.createElement('option');
+ openai_comp_option.value = prefs.openai_comp_model;
+ openai_comp_option.text = prefs.openai_comp_model;
+ select_openai_comp_model.appendChild(openai_comp_option);
+ select_openai_comp_model.addEventListener("change", () => warn_OpenAIComp_HostEmpty(modelId_prefix));
+
+ document.getElementById('btnUpdateOpenAICompModels').addEventListener('click', async () => {
+ document.getElementById('openai_comp_model_fetch_loading').style.display = 'inline';
+ let openai_comp = new OpenAIComp(document.getElementById("openai_comp_host").value , null, document.getElementById("openai_comp_api_key").value, true, document.getElementById("openai_comp_use_v1").checked);
+ openai_comp.fetchModels().then((data) => {
+ if(!data.ok){
+ let errorDetail;
+ try {
+ errorDetail = JSON.parse(data.error);
+ errorDetail = errorDetail.error.message;
+ } catch (e) {
+ errorDetail = data.error;
+ }
+ document.getElementById('openai_comp_model_fetch_loading').style.display = 'none';
+ console.error("[ThunderAI] " + browser.i18n.getMessage("OpenAIComp_Models_Error_fetching"));
+ alert(browser.i18n.getMessage("OpenAIComp_Models_Error_fetching")+": " + errorDetail);
+ return;
+ }
+ taLog.log("OpenAIComp models: " + JSON.stringify(data));
+ data.response.forEach(model => {
+ if (!Array.from(select_openai_comp_model.options).some(option => option.value === model.id)) {
+ const option = document.createElement('option');
+ option.value = model.id;
+ option.text = model.id;
+ select_openai_comp_model.appendChild(option);
+ }
+ });
+ document.getElementById('openai_comp_model_fetch_loading').style.display = 'none';
+ });
+
+ warn_OpenAIComp_HostEmpty(modelId_prefix);
+ });
+
+ // Anthropic API model fetching
+ let select_anthropic_model = getModelEl('anthropic_model', modelId_prefix);
+ const anthropic_option = document.createElement('option');
+ anthropic_option.value = prefs.anthropic_model;
+ anthropic_option.text = prefs.anthropic_model;
+ select_anthropic_model.appendChild(anthropic_option);
+ select_anthropic_model.addEventListener("change", () => warn_Anthropic_APIKeyEmpty(modelId_prefix));
+ select_anthropic_model.addEventListener("change", () => warn_Anthropic_VersionEmpty(modelId_prefix));
+
+ document.getElementById('btnUpdateAnthropicModels').addEventListener('click', async () => {
+ document.getElementById('anthropic_model_fetch_loading').style.display = 'inline';
+ let anthropic = new Anthropic(document.getElementById("anthropic_api_key").value, document.getElementById("anthropic_version").value, '');
+ anthropic.fetchModels().then((data) => {
+ if(!data.ok){
+ let errorDetail;
+ try {
+ errorDetail = JSON.parse(data.error);
+ errorDetail = errorDetail.error.message;
+ } catch (e) {
+ errorDetail = data.error;
+ }
+ document.getElementById('anthropic_model_fetch_loading').style.display = 'none';
+ console.error("[ThunderAI] " + browser.i18n.getMessage("Anthropic_Models_Error_fetching"));
+ alert(browser.i18n.getMessage("Anthropic_Models_Error_fetching")+": " + errorDetail);
+ return;
+ }
+ taLog.log("Anthropic models: " + JSON.stringify(data));
+ data.response.forEach(model => {
+ const existingOption = Array.from(select_anthropic_model.options).find(option => option.value === model.id);
+ if (existingOption) {
+ existingOption.text = model.display_name + " (" + model.id + ")";
+ } else {
+ const option = document.createElement('option');
+ option.value = model.id;
+ option.text = model.display_name + " (" + model.id + ")";
+ select_anthropic_model.appendChild(option);
+ }
+ });
+ document.getElementById('anthropic_model_fetch_loading').style.display = 'none';
+ });
+
+ warn_Anthropic_APIKeyEmpty(modelId_prefix);
+ });
+
+ document.getElementById('btnOpenAICompForceModel').addEventListener('click', () => {
+ let modelName = prompt(browser.i18n.getMessage('OpenAIComp_force_model_ask')).trim();
+ if ((modelName !== null) && (modelName !== undefined) && (modelName !== '')) {
+ let select_openai_comp_model = getModelEl('openai_comp_model', modelId_prefix);
+ let option = document.createElement('option');
+ option.value = modelName;
+ option.text = modelName;
+ select_openai_comp_model.appendChild(option);
+ select_openai_comp_model.value = modelName;
+ select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
+ }
+ });
+
+ document.getElementById('btnOpenAICompClearModelsList').addEventListener('click', () => {
+ if (!confirm(browser.i18n.getMessage('OpenAIComp_ClearModelsList_Confirm'))) {
+ return;
+ }
+ let select_openai_comp_model = getModelEl('openai_comp_model', modelId_prefix);
+ while (select_openai_comp_model.options.length > 0) {
+ select_openai_comp_model.remove(0);
+ }
+ select_openai_comp_model.value = '';
+ select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
+ });
+
+ document.getElementById('btnGiveAllUrlsPermission_ollama_api').addEventListener('click', async () => {
+ permission_all_urls = await messenger.permissions.request({ origins: [""] });
+ });
+
+ document.getElementById('btnGiveAllUrlsPermission_openai_comp_api').addEventListener('click', async () => {
+ permission_all_urls = await messenger.permissions.request({ origins: [""] });
+ });
+
+ warn_ChatGPT_APIKeyEmpty(modelId_prefix);
+ warn_Ollama_HostEmpty(modelId_prefix);
+ warn_OpenAIComp_HostEmpty(modelId_prefix);
+ warn_GoogleGemini_APIKeyEmpty(modelId_prefix);
+ warn_Anthropic_APIKeyEmpty(modelId_prefix);
+ warn_Anthropic_VersionEmpty(modelId_prefix);
+
+ return {
+ select: conntype_select,
+ onTypeChange: (fn) => { onTypeChange = fn; fn(conntype_select.value, { select: conntype_select }); }
+ };
+}
+
+
+// From here there are exported functions
+
+export function updateWarnings(modelId_prefix = '') {
+ warn_ChatGPT_APIKeyEmpty(modelId_prefix);
+ warn_Ollama_HostEmpty(modelId_prefix);
+ warn_OpenAIComp_HostEmpty(modelId_prefix);
+ warn_GoogleGemini_APIKeyEmpty(modelId_prefix);
+ warn_Anthropic_APIKeyEmpty(modelId_prefix);
+ warn_Anthropic_VersionEmpty(modelId_prefix);
+}
+
+export function changeConnTypeRowColor(conntype_row, conntype_select) {
+ conntype_row.classList.toggle("conntype_chatgpt_web", (conntype_select.value === "chatgpt_web"));
+ conntype_row.classList.toggle("conntype_chatgpt_api", (conntype_select.value === "chatgpt_api"));
+ conntype_row.classList.toggle("conntype_ollama_api", (conntype_select.value === "ollama_api"));
+ conntype_row.classList.toggle("conntype_openai_comp_api", (conntype_select.value === "openai_comp_api"));
+ conntype_row.classList.toggle("conntype_google_gemini_api", (conntype_select.value === "google_gemini_api"));
+ conntype_row.classList.toggle("conntype_anthropic_api", (conntype_select.value === "anthropic_api"));
+}
+
+export function showConnectionOptions(conntype_select) {
+ let chatgpt_web_display = 'table-row';
+ let chatgpt_api_display = 'none';
+ let ollama_api_display = 'none';
+ let openai_comp_api_display = 'none';
+ let google_gemini_api_display = 'none';
+ let anthropic_api_display = 'none';
+ let parent = conntype_select.parentElement.parentElement.parentElement;
+ changeConnTypeRowColor(parent, conntype_select);
+ if (conntype_select.value === "chatgpt_web") {
+ chatgpt_web_display = 'table-row';
+ }else{
+ chatgpt_web_display = 'none';
+ }
+ if (conntype_select.value === "chatgpt_api") {
+ chatgpt_api_display = 'table-row';
+ }else{
+ chatgpt_api_display = 'none';
+ }
+ if (conntype_select.value === "ollama_api") {
+ ollama_api_display = 'table-row';
+ }else{
+ ollama_api_display = 'none';
+ }
+ if (conntype_select.value === "openai_comp_api") {
+ openai_comp_api_display = 'table-row';
+ }else{
+ openai_comp_api_display = 'none';
+ }
+ if (conntype_select.value === "google_gemini_api") {
+ google_gemini_api_display = 'table-row';
+ }else{
+ google_gemini_api_display = 'none';
+ }
+ if (conntype_select.value === "anthropic_api") {
+ anthropic_api_display = 'table-row';
+ }else{
+ anthropic_api_display = 'none';
+ }
+ document.querySelectorAll(".conntype_chatgpt_web").forEach(element => {
+ element.style.display = chatgpt_web_display;
+ });
+ document.querySelectorAll(".conntype_chatgpt_api").forEach(element => {
+ element.style.display = chatgpt_api_display;
+ });
+ document.querySelectorAll(".conntype_ollama_api").forEach(element => {
+ element.style.display = ollama_api_display;
+ });
+ document.querySelectorAll(".conntype_openai_comp_api").forEach(element => {
+ element.style.display = openai_comp_api_display;
+ });
+ document.querySelectorAll(".conntype_google_gemini_api").forEach(element => {
+ element.style.display = google_gemini_api_display;
+ });
+ document.querySelectorAll(".conntype_anthropic_api").forEach(element => {
+ element.style.display = anthropic_api_display;
+ });
+ if (varConnectionUI.permission_all_urls) {
+ document.getElementById('openai_comp_api_cors_warning').style.display = 'none';
+ document.getElementById('ollama_api_cors_warning').style.display = 'none';
+ }
+}
+
+
+// From here there are internal functions
+
+function getModelEl(model, modelId_prefix) {
+ return document.getElementById((modelId_prefix ? modelId_prefix : '') + model);
+}
+
+function populateConnectionTypeOptions(selectId, no_chatgpt_web = false) {
+ const conntype_select = document.getElementById(selectId);
+ if (!conntype_select) return;
+
+ const prevValue = conntype_select.value;
+
+ const options = [
+ { value: 'chatgpt_web', msgKey: 'prefs_Connection_type_ChatGPT_Web' },
+ { value: 'chatgpt_api', msgKey: 'prefs_Connection_type_ChatGPT_API' },
+ { value: 'google_gemini_api', msgKey: 'prefs_Connection_type_Google_Gemini_API' },
+ { value: 'anthropic_api', msgKey: 'prefs_Connection_type_Anthropic_API' },
+ { value: 'ollama_api', msgKey: 'prefs_Connection_type_Ollama_API' },
+ { value: 'openai_comp_api', msgKey: 'prefs_Connection_type_OpenAI_Comp_API' }
+ ];
+
+ conntype_select.innerHTML = '';
+
+ for (const opt of options.filter(o => !(no_chatgpt_web && o.value === 'chatgpt_web'))) {
+ const optionEl = document.createElement('option');
+ optionEl.value = opt.value;
+ optionEl.textContent = browser.i18n.getMessage(opt.msgKey) || opt.msgKey;
+ conntype_select.appendChild(optionEl);
+ }
+
+ if (options.some(o => o.value === prevValue)) {
+ conntype_select.value = prevValue;
+ }
+}
+
+function warn_ChatGPT_APIKeyEmpty(modelId_prefix) {
+ let apiKeyInput = document.getElementById('chatgpt_api_key');
+ let btnFetchChatGPTModels = document.getElementById('btnUpdateChatGPTModels');
+ let modelChatGPT = getModelEl('chatgpt_model', modelId_prefix);
+ if(apiKeyInput.value === ''){
+ apiKeyInput.style.border = '2px solid red';
+ btnFetchChatGPTModels.disabled = true;
+ modelChatGPT.disabled = true;
+ modelChatGPT.selectedIndex = -1;
+ modelChatGPT.style.border = '';
+ }else{
+ apiKeyInput.style.border = '';
+ btnFetchChatGPTModels.disabled = false;
+ modelChatGPT.disabled = false;
+ if((modelChatGPT.selectedIndex === -1)||(modelChatGPT.value === '')){
+ modelChatGPT.style.border = '2px solid red';
+ }else{
+ modelChatGPT.style.border = '';
+ }
+ }
+}
+
+function warn_GoogleGemini_APIKeyEmpty(modelId_prefix) {
+ let apiKeyInput = document.getElementById('google_gemini_api_key');
+ let btnFetchGoogleGeminiModels = document.getElementById('btnUpdateGoogleGeminiModels');
+ let modelGoogleGemini = getModelEl('google_gemini_model', modelId_prefix);
+ if(apiKeyInput.value === ''){
+ apiKeyInput.style.border = '2px solid red';
+ btnFetchGoogleGeminiModels.disabled = true;
+ modelGoogleGemini.disabled = true;
+ modelGoogleGemini.selectedIndex = -1;
+ modelGoogleGemini.style.border = '';
+ }else{
+ apiKeyInput.style.border = '';
+ btnFetchGoogleGeminiModels.disabled = false;
+ modelGoogleGemini.disabled = false;
+ if((modelGoogleGemini.selectedIndex === -1)||(modelGoogleGemini.value === '')){
+ modelGoogleGemini.style.border = '2px solid red';
+ }else{
+ modelGoogleGemini.style.border = '';
+ }
+ }
+}
+
+function warn_Ollama_HostEmpty(modelId_prefix) {
+ let hostInput = document.getElementById('ollama_host');
+ let btnFetchOllamaModels = document.getElementById('btnUpdateOllamaModels');
+ let modelOllama = getModelEl('ollama_model', modelId_prefix);
+ if(hostInput.value === ''){
+ hostInput.style.border = '2px solid red';
+ btnFetchOllamaModels.disabled = true;
+ modelOllama.disabled = true;
+ modelOllama.selectedIndex = -1;
+ modelOllama.style.border = '';
+ }else{
+ hostInput.style.border = '';
+ btnFetchOllamaModels.disabled = false;
+ modelOllama.disabled = false;
+ if((modelOllama.selectedIndex === -1)||(modelOllama.value === '')){
+ modelOllama.style.border = '2px solid red';
+ }else{
+ modelOllama.style.border = '';
+ }
+ }
+}
+
+function warn_OpenAIComp_HostEmpty(modelId_prefix) {
+ let hostInput = document.getElementById('openai_comp_host');
+ let btnUpdateOpenAICompModels = document.getElementById('btnUpdateOpenAICompModels');
+ let modelOpenAIComp = getModelEl('openai_comp_model', modelId_prefix);
+ if(hostInput.value === ''){
+ hostInput.style.border = '2px solid red';
+ btnUpdateOpenAICompModels.disabled = true;
+ modelOpenAIComp.disabled = true;
+ modelOpenAIComp.selectedIndex = -1;
+ modelOpenAIComp.style.border = '';
+ }else{
+ hostInput.style.border = '';
+ btnUpdateOpenAICompModels.disabled = false;
+ modelOpenAIComp.disabled = false;
+ if((modelOpenAIComp.selectedIndex === -1)||(modelOpenAIComp.value === '')){
+ modelOpenAIComp.style.border = '2px solid red';
+ }else{
+ modelOpenAIComp.style.border = '';
+ }
+ }
+}
+
+function warn_Anthropic_APIKeyEmpty(modelId_prefix) {
+ let apiKeyInput = document.getElementById('anthropic_api_key');
+ let btnFetchAnthropicModels = document.getElementById('btnUpdateAnthropicModels');
+ let modelAnthropic = getModelEl('anthropic_model', modelId_prefix);
+ if(apiKeyInput.value === ''){
+ apiKeyInput.style.border = '2px solid red';
+ btnFetchAnthropicModels.disabled = true;
+ modelAnthropic.disabled = true;
+ modelAnthropic.selectedIndex = -1;
+ modelAnthropic.style.border = '';
+ }else{
+ apiKeyInput.style.border = '';
+ btnFetchAnthropicModels.disabled = false;
+ modelAnthropic.disabled = false;
+ if((modelAnthropic.selectedIndex === -1)||(modelAnthropic.value === '')){
+ modelAnthropic.style.border = '2px solid red';
+ }else{
+ modelAnthropic.style.border = '';
+ }
+ }
+}
+
+function warn_Anthropic_VersionEmpty(modelId_prefix) {
+ let versionInput = document.getElementById('anthropic_version');
+ let btnFetchAnthropicModels = document.getElementById('btnUpdateAnthropicModels');
+ let modelAnthropic = getModelEl('anthropic_model', modelId_prefix);
+ if(versionInput.value === ''){
+ versionInput.style.border = '2px solid red';
+ btnFetchAnthropicModels.disabled = true;
+ modelAnthropic.disabled = true;
+ modelAnthropic.selectedIndex = -1;
+ modelAnthropic.style.border = '';
+ }else{
+ versionInput.style.border = '';
+ btnFetchAnthropicModels.disabled = false;
+ modelAnthropic.disabled = false;
+ if((modelAnthropic.selectedIndex === -1)||(modelAnthropic.value === '')){
+ modelAnthropic.style.border = '2px solid red';
+ }else{
+ modelAnthropic.style.border = '';
+ }
+ }
+}
+
+function resetOpenAICompConfigs(){
+ let select_openai_comp_model = document.getElementById('openai_comp_services_shortcut');
+ select_openai_comp_model.value = 'custom';
+}
+
+function loadOpenAICompConfigs(){
+ let select_openai_comp_model = document.getElementById('openai_comp_services_shortcut');
+ openAICompConfigs.forEach(config => {
+ const option = document.createElement('option');
+ option.value = config.id;
+ option.text = config.name;
+ select_openai_comp_model.appendChild(option);
+ });
+}
\ No newline at end of file
diff --git a/pages/addtags/mzta-add-tags.css b/pages/addtags/mzta-add-tags.css
index 070f3bdf..9b02a45c 100644
--- a/pages/addtags/mzta-add-tags.css
+++ b/pages/addtags/mzta-add-tags.css
@@ -43,10 +43,46 @@
background-color: #e9ffdf;
}
-tr.add_tags_auto_sub td{
+.specific_integration{
+ background-color: #dfeaff;
+}
+
+tr.add_tags_auto_sub td,
+tr.specific_integration_sub td{
padding-left: 0.8em !important;
}
+.specific_integration_sub{
+ display: none;
+}
+
+table {
+ border-collapse: separate;
+ border-spacing: 0;
+}
+
+.group td {
+ border-top: none;
+ border-bottom: none;
+}
+
+.specific_integration_sub td:first-child {
+ border-left: 10px solid #dfeaff;
+}
+
+.specific_integration_sub td:last-child {
+ border-right: 10px solid #dfeaff;
+}
+
+#connection_ui_end td{
+ height: 6px;
+ background-color: #dfeaff;
+}
+
+#connection_ui_end{
+ display: none;
+}
+
.btn_div{
width: 100%;
display: flex;
@@ -72,6 +108,7 @@ table#miczPrefs {
.section_title{
font-weight: bold;
+ font-size: 1.2em;
}
table#miczPrefs td{
@@ -159,4 +196,20 @@ table#miczPrefs tr:last-child td {
.add_tags_auto{
background-color: #415c35;
}
+
+ .specific_integration{
+ background-color: #2E3A4F;
+ }
+
+ .specific_integration_sub td:first-child {
+ border-left: 10px solid #2E3A4F;
+ }
+
+ .specific_integration_sub td:last-child {
+ border-right: 10px solid #2E3A4F;
+ }
+
+ #connection_ui_end td{
+ background-color: #2E3A4F;
+ }
}
\ No newline at end of file
diff --git a/pages/addtags/mzta-add-tags.html b/pages/addtags/mzta-add-tags.html
index bf9d8c53..0c27b53f 100644
--- a/pages/addtags/mzta-add-tags.html
+++ b/pages/addtags/mzta-add-tags.html
@@ -4,6 +4,7 @@
ThunderAI - __MSG_AddTags_PageTitle__
+
@@ -13,8 +14,20 @@
__MSG_AddTags_prompt_prefs_title__
+
+ | __MSG_prefs_OptionText_use_specific_integration__
+ |
+
+
+ |
+
+
+ |
- | __MSG_prefs_OptionText_add_tags_maxnum__ |
+ __MSG_prefs_OptionText_add_tags_maxnum__ |
|
- | __MSG_prefs_OptionText_add_tags_exclusions_exact_match__ |
+ __MSG_prefs_OptionText_add_tags_exclusions_exact_match__ |
|
- | __MSG_prefs_OptionText_add_tags_hide_exclusions__ |
+ __MSG_prefs_OptionText_add_tags_hide_exclusions__ |
|
- | __MSG_prefs_OptionText_add_tags_first_uppercase__ |
+ __MSG_prefs_OptionText_add_tags_first_uppercase__ |
|
- | __MSG_prefs_OptionText_add_tags_force_lang__ |
+ __MSG_prefs_OptionText_add_tags_force_lang__ |
|
- | __MSG_prefs_OptionText_add_tags_auto__
+ | __MSG_prefs_OptionText_add_tags_auto__
__MSG_prefs_OptionText_add_tags_auto_Info2__ |
|
- | __MSG_prefs_OptionText_add_tags_auto_only_inbox__ |
+ __MSG_prefs_OptionText_add_tags_auto_only_inbox__ |
|
- | __MSG_prefs_OptionText_add_tags_auto_uselist__ |
+ __MSG_prefs_OptionText_add_tags_auto_uselist__ |
|
- | __MSG_prefs_OptionText_add_tags_context_menu__ |
+ __MSG_prefs_OptionText_add_tags_context_menu__ |
|
- | __MSG_prefs_OptionText_add_tags_auto_force_existing__ |
+ __MSG_prefs_OptionText_add_tags_auto_force_existing__ |
|