diff --git a/src/lib/components/chat/MessageInput/InputVariablesModal.svelte b/src/lib/components/chat/MessageInput/InputVariablesModal.svelte index d2410ad80..b50ed3839 100644 --- a/src/lib/components/chat/MessageInput/InputVariablesModal.svelte +++ b/src/lib/components/chat/MessageInput/InputVariablesModal.svelte @@ -21,6 +21,12 @@ let variableValues = {}; const submitHandler = async () => { + // Normalize Windows CRLF (\r\n) to LF (\n) for all string values + for (const key of Object.keys(variableValues)) { + if (typeof variableValues[key] === 'string') { + variableValues[key] = variableValues[key].replace(/\r\n/g, '\n'); + } + } onSave(variableValues); show = false; }; diff --git a/src/lib/components/common/RichTextInput.svelte b/src/lib/components/common/RichTextInput.svelte index 07bc4680e..b9dd05855 100644 --- a/src/lib/components/common/RichTextInput.svelte +++ b/src/lib/components/common/RichTextInput.svelte @@ -485,6 +485,17 @@ focus(); }; + // Convert text to ProseMirror nodes, using hardBreak for newlines + const textToNodes = (state, text) => { + if (!text.includes('\n')) return state.schema.text(text); + const nodes = []; + text.split('\n').forEach((line, i) => { + if (i > 0) nodes.push(state.schema.nodes.hardBreak.create()); + if (line) nodes.push(state.schema.text(line)); + }); + return nodes; + }; + export const replaceVariables = (variables) => { if (!editor || !editor.view) return; const { state, view } = editor; @@ -519,7 +530,7 @@ // Apply replacements in reverse order to maintain correct positions replacements.reverse().forEach(({ from, to, text }) => { - tr = tr.replaceWith(from, to, text !== '' ? state.schema.text(text) : []); + tr = tr.replaceWith(from, to, text !== '' ? textToNodes(state, text) : []); }); // Only dispatch if there are changes