Fix /genraw user instruct format not applied and unwanted system newline (#5372) * Initial plan * Fix /genraw user instruct format and system newline bugs - Fix Bug #1: Change default role for string prompts from 'system' to 'user' to ensure user instruct formatting is properly applied - Fix Bug #2: Remove unconditional newline after system prompt when using instruct mode, respecting the actual system instruct format Agent-Logs-Url: https://github.com/SillyTavern/SillyTavern/sessions/7bfd62eb-2898-468d-9ea9-42d694a394b9 Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com> * fix: add runtime string type check for substituteParams content * Add fallback wrap for story string --------- Co-authored-by: anthropic-code-agent[bot] <242468646+Claude@users.noreply.github.com> Co-authored-by: Cohee1207 <18619528+Cohee1207@users.noreply.github.com>
Signed| @@ -2907,6 +2907,11 @@ export function substituteParamsLegacy(content, _name1, _name2, _original, _grou | ||
| 2907 | 2907 | export function substituteParams(content, options = {}) { |
| 2908 | 2908 | if (!content) return ''; |
| 2909 | 2909 | |
| 2910 | + if (typeof content !== 'string') { | |
| 2911 | + console.warn('substituteParams: content will be coerced to string', content); | |
| 2912 | + content = String(content); | |
| 2913 | + } | |
| 2914 | + | |
| 2910 | 2915 | // Handle legacy signature calls to substituteParams |
| 2911 | 2916 | // We'll simply re-route them to a temporary legacy function. In the future, we'll remove this and cleanly build the options object ourselves. |
| 2912 | 2917 | const isOptionsObject = options && typeof options === 'object' && !Array.isArray(options); |
| @@ -3847,9 +3852,7 @@ export function createRawPrompt(prompt, api, instructOverride, quietToLoud, syst | ||
| 3847 | 3852 | |
| 3848 | 3853 | // If the prompt was given as a string, convert to a message-style object assuming user role |
| 3849 | 3854 | if (typeof prompt === 'string') { |
| 3850 | 3855 | const message = api{ ===role: 'openaiuser', content: prompt.trim() }; |
| 3851 | - ? { role: 'user', content: prompt.trim() } | |
| 3852 | - : { role: 'system', content: prompt }; | |
| 3853 | 3856 | prompt = [message]; |
| 3854 | 3857 | } else { // checks for message-style object |
| 3855 | 3858 | if (prompt.length === 0 && !systemPrompt) throw Error('No messages provided'); |
| @@ -3876,7 +3879,12 @@ export function createRawPrompt(prompt, api, instructOverride, quietToLoud, syst | ||
| 3876 | 3879 | // prepend system prompt, if provided |
| 3877 | 3880 | if (systemPrompt) { |
| 3878 | 3881 | systemPrompt = substituteParams(systemPrompt); |
| 3879 | 3882 | systemPrompt = isInstruct ? (formatInstructModeStoryString(systemPrompt) + '\n') : systemPrompt.trim(); |
| 3883 | + if (isInstruct && systemPrompt.length > 0 && !systemPrompt.endsWith('\n')) { | |
| 3884 | + if (power_user.instruct.wrap && !power_user.instruct.story_string_suffix) { | |
| 3885 | + systemPrompt += '\n'; | |
| 3886 | + } | |
| 3887 | + } | |
| 3880 | 3888 | prompt.unshift({ role: 'system', content: systemPrompt }); |
| 3881 | 3889 | } |
| 3882 | 3890 | |