Move config migration from post-install to src
| @@ -350,6 +350,7 @@ Start.bat --port 8000 --listen false | ||
| 350 | 350 | | Option | Description | Type | |
| 351 | 351 | |-------------------------|----------------------------------------------------------------------|----------| |
| 352 | 352 | | `--version` | Show version number | boolean | |
| 353 | +| `--configPath` | Override the path to the config.yaml file | string | | |
| 353 | 354 | | `--dataRoot` | Root directory for data storage | string | |
| 354 | 355 | | `--port` | Sets the port under which SillyTavern will run | number | |
| 355 | 356 | | `--listen` | SillyTavern will listen on all network interfaces | boolean | |
| @@ -5,130 +5,15 @@ import fs from 'node:fs'; | ||
| 5 | 5 | import path from 'node:path'; |
| 6 | 6 | import process from 'node:process'; |
| 7 | 7 | import yaml from 'yaml'; |
| 8 | -import _ from 'lodash'; | |
| 9 | 8 | import chalk from 'chalk'; |
| 10 | 9 | import { createRequire } from 'node:module'; |
| 10 | +import { addMissingConfigValues } from './src/config-init.js'; | |
| 11 | 11 | |
| 12 | 12 | /** |
| 13 | 13 | * Colorizes console output. |
| 14 | 14 | */ |
| 15 | 15 | const color = chalk; |
| 16 | 16 | |
| 17 | -const keyMigrationMap = [ | |
| 18 | - { | |
| 19 | - oldKey: 'disableThumbnails', | |
| 20 | - newKey: 'thumbnails.enabled', | |
| 21 | - migrate: (value) => !value, | |
| 22 | - }, | |
| 23 | - { | |
| 24 | - oldKey: 'thumbnailsQuality', | |
| 25 | - newKey: 'thumbnails.quality', | |
| 26 | - migrate: (value) => value, | |
| 27 | - }, | |
| 28 | - { | |
| 29 | - oldKey: 'avatarThumbnailsPng', | |
| 30 | - newKey: 'thumbnails.format', | |
| 31 | - migrate: (value) => (value ? 'png' : 'jpg'), | |
| 32 | - }, | |
| 33 | - { | |
| 34 | - oldKey: 'disableChatBackup', | |
| 35 | - newKey: 'backups.chat.enabled', | |
| 36 | - migrate: (value) => !value, | |
| 37 | - }, | |
| 38 | - { | |
| 39 | - oldKey: 'numberOfBackups', | |
| 40 | - newKey: 'backups.common.numberOfBackups', | |
| 41 | - migrate: (value) => value, | |
| 42 | - }, | |
| 43 | - { | |
| 44 | - oldKey: 'maxTotalChatBackups', | |
| 45 | - newKey: 'backups.chat.maxTotalBackups', | |
| 46 | - migrate: (value) => value, | |
| 47 | - }, | |
| 48 | - { | |
| 49 | - oldKey: 'chatBackupThrottleInterval', | |
| 50 | - newKey: 'backups.chat.throttleInterval', | |
| 51 | - migrate: (value) => value, | |
| 52 | - }, | |
| 53 | - { | |
| 54 | - oldKey: 'enableExtensions', | |
| 55 | - newKey: 'extensions.enabled', | |
| 56 | - migrate: (value) => value, | |
| 57 | - }, | |
| 58 | - { | |
| 59 | - oldKey: 'enableExtensionsAutoUpdate', | |
| 60 | - newKey: 'extensions.autoUpdate', | |
| 61 | - migrate: (value) => value, | |
| 62 | - }, | |
| 63 | - { | |
| 64 | - oldKey: 'extras.disableAutoDownload', | |
| 65 | - newKey: 'extensions.models.autoDownload', | |
| 66 | - migrate: (value) => !value, | |
| 67 | - }, | |
| 68 | - { | |
| 69 | - oldKey: 'extras.classificationModel', | |
| 70 | - newKey: 'extensions.models.classification', | |
| 71 | - migrate: (value) => value, | |
| 72 | - }, | |
| 73 | - { | |
| 74 | - oldKey: 'extras.captioningModel', | |
| 75 | - newKey: 'extensions.models.captioning', | |
| 76 | - migrate: (value) => value, | |
| 77 | - }, | |
| 78 | - { | |
| 79 | - oldKey: 'extras.embeddingModel', | |
| 80 | - newKey: 'extensions.models.embedding', | |
| 81 | - migrate: (value) => value, | |
| 82 | - }, | |
| 83 | - { | |
| 84 | - oldKey: 'extras.speechToTextModel', | |
| 85 | - newKey: 'extensions.models.speechToText', | |
| 86 | - migrate: (value) => value, | |
| 87 | - }, | |
| 88 | - { | |
| 89 | - oldKey: 'extras.textToSpeechModel', | |
| 90 | - newKey: 'extensions.models.textToSpeech', | |
| 91 | - migrate: (value) => value, | |
| 92 | - }, | |
| 93 | - { | |
| 94 | - oldKey: 'minLogLevel', | |
| 95 | - newKey: 'logging.minLogLevel', | |
| 96 | - migrate: (value) => value, | |
| 97 | - }, | |
| 98 | - { | |
| 99 | - oldKey: 'cardsCacheCapacity', | |
| 100 | - newKey: 'performance.memoryCacheCapacity', | |
| 101 | - migrate: (value) => `${value}mb`, | |
| 102 | - }, | |
| 103 | - { | |
| 104 | - oldKey: 'cookieSecret', | |
| 105 | - newKey: 'cookieSecret', | |
| 106 | - migrate: () => void 0, | |
| 107 | - remove: true, | |
| 108 | - }, | |
| 109 | -]; | |
| 110 | - | |
| 111 | -/** | |
| 112 | - * Gets all keys from an object recursively. | |
| 113 | - * @param {object} obj Object to get all keys from | |
| 114 | - * @param {string} prefix Prefix to prepend to all keys | |
| 115 | - * @returns {string[]} Array of all keys in the object | |
| 116 | - */ | |
| 117 | -function getAllKeys(obj, prefix = '') { | |
| 118 | - if (typeof obj !== 'object' || Array.isArray(obj) || obj === null) { | |
| 119 | - return []; | |
| 120 | - } | |
| 121 | - | |
| 122 | - return _.flatMap(Object.keys(obj), key => { | |
| 123 | - const newPrefix = prefix ? `${prefix}.${key}` : key; | |
| 124 | - if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) { | |
| 125 | - return getAllKeys(obj[key], newPrefix); | |
| 126 | - } else { | |
| 127 | - return [newPrefix]; | |
| 128 | - } | |
| 129 | - }); | |
| 130 | -} | |
| 131 | - | |
| 132 | 17 | /** |
| 133 | 18 | * Converts the old config.conf file to the new config.yaml format. |
| 134 | 19 | */ |
| @@ -156,71 +41,6 @@ function convertConfig() { | ||
| 156 | 41 | } |
| 157 | 42 | |
| 158 | 43 | /** |
| 159 | - * Compares the current config.yaml with the default config.yaml and adds any missing values. | |
| 160 | - */ | |
| 161 | -function addMissingConfigValues() { | |
| 162 | - try { | |
| 163 | - const defaultConfig = yaml.parse(fs.readFileSync(path.join(process.cwd(), './default/config.yaml'), 'utf8')); | |
| 164 | - let config = yaml.parse(fs.readFileSync(path.join(process.cwd(), './config.yaml'), 'utf8')); | |
| 165 | - | |
| 166 | - // Migrate old keys to new keys | |
| 167 | - const migratedKeys = []; | |
| 168 | - for (const { oldKey, newKey, migrate, remove } of keyMigrationMap) { | |
| 169 | - if (_.has(config, oldKey)) { | |
| 170 | - if (remove) { | |
| 171 | - _.unset(config, oldKey); | |
| 172 | - migratedKeys.push({ | |
| 173 | - oldKey, | |
| 174 | - newValue: void 0, | |
| 175 | - }); | |
| 176 | - continue; | |
| 177 | - } | |
| 178 | - | |
| 179 | - const oldValue = _.get(config, oldKey); | |
| 180 | - const newValue = migrate(oldValue); | |
| 181 | - _.set(config, newKey, newValue); | |
| 182 | - _.unset(config, oldKey); | |
| 183 | - | |
| 184 | - migratedKeys.push({ | |
| 185 | - oldKey, | |
| 186 | - newKey, | |
| 187 | - oldValue, | |
| 188 | - newValue, | |
| 189 | - }); | |
| 190 | - } | |
| 191 | - } | |
| 192 | - | |
| 193 | - // Get all keys from the original config | |
| 194 | - const originalKeys = getAllKeys(config); | |
| 195 | - | |
| 196 | - // Use lodash's defaultsDeep function to recursively apply default properties | |
| 197 | - config = _.defaultsDeep(config, defaultConfig); | |
| 198 | - | |
| 199 | - // Get all keys from the updated config | |
| 200 | - const updatedKeys = getAllKeys(config); | |
| 201 | - | |
| 202 | - // Find the keys that were added | |
| 203 | - const addedKeys = _.difference(updatedKeys, originalKeys); | |
| 204 | - | |
| 205 | - if (addedKeys.length === 0 && migratedKeys.length === 0) { | |
| 206 | - return; | |
| 207 | - } | |
| 208 | - | |
| 209 | - if (addedKeys.length > 0) { | |
| 210 | - console.log('Adding missing config values to config.yaml:', addedKeys); | |
| 211 | - } | |
| 212 | - | |
| 213 | - if (migratedKeys.length > 0) { | |
| 214 | - console.log('Migrating config values in config.yaml:', migratedKeys); | |
| 215 | - } | |
| 216 | - | |
| 217 | - fs.writeFileSync('./config.yaml', yaml.stringify(config)); | |
| 218 | - } catch (error) { | |
| 219 | - console.error(color.red('FATAL: Could not add missing config values to config.yaml'), error); | |
| 220 | - } | |
| 221 | -} | |
| 222 | - | |
| 223 | -/** | |
| 224 | 44 | * Creates the default config files if they don't exist yet. |
| 225 | 45 | */ |
| 226 | 46 | function createDefaultFiles() { |
| @@ -288,7 +108,7 @@ try { | ||
| 288 | 108 | // 1. Create default config files |
| 289 | 109 | createDefaultFiles(); |
| 290 | 110 | // 2. Add missing config values |
| 291 | - addMissingConfigValues(); | |
| 111 | + addMissingConfigValues(path.join(process.cwd(), './config.yaml')); | |
| 292 | 112 | } catch (error) { |
| 293 | 113 | console.error(error); |
| 294 | 114 | } |
| @@ -1,7 +1,8 @@ | ||
| 1 | 1 | import yargs from 'yargs/yargs'; |
| 2 | 2 | import { hideBin } from 'yargs/helpers'; |
| 3 | 3 | import ipRegex from 'ip-regex'; |
| 4 | 4 | import { canResolve, color, getConfigValue, setConfigFilePath, stringToBool } from './util.js'; |
| 5 | +import { initConfig } from './config-init.js'; | |
| 5 | 6 | |
| 6 | 7 | /** |
| 7 | 8 | * @typedef {object} CommandLineArguments Parsed command line arguments |
| @@ -185,7 +186,7 @@ export class CommandLineParser { | ||
| 185 | 186 | }).parseSync(); |
| 186 | 187 | |
| 187 | 188 | const configPath = cliArguments.configPath ?? this.default.configPath; |
| 188 | 189 | setConfigFilePathinitConfig(configPath); |
| 189 | 190 | /** @type {CommandLineArguments} */ |
| 190 | 191 | const result = { |
| 191 | 192 | configPath: configPath, |
| @@ -0,0 +1,197 @@ | ||
| 1 | +import fs from 'node:fs'; | |
| 2 | +import path from 'node:path'; | |
| 3 | +import yaml from 'yaml'; | |
| 4 | +import color from 'chalk'; | |
| 5 | +import _ from 'lodash'; | |
| 6 | +import { serverDirectory } from './server-directory.js'; | |
| 7 | +import { setConfigFilePath } from './util.js'; | |
| 8 | + | |
| 9 | +const keyMigrationMap = [ | |
| 10 | + { | |
| 11 | + oldKey: 'disableThumbnails', | |
| 12 | + newKey: 'thumbnails.enabled', | |
| 13 | + migrate: (value) => !value, | |
| 14 | + }, | |
| 15 | + { | |
| 16 | + oldKey: 'thumbnailsQuality', | |
| 17 | + newKey: 'thumbnails.quality', | |
| 18 | + migrate: (value) => value, | |
| 19 | + }, | |
| 20 | + { | |
| 21 | + oldKey: 'avatarThumbnailsPng', | |
| 22 | + newKey: 'thumbnails.format', | |
| 23 | + migrate: (value) => (value ? 'png' : 'jpg'), | |
| 24 | + }, | |
| 25 | + { | |
| 26 | + oldKey: 'disableChatBackup', | |
| 27 | + newKey: 'backups.chat.enabled', | |
| 28 | + migrate: (value) => !value, | |
| 29 | + }, | |
| 30 | + { | |
| 31 | + oldKey: 'numberOfBackups', | |
| 32 | + newKey: 'backups.common.numberOfBackups', | |
| 33 | + migrate: (value) => value, | |
| 34 | + }, | |
| 35 | + { | |
| 36 | + oldKey: 'maxTotalChatBackups', | |
| 37 | + newKey: 'backups.chat.maxTotalBackups', | |
| 38 | + migrate: (value) => value, | |
| 39 | + }, | |
| 40 | + { | |
| 41 | + oldKey: 'chatBackupThrottleInterval', | |
| 42 | + newKey: 'backups.chat.throttleInterval', | |
| 43 | + migrate: (value) => value, | |
| 44 | + }, | |
| 45 | + { | |
| 46 | + oldKey: 'enableExtensions', | |
| 47 | + newKey: 'extensions.enabled', | |
| 48 | + migrate: (value) => value, | |
| 49 | + }, | |
| 50 | + { | |
| 51 | + oldKey: 'enableExtensionsAutoUpdate', | |
| 52 | + newKey: 'extensions.autoUpdate', | |
| 53 | + migrate: (value) => value, | |
| 54 | + }, | |
| 55 | + { | |
| 56 | + oldKey: 'extras.disableAutoDownload', | |
| 57 | + newKey: 'extensions.models.autoDownload', | |
| 58 | + migrate: (value) => !value, | |
| 59 | + }, | |
| 60 | + { | |
| 61 | + oldKey: 'extras.classificationModel', | |
| 62 | + newKey: 'extensions.models.classification', | |
| 63 | + migrate: (value) => value, | |
| 64 | + }, | |
| 65 | + { | |
| 66 | + oldKey: 'extras.captioningModel', | |
| 67 | + newKey: 'extensions.models.captioning', | |
| 68 | + migrate: (value) => value, | |
| 69 | + }, | |
| 70 | + { | |
| 71 | + oldKey: 'extras.embeddingModel', | |
| 72 | + newKey: 'extensions.models.embedding', | |
| 73 | + migrate: (value) => value, | |
| 74 | + }, | |
| 75 | + { | |
| 76 | + oldKey: 'extras.speechToTextModel', | |
| 77 | + newKey: 'extensions.models.speechToText', | |
| 78 | + migrate: (value) => value, | |
| 79 | + }, | |
| 80 | + { | |
| 81 | + oldKey: 'extras.textToSpeechModel', | |
| 82 | + newKey: 'extensions.models.textToSpeech', | |
| 83 | + migrate: (value) => value, | |
| 84 | + }, | |
| 85 | + { | |
| 86 | + oldKey: 'minLogLevel', | |
| 87 | + newKey: 'logging.minLogLevel', | |
| 88 | + migrate: (value) => value, | |
| 89 | + }, | |
| 90 | + { | |
| 91 | + oldKey: 'cardsCacheCapacity', | |
| 92 | + newKey: 'performance.memoryCacheCapacity', | |
| 93 | + migrate: (value) => `${value}mb`, | |
| 94 | + }, | |
| 95 | + { | |
| 96 | + oldKey: 'cookieSecret', | |
| 97 | + newKey: 'cookieSecret', | |
| 98 | + migrate: () => void 0, | |
| 99 | + remove: true, | |
| 100 | + }, | |
| 101 | +]; | |
| 102 | + | |
| 103 | +/** | |
| 104 | + * Gets all keys from an object recursively. | |
| 105 | + * @param {object} obj Object to get all keys from | |
| 106 | + * @param {string} prefix Prefix to prepend to all keys | |
| 107 | + * @returns {string[]} Array of all keys in the object | |
| 108 | + */ | |
| 109 | +function getAllKeys(obj, prefix = '') { | |
| 110 | + if (typeof obj !== 'object' || Array.isArray(obj) || obj === null) { | |
| 111 | + return []; | |
| 112 | + } | |
| 113 | + | |
| 114 | + return _.flatMap(Object.keys(obj), key => { | |
| 115 | + const newPrefix = prefix ? `${prefix}.${key}` : key; | |
| 116 | + if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) { | |
| 117 | + return getAllKeys(obj[key], newPrefix); | |
| 118 | + } else { | |
| 119 | + return [newPrefix]; | |
| 120 | + } | |
| 121 | + }); | |
| 122 | +} | |
| 123 | + | |
| 124 | +/** | |
| 125 | + * Compares the current config.yaml with the default config.yaml and adds any missing values. | |
| 126 | + * @param {string} configPath Path to config.yaml | |
| 127 | + */ | |
| 128 | +export function addMissingConfigValues(configPath) { | |
| 129 | + try { | |
| 130 | + const defaultConfig = yaml.parse(fs.readFileSync(path.join(serverDirectory, './default/config.yaml'), 'utf8')); | |
| 131 | + let config = yaml.parse(fs.readFileSync(configPath, 'utf8')); | |
| 132 | + | |
| 133 | + // Migrate old keys to new keys | |
| 134 | + const migratedKeys = []; | |
| 135 | + for (const { oldKey, newKey, migrate, remove } of keyMigrationMap) { | |
| 136 | + if (_.has(config, oldKey)) { | |
| 137 | + if (remove) { | |
| 138 | + _.unset(config, oldKey); | |
| 139 | + migratedKeys.push({ | |
| 140 | + oldKey, | |
| 141 | + newValue: void 0, | |
| 142 | + }); | |
| 143 | + continue; | |
| 144 | + } | |
| 145 | + | |
| 146 | + const oldValue = _.get(config, oldKey); | |
| 147 | + const newValue = migrate(oldValue); | |
| 148 | + _.set(config, newKey, newValue); | |
| 149 | + _.unset(config, oldKey); | |
| 150 | + | |
| 151 | + migratedKeys.push({ | |
| 152 | + oldKey, | |
| 153 | + newKey, | |
| 154 | + oldValue, | |
| 155 | + newValue, | |
| 156 | + }); | |
| 157 | + } | |
| 158 | + } | |
| 159 | + | |
| 160 | + // Get all keys from the original config | |
| 161 | + const originalKeys = getAllKeys(config); | |
| 162 | + | |
| 163 | + // Use lodash's defaultsDeep function to recursively apply default properties | |
| 164 | + config = _.defaultsDeep(config, defaultConfig); | |
| 165 | + | |
| 166 | + // Get all keys from the updated config | |
| 167 | + const updatedKeys = getAllKeys(config); | |
| 168 | + | |
| 169 | + // Find the keys that were added | |
| 170 | + const addedKeys = _.difference(updatedKeys, originalKeys); | |
| 171 | + | |
| 172 | + if (addedKeys.length === 0 && migratedKeys.length === 0) { | |
| 173 | + return; | |
| 174 | + } | |
| 175 | + | |
| 176 | + if (addedKeys.length > 0) { | |
| 177 | + console.log('Adding missing config values to config.yaml:', addedKeys); | |
| 178 | + } | |
| 179 | + | |
| 180 | + if (migratedKeys.length > 0) { | |
| 181 | + console.log('Migrating config values in config.yaml:', migratedKeys); | |
| 182 | + } | |
| 183 | + | |
| 184 | + fs.writeFileSync(configPath, yaml.stringify(config)); | |
| 185 | + } catch (error) { | |
| 186 | + console.error(color.red('FATAL: Could not add missing config values to config.yaml'), error); | |
| 187 | + } | |
| 188 | +} | |
| 189 | + | |
| 190 | +/** | |
| 191 | + * Performs early initialization tasks before the server starts. | |
| 192 | + * @param {string} configPath Path to config.yaml | |
| 193 | + */ | |
| 194 | +export function initConfig(configPath) { | |
| 195 | + setConfigFilePath(configPath); | |
| 196 | + addMissingConfigValues(configPath); | |
| 197 | +} | |
| @@ -12,7 +12,6 @@ configureTransformers(); | ||
| 12 | 12 | function configureTransformers() { |
| 13 | 13 | // Limit the number of threads to 1 to avoid issues on Android |
| 14 | 14 | env.backends.onnx.wasm.numThreads = 1; |
| 15 | - console.log(env.backends.onnx.wasm.wasmPaths); | |
| 16 | 15 | // Use WASM from a local folder to avoid CDN connections |
| 17 | 16 | env.backends.onnx.wasm.wasmPaths = path.join(serverDirectory, 'node_modules', 'sillytavern-transformers', 'dist') + path.sep; |
| 18 | 17 | } |
| @@ -15,8 +15,8 @@ import yauzl from 'yauzl'; | ||
| 15 | 15 | import mime from 'mime-types'; |
| 16 | 16 | import { default as simpleGit } from 'simple-git'; |
| 17 | 17 | import chalk from 'chalk'; |
| 18 | -import { LOG_LEVELS } from './constants.js'; | |
| 19 | 18 | import bytes from 'bytes'; |
| 19 | +import { LOG_LEVELS } from './constants.js'; | |
| 20 | 20 | import { serverDirectory } from './server-directory.js'; |
| 21 | 21 | |
| 22 | 22 | /** |