v1.0.0
This commit is contained in:
@@ -43,14 +43,27 @@ Type back the <b>code</b> on the keyboard and the code will be removed from the
|
||||
- <b>Cursor indication</b>: show a pointer cursor and a hourglass to know when the request is finished.
|
||||
- <b>Title indication</b>: show some informations into the title to know for example if the code have been injected.
|
||||
<br/> 
|
||||
- <b>Infinite try</b>: click as much as you want on the question (don't forget to reset the question).
|
||||
- <b>Console logs</b>: show logs into the console.
|
||||
<br/><img src="./assets/logs.png" alt="Logs" width="250">
|
||||
- <b>Request timeout</b>: If the request is too long it will be abort after 10seconds.
|
||||
- <b>Typing effect</b>: create a typing effect for text. Type any text and it will be replaced by the correct one. If you want to stop it press <b>Backspace</b> key.
|
||||
<br/> 
|
||||
- <b>Mouseover effect</b>: you will need to hover (or click for select) the question response to complete it automaticaly.
|
||||
<br/> 
|
||||
<br/> 
|
||||
- <b>Table formatting</b>: Format table from the question to make it more readable for CHAT-GPT.
|
||||
|
||||
```
|
||||
--------------------------------
|
||||
| |name |birthDate |cars|
|
||||
--------------------------------
|
||||
|Person 1|Yvick|15/08/1999|yes |
|
||||
--------------------------------
|
||||
|Person 2|Yann |19/01/2000|no |
|
||||
--------------------------------
|
||||
```
|
||||
|
||||
- <b>Infinite try</b>: click as much as you want on the question (don't forget to reset the question).
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 49 KiB |
+53
-7
@@ -77,12 +77,15 @@
|
||||
*/
|
||||
function getChatGPTResponse(config, question) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const controller = new AbortController();
|
||||
const timeoutControler = setTimeout(() => controller.abort(), 10000);
|
||||
const req = yield fetch("https://api.openai.com/v1/chat/completions", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${config.apiKey}`,
|
||||
},
|
||||
signal: config.timeout ? controller.signal : null,
|
||||
body: JSON.stringify({
|
||||
model: config.model && config.model !== "" ? config.model : "gpt-3.5-turbo",
|
||||
messages: [{ role: "user", content: question }],
|
||||
@@ -92,21 +95,58 @@
|
||||
stop: null,
|
||||
}),
|
||||
});
|
||||
clearTimeout(timeoutControler);
|
||||
const rep = yield req.json();
|
||||
const response = rep.choices[0].message.content;
|
||||
return normalizeText(response);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert table to representating string table
|
||||
* @param table
|
||||
* @returns
|
||||
*/
|
||||
function htmlTableToString(table) {
|
||||
const tab = [];
|
||||
const lines = Array.from(table.querySelectorAll("tr"));
|
||||
const maxColumnsLength = [];
|
||||
lines.map((line) => {
|
||||
const cells = Array.from(line.querySelectorAll("td, th"));
|
||||
const cellsContent = cells.map((cell, index) => {
|
||||
var _a;
|
||||
const content = (_a = cell.textContent) === null || _a === void 0 ? void 0 : _a.trim();
|
||||
maxColumnsLength[index] = Math.max(maxColumnsLength[index] || 0, content.length || 0);
|
||||
return content;
|
||||
});
|
||||
tab.push(cellsContent);
|
||||
});
|
||||
const lineSeparationSize = maxColumnsLength.reduce((a, b) => a + b) + tab[0].length + 1;
|
||||
const lineSeparation = "\n" + Array(lineSeparationSize).fill("-").join("") + "\n";
|
||||
const mappedTab = tab.map((line) => {
|
||||
const mappedLine = line.map((content, index) => content.padEnd(maxColumnsLength[index], "\u00A0"));
|
||||
return "|" + mappedLine.join("|") + "|";
|
||||
});
|
||||
return lineSeparation + mappedTab.join(lineSeparation) + lineSeparation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the question and add sub informations
|
||||
* @param langage
|
||||
* @param question
|
||||
* @returns
|
||||
*/
|
||||
function normalizeQuestion(langage, question) {
|
||||
const finalQuestion = `Give a short response as possible for this question, reply in ${langage && langage !== ""
|
||||
? 'this langage "' + langage + '"'
|
||||
function normalizeQuestion(config, questionContainer) {
|
||||
let question = questionContainer.textContent;
|
||||
if (config.table) {
|
||||
//make table more readable for chat-gpt
|
||||
const tables = questionContainer.querySelectorAll("table");
|
||||
for (const table of tables) {
|
||||
question = question.replace(table.textContent, htmlTableToString(table));
|
||||
}
|
||||
}
|
||||
const finalQuestion = `Give a short response as possible for this question, reply in ${config.langage && config.langage !== ""
|
||||
? 'this langage "' + config.langage + '"'
|
||||
: "the following question langage"} and only show the result:
|
||||
${question}
|
||||
(If you have to choose between multiple results only show the corrects one, separate them with new line and take the same text as the question)`;
|
||||
@@ -297,15 +337,21 @@
|
||||
if (config.cursor)
|
||||
hiddenButton.style.cursor = "wait";
|
||||
(_a = form.querySelector(".accesshide")) === null || _a === void 0 ? void 0 : _a.remove();
|
||||
const question = normalizeQuestion(config.langage, form.textContent);
|
||||
const question = normalizeQuestion(config, form);
|
||||
const inputList = form.querySelectorAll(query);
|
||||
const response = yield getChatGPTResponse(config, question);
|
||||
const response = yield getChatGPTResponse(config, question).catch((error) => ({
|
||||
error,
|
||||
}));
|
||||
if (config.cursor)
|
||||
hiddenButton.style.cursor = config.infinite ? "pointer" : "initial";
|
||||
if (typeof response === "object" && "error" in response) {
|
||||
console.error(response.error);
|
||||
return;
|
||||
}
|
||||
if (config.logs) {
|
||||
Logs.question(question);
|
||||
Logs.response(response);
|
||||
}
|
||||
if (config.cursor)
|
||||
hiddenButton.style.cursor = config.infinite ? "pointer" : "initial";
|
||||
const handlers = [
|
||||
handleTextbox,
|
||||
handleNumber,
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -45,6 +45,10 @@
|
||||
<input id="mouseover" type="checkbox" />
|
||||
<label for="mouseover">Mouseover effect</label>
|
||||
</div>
|
||||
<div class="line">
|
||||
<input id="table" type="checkbox" checked />
|
||||
<label for="table">Table formatting</label>
|
||||
</div>
|
||||
<div class="line">
|
||||
<input id="infinite" type="checkbox" />
|
||||
<label for="infinite">Infinite try</label>
|
||||
@@ -63,6 +67,10 @@
|
||||
<input id="cursor" type="checkbox" checked />
|
||||
<label for="cursor">Cursor indication</label>
|
||||
</div>
|
||||
<div class="line">
|
||||
<input id="timeout" type="checkbox" checked />
|
||||
<label for="timeout">Request timeout</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p id="message">Message</p>
|
||||
|
||||
@@ -9,6 +9,8 @@ const inputsCheckbox = [
|
||||
"typing",
|
||||
"mouseover",
|
||||
"infinite",
|
||||
"table",
|
||||
"timeout",
|
||||
];
|
||||
|
||||
function showMessage(messageTxt, valide) {
|
||||
@@ -23,9 +25,10 @@ saveBtn.addEventListener("click", function () {
|
||||
const [apiKey, code, langage, model] = inputsText.map((selector) =>
|
||||
document.querySelector("#" + selector).value.trim()
|
||||
);
|
||||
const [logs, title, cursor, typing, mouseover, infinite] = inputsCheckbox.map(
|
||||
(selector) => document.querySelector("#" + selector).checked
|
||||
);
|
||||
const [logs, title, cursor, typing, mouseover, infinite, table, timeout] =
|
||||
inputsCheckbox.map(
|
||||
(selector) => document.querySelector("#" + selector).checked
|
||||
);
|
||||
|
||||
if (!apiKey || !code) {
|
||||
showMessage("Please comple all the form");
|
||||
@@ -49,6 +52,8 @@ saveBtn.addEventListener("click", function () {
|
||||
typing,
|
||||
mouseover,
|
||||
infinite,
|
||||
table,
|
||||
timeout,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -11,12 +11,15 @@ async function getChatGPTResponse(
|
||||
config: Config,
|
||||
question: string
|
||||
): Promise<string> {
|
||||
const controller = new AbortController();
|
||||
const timeoutControler = setTimeout(() => controller.abort(), 10000);
|
||||
const req = await fetch("https://api.openai.com/v1/chat/completions", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${config.apiKey}`,
|
||||
},
|
||||
signal: config.timeout ? controller.signal : null,
|
||||
body: JSON.stringify({
|
||||
model:
|
||||
config.model && config.model !== "" ? config.model : "gpt-3.5-turbo",
|
||||
@@ -27,6 +30,7 @@ async function getChatGPTResponse(
|
||||
stop: null,
|
||||
}),
|
||||
});
|
||||
clearTimeout(timeoutControler);
|
||||
const rep = await req.json();
|
||||
const response = rep.choices[0].message.content;
|
||||
return normalizeText(response);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import Config from "../types/config";
|
||||
import normalizeText from "../utils/normalize-text";
|
||||
import htmlTableToString from "../utils/html-table-to-string";
|
||||
|
||||
/**
|
||||
* Normalize the question and add sub informations
|
||||
@@ -7,10 +8,20 @@ import normalizeText from "../utils/normalize-text";
|
||||
* @param question
|
||||
* @returns
|
||||
*/
|
||||
function normalizeQuestion(langage: Config["langage"], question: string) {
|
||||
function normalizeQuestion(config: Config, questionContainer: HTMLElement) {
|
||||
let question = questionContainer.textContent;
|
||||
|
||||
if (config.table) {
|
||||
//make table more readable for chat-gpt
|
||||
const tables = questionContainer.querySelectorAll("table");
|
||||
for (const table of tables) {
|
||||
question = question.replace(table.textContent, htmlTableToString(table));
|
||||
}
|
||||
}
|
||||
|
||||
const finalQuestion = `Give a short response as possible for this question, reply in ${
|
||||
langage && langage !== ""
|
||||
? 'this langage "' + langage + '"'
|
||||
config.langage && config.langage !== ""
|
||||
? 'this langage "' + config.langage + '"'
|
||||
: "the following question langage"
|
||||
} and only show the result:
|
||||
${question}
|
||||
|
||||
+14
-5
@@ -26,19 +26,28 @@ async function reply(
|
||||
|
||||
form.querySelector(".accesshide")?.remove();
|
||||
|
||||
const question = normalizeQuestion(config.langage, form.textContent);
|
||||
const question = normalizeQuestion(config, form);
|
||||
const inputList: NodeListOf<HTMLElement> = form.querySelectorAll(query);
|
||||
|
||||
const response = await getChatGPTResponse(config, question);
|
||||
const response = await getChatGPTResponse(config, question).catch(
|
||||
(error) => ({
|
||||
error,
|
||||
})
|
||||
);
|
||||
|
||||
if (config.cursor)
|
||||
hiddenButton.style.cursor = config.infinite ? "pointer" : "initial";
|
||||
|
||||
if (typeof response === "object" && "error" in response) {
|
||||
console.error(response.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.logs) {
|
||||
Logs.question(question);
|
||||
Logs.response(response);
|
||||
}
|
||||
|
||||
if (config.cursor)
|
||||
hiddenButton.style.cursor = config.infinite ? "pointer" : "initial";
|
||||
|
||||
const handlers = [
|
||||
handleTextbox,
|
||||
handleNumber,
|
||||
|
||||
Vendored
+2
@@ -9,6 +9,8 @@ type Config = {
|
||||
cursor?: boolean;
|
||||
logs?: boolean;
|
||||
title?: boolean;
|
||||
table?: boolean;
|
||||
timeout?: boolean;
|
||||
};
|
||||
|
||||
export default Config;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Convert table to representating string table
|
||||
* @param table
|
||||
* @returns
|
||||
*/
|
||||
function htmlTableToString(table: HTMLTableElement) {
|
||||
const tab: string[][] = [];
|
||||
const lines = Array.from(table.querySelectorAll("tr"));
|
||||
const maxColumnsLength: number[] = [];
|
||||
lines.map((line) => {
|
||||
const cells = Array.from(line.querySelectorAll("td, th"));
|
||||
const cellsContent = cells.map((cell, index) => {
|
||||
const content = cell.textContent?.trim();
|
||||
maxColumnsLength[index] = Math.max(
|
||||
maxColumnsLength[index] || 0,
|
||||
content.length || 0
|
||||
);
|
||||
return content;
|
||||
});
|
||||
tab.push(cellsContent);
|
||||
});
|
||||
|
||||
const lineSeparationSize =
|
||||
maxColumnsLength.reduce((a, b) => a + b) + tab[0].length + 1;
|
||||
const lineSeparation =
|
||||
"\n" + Array(lineSeparationSize).fill("-").join("") + "\n";
|
||||
|
||||
const mappedTab = tab.map((line) => {
|
||||
const mappedLine = line.map((content, index) =>
|
||||
content.padEnd(maxColumnsLength[index], "\u00A0")
|
||||
);
|
||||
return "|" + mappedLine.join("|") + "|";
|
||||
});
|
||||
|
||||
return lineSeparation + mappedTab.join(lineSeparation) + lineSeparation;
|
||||
}
|
||||
|
||||
export default htmlTableToString;
|
||||
Reference in New Issue
Block a user