@@ -1,21 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
plugins: ['@typescript-eslint'],
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/eslint-recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'prettier'
|
|
||||||
],
|
|
||||||
ignorePatterns: ['node_modules/'],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: ['extension/popup/*.js', 'src/**/*.ts'],
|
|
||||||
rules: {
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
|
||||||
'no-constant-condition': 'off'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,10 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v1.1.3
|
||||||
|
|
||||||
|
- Added `base url` and `max token` in config (by dmunozv04)
|
||||||
|
- Code dependencies update
|
||||||
|
|
||||||
## v1.1.2
|
## v1.1.2
|
||||||
|
|
||||||
- Advanced settings
|
- Advanced settings
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
href="https://www.flaticon.com/free-icons/mortarboard" target="_blank" rel="noopener noreferrer"
|
href="https://www.flaticon.com/free-icons/mortarboard" target="_blank" rel="noopener noreferrer"
|
||||||
title="Mortarboard icons created by itim2101 - Flaticon" ><img src="./extension/icon.png" alt="Mortarboard icons created by itim2101 - Flaticon" width="150" style="display:block; margin:auto;"></a></p>
|
title="Mortarboard icons created by itim2101 - Flaticon" ><img src="./extension/icon.png" alt="Mortarboard icons created by itim2101 - Flaticon" width="150" style="display:block; margin:auto;"></a></p>
|
||||||
|
|
||||||
# MoodleGPT 1.1.2
|
# MoodleGPT 1.1.3
|
||||||
|
|
||||||
This extension allows you to hide CHAT-GPT in a Moodle quiz. You just need to click on the question you want to solve, and CHAT-GPT will automatically provide the answer. However, one needs to be careful because as we know, CHAT-GPT can make errors especially in calculations.
|
This extension allows you to hide CHAT-GPT in a Moodle quiz. You just need to click on the question you want to solve, and CHAT-GPT will automatically provide the answer. However, one needs to be careful because as we know, CHAT-GPT can make errors especially in calculations.
|
||||||
|
|
||||||
@@ -12,15 +12,17 @@ Find the extension on the Chrome Webstore right [here](https://chrome.google.com
|
|||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
- [MoodleGPT 1.1.2](#moodlegpt-112)
|
- [MoodleGPT 1.1.3](#moodlegpt-113)
|
||||||
- [Chrome Webstore](#chrome-webstore)
|
- [Chrome Webstore](#chrome-webstore)
|
||||||
- [Summary](#summary)
|
- [Summary](#summary)
|
||||||
- [Disclaimer !](#disclaimer-)
|
- [Disclaimer !](#disclaimer-)
|
||||||
- [Donate](#donate)
|
- [Donate](#donate)
|
||||||
- [Update](#update)
|
- [Update](#update)
|
||||||
- [Set up](#set-up)
|
- [Set up](#set-up)
|
||||||
- [Mode](#mode)
|
|
||||||
- [Settings](#settings)
|
- [Settings](#settings)
|
||||||
|
- [Advanced Settings](#advanced-settings)
|
||||||
|
- [Mode](#mode)
|
||||||
|
- [Options](#options)
|
||||||
- [Internal other features](#internal-other-features)
|
- [Internal other features](#internal-other-features)
|
||||||
- [Support table](#support-table)
|
- [Support table](#support-table)
|
||||||
- [Supported questions type](#supported-questions-type)
|
- [Supported questions type](#supported-questions-type)
|
||||||
@@ -61,6 +63,17 @@ See the [changelog](./CHANGELOG.md) to see every updates !
|
|||||||
|
|
||||||
Go to <b>"Manage my extensions"</b> on your browser, then click on <b>"Load unpacked extension"</b> and select the <b>"extension"</b> folder. Afterwards, click on the extension icon and enter the ApiKey obtained from [openai api](https://platform.openai.com/api-keys). Finally, select a [gpt model](https://platform.openai.com/docs/models) (ensure it work with completion api).
|
Go to <b>"Manage my extensions"</b> on your browser, then click on <b>"Load unpacked extension"</b> and select the <b>"extension"</b> folder. Afterwards, click on the extension icon and enter the ApiKey obtained from [openai api](https://platform.openai.com/api-keys). Finally, select a [gpt model](https://platform.openai.com/docs/models) (ensure it work with completion api).
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
|
||||||
|
- <b>API KEY\*</b>: Your openai [API KEY](https://platform.openai.com/api-keys)
|
||||||
|
- <b>GPT MODEL\*</b>: The [gpt model](https://platform.openai.com/docs/models) (you can click on the play button to ensure the model work with the extension)
|
||||||
|
|
||||||
|
## Advanced Settings
|
||||||
|
|
||||||
|
- <b>CODE</b>: A code you will need to type on your keyboard to inject/remove the extension code from the moodle page. It allow you to be more discret and control the injection so it's recommended.
|
||||||
|
- <b>BASE URL</b>: The API endpoint if you need to use your own llm.
|
||||||
|
- <b>MAX TOKENS</b>: The max tokens length you want the api to respond with.
|
||||||
|
|
||||||
## Mode
|
## Mode
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -72,7 +85,7 @@ Go to <b>"Manage my extensions"</b> on your browser, then click on <b>"Load unpa
|
|||||||
- <b>Question to answer:</b> The question is converted to the answer and you can click on it to show back the question (or show back the answer).
|
- <b>Question to answer:</b> The question is converted to the answer and you can click on it to show back the question (or show back the answer).
|
||||||
<br/><img src="./assets/question-to-answer.gif" alt="Question to Answer">
|
<br/><img src="./assets/question-to-answer.gif" alt="Question to Answer">
|
||||||
|
|
||||||
## Settings
|
## Options
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="./assets/settings.png" alt="Popup" width="300">
|
<img src="./assets/settings.png" alt="Popup" width="300">
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
const js = require('@eslint/js');
|
||||||
|
const tsParser = require('@typescript-eslint/parser');
|
||||||
|
const tsPlugin = require('@typescript-eslint/eslint-plugin');
|
||||||
|
const prettierConfig = require('eslint-config-prettier');
|
||||||
|
const tseslint = require('typescript-eslint');
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
ignores: ['**/node_modules/*', '**/dist/*', '**/*.js']
|
||||||
|
},
|
||||||
|
|
||||||
|
js.configs.recommended,
|
||||||
|
...tseslint.configs.recommended,
|
||||||
|
|
||||||
|
{
|
||||||
|
files: ['**/*.ts'],
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
sourceType: 'module'
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
'@typescript-eslint': tsPlugin
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...tsPlugin.configs['eslint-recommended'].rules,
|
||||||
|
...tsPlugin.configs.recommended.rules,
|
||||||
|
...prettierConfig.rules,
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "MoodleGPT",
|
"name": "MoodleGPT",
|
||||||
"version": "1.1.2",
|
"version": "1.1.3",
|
||||||
"description": "Hidden chat-gpt for your moodle quiz",
|
"description": "Hidden chat-gpt for your moodle quiz",
|
||||||
"permissions": ["storage"],
|
"permissions": ["storage"],
|
||||||
"action": {
|
"action": {
|
||||||
|
|||||||
@@ -56,6 +56,14 @@
|
|||||||
<label for="code" class="textLabel">Code:</label>
|
<label for="code" class="textLabel">Code:</label>
|
||||||
<input id="code" type="text" />
|
<input id="code" type="text" />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="line center">
|
||||||
|
<label for="baseURL" class="textLabel">Base URL:</label>
|
||||||
|
<input id="baseURL" type="text" />
|
||||||
|
</div>
|
||||||
|
<div class="line center">
|
||||||
|
<label for="maxTokens" class="textLabel">Max Tokens:</label>
|
||||||
|
<input id="maxTokens" type="number" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- SWITCH SETTINGS MODE -->
|
<!-- SWITCH SETTINGS MODE -->
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -82,6 +82,7 @@ a {
|
|||||||
|
|
||||||
.line input[type='text'],
|
.line input[type='text'],
|
||||||
.line input[type='password'],
|
.line input[type='password'],
|
||||||
|
.line input[type='number'],
|
||||||
.line select {
|
.line select {
|
||||||
flex: 1 1;
|
flex: 1 1;
|
||||||
border: thin solid var(--color);
|
border: thin solid var(--color);
|
||||||
|
|||||||
Generated
+1301
-1691
File diff suppressed because it is too large
Load Diff
+9
-7
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "moodlegpt",
|
"name": "moodlegpt",
|
||||||
"version": "1.1.2",
|
"version": "1.1.3",
|
||||||
"description": "This extension allows you to hide CHAT-GPT in a Moodle quiz.",
|
"description": "This extension allows you to hide CHAT-GPT in a Moodle quiz.",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run prettier && npm run lint && npm run fastBuild",
|
"build": "npm run prettier && npm run lint && npm run fastBuild",
|
||||||
@@ -26,19 +26,21 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/yoannchb-pro/MoodleGPT#readme",
|
"homepage": "https://github.com/yoannchb-pro/MoodleGPT#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.22.0",
|
||||||
"@rollup/plugin-commonjs": "^28.0.2",
|
"@rollup/plugin-commonjs": "^28.0.2",
|
||||||
"@rollup/plugin-node-resolve": "^16.0.0",
|
"@rollup/plugin-node-resolve": "^16.0.0",
|
||||||
"@rollup/plugin-terser": "^0.4.4",
|
"@rollup/plugin-terser": "^0.4.4",
|
||||||
"@rollup/plugin-typescript": "^12.1.2",
|
"@rollup/plugin-typescript": "^12.1.2",
|
||||||
"@types/chrome": "^0.0.294",
|
"@types/chrome": "^0.0.309",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
"@typescript-eslint/eslint-plugin": "^8.26.1",
|
||||||
"@typescript-eslint/parser": "^7.2.0",
|
"@typescript-eslint/parser": "^8.26.1",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^9.22.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.1.1",
|
||||||
"openai": "^4.78.1",
|
"openai": "^4.78.1",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"rollup": "^4.13.0",
|
"rollup": "^4.13.0",
|
||||||
"rollup-plugin-ts": "^3.2.0",
|
"rollup-plugin-ts": "^3.2.0",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2",
|
||||||
|
"typescript-eslint": "^8.26.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ async function getChatGPTResponse(
|
|||||||
|
|
||||||
const client = new OpenAI({
|
const client = new OpenAI({
|
||||||
apiKey: config.apiKey,
|
apiKey: config.apiKey,
|
||||||
|
baseURL: config.baseURL,
|
||||||
dangerouslyAllowBrowser: true
|
dangerouslyAllowBrowser: true
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -36,7 +37,7 @@ async function getChatGPTResponse(
|
|||||||
temperature: 0.1, // Controls the randomness of the generated responses, with lower values producing more deterministic and predictable outputs. With set to 0.1 instead of 0 for more creativity.
|
temperature: 0.1, // Controls the randomness of the generated responses, with lower values producing more deterministic and predictable outputs. With set to 0.1 instead of 0 for more creativity.
|
||||||
top_p: 0.6, // Determines the diversity of the generated responses
|
top_p: 0.6, // Determines the diversity of the generated responses
|
||||||
presence_penalty: 0, // Encourages the model to introduce new concepts by penalizing words that have already appeared in the text.
|
presence_penalty: 0, // Encourages the model to introduce new concepts by penalizing words that have already appeared in the text.
|
||||||
max_tokens: 2000 // Maximum length of the response,
|
max_tokens: config.maxTokens || 2000 // Maximum length of the response,
|
||||||
}),
|
}),
|
||||||
{ signal: config.timeout ? controller.signal : null }
|
{ signal: config.timeout ? controller.signal : null }
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ type Config = {
|
|||||||
history?: boolean;
|
history?: boolean;
|
||||||
includeImages?: boolean;
|
includeImages?: boolean;
|
||||||
mode?: 'autocomplete' | 'question-to-answer' | 'clipboard';
|
mode?: 'autocomplete' | 'question-to-answer' | 'clipboard';
|
||||||
|
baseURL?: string;
|
||||||
|
maxTokens?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Config;
|
export default Config;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ const apiKeySelector: HTMLInputElement = document.querySelector('#apiKey')!;
|
|||||||
const inputModel: HTMLInputElement = document.querySelector('#model')!;
|
const inputModel: HTMLInputElement = document.querySelector('#model')!;
|
||||||
const modelsList: HTMLElement = document.querySelector('#models')!;
|
const modelsList: HTMLElement = document.querySelector('#models')!;
|
||||||
const imagesIntegrationLine: HTMLInputElement = document.querySelector('#includeImages-line')!;
|
const imagesIntegrationLine: HTMLInputElement = document.querySelector('#includeImages-line')!;
|
||||||
|
const baseURLSelector: HTMLInputElement = document.querySelector('#baseURL')!;
|
||||||
/**
|
/**
|
||||||
* Check if the gpt version is at least 4 to show the option 'Include images'
|
* Check if the gpt version is at least 4 to show the option 'Include images'
|
||||||
*/
|
*/
|
||||||
@@ -23,6 +23,7 @@ inputModel.addEventListener('input', checkCanIncludeImages);
|
|||||||
// We populate the datalist of the chatgpt model
|
// We populate the datalist of the chatgpt model
|
||||||
export async function populateDatalistWithGptVersions() {
|
export async function populateDatalistWithGptVersions() {
|
||||||
const apiKey = apiKeySelector.value?.trim();
|
const apiKey = apiKeySelector.value?.trim();
|
||||||
|
const baseURL = baseURLSelector.value?.trim();
|
||||||
|
|
||||||
if (!apiKey) return;
|
if (!apiKey) return;
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ export async function populateDatalistWithGptVersions() {
|
|||||||
try {
|
try {
|
||||||
const client = new OpenAI({
|
const client = new OpenAI({
|
||||||
apiKey,
|
apiKey,
|
||||||
|
baseURL,
|
||||||
dangerouslyAllowBrowser: true
|
dangerouslyAllowBrowser: true
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -61,9 +63,11 @@ inputModel.addEventListener('focus', populateDatalistWithGptVersions);
|
|||||||
export async function checkModel() {
|
export async function checkModel() {
|
||||||
const model = inputModel.value?.trim();
|
const model = inputModel.value?.trim();
|
||||||
const apiKey = apiKeySelector.value?.trim();
|
const apiKey = apiKeySelector.value?.trim();
|
||||||
|
const baseURL = baseURLSelector.value?.trim();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const client = new OpenAI({ apiKey, dangerouslyAllowBrowser: true });
|
showMessage({ msg: 'Checking GPT version...', isInfinite: true, isError: false });
|
||||||
|
const client = new OpenAI({ apiKey, baseURL, dangerouslyAllowBrowser: true });
|
||||||
await client.chat.completions.create({
|
await client.chat.completions.create({
|
||||||
model,
|
model,
|
||||||
messages: [{ role: 'user', content: 'reply just pong' }]
|
messages: [{ role: 'user', content: 'reply just pong' }]
|
||||||
|
|||||||
+4
-2
@@ -9,11 +9,11 @@ import { showMessage } from './utils';
|
|||||||
const saveBtn = document.querySelector('.save')!;
|
const saveBtn = document.querySelector('.save')!;
|
||||||
|
|
||||||
// inputs id
|
// inputs id
|
||||||
const inputsText = ['apiKey', 'code', 'model'];
|
const inputsText = ['apiKey', 'code', 'model', 'baseURL', 'maxTokens'];
|
||||||
|
|
||||||
// Save the configuration
|
// Save the configuration
|
||||||
saveBtn.addEventListener('click', function () {
|
saveBtn.addEventListener('click', function () {
|
||||||
const [apiKey, code, model] = inputsText.map(selector =>
|
const [apiKey, code, model, baseURL, maxTokens] = inputsText.map(selector =>
|
||||||
(document.querySelector('#' + selector) as HTMLInputElement).value.trim()
|
(document.querySelector('#' + selector) as HTMLInputElement).value.trim()
|
||||||
);
|
);
|
||||||
const [logs, title, cursor, typing, mouseover, infinite, timeout, history, includeImages] =
|
const [logs, title, cursor, typing, mouseover, infinite, timeout, history, includeImages] =
|
||||||
@@ -40,6 +40,8 @@ saveBtn.addEventListener('click', function () {
|
|||||||
apiKey,
|
apiKey,
|
||||||
code,
|
code,
|
||||||
model,
|
model,
|
||||||
|
baseURL,
|
||||||
|
maxTokens: maxTokens ? parseInt(maxTokens) : undefined,
|
||||||
logs,
|
logs,
|
||||||
title,
|
title,
|
||||||
cursor,
|
cursor,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const CURRENT_VERSION = '1.1.2';
|
const CURRENT_VERSION = '1.1.3';
|
||||||
const versionDisplay = document.querySelector('#version')!;
|
const versionDisplay = document.querySelector('#version')!;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user