diff --git a/default/config.yaml b/default/config.yaml index a9d38a4d0..4c28044dc 100644 --- a/default/config.yaml +++ b/default/config.yaml @@ -133,24 +133,26 @@ whitelistImportDomains: ## headers: ## User-Agent: "Googlebot/2.1 (+http://www.google.com/bot.html)" requestOverrides: [] -# -- EXTENSIONS CONFIGURATION -- -# Enable UI extensions -enableExtensions: true -# Automatically update extensions when a release version changes -enableExtensionsAutoUpdate: true + +# EXTENSIONS CONFIGURATION +extensions: + # Enable UI extensions + enabled: true + # Automatically update extensions when a release version changes + autoUpdate: true + models: + # Enables automatic model download from HuggingFace + autoDownload: true + # Additional models for extensions. Expects model IDs from HuggingFace model hub in ONNX format + classification: Cohee/distilbert-base-uncased-go-emotions-onnx + captioning: Xenova/vit-gpt2-image-captioning + embedding: Cohee/jina-embeddings-v2-base-en + speechToText: Xenova/whisper-small + textToSpeech: Xenova/speecht5_tts + # Additional model tokenizers can be downloaded on demand. # Disabling will fallback to another locally available tokenizer. enableDownloadableTokenizers: true -# Extension settings -extras: - # Disables automatic model download from HuggingFace - disableAutoDownload: false - # Extra models for plugins. Expects model IDs from HuggingFace model hub in ONNX format - classificationModel: Cohee/distilbert-base-uncased-go-emotions-onnx - captioningModel: Xenova/vit-gpt2-image-captioning - embeddingModel: Cohee/jina-embeddings-v2-base-en - speechToTextModel: Xenova/whisper-small - textToSpeechModel: Xenova/speecht5_tts # -- OPENAI CONFIGURATION -- # A placeholder message to use in strict prompt post-processing mode when the prompt doesn't start with a user message promptPlaceholder: "[Start a new chat]" diff --git a/jsconfig.json b/jsconfig.json index 042caf675..4130eaedc 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -15,7 +15,7 @@ "**/node_modules/**", "**/dist/**", "**/.git/**", - "public/lib/**", + "public/**", "backups/**", "data/**", "cache/**", diff --git a/post-install.js b/post-install.js index 63c3de926..4c9765eb8 100644 --- a/post-install.js +++ b/post-install.js @@ -64,6 +64,46 @@ const keyMigrationMap = [ newKey: 'backups.chat.throttleInterval', migrate: (value) => value, }, + { + oldKey: 'enableExtensions', + newKey: 'extensions.enabled', + migrate: (value) => value, + }, + { + oldKey: 'enableExtensionsAutoUpdate', + newKey: 'extensions.autoUpdate', + migrate: (value) => value, + }, + { + oldKey: 'extras.disableAutoDownload', + newKey: 'extensions.models.autoDownload', + migrate: (value) => !value, + }, + { + oldKey: 'extras.classificationModel', + newKey: 'extensions.models.classification', + migrate: (value) => value, + }, + { + oldKey: 'extras.captioningModel', + newKey: 'extensions.models.captioning', + migrate: (value) => value, + }, + { + oldKey: 'extras.embeddingModel', + newKey: 'extensions.models.embedding', + migrate: (value) => value, + }, + { + oldKey: 'extras.speechToTextModel', + newKey: 'extensions.models.speechToText', + migrate: (value) => value, + }, + { + oldKey: 'extras.textToSpeechModel', + newKey: 'extensions.models.textToSpeech', + migrate: (value) => value, + }, ]; /** diff --git a/src/endpoints/settings.js b/src/endpoints/settings.js index 0c4a7cf28..3cc7e3bec 100644 --- a/src/endpoints/settings.js +++ b/src/endpoints/settings.js @@ -10,8 +10,8 @@ import { getConfigValue, generateTimestamp, removeOldBackups } from '../util.js' import { jsonParser } from '../express-common.js'; import { getAllUserHandles, getUserDirectories } from '../users.js'; -const ENABLE_EXTENSIONS = getConfigValue('enableExtensions', true); -const ENABLE_EXTENSIONS_AUTO_UPDATE = getConfigValue('enableExtensionsAutoUpdate', true); +const ENABLE_EXTENSIONS = !!getConfigValue('extensions.enabled', true); +const ENABLE_EXTENSIONS_AUTO_UPDATE = !!getConfigValue('extensions.autoUpdate', true); const ENABLE_ACCOUNTS = getConfigValue('enableUserAccounts', false); // 10 minutes diff --git a/src/endpoints/vectors.js b/src/endpoints/vectors.js index 325684601..b0b9819ac 100644 --- a/src/endpoints/vectors.js +++ b/src/endpoints/vectors.js @@ -164,7 +164,7 @@ function getSourceSettings(source, request) { }; case 'transformers': return { - model: getConfigValue('extras.embeddingModel', ''), + model: getConfigValue('extensions.models.embedding', ''), }; case 'palm': return { diff --git a/src/transformers.js b/src/transformers.js index 3413101a6..c8f8da4f6 100644 --- a/src/transformers.js +++ b/src/transformers.js @@ -19,31 +19,31 @@ const tasks = { 'text-classification': { defaultModel: 'Cohee/distilbert-base-uncased-go-emotions-onnx', pipeline: null, - configField: 'extras.classificationModel', + configField: 'extensions.models.classification', quantized: true, }, 'image-to-text': { defaultModel: 'Xenova/vit-gpt2-image-captioning', pipeline: null, - configField: 'extras.captioningModel', + configField: 'extensions.models.captioning', quantized: true, }, 'feature-extraction': { defaultModel: 'Xenova/all-mpnet-base-v2', pipeline: null, - configField: 'extras.embeddingModel', + configField: 'extensions.models.embedding', quantized: true, }, 'automatic-speech-recognition': { defaultModel: 'Xenova/whisper-small', pipeline: null, - configField: 'extras.speechToTextModel', + configField: 'extensions.models.speechToText', quantized: true, }, 'text-to-speech': { defaultModel: 'Xenova/speecht5_tts', pipeline: null, - configField: 'extras.textToSpeechModel', + configField: 'extensions.models.textToSpeech', quantized: false, }, }; @@ -132,7 +132,7 @@ export async function getPipeline(task, forceModel = '') { const cacheDir = path.join(globalThis.DATA_ROOT, '_cache'); const model = forceModel || getModelForTask(task); - const localOnly = getConfigValue('extras.disableAutoDownload', false); + const localOnly = !getConfigValue('extensions.models.autoDownload', true); console.log('Initializing transformers.js pipeline for task', task, 'with model', model); const instance = await pipeline(task, model, { cache_dir: cacheDir, quantized: tasks[task].quantized ?? true, local_files_only: localOnly }); tasks[task].pipeline = instance;