Reasoning template

62342b35e27253512352f8be5142dbb0c7063d47

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

11 files changed, +234 -20Ignore whitespace
default/content/index.json+4 -0
@@ -786,5 +786,9 @@
786 {786 {
787 "filename": "presets/context/DeepSeek-V2.5.json",787 "filename": "presets/context/DeepSeek-V2.5.json",
788 "type": "context"788 "type": "context"
789 },
790 {
791 "filename": "presets/reasoning/DeepSeek R1.json",
792 "type": "reasoning"
789 }793 }
790]794]
default/content/presets/reasoning/DeepSeek R1.json+6 -0
@@ -0,0 +1,6 @@
1{
2 "name": "DeepSeek R1",
3 "prefix": "<think>\n",
4 "suffix": "\n</think>",
5 "separator": "\n\n"
6}
public/index.html+13 -0
@@ -3917,6 +3917,19 @@
3917 <summary data-i18n="Reasoning Formatting">3917 <summary data-i18n="Reasoning Formatting">
3918 Reasoning Formatting3918 Reasoning Formatting
3919 </summary>3919 </summary>
3920 <div class="flex-container" title="Select your current Reasoning Template" data-i18n="[title]Select your current Reasoning Template">
3921 <select id="reasoning_select" data-preset-manager-for="reasoning" class="flex1 text_pole"></select>
3922 <div class="flex-container margin0 justifyCenter gap3px">
3923 <input type="file" hidden data-preset-manager-file="reasoning" accept=".json, .settings">
3924 <i data-preset-manager-update="reasoning" class="menu_button fa-solid fa-save" title="Update current template" data-i18n="[title]Update current template"></i>
3925 <i data-preset-manager-rename="reasoning" class="menu_button fa-pencil fa-solid" title="Rename current template" data-i18n="[title]Rename current template"></i>
3926 <i data-preset-manager-new="reasoning" class="menu_button fa-solid fa-file-circle-plus" title="Save template as" data-i18n="[title]Save template as"></i>
3927 <i data-preset-manager-import="reasoning" class="displayNone menu_button fa-solid fa-file-import" title="Import template" data-i18n="[title]Import template"></i>
3928 <i data-preset-manager-export="reasoning" class="displayNone menu_button fa-solid fa-file-export" title="Export template" data-i18n="[title]Export template"></i>
3929 <i data-preset-manager-restore="reasoning" class="menu_button fa-solid fa-recycle" title="Restore current template" data-i18n="[title]Restore current template"></i>
3930 <i data-preset-manager-delete="reasoning" class="menu_button fa-solid fa-trash-can" title="Delete template" data-i18n="[title]Delete template"></i>
3931 </div>
3932 </div>
3920 <div class="flex-container">3933 <div class="flex-container">
3921 <div class="flex1" title="Inserted before the reasoning content." data-i18n="[title]reasoning_prefix">3934 <div class="flex1" title="Inserted before the reasoning content." data-i18n="[title]reasoning_prefix">
3922 <small data-i18n="Prefix">Prefix</small>3935 <small data-i18n="Prefix">Prefix</small>
public/scripts/power-user.js+3 -0
@@ -55,6 +55,7 @@ import { POPUP_TYPE, callGenericPopup } from './popup.js';
55import { loadSystemPrompts } from './sysprompt.js';55import { loadSystemPrompts } from './sysprompt.js';
56import { fuzzySearchCategories } from './filters.js';56import { fuzzySearchCategories } from './filters.js';
57import { accountStorage } from './util/AccountStorage.js';57import { accountStorage } from './util/AccountStorage.js';
58import { loadReasoningTemplates } from './reasoning.js';
5859
59export {60export {
60 loadPowerUserSettings,61 loadPowerUserSettings,
@@ -255,6 +256,7 @@ let power_user = {
255 },256 },
256257
257 reasoning: {258 reasoning: {
259 name: 'DeepSeek R1',
258 auto_parse: false,260 auto_parse: false,
259 add_to_prompts: false,261 add_to_prompts: false,
260 auto_expand: false,262 auto_expand: false,
@@ -1622,6 +1624,7 @@ async function loadPowerUserSettings(settings, data) {
1622 await loadInstructMode(data);1624 await loadInstructMode(data);
1623 await loadContextSettings();1625 await loadContextSettings();
1624 await loadSystemPrompts(data);1626 await loadSystemPrompts(data);
1627 await loadReasoningTemplates(data);
1625 loadMaxContextUnlocked();1628 loadMaxContextUnlocked();
1626 switchWaifuMode();1629 switchWaifuMode();
1627 switchSpoilerMode();1630 switchSpoilerMode();
public/scripts/preset-manager.js+44 -2
@@ -21,7 +21,7 @@ import { groups, selected_group } from './group-chats.js';
21import { instruct_presets } from './instruct-mode.js';21import { instruct_presets } from './instruct-mode.js';
22import { kai_settings } from './kai-settings.js';22import { kai_settings } from './kai-settings.js';
23import { convertNovelPreset } from './nai-settings.js';23import { convertNovelPreset } from './nai-settings.js';
24import { openai_settings, openai_setting_names, oai_settings } from './openai.js';24import { openai_settings, openai_setting_names } from './openai.js';
25import { Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js';25import { Popup, POPUP_RESULT, POPUP_TYPE } from './popup.js';
26import { context_presets, getContextSettings, power_user } from './power-user.js';26import { context_presets, getContextSettings, power_user } from './power-user.js';
27import { SlashCommand } from './slash-commands/SlashCommand.js';27import { SlashCommand } from './slash-commands/SlashCommand.js';
@@ -38,6 +38,7 @@ import {
38} from './textgen-settings.js';38} from './textgen-settings.js';
39import { download, parseJsonFile, waitUntilCondition } from './utils.js';39import { download, parseJsonFile, waitUntilCondition } from './utils.js';
40import { t } from './i18n.js';40import { t } from './i18n.js';
41import { reasoning_templates } from './reasoning.js';
4142
42const presetManagers = {};43const presetManagers = {};
4344
@@ -168,6 +169,20 @@ class PresetManager {
168 },169 },
169 isValid: (data) => PresetManager.isPossiblyTextCompletionData(data),170 isValid: (data) => PresetManager.isPossiblyTextCompletionData(data),
170 },171 },
172 'reasoning': {
173 name: 'Reasoning Formatting',
174 getData: () => {
175 const manager = getPresetManager('reasoning');
176 const name = manager.getSelectedPresetName();
177 return manager.getPresetSettings(name);
178 },
179 setData: (data) => {
180 const manager = getPresetManager('reasoning');
181 const name = data.name;
182 return manager.savePreset(name, data);
183 },
184 isValid: (data) => PresetManager.isPossiblyReasoningData(data),
185 },
171 };186 };
172187
173 static isPossiblyInstructData(data) {188 static isPossiblyInstructData(data) {
@@ -190,6 +205,11 @@ class PresetManager {
190 return data && textCompletionProps.every(prop => Object.keys(data).includes(prop));205 return data && textCompletionProps.every(prop => Object.keys(data).includes(prop));
191 }206 }
192207
208 static isPossiblyReasoningData(data) {
209 const reasoningProps = ['name', 'prefix', 'suffix', 'separator'];
210 return data && reasoningProps.every(prop => Object.keys(data).includes(prop));
211 }
212
193 /**213 /**
194 * Imports master settings from JSON data.214 * Imports master settings from JSON data.
195 * @param {object} data Data to import215 * @param {object} data Data to import
@@ -227,6 +247,12 @@ class PresetManager {
227 return await getPresetManager('textgenerationwebui').savePreset(fileName, data);247 return await getPresetManager('textgenerationwebui').savePreset(fileName, data);
228 }248 }
229249
250 // 5. Reasoning Template
251 if (this.isPossiblyReasoningData(data)) {
252 toastr.info(t`Importing as reasoning template...`, t`Reasoning template detected`);
253 return await getPresetManager('reasoning').savePreset(data.name, data);
254 }
255
230 const validSections = [];256 const validSections = [];
231 for (const [key, section] of Object.entries(this.masterSections)) {257 for (const [key, section] of Object.entries(this.masterSections)) {
232 if (key in data && section.isValid(data[key])) {258 if (key in data && section.isValid(data[key])) {
@@ -478,6 +504,10 @@ class PresetManager {
478 presets = system_prompts;504 presets = system_prompts;
479 preset_names = system_prompts.map(x => x.name);505 preset_names = system_prompts.map(x => x.name);
480 break;506 break;
507 case 'reasoning':
508 presets = reasoning_templates;
509 preset_names = reasoning_templates.map(x => x.name);
510 break;
481 default:511 default:
482 console.warn(`Unknown API ID ${api}`);512 console.warn(`Unknown API ID ${api}`);
483 }513 }
@@ -490,7 +520,7 @@ class PresetManager {
490 }520 }
491521
492 isAdvancedFormatting() {522 isAdvancedFormatting() {
493 return this.apiId == 'context' || this.apiId == 'instruct' || this.apiId == 'sysprompt';523 return ['context', 'instruct', 'sysprompt', 'reasoning'].includes(this.apiId);
494 }524 }
495525
496 updateList(name, preset) {526 updateList(name, preset) {
@@ -553,6 +583,11 @@ class PresetManager {
553 sysprompt_preset['name'] = name || power_user.sysprompt.preset;583 sysprompt_preset['name'] = name || power_user.sysprompt.preset;
554 return sysprompt_preset;584 return sysprompt_preset;
555 }585 }
586 case 'reasoning': {
587 const reasoning_preset = structuredClone(power_user.reasoning);
588 reasoning_preset['name'] = name || power_user.reasoning.preset;
589 return reasoning_preset;
590 }
556 default:591 default:
557 console.warn(`Unknown API ID ${apiId}`);592 console.warn(`Unknown API ID ${apiId}`);
558 return {};593 return {};
@@ -599,6 +634,13 @@ class PresetManager {
599 'include_reasoning',634 'include_reasoning',
600 'global_banned_tokens',635 'global_banned_tokens',
601 'send_banned_tokens',636 'send_banned_tokens',
637
638 // Reasoning exclusions
639 'auto_parse',
640 'add_to_prompts',
641 'auto_expand',
642 'show_hidden',
643 'max_additions',
602 ];644 ];
603 const settings = Object.assign({}, getSettingsByApiId(this.apiId));645 const settings = Object.assign({}, getSettingsByApiId(this.apiId));
604646
public/scripts/reasoning.js+154 -17
@@ -1,4 +1,5 @@
1import {1import {
2 Fuse,
2 moment,3 moment,
3} from '../lib.js';4} from '../lib.js';
4import { chat, closeMessageEditor, event_types, eventSource, main_api, messageFormatting, saveChatConditional, saveChatDebounced, saveSettingsDebounced, substituteParams, syncMesToSwipe, updateMessageBlock } from '../script.js';5import { chat, closeMessageEditor, event_types, eventSource, main_api, messageFormatting, saveChatConditional, saveChatDebounced, saveSettingsDebounced, substituteParams, syncMesToSwipe, updateMessageBlock } from '../script.js';
@@ -14,7 +15,36 @@ import { commonEnumProviders, enumIcons } from './slash-commands/SlashCommandCom
14import { enumTypes, SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';15import { enumTypes, SlashCommandEnumValue } from './slash-commands/SlashCommandEnumValue.js';
15import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';16import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
16import { textgen_types, textgenerationwebui_settings } from './textgen-settings.js';17import { textgen_types, textgenerationwebui_settings } from './textgen-settings.js';
17import { copyText, escapeRegex, isFalseBoolean, setDatasetProperty, trimSpaces } from './utils.js';18import { copyText, escapeRegex, isFalseBoolean, isTrueBoolean, setDatasetProperty, trimSpaces } from './utils.js';
19
20/**
21 * @typedef {object} ReasoningTemplate
22 * @property {string} name - The name of the template
23 * @property {string} prefix - Reasoning prefix
24 * @property {string} suffix - Reasoning suffix
25 * @property {string} separator - Reasoning separator
26 */
27
28/**
29 * @type {ReasoningTemplate[]} List of reasoning templates
30 */
31export const reasoning_templates = [];
32
33/**
34 * @type {Record<string, JQuery<HTMLElement>>} List of UI elements for reasoning settings
35 * @readonly
36 */
37const UI = {
38 $select: $('#reasoning_select'),
39 $suffix: $('#reasoning_suffix'),
40 $prefix: $('#reasoning_prefix'),
41 $separator: $('#reasoning_separator'),
42 $autoParse: $('#reasoning_auto_parse'),
43 $autoExpand: $('#reasoning_auto_expand'),
44 $showHidden: $('#reasoning_show_hidden'),
45 $addToPrompts: $('#reasoning_add_to_prompts'),
46 $maxAdditions: $('#reasoning_max_additions'),
47};
1848
19/**49/**
20 * Enum representing the type of the reasoning for a message (where it came from)50 * Enum representing the type of the reasoning for a message (where it came from)
@@ -664,57 +694,103 @@ export class PromptReasoning {
664}694}
665695
666function loadReasoningSettings() {696function loadReasoningSettings() {
667 $('#reasoning_add_to_prompts').prop('checked', power_user.reasoning.add_to_prompts);697 UI.$addToPrompts.prop('checked', power_user.reasoning.add_to_prompts);
668 $('#reasoning_add_to_prompts').on('change', function () {698 UI.$addToPrompts.on('change', function () {
669 power_user.reasoning.add_to_prompts = !!$(this).prop('checked');699 power_user.reasoning.add_to_prompts = !!$(this).prop('checked');
670 saveSettingsDebounced();700 saveSettingsDebounced();
671 });701 });
672702
673 $('#reasoning_prefix').val(power_user.reasoning.prefix);703 UI.$prefix.val(power_user.reasoning.prefix);
674 $('#reasoning_prefix').on('input', function () {704 UI.$prefix.on('input', function () {
675 power_user.reasoning.prefix = String($(this).val());705 power_user.reasoning.prefix = String($(this).val());
676 saveSettingsDebounced();706 saveSettingsDebounced();
677 });707 });
678708
679 $('#reasoning_suffix').val(power_user.reasoning.suffix);709 UI.$suffix.val(power_user.reasoning.suffix);
680 $('#reasoning_suffix').on('input', function () {710 UI.$suffix.on('input', function () {
681 power_user.reasoning.suffix = String($(this).val());711 power_user.reasoning.suffix = String($(this).val());
682 saveSettingsDebounced();712 saveSettingsDebounced();
683 });713 });
684714
685 $('#reasoning_separator').val(power_user.reasoning.separator);715 UI.$separator.val(power_user.reasoning.separator);
686 $('#reasoning_separator').on('input', function () {716 UI.$separator.on('input', function () {
687 power_user.reasoning.separator = String($(this).val());717 power_user.reasoning.separator = String($(this).val());
688 saveSettingsDebounced();718 saveSettingsDebounced();
689 });719 });
690720
691 $('#reasoning_max_additions').val(power_user.reasoning.max_additions);721 UI.$maxAdditions.val(power_user.reasoning.max_additions);
692 $('#reasoning_max_additions').on('input', function () {722 UI.$maxAdditions.on('input', function () {
693 power_user.reasoning.max_additions = Number($(this).val());723 power_user.reasoning.max_additions = Number($(this).val());
694 saveSettingsDebounced();724 saveSettingsDebounced();
695 });725 });
696726
697 $('#reasoning_auto_parse').prop('checked', power_user.reasoning.auto_parse);727 UI.$autoParse.prop('checked', power_user.reasoning.auto_parse);
698 $('#reasoning_auto_parse').on('change', function () {728 UI.$autoParse.on('change', function () {
699 power_user.reasoning.auto_parse = !!$(this).prop('checked');729 power_user.reasoning.auto_parse = !!$(this).prop('checked');
700 saveSettingsDebounced();730 saveSettingsDebounced();
701 });731 });
702732
703 $('#reasoning_auto_expand').prop('checked', power_user.reasoning.auto_expand);733 UI.$autoExpand.prop('checked', power_user.reasoning.auto_expand);
704 $('#reasoning_auto_expand').on('change', function () {734 UI.$autoExpand.on('change', function () {
705 power_user.reasoning.auto_expand = !!$(this).prop('checked');735 power_user.reasoning.auto_expand = !!$(this).prop('checked');
706 toggleReasoningAutoExpand();736 toggleReasoningAutoExpand();
707 saveSettingsDebounced();737 saveSettingsDebounced();
708 });738 });
709 toggleReasoningAutoExpand();739 toggleReasoningAutoExpand();
710740
711 $('#reasoning_show_hidden').prop('checked', power_user.reasoning.show_hidden);741 UI.$showHidden.prop('checked', power_user.reasoning.show_hidden);
712 $('#reasoning_show_hidden').on('change', function () {742 UI.$showHidden.on('change', function () {
713 power_user.reasoning.show_hidden = !!$(this).prop('checked');743 power_user.reasoning.show_hidden = !!$(this).prop('checked');
714 $('#chat').attr('data-show-hidden-reasoning', power_user.reasoning.show_hidden ? 'true' : null);744 $('#chat').attr('data-show-hidden-reasoning', power_user.reasoning.show_hidden ? 'true' : null);
715 saveSettingsDebounced();745 saveSettingsDebounced();
716 });746 });
717 $('#chat').attr('data-show-hidden-reasoning', power_user.reasoning.show_hidden ? 'true' : null);747 $('#chat').attr('data-show-hidden-reasoning', power_user.reasoning.show_hidden ? 'true' : null);
748
749 UI.$select.on('change', async function () {
750 const name = String($(this).val());
751 const template = reasoning_templates.find(p => p.name === name);
752 if (!template) {
753 return;
754 }
755
756 UI.$prefix.val(template.prefix);
757 UI.$suffix.val(template.suffix);
758 UI.$separator.val(template.separator);
759
760 power_user.reasoning.name = name;
761 power_user.reasoning.prefix = template.prefix;
762 power_user.reasoning.suffix = template.suffix;
763 power_user.reasoning.separator = template.separator;
764
765 saveSettingsDebounced();
766 });
767}
768
769function selectReasoningTemplateCallback(args, name) {
770 if (!name) {
771 return power_user.reasoning.name ?? '';
772 }
773
774 const quiet = isTrueBoolean(args?.quiet);
775 const templateNames = reasoning_templates.map(preset => preset.name);
776 let foundName = templateNames.find(x => x.toLowerCase() === name.toLowerCase());
777
778 if (!foundName) {
779 const fuse = new Fuse(templateNames);
780 const result = fuse.search(name);
781
782 if (result.length === 0) {
783 !quiet && toastr.warning(`Reasoning template "${name}" not found`);
784 return '';
785 }
786
787 foundName = result[0].item;
788 }
789
790 UI.$select.val(foundName).trigger('change');
791 !quiet && toastr.success(`Reasoning template "${foundName}" selected`);
792 return foundName;
793
718}794}
719795
720function registerReasoningSlashCommands() {796function registerReasoningSlashCommands() {
@@ -848,6 +924,42 @@ function registerReasoningSlashCommands() {
848 : parsedReasoning.reasoning;924 : parsedReasoning.reasoning;
849 },925 },
850 }));926 }));
927 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
928 name: 'reasoning-template',
929 aliases: ['reasoning-formatting', 'reasoning-preset'],
930 callback: selectReasoningTemplateCallback,
931 returns: 'template name',
932 namedArgumentList: [
933 SlashCommandNamedArgument.fromProps({
934 name: 'quiet',
935 description: 'Suppress the toast message on template change',
936 typeList: [ARGUMENT_TYPE.BOOLEAN],
937 defaultValue: 'false',
938 enumList: commonEnumProviders.boolean('trueFalse')(),
939 }),
940 ],
941 unnamedArgumentList: [
942 SlashCommandArgument.fromProps({
943 description: 'reasoning template name',
944 typeList: [ARGUMENT_TYPE.STRING],
945 enumProvider: () => reasoning_templates.map(x => new SlashCommandEnumValue(x.name, null, enumTypes.enum, enumIcons.preset)),
946 }),
947 ],
948 helpString: `
949 <div>
950 Selects a reasoning template by name, using fuzzy search to find the closest match.
951 Gets the current template if no name is provided.
952 </div>
953 <div>
954 <strong>Example:</strong>
955 <ul>
956 <li>
957 <pre><code class="language-stscript">/reasoning-template DeepSeek R1</code></pre>
958 </li>
959 </ul>
960 </div>
961 `,
962 }));
851}963}
852964
853function registerReasoningMacros() {965function registerReasoningMacros() {
@@ -1207,6 +1319,31 @@ function registerReasoningAppEvents() {
1207 }1319 }
1208}1320}
12091321
1322/**
1323 * Loads reasoning templates from the settings data.
1324 * @param {object} data Settings data
1325 * @param {ReasoningTemplate[]} data.reasoning Reasoning templates
1326 * @returns {Promise<void>}
1327 */
1328export async function loadReasoningTemplates(data) {
1329 if (data.reasoning !== undefined) {
1330 reasoning_templates.splice(0, reasoning_templates.length, ...data.reasoning);
1331 }
1332
1333 for (const template of reasoning_templates) {
1334 $('<option>').val(template.name).text(template.name).appendTo(UI.$select);
1335 }
1336
1337 if (!power_user.reasoning.name) {
1338 power_user.reasoning.name = reasoning_templates[0]?.name ?? '';
1339 }
1340
1341 UI.$select.val(power_user.reasoning.name);
1342}
1343
1344/**
1345 * Initializes reasoning settings and event handlers.
1346 */
1210export function initReasoning() {1347export function initReasoning() {
1211 loadReasoningSettings();1348 loadReasoningSettings();
1212 setReasoningEventHandlers();1349 setReasoningEventHandlers();
src/constants.js+1 -0
@@ -43,6 +43,7 @@ export const USER_DIRECTORY_TEMPLATE = Object.freeze({
43 vectors: 'vectors',43 vectors: 'vectors',
44 backups: 'backups',44 backups: 'backups',
45 sysprompt: 'sysprompt',45 sysprompt: 'sysprompt',
46 reasoning: 'reasoning',
46});47});
4748
48/**49/**
src/endpoints/content-manager.js+4 -1
@@ -48,6 +48,7 @@ export const CONTENT_TYPES = {
48 MOVING_UI: 'moving_ui',48 MOVING_UI: 'moving_ui',
49 QUICK_REPLIES: 'quick_replies',49 QUICK_REPLIES: 'quick_replies',
50 SYSPROMPT: 'sysprompt',50 SYSPROMPT: 'sysprompt',
51 REASONING: 'reasoning',
51};52};
5253
53/**54/**
@@ -61,7 +62,7 @@ export function getDefaultPresets(directories) {
61 const presets = [];62 const presets = [];
6263
63 for (const contentItem of contentIndex) {64 for (const contentItem of contentIndex) {
64 if (contentItem.type.endsWith('_preset') || contentItem.type === 'instruct' || contentItem.type === 'context' || contentItem.type === 'sysprompt') {65 if (contentItem.type.endsWith('_preset') || ['instruct', 'context', 'sysprompt', 'reasoning'].includes(contentItem.type)) {
65 contentItem.name = path.parse(contentItem.filename).name;66 contentItem.name = path.parse(contentItem.filename).name;
66 contentItem.folder = getTargetByType(contentItem.type, directories);67 contentItem.folder = getTargetByType(contentItem.type, directories);
67 presets.push(contentItem);68 presets.push(contentItem);
@@ -299,6 +300,8 @@ function getTargetByType(type, directories) {
299 return directories.quickreplies;300 return directories.quickreplies;
300 case CONTENT_TYPES.SYSPROMPT:301 case CONTENT_TYPES.SYSPROMPT:
301 return directories.sysprompt;302 return directories.sysprompt;
303 case CONTENT_TYPES.REASONING:
304 return directories.reasoning;
302 default:305 default:
303 return null;306 return null;
304 }307 }
src/endpoints/presets.js+2 -0
@@ -30,6 +30,8 @@ function getPresetSettingsByAPI(apiId, directories) {
30 return { folder: directories.context, extension: '.json' };30 return { folder: directories.context, extension: '.json' };
31 case 'sysprompt':31 case 'sysprompt':
32 return { folder: directories.sysprompt, extension: '.json' };32 return { folder: directories.sysprompt, extension: '.json' };
33 case 'reasoning':
34 return { folder: directories.reasoning, extension: '.json' };
33 default:35 default:
34 return { folder: null, extension: null };36 return { folder: null, extension: null };
35 }37 }
src/endpoints/settings.js+2 -0
@@ -254,6 +254,7 @@ router.post('/get', (request, response) => {
254 const instruct = readAndParseFromDirectory(request.user.directories.instruct);254 const instruct = readAndParseFromDirectory(request.user.directories.instruct);
255 const context = readAndParseFromDirectory(request.user.directories.context);255 const context = readAndParseFromDirectory(request.user.directories.context);
256 const sysprompt = readAndParseFromDirectory(request.user.directories.sysprompt);256 const sysprompt = readAndParseFromDirectory(request.user.directories.sysprompt);
257 const reasoning = readAndParseFromDirectory(request.user.directories.reasoning);
257258
258 response.send({259 response.send({
259 settings,260 settings,
@@ -272,6 +273,7 @@ router.post('/get', (request, response) => {
272 instruct,273 instruct,
273 context,274 context,
274 sysprompt,275 sysprompt,
276 reasoning,
275 enable_extensions: ENABLE_EXTENSIONS,277 enable_extensions: ENABLE_EXTENSIONS,
276 enable_extensions_auto_update: ENABLE_EXTENSIONS_AUTO_UPDATE,278 enable_extensions_auto_update: ENABLE_EXTENSIONS_AUTO_UPDATE,
277 enable_accounts: ENABLE_ACCOUNTS,279 enable_accounts: ENABLE_ACCOUNTS,
src/users.js+1 -0
@@ -95,6 +95,7 @@ const STORAGE_KEYS = {
95 * @property {string} vectors - The directory where the vectors are stored95 * @property {string} vectors - The directory where the vectors are stored
96 * @property {string} backups - The directory where the backups are stored96 * @property {string} backups - The directory where the backups are stored
97 * @property {string} sysprompt - The directory where the system prompt data is stored97 * @property {string} sysprompt - The directory where the system prompt data is stored
98 * @property {string} reasoning - The directory where the reasoning templates are stored
98 */99 */
99100
100/**101/**