enh: follow up prompts behaviour

This commit is contained in:
Timothy Jaeryang Baek 2025-07-18 17:49:24 +04:00
parent 5e4e1cf662
commit c414f0c3ce
7 changed files with 86 additions and 2 deletions

View file

@ -2123,6 +2123,9 @@
bind:history
bind:autoScroll
bind:prompt
setInputText={(text) => {
messageInput?.setText(text);
}}
{selectedModels}
{atSelectedModel}
{sendPrompt}

View file

@ -36,6 +36,8 @@
let messages = [];
export let setInputText: Function = () => {};
export let sendPrompt: Function;
export let continueResponse: Function;
export let regenerateResponse: Function;
@ -426,6 +428,7 @@
messageId={message.id}
idx={messageIdx}
{user}
{setInputText}
{gotoMessage}
{showPreviousMessage}
{showNextMessage}

View file

@ -21,6 +21,7 @@
export let user;
export let setInputText: Function = () => {};
export let gotoMessage;
export let showPreviousMessage;
export let showNextMessage;
@ -74,6 +75,7 @@
{selectedModels}
isLastMessage={messageId === history.currentId}
siblings={history.messages[history.messages[messageId].parentId]?.childrenIds ?? []}
{setInputText}
{gotoMessage}
{showPreviousMessage}
{showNextMessage}
@ -96,6 +98,7 @@
{messageId}
{selectedModels}
isLastMessage={messageId === history?.currentId}
{setInputText}
{updateChat}
{editMessage}
{saveMessage}

View file

@ -28,6 +28,7 @@
export let isLastMessage;
export let readOnly = false;
export let setInputText: Function = () => {};
export let updateChat: Function;
export let editMessage: Function;
export let saveMessage: Function;
@ -259,6 +260,7 @@
gotoMessage={(message, messageIdx) => gotoMessage(modelIdx, messageIdx)}
showPreviousMessage={() => showPreviousMessage(modelIdx)}
showNextMessage={() => showNextMessage(modelIdx)}
{setInputText}
{updateChat}
{editMessage}
{saveMessage}

View file

@ -117,6 +117,7 @@
export let siblings;
export let setInputText: Function = () => {};
export let gotoMessage: Function = () => {};
export let showPreviousMessage: Function;
export let showNextMessage: Function;
@ -1464,12 +1465,18 @@
/>
{/if}
{#if isLastMessage && message.done && !readOnly && (message?.followUps ?? []).length > 0}
{#if (isLastMessage || ($settings?.keepFollowUpPrompts ?? false)) && message.done && !readOnly && (message?.followUps ?? []).length > 0}
<div class="mt-2.5" in:fade={{ duration: 100 }}>
<FollowUps
followUps={message?.followUps}
onClick={(prompt) => {
submitMessage(message?.id, prompt);
if ($settings?.insertFollowUpPrompt ?? false) {
// Insert the follow-up prompt into the input box
setInputText(prompt);
} else {
// Submit the follow-up prompt directly
submitMessage(message?.id, prompt);
}
}}
/>
</div>

View file

@ -43,6 +43,9 @@
let largeTextAsFile = false;
let keepFollowUpPrompts = false;
let insertFollowUpPrompt = false;
let landingPageMode = '';
let chatBubble = true;
let chatDirection: 'LTR' | 'RTL' | 'auto' = 'auto';
@ -230,6 +233,16 @@
saveSettings({ insertPromptAsRichText });
};
const toggleKeepFollowUpPrompts = async () => {
keepFollowUpPrompts = !keepFollowUpPrompts;
saveSettings({ keepFollowUpPrompts });
};
const toggleInsertFollowUpPrompt = async () => {
insertFollowUpPrompt = !insertFollowUpPrompt;
saveSettings({ insertFollowUpPrompt });
};
const toggleLargeTextAsFile = async () => {
largeTextAsFile = !largeTextAsFile;
saveSettings({ largeTextAsFile });
@ -325,6 +338,9 @@
insertPromptAsRichText = $settings?.insertPromptAsRichText ?? false;
promptAutocomplete = $settings?.promptAutocomplete ?? false;
keepFollowUpPrompts = $settings?.keepFollowUpPrompts ?? false;
insertFollowUpPrompt = $settings?.insertFollowUpPrompt ?? false;
largeTextAsFile = $settings?.largeTextAsFile ?? false;
copyFormatted = $settings?.copyFormatted ?? false;
@ -777,6 +793,52 @@
</div>
</div>
<div>
<div class=" py-0.5 flex w-full justify-between">
<div id="keep-followup-prompts-label" class=" self-center text-xs">
{$i18n.t('Keep Follow-Up Prompts in Chat')}
</div>
<button
aria-labelledby="keep-followup-prompts-label"
class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => {
toggleKeepFollowUpPrompts();
}}
type="button"
>
{#if keepFollowUpPrompts === true}
<span class="ml-2 self-center">{$i18n.t('On')}</span>
{:else}
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
{/if}
</button>
</div>
</div>
<div>
<div class=" py-0.5 flex w-full justify-between">
<div id="insert-followup-prompt-label" class=" self-center text-xs">
{$i18n.t('Insert Follow-Up Prompt to Input')}
</div>
<button
aria-labelledby="insert-followup-prompt-label"
class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => {
toggleInsertFollowUpPrompt();
}}
type="button"
>
{#if insertFollowUpPrompt === true}
<span class="ml-2 self-center">{$i18n.t('On')}</span>
{:else}
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
{/if}
</button>
</div>
</div>
<div>
<div class=" py-0.5 flex w-full justify-between">
<div id="rich-input-label" class=" self-center text-xs">

View file

@ -655,6 +655,10 @@
export const setText = (text: string) => {
if (!editor) return;
text = text.replaceAll('\n\n', '\n');
// reset the editor content
editor.commands.clearContent();
const { state, view } = editor;
const { schema, tr } = state;