Migrate only unique and non-default instruct prompts

4b235f0b3159ae90007715f7f1bb709550e05c6a

Cohee <18619528+Cohee1207@users.noreply.github.com>

2 files changed, +60 -4Showing whitespace changes
src/endpoints/content-manager.js+32 -0
@@ -219,6 +219,37 @@ function getContentIndex() {
219219}
220220
221221/**
222+ * Gets content by type and format.
223+ * @param {string} type Type of content
224+ * @param {'json'|'string'|'raw'} format Format of content
225+ * @returns {string[]|Buffer[]} Array of content
226+ */
227+function getContentOfType(type, format) {
228+ const contentIndex = getContentIndex();
229+ const indexItems = contentIndex.filter((item) => item.type === type && item.folder);
230+ const files = [];
231+ for (const item of indexItems) {
232+ if (!item.folder) {
233+ continue;
234+ }
235+ const filePath = path.join(item.folder, item.filename);
236+ const fileContent = fs.readFileSync(filePath);
237+ switch (format) {
238+ case 'json':
239+ files.push(JSON.parse(fileContent.toString()));
240+ break;
241+ case 'string':
242+ files.push(fileContent.toString());
243+ break;
244+ case 'raw':
245+ files.push(fileContent);
246+ break;
247+ }
248+ }
249+ return files;
250+}
251+
252+/**
222253 * Gets the target directory for the specified asset type.
223254 * @param {ContentType} type Asset type
224255 * @param {import('../users').UserDirectoryList} directories User directories
@@ -724,5 +755,6 @@ module.exports = {
724755 checkForNewContent,
725756 getDefaultPresets,
726757 getDefaultPresetFile,
758+ getContentOfType,
727759 router,
728760};
src/users.js+28 -4
@@ -10,6 +10,7 @@ const express = require('express');
1010const mime = require('mime-types');
1111const archiver = require('archiver');
1212const writeFileAtomicSync = require('write-file-atomic').sync;
13+const _ = require('lodash');
1314
1415const { USER_DIRECTORY_TEMPLATE, DEFAULT_USER, PUBLIC_DIRECTORIES, SETTINGS_FILE } = require('./constants');
1516const { getConfigValue, color, delay, setConfigValue, generateTimestamp } = require('./util');
@@ -326,6 +327,19 @@ async function migrateUserData() {
326327}
327328
328329async function migrateSystemPrompts() {
330+ /**
331+ * Gets the default system prompts.
332+ * @returns {Promise<any[]>} - The list of default system prompts
333+ */
334+ async function getDefaultSystemPrompts() {
335+ try {
336+ const { getContentOfType } = await import('./endpoints/content-manager.js');
337+ return getContentOfType('sysprompt', 'json');
338+ } catch {
339+ return [];
340+ }
341+ }
342+
329343 const directories = await getUserDirectoriesList();
330344 for (const directory of directories) {
331345 try {
@@ -333,21 +347,31 @@ async function migrateSystemPrompts() {
333347 if (fs.existsSync(migrateMarker)) {
334348 continue;
335349 }
350+ const defaultPrompts = await getDefaultSystemPrompts();
336351 const instucts = fs.readdirSync(directory.instruct);
352+ let migratedPrompts = [];
337353 for (const instruct of instucts) {
338354 const instructPath = path.join(directory.instruct, instruct);
339355 const syspromptPathsysPromptPath = path.join(directory.sysprompt, instruct);
340356 if (path.extname(instruct) === '.json' && !fs.existsSync(syspromptPathsysPromptPath)) {
341357 const instructData = JSON.parse(fs.readFileSync(instructPath, 'utf8'));
342358 if ('system_prompt' in instructData && 'name' in instructData) {
343359 const syspromptData = { name: instructData.name, content: instructData.system_prompt };
344- writeFileAtomicSync(syspromptPath, JSON.stringify(syspromptData, null, 4));
360+ migratedPrompts.push(syspromptData);
345361 delete instructData.system_prompt;
346362 writeFileAtomicSync(instructPath, JSON.stringify(instructData, null, 4));
347- console.log(`Migrated system prompt ${instruct} for ${directory.root.split(path.sep).pop()}`);
348363 }
349364 }
350365 }
366+ // Only leave unique contents
367+ migratedPrompts = _.uniqBy(migratedPrompts, 'content');
368+ // Only leave contents that are not in the default prompts
369+ migratedPrompts = migratedPrompts.filter(x => !defaultPrompts.some(y => y.content === x.content));
370+ for (const sysPromptData of migratedPrompts) {
371+ const syspromptPath = path.join(directory.sysprompt, `${sysPromptData.name}.json`);
372+ writeFileAtomicSync(syspromptPath, JSON.stringify(sysPromptData, null, 4));
373+ console.log(`Migrated system prompt ${sysPromptData.name} for ${directory.root.split(path.sep).pop()}`);
374+ }
351375 writeFileAtomicSync(migrateMarker, '');
352376 } catch {
353377 // Ignore errors