diff --git a/js/api/openai.js b/js/api/openai.js
deleted file mode 100644
index 6d589c4c..00000000
--- a/js/api/openai.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * 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 .
- */
-
-// Some original methods derived from https://github.com/ali-raheem/Aify/blob/4ece286095ea7a6cf89d696902e6b81b5d1c3a4b/plugin/html/API.js
-
-
-export class OpenAI {
-
- apiKey = '';
- model = '';
- developer_messages = '';
- stream = false;
- store = false;
-
- constructor({
- apiKey = '',
- model = '',
- developer_messages = '',
- stream = false,
- store = false
- } = {}) {
- this.apiKey = apiKey;
- this.model = model;
- this.developer_messages = developer_messages;
- this.stream = stream;
- this.store = store;
- }
-
-
- fetchModels = async () => {
- try{
- const response = await fetch("https://api.openai.com/v1/models", {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Authorization: "Bearer "+ this.apiKey
- },
- });
-
- if (!response.ok) {
- const errorDetail = await response.text();
- let err_msg = "[ThunderAI] OpenAI API request failed: " + response.status + " " + response.statusText + ", Detail: " + errorDetail;
- console.error(err_msg);
- let output = {};
- output.ok = false;
- output.error = errorDetail;
- return output;
- }
-
- let output = {};
- output.ok = true;
- let output_response = await response.json();
- output.response = output_response.data.filter(item => item.id.startsWith('gpt-')).sort((a, b) => b.id.localeCompare(a.id));
-
- return output;
- }catch (error) {
- console.error("[ThunderAI] OpenAI API request failed: " + error);
- let output = {};
- output.is_exception = true;
- output.ok = false;
- output.error = "OpenAI API request failed: " + error;
- return output;
- }
- }
-
- fetchResponse = async (messages, maxTokens = 0) => {
-
- if(this.developer_messages !== ''){
- messages.push({role: "developer", content: [{"type": "text", "text": this.developer_messages}]});
- }
-
- // console.log(">>>>>>>>>>> OpenAI API request: " + JSON.stringify(messages));
-
- try {
- const response = await fetch("https://api.openai.com/v1/chat/completions", {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Authorization: "Bearer "+ this.apiKey
- },
- body: JSON.stringify({
- model: this.model,
- messages: messages,
- stream: this.stream,
- store: this.store,
- ...(maxTokens > 0 ? { 'max_tokens': parseInt(maxTokens) } : {})
- }),
- });
- return response;
- }catch (error) {
- console.error("[ThunderAI] OpenAI API request failed: " + error);
- let output = {};
- output.is_exception = true;
- output.ok = false;
- output.error = "OpenAI API request failed: " + error;
- return output;
- }
- }
-
- async countTokensUsingAPI(model, text) {
- const response = await fetch('https://api.openai.com/v1/engines/'+model+'/tokenizer', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Bearer ' + this.apiKey
- },
- body: JSON.stringify({ text })
- });
-
- const data = await response.json();
- return data.token_count;
- }
-
-}
diff --git a/js/workers/model-worker-openai.js b/js/workers/model-worker-openai.js
deleted file mode 100644
index 1cd9055b..00000000
--- a/js/workers/model-worker-openai.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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 .
- *
- *
- * This file contains a modified version of the code from the project at https://github.com/boxabirds/chatgpt-frontend-nobuild
- * The original code has been released under the Apache License, Version 2.0.
- */
-
-import { OpenAI } from '../api/openai.js';
-import { taLogger } from '../mzta-logger.js';
-
-let chatgpt_api_key = null;
-let chatgpt_model = '';
-let openai = null;
-let stopStreaming = false;
-let i18nStrings = null;
-let do_debug = false;
-let taLog = null;
-
-let conversationHistory = [];
-let assistantResponseAccumulator = '';
-
-self.onmessage = async function(event) {
- if (event.data.type === 'init') {
- chatgpt_api_key = event.data.chatgpt_api_key;
- chatgpt_model = event.data.chatgpt_model;
- openai = new OpenAI({
- apiKey: chatgpt_api_key,
- model: chatgpt_model,
- developer_messages: event.data.chatgpt_developer_messages,
- stream: true,
- store: event.data.chatgpt_api_store
- });
- do_debug = event.data.do_debug;
- i18nStrings = event.data.i18nStrings;
- taLog = new taLogger('model-worker-openai', do_debug);
- } else if (event.data.type === 'chatMessage') {
- conversationHistory.push({ role: 'user', content: event.data.message });
-
- const response = await openai.fetchResponse(conversationHistory); //4096);
- postMessage({ type: 'messageSent' });
-
- if (!response.ok) {
- let error_message = '';
- let errorDetail = '';
- if(response.is_exception === true){
- error_message = response.error;
- }else{
- try{
- const errorJSON = await response.json();
- errorDetail = JSON.stringify(errorJSON);
- error_message = errorJSON.error.message;
- }catch(e){
- error_message = response.statusText;
- }
- taLog.log("error_message: " + JSON.stringify(error_message));
- }
- postMessage({ type: 'error', payload: i18nStrings["chatgpt_api_request_failed"] + ": " + response.status + " " + response.statusText + ", Detail: " + error_message + " " + errorDetail });
- throw new Error("[ThunderAI] OpenAI ChatGPT API request failed: " + response.status + " " + response.statusText + ", Detail: " + error_message + " " + errorDetail);
- }
-
- const reader = response.body.getReader();
- const decoder = new TextDecoder("utf-8");
- let buffer = '';
-
- while (true) {
- if (stopStreaming) {
- stopStreaming = false;
- reader.cancel();
- conversationHistory.push({ role: 'assistant', content: assistantResponseAccumulator });
- assistantResponseAccumulator = '';
- postMessage({ type: 'tokensDone' });
- break;
- }
- const { done, value } = await reader.read();
- if (done) {
- conversationHistory.push({ role: 'assistant', content: assistantResponseAccumulator });
- assistantResponseAccumulator = '';
- postMessage({ type: 'tokensDone' });
- break;
- }
- // lots of low-level OpenAI response parsing stuff
- const chunk = decoder.decode(value);
- buffer += chunk;
- taLog.log("buffer " + buffer);
- const lines = buffer.split("\n");
- buffer = lines.pop();
- let parsedLines = [];
- try{
- parsedLines = lines
- .map((line) => line.replace(/^data: /, "").trim()) // Remove the "data: " prefix
- .filter((line) => line !== "" && line !== "[DONE]") // Remove empty lines and "[DONE]"
- // .map((line) => JSON.parse(line)); // Parse the JSON string
- .map((line) => {
- try {
- taLog.log("line: " + JSON.stringify(line));
- return JSON.parse(line);
- } catch (e) {
- taLog.warn("JSON parse warning, skipped line: " + line + " - " + e.message);
- return null;
- }
- })
- .filter((parsed) => parsed !== null);
- }catch(e){
- taLog.error("Error parsing lines: " + e);
- }
-
- for (const parsedLine of parsedLines) {
- const { choices } = parsedLine;
- const { delta } = choices[0];
- const { content } = delta;
- // Update the UI with the new content
- if (content) {
- assistantResponseAccumulator += content;
- postMessage({ type: 'newToken', payload: { token: content } });
- }
- }
- }
- } else if (event.data.type === 'stop') {
- stopStreaming = true;
- }
-};