Merge pull request #105 from micz/chatgpt_web_new_import_response
ChatGPT Web new response import method
This commit is contained in:
commit
8f9d3e4ec3
10 changed files with 150 additions and 122 deletions
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
<h2>Version 2.0.2 - ??/??/2024</h2>
|
||||
<ul>
|
||||
<li><i>[ChatGPT Web]</i> Now, the ChatGPT response must be selected by the user to be retrieved by ThunderAI. A single click on the text should work, but it's also possible to select the text manually [<a href="https://github.com/micz/ThunderAI/issues/104">#104</a>].</li>
|
||||
<li>Added a better error message when there is an error fetching models.</li>
|
||||
<li>When selecting a correct model in the options page, the field is no more highlighted in red [<a href="https://github.com/micz/ThunderAI/issues/100">#100</a>].</li>
|
||||
<li>When using the ChatGPT API, the double quotes at the beginning and end of the response are removed [<a href="https://github.com/micz/ThunderAI/issues/99">#99</a>].</li>
|
||||
|
|
@ -13,7 +14,7 @@
|
|||
</ul>
|
||||
<h2>Version 2.0.1 - 09/08/2024</h2>
|
||||
<ul>
|
||||
<li>No more notifying a missing API Key or model when using the web interface.</li>
|
||||
<li><i>[ChatGPT Web]</i> No more notifying a missing API Key or model when using the web interface.</li>
|
||||
</ul>
|
||||
<h2>Version 2.0.0 - 30/07/2024</h2>
|
||||
<ul>
|
||||
|
|
|
|||
|
|
@ -207,8 +207,12 @@
|
|||
"message": "Abgeschlossen!",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_job_completed_select": {
|
||||
"message": "Text auswählen und auf die Schaltfläche klicken.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_get_answer": {
|
||||
"message": "Letzte Antwort verwenden",
|
||||
"message": "Verwenden Sie die ausgewählte Antwort.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_close": {
|
||||
|
|
@ -295,14 +299,6 @@
|
|||
"message": "Antworttyp",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_keep_formatting": {
|
||||
"message": "Behalte die Formatierung bei",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_keep_formatting_info": {
|
||||
"message": "Behalte die Formatierung und die Zahlen oder Aufzählungspunkte aus der ChatGPT-Antwort bei.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_use_gpt4": {
|
||||
"message": "Verwenden Sie ChatGPT-4",
|
||||
"description": ""
|
||||
|
|
|
|||
|
|
@ -207,8 +207,12 @@
|
|||
"message": "Completed!",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_job_completed_select": {
|
||||
"message": "Select the text you want to use and click the button.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_get_answer": {
|
||||
"message": "Use last answer",
|
||||
"message": "Use the selected answer",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_close": {
|
||||
|
|
@ -295,14 +299,6 @@
|
|||
"message": "Reply type",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_keep_formatting": {
|
||||
"message": "Keep formatting",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_keep_formatting_info": {
|
||||
"message": "Keep the formatting and numeral or bullet points from the ChatGPT response.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_use_gpt4": {
|
||||
"message": "Use ChatGPT-4",
|
||||
"description": ""
|
||||
|
|
|
|||
|
|
@ -207,8 +207,12 @@
|
|||
"message": "Terminé !",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_job_completed_select": {
|
||||
"message": "Sélectionnez le texte que vous souhaitez utiliser et cliquez sur le bouton.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_get_answer": {
|
||||
"message": "Utiliser la dernière réponse",
|
||||
"message": "Utilisez la réponse sélectionnée",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_close": {
|
||||
|
|
@ -295,14 +299,6 @@
|
|||
"message": "Type de réponse",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_keep_formatting": {
|
||||
"message": "Conserver la mise en forme",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_keep_formatting_info": {
|
||||
"message": "Conservez la mise en forme et les numéros ou les puces de la réponse de ChatGPT.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_use_gpt4": {
|
||||
"message": "Utiliser ChatGPT-4",
|
||||
"description": ""
|
||||
|
|
|
|||
|
|
@ -207,8 +207,12 @@
|
|||
"message": "Completato!",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_job_completed_select": {
|
||||
"message": "Seleziona il testo che desideri utilizzare e clicca sul pulsante.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_get_answer": {
|
||||
"message": "Usa l'ultima risposta",
|
||||
"message": "Usa la risposta selezionata",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_close": {
|
||||
|
|
@ -295,14 +299,6 @@
|
|||
"message": "Modalità di risposta",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_keep_formatting": {
|
||||
"message": "Mantieni la formattazione",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_keep_formatting_info": {
|
||||
"message": "Mantieni la formattazione del testo e gli elenchi puntati e numerati della risposta di ChatGPT.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatpgt_use_gpt4": {
|
||||
"message": "Usa il modello ChatGPT-4",
|
||||
"description": ""
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@
|
|||
export const mzta_script = `
|
||||
let force_go = false;
|
||||
let current_message = null;
|
||||
let current_action = null;
|
||||
let selectionChangeTimeout = null;
|
||||
let isDragging = false;
|
||||
|
||||
async function chatgpt_sendMsg(msg, method ='') { // return -1 send button not found, -2 textarea not found
|
||||
const textArea = document.querySelector('form textarea'),
|
||||
|
|
@ -62,73 +65,6 @@ function chatgpt_getRegenerateButton() {
|
|||
}
|
||||
}
|
||||
|
||||
async function chatgpt_getFromDOM(pos) {
|
||||
const responseDivs = document.querySelectorAll('div[data-testid*="conversation-turn"]:nth-child(odd)'),
|
||||
strPos = pos.toString().toLowerCase();
|
||||
//console.log(">>>>>>>>>>>>> responseDivs.length: "+ responseDivs.length);
|
||||
let response = '';
|
||||
if (responseDivs.length) {
|
||||
if (/last|final/.test(strPos)){ // get last response
|
||||
responseDivs[responseDivs.length - 1].innerHTML = responseDivs[responseDivs.length - 1].innerHTML.replace(/<\\/p>/g, '</p>\\n\\n').replace(/<br\\s*\\/?>/g, '<br>\\n');
|
||||
// Removing the new buttons that let the user change model and insert a number (4 or 3.5 at the end of the text)
|
||||
let parser = new DOMParser();
|
||||
let doc = parser.parseFromString(responseDivs[responseDivs.length - 1].innerHTML, 'text/html');
|
||||
if(!mztaKeepFormatting) { // Return only TEXT
|
||||
// Select the div with class 'empty:hidden'
|
||||
let correct_div = responseDivs[responseDivs.length - 1].querySelector('div[data-message-author-role="assistant"]');
|
||||
response = correct_div.textContent;
|
||||
//console.log(">>>>>>>>>> response: " + response);
|
||||
response = response.replace(/^ChatGPT(?:ChatGPT)?/, ''); // strip sender name
|
||||
response = response.trim().replace(/^"|"$/g, ''); // strip quotation marks
|
||||
response = "<body><p>" + response + "</p></body>";
|
||||
//console.log(">>>>>>>>> response: " + JSON.stringify(response));
|
||||
let parser_2 = new DOMParser();
|
||||
let doc_response = parser_2.parseFromString(response, 'text/html');
|
||||
//console.log(">>>>>>>>> doc_response: " + JSON.stringify(doc_response.body.innerHTML));
|
||||
replaceNewlinesWithBr(doc_response.body)
|
||||
response = doc_response.body.innerHTML;
|
||||
} else { // Return HTML
|
||||
// Tags to exclude
|
||||
//console.log(">>>>>>>>> doc.body.innerHTML original: " + doc.body.innerHTML);
|
||||
const excludeTags = ['div', 'text', 'svg', 'path', 'button'];
|
||||
const includeTags = ['p', 'ul'];
|
||||
// removeTags(doc.body, excludeTags);
|
||||
response = removeTagsAndReturnHTML(doc.body, excludeTags, includeTags)
|
||||
//console.log(">>>>>>>>> doc.body.innerHTML final: " + doc.body.innerHTML);
|
||||
// response = doc.body.innerHTML;
|
||||
}
|
||||
//console.log('chatgpt_getFromDOM final response: '+response);
|
||||
//console.log('chatgpt_getFromDOM: [HTML] ' + responseDivs[responseDivs.length - 1].innerHTML.replace(/<div[^>]*>/gi, '').replace(/<\\/div>/gi, '').replace(/<svg[^>]*>/gi, '').replace(/<\\/svg>/gi, '').replace(/<path[^>]*>/gi, '').replace(/<\\/path>/gi, '').replace(/<text[^>]*>/gi, '').replace(/<\\/text>/gi, '').replace(/<span[^>]*>/gi, '').replace(/<\\/span>/gi, '').replace(/<button[^>]*>/gi, '').replace(/<\\/button>/gi, ''));
|
||||
} else { // get nth response --- HERE ONLY TEXT FROM RESPONSE, NO HTML
|
||||
const nthOfResponse = (
|
||||
|
||||
// Calculate base number
|
||||
Number.isInteger(pos) ? pos : // do nothing for integers
|
||||
/^\d+/.test(strPos) ? /^\d+/.exec(strPos)[0] : // extract first digits for strings w/ them
|
||||
( // convert words to integers for digitless strings
|
||||
/^(?:1|one|fir)(?:st)?$/.test(strPos) ? 1
|
||||
: /^(?:2|tw(?:o|en|el(?:ve|f))|seco)(?:nd|t[yi])?(?:e?th)?$/.test(strPos) ? 2
|
||||
: /^(?:3|th(?:ree|ir?))(?:rd|teen|t[yi])?(?:e?th)?$/.test(strPos) ? 3
|
||||
: /^(?:4|fou?r)(?:teen|t[yi])?(?:e?th)?$/.test(strPos) ? 4
|
||||
: /^(?:5|fi(?:ve|f))(?:teen|t[yi])?(?:e?th)?$/.test(strPos) ? 5
|
||||
: /^(?:6|six)(?:teen|t[yi])?(?:e?th)?$/.test(strPos) ? 6
|
||||
: /^(?:7|seven)(?:teen|t[yi])?(?:e?th)?$/.test(strPos) ? 7
|
||||
: /^(?:8|eight?)(?:teen|t[yi])?(?:e?th)?$/.test(strPos) ? 8
|
||||
: /^(?:9|nine?)(?:teen|t[yi])?(?:e?th)?$/.test(strPos) ? 9
|
||||
: /^(?:10|ten)(?:th)?$/.test(strPos) ? 10 : 1 )
|
||||
|
||||
// Transform base number if suffixed
|
||||
* ( /(ty|ieth)$/.test(strPos) ? 10 : 1 ) // x 10 if -ty/ieth
|
||||
+ ( /teen(th)?$/.test(strPos) ? 10 : 0 ) // + 10 if -teen/teenth
|
||||
|
||||
);
|
||||
response = responseDivs[nthOfResponse - 1].textContent;
|
||||
}
|
||||
//console.log('>>>>>>>>>>>>>> chatgpt_getFromDOM: ' + JSON.stringify(response));
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
function chatpgt_scrollToBottom () {
|
||||
try { document.querySelector('button[class*="cursor"][class*="bottom"]').click(); }
|
||||
catch (err) { console.error('[ThunderAI] ', err); }
|
||||
|
|
@ -141,6 +77,8 @@ function addCustomDiv(prompt_action,tabId,mailMessageId) {
|
|||
style.textContent += "body {padding-bottom: 100px;} [id^='headlessui-dialog-panel-:r']{padding-bottom: 100px;}";
|
||||
style.textContent += ".mzta-btn {background-color: #007bff;border: none;color: white;padding: 8px 15px;text-align: center;text-decoration: none;display: inline-block;font-size: 16px;margin: 4px 2px;transition-duration: 0.4s;cursor: pointer;border-radius: 5px;}";
|
||||
style.textContent += ".mzta-btn:hover {background-color:#0056b3;color:white;}";
|
||||
style.textContent += ".btn_disabled {background-color: #6a829b !important;color: white !important;cursor: not-allowed;}";
|
||||
style.textContent += ".btn_disabled:hover {background-color:#6a829b !important;color:white !important;}";
|
||||
style.textContent += "#mzta-loading{height:50px;display:inline-block;}";
|
||||
style.textContent += "#mzta-model_warn{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);max-height:100%px;min-width:30%;max-width:50%;padding:3px;border-radius:5px;text-align:center;background-color:#FFBABA;border:1px solid;font-size:13px;color:#D8000C;display:none;}#mzta-model_warn a{color:blue;text-decoration: underline;}";
|
||||
style.textContent += "#mzta-btn_gpt35 {background-color: #007bff;border: none;color: white;padding: 2px 4px;text-align: center;text-decoration: none;display: none;font-size: 13px;margin-left: 4px;transition-duration: 0.4s;cursor: pointer;border-radius: 2px;}";
|
||||
|
|
@ -225,18 +163,20 @@ function addCustomDiv(prompt_action,tabId,mailMessageId) {
|
|||
};
|
||||
break;
|
||||
case "1": // do reply
|
||||
btn_ok.disabled = true;
|
||||
btn_ok.textContent = browser.i18n.getMessage("chatgpt_win_get_answer");
|
||||
btn_ok.onclick = async function() {
|
||||
const response = await chatgpt_getFromDOM('last');
|
||||
const response = getSelectedHtml();
|
||||
browser.runtime.sendMessage({command: "chatgpt_replyMessage", text: response, tabId: tabId, mailMessageId: mailMessageId});
|
||||
//console.log(response);
|
||||
browser.runtime.sendMessage({command: "chatgpt_close"});
|
||||
};
|
||||
break;
|
||||
case "2": // replace text
|
||||
btn_ok.disabled = true;
|
||||
btn_ok.textContent = browser.i18n.getMessage("chatgpt_win_get_answer");
|
||||
btn_ok.onclick = async function() {
|
||||
const response = await chatgpt_getFromDOM('last');
|
||||
const response = getSelectedHtml();
|
||||
//console.log('replace text: '+tabId)
|
||||
browser.runtime.sendMessage({command: "chatgpt_replaceSelectedText", text: response, tabId: tabId, mailMessageId: mailMessageId});
|
||||
//console.log(response);
|
||||
|
|
@ -320,6 +260,9 @@ function checkGPT4Model() {
|
|||
function operation_done(){
|
||||
let curr_msg = document.getElementById('mzta-curr_msg');
|
||||
curr_msg.textContent = browser.i18n.getMessage("chatgpt_win_job_completed");
|
||||
if(current_action != '0'){
|
||||
curr_msg.textContent += " " + browser.i18n.getMessage("chatgpt_win_job_completed_select");
|
||||
}
|
||||
curr_msg.style.display = 'block';
|
||||
document.getElementById('mzta-btn_ok').style.display = 'inline';
|
||||
document.getElementById('mzta-loading').style.display = 'none';
|
||||
|
|
@ -416,6 +359,113 @@ function replaceNewlinesWithBr(node) {
|
|||
}
|
||||
}
|
||||
|
||||
function getSelectedHtml() {
|
||||
// Get the Selection object
|
||||
var selection = window.getSelection();
|
||||
|
||||
if (selection.rangeCount > 0) {
|
||||
// Get the first selected range
|
||||
var range = selection.getRangeAt(0);
|
||||
|
||||
// Create a new temporary div
|
||||
var tempDiv = document.createElement("div");
|
||||
|
||||
// Clone the contents of the range into the temporary div
|
||||
tempDiv.appendChild(range.cloneContents());
|
||||
|
||||
// Return the HTML of the selected content
|
||||
return tempDiv.innerHTML.replace(/^<p>"/, '<p>').replace(/"<\\/p>$/, '</p>'); // strip quotation marks;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function isSomethingSelected() {
|
||||
// Get the Selection object
|
||||
var selection = window.getSelection();
|
||||
|
||||
// Check if the selection range count is greater than 0 and the selection is not empty
|
||||
return selection.rangeCount > 0 && !selection.isCollapsed;
|
||||
}
|
||||
|
||||
document.addEventListener("selectionchange", function() {
|
||||
// Clear any previous timeout to reset the delay
|
||||
clearTimeout(selectionChangeTimeout);
|
||||
if(current_action === '0'){
|
||||
return;
|
||||
}
|
||||
// Set a timeout to delay the execution of the callback
|
||||
selectionChangeTimeout = setTimeout(function() {
|
||||
let btn_ok = document.getElementById('mzta-btn_ok');
|
||||
if (isSomethingSelected()) {
|
||||
btn_ok.disabled = false;
|
||||
btn_ok.classList.remove('btn_disabled');
|
||||
} else {
|
||||
btn_ok.disabled = true;
|
||||
btn_ok.classList.add('btn_disabled');
|
||||
}
|
||||
}, 300); // Delay in milliseconds
|
||||
});
|
||||
|
||||
function selectContentOnMouseDown(event) {
|
||||
// Reset the dragging flag when the mouse is pressed down
|
||||
isDragging = false;
|
||||
}
|
||||
|
||||
function selectContentOnMouseMove(event) {
|
||||
// Set the dragging flag to true if the mouse moves
|
||||
isDragging = true;
|
||||
}
|
||||
|
||||
function selectContentOnMouseUp(event) {
|
||||
var excludedArea = document.querySelector('.mzta-header-fixed');
|
||||
|
||||
if (excludedArea && excludedArea.contains(event.target)) {
|
||||
// If the click was inside the excluded area, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!isDragging)&&(!isSomethingSelected())) {
|
||||
// If no dragging has occurred, execute the selection code
|
||||
selectContentOnClick(event);
|
||||
}
|
||||
// Remove the event listeners to prevent future executions
|
||||
// document.removeEventListener('mousedown', selectContentOnMouseDown);
|
||||
// document.removeEventListener('mousemove', selectContentOnMouseMove);
|
||||
// document.removeEventListener('mouseup', selectContentOnMouseUp);
|
||||
}
|
||||
|
||||
function selectContentOnClick(event) {
|
||||
if(current_action === '0'){
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent the default behavior of the click
|
||||
event.preventDefault();
|
||||
|
||||
// Get the element that was clicked
|
||||
var clickedElement = event.target;
|
||||
|
||||
// Traverse the DOM upwards to find the nearest parent div
|
||||
var parentDiv = clickedElement.closest('div');
|
||||
|
||||
if (parentDiv) {
|
||||
// Create a range object
|
||||
var range = document.createRange();
|
||||
|
||||
// Select the contents of the div
|
||||
range.selectNodeContents(parentDiv);
|
||||
|
||||
// Get the selection object
|
||||
var selection = window.getSelection();
|
||||
|
||||
// Clear any existing selections
|
||||
selection.removeAllRanges();
|
||||
|
||||
// Add the new range to the selection
|
||||
selection.addRange(range);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// In the content script
|
||||
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
|
|
@ -424,6 +474,7 @@ browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||
// User not logged in
|
||||
alert(browser.i18n.getMessage("chatgpt_user_not_logged_in"));
|
||||
}else{
|
||||
current_action = message.action;
|
||||
addCustomDiv(message.action,message.tabId,message.mailMessageId);
|
||||
(async () => {
|
||||
if(mztaDoCustomText === 1){
|
||||
|
|
@ -432,6 +483,10 @@ browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||
} else {
|
||||
await doProceed(message);
|
||||
}
|
||||
// Add an event listener to the document to detect clicks
|
||||
document.addEventListener('mousedown', selectContentOnMouseDown);
|
||||
document.addEventListener('mousemove', selectContentOnMouseMove);
|
||||
document.addEventListener('mouseup', selectContentOnMouseUp);
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,7 +196,6 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_
|
|||
let mztaForceCompletionDesc="`+ browser.i18n.getMessage("chatgpt_force_completion") +`";
|
||||
let mztaForceCompletionTitle="`+ browser.i18n.getMessage("chatgpt_force_completion_title") +`";
|
||||
let mztaDoCustomText=`+ do_custom_text +`;
|
||||
let mztaKeepFormatting=`+ prefs.chatgpt_keep_formatting +`;
|
||||
let mztaPromptName="[`+ i18nConditionalGet(prompt_name) +`]";
|
||||
`;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ export const prefs_default = {
|
|||
chatgpt_win_height: 800,
|
||||
chatgpt_win_width: 700,
|
||||
chatpgt_use_gpt4: false,
|
||||
chatgpt_keep_formatting: false,
|
||||
default_chatgpt_lang: '',
|
||||
connection_type: 'chatgpt_web', //Other values: 'chatgpt_api'
|
||||
chatgpt_api_key: '',
|
||||
|
|
|
|||
|
|
@ -75,17 +75,6 @@
|
|||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr class="conntype_chatgpt_web">
|
||||
<td><label>
|
||||
<span>__MSG_prefs_OptionText_chatpgt_keep_formatting__</span>
|
||||
</label></td>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" id="chatgpt_keep_formatting" name="chatgpt_keep_formatting" class="option-input" />
|
||||
<span>__MSG_prefs_OptionText_chatpgt_keep_formatting_info__</span>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="conntype_chatgpt_web">
|
||||
<td><label>
|
||||
<span>__MSG_prefs_OptionText_chatpgt_use_gpt4__</span>
|
||||
|
|
|
|||
|
|
@ -9,14 +9,15 @@
|
|||
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
||||
<h2>Version 2.0.2 - ??/??/2024</h2>
|
||||
<ul>
|
||||
<li>Added a better error message when there is an error fetching models.</li>
|
||||
<li><i>[ChatGPT Web]</i> Now, the ChatGPT response must be selected by the user to be retrieved by ThunderAI. A single click on the text should work, but it's also possible to select the text manually [<a href="https://github.com/micz/ThunderAI/issues/104">#104</a>].</li>
|
||||
<li><i>[ChatGPT API]</i> Added a better error message when there is an error fetching models.</li>
|
||||
<li>When selecting a correct model in the options page, the field is no more highlighted in red [<a href="https://github.com/micz/ThunderAI/issues/100">#100</a>].</li>
|
||||
<li>When using the ChatGPT API, the double quotes at the beginning and end of the response are removed [<a href="https://github.com/micz/ThunderAI/issues/99">#99</a>].</li>
|
||||
<li><i>[ChatGPT API]</i> The double quotes at the beginning and end of the response are removed [<a href="https://github.com/micz/ThunderAI/issues/99">#99</a>].</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
<h2>Version 2.0.1 - 09/08/2024</h2>
|
||||
<ul>
|
||||
<li>No more notifying a missing API Key or model when using the web interface.</li>
|
||||
<li><i>[ChatGPT Web]</i> No more notifying a missing API Key or model when using the web interface.</li>
|
||||
</ul>
|
||||
<h2>Version 2.0.0 - 30/07/2024</h2>
|
||||
<ul>
|
||||
|
|
|
|||
Loading…
Reference in a new issue