From 7aaa4a692e949724913834efc47c57572042703b Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 10 Sep 2026 19:05:36 -0400 Subject: [PATCH] refac Co-Authored-By: G30 <50341825+silentoplayz@users.noreply.github.com> --- src/app.css | 9 +++++++ src/lib/components/chat/MessageInput.svelte | 5 ++++ .../components/common/RichTextInput.svelte | 26 +++++++++++++++++-- .../common/RichTextInput/AutoCompletion.js | 8 +++++- 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/app.css b/src/app.css index 5c03d7cf27..fee41b409f 100644 --- a/src/app.css +++ b/src/app.css @@ -607,6 +607,15 @@ html.high-contrast.dark .ProseMirror p.is-editor-empty:first-child::before { } } +.ProseMirror p.is-editor-empty.ai-autocompletion:first-child::before { + content: attr(data-suggestion); + color: #a0a0a0; +} + +.ProseMirror p.is-editor-empty.ai-autocompletion:first-child::after { + content: none; +} + .ai-autocompletion::after { color: #a0a0a0; diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 4c72d45ef7..57c144fdb3 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -2029,6 +2029,11 @@ json={true} richText={$settings?.richTextInput ?? true} messageInput={true} + followUpSuggestion={!generating && + history?.messages?.[history?.currentId]?.role === 'assistant' && + history?.messages?.[history?.currentId]?.done + ? (history.messages[history.currentId].followUps?.[0] ?? '') + : ''} showFormattingToolbar={$settings?.showFormattingToolbar ?? false} floatingMenuPlacement={'top-start'} insertPromptAsRichText={$settings?.insertPromptAsRichText ?? false} diff --git a/src/lib/components/common/RichTextInput.svelte b/src/lib/components/common/RichTextInput.svelte index 61654914b2..d8f47dad9c 100644 --- a/src/lib/components/common/RichTextInput.svelte +++ b/src/lib/components/common/RichTextInput.svelte @@ -317,6 +317,28 @@ export let preserveBreaks = false; export let generateAutoCompletion: Function = async () => null; export let autocomplete = false; + export let followUpSuggestion = ''; + + $: if (editor && !editor.isDestroyed) { + const { doc } = editor.state; + const node = doc.firstChild; + if (node?.type.name === 'paragraph' && !node.attrs['data-prompt']) { + const suggestion = doc.childCount === 1 && node.content.size === 0 ? followUpSuggestion : ''; + if ((node.attrs['data-suggestion'] ?? '') !== suggestion) { + editor.view.dispatch( + editor.state.tr + .setNodeMarkup(0, null, { + ...node.attrs, + class: suggestion ? 'ai-autocompletion' : null, + 'data-prompt': suggestion ? '' : null, + 'data-suggestion': suggestion || null + }) + .setMeta('addToHistory', false) + ); + } + } + } + export let messageInput = false; export let shiftEnter = false; export let largeTextAsFile = false; @@ -844,11 +866,11 @@ }) ] : []), - ...(autocomplete + ...(autocomplete || messageInput ? [ AIAutocompletion.configure({ generateCompletion: async (text) => { - if (text.trim().length === 0) { + if (!autocomplete || text.trim().length === 0) { return null; } diff --git a/src/lib/components/common/RichTextInput/AutoCompletion.js b/src/lib/components/common/RichTextInput/AutoCompletion.js index d76a5ec021..89cff891ea 100644 --- a/src/lib/components/common/RichTextInput/AutoCompletion.js +++ b/src/lib/components/common/RichTextInput/AutoCompletion.js @@ -134,6 +134,8 @@ export const AIAutocompletion = Extension.create({ key: new PluginKey('aiAutocompletion'), props: { handleKeyDown: (view, event) => { + if (isComposing || event.isComposing || (event.key === 'Tab' && event.shiftKey)) + return false; const { state, dispatch } = view; const { selection } = state; const { $head } = selection; @@ -274,7 +276,11 @@ export const AIAutocompletion = Extension.create({ // Iterate over all nodes in the document const tr = state.tr; state.doc.descendants((node, pos) => { - if (node.type.name === 'paragraph' && node.attrs['data-suggestion']) { + if ( + node.type.name === 'paragraph' && + node.attrs['data-suggestion'] && + node.attrs['data-prompt'] + ) { // Remove suggestion from this paragraph tr.setNodeMarkup(pos, null, { ...node.attrs,