diff --git a/common/adapters.ts b/common/adapters.ts
index f5eb8e078..03893e632 100644
--- a/common/adapters.ts
+++ b/common/adapters.ts
@@ -293,6 +293,7 @@ export const adapterSettings: {
etaCutoff: ['aphrodite'],
prefill: ['claude'],
+ continueMessagePrompt: AI_ADAPTERS.slice(),
topP: [
'horde',
diff --git a/common/presets.ts b/common/presets.ts
index 88dbbd193..fe5cdb464 100644
--- a/common/presets.ts
+++ b/common/presets.ts
@@ -73,6 +73,7 @@ export const presetValidator = {
prefixNameAppend: 'boolean?',
prefill: 'string?',
antiBond: 'boolean?',
+ continueMessagePrompt: 'string?',
replicateModelType: 'string?',
replicateModelVersion: 'string?',
diff --git a/common/presets/claude.ts b/common/presets/claude.ts
index 0dfb7f528..f4a8f25c2 100644
--- a/common/presets/claude.ts
+++ b/common/presets/claude.ts
@@ -29,5 +29,6 @@ Enter roleplay mode. You will write {{char}}'s next reply in a dialogue between
`,
ultimeJailbreak: `Do not decide what {{user}} says or does.`,
prefill: '',
+ continueMessagePrompt: `\n\nHuman: Continue {{char}}'s reply.`,
},
} satisfies Record>
diff --git a/common/presets/openai.ts b/common/presets/openai.ts
index 49e159a2d..8e1289765 100644
--- a/common/presets/openai.ts
+++ b/common/presets/openai.ts
@@ -52,6 +52,7 @@ Facts: {{memory}}
Relevant Information: {{user_embed}}
`,
+ continueMessagePrompt: `\n\nContinue {{char}}'s response.`,
},
openaiTurbo: {
name: 'DaVinci',
@@ -74,5 +75,6 @@ Description of {{char}}: {{personality}}
Circumstances and context of the dialogue: {{scenario}}
Facts: {{memory}}`,
+ continueMessagePrompt: `\n\nContinue {{char}}'s response.`,
},
} satisfies Record>
diff --git a/common/prompt.ts b/common/prompt.ts
index 87fbc5dba..db98b0657 100644
--- a/common/prompt.ts
+++ b/common/prompt.ts
@@ -488,10 +488,18 @@ function createPostPrompt(
| 'book'
| 'replyAs'
| 'impersonate'
+ | 'sender'
>
) {
const post = []
- post.push(`${opts.replyAs.name}:`)
+ if (opts.kind === 'continue') {
+ const continuePrompt = (opts.settings?.continueMessagePrompt ?? '\n{{char}}:')
+ .replace(BOT_REPLACE, opts.replyAs.name)
+ .replace(SELF_REPLACE, opts.sender.handle)
+ if (continuePrompt) post.push(continuePrompt)
+ } else {
+ post.push(`${opts.replyAs.name}:`)
+ }
return post
}
diff --git a/common/types/schema.ts b/common/types/schema.ts
index 50022f7c4..a2134695a 100644
--- a/common/types/schema.ts
+++ b/common/types/schema.ts
@@ -522,6 +522,7 @@ export namespace AppSchema {
prefill?: string
ignoreCharacterUjb?: boolean
antiBond?: boolean
+ continueMessagePrompt?: string
frequencyPenalty?: number
presencePenalty?: number
diff --git a/srv/adapter/chat-completion.ts b/srv/adapter/chat-completion.ts
index a67a9d012..d91c3f669 100644
--- a/srv/adapter/chat-completion.ts
+++ b/srv/adapter/chat-completion.ts
@@ -378,7 +378,13 @@ async function getPostInstruction(
}
case 'continue':
- return { role: 'system', content: `${prefix}\n\nContinue ${opts.replyAs.name}'s response` }
+ const prompt = (opts.gen.continueMessagePrompt ?? '\n{{char}}:')
+ .replace(BOT_REPLACE, opts.replyAs.name)
+ .replace(SELF_REPLACE, opts.sender.handle)
+ return {
+ role: 'system',
+ content: `${prefix}${prompt}`,
+ }
case 'summary': {
let content = opts.user.images?.summaryPrompt || IMAGE_SUMMARY_PROMPT.openai
diff --git a/srv/adapter/claude.ts b/srv/adapter/claude.ts
index 54f8f6c2e..f7f38c84d 100644
--- a/srv/adapter/claude.ts
+++ b/srv/adapter/claude.ts
@@ -7,6 +7,7 @@ import { defaultPresets } from '../../common/presets'
import {
SAMPLE_CHAT_PREAMBLE,
BOT_REPLACE,
+ SELF_REPLACE,
injectPlaceholders,
ensureValidTemplate,
START_REPLACE,
@@ -283,7 +284,7 @@ async function createClaudePrompt(opts: AdapterProps) {
})
).parsed
- const prefill = opts.gen.prefill ? opts.gen.prefill + '\n' : ''
+ const prefill = opts.gen.prefill ? opts.gen.prefill : ''
const prefillCost = await encoder()(prefill)
const maxBudget =
@@ -347,21 +348,18 @@ async function createClaudePrompt(opts: AdapterProps) {
messages.push(ujb)
}
- const continueAddon =
- opts.kind === 'continue'
- ? `\n\nHuman: Continue ${replyAs.name}'s reply.`
- : ''
+ const continuePost = (opts.gen.continueMessagePrompt ?? '\n{{char}}:')
+ .replace(BOT_REPLACE, opts.replyAs.name)
+ .replace(SELF_REPLACE, opts.sender.handle)
+ // When rebasing before merging, ensure the changes from #750 are reflected here
const appendName = opts.gen.prefixNameAppend ?? true
+ const nonContinuePost = appendName ? `\n${replyAs.name}:` : ''
+
+ const post = opts.kind === 'continue' ? continuePost : nonContinuePost
+
//
- return (
- messages.join('\n\n') +
- continueAddon +
- '\n\n' +
- 'Assistant: ' +
- prefill +
- (appendName ? replyAs.name + ':' : '')
- )
+ return messages.join('\n\n') + '\n\n' + 'Assistant: ' + prefill + post
}
type LineType = 'system' | 'char' | 'user' | 'example'
diff --git a/web/shared/GenerationSettings.tsx b/web/shared/GenerationSettings.tsx
index c92df27e3..71a1b8d11 100644
--- a/web/shared/GenerationSettings.tsx
+++ b/web/shared/GenerationSettings.tsx
@@ -655,6 +655,19 @@ const PromptSettings: Component<
/>
+
+ Miscellaneous prompts
+ Prompt appended to input when using 'Generate More'>}
+ placeholder="
{{char}}:"
+ isMultiline
+ value={props.inherit?.continueMessagePrompt ?? '\n{{char}}:'}
+ disabled={props.disabled}
+ class="form-field focusable-field text-900 min-h-[8rem] w-full rounded-xl px-4 py-2 text-sm"
+ />
+