mirror of
https://github.com/open-webui/open-webui
synced 2025-06-22 18:07:17 +00:00
Merge b4025a1ffc
into aef0ad2d10
This commit is contained in:
commit
51fb136845
@ -754,6 +754,7 @@
|
||||
bind:this={chatInputElement}
|
||||
bind:value={prompt}
|
||||
id="chat-input"
|
||||
preserveBreaks={true}
|
||||
messageInput={true}
|
||||
shiftEnter={!($settings?.ctrlEnterToSend ?? false) &&
|
||||
(!$mobile ||
|
||||
|
@ -22,9 +22,18 @@
|
||||
let selectedPromptIdx = 0;
|
||||
let filteredPrompts = [];
|
||||
|
||||
$: filteredPrompts = $prompts
|
||||
.filter((p) => p.command.toLowerCase().includes(command.toLowerCase()))
|
||||
$: {
|
||||
if (command && command.length > 0) {
|
||||
const commandName = command.substring(1).toLowerCase();
|
||||
const cleanedCommandName = commandName.replace(/<\/?p>/gi, '').trim();
|
||||
|
||||
filteredPrompts = $prompts
|
||||
.filter((p) => p.command.toLowerCase().includes(cleanedCommandName))
|
||||
.sort((a, b) => a.title.localeCompare(b.title));
|
||||
} else {
|
||||
filteredPrompts = [];
|
||||
}
|
||||
}
|
||||
|
||||
$: if (command) {
|
||||
selectedPromptIdx = 0;
|
||||
@ -120,23 +129,42 @@
|
||||
text = text.replaceAll('{{CURRENT_WEEKDAY}}', weekday);
|
||||
}
|
||||
|
||||
const lines = prompt.split('\n');
|
||||
const lastLine = lines.pop();
|
||||
|
||||
const lastLineWords = lastLine.split(' ');
|
||||
const lastWord = lastLineWords.pop();
|
||||
|
||||
if ($settings?.richTextInput ?? true) {
|
||||
lastLineWords.push(
|
||||
`${text.replace(/</g, '<').replace(/>/g, '>').replaceAll('\n', '<br/>')}`
|
||||
);
|
||||
const allPromptLines = prompt.split('\n');
|
||||
const lastLineWithTrigger = allPromptLines.pop() || ''; // Line where command was typed
|
||||
const wordsInLastLine = lastLineWithTrigger.split(' ');
|
||||
wordsInLastLine.pop(); // Remove the command trigger itself (e.g., /mycommand)
|
||||
|
||||
lines.push(lastLineWords.join(' '));
|
||||
prompt = lines.join('<br/>');
|
||||
let fullPromptPrefix = '';
|
||||
if (allPromptLines.length > 0) {
|
||||
fullPromptPrefix = allPromptLines.join('\n');
|
||||
}
|
||||
if (wordsInLastLine.length > 0) {
|
||||
if (fullPromptPrefix.length > 0) {
|
||||
fullPromptPrefix += '\n';
|
||||
}
|
||||
fullPromptPrefix += wordsInLastLine.join(' ');
|
||||
}
|
||||
fullPromptPrefix = fullPromptPrefix.trimEnd();
|
||||
|
||||
if (text && text.trim().length > 0) { // If 'text' (the command's content) is not empty
|
||||
if (fullPromptPrefix.length > 0) {
|
||||
prompt = fullPromptPrefix + '\n\n' + text;
|
||||
} else {
|
||||
lastLineWords.push(text);
|
||||
lines.push(lastLineWords.join(' '));
|
||||
prompt = lines.join('\n');
|
||||
prompt = text;
|
||||
}
|
||||
} else {
|
||||
prompt = fullPromptPrefix;
|
||||
}
|
||||
|
||||
} else {
|
||||
const currentInputLines = prompt.split('\n');
|
||||
const lastCurrentInputLine = currentInputLines.pop() || '';
|
||||
const lastCurrentInputLineWords = lastCurrentInputLine.split(' ');
|
||||
lastCurrentInputLineWords.pop();
|
||||
lastCurrentInputLineWords.push(command.content);
|
||||
currentInputLines.push(lastCurrentInputLineWords.join(' '));
|
||||
prompt = currentInputLines.join('\n');
|
||||
}
|
||||
|
||||
const chatInputContainerElement = document.getElementById('chat-input-container');
|
||||
|
@ -163,25 +163,34 @@
|
||||
}
|
||||
|
||||
if (!raw) {
|
||||
async function tryParse(value, attempts = 3, interval = 100) {
|
||||
async function tryParse(value, attempts = 3, interval = 100, useMarkdownBreaks = false) {
|
||||
try {
|
||||
// Normalize all types of newlines to \n
|
||||
const normalizedTextValue = (value || '').replace(/\r\n|\r/g, '\n');
|
||||
// Try parsing the value
|
||||
return marked.parse(value.replaceAll(`\n<br/>`, `<br/>`), {
|
||||
breaks: false
|
||||
return marked.parse(normalizedTextValue, {
|
||||
breaks: useMarkdownBreaks,
|
||||
gfm: true // Ensure GFM is active for paragraph handling
|
||||
});
|
||||
} catch (error) {
|
||||
// If no attempts remain, fallback to plain text
|
||||
if (attempts <= 1) {
|
||||
return value;
|
||||
return (value || '').replace(/\r\n|\r/g, '\n');
|
||||
}
|
||||
// Wait for the interval, then retry
|
||||
await new Promise((resolve) => setTimeout(resolve, interval));
|
||||
return tryParse(value, attempts - 1, interval); // Recursive call
|
||||
return tryParse(value, attempts - 1, interval, useMarkdownBreaks);
|
||||
}
|
||||
}
|
||||
|
||||
// Usage example
|
||||
content = await tryParse(value);
|
||||
content = await tryParse(value, 3, 100, preserveBreaks);
|
||||
|
||||
if (preserveBreaks && content) {
|
||||
// Ensure truly empty paragraphs generated by marked get an
|
||||
// so they are visually represented and can be saved back correctly.
|
||||
content = content.replace(/<p>(?: |<br\s*\/?>)?<\/p>/gi, '<p>​</p>');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (html && !content) {
|
||||
@ -244,9 +253,7 @@
|
||||
if (!raw) {
|
||||
let newValue = turndownService
|
||||
.turndown(
|
||||
editor
|
||||
.getHTML()
|
||||
.replace(/<p><\/p>/g, '<br/>')
|
||||
html
|
||||
.replace(/ {2,}/g, (m) => m.replace(/ /g, '\u00a0'))
|
||||
)
|
||||
.replace(/\u00a0/g, ' ');
|
||||
@ -438,14 +445,23 @@
|
||||
)
|
||||
.replace(/\u00a0/g, ' ')
|
||||
) {
|
||||
preserveBreaks
|
||||
? editor.commands.setContent(value)
|
||||
: editor.commands.setContent(
|
||||
marked.parse(value.replaceAll(`\n<br/>`, `<br/>`), {
|
||||
breaks: false
|
||||
})
|
||||
); // Update editor content
|
||||
|
||||
if (preserveBreaks) {
|
||||
const normalizedValue = (value || '').replace(/\r\n|\r/g, '\n');
|
||||
// Parse Markdown with breaks:true to convert \n to <br> for Tiptap
|
||||
let htmlToSet = marked.parse(normalizedValue, { breaks: true, gfm: true });
|
||||
if (htmlToSet) {
|
||||
// htmlToSet = htmlToSet.replace(/<p><\/p>/g, '<p> </p>'); // Old way
|
||||
htmlToSet = htmlToSet.replace(/<p>(?: |<br\s*\/?>)?<\/p>/gi, '<p>​</p>');
|
||||
}
|
||||
editor.commands.setContent(
|
||||
marked.parse(normalizedValue, { breaks: true, gfm: true })
|
||||
);
|
||||
} else {
|
||||
const normalizedValue = (value || '').replace(/\r\n|\r/g, '\n');
|
||||
editor.commands.setContent(
|
||||
marked.parse(normalizedValue, { breaks: false, gfm: true })
|
||||
);
|
||||
}
|
||||
selectTemplate();
|
||||
}
|
||||
}
|
||||
|
@ -156,6 +156,7 @@
|
||||
bind:value={content}
|
||||
rows={6}
|
||||
required
|
||||
preserveBreaks={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user