refac
This commit is contained in:
1 parent
b16a4c4e9a
commit
185bca8552
20 files changed
+693
-156
No files matched your search
@@ -283,31 +283,35 @@
|
||||
onPreview={previewHandler}
|
||||
/>
|
||||
{:else if $settings?.renderMarkdownInAssistantMessages ?? true}
|
||||
<Markdown
|
||||
{id}
|
||||
content={formatMessageContent(content)}
|
||||
{model}
|
||||
{save}
|
||||
{preview}
|
||||
{done}
|
||||
{editCodeBlock}
|
||||
{topPadding}
|
||||
{sourceIds}
|
||||
{onSourceClick}
|
||||
{onTaskClick}
|
||||
{onSave}
|
||||
onUpdate={markdownUpdateHandler}
|
||||
onPreview={previewHandler}
|
||||
/>
|
||||
<div class="markdown-prose">
|
||||
<Markdown
|
||||
{id}
|
||||
content={formatMessageContent(content)}
|
||||
{model}
|
||||
{save}
|
||||
{preview}
|
||||
{done}
|
||||
{editCodeBlock}
|
||||
{topPadding}
|
||||
{sourceIds}
|
||||
{onSourceClick}
|
||||
{onTaskClick}
|
||||
{onSave}
|
||||
onUpdate={markdownUpdateHandler}
|
||||
onPreview={previewHandler}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
{@const extracted = extractDetailsBlocks(content)}
|
||||
|
||||
{#if extracted.detailsContent}
|
||||
<!-- Render structural blocks (tool calls, reasoning, etc.) through Markdown -->
|
||||
<Markdown {id} content={extracted.detailsContent} {done} />
|
||||
<div class="markdown-prose">
|
||||
<Markdown {id} content={extracted.detailsContent} {done} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if extracted.plainContent}
|
||||
<div class="whitespace-pre-wrap">{extracted.plainContent}</div>
|
||||
<div class="whitespace-pre-wrap text-sm">{extracted.plainContent}</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -38,11 +38,11 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="my-2 flex w-full items-start gap-3 rounded-3xl bg-black/[0.03] px-4 py-3 text-gray-500 dark:bg-white/[0.04] dark:text-gray-400"
|
||||
class="my-1.5 flex w-full items-start gap-2 rounded-2xl bg-black/[0.03] px-3 py-2 text-gray-500 dark:bg-white/[0.04] dark:text-gray-400"
|
||||
>
|
||||
<Info className="mt-0.5 size-5 shrink-0 text-gray-400 dark:text-gray-500" strokeWidth="2" />
|
||||
<Info className="mt-0.5 size-4 shrink-0 text-gray-400 dark:text-gray-500" strokeWidth="1.8" />
|
||||
|
||||
<div class="min-w-0 break-words text-sm leading-6">
|
||||
<div class="min-w-0 break-words text-[0.8125rem] leading-5">
|
||||
{message}
|
||||
</div>
|
||||
</div>
|
||||
@@ -10,8 +10,7 @@
|
||||
import citationExtension from '$lib/utils/marked/citation-extension';
|
||||
|
||||
const options = {
|
||||
throwOnError: false,
|
||||
breaks: true
|
||||
throwOnError: false
|
||||
};
|
||||
|
||||
marked.use(markedKatexExtension(options));
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
<div {id} class="w-full">
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<button
|
||||
class="w-fit text-left text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 transition cursor-pointer"
|
||||
class="w-fit py-1 text-left text-sm text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 transition cursor-pointer"
|
||||
aria-label={$i18n.t('Toggle details')}
|
||||
aria-expanded={open}
|
||||
on:click={() => {
|
||||
@@ -158,7 +158,7 @@
|
||||
|
||||
{#if open}
|
||||
<div transition:slide={{ duration: 300, easing: quintOut, axis: 'y' }}>
|
||||
<div class="mb-0.5 space-y-0.5">
|
||||
<div class="mb-1 space-y-1.5">
|
||||
<slot name="content" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -98,6 +98,9 @@
|
||||
};
|
||||
|
||||
$: displayTokens = getDisplayTokens(tokens);
|
||||
$: singlePlainBlock =
|
||||
displayTokens.length === 1 &&
|
||||
(displayTokens[0]?.type === 'paragraph' || displayTokens[0]?.type === 'text');
|
||||
|
||||
const exportTableToCSVHandler = (token, tokenIdx = 0) => {
|
||||
console.log('Exporting table to CSV');
|
||||
@@ -141,7 +144,7 @@
|
||||
<!-- {JSON.stringify(tokens)} -->
|
||||
{#each displayTokens as token, tokenIdx (tokenIdx)}
|
||||
{#if token.type === 'hr'}
|
||||
<hr class=" border-gray-100/30 dark:border-gray-850/30" />
|
||||
<hr class="border-gray-50 dark:border-gray-850/30" />
|
||||
{:else if token.type === 'heading'}
|
||||
<svelte:element this={headerComponent(token.depth)} dir="auto">
|
||||
<MarkdownInlineTokens
|
||||
@@ -385,7 +388,7 @@
|
||||
resultContent={getDetailTextContent(detailToken)}
|
||||
grouped={true}
|
||||
open={$settings?.expandDetails ?? false}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
/>
|
||||
{:else if textContent.length > 0}
|
||||
<Collapsible
|
||||
@@ -393,7 +396,7 @@
|
||||
open={$settings?.expandDetails ?? false}
|
||||
attributes={detailToken?.attributes}
|
||||
messageDone={done}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
dir="auto"
|
||||
>
|
||||
<div class="mb-1.5" slot="content">
|
||||
@@ -416,7 +419,7 @@
|
||||
disabled={true}
|
||||
attributes={detailToken?.attributes}
|
||||
messageDone={done}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
dir="auto"
|
||||
/>
|
||||
{/if}
|
||||
@@ -433,7 +436,7 @@
|
||||
attributes={token.attributes}
|
||||
resultContent={getDetailTextContent(token)}
|
||||
open={$settings?.expandDetails ?? false}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
/>
|
||||
{:else if textContent.length > 0}
|
||||
<Collapsible
|
||||
@@ -441,7 +444,7 @@
|
||||
open={$settings?.expandDetails ?? false}
|
||||
attributes={token?.attributes}
|
||||
messageDone={done}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
dir="auto"
|
||||
>
|
||||
<div class=" mb-1.5" slot="content">
|
||||
@@ -464,7 +467,7 @@
|
||||
disabled={true}
|
||||
attributes={token?.attributes}
|
||||
messageDone={done}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
dir="auto"
|
||||
/>
|
||||
{/if}
|
||||
@@ -495,7 +498,7 @@
|
||||
/>
|
||||
</span>
|
||||
{:else}
|
||||
<p dir="auto">
|
||||
<p dir="auto" class={singlePlainBlock ? '!my-0' : ''}>
|
||||
<MarkdownInlineTokens
|
||||
id={`${id}-${tokenIdx}-p`}
|
||||
tokens={token.tokens ?? []}
|
||||
@@ -507,7 +510,7 @@
|
||||
{/if}
|
||||
{:else if token.type === 'text'}
|
||||
{#if top}
|
||||
<p>
|
||||
<p class={singlePlainBlock ? '!my-0' : ''}>
|
||||
{#if token.tokens}
|
||||
<MarkdownInlineTokens
|
||||
id={`${id}-${tokenIdx}-t`}
|
||||
@@ -551,7 +554,7 @@
|
||||
{onSourceClick}
|
||||
/>
|
||||
{:else if token.type === 'space'}
|
||||
<div class="my-2" />
|
||||
<!-- skip -->
|
||||
{:else}
|
||||
{console.log('Unknown token', token)}
|
||||
{/if}
|
||||
|
||||
@@ -405,11 +405,13 @@
|
||||
{$i18n.t('Merged Response')}
|
||||
</Name>
|
||||
|
||||
<div class="mt-1 markdown-prose w-full min-w-full">
|
||||
<div class="mt-1 w-full min-w-full">
|
||||
{#if (message?.content ?? '') === ''}
|
||||
<Skeleton />
|
||||
{:else}
|
||||
<Markdown id={`merged`} content={message.content ?? ''} />
|
||||
<div class="markdown-prose">
|
||||
<Markdown id={`merged`} content={message.content ?? ''} />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class=" self-center font-normal line-clamp-1 flex gap-1 items-center">
|
||||
<div class=" self-center text-sm font-normal line-clamp-1 flex gap-1 items-center">
|
||||
<slot />
|
||||
</div>
|
||||
@@ -655,10 +655,10 @@
|
||||
dir={$settings.chatDirection}
|
||||
style="scroll-margin-top: 3rem;"
|
||||
>
|
||||
<div class={`shrink-0 ltr:mr-3 rtl:ml-3 hidden @lg:flex mt-1 `}>
|
||||
<div class={`shrink-0 ltr:mr-2 rtl:ml-2 hidden @lg:flex mt-0.5 `}>
|
||||
<ProfileImage
|
||||
src={`${WEBUI_API_BASE_URL}/models/model/profile/image?id=${model?.id}&lang=${$i18n.language}`}
|
||||
className={'size-8 assistant-message-profile-image'}
|
||||
className={'size-7 assistant-message-profile-image'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -672,7 +672,7 @@
|
||||
</Name>
|
||||
|
||||
<div>
|
||||
<div class="chat-{message.role} w-full min-w-full markdown-prose">
|
||||
<div class="chat-{message.role} w-full min-w-full">
|
||||
<div>
|
||||
{#if model?.info?.meta?.capabilities?.status_updates ?? true}
|
||||
<StatusHistory statusHistory={message?.statusHistory} />
|
||||
|
||||
@@ -38,24 +38,26 @@
|
||||
{#each displayItems as displayItem (displayItem.id)}
|
||||
{#if displayItem.type === 'message'}
|
||||
{#if renderMarkdown}
|
||||
<Markdown
|
||||
id={`${id}-${displayItem.id}`}
|
||||
content={formatMessageContent(displayItem.text)}
|
||||
{model}
|
||||
{save}
|
||||
{preview}
|
||||
{done}
|
||||
{editCodeBlock}
|
||||
{topPadding}
|
||||
{sourceIds}
|
||||
{onSourceClick}
|
||||
{onTaskClick}
|
||||
{onSave}
|
||||
{onUpdate}
|
||||
{onPreview}
|
||||
/>
|
||||
<div class="markdown-prose">
|
||||
<Markdown
|
||||
id={`${id}-${displayItem.id}`}
|
||||
content={formatMessageContent(displayItem.text)}
|
||||
{model}
|
||||
{save}
|
||||
{preview}
|
||||
{done}
|
||||
{editCodeBlock}
|
||||
{topPadding}
|
||||
{sourceIds}
|
||||
{onSourceClick}
|
||||
{onTaskClick}
|
||||
{onSave}
|
||||
{onUpdate}
|
||||
{onPreview}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="whitespace-pre-wrap">{displayItem.text}</div>
|
||||
<div class="whitespace-pre-wrap text-sm">{displayItem.text}</div>
|
||||
{/if}
|
||||
{:else if displayItem.type === 'detail_group'}
|
||||
<ConsecutiveDetailsGroup
|
||||
@@ -63,7 +65,7 @@
|
||||
tokens={displayItem.tokens}
|
||||
messageDone={done}
|
||||
>
|
||||
<div slot="content" class="space-y-1">
|
||||
<div slot="content" class="space-y-2">
|
||||
{#each displayItem.tokens as detailToken, detailIndex}
|
||||
{#if detailToken.attributes?.type === 'tool_calls'}
|
||||
<ToolCallDisplay
|
||||
@@ -72,7 +74,7 @@
|
||||
resultContent={detailToken.text}
|
||||
grouped={true}
|
||||
open={$settings?.expandDetails ?? false}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
/>
|
||||
{:else if detailToken.text?.length > 0}
|
||||
<Collapsible
|
||||
@@ -80,15 +82,17 @@
|
||||
open={$settings?.expandDetails ?? false}
|
||||
attributes={getDetailAttributes(detailToken)}
|
||||
messageDone={done}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
>
|
||||
<div class="mb-1.5" slot="content">
|
||||
<Markdown
|
||||
id={`${id}-${displayItem.id}-${detailIndex}-detail`}
|
||||
content={detailToken.text}
|
||||
{done}
|
||||
{editCodeBlock}
|
||||
/>
|
||||
<div class="markdown-prose">
|
||||
<Markdown
|
||||
id={`${id}-${displayItem.id}-${detailIndex}-detail`}
|
||||
content={detailToken.text}
|
||||
{done}
|
||||
{editCodeBlock}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Collapsible>
|
||||
{:else}
|
||||
@@ -98,7 +102,7 @@
|
||||
disabled={true}
|
||||
attributes={getDetailAttributes(detailToken)}
|
||||
messageDone={done}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
/>
|
||||
{/if}
|
||||
{/each}
|
||||
@@ -112,7 +116,7 @@
|
||||
attributes={detailToken.attributes}
|
||||
resultContent={detailToken.text}
|
||||
open={$settings?.expandDetails ?? false}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
/>
|
||||
{:else if detailToken.text?.length > 0}
|
||||
<Collapsible
|
||||
@@ -120,15 +124,17 @@
|
||||
open={$settings?.expandDetails ?? false}
|
||||
attributes={getDetailAttributes(detailToken)}
|
||||
messageDone={done}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
>
|
||||
<div class="mb-1.5" slot="content">
|
||||
<Markdown
|
||||
id={`${id}-${displayItem.id}-detail`}
|
||||
content={detailToken.text}
|
||||
{done}
|
||||
{editCodeBlock}
|
||||
/>
|
||||
<div class="markdown-prose">
|
||||
<Markdown
|
||||
id={`${id}-${displayItem.id}-detail`}
|
||||
content={detailToken.text}
|
||||
{done}
|
||||
{editCodeBlock}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Collapsible>
|
||||
{:else}
|
||||
@@ -138,7 +144,7 @@
|
||||
disabled={true}
|
||||
attributes={getDetailAttributes(detailToken)}
|
||||
messageDone={done}
|
||||
className="w-full space-y-1"
|
||||
className="w-full space-y-2"
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -144,12 +144,12 @@
|
||||
style="scroll-margin-top: 3rem;"
|
||||
>
|
||||
{#if !($settings?.chatBubble ?? true) && !subagentResult}
|
||||
<div class={`shrink-0 ltr:mr-3 rtl:ml-3 mt-1`}>
|
||||
<div class={`shrink-0 ltr:mr-2 rtl:ml-2 mt-0.5`}>
|
||||
<ProfileImage
|
||||
src={user?.id
|
||||
? `${WEBUI_API_BASE_URL}/users/${user.id}/profile/image`
|
||||
: `${WEBUI_BASE_URL}/static/favicon.png`}
|
||||
className={'size-8 user-message-profile-image'}
|
||||
className={'size-7 user-message-profile-image'}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -169,7 +169,7 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="chat-{message.role} w-full min-w-full markdown-prose">
|
||||
<div class="chat-{message.role} w-full min-w-full">
|
||||
{#if edit !== true}
|
||||
{#if message.files}
|
||||
<div
|
||||
@@ -271,7 +271,7 @@
|
||||
<textarea
|
||||
id="message-edit-{message.id}"
|
||||
bind:this={messageEditTextAreaElement}
|
||||
class=" bg-transparent outline-hidden w-full resize-none"
|
||||
class=" bg-transparent outline-hidden w-full resize-none text-sm"
|
||||
bind:value={editedContent}
|
||||
on:input={(e) => {
|
||||
const messagesContainer = document.getElementById('messages-container');
|
||||
@@ -349,14 +349,16 @@
|
||||
>
|
||||
{#if message.content}
|
||||
{#if $settings?.renderMarkdownInUserMessages ?? true}
|
||||
<Markdown
|
||||
id={`${chatId}-${message.id}`}
|
||||
content={message.content}
|
||||
{editCodeBlock}
|
||||
{topPadding}
|
||||
/>
|
||||
<div class="markdown-prose">
|
||||
<Markdown
|
||||
id={`${chatId}-${message.id}`}
|
||||
content={message.content}
|
||||
{editCodeBlock}
|
||||
{topPadding}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="whitespace-pre-wrap" dir={$settings?.chatDirection ?? 'auto'}>
|
||||
<div class="whitespace-pre-wrap text-sm" dir={$settings?.chatDirection ?? 'auto'}>
|
||||
{message.content}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in new issue
Block a user