mirror of
https://github.com/open-webui/open-webui.git
synced 2025-12-24 10:15:22 +00:00
refac
Some checks failed
Deploy to HuggingFace Spaces / check-secret (push) Has been cancelled
Frontend Build / Frontend Unit Tests (push) Has been cancelled
Create and publish Docker images with specific build args / build-main-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-main-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda126-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda126-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-ollama-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-ollama-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-slim-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-slim-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Python CI / Format Backend (push) Has been cancelled
Frontend Build / Format & Build Frontend (push) Has been cancelled
Deploy to HuggingFace Spaces / deploy (push) Has been cancelled
Create and publish Docker images with specific build args / merge-main-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-cuda-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-cuda126-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-ollama-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-slim-images (push) Has been cancelled
Some checks failed
Deploy to HuggingFace Spaces / check-secret (push) Has been cancelled
Frontend Build / Frontend Unit Tests (push) Has been cancelled
Create and publish Docker images with specific build args / build-main-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-main-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda126-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-cuda126-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-ollama-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-ollama-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Create and publish Docker images with specific build args / build-slim-image (linux/amd64, ubuntu-latest) (push) Has been cancelled
Create and publish Docker images with specific build args / build-slim-image (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Python CI / Format Backend (push) Has been cancelled
Frontend Build / Format & Build Frontend (push) Has been cancelled
Deploy to HuggingFace Spaces / deploy (push) Has been cancelled
Create and publish Docker images with specific build args / merge-main-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-cuda-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-cuda126-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-ollama-images (push) Has been cancelled
Create and publish Docker images with specific build args / merge-slim-images (push) Has been cancelled
This commit is contained in:
parent
4c2e5c93e9
commit
fe653a1336
3 changed files with 160 additions and 164 deletions
|
|
@ -331,13 +331,21 @@ class Loader:
|
|||
elif self.engine == "mineru" and file_ext in [
|
||||
"pdf"
|
||||
]: # MinerU currently only supports PDF
|
||||
|
||||
mineru_timeout = self.kwargs.get("MINERU_API_TIMEOUT", 300)
|
||||
if mineru_timeout:
|
||||
try:
|
||||
mineru_timeout = int(mineru_timeout)
|
||||
except ValueError:
|
||||
mineru_timeout = 300
|
||||
|
||||
loader = MinerULoader(
|
||||
file_path=file_path,
|
||||
api_mode=self.kwargs.get("MINERU_API_MODE", "local"),
|
||||
api_url=self.kwargs.get("MINERU_API_URL", "http://localhost:8000"),
|
||||
api_key=self.kwargs.get("MINERU_API_KEY", ""),
|
||||
params=self.kwargs.get("MINERU_PARAMS", {}),
|
||||
timeout=int(self.kwargs.get("MINERU_API_TIMEOUT", 300)),
|
||||
timeout=mineru_timeout,
|
||||
)
|
||||
elif (
|
||||
self.engine == "mistral_ocr"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class MinerULoader:
|
|||
api_url: str = "http://localhost:8000",
|
||||
api_key: str = "",
|
||||
params: dict = None,
|
||||
timeout: int = 300,
|
||||
timeout: Optional[int] = 300,
|
||||
):
|
||||
self.file_path = file_path
|
||||
self.api_mode = api_mode.lower()
|
||||
|
|
@ -103,7 +103,7 @@ class MinerULoader:
|
|||
f"{self.api_url}/file_parse",
|
||||
data=form_data,
|
||||
files=files,
|
||||
timeout=self.timeout, # 5 minute timeout for large documents
|
||||
timeout=self.timeout,
|
||||
)
|
||||
response.raise_for_status()
|
||||
|
||||
|
|
@ -302,7 +302,7 @@ class MinerULoader:
|
|||
response = requests.put(
|
||||
upload_url,
|
||||
data=f,
|
||||
timeout=self.timeout, # 5 minute timeout for large files
|
||||
timeout=self.timeout,
|
||||
)
|
||||
response.raise_for_status()
|
||||
except FileNotFoundError:
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
<script lang="ts">
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
import { getContext, onMount, tick } from 'svelte';
|
||||
|
||||
import { formatFileSize, getLineCount } from '$lib/utils';
|
||||
import { WEBUI_API_BASE_URL } from '$lib/constants';
|
||||
import { getKnowledgeById } from '$lib/apis/knowledge';
|
||||
import * as XLSX from 'xlsx';
|
||||
import { getFileById } from '$lib/apis/files';
|
||||
|
||||
import CodeBlock from '$lib/components/chat/Messages/CodeBlock.svelte';
|
||||
import Markdown from '$lib/components/chat/Messages/Markdown.svelte';
|
||||
|
|
@ -17,7 +20,6 @@
|
|||
import Tooltip from './Tooltip.svelte';
|
||||
import dayjs from 'dayjs';
|
||||
import Spinner from './Spinner.svelte';
|
||||
import { getFileById } from '$lib/apis/files';
|
||||
|
||||
export let item;
|
||||
export let show = false;
|
||||
|
|
@ -130,7 +132,6 @@
|
|||
});
|
||||
};
|
||||
|
||||
|
||||
$: if (selectedSheet && excelWorkbook) {
|
||||
renderExcelSheet();
|
||||
}
|
||||
|
|
@ -348,175 +349,162 @@
|
|||
{(item?.file?.data?.content ?? '').trim() || 'No content'}
|
||||
</div>
|
||||
{/if}
|
||||
{:else if isExcel}
|
||||
<div
|
||||
class="flex mb-2.5 scrollbar-none overflow-x-auto w-full border-b border-gray-50 dark:border-gray-850/30 text-center text-sm font-medium bg-transparent dark:text-gray-200"
|
||||
>
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === ''
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = '';
|
||||
}}>{$i18n.t('Content')}</button
|
||||
>
|
||||
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === 'preview'
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = 'preview';
|
||||
}}>{$i18n.t('Preview')}</button
|
||||
>
|
||||
</div>
|
||||
|
||||
{#if selectedTab === 'preview'}
|
||||
{#if excelError}
|
||||
<div class="text-red-500 text-sm p-4">
|
||||
{excelError}
|
||||
</div>
|
||||
{:else}
|
||||
{#if excelSheetNames.length > 1}
|
||||
<div
|
||||
class="flex mb-2.5 scrollbar-none overflow-x-auto w-full border-b border-gray-50 dark:border-gray-850/30 text-center text-sm font-medium bg-transparent dark:text-gray-200"
|
||||
>
|
||||
{#each excelSheetNames as sheetName}
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedSheet === sheetName
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedSheet = sheetName;
|
||||
}}>{sheetName}</button
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if excelHtml}
|
||||
<div class="excel-table-container overflow-auto max-h-[60vh]">
|
||||
{@html excelHtml}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-gray-500 text-sm p-4">No content available</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{:else}
|
||||
{:else if isExcel}
|
||||
<div
|
||||
class="max-h-96 overflow-scroll scrollbar-hidden text-xs whitespace-pre-wrap"
|
||||
class="flex mb-2.5 scrollbar-none overflow-x-auto w-full border-b border-gray-50 dark:border-gray-850/30 text-center text-sm font-medium bg-transparent dark:text-gray-200"
|
||||
>
|
||||
{(item?.file?.data?.content ?? '').trim() || 'No content'}
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === ''
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = '';
|
||||
}}>{$i18n.t('Content')}</button
|
||||
>
|
||||
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === 'preview'
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = 'preview';
|
||||
}}>{$i18n.t('Preview')}</button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
{#if isAudio}
|
||||
<audio
|
||||
src={`${WEBUI_API_BASE_URL}/files/${item.id}/content`}
|
||||
class="w-full border-0 rounded-lg mb-2"
|
||||
controls
|
||||
playsinline
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if item?.file?.data}
|
||||
{#if isMarkdown}
|
||||
<div
|
||||
class="flex mb-2.5 scrollbar-none overflow-x-auto w-full border-b border-gray-50 dark:border-gray-850/30 text-center text-sm font-medium bg-transparent dark:text-gray-200"
|
||||
>
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === ''
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = '';
|
||||
}}>{$i18n.t('Content')}</button
|
||||
>
|
||||
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === 'preview'
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = 'preview';
|
||||
}}>{$i18n.t('Preview')}</button
|
||||
>
|
||||
</div>
|
||||
|
||||
{#if selectedTab === 'preview'}
|
||||
<div
|
||||
class="max-h-[60vh] overflow-scroll scrollbar-hidden text-sm prose dark:prose-invert max-w-full"
|
||||
>
|
||||
<Markdown
|
||||
content={item.file.data.content}
|
||||
id="markdown-viewer"
|
||||
/>
|
||||
{#if selectedTab === 'preview'}
|
||||
{#if excelError}
|
||||
<div class="text-red-500 text-sm p-4">
|
||||
{excelError}
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class="max-h-96 overflow-scroll scrollbar-hidden text-xs whitespace-pre-wrap"
|
||||
>
|
||||
{(item?.file?.data?.content ?? '').trim() || 'No content'}
|
||||
</div>
|
||||
{/if}
|
||||
{:else if isCode}
|
||||
<div
|
||||
class="flex mb-2.5 scrollbar-none overflow-x-auto w-full border-b border-gray-50 dark:border-gray-850/30 text-center text-sm font-medium bg-transparent dark:text-gray-200"
|
||||
>
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === ''
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = '';
|
||||
}}>{$i18n.t('Content')}</button
|
||||
>
|
||||
{#if excelSheetNames.length > 1}
|
||||
<div
|
||||
class="flex mb-2.5 scrollbar-none overflow-x-auto w-full border-b border-gray-50 dark:border-gray-850/30 text-center text-sm font-medium bg-transparent dark:text-gray-200"
|
||||
>
|
||||
{#each excelSheetNames as sheetName}
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedSheet === sheetName
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedSheet = sheetName;
|
||||
}}>{sheetName}</button
|
||||
>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === 'preview'
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = 'preview';
|
||||
}}>{$i18n.t('Preview')}</button
|
||||
>
|
||||
</div>
|
||||
|
||||
{#if selectedTab === 'preview'}
|
||||
<div
|
||||
class="max-h-[60vh] overflow-scroll scrollbar-hidden text-sm relative"
|
||||
>
|
||||
<CodeBlock
|
||||
code={item.file.data.content}
|
||||
lang={item.name.split('.').pop()}
|
||||
token={null}
|
||||
edit={false}
|
||||
run={false}
|
||||
save={false}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class="max-h-96 overflow-scroll scrollbar-hidden text-xs whitespace-pre-wrap"
|
||||
>
|
||||
{(item?.file?.data?.content ?? '').trim() || 'No content'}
|
||||
</div>
|
||||
{#if excelHtml}
|
||||
<div class="excel-table-container overflow-auto max-h-[60vh]">
|
||||
{@html excelHtml}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="text-gray-500 text-sm p-4">No content available</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{:else}
|
||||
<div
|
||||
class="max-h-96 overflow-scroll scrollbar-hidden text-xs whitespace-pre-wrap"
|
||||
>
|
||||
<div class="max-h-96 overflow-scroll scrollbar-hidden text-xs whitespace-pre-wrap">
|
||||
{(item?.file?.data?.content ?? '').trim() || 'No content'}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{:else}
|
||||
{#if isAudio}
|
||||
<audio
|
||||
src={`${WEBUI_API_BASE_URL}/files/${item.id}/content`}
|
||||
class="w-full border-0 rounded-lg mb-2"
|
||||
controls
|
||||
playsinline
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if item?.file?.data}
|
||||
{#if isMarkdown}
|
||||
<div
|
||||
class="flex mb-2.5 scrollbar-none overflow-x-auto w-full border-b border-gray-50 dark:border-gray-850/30 text-center text-sm font-medium bg-transparent dark:text-gray-200"
|
||||
>
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === ''
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = '';
|
||||
}}>{$i18n.t('Content')}</button
|
||||
>
|
||||
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === 'preview'
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = 'preview';
|
||||
}}>{$i18n.t('Preview')}</button
|
||||
>
|
||||
</div>
|
||||
|
||||
{#if selectedTab === 'preview'}
|
||||
<div
|
||||
class="max-h-[60vh] overflow-scroll scrollbar-hidden text-sm prose dark:prose-invert max-w-full"
|
||||
>
|
||||
<Markdown content={item.file.data.content} id="markdown-viewer" />
|
||||
</div>
|
||||
{:else}
|
||||
<div class="max-h-96 overflow-scroll scrollbar-hidden text-xs whitespace-pre-wrap">
|
||||
{(item?.file?.data?.content ?? '').trim() || 'No content'}
|
||||
</div>
|
||||
{/if}
|
||||
{:else if isCode}
|
||||
<div
|
||||
class="flex mb-2.5 scrollbar-none overflow-x-auto w-full border-b border-gray-50 dark:border-gray-850/30 text-center text-sm font-medium bg-transparent dark:text-gray-200"
|
||||
>
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === ''
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = '';
|
||||
}}>{$i18n.t('Content')}</button
|
||||
>
|
||||
|
||||
<button
|
||||
class="min-w-fit py-1.5 px-4 border-b {selectedTab === 'preview'
|
||||
? ' '
|
||||
: ' border-transparent text-gray-300 dark:text-gray-600 hover:text-gray-700 dark:hover:text-white'} transition"
|
||||
type="button"
|
||||
on:click={() => {
|
||||
selectedTab = 'preview';
|
||||
}}>{$i18n.t('Preview')}</button
|
||||
>
|
||||
</div>
|
||||
|
||||
{#if selectedTab === 'preview'}
|
||||
<div class="max-h-[60vh] overflow-scroll scrollbar-hidden text-sm relative">
|
||||
<CodeBlock
|
||||
code={item.file.data.content}
|
||||
lang={item.name.split('.').pop()}
|
||||
token={null}
|
||||
edit={false}
|
||||
run={false}
|
||||
save={false}
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="max-h-96 overflow-scroll scrollbar-hidden text-xs whitespace-pre-wrap">
|
||||
{(item?.file?.data?.content ?? '').trim() || 'No content'}
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="max-h-96 overflow-scroll scrollbar-hidden text-xs whitespace-pre-wrap">
|
||||
{(item?.file?.data?.content ?? '').trim() || 'No content'}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="flex items-center justify-center py-6">
|
||||
|
|
|
|||
Loading…
Reference in a new issue