diff --git a/frontend/src/components/ai-elements/prompt-input.tsx b/frontend/src/components/ai-elements/prompt-input.tsx index 682b804e..53491204 100644 --- a/frontend/src/components/ai-elements/prompt-input.tsx +++ b/frontend/src/components/ai-elements/prompt-input.tsx @@ -883,7 +883,32 @@ export const PromptInputTextarea = ({ if (!submitOnEnter) { return; } + if (e.shiftKey || e.ctrlKey || e.metaKey) { + // Keep newline behavior explicit for modified-Enter combos. + // This avoids accidental submit shortcuts swallowing Ctrl/Cmd+Enter. + if (e.ctrlKey || e.metaKey) { + e.preventDefault(); + const target = e.currentTarget; + const start = target.selectionStart ?? target.value.length; + const end = target.selectionEnd ?? target.value.length; + const nextValue = + target.value.slice(0, start) + "\n" + target.value.slice(end); + + if (controller) { + controller.textInput.setInput(nextValue); + } else { + target.value = nextValue; + const inputEvent = new Event("input", { bubbles: true }); + target.dispatchEvent(inputEvent); + } + + // Place caret right after the inserted newline. + requestAnimationFrame(() => { + target.selectionStart = start + 1; + target.selectionEnd = start + 1; + }); + } return; } e.preventDefault();