mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
refac: inline citation handling
This commit is contained in:
parent
3468dda556
commit
d844fc7edb
@ -17,6 +17,7 @@
|
|||||||
import Collapsible from '$lib/components/common/Collapsible.svelte';
|
import Collapsible from '$lib/components/common/Collapsible.svelte';
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
|
import ArrowDownTray from '$lib/components/icons/ArrowDownTray.svelte';
|
||||||
|
import Source from './Source.svelte';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
@ -261,6 +262,8 @@
|
|||||||
{@html html}
|
{@html html}
|
||||||
{:else if token.text.includes(`<iframe src="${WEBUI_BASE_URL}/api/v1/files/`)}
|
{:else if token.text.includes(`<iframe src="${WEBUI_BASE_URL}/api/v1/files/`)}
|
||||||
{@html `${token.text}`}
|
{@html `${token.text}`}
|
||||||
|
{:else if token.text.includes(`<source_id`)}
|
||||||
|
<Source {id} {token} onClick={onSourceClick} />
|
||||||
{:else}
|
{:else}
|
||||||
{token.text}
|
{token.text}
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -26,43 +26,50 @@ function escapeRegExp(string: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const replaceTokens = (content, sourceIds, char, user) => {
|
export const replaceTokens = (content, sourceIds, char, user) => {
|
||||||
const charToken = /{{char}}/gi;
|
const tokens = [
|
||||||
const userToken = /{{user}}/gi;
|
{ regex: /{{char}}/gi, replacement: char },
|
||||||
const videoIdToken = /{{VIDEO_FILE_ID_([a-f0-9-]+)}}/gi; // Regex to capture the video ID
|
{ regex: /{{user}}/gi, replacement: user },
|
||||||
const htmlIdToken = /{{HTML_FILE_ID_([a-f0-9-]+)}}/gi; // Regex to capture the HTML ID
|
{
|
||||||
|
regex: /{{VIDEO_FILE_ID_([a-f0-9-]+)}}/gi,
|
||||||
|
replacement: (_, fileId) =>
|
||||||
|
`<video src="${WEBUI_BASE_URL}/api/v1/files/${fileId}/content" controls></video>`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
regex: /{{HTML_FILE_ID_([a-f0-9-]+)}}/gi,
|
||||||
|
replacement: (_, fileId) =>
|
||||||
|
`<iframe src="${WEBUI_BASE_URL}/api/v1/files/${fileId}/content/html" width="100%" frameborder="0" onload="this.style.height=(this.contentWindow.document.body.scrollHeight+20)+'px';"></iframe>`
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
// Replace {{char}} if char is provided
|
// Replace tokens outside code blocks only
|
||||||
if (char !== undefined && char !== null) {
|
const processOutsideCodeBlocks = (text, replacementFn) => {
|
||||||
content = content.replace(charToken, char);
|
return text
|
||||||
}
|
.split(/(```[\s\S]*?```|`[\s\S]*?`)/)
|
||||||
|
.map((segment) => {
|
||||||
|
return segment.startsWith('```') || segment.startsWith('`')
|
||||||
|
? segment
|
||||||
|
: replacementFn(segment);
|
||||||
|
})
|
||||||
|
.join('');
|
||||||
|
};
|
||||||
|
|
||||||
// Replace {{user}} if user is provided
|
// Apply replacements
|
||||||
if (user !== undefined && user !== null) {
|
content = processOutsideCodeBlocks(content, (segment) => {
|
||||||
content = content.replace(userToken, user);
|
tokens.forEach(({ regex, replacement }) => {
|
||||||
}
|
if (replacement !== undefined && replacement !== null) {
|
||||||
|
segment = segment.replace(regex, replacement);
|
||||||
// Replace video ID tags with corresponding <video> elements
|
}
|
||||||
content = content.replace(videoIdToken, (match, fileId) => {
|
|
||||||
const videoUrl = `${WEBUI_BASE_URL}/api/v1/files/${fileId}/content`;
|
|
||||||
return `<video src="${videoUrl}" controls></video>`;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Replace HTML ID tags with corresponding HTML content
|
|
||||||
content = content.replace(htmlIdToken, (match, fileId) => {
|
|
||||||
const htmlUrl = `${WEBUI_BASE_URL}/api/v1/files/${fileId}/content/html`;
|
|
||||||
return `<iframe src="${htmlUrl}" width="100%" frameborder="0" onload="this.style.height=(this.contentWindow.document.body.scrollHeight+20)+'px';"></iframe>`;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove sourceIds from the content and replace them with <source_id>...</source_id>
|
|
||||||
if (Array.isArray(sourceIds)) {
|
|
||||||
sourceIds.forEach((sourceId, idx) => {
|
|
||||||
// Create a token based on the exact `[sourceId]` string
|
|
||||||
const sourceToken = `\\[${idx}\\]`; // Escape special characters for RegExp
|
|
||||||
const sourceRegex = new RegExp(sourceToken, 'g'); // Match all occurrences of [sourceId]
|
|
||||||
|
|
||||||
content = content.replace(sourceRegex, `<source_id data="${idx}" title="${sourceId}" />`);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
if (Array.isArray(sourceIds)) {
|
||||||
|
sourceIds.forEach((sourceId, idx) => {
|
||||||
|
const regex = new RegExp(`\\[${idx}\\]`, 'g');
|
||||||
|
segment = segment.replace(regex, `<source_id data="${idx}" title="${sourceId}" />`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return segment;
|
||||||
|
});
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user