adding prefill parameter to generateRaw() (#4266)

* adding prefill parameter to generateRaw()

* additional comments

* Substitute params in prefill

* Add prefill prompt for /genraw command

* Fix param comment

* fixing generateRaw param comment

* fixing param comment

---------

Co-authored-by: qvink <qvink@users.noreply.github.com>
Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
This commit is contained in:
qvink
2025-07-14 17:51:53 +00:00
committed by GitHub
parent 3edb5a5616
commit 556fb4ba08
2 changed files with 31 additions and 12 deletions
+17 -7
View File
@@ -3058,10 +3058,11 @@ class StreamingProcessor {
* @param {string} api API to use.
* @param {boolean} instructOverride true to override instruct mode, false to use the default value
* @param {boolean} quietToLoud true to generate a message in system mode, false to generate a message in character mode
* @param {string} [systemPrompt] System prompt to use. Only Instruct mode or OpenAI.
* @param {string} [systemPrompt] System prompt to use.
* @param {string} [prefill] Prefill for the prompt.
* @returns {string | object[]} Prompt ready for use in generation. If using TC, this will be a string. If using CC, this will be an array of chat-style messages.
*/
export function createRawPrompt(prompt, api, instructOverride, quietToLoud, systemPrompt) {
export function createRawPrompt(prompt, api, instructOverride, quietToLoud, systemPrompt, prefill) {
const isInstruct = power_user.instruct.enabled && api !== 'openai' && api !== 'novel' && !instructOverride;
// If the prompt was given as a string, convert to a message-style object assuming user role
@@ -3074,6 +3075,9 @@ export function createRawPrompt(prompt, api, instructOverride, quietToLoud, syst
if (prompt.length === 0 && !systemPrompt) throw Error('No messages provided');
}
// Substitute the prefill if provided
prefill = substituteParams(prefill ?? '');
// Format each message in the prompt, accounting for the provided roles
for (const message of prompt) {
let name = '';
@@ -3096,12 +3100,17 @@ export function createRawPrompt(prompt, api, instructOverride, quietToLoud, syst
prompt.unshift({ role: 'system', content: systemPrompt });
}
// If text completion, convert to text prompt by concatenating all message contents
// with Chat Completion, the prefill is an additional assistant message at the end.
if (api === 'openai' && prefill) {
prompt.push({ role: 'assistant', content: prefill });
}
// if text completion, convert to text prompt by concatenating all message contents and adding the prefill as a promptBias.
if (api !== 'openai') {
const joiner = isInstruct ? '' : '\n';
prompt = prompt.map(message => message.content).join(joiner);
prompt = api === 'novel' ? adjustNovelInstructionPrompt(prompt) : prompt;
prompt = prompt + (isInstruct ? formatInstructModePrompt(name2, false, '', name1, name2, true, quietToLoud) : '\n'); // add last line
prompt = prompt + (isInstruct ? formatInstructModePrompt(name2, false, prefill, name1, name2, true, quietToLoud) : `\n${prefill}`); // add last line
}
return prompt;
@@ -3114,12 +3123,13 @@ export function createRawPrompt(prompt, api, instructOverride, quietToLoud, syst
* @param {string} api API to use. Main API is used if not specified.
* @param {boolean} instructOverride true to override instruct mode, false to use the default value
* @param {boolean} quietToLoud true to generate a message in system mode, false to generate a message in character mode
* @param {string} [systemPrompt] System prompt to use. Only Instruct mode or OpenAI.
* @param {string} [systemPrompt] System prompt to use.
* @param {number} [responseLength] Maximum response length. If unset, the global default value is used.
* @param {boolean} [trimNames] Whether to allow trimming "{{user}}:" and "{{char}}:" from the response.
* @param {string} [prefill] An optional prefill for the prompt.
* @returns {Promise<string>} Generated message
*/
export async function generateRaw(prompt, api, instructOverride, quietToLoud, systemPrompt, responseLength, trimNames = true) {
export async function generateRaw(prompt, api, instructOverride, quietToLoud, systemPrompt, responseLength, trimNames = true, prefill = '') {
if (!api) {
api = main_api;
}
@@ -3129,7 +3139,7 @@ export async function generateRaw(prompt, api, instructOverride, quietToLoud, sy
let eventHook = () => { };
// construct final prompt from the input. Can either be a string or an array of chat-style messages.
prompt = createRawPrompt(prompt, api, instructOverride, quietToLoud, systemPrompt);
prompt = createRawPrompt(prompt, api, instructOverride, quietToLoud, systemPrompt, prefill);
try {
if (responseLengthCustomized) {
+14 -5
View File
@@ -1672,17 +1672,18 @@ export function initDefaultSlashCommands() {
returns: 'generated text',
namedArgumentList: [
new SlashCommandNamedArgument(
'lock', 'lock user input during generation', [ARGUMENT_TYPE.BOOLEAN], false, false, null, commonEnumProviders.boolean('onOff')(),
'lock', 'lock user input during generation', [ARGUMENT_TYPE.BOOLEAN], false, false, 'off', commonEnumProviders.boolean('onOff')(),
),
new SlashCommandNamedArgument(
'instruct', 'use instruct mode', [ARGUMENT_TYPE.BOOLEAN], false, false, 'on', commonEnumProviders.boolean('onOff')(),
),
new SlashCommandNamedArgument(
'stop', 'one-time custom stop strings', [ARGUMENT_TYPE.LIST], false,
'stop', 'one-time custom stop strings', [ARGUMENT_TYPE.LIST], false, false, '[]',
),
SlashCommandNamedArgument.fromProps({
name: 'as',
description: 'role of the output prompt',
defaultValue: 'system',
typeList: [ARGUMENT_TYPE.STRING],
enumList: [
new SlashCommandEnumValue('system', null, enumTypes.enum, enumIcons.assistant),
@@ -1690,10 +1691,16 @@ export function initDefaultSlashCommands() {
],
}),
new SlashCommandNamedArgument(
'system', 'system prompt at the start', [ARGUMENT_TYPE.STRING], false,
'system', 'system prompt at the start', [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.VARIABLE_NAME], false,
),
new SlashCommandNamedArgument(
'length', 'API response length in tokens', [ARGUMENT_TYPE.NUMBER], false,
'prefill', 'prefill prompt at the end', [ARGUMENT_TYPE.STRING, ARGUMENT_TYPE.VARIABLE_NAME], false,
),
new SlashCommandNamedArgument(
'length', 'API response length in tokens', [ARGUMENT_TYPE.NUMBER, ARGUMENT_TYPE.VARIABLE_NAME], false,
),
new SlashCommandNamedArgument(
'trim', 'trim {{user}} and {{char}} prefixes from the output', [ARGUMENT_TYPE.BOOLEAN], false, false, 'on', commonEnumProviders.boolean('onOff')(),
),
],
unnamedArgumentList: [
@@ -3628,7 +3635,9 @@ async function generateRawCallback(args, value) {
const as = args?.as || 'system';
const quietToLoud = as === 'char';
const systemPrompt = resolveVariable(args?.system) || '';
const prefillPrompt = resolveVariable(args?.prefill) || '';
const length = Number(resolveVariable(args?.length) ?? 0) || 0;
const trimNames = !isFalseBoolean(args?.trim);
try {
if (lock) {
@@ -3636,7 +3645,7 @@ async function generateRawCallback(args, value) {
}
setEphemeralStopStrings(resolveVariable(args?.stop));
const result = await generateRaw(value, '', isFalseBoolean(args?.instruct), quietToLoud, systemPrompt, length);
const result = await generateRaw(value, '', isFalseBoolean(args?.instruct), quietToLoud, systemPrompt, length, trimNames, prefillPrompt);
return result;
} catch (err) {
console.error('Error on /genraw generation', err);