| __MSG_prefs_OptionText_max_prompt_length__ |
diff --git a/options/mzta-options.js b/options/mzta-options.js
index 67d73003..871f08cf 100644
--- a/options/mzta-options.js
+++ b/options/mzta-options.js
@@ -22,6 +22,7 @@ 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';
let taLog = new taLogger("mzta-options",true);
@@ -60,7 +61,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" ? "****************" : result[element.id]));
+ 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]));
switch (element.type) {
case 'checkbox':
element.checked = result[element.id] || false;
@@ -109,6 +110,7 @@ function showConnectionOptions() {
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"));
@@ -116,6 +118,7 @@ function showConnectionOptions() {
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{
@@ -141,6 +144,11 @@ function showConnectionOptions() {
}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;
});
@@ -156,6 +164,9 @@ function showConnectionOptions() {
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';
@@ -250,6 +261,50 @@ function warn_OpenAIComp_HostEmpty() {
}
}
+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");
@@ -450,6 +505,8 @@ document.addEventListener('DOMContentLoaded', async () => {
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_GetCalendarEvent);
@@ -459,8 +516,10 @@ document.addEventListener('DOMContentLoaded', async () => {
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);
- let prefs = await browser.storage.sync.get({chatgpt_web_model: '', chatgpt_model: '', ollama_model: '', openai_comp_model: '', google_gemini_model: '', chatgpt_win_height: 0, chatgpt_win_width: 0 });
+ 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');
@@ -502,7 +561,7 @@ document.addEventListener('DOMContentLoaded', async () => {
warn_ChatGPT_APIKeyEmpty();
});
- // Google Gemini API ChatGPT model fetching
+ // 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;
@@ -640,11 +699,57 @@ document.addEventListener('DOMContentLoaded', async () => {
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(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();
+ });
+
showConnectionOptions();
warn_ChatGPT_APIKeyEmpty();
warn_Ollama_HostEmpty();
warn_OpenAIComp_HostEmpty();
warn_GoogleGemini_APIKeyEmpty();
+ warn_Anthropic_APIKeyEmpty();
+ warn_Anthropic_VersionEmpty();
disable_MaxPromptLength();
disable_AddTags();
disable_SpamFilter();
@@ -683,6 +788,17 @@ document.addEventListener('DOMContentLoaded', async () => {
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});
diff --git a/options/mzta-release-notes.html b/options/mzta-release-notes.html
index 6ae39eb0..e79f7678 100644
--- a/options/mzta-release-notes.html
+++ b/options/mzta-release-notes.html
@@ -9,6 +9,9 @@
ThunderAI Release Notes
Version 3.5.0 - ??/??/2025
+ - Added Anthropic API support [#349].
+ - Fix: in the Spamfilter page the unsaved changes warning is now correctly shown.
+ - Fixed incoming emails elaboration that was failing when the auto tagging was enabled and then the complete tagging feature was disabled.
- ...
Version 3.4.1 - 12/05/2025
diff --git a/pages/spamfilter/mzta-spamfilter.html b/pages/spamfilter/mzta-spamfilter.html
index 2496b976..cffc7831 100644
--- a/pages/spamfilter/mzta-spamfilter.html
+++ b/pages/spamfilter/mzta-spamfilter.html
@@ -33,7 +33,7 @@
|