Merge branch 'upstream-dev' into dev

This commit is contained in:
Jannik Streidl
2024-10-12 15:18:59 +02:00
103 changed files with 2956 additions and 3023 deletions

View File

@@ -167,6 +167,44 @@ export const getAllChats = async (token: string) => {
return res;
};
export const getChatListBySearchText = async (token: string, text: string, page: number = 1) => {
let error = null;
const searchParams = new URLSearchParams();
searchParams.append('text', text);
searchParams.append('page', `${page}`);
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/search?${searchParams.toString()}`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(token && { authorization: `Bearer ${token}` })
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res.map((chat) => ({
...chat,
time_range: getTimeRange(chat.updated_at)
}));
};
export const getAllArchivedChats = async (token: string) => {
let error = null;
@@ -232,7 +270,7 @@ export const getAllUserChats = async (token: string) => {
export const getAllChatTags = async (token: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/tags/all`, {
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/all/tags`, {
method: 'GET',
headers: {
Accept: 'application/json',
@@ -260,6 +298,40 @@ export const getAllChatTags = async (token: string) => {
return res;
};
export const getPinnedChatList = async (token: string = '') => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/pinned`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(token && { authorization: `Bearer ${token}` })
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res.map((chat) => ({
...chat,
time_range: getTimeRange(chat.updated_at)
}));
};
export const getChatListByTagName = async (token: string = '', tagName: string) => {
let error = null;
@@ -361,11 +433,87 @@ export const getChatByShareId = async (token: string, share_id: string) => {
return res;
};
export const getChatPinnedStatusById = async (token: string, id: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/pinned`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(token && { authorization: `Bearer ${token}` })
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err;
if ('detail' in err) {
error = err.detail;
} else {
error = err;
}
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const toggleChatPinnedStatusById = async (token: string, id: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/pin`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(token && { authorization: `Bearer ${token}` })
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err;
if ('detail' in err) {
error = err.detail;
} else {
error = err;
}
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const cloneChatById = async (token: string, id: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/clone`, {
method: 'GET',
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
@@ -435,7 +583,7 @@ export const archiveChatById = async (token: string, id: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/${id}/archive`, {
method: 'GET',
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
@@ -605,8 +753,7 @@ export const addTagById = async (token: string, id: string, tagName: string) =>
...(token && { authorization: `Bearer ${token}` })
},
body: JSON.stringify({
tag_name: tagName,
chat_id: id
name: tagName
})
})
.then(async (res) => {
@@ -641,8 +788,7 @@ export const deleteTagById = async (token: string, id: string, tagName: string)
...(token && { authorization: `Bearer ${token}` })
},
body: JSON.stringify({
tag_name: tagName,
chat_id: id
name: tagName
})
})
.then(async (res) => {

View File

@@ -1,232 +0,0 @@
import { WEBUI_API_BASE_URL } from '$lib/constants';
export const createNewDoc = async (
token: string,
collection_name: string,
filename: string,
name: string,
title: string,
content: object | null = null
) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/documents/create`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
},
body: JSON.stringify({
collection_name: collection_name,
filename: filename,
name: name,
title: title,
...(content ? { content: JSON.stringify(content) } : {})
})
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const getDocs = async (token: string = '') => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/documents/`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const getDocByName = async (token: string, name: string) => {
let error = null;
const searchParams = new URLSearchParams();
searchParams.append('name', name);
const res = await fetch(`${WEBUI_API_BASE_URL}/documents/docs?${searchParams.toString()}`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
type DocUpdateForm = {
name: string;
title: string;
};
export const updateDocByName = async (token: string, name: string, form: DocUpdateForm) => {
let error = null;
const searchParams = new URLSearchParams();
searchParams.append('name', name);
const res = await fetch(`${WEBUI_API_BASE_URL}/documents/doc/update?${searchParams.toString()}`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
},
body: JSON.stringify({
name: form.name,
title: form.title
})
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
type TagDocForm = {
name: string;
tags: string[];
};
export const tagDocByName = async (token: string, name: string, form: TagDocForm) => {
let error = null;
const searchParams = new URLSearchParams();
searchParams.append('name', name);
const res = await fetch(`${WEBUI_API_BASE_URL}/documents/doc/tags?${searchParams.toString()}`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
},
body: JSON.stringify({
name: form.name,
tags: form.tags
})
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const deleteDocByName = async (token: string, name: string) => {
let error = null;
const searchParams = new URLSearchParams();
searchParams.append('name', name);
const res = await fetch(`${WEBUI_API_BASE_URL}/documents/doc/delete?${searchParams.toString()}`, {
method: 'DELETE',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: `Bearer ${token}`
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err.detail;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};

View File

@@ -200,13 +200,13 @@ export const getEmbeddingConfig = async (token: string) => {
type OpenAIConfigForm = {
key: string;
url: string;
batch_size: number;
};
type EmbeddingModelUpdateForm = {
openai_config?: OpenAIConfigForm;
embedding_engine: string;
embedding_model: string;
embedding_batch_size?: number;
};
export const updateEmbeddingConfig = async (token: string, payload: EmbeddingModelUpdateForm) => {

View File

@@ -2,20 +2,27 @@
import { getContext } from 'svelte';
export let title = '';
export let content = '';
const i18n = getContext('i18n');
</script>
<div class=" text-center text-6xl mb-3">📄</div>
<div class="text-center dark:text-white text-2xl font-semibold z-50">
{#if title}
{title}
{:else}
{$i18n.t('Add Files')}
{/if}
</div>
<slot
><div class=" mt-2 text-center text-sm dark:text-gray-200 w-full">
{$i18n.t('Drop any files here to add to the conversation')}
<div class="px-3">
<div class="text-center text-6xl mb-3">📄</div>
<div class="text-center dark:text-white text-xl font-semibold z-50">
{#if title}
{title}
{:else}
{$i18n.t('Add Files')}
{/if}
</div>
</slot>
<slot
><div class="px-2 mt-2 text-center text-sm dark:text-gray-200 w-full">
{#if content}
{content}
{:else}
{$i18n.t('Drop any files here to add to the conversation')}
{/if}
</div>
</slot>
</div>

View File

@@ -38,6 +38,7 @@
let embeddingEngine = '';
let embeddingModel = '';
let embeddingBatchSize = 1;
let rerankingModel = '';
let fileMaxSize = null;
@@ -53,7 +54,6 @@
let OpenAIKey = '';
let OpenAIUrl = '';
let OpenAIBatchSize = 1;
let querySettings = {
template: '',
@@ -100,12 +100,16 @@
const res = await updateEmbeddingConfig(localStorage.token, {
embedding_engine: embeddingEngine,
embedding_model: embeddingModel,
...(embeddingEngine === 'openai' || embeddingEngine === 'ollama'
? {
embedding_batch_size: embeddingBatchSize
}
: {}),
...(embeddingEngine === 'openai'
? {
openai_config: {
key: OpenAIKey,
url: OpenAIUrl,
batch_size: OpenAIBatchSize
url: OpenAIUrl
}
}
: {})
@@ -193,10 +197,10 @@
if (embeddingConfig) {
embeddingEngine = embeddingConfig.embedding_engine;
embeddingModel = embeddingConfig.embedding_model;
embeddingBatchSize = embeddingConfig.embedding_batch_size ?? 1;
OpenAIKey = embeddingConfig.openai_config.key;
OpenAIUrl = embeddingConfig.openai_config.url;
OpenAIBatchSize = embeddingConfig.openai_config.batch_size ?? 1;
}
};
@@ -309,6 +313,8 @@
<SensitiveInput placeholder={$i18n.t('API Key')} bind:value={OpenAIKey} />
</div>
{/if}
{#if embeddingEngine === 'ollama' || embeddingEngine === 'openai'}
<div class="flex mt-0.5 space-x-2">
<div class=" self-center text-xs font-medium">{$i18n.t('Embedding Batch Size')}</div>
<div class=" flex-1">
@@ -318,13 +324,13 @@
min="1"
max="2048"
step="1"
bind:value={OpenAIBatchSize}
bind:value={embeddingBatchSize}
class="w-full h-2 rounded-lg appearance-none cursor-pointer dark:bg-gray-700"
/>
</div>
<div class="">
<input
bind:value={OpenAIBatchSize}
bind:value={embeddingBatchSize}
type="number"
class=" bg-transparent text-center w-14"
min="-2"

View File

@@ -10,6 +10,7 @@
import ArrowsPointingOut from '../icons/ArrowsPointingOut.svelte';
import Tooltip from '../common/Tooltip.svelte';
import SvgPanZoom from '../common/SVGPanZoom.svelte';
import ArrowLeft from '../icons/ArrowLeft.svelte';
export let overlay = false;
export let history;
@@ -183,6 +184,17 @@
<div class=" absolute top-0 left-0 right-0 bottom-0 z-10"></div>
{/if}
<div class="absolute pointer-events-none z-50 w-full flex items-center justify-start p-4">
<button
class="self-center pointer-events-auto p-1 rounded-full bg-white dark:bg-gray-850"
on:click={() => {
showArtifacts.set(false);
}}
>
<ArrowLeft className="size-3.5 text-gray-900 dark:text-white" />
</button>
</div>
<div class=" absolute pointer-events-none z-50 w-full flex items-center justify-end p-4">
<button
class="self-center pointer-events-auto p-1 rounded-full bg-white dark:bg-gray-850"
@@ -192,7 +204,7 @@
showArtifacts.set(false);
}}
>
<XMark className="size-3 text-gray-900 dark:text-white" />
<XMark className="size-3.5 text-gray-900 dark:text-white" />
</button>
</div>

View File

@@ -53,7 +53,7 @@
updateChatById
} from '$lib/apis/chats';
import { generateOpenAIChatCompletion } from '$lib/apis/openai';
import { processWebSearch } from '$lib/apis/retrieval';
import { processWeb, processWebSearch, processYoutubeVideo } from '$lib/apis/retrieval';
import { createOpenAITextStream } from '$lib/apis/streaming';
import { queryMemory } from '$lib/apis/memories';
import { getAndUpdateUserLocation, getUserSettings } from '$lib/apis/users';
@@ -78,6 +78,7 @@
let loaded = false;
const eventTarget = new EventTarget();
let controlPane;
let controlPaneComponent;
let stopResponseFlag = false;
let autoScroll = true;
@@ -199,6 +200,20 @@
eventConfirmationTitle = data.title;
eventConfirmationMessage = data.message;
} else if (type === 'execute') {
eventCallback = cb;
try {
// Use Function constructor to evaluate code in a safer way
const asyncFunction = new Function(`return (async () => { ${data.code} })()`);
const result = await asyncFunction(); // Await the result of the async function
if (cb) {
cb(result);
}
} catch (error) {
console.error('Error executing code:', error);
}
} else if (type === 'input') {
eventCallback = cb;
@@ -276,14 +291,9 @@
if (controlPane && !$mobile) {
try {
if (value) {
const currentSize = controlPane.getSize();
if (currentSize === 0) {
const size = parseInt(localStorage?.chatControlsSize ?? '30');
controlPane.resize(size ? size : 30);
}
controlPaneComponent.openPane();
} else {
controlPane.resize(0);
controlPane.collapse();
}
} catch (e) {
// ignore
@@ -293,6 +303,7 @@
if (!value) {
showCallOverlay.set(false);
showOverview.set(false);
showArtifacts.set(false);
}
});
@@ -308,6 +319,74 @@
$socket?.off('chat-events');
});
// File upload functions
const uploadWeb = async (url) => {
console.log(url);
const fileItem = {
type: 'doc',
name: url,
collection_name: '',
status: 'uploading',
url: url,
error: ''
};
try {
files = [...files, fileItem];
const res = await processWeb(localStorage.token, '', url);
if (res) {
fileItem.status = 'uploaded';
fileItem.collection_name = res.collection_name;
fileItem.file = {
...res.file,
...fileItem.file
};
files = files;
}
} catch (e) {
// Remove the failed doc from the files array
files = files.filter((f) => f.name !== url);
toast.error(JSON.stringify(e));
}
};
const uploadYoutubeTranscription = async (url) => {
console.log(url);
const fileItem = {
type: 'doc',
name: url,
collection_name: '',
status: 'uploading',
context: 'full',
url: url,
error: ''
};
try {
files = [...files, fileItem];
const res = await processYoutubeVideo(localStorage.token, url);
if (res) {
fileItem.status = 'uploaded';
fileItem.collection_name = res.collection_name;
fileItem.file = {
...res.file,
...fileItem.file
};
files = files;
}
} catch (e) {
// Remove the failed doc from the files array
files = files.filter((f) => f.name !== url);
toast.error(e);
}
};
//////////////////////////
// Web functions
//////////////////////////
@@ -345,7 +424,17 @@
console.log($config?.default_models.split(',') ?? '');
selectedModels = $config?.default_models.split(',');
} else {
selectedModels = [''];
if ($models.length > 0) {
selectedModels = [$models[0].id];
} else {
selectedModels = [''];
}
}
if ($page.url.searchParams.get('youtube')) {
uploadYoutubeTranscription(
`https://www.youtube.com/watch?v=${$page.url.searchParams.get('youtube')}`
);
}
if ($page.url.searchParams.get('web-search') === 'true') {
@@ -366,6 +455,11 @@
.filter((id) => id);
}
if ($page.url.searchParams.get('call') === 'true') {
showCallOverlay.set(true);
showControls.set(true);
}
if ($page.url.searchParams.get('q')) {
prompt = $page.url.searchParams.get('q') ?? '';
@@ -375,11 +469,6 @@
}
}
if ($page.url.searchParams.get('call') === 'true') {
showCallOverlay.set(true);
showControls.set(true);
}
selectedModels = selectedModels.map((modelId) =>
$models.map((m) => m.id).includes(modelId) ? modelId : ''
);
@@ -1855,6 +1944,7 @@
system: $settings.system ?? undefined,
params: params,
history: history,
messages: createMessagesList(history.currentId),
tags: [],
timestamp: Date.now()
});
@@ -1920,6 +2010,7 @@
class="h-screen max-h-[100dvh] {$showSidebar
? 'md:max-w-[calc(100%-260px)]'
: ''} w-full max-w-full flex flex-col"
id="chat-container"
>
{#if $settings?.backgroundImageUrl ?? null}
<div
@@ -1935,7 +2026,17 @@
{/if}
<Navbar
{chat}
chat={{
id: $chatId,
chat: {
title: $chatTitle,
models: selectedModels,
system: $settings.system ?? undefined,
params: params,
history: history,
timestamp: Date.now()
}
}}
title={$chatTitle}
bind:selectedModels
shareEnabled={!!history.currentId}
@@ -2050,6 +2151,15 @@
transparentBackground={$settings?.backgroundImageUrl ?? false}
{stopResponse}
{createMessagePair}
on:upload={async (e) => {
const { type, data } = e.detail;
if (type === 'web') {
await uploadWeb(data);
} else if (type === 'youtube') {
await uploadYoutubeTranscription(data);
}
}}
on:submit={async (e) => {
if (e.detail) {
prompt = '';
@@ -2066,38 +2176,50 @@
</div>
</div>
{:else}
<Placeholder
{history}
{selectedModels}
bind:files
bind:prompt
bind:autoScroll
bind:selectedToolIds
bind:webSearchEnabled
bind:atSelectedModel
availableToolIds={selectedModelIds.reduce((a, e, i, arr) => {
const model = $models.find((m) => m.id === e);
if (model?.info?.meta?.toolIds ?? false) {
return [...new Set([...a, ...model.info.meta.toolIds])];
}
return a;
}, [])}
transparentBackground={$settings?.backgroundImageUrl ?? false}
{stopResponse}
{createMessagePair}
on:submit={async (e) => {
if (e.detail) {
prompt = '';
await tick();
submitPrompt(e.detail);
}
}}
/>
<div class="overflow-auto w-full h-full flex items-center">
<Placeholder
{history}
{selectedModels}
bind:files
bind:prompt
bind:autoScroll
bind:selectedToolIds
bind:webSearchEnabled
bind:atSelectedModel
availableToolIds={selectedModelIds.reduce((a, e, i, arr) => {
const model = $models.find((m) => m.id === e);
if (model?.info?.meta?.toolIds ?? false) {
return [...new Set([...a, ...model.info.meta.toolIds])];
}
return a;
}, [])}
transparentBackground={$settings?.backgroundImageUrl ?? false}
{stopResponse}
{createMessagePair}
on:upload={async (e) => {
const { type, data } = e.detail;
if (type === 'web') {
await uploadWeb(data);
} else if (type === 'youtube') {
await uploadYoutubeTranscription(data);
}
}}
on:submit={async (e) => {
if (e.detail) {
prompt = '';
await tick();
submitPrompt(e.detail);
}
}}
/>
</div>
{/if}
</div>
</Pane>
<ChatControls
bind:this={controlPaneComponent}
bind:history
bind:chatFiles
bind:params

View File

@@ -1,6 +1,7 @@
<script lang="ts">
import { SvelteFlowProvider } from '@xyflow/svelte';
import { slide } from 'svelte/transition';
import { Pane, PaneResizer } from 'paneforge';
import { onDestroy, onMount, tick } from 'svelte';
import { mobile, showControls, showCallOverlay, showOverview, showArtifacts } from '$lib/stores';
@@ -10,9 +11,9 @@
import CallOverlay from './MessageInput/CallOverlay.svelte';
import Drawer from '../common/Drawer.svelte';
import Overview from './Overview.svelte';
import { Pane, PaneResizer } from 'paneforge';
import EllipsisVertical from '../icons/EllipsisVertical.svelte';
import Artifacts from './Artifacts.svelte';
import { min } from '@floating-ui/utils';
export let history;
export let models = [];
@@ -35,6 +36,16 @@
let largeScreen = false;
let dragged = false;
let minSize = 0;
export const openPane = () => {
if (parseInt(localStorage?.chatControlsSize)) {
pane.resize(parseInt(localStorage?.chatControlsSize));
} else {
pane.resize(minSize);
}
};
const handleMediaQuery = async (e) => {
if (e.matches) {
largeScreen = true;
@@ -71,6 +82,32 @@
mediaQuery.addEventListener('change', handleMediaQuery);
handleMediaQuery(mediaQuery);
// Select the container element you want to observe
const container = document.getElementById('chat-container');
// initialize the minSize based on the container width
minSize = Math.floor((350 / container.clientWidth) * 100);
// Create a new ResizeObserver instance
const resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
const width = entry.contentRect.width;
// calculate the percentage of 200px
const percentage = (350 / width) * 100;
// set the minSize to the percentage, must be an integer
minSize = Math.floor(percentage);
if ($showControls) {
if (pane && pane.isExpanded() && pane.getSize() < minSize) {
pane.resize(minSize);
}
}
}
});
// Start observing the container's size changes
resizeObserver.observe(container);
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mouseup', onMouseUp);
});
@@ -163,23 +200,29 @@
</div>
</PaneResizer>
{/if}
<Pane
bind:pane
defaultSize={$showControls
? parseInt(localStorage?.chatControlsSize ?? '30')
? parseInt(localStorage?.chatControlsSize ?? '30')
: 30
: 0}
defaultSize={0}
onResize={(size) => {
if (size === 0) {
showControls.set(false);
} else {
if (!$showControls) {
showControls.set(true);
console.log('size', size, minSize);
if ($showControls && pane.isExpanded()) {
if (size < minSize) {
pane.resize(minSize);
}
if (size < minSize) {
localStorage.chatControlsSize = 0;
} else {
localStorage.chatControlsSize = size;
}
localStorage.chatControlsSize = size;
}
}}
onCollapse={() => {
showControls.set(false);
}}
collapsible={true}
class="pt-8"
>
{#if $showControls}
@@ -187,7 +230,7 @@
<div
class="w-full {($showOverview || $showArtifacts) && !$showCallOverlay
? ' '
: 'px-5 py-4 bg-white dark:shadow-lg dark:bg-gray-850 border border-gray-50 dark:border-gray-800'} rounded-lg z-40 pointer-events-auto overflow-y-auto scrollbar-hidden"
: 'px-4 py-4 bg-white dark:shadow-lg dark:bg-gray-850 border border-gray-50 dark:border-gray-800'} rounded-lg z-40 pointer-events-auto overflow-y-auto scrollbar-hidden"
>
{#if $showCallOverlay}
<div class="w-full h-full flex justify-center">

View File

@@ -16,7 +16,7 @@
</script>
<div class=" dark:text-white">
<div class=" flex justify-between dark:text-gray-100 mb-2">
<div class=" flex items-center justify-between dark:text-gray-100 mb-2">
<div class=" text-lg font-medium self-center font-primary">{$i18n.t('Chat Controls')}</div>
<button
class="self-center"
@@ -24,11 +24,11 @@
dispatch('close');
}}
>
<XMark className="size-4" />
<XMark className="size-3.5" />
</button>
</div>
<div class=" dark:text-gray-200 text-sm font-primary py-0.5">
<div class=" dark:text-gray-200 text-sm font-primary py-0.5 px-0.5">
{#if chatFiles.length > 0}
<Collapsible title={$i18n.t('Files')} open={true}>
<div class="flex flex-col gap-1 mt-1.5" slot="content">

View File

@@ -1,6 +1,6 @@
<script lang="ts">
import { toast } from 'svelte-sonner';
import { onMount, tick, getContext, createEventDispatcher } from 'svelte';
import { onMount, tick, getContext, createEventDispatcher, onDestroy } from 'svelte';
const dispatch = createEventDispatcher();
import {
@@ -175,57 +175,59 @@
});
};
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
console.log('Escape');
dragged = false;
}
};
const onDragOver = (e) => {
e.preventDefault();
dragged = true;
};
const onDragLeave = () => {
dragged = false;
};
const onDrop = async (e) => {
e.preventDefault();
console.log(e);
if (e.dataTransfer?.files) {
const inputFiles = Array.from(e.dataTransfer?.files);
if (inputFiles && inputFiles.length > 0) {
console.log(inputFiles);
inputFilesHandler(inputFiles);
} else {
toast.error($i18n.t(`File not found.`));
}
}
dragged = false;
};
onMount(() => {
window.setTimeout(() => chatTextAreaElement?.focus(), 0);
const dropZone = document.querySelector('body');
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
console.log('Escape');
dragged = false;
}
};
const onDragOver = (e) => {
e.preventDefault();
dragged = true;
};
const onDragLeave = () => {
dragged = false;
};
const onDrop = async (e) => {
e.preventDefault();
console.log(e);
if (e.dataTransfer?.files) {
const inputFiles = Array.from(e.dataTransfer?.files);
if (inputFiles && inputFiles.length > 0) {
console.log(inputFiles);
inputFilesHandler(inputFiles);
} else {
toast.error($i18n.t(`File not found.`));
}
}
dragged = false;
};
window.addEventListener('keydown', handleKeyDown);
const dropZone = document.getElementById('chat-container');
dropZone?.addEventListener('dragover', onDragOver);
dropZone?.addEventListener('drop', onDrop);
dropZone?.addEventListener('dragleave', onDragLeave);
});
return () => {
window.removeEventListener('keydown', handleKeyDown);
onDestroy(() => {
window.removeEventListener('keydown', handleKeyDown);
dropZone?.removeEventListener('dragover', onDragOver);
dropZone?.removeEventListener('drop', onDrop);
dropZone?.removeEventListener('dragleave', onDragLeave);
};
const dropZone = document.getElementById('chat-container');
dropZone?.removeEventListener('dragover', onDragOver);
dropZone?.removeEventListener('drop', onDrop);
dropZone?.removeEventListener('dragleave', onDragLeave);
});
</script>
@@ -300,6 +302,9 @@
bind:this={commandsElement}
bind:prompt
bind:files
on:upload={(e) => {
dispatch('upload', e.detail);
}}
on:select={(e) => {
const data = e.detail;
@@ -791,25 +796,27 @@
{/if}
{:else}
<div class=" flex items-center mb-1.5">
<button
class="bg-white hover:bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-1.5"
on:click={() => {
stopResponse();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="size-6"
<Tooltip content={$i18n.t('Stop')}>
<button
class="bg-white hover:bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-800 transition rounded-full p-1.5"
on:click={() => {
stopResponse();
}}
>
<path
fill-rule="evenodd"
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm6-2.438c0-.724.588-1.312 1.313-1.312h4.874c.725 0 1.313.588 1.313 1.313v4.874c0 .725-.588 1.313-1.313 1.313H9.564a1.312 1.312 0 01-1.313-1.313V9.564z"
clip-rule="evenodd"
/>
</svg>
</button>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="size-6"
>
<path
fill-rule="evenodd"
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm6-2.438c0-.724.588-1.312 1.313-1.312h4.874c.725 0 1.313.588 1.313 1.313v4.874c0 .725-.588 1.313-1.313 1.313H9.564a1.312 1.312 0 01-1.313-1.313V9.564z"
clip-rule="evenodd"
/>
</svg>
</button>
</Tooltip>
</div>
{/if}
</div>

View File

@@ -26,71 +26,6 @@
let command = '';
$: command = (prompt?.trim() ?? '').split(' ')?.at(-1) ?? '';
const uploadWeb = async (url) => {
console.log(url);
const fileItem = {
type: 'doc',
name: url,
collection_name: '',
status: 'uploading',
url: url,
error: ''
};
try {
files = [...files, fileItem];
const res = await processWeb(localStorage.token, '', url);
if (res) {
fileItem.status = 'uploaded';
fileItem.collection_name = res.collection_name;
fileItem.file = {
...res.file,
...fileItem.file
};
files = files;
}
} catch (e) {
// Remove the failed doc from the files array
files = files.filter((f) => f.name !== url);
toast.error(JSON.stringify(e));
}
};
const uploadYoutubeTranscription = async (url) => {
console.log(url);
const fileItem = {
type: 'doc',
name: url,
collection_name: '',
status: 'uploading',
url: url,
error: ''
};
try {
files = [...files, fileItem];
const res = await processYoutubeVideo(localStorage.token, url);
if (res) {
fileItem.status = 'uploaded';
fileItem.collection_name = res.collection_name;
fileItem.file = {
...res.file,
...fileItem.file
};
files = files;
}
} catch (e) {
// Remove the failed doc from the files array
files = files.filter((f) => f.name !== url);
toast.error(e);
}
};
</script>
{#if ['/', '#', '@'].includes(command?.charAt(0))}
@@ -103,18 +38,23 @@
{command}
on:youtube={(e) => {
console.log(e);
uploadYoutubeTranscription(e.detail);
dispatch('upload', {
type: 'youtube',
data: e.detail
});
}}
on:url={(e) => {
console.log(e);
uploadWeb(e.detail);
dispatch('upload', {
type: 'web',
data: e.detail
});
}}
on:select={(e) => {
console.log(e);
files = [
...files,
{
type: e?.detail?.meta?.document ? 'file' : 'collection',
...e.detail,
status: 'processed'
}

View File

@@ -2,6 +2,10 @@
import { toast } from 'svelte-sonner';
import Fuse from 'fuse.js';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);
import { createEventDispatcher, tick, getContext, onMount } from 'svelte';
import { removeLastWordFromString, isValidHttpUrl } from '$lib/utils';
import { knowledge } from '$lib/stores';
@@ -72,7 +76,13 @@
};
onMount(() => {
let legacy_documents = $knowledge.filter((item) => item?.meta?.document);
let legacy_documents = $knowledge
.filter((item) => item?.meta?.document)
.map((item) => ({
...item,
type: 'file'
}));
let legacy_collections =
legacy_documents.length > 0
? [
@@ -101,12 +111,44 @@
]
: [];
items = [...$knowledge, ...legacy_collections].map((item) => {
return {
let collections = $knowledge
.filter((item) => !item?.meta?.document)
.map((item) => ({
...item,
...(item?.legacy || item?.meta?.legacy || item?.meta?.document ? { legacy: true } : {})
};
});
type: 'collection'
}));
let collection_files =
$knowledge.length > 0
? [
...$knowledge
.reduce((a, item) => {
return [
...new Set([
...a,
...(item?.files ?? []).map((file) => ({
...file,
collection: { name: item.name, description: item.description }
}))
])
];
}, [])
.map((file) => ({
...file,
name: file?.meta?.name,
description: `${file?.collection?.name} - ${file?.collection?.description}`,
type: 'file'
}))
]
: [];
items = [...collections, ...collection_files, ...legacy_collections, ...legacy_documents].map(
(item) => {
return {
...item,
...(item?.legacy || item?.meta?.legacy || item?.meta?.document ? { legacy: true } : {})
};
}
);
fuse = new Fuse(items, {
keys: ['name', 'description']
@@ -117,20 +159,17 @@
{#if filteredItems.length > 0 || prompt.split(' ')?.at(0)?.substring(1).startsWith('http')}
<div
id="commands-container"
class="pl-2 pr-14 mb-3 text-left w-full absolute bottom-0 left-0 right-0 z-10"
class="pl-8 pr-16 mb-3 text-left w-full absolute bottom-0 left-0 right-0 z-10"
>
<div class="flex w-full dark:border dark:border-gray-850 rounded-lg">
<div class=" bg-gray-50 dark:bg-gray-850 w-10 rounded-l-lg text-center">
<div class=" text-lg font-medium mt-2">#</div>
</div>
<div class="flex w-full rounded-xl border border-gray-50 dark:border-gray-850">
<div
class="max-h-60 flex flex-col w-full rounded-r-xl bg-white dark:bg-gray-900 dark:text-gray-100"
class="max-h-60 flex flex-col w-full rounded-xl bg-white dark:bg-gray-900 dark:text-gray-100"
>
<div class="m-1 overflow-y-auto p-1 rounded-r-xl space-y-0.5 scrollbar-hidden">
{#each filteredItems as item, idx}
<button
class=" px-3 py-1.5 rounded-xl w-full text-left {idx === selectedIdx
class=" px-3 py-1.5 rounded-xl w-full text-left flex justify-between items-center {idx ===
selectedIdx
? ' bg-gray-50 dark:bg-gray-850 dark:text-gray-100 selected-command-option-button'
: ''}"
type="button"
@@ -141,38 +180,87 @@
on:mousemove={() => {
selectedIdx = idx;
}}
on:focus={() => {}}
>
<div class=" font-medium text-black dark:text-gray-100 flex items-center gap-1">
{#if item.legacy}
<div
class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded uppercase text-xs font-bold px-1"
>
Legacy
</div>
{:else if item?.meta?.document}
<div
class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded uppercase text-xs font-bold px-1"
>
Document
</div>
{:else}
<div
class="bg-green-500/20 text-green-700 dark:text-green-200 rounded uppercase text-xs font-bold px-1"
>
Collection
</div>
{/if}
<div>
<div class=" font-medium text-black dark:text-gray-100 flex items-center gap-1">
{#if item.legacy}
<div
class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded uppercase text-xs font-bold px-1 flex-shrink-0"
>
Legacy
</div>
{:else if item?.meta?.document}
<div
class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded uppercase text-xs font-bold px-1 flex-shrink-0"
>
Document
</div>
{:else if item?.type === 'file'}
<div
class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded uppercase text-xs font-bold px-1 flex-shrink-0"
>
File
</div>
{:else}
<div
class="bg-green-500/20 text-green-700 dark:text-green-200 rounded uppercase text-xs font-bold px-1 flex-shrink-0"
>
Collection
</div>
{/if}
<div class="line-clamp-1">
{item.name}
<div class="line-clamp-1">
{item?.name}
</div>
</div>
<div class=" text-xs text-gray-600 dark:text-gray-100 line-clamp-1">
{item?.description}
</div>
</div>
<div class=" text-xs text-gray-600 dark:text-gray-100 line-clamp-1">
{item?.description}
</div>
</button>
<!-- <div slot="content" class=" pl-2 pt-1 flex flex-col gap-0.5">
{#if !item.legacy && (item?.files ?? []).length > 0}
{#each item?.files ?? [] as file, fileIdx}
<button
class=" px-3 py-1.5 rounded-xl w-full text-left flex justify-between items-center hover:bg-gray-50 dark:hover:bg-gray-850 dark:hover:text-gray-100 selected-command-option-button"
type="button"
on:click={() => {
console.log(file);
}}
on:mousemove={() => {
selectedIdx = idx;
}}
>
<div>
<div
class=" font-medium text-black dark:text-gray-100 flex items-center gap-1"
>
<div
class="bg-gray-500/20 text-gray-700 dark:text-gray-200 rounded uppercase text-xs font-bold px-1 flex-shrink-0"
>
File
</div>
<div class="line-clamp-1">
{file?.meta?.name}
</div>
</div>
<div class=" text-xs text-gray-600 dark:text-gray-100 line-clamp-1">
{$i18n.t('Updated')}
{dayjs(file.updated_at * 1000).fromNow()}
</div>
</div>
</button>
{/each}
{:else}
<div class=" text-gray-500 text-xs mt-1 mb-2">
{$i18n.t('No files found.')}
</div>
{/if}
</div> -->
{/each}
{#if prompt

View File

@@ -68,15 +68,11 @@
{#if filteredItems.length > 0}
<div
id="commands-container"
class="pl-2 pr-14 mb-3 text-left w-full absolute bottom-0 left-0 right-0 z-10"
class="pl-8 pr-16 mb-3 text-left w-full absolute bottom-0 left-0 right-0 z-10"
>
<div class="flex w-full dark:border dark:border-gray-850 rounded-lg">
<div class=" bg-gray-50 dark:bg-gray-850 w-10 rounded-l-lg text-center">
<div class=" text-lg font-medium mt-2">@</div>
</div>
<div class="flex w-full rounded-xl border border-gray-50 dark:border-gray-850">
<div
class="max-h-60 flex flex-col w-full rounded-r-lg bg-white dark:bg-gray-900 dark:text-gray-100"
class="max-h-60 flex flex-col w-full rounded-xl bg-white dark:bg-gray-900 dark:text-gray-100"
>
<div class="m-1 overflow-y-auto p-1 rounded-r-lg space-y-0.5 scrollbar-hidden">
{#each filteredItems as model, modelIdx}

View File

@@ -132,17 +132,13 @@
{#if filteredPrompts.length > 0}
<div
id="commands-container"
class="pl-2 pr-14 mb-3 text-left w-full absolute bottom-0 left-0 right-0 z-10"
class="pl-8 pr-16 mb-3 text-left w-full absolute bottom-0 left-0 right-0 z-10"
>
<div class="flex w-full dark:border dark:border-gray-850 rounded-lg">
<div class=" bg-gray-50 dark:bg-gray-850 w-10 rounded-l-lg text-center">
<div class=" text-lg font-medium mt-2">/</div>
</div>
<div class="flex w-full rounded-xl border border-gray-50 dark:border-gray-850">
<div
class="max-h-60 flex flex-col w-full rounded-r-lg bg-white dark:bg-gray-900 dark:text-gray-100"
class="max-h-60 flex flex-col w-full rounded-xl bg-white dark:bg-gray-900 dark:text-gray-100"
>
<div class="m-1 overflow-y-auto p-1 rounded-r-lg space-y-0.5 scrollbar-hidden">
<div class="m-1 overflow-y-auto p-1 space-y-0.5 scrollbar-hidden">
{#each filteredPrompts as prompt, promptIdx}
<button
class=" px-3 py-1.5 rounded-xl w-full text-left {promptIdx === selectedPromptIdx
@@ -169,7 +165,7 @@
</div>
<div
class=" px-2 pb-1 text-xs text-gray-600 dark:text-gray-100 bg-white dark:bg-gray-900 rounded-br-xl flex items-center space-x-1"
class=" px-2 pt-0.5 pb-1 text-xs text-gray-600 dark:text-gray-100 bg-white dark:bg-gray-900 rounded-b-xl flex items-center space-x-1"
>
<div>
<svg

View File

@@ -302,6 +302,7 @@ __builtins__.input = input`);
<SvgPanZoom
className=" border border-gray-50 dark:border-gray-850 rounded-lg max-h-fit overflow-hidden"
svg={mermaidHtml}
content={_token.text}
/>
{:else}
<pre class="mermaid">{code}</pre>

View File

@@ -479,7 +479,7 @@
id={message.id}
content={message.content}
floatingButtons={message?.done}
save={true}
save={!readOnly}
{model}
on:update={(e) => {
const { raw, oldContent, newContent } = e.detail;

View File

@@ -94,7 +94,7 @@
: (user?.profile_image_url ?? '/user.png')}
/>
{/if}
<div class="w-full w-0 pl-1">
<div class="flex-auto w-0 max-w-full pl-1">
{#if !($settings?.chatBubble ?? true)}
<div>
<Name>

View File

@@ -15,6 +15,7 @@
import CustomNode from './Overview/Node.svelte';
import Flow from './Overview/Flow.svelte';
import XMark from '../icons/XMark.svelte';
import ArrowLeft from '../icons/ArrowLeft.svelte';
const { width, height } = useStore();
@@ -159,16 +160,26 @@
</script>
<div class="w-full h-full relative">
<div class=" absolute z-50 w-full flex justify-between dark:text-gray-100 px-5 py-4">
<div class=" text-lg font-medium self-center font-primary">{$i18n.t('Chat Overview')}</div>
<div class=" absolute z-50 w-full flex justify-between dark:text-gray-100 px-4 py-3.5">
<div class="flex items-center gap-2.5">
<button
class="self-center p-0.5"
on:click={() => {
showOverview.set(false);
}}
>
<ArrowLeft className="size-3.5" />
</button>
<div class=" text-lg font-medium self-center font-primary">{$i18n.t('Chat Overview')}</div>
</div>
<button
class="self-center"
class="self-center p-0.5"
on:click={() => {
dispatch('close');
showOverview.set(false);
}}
>
<XMark className="size-4" />
<XMark className="size-3.5" />
</button>
</div>

View File

@@ -89,7 +89,7 @@
</script>
{#key mounted}
<div class="m-auto w-full max-w-6xl px-2 xl:px-20 translate-y-6 text-center">
<div class="m-auto w-full max-w-6xl px-2 xl:px-20 translate-y-6 py-24 text-center">
{#if $temporaryChatEnabled}
<Tooltip
content="This chat won't appear in history and your messages will not be saved."
@@ -186,7 +186,7 @@
</div>
<div
class="text-base font-normal xl:translate-x-6 lg:max-w-3xl w-full py-3 {atSelectedModel
class="text-base font-normal xl:translate-x-6 md:max-w-3xl w-full py-3 {atSelectedModel
? 'mt-2'
: ''}"
>
@@ -204,6 +204,9 @@
{stopResponse}
{createMessagePair}
placeholder={$i18n.t('How can I help you today?')}
on:upload={(e) => {
dispatch('upload', e.detail);
}}
on:submit={(e) => {
dispatch('submit', e.detail);
}}

View File

@@ -25,51 +25,32 @@
let tags = [];
const getTags = async () => {
return (
await getTagsById(localStorage.token, chatId).catch(async (error) => {
return [];
})
).filter((tag) => tag.name !== 'pinned');
return await getTagsById(localStorage.token, chatId).catch(async (error) => {
return [];
});
};
const addTag = async (tagName) => {
const res = await addTagById(localStorage.token, chatId, tagName);
tags = await getTags();
await updateChatById(localStorage.token, chatId, {
tags: tags
});
_tags.set(await getAllChatTags(localStorage.token));
await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned'));
};
const deleteTag = async (tagName) => {
const res = await deleteTagById(localStorage.token, chatId, tagName);
tags = await getTags();
await updateChatById(localStorage.token, chatId, {
tags: tags
});
await _tags.set(await getAllChatTags(localStorage.token));
if ($_tags.map((t) => t.name).includes(tagName)) {
if (tagName === 'pinned') {
await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned'));
} else {
await chats.set(await getChatListByTagName(localStorage.token, tagName));
}
if ($chats.find((chat) => chat.id === chatId)) {
dispatch('close');
}
} else {
// if the tag we deleted is no longer a valid tag, return to main chat list view
currentChatPage.set(1);
await chats.set(await getChatList(localStorage.token, $currentChatPage));
await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned'));
await scrollPaginationEnabled.set(true);
}
dispatch('delete', {
name: tagName
});
};
onMount(async () => {

View File

@@ -1,11 +1,19 @@
<script lang="ts">
import { onMount } from 'svelte';
import { onMount, getContext } from 'svelte';
const i18n = getContext('i18n');
import panzoom from 'panzoom';
import DOMPurify from 'dompurify';
import DocumentDuplicate from '../icons/DocumentDuplicate.svelte';
import { copyToClipboard } from '$lib/utils';
import { toast } from 'svelte-sonner';
import Tooltip from './Tooltip.svelte';
import Clipboard from '../icons/Clipboard.svelte';
export let className = '';
export let svg = '';
export let content = '';
let instance;
@@ -22,8 +30,24 @@
}
</script>
<div bind:this={sceneParentElement} class={className}>
<div bind:this={sceneParentElement} class="relative {className}">
<div bind:this={sceneElement} class="flex h-full max-h-full justify-center items-center">
{@html svg}
</div>
{#if content}
<div class=" absolute top-1 right-1">
<Tooltip content={$i18n.t('Copy to clipboard')}>
<button
class="p-1.5 rounded-lg border border-gray-100 dark:border-none dark:bg-gray-850 hover:bg-gray-50 dark:hover:bg-gray-800 transition"
on:click={() => {
copyToClipboard(content);
toast.success($i18n.t('Copied to clipboard'));
}}
>
<Clipboard className=" size-4" strokeWidth="1.5" />
</button>
</Tooltip>
</div>
{/if}
</div>

View File

@@ -1,166 +0,0 @@
<script lang="ts">
import { toast } from 'svelte-sonner';
import dayjs from 'dayjs';
import { onMount, getContext } from 'svelte';
import { getDocs } from '$lib/apis/documents';
import Modal from '../common/Modal.svelte';
import { documents } from '$lib/stores';
import { SUPPORTED_FILE_EXTENSIONS, SUPPORTED_FILE_TYPE } from '$lib/constants';
import Tags from '../common/Tags.svelte';
const i18n = getContext('i18n');
export let show = false;
export let uploadDoc: Function;
let uploadDocInputElement: HTMLInputElement;
let inputFiles;
let tags = [];
let doc = {
name: '',
title: '',
content: null
};
const submitHandler = async () => {
if (inputFiles && inputFiles.length > 0) {
for (const file of inputFiles) {
console.log(file, file.name.split('.').at(-1));
if (
SUPPORTED_FILE_TYPE.includes(file['type']) ||
SUPPORTED_FILE_EXTENSIONS.includes(file.name.split('.').at(-1))
) {
uploadDoc(file, tags);
} else {
toast.error(
`Unknown File Type '${file['type']}', but accepting and treating as plain text`
);
uploadDoc(file, tags);
}
}
inputFiles = null;
uploadDocInputElement.value = '';
} else {
toast.error($i18n.t(`File not found.`));
}
show = false;
documents.set(await getDocs(localStorage.token));
};
const addTagHandler = async (tagName) => {
if (!tags.find((tag) => tag.name === tagName) && tagName !== '') {
tags = [...tags, { name: tagName }];
} else {
console.log('tag already exists');
}
};
const deleteTagHandler = async (tagName) => {
tags = tags.filter((tag) => tag.name !== tagName);
};
onMount(() => {});
</script>
<Modal size="sm" bind:show>
<div>
<div class=" flex justify-between dark:text-gray-300 px-5 pt-4">
<div class=" text-lg font-medium self-center">{$i18n.t('Add Docs')}</div>
<button
class="self-center"
on:click={() => {
show = false;
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-5 h-5"
>
<path
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
/>
</svg>
</button>
</div>
<div class="flex flex-col md:flex-row w-full px-5 py-4 md:space-x-4 dark:text-gray-200">
<div class=" flex flex-col w-full sm:flex-row sm:justify-center sm:space-x-6">
<form
class="flex flex-col w-full"
on:submit|preventDefault={() => {
submitHandler();
}}
>
<div class="mb-3 w-full">
<input
id="upload-doc-input"
bind:this={uploadDocInputElement}
hidden
bind:files={inputFiles}
type="file"
multiple
/>
<button
class="w-full text-sm font-medium py-3 bg-gray-100 hover:bg-gray-200 dark:bg-gray-850 dark:hover:bg-gray-800 text-center rounded-xl"
type="button"
on:click={() => {
uploadDocInputElement.click();
}}
>
{#if inputFiles}
{inputFiles.length > 0 ? `${inputFiles.length}` : ''} document(s) selected.
{:else}
{$i18n.t('Click here to select documents.')}
{/if}
</button>
</div>
<div class=" flex flex-col space-y-1.5">
<div class="flex flex-col w-full">
<div class=" mb-1.5 text-xs text-gray-500">{$i18n.t('Tags')}</div>
<Tags {tags} addTag={addTagHandler} deleteTag={deleteTagHandler} />
</div>
</div>
<div class="flex justify-end pt-5 text-sm font-medium">
<button
class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
type="submit"
>
{$i18n.t('Save')}
</button>
</div>
</form>
</div>
</div>
</div>
</Modal>
<style>
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
/* display: none; <- Crashes Chrome on hover */
-webkit-appearance: none;
margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
}
.tabs::-webkit-scrollbar {
display: none; /* for Chrome, Safari and Opera */
}
.tabs {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
input[type='number'] {
-moz-appearance: textfield; /* Firefox */
}
</style>

View File

@@ -1,181 +0,0 @@
<script lang="ts">
import { toast } from 'svelte-sonner';
import dayjs from 'dayjs';
import { onMount, getContext } from 'svelte';
import { getDocs, tagDocByName, updateDocByName } from '$lib/apis/documents';
import Modal from '../common/Modal.svelte';
import { documents } from '$lib/stores';
import TagInput from '../common/Tags/TagInput.svelte';
import Tags from '../common/Tags.svelte';
import { addTagById } from '$lib/apis/chats';
const i18n = getContext('i18n');
export let show = false;
export let selectedDoc;
let tags = [];
let doc = {
name: '',
title: '',
content: null
};
const submitHandler = async () => {
const res = await updateDocByName(localStorage.token, selectedDoc.name, {
title: doc.title,
name: doc.name
}).catch((error) => {
toast.error(error);
});
if (res) {
show = false;
documents.set(await getDocs(localStorage.token));
}
};
const addTagHandler = async (tagName) => {
if (!tags.find((tag) => tag.name === tagName) && tagName !== '') {
tags = [...tags, { name: tagName }];
await tagDocByName(localStorage.token, doc.name, {
name: doc.name,
tags: tags
});
documents.set(await getDocs(localStorage.token));
} else {
console.log('tag already exists');
}
};
const deleteTagHandler = async (tagName) => {
tags = tags.filter((tag) => tag.name !== tagName);
await tagDocByName(localStorage.token, doc.name, {
name: doc.name,
tags: tags
});
documents.set(await getDocs(localStorage.token));
};
onMount(() => {
if (selectedDoc) {
doc = JSON.parse(JSON.stringify(selectedDoc));
tags = doc?.content?.tags ?? [];
}
});
</script>
<Modal size="sm" bind:show>
<div>
<div class=" flex justify-between dark:text-gray-300 px-5 pt-4">
<div class=" text-lg font-medium self-center">{$i18n.t('Edit Doc')}</div>
<button
class="self-center"
on:click={() => {
show = false;
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-5 h-5"
>
<path
d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"
/>
</svg>
</button>
</div>
<div class="flex flex-col md:flex-row w-full px-5 py-4 md:space-x-4 dark:text-gray-200">
<div class=" flex flex-col w-full sm:flex-row sm:justify-center sm:space-x-6">
<form
class="flex flex-col w-full"
on:submit|preventDefault={() => {
submitHandler();
}}
>
<div class=" flex flex-col space-y-1.5">
<div class="flex flex-col w-full">
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Name Tag')}</div>
<div class="flex flex-1">
<div
class="bg-gray-200 dark:bg-gray-800 font-semibold px-3 py-0.5 border border-r-0 dark:border-gray-800 rounded-l-xl flex items-center"
>
#
</div>
<input
class="w-full rounded-r-xl py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 disabled:text-gray-500 dark:disabled:text-gray-500 outline-none"
type="text"
bind:value={doc.name}
autocomplete="off"
required
/>
</div>
</div>
<div class="flex flex-col w-full">
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Title')}</div>
<div class="flex-1">
<input
class="w-full rounded-xl py-2 px-4 text-sm dark:text-gray-300 dark:bg-gray-850 outline-none"
type="text"
bind:value={doc.title}
autocomplete="off"
required
/>
</div>
</div>
<div class="flex flex-col w-full">
<div class=" mb-2 text-xs text-gray-500">{$i18n.t('Tags')}</div>
<Tags {tags} addTag={addTagHandler} deleteTag={deleteTagHandler} />
</div>
</div>
<div class="flex justify-end pt-5 text-sm font-medium">
<button
class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
type="submit"
>
{$i18n.t('Save')}
</button>
</div>
</form>
</div>
</div>
</div>
</Modal>
<style>
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
/* display: none; <- Crashes Chrome on hover */
-webkit-appearance: none;
margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
}
.tabs::-webkit-scrollbar {
display: none; /* for Chrome, Safari and Opera */
}
.tabs {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
input[type='number'] {
-moz-appearance: textfield; /* Firefox */
}
</style>

View File

@@ -0,0 +1,15 @@
<script lang="ts">
export let className = 'size-4';
export let strokeWidth = '1.5';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
stroke="currentColor"
class={className}
>
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
</svg>

View File

@@ -10,6 +10,7 @@
showArchivedChats,
showControls,
showSidebar,
temporaryChatEnabled,
user
} from '$lib/stores';
@@ -23,6 +24,7 @@
import MenuLines from '../icons/MenuLines.svelte';
import AdjustmentsHorizontal from '../icons/AdjustmentsHorizontal.svelte';
import Map from '../icons/Map.svelte';
import { stringify } from 'postcss';
const i18n = getContext('i18n');
@@ -74,8 +76,7 @@
<div class="self-start flex flex-none items-center text-gray-600 dark:text-gray-400">
<!-- <div class="md:hidden flex self-center w-[1px] h-5 mx-2 bg-gray-300 dark:bg-stone-700" /> -->
{#if shareEnabled && chat && chat.id}
{#if shareEnabled && chat && (chat.id || $temporaryChatEnabled)}
<Menu
{chat}
{shareEnabled}

View File

@@ -9,7 +9,13 @@
import { downloadChatAsPDF } from '$lib/apis/utils';
import { copyToClipboard, createMessagesList } from '$lib/utils';
import { showOverview, showControls, showArtifacts, mobile } from '$lib/stores';
import {
showOverview,
showControls,
showArtifacts,
mobile,
temporaryChatEnabled
} from '$lib/stores';
import { flyAndScale } from '$lib/utils/transitions';
import Dropdown from '$lib/components/common/Dropdown.svelte';
@@ -18,6 +24,7 @@
import Clipboard from '$lib/components/icons/Clipboard.svelte';
import AdjustmentsHorizontal from '$lib/components/icons/AdjustmentsHorizontal.svelte';
import Cube from '$lib/components/icons/Cube.svelte';
import { getChatById } from '$lib/apis/chats';
const i18n = getContext('i18n');
@@ -31,9 +38,8 @@
export let onClose: Function = () => {};
const getChatAsText = async () => {
const _chat = chat.chat;
const messages = createMessagesList(_chat.history, _chat.history.currentId);
const history = chat.chat.history;
const messages = createMessagesList(history, history.currentId);
const chatText = messages.reduce((a, message, i, arr) => {
return `${a}### ${message.role.toUpperCase()}\n${message.content}\n\n`;
}, '');
@@ -52,12 +58,9 @@
};
const downloadPdf = async () => {
const _chat = chat.chat;
const messages = createMessagesList(_chat.history, _chat.history.currentId);
console.log('download', chat);
const blob = await downloadChatAsPDF(_chat.title, messages);
const history = chat.chat.history;
const messages = createMessagesList(history, history.currentId);
const blob = await downloadChatAsPDF(chat.chat.title, messages);
// Create a URL for the blob
const url = window.URL.createObjectURL(blob);
@@ -65,7 +68,7 @@
// Create a link element to trigger the download
const a = document.createElement('a');
a.href = url;
a.download = `chat-${_chat.title}.pdf`;
a.download = `chat-${chat.chat.title}.pdf`;
// Append the link to the body and click it programmatically
document.body.appendChild(a);
@@ -79,6 +82,9 @@
};
const downloadJSONExport = async () => {
if (chat.id) {
chat = await getChatById(localStorage.token, chat.id);
}
let blob = new Blob([JSON.stringify([chat])], {
type: 'application/json'
});
@@ -189,27 +195,29 @@
<div class="flex items-center">{$i18n.t('Copy')}</div>
</DropdownMenu.Item>
<DropdownMenu.Item
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
id="chat-share-button"
on:click={() => {
shareHandler();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="size-4"
{#if !$temporaryChatEnabled}
<DropdownMenu.Item
class="flex gap-2 items-center px-3 py-2 text-sm cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800 rounded-md"
id="chat-share-button"
on:click={() => {
shareHandler();
}}
>
<path
fill-rule="evenodd"
d="M15.75 4.5a3 3 0 1 1 .825 2.066l-8.421 4.679a3.002 3.002 0 0 1 0 1.51l8.421 4.679a3 3 0 1 1-.729 1.31l-8.421-4.678a3 3 0 1 1 0-4.132l8.421-4.679a3 3 0 0 1-.096-.755Z"
clip-rule="evenodd"
/>
</svg>
<div class="flex items-center">{$i18n.t('Share')}</div>
</DropdownMenu.Item>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="size-4"
>
<path
fill-rule="evenodd"
d="M15.75 4.5a3 3 0 1 1 .825 2.066l-8.421 4.679a3.002 3.002 0 0 1 0 1.51l8.421 4.679a3 3 0 1 1-.729 1.31l-8.421-4.678a3 3 0 1 1 0-4.132l8.421-4.679a3 3 0 0 1-.096-.755Z"
clip-rule="evenodd"
/>
</svg>
<div class="flex items-center">{$i18n.t('Share')}</div>
</DropdownMenu.Item>
{/if}
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger
@@ -265,11 +273,13 @@
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
<hr class="border-gray-100 dark:border-gray-800 mt-2.5 mb-1.5" />
{#if !$temporaryChatEnabled}
<hr class="border-gray-100 dark:border-gray-800 mt-2.5 mb-1.5" />
<div class="flex p-1">
<Tags chatId={chat.id} />
</div>
<div class="flex p-1">
<Tags chatId={chat.id} />
</div>
{/if}
</DropdownMenu.Content>
</div>
</Dropdown>

View File

@@ -19,7 +19,7 @@
showOverview,
showControls
} from '$lib/stores';
import { onMount, getContext, tick } from 'svelte';
import { onMount, getContext, tick, onDestroy } from 'svelte';
const i18n = getContext('i18n');
@@ -32,7 +32,10 @@
updateChatById,
getAllChatTags,
archiveChatById,
cloneChatById
cloneChatById,
getChatListBySearchText,
createNewChat,
getPinnedChatList
} from '$lib/apis/chats';
import { WEBUI_BASE_URL } from '$lib/constants';
@@ -42,6 +45,9 @@
import DeleteConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import Spinner from '../common/Spinner.svelte';
import Loader from '../common/Loader.svelte';
import FilesOverlay from '../chat/MessageInput/FilesOverlay.svelte';
import AddFilesPlaceholder from '../AddFilesPlaceholder.svelte';
import { select } from 'd3-selection';
const BREAKPOINT = 768;
@@ -58,33 +64,11 @@
let selectedTagName = null;
let filteredChatList = [];
// Pagination variables
let chatListLoading = false;
let allChatsLoaded = false;
$: filteredChatList = $chats.filter((chat) => {
if (search === '') {
return true;
} else {
let title = chat.title.toLowerCase();
const query = search.toLowerCase();
let contentMatches = false;
// Access the messages within chat.chat.messages
if (chat.chat && chat.chat.messages && Array.isArray(chat.chat.messages)) {
contentMatches = chat.chat.messages.some((message) => {
// Check if message.content exists and includes the search query
return message.content && message.content.toLowerCase().includes(query);
});
}
return title.includes(query) || contentMatches;
}
});
const enablePagination = async () => {
const initChatList = async () => {
// Reset pagination variables
currentChatPage.set(1);
allChatsLoaded = false;
@@ -98,7 +82,14 @@
chatListLoading = true;
currentChatPage.set($currentChatPage + 1);
const newChatList = await getChatList(localStorage.token, $currentChatPage);
let newChatList = [];
if (search) {
newChatList = await getChatListBySearchText(localStorage.token, search, $currentChatPage);
} else {
newChatList = await getChatList(localStorage.token, $currentChatPage);
}
// once the bottom of the list has been reached (no results) there is no need to continue querying
allChatsLoaded = newChatList.length === 0;
@@ -107,110 +98,26 @@
chatListLoading = false;
};
onMount(async () => {
mobile.subscribe((e) => {
if ($showSidebar && e) {
showSidebar.set(false);
}
let searchDebounceTimeout;
if (!$showSidebar && !e) {
showSidebar.set(true);
}
});
const searchDebounceHandler = async () => {
console.log('search', search);
chats.set(null);
selectedTagName = null;
showSidebar.set(!$mobile ? localStorage.sidebar === 'true' : false);
showSidebar.subscribe((value) => {
localStorage.sidebar = value;
});
await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned'));
await enablePagination();
let touchstart;
let touchend;
function checkDirection() {
const screenWidth = window.innerWidth;
const swipeDistance = Math.abs(touchend.screenX - touchstart.screenX);
if (touchstart.clientX < 40 && swipeDistance >= screenWidth / 8) {
if (touchend.screenX < touchstart.screenX) {
showSidebar.set(false);
}
if (touchend.screenX > touchstart.screenX) {
showSidebar.set(true);
}
}
if (searchDebounceTimeout) {
clearTimeout(searchDebounceTimeout);
}
const onTouchStart = (e) => {
touchstart = e.changedTouches[0];
console.log(touchstart.clientX);
};
const onTouchEnd = (e) => {
touchend = e.changedTouches[0];
checkDirection();
};
const onKeyDown = (e) => {
if (e.key === 'Shift') {
shiftKey = true;
}
};
const onKeyUp = (e) => {
if (e.key === 'Shift') {
shiftKey = false;
}
};
const onFocus = () => {};
const onBlur = () => {
shiftKey = false;
selectedChatId = null;
};
window.addEventListener('keydown', onKeyDown);
window.addEventListener('keyup', onKeyUp);
window.addEventListener('touchstart', onTouchStart);
window.addEventListener('touchend', onTouchEnd);
window.addEventListener('focus', onFocus);
window.addEventListener('blur', onBlur);
return () => {
window.removeEventListener('keydown', onKeyDown);
window.removeEventListener('keyup', onKeyUp);
window.removeEventListener('touchstart', onTouchStart);
window.removeEventListener('touchend', onTouchEnd);
window.removeEventListener('focus', onFocus);
window.removeEventListener('blur', onBlur);
};
});
// Helper function to fetch and add chat content to each chat
const enrichChatsWithContent = async (chatList) => {
const enrichedChats = await Promise.all(
chatList.map(async (chat) => {
const chatDetails = await getChatById(localStorage.token, chat.id).catch((error) => null); // Handle error or non-existent chat gracefully
if (chatDetails) {
chat.chat = chatDetails.chat; // Assuming chatDetails.chat contains the chat content
}
return chat;
})
);
await chats.set(enrichedChats);
};
const saveSettings = async (updated) => {
await settings.set({ ...$settings, ...updated });
await updateUserSettings(localStorage.token, { ui: $settings });
location.href = '/';
if (search === '') {
await initChatList();
return;
} else {
searchDebounceTimeout = setTimeout(async () => {
currentChatPage.set(1);
await chats.set(await getChatListBySearchText(localStorage.token, search));
}, 1000);
}
};
const deleteChatHandler = async (id) => {
@@ -230,9 +137,175 @@
currentChatPage.set(1);
await chats.set(await getChatList(localStorage.token, $currentChatPage));
await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned'));
await pinnedChats.set(await getPinnedChatList(localStorage.token));
}
};
const inputFilesHandler = async (files) => {
console.log(files);
for (const file of files) {
const reader = new FileReader();
reader.onload = async (e) => {
const content = e.target.result;
try {
const items = JSON.parse(content);
for (const item of items) {
if (item.chat) {
await createNewChat(localStorage.token, item.chat);
}
}
} catch {
toast.error($i18n.t(`Invalid file format.`));
}
initChatList();
};
reader.readAsText(file);
}
};
const tagEventHandler = async (type, tagName, chatId) => {
console.log(type, tagName, chatId);
if (type === 'delete') {
if (selectedTagName === tagName) {
if ($tags.map((t) => t.name).includes(tagName)) {
await chats.set(await getChatListByTagName(localStorage.token, tagName));
} else {
selectedTagName = null;
await initChatList();
}
}
}
};
let dragged = false;
const onDragOver = (e) => {
e.preventDefault();
dragged = true;
};
const onDragLeave = () => {
dragged = false;
};
const onDrop = async (e) => {
e.preventDefault();
console.log(e);
if (e.dataTransfer?.files) {
const inputFiles = Array.from(e.dataTransfer?.files);
if (inputFiles && inputFiles.length > 0) {
console.log(inputFiles);
inputFilesHandler(inputFiles);
} else {
toast.error($i18n.t(`File not found.`));
}
}
dragged = false;
};
let touchstart;
let touchend;
function checkDirection() {
const screenWidth = window.innerWidth;
const swipeDistance = Math.abs(touchend.screenX - touchstart.screenX);
if (touchstart.clientX < 40 && swipeDistance >= screenWidth / 8) {
if (touchend.screenX < touchstart.screenX) {
showSidebar.set(false);
}
if (touchend.screenX > touchstart.screenX) {
showSidebar.set(true);
}
}
}
const onTouchStart = (e) => {
touchstart = e.changedTouches[0];
console.log(touchstart.clientX);
};
const onTouchEnd = (e) => {
touchend = e.changedTouches[0];
checkDirection();
};
const onKeyDown = (e) => {
if (e.key === 'Shift') {
shiftKey = true;
}
};
const onKeyUp = (e) => {
if (e.key === 'Shift') {
shiftKey = false;
}
};
const onFocus = () => {};
const onBlur = () => {
shiftKey = false;
selectedChatId = null;
};
onMount(async () => {
mobile.subscribe((e) => {
if ($showSidebar && e) {
showSidebar.set(false);
}
if (!$showSidebar && !e) {
showSidebar.set(true);
}
});
showSidebar.set(!$mobile ? localStorage.sidebar === 'true' : false);
showSidebar.subscribe((value) => {
localStorage.sidebar = value;
});
await pinnedChats.set(await getPinnedChatList(localStorage.token));
await initChatList();
window.addEventListener('keydown', onKeyDown);
window.addEventListener('keyup', onKeyUp);
window.addEventListener('touchstart', onTouchStart);
window.addEventListener('touchend', onTouchEnd);
window.addEventListener('focus', onFocus);
window.addEventListener('blur', onBlur);
const dropZone = document.getElementById('sidebar');
dropZone?.addEventListener('dragover', onDragOver);
dropZone?.addEventListener('drop', onDrop);
dropZone?.addEventListener('dragleave', onDragLeave);
});
onDestroy(() => {
window.removeEventListener('keydown', onKeyDown);
window.removeEventListener('keyup', onKeyUp);
window.removeEventListener('touchstart', onTouchStart);
window.removeEventListener('touchend', onTouchEnd);
window.removeEventListener('focus', onFocus);
window.removeEventListener('blur', onBlur);
const dropZone = document.getElementById('sidebar');
dropZone?.removeEventListener('dragover', onDragOver);
dropZone?.removeEventListener('drop', onDrop);
dropZone?.removeEventListener('dragleave', onDragLeave);
});
</script>
<ArchivedChatsModal
@@ -274,6 +347,18 @@
"
data-state={$showSidebar}
>
{#if dragged}
<div
class="absolute w-full h-full max-h-full backdrop-blur bg-gray-800/40 flex justify-center z-[999] touch-none pointer-events-none"
>
<div class="m-auto pt-64 flex flex-col justify-center">
<AddFilesPlaceholder
title={$i18n.t('Drop Chat Export')}
content={$i18n.t('Drop a chat export file here to import it.')}
/>
</div>
</div>
{/if}
<div
class="py-2.5 my-auto flex flex-col justify-between h-screen max-h-[100dvh] w-[260px] z-50 {$showSidebar
? ''
@@ -419,30 +504,27 @@
class="w-full rounded-r-xl py-1.5 pl-2.5 pr-4 text-sm bg-transparent dark:text-gray-300 outline-none"
placeholder={$i18n.t('Search')}
bind:value={search}
on:focus={async () => {
// TODO: migrate backend for more scalable search mechanism
scrollPaginationEnabled.set(false);
await chats.set(await getChatList(localStorage.token)); // when searching, load all chats
enrichChatsWithContent($chats);
on:input={() => {
searchDebounceHandler();
}}
/>
</div>
</div>
{#if $tags.filter((t) => t.name !== 'pinned').length > 0}
<div class="px-3.5 mb-1 flex gap-0.5 flex-wrap">
{#if $tags.length > 0}
<div class="px-3.5 mb-2.5 flex gap-0.5 flex-wrap">
<button
class="px-2.5 py-[1px] text-xs transition {selectedTagName === null
? 'bg-gray-100 dark:bg-gray-900'
: ' '} rounded-md font-medium"
on:click={async () => {
selectedTagName = null;
await enablePagination();
await initChatList();
}}
>
{$i18n.t('all')}
</button>
{#each $tags.filter((t) => t.name !== 'pinned') as tag}
{#each $tags as tag}
<button
class="px-2.5 py-[1px] text-xs transition {selectedTagName === tag.name
? 'bg-gray-100 dark:bg-gray-900'
@@ -450,15 +532,15 @@
on:click={async () => {
selectedTagName = tag.name;
scrollPaginationEnabled.set(false);
let chatIds = await getChatListByTagName(localStorage.token, tag.name);
if (chatIds.length === 0) {
let taggedChatList = await getChatListByTagName(localStorage.token, tag.name);
if (taggedChatList.length === 0) {
await tags.set(await getAllChatTags(localStorage.token));
// if the tag we deleted is no longer a valid tag, return to main chat list view
await enablePagination();
await initChatList();
} else {
await chats.set(taggedChatList);
}
await chats.set(chatIds);
chatListLoading = false;
}}
>
@@ -469,7 +551,7 @@
{/if}
{#if !search && $pinnedChats.length > 0}
<div class="pl-2 py-2 flex flex-col space-y-1">
<div class="pl-2 pb-2 flex flex-col space-y-1">
<div class="">
<div class="w-full pl-2.5 text-xs text-gray-500 dark:text-gray-500 font-medium pb-1.5">
{$i18n.t('Pinned')}
@@ -494,22 +576,27 @@
showDeleteConfirm = true;
}
}}
on:tag={(e) => {
const { type, name } = e.detail;
tagEventHandler(type, name, chat.id);
}}
/>
{/each}
</div>
</div>
{/if}
<div class="pl-2 my-2 flex-1 flex flex-col space-y-1 overflow-y-auto scrollbar-hidden">
{#each filteredChatList as chat, idx}
{#if idx === 0 || (idx > 0 && chat.time_range !== filteredChatList[idx - 1].time_range)}
<div
class="w-full pl-2.5 text-xs text-gray-500 dark:text-gray-500 font-medium {idx === 0
? ''
: 'pt-5'} pb-0.5"
>
{$i18n.t(chat.time_range)}
<!-- localisation keys for time_range to be recognized from the i18next parser (so they don't get automatically removed):
<div class="pl-2 flex-1 flex flex-col space-y-1 overflow-y-auto scrollbar-hidden">
{#if $chats}
{#each $chats as chat, idx}
{#if idx === 0 || (idx > 0 && chat.time_range !== $chats[idx - 1].time_range)}
<div
class="w-full pl-2.5 text-xs text-gray-500 dark:text-gray-500 font-medium {idx === 0
? ''
: 'pt-5'} pb-0.5"
>
{$i18n.t(chat.time_range)}
<!-- localisation keys for time_range to be recognized from the i18next parser (so they don't get automatically removed):
{$i18n.t('Today')}
{$i18n.t('Yesterday')}
{$i18n.t('Previous 7 days')}
@@ -527,43 +614,53 @@
{$i18n.t('November')}
{$i18n.t('December')}
-->
</div>
</div>
{/if}
<ChatItem
{chat}
{shiftKey}
selected={selectedChatId === chat.id}
on:select={() => {
selectedChatId = chat.id;
}}
on:unselect={() => {
selectedChatId = null;
}}
on:delete={(e) => {
if ((e?.detail ?? '') === 'shift') {
deleteChatHandler(chat.id);
} else {
deleteChat = chat;
showDeleteConfirm = true;
}
}}
on:tag={(e) => {
const { type, name } = e.detail;
tagEventHandler(type, name, chat.id);
}}
/>
{/each}
{#if $scrollPaginationEnabled && !allChatsLoaded}
<Loader
on:visible={(e) => {
if (!chatListLoading) {
loadMoreChats();
}
}}
>
<div class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2">
<Spinner className=" size-4" />
<div class=" ">Loading...</div>
</div>
</Loader>
{/if}
<ChatItem
{chat}
{shiftKey}
selected={selectedChatId === chat.id}
on:select={() => {
selectedChatId = chat.id;
}}
on:unselect={() => {
selectedChatId = null;
}}
on:delete={(e) => {
if ((e?.detail ?? '') === 'shift') {
deleteChatHandler(chat.id);
} else {
deleteChat = chat;
showDeleteConfirm = true;
}
}}
/>
{/each}
{#if $scrollPaginationEnabled && !allChatsLoaded}
<Loader
on:visible={(e) => {
if (!chatListLoading) {
loadMoreChats();
}
}}
>
<div class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2">
<Spinner className=" size-4" />
<div class=" ">Loading...</div>
</div>
</Loader>
{:else}
<div class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2">
<Spinner className=" size-4" />
<div class=" ">Loading...</div>
</div>
{/if}
</div>
</div>

View File

@@ -12,6 +12,7 @@
deleteChatById,
getChatList,
getChatListByTagName,
getPinnedChatList,
updateChatById
} from '$lib/apis/chats';
import {
@@ -55,7 +56,7 @@
currentChatPage.set(1);
await chats.set(await getChatList(localStorage.token, $currentChatPage));
await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned'));
await pinnedChats.set(await getPinnedChatList(localStorage.token));
}
};
@@ -70,7 +71,7 @@
currentChatPage.set(1);
await chats.set(await getChatList(localStorage.token, $currentChatPage));
await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned'));
await pinnedChats.set(await getPinnedChatList(localStorage.token));
}
};
@@ -79,7 +80,7 @@
currentChatPage.set(1);
await chats.set(await getChatList(localStorage.token, $currentChatPage));
await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned'));
await pinnedChats.set(await getPinnedChatList(localStorage.token));
};
const focusEdit = async (node: HTMLInputElement) => {
@@ -256,7 +257,10 @@
dispatch('unselect');
}}
on:change={async () => {
await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned'));
await pinnedChats.set(await getPinnedChatList(localStorage.token));
}}
on:tag={(e) => {
dispatch('tag', e.detail);
}}
>
<button

View File

@@ -15,7 +15,13 @@
import DocumentDuplicate from '$lib/components/icons/DocumentDuplicate.svelte';
import Bookmark from '$lib/components/icons/Bookmark.svelte';
import BookmarkSlash from '$lib/components/icons/BookmarkSlash.svelte';
import { addTagById, deleteTagById, getTagsById } from '$lib/apis/chats';
import {
addTagById,
deleteTagById,
getChatPinnedStatusById,
getTagsById,
toggleChatPinnedStatusById
} from '$lib/apis/chats';
const i18n = getContext('i18n');
@@ -32,20 +38,12 @@
let pinned = false;
const pinHandler = async () => {
if (pinned) {
await deleteTagById(localStorage.token, chatId, 'pinned');
} else {
await addTagById(localStorage.token, chatId, 'pinned');
}
await toggleChatPinnedStatusById(localStorage.token, chatId);
dispatch('change');
};
const checkPinned = async () => {
pinned = (
await getTagsById(localStorage.token, chatId).catch(async (error) => {
return [];
})
).find((tag) => tag.name === 'pinned');
pinned = await getChatPinnedStatusById(localStorage.token, chatId);
};
$: if (show) {
@@ -143,6 +141,13 @@
<div class="flex p-1">
<Tags
{chatId}
on:delete={(e) => {
dispatch('tag', {
type: 'delete',
name: e.detail.name
});
show = false;
}}
on:close={() => {
show = false;
onClose();

View File

@@ -1,627 +0,0 @@
<script lang="ts">
import { toast } from 'svelte-sonner';
import fileSaver from 'file-saver';
const { saveAs } = fileSaver;
import { onMount, getContext } from 'svelte';
import { WEBUI_NAME, documents, showSidebar } from '$lib/stores';
import { createNewDoc, deleteDocByName, getDocs } from '$lib/apis/documents';
import { SUPPORTED_FILE_TYPE, SUPPORTED_FILE_EXTENSIONS } from '$lib/constants';
import { processFile } from '$lib/apis/retrieval';
import { blobToFile, transformFileName } from '$lib/utils';
import Checkbox from '$lib/components/common/Checkbox.svelte';
import EditDocModal from '$lib/components/documents/EditDocModal.svelte';
import AddFilesPlaceholder from '$lib/components/AddFilesPlaceholder.svelte';
import AddDocModal from '$lib/components/documents/AddDocModal.svelte';
import { transcribeAudio } from '$lib/apis/audio';
import { uploadFile } from '$lib/apis/files';
const i18n = getContext('i18n');
let importFiles = '';
let inputFiles = '';
let query = '';
let documentsImportInputElement: HTMLInputElement;
let tags = [];
let showSettingsModal = false;
let showAddDocModal = false;
let showEditDocModal = false;
let selectedDoc;
let selectedTag = '';
let dragged = false;
const deleteDoc = async (name) => {
await deleteDocByName(localStorage.token, name);
await documents.set(await getDocs(localStorage.token));
};
const deleteDocs = async (docs) => {
const res = await Promise.all(
docs.map(async (doc) => {
return await deleteDocByName(localStorage.token, doc.name);
})
);
await documents.set(await getDocs(localStorage.token));
};
const uploadDoc = async (file, tags?: object) => {
console.log(file);
// Check if the file is an audio file and transcribe/convert it to text file
if (['audio/mpeg', 'audio/wav', 'audio/ogg', 'audio/x-m4a'].includes(file['type'])) {
const transcribeRes = await transcribeAudio(localStorage.token, file).catch((error) => {
toast.error(error);
return null;
});
if (transcribeRes) {
console.log(transcribeRes);
const blob = new Blob([transcribeRes.text], { type: 'text/plain' });
file = blobToFile(blob, `${file.name}.txt`);
}
}
// Upload the file to the server
const uploadedFile = await uploadFile(localStorage.token, file).catch((error) => {
toast.error(error);
return null;
});
const res = await processFile(localStorage.token, uploadedFile.id).catch((error) => {
toast.error(error);
return null;
});
if (res) {
await createNewDoc(
localStorage.token,
res.collection_name,
res.filename,
transformFileName(res.filename),
res.filename,
tags?.length > 0
? {
tags: tags
}
: null
).catch((error) => {
toast.error(error);
return null;
});
await documents.set(await getDocs(localStorage.token));
}
};
onMount(() => {
documents.subscribe((docs) => {
tags = docs.reduce((a, e, i, arr) => {
return [...new Set([...a, ...(e?.content?.tags ?? []).map((tag) => tag.name)])];
}, []);
});
const dropZone = document.querySelector('body');
const onDragOver = (e) => {
e.preventDefault();
dragged = true;
};
const onDragLeave = () => {
dragged = false;
};
const onDrop = async (e) => {
e.preventDefault();
if (e.dataTransfer?.files) {
let reader = new FileReader();
reader.onload = (event) => {
files = [
...files,
{
type: 'image',
url: `${event.target.result}`
}
];
};
const inputFiles = e.dataTransfer?.files;
if (inputFiles && inputFiles.length > 0) {
for (const file of inputFiles) {
console.log(file, file.name.split('.').at(-1));
if (
SUPPORTED_FILE_TYPE.includes(file['type']) ||
SUPPORTED_FILE_EXTENSIONS.includes(file.name.split('.').at(-1))
) {
uploadDoc(file);
} else {
toast.error(
`Unknown File Type '${file['type']}', but accepting and treating as plain text`
);
uploadDoc(file);
}
}
} else {
toast.error($i18n.t(`File not found.`));
}
}
dragged = false;
};
dropZone?.addEventListener('dragover', onDragOver);
dropZone?.addEventListener('drop', onDrop);
dropZone?.addEventListener('dragleave', onDragLeave);
return () => {
dropZone?.removeEventListener('dragover', onDragOver);
dropZone?.removeEventListener('drop', onDrop);
dropZone?.removeEventListener('dragleave', onDragLeave);
};
});
let filteredDocs;
$: filteredDocs = $documents.filter(
(doc) =>
(selectedTag === '' ||
(doc?.content?.tags ?? []).map((tag) => tag.name).includes(selectedTag)) &&
(query === '' || doc.name.includes(query))
);
</script>
<svelte:head>
<title>
{$i18n.t('Documents')} | {$WEBUI_NAME}
</title>
</svelte:head>
{#if dragged}
<div
class="fixed {$showSidebar
? 'left-0 md:left-[260px] md:w-[calc(100%-260px)]'
: 'left-0'} w-full h-full flex z-50 touch-none pointer-events-none"
id="dropzone"
role="region"
aria-label="Drag and Drop Container"
>
<div class="absolute w-full h-full backdrop-blur bg-gray-800/40 flex justify-center">
<div class="m-auto pt-64 flex flex-col justify-center">
<div class="max-w-md">
<AddFilesPlaceholder>
<div class=" mt-2 text-center text-sm dark:text-gray-200 w-full">
Drop any files here to add to my documents
</div>
</AddFilesPlaceholder>
</div>
</div>
</div>
</div>
{/if}
{#key selectedDoc}
<EditDocModal bind:show={showEditDocModal} {selectedDoc} />
{/key}
<AddDocModal bind:show={showAddDocModal} {uploadDoc} />
<div class="mb-3">
<div class="flex justify-between items-center">
<div class="flex md:self-center text-lg font-medium px-0.5">
{$i18n.t('Documents')}
<div class="flex self-center w-[1px] h-6 mx-2.5 bg-gray-200 dark:bg-gray-700" />
<span class="text-lg font-medium text-gray-500 dark:text-gray-300">{$documents.length}</span>
</div>
</div>
</div>
<div class=" flex w-full space-x-2">
<div class="flex flex-1">
<div class=" self-center ml-1 mr-3">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M9 3.5a5.5 5.5 0 100 11 5.5 5.5 0 000-11zM2 9a7 7 0 1112.452 4.391l3.328 3.329a.75.75 0 11-1.06 1.06l-3.329-3.328A7 7 0 012 9z"
clip-rule="evenodd"
/>
</svg>
</div>
<input
class=" w-full text-sm pr-4 py-1 rounded-r-xl outline-none bg-transparent"
bind:value={query}
placeholder={$i18n.t('Search Documents')}
/>
</div>
<div>
<button
class=" px-2 py-2 rounded-xl border border-gray-200 dark:border-gray-600 dark:border-0 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 transition font-medium text-sm flex items-center space-x-1"
aria-label={$i18n.t('Add Docs')}
on:click={() => {
showAddDocModal = true;
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
d="M8.75 3.75a.75.75 0 0 0-1.5 0v3.5h-3.5a.75.75 0 0 0 0 1.5h3.5v3.5a.75.75 0 0 0 1.5 0v-3.5h3.5a.75.75 0 0 0 0-1.5h-3.5v-3.5Z"
/>
</svg>
</button>
</div>
</div>
<!-- <div>
<div
class="my-3 py-16 rounded-lg border-2 border-dashed dark:border-gray-600 {dragged &&
' dark:bg-gray-700'} "
role="region"
on:drop={onDrop}
on:dragover={onDragOver}
on:dragleave={onDragLeave}
>
<div class=" pointer-events-none">
<div class="text-center dark:text-white text-2xl font-semibold z-50">{$i18n.t('Add Files')}</div>
<div class=" mt-2 text-center text-sm dark:text-gray-200 w-full">
Drop any files here to add to my documents
</div>
</div>
</div>
</div> -->
<hr class=" dark:border-gray-850 my-2.5" />
{#if tags.length > 0}
<div class="px-2.5 pt-1 flex gap-1 flex-wrap">
<div class="ml-0.5 pr-3 my-auto flex items-center">
<Checkbox
state={filteredDocs.filter((doc) => doc?.selected === 'checked').length ===
filteredDocs.length
? 'checked'
: 'unchecked'}
indeterminate={filteredDocs.filter((doc) => doc?.selected === 'checked').length > 0 &&
filteredDocs.filter((doc) => doc?.selected === 'checked').length !== filteredDocs.length}
on:change={(e) => {
if (e.detail === 'checked') {
filteredDocs = filteredDocs.map((doc) => ({ ...doc, selected: 'checked' }));
} else if (e.detail === 'unchecked') {
filteredDocs = filteredDocs.map((doc) => ({ ...doc, selected: 'unchecked' }));
}
}}
/>
</div>
{#if filteredDocs.filter((doc) => doc?.selected === 'checked').length === 0}
<button
class="px-2 py-0.5 space-x-1 flex h-fit items-center rounded-full transition bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:text-white"
on:click={async () => {
selectedTag = '';
// await chats.set(await getChatListByTagName(localStorage.token, tag.name));
}}
>
<div class=" text-xs font-medium self-center line-clamp-1">{$i18n.t('all')}</div>
</button>
{#each tags as tag}
<button
class="px-2 py-0.5 space-x-1 flex h-fit items-center rounded-full transition bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:text-white"
on:click={async () => {
selectedTag = tag;
// await chats.set(await getChatListByTagName(localStorage.token, tag.name));
}}
>
<div class=" text-xs font-medium self-center line-clamp-1">
#{tag}
</div>
</button>
{/each}
{:else}
<div class="flex-1 flex w-full justify-between items-center">
<div class="text-xs font-medium py-0.5 self-center mr-1">
{filteredDocs.filter((doc) => doc?.selected === 'checked').length} Selected
</div>
<div class="flex gap-1">
<!-- <button
class="px-2 py-0.5 space-x-1 flex h-fit items-center rounded-full transition bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:text-white"
on:click={async () => {
selectedTag = '';
// await chats.set(await getChatListByTagName(localStorage.token, tag.name));
}}
>
<div class=" text-xs font-medium self-center line-clamp-1">add tags</div>
</button> -->
<button
class="px-2 py-0.5 space-x-1 flex h-fit items-center rounded-full transition bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:text-white"
on:click={async () => {
deleteDocs(filteredDocs.filter((doc) => doc.selected === 'checked'));
// await chats.set(await getChatListByTagName(localStorage.token, tag.name));
}}
>
<div class=" text-xs font-medium self-center line-clamp-1">
{$i18n.t('delete')}
</div>
</button>
</div>
</div>
{/if}
</div>
{/if}
<div class="my-3 mb-5">
{#each filteredDocs as doc}
<button
class=" flex space-x-4 cursor-pointer text-left w-full px-3 py-2 dark:hover:bg-white/5 hover:bg-black/5 rounded-xl"
on:click={() => {
if (doc?.selected === 'checked') {
doc.selected = 'unchecked';
} else {
doc.selected = 'checked';
}
}}
>
<div class="my-auto flex items-center">
<Checkbox state={doc?.selected ?? 'unchecked'} />
</div>
<div class=" flex flex-1 space-x-4 cursor-pointer w-full">
<div class=" flex items-center space-x-3">
<div class="p-2.5 bg-red-400 text-white rounded-lg">
{#if doc}
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="w-6 h-6"
>
<path
fill-rule="evenodd"
d="M5.625 1.5c-1.036 0-1.875.84-1.875 1.875v17.25c0 1.035.84 1.875 1.875 1.875h12.75c1.035 0 1.875-.84 1.875-1.875V12.75A3.75 3.75 0 0 0 16.5 9h-1.875a1.875 1.875 0 0 1-1.875-1.875V5.25A3.75 3.75 0 0 0 9 1.5H5.625ZM7.5 15a.75.75 0 0 1 .75-.75h7.5a.75.75 0 0 1 0 1.5h-7.5A.75.75 0 0 1 7.5 15Zm.75 2.25a.75.75 0 0 0 0 1.5H12a.75.75 0 0 0 0-1.5H8.25Z"
clip-rule="evenodd"
/>
<path
d="M12.971 1.816A5.23 5.23 0 0 1 14.25 5.25v1.875c0 .207.168.375.375.375H16.5a5.23 5.23 0 0 1 3.434 1.279 9.768 9.768 0 0 0-6.963-6.963Z"
/>
</svg>
{:else}
<svg
class=" w-6 h-6 translate-y-[0.5px]"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
><style>
.spinner_qM83 {
animation: spinner_8HQG 1.05s infinite;
}
.spinner_oXPr {
animation-delay: 0.1s;
}
.spinner_ZTLf {
animation-delay: 0.2s;
}
@keyframes spinner_8HQG {
0%,
57.14% {
animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1);
transform: translate(0);
}
28.57% {
animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33);
transform: translateY(-6px);
}
100% {
transform: translate(0);
}
}
</style><circle class="spinner_qM83" cx="4" cy="12" r="2.5" /><circle
class="spinner_qM83 spinner_oXPr"
cx="12"
cy="12"
r="2.5"
/><circle class="spinner_qM83 spinner_ZTLf" cx="20" cy="12" r="2.5" /></svg
>
{/if}
</div>
<div class=" self-center flex-1">
<div class=" font-semibold line-clamp-1">#{doc.name} ({doc.filename})</div>
<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
{doc.title}
</div>
</div>
</div>
</div>
<div class="flex flex-row space-x-1 self-center">
<button
class="self-center w-fit text-sm z-20 px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
type="button"
aria-label={$i18n.t('Edit Doc')}
on:click={async (e) => {
e.stopPropagation();
showEditDocModal = !showEditDocModal;
selectedDoc = doc;
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
/>
</svg>
</button>
<!-- <button
class="self-center w-fit text-sm px-2 py-2 border dark:border-gray-600 rounded-xl"
type="button"
on:click={() => {
console.log('download file');
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
d="M8.75 2.75a.75.75 0 0 0-1.5 0v5.69L5.03 6.22a.75.75 0 0 0-1.06 1.06l3.5 3.5a.75.75 0 0 0 1.06 0l3.5-3.5a.75.75 0 0 0-1.06-1.06L8.75 8.44V2.75Z"
/>
<path
d="M3.5 9.75a.75.75 0 0 0-1.5 0v1.5A2.75 2.75 0 0 0 4.75 14h6.5A2.75 2.75 0 0 0 14 11.25v-1.5a.75.75 0 0 0-1.5 0v1.5c0 .69-.56 1.25-1.25 1.25h-6.5c-.69 0-1.25-.56-1.25-1.25v-1.5Z"
/>
</svg>
</button> -->
<button
class="self-center w-fit text-sm px-2 py-2 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
type="button"
aria-label={$i18n.t('Delete Doc')}
on:click={(e) => {
e.stopPropagation();
deleteDoc(doc.name);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
/>
</svg>
</button>
</div>
</button>
{/each}
</div>
<div class=" text-gray-500 text-xs mt-1 mb-2">
{$i18n.t("Use '#' in the prompt input to load and select your documents.")}
</div>
<div class=" flex justify-end w-full mb-2">
<div class="flex space-x-2">
<input
id="documents-import-input"
bind:this={documentsImportInputElement}
bind:files={importFiles}
type="file"
accept=".json"
hidden
on:change={() => {
console.log(importFiles);
const reader = new FileReader();
reader.onload = async (event) => {
const savedDocs = JSON.parse(event.target.result);
console.log(savedDocs);
for (const doc of savedDocs) {
await createNewDoc(
localStorage.token,
doc.collection_name,
doc.filename,
doc.name,
doc.title,
doc.content
).catch((error) => {
toast.error(error);
return null;
});
}
await documents.set(await getDocs(localStorage.token));
};
reader.readAsText(importFiles[0]);
}}
/>
<button
class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-200 transition"
on:click={() => {
documentsImportInputElement.click();
}}
>
<div class=" self-center mr-2 font-medium line-clamp-1">
{$i18n.t('Import Documents Mapping')}
</div>
<div class=" self-center">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M4 2a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 4 14h8a1.5 1.5 0 0 0 1.5-1.5V6.621a1.5 1.5 0 0 0-.44-1.06L9.94 2.439A1.5 1.5 0 0 0 8.878 2H4Zm4 9.5a.75.75 0 0 1-.75-.75V8.06l-.72.72a.75.75 0 0 1-1.06-1.06l2-2a.75.75 0 0 1 1.06 0l2 2a.75.75 0 1 1-1.06 1.06l-.72-.72v2.69a.75.75 0 0 1-.75.75Z"
clip-rule="evenodd"
/>
</svg>
</div>
</button>
<button
class="flex text-xs items-center space-x-1 px-3 py-1.5 rounded-xl bg-gray-50 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-200 transition"
on:click={async () => {
let blob = new Blob([JSON.stringify($documents)], {
type: 'application/json'
});
saveAs(blob, `documents-mapping-export-${Date.now()}.json`);
}}
>
<div class=" self-center mr-2 font-medium line-clamp-1">
{$i18n.t('Export Documents Mapping')}
</div>
<div class=" self-center">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M4 2a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 4 14h8a1.5 1.5 0 0 0 1.5-1.5V6.621a1.5 1.5 0 0 0-.44-1.06L9.94 2.439A1.5 1.5 0 0 0 8.878 2H4Zm4 3.5a.75.75 0 0 1 .75.75v2.69l.72-.72a.75.75 0 1 1 1.06 1.06l-2 2a.75.75 0 0 1-1.06 0l-2-2a.75.75 0 0 1 1.06-1.06l.72.72V6.25A.75.75 0 0 1 8 5.5Z"
clip-rule="evenodd"
/>
</svg>
</div>
</button>
</div>
</div>

View File

@@ -181,7 +181,8 @@
{/if}
</div>
<div class=" text-xs text-gray-500">
Updated {dayjs(item.updated_at * 1000).fromNow()}
{$i18n.t('Updated')}
{dayjs(item.updated_at * 1000).fromNow()}
</div>
</div>
</div>

View File

@@ -1,6 +1,7 @@
<script lang="ts">
import Fuse from 'fuse.js';
import { toast } from 'svelte-sonner';
import { v4 as uuidv4 } from 'uuid';
import { onMount, getContext, onDestroy, tick } from 'svelte';
const i18n = getContext('i18n');
@@ -101,6 +102,7 @@
const uploadFileHandler = async (file) => {
console.log(file);
const tempItemId = uuidv4();
const fileItem = {
type: 'file',
file: '',
@@ -109,7 +111,8 @@
name: file.name,
size: file.size,
status: 'uploading',
error: ''
error: '',
itemId: tempItemId
};
knowledge.files = [...(knowledge.files ?? []), fileItem];
@@ -131,10 +134,20 @@
try {
const uploadedFile = await uploadFile(localStorage.token, file).catch((e) => {
toast.error(e);
return null;
});
if (uploadedFile) {
console.log(uploadedFile);
knowledge.files = knowledge.files.map((item) => {
if (item.itemId === tempItemId) {
item.id = uploadedFile.id;
}
// Remove temporary item id
delete item.itemId;
return item;
});
await addFileHandler(uploadedFile.id);
} else {
toast.error($i18n.t('Failed to upload file.'));
@@ -329,12 +342,16 @@
const updatedKnowledge = await addFileToKnowledgeById(localStorage.token, id, fileId).catch(
(e) => {
toast.error(e);
return null;
}
);
if (updatedKnowledge) {
knowledge = updatedKnowledge;
toast.success($i18n.t('File added successfully.'));
} else {
toast.error($i18n.t('Failed to add file.'));
knowledge.files = knowledge.files.filter((file) => file.id !== fileId);
}
};
@@ -517,10 +534,10 @@
type="file"
multiple
hidden
on:change={() => {
on:change={async () => {
if (inputFiles && inputFiles.length > 0) {
for (const file of inputFiles) {
uploadFileHandler(file);
await uploadFileHandler(file);
}
inputFiles = null;
@@ -536,65 +553,38 @@
/>
<div class="flex flex-col w-full max-h-[100dvh] h-full">
<button
class="flex space-x-1 w-fit"
on:click={() => {
goto('/workspace/knowledge');
}}
>
<div class=" self-center">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M17 10a.75.75 0 01-.75.75H5.612l4.158 3.96a.75.75 0 11-1.04 1.08l-5.5-5.25a.75.75 0 010-1.08l5.5-5.25a.75.75 0 111.04 1.08L5.612 9.25H16.25A.75.75 0 0117 10z"
clip-rule="evenodd"
/>
</svg>
</div>
<div class=" self-center font-medium text-sm">{$i18n.t('Back')}</div>
</button>
<div class="flex items-center justify-between">
<button
class="flex space-x-1 w-fit"
on:click={() => {
goto('/workspace/knowledge');
}}
>
<div class=" self-center">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M17 10a.75.75 0 01-.75.75H5.612l4.158 3.96a.75.75 0 11-1.04 1.08l-5.5-5.25a.75.75 0 010-1.08l5.5-5.25a.75.75 0 111.04 1.08L5.612 9.25H16.25A.75.75 0 0117 10z"
clip-rule="evenodd"
/>
</svg>
</div>
<div class=" self-center font-medium text-sm">{$i18n.t('Back')}</div>
</button>
<div class=" flex-shrink-0">
<div>
<Badge type="success" content="Collection" />
</div>
</div>
</div>
<div class="flex flex-col my-2 flex-1 overflow-auto h-0">
{#if id && knowledge}
<div class=" flex w-full mt-1 mb-3.5">
<div class="flex-1">
<div class="flex items-center justify-between w-full px-0.5 mb-1">
<div class="w-full">
<input
type="text"
class="w-full font-medium text-2xl font-primary bg-transparent outline-none"
bind:value={knowledge.name}
on:input={() => {
changeDebounceHandler();
}}
/>
</div>
<div class=" flex-shrink-0">
<div>
<Badge type="success" content="Collection" />
</div>
</div>
</div>
<div class="flex w-full px-1">
<input
type="text"
class="w-full text-gray-500 text-sm bg-transparent outline-none"
bind:value={knowledge.description}
on:input={() => {
changeDebounceHandler();
}}
/>
</div>
</div>
</div>
<div class="flex flex-row h-0 flex-1 overflow-auto">
<div
class=" {largeScreen
@@ -623,6 +613,9 @@
class=" w-full text-sm pr-4 py-1 rounded-r-xl outline-none bg-transparent"
bind:value={query}
placeholder={$i18n.t('Search Collection')}
on:focus={() => {
selectedFileId = null;
}}
/>
<div>
@@ -652,7 +645,7 @@
files={filteredItems}
{selectedFileId}
on:click={(e) => {
selectedFileId = e.detail;
selectedFileId = selectedFileId === e.detail ? null : e.detail;
}}
on:delete={(e) => {
console.log(e.detail);
@@ -663,7 +656,7 @@
/>
</div>
{:else}
<div class="m-auto text-gray-500 text-xs">No content found</div>
<div class="m-auto text-gray-500 text-xs">{$i18n.t('No content found')}</div>
{/if}
</div>
</div>
@@ -699,12 +692,40 @@
</div>
</div>
{:else}
<div class="m-auto">
<AddFilesPlaceholder title={$i18n.t('Select/Add Files')}>
<div class=" mt-2 text-center text-sm dark:text-gray-200 w-full">
Select a file to view or drag and drop a file to upload
<div class="m-auto pb-32">
<div>
<div class=" flex w-full mt-1 mb-3.5">
<div class="flex-1">
<div class="flex items-center justify-between w-full px-0.5 mb-1">
<div class="w-full">
<input
type="text"
class="text-center w-full font-medium text-3xl font-primary bg-transparent outline-none"
bind:value={knowledge.name}
on:input={() => {
changeDebounceHandler();
}}
/>
</div>
</div>
<div class="flex w-full px-1">
<input
type="text"
class="text-center w-full text-gray-500 bg-transparent outline-none"
bind:value={knowledge.description}
on:input={() => {
changeDebounceHandler();
}}
/>
</div>
</div>
</div>
</AddFilesPlaceholder>
</div>
<div class=" mt-2 text-center text-sm text-gray-200 dark:text-gray-700 w-full">
{$i18n.t('Select a file to view or drag and drop a file to upload')}
</div>
</div>
{/if}
</div>

View File

@@ -59,7 +59,7 @@
<div class="mb-3 w-full">
<div class="w-full flex flex-col gap-2.5">
<div class="w-full">
<div class=" text-sm mb-2">Title</div>
<div class=" text-sm mb-2">{$i18n.t('Title')}</div>
<div class="w-full mt-1">
<input
@@ -73,7 +73,7 @@
</div>
<div>
<div class="text-sm mb-2">Content</div>
<div class="text-sm mb-2">{$i18n.t('Content')}</div>
<div class=" w-full mt-1">
<textarea

View File

@@ -414,7 +414,9 @@
<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1 text-gray-500">
{!!model?.info?.meta?.description
? model?.info?.meta?.description
: (model?.ollama?.digest ?? model.id)}
: model?.ollama?.digest
? `${model.id} (${model?.ollama?.digest})`
: model.id}
</div>
</div>
</a>

View File

@@ -294,6 +294,7 @@
"Export Prompts": "مطالبات التصدير",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "فشل في إنشاء مفتاح API.",
"Failed to read clipboard contents": "فشل في قراءة محتويات الحافظة",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "قم بتسمية النموذج الخاص بك",
"New Chat": "دردشة جديدة",
"New Password": "كلمة المرور الجديدة",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -592,6 +594,7 @@
"Seed": "Seed",
"Select a base model": "حدد نموذجا أساسيا",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "أختار الموديل",
"Select a pipeline": "حدد مسارا",
@@ -602,7 +605,6 @@
"Select Knowledge": "",
"Select model": " أختار موديل",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "النموذج (النماذج) المحددة لا تدعم مدخلات الصور",
"Send": "تم",
"Send a Message": "يُرجى إدخال طلبك هنا",
@@ -730,6 +732,7 @@
"Update and Copy Link": "تحديث ونسخ الرابط",
"Update for the latest features and improvements.": "",
"Update password": "تحديث كلمة المرور",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "GGUF رفع موديل نوع",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Експортване на промптове",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "Неуспешно създаване на API ключ.",
"Failed to read clipboard contents": "Грешка при четене на съдържанието от клипборда",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "Дайте име на вашия модел",
"New Chat": "Нов чат",
"New Password": "Нова парола",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Seed",
"Select a base model": "Изберете базов модел",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Изберете модел",
"Select a pipeline": "Изберете тръбопровод",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "Изберете модел",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Избраният(те) модел(и) не поддържа въвеждане на изображения",
"Send": "Изпрати",
"Send a Message": "Изпращане на Съобщение",
@@ -726,6 +728,7 @@
"Update and Copy Link": "Обнови и копирай връзка",
"Update for the latest features and improvements.": "",
"Update password": "Обновяване на парола",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Качване на GGUF модел",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "প্রম্পটগুলো একপোর্ট করুন",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "API Key তৈরি করা যায়নি।",
"Failed to read clipboard contents": "ক্লিপবোর্ডের বিষয়বস্তু পড়া সম্ভব হয়নি",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "আপনার মডেলের নাম দিন",
"New Chat": "নতুন চ্যাট",
"New Password": "নতুন পাসওয়ার্ড",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "সীড",
"Select a base model": "একটি বেস মডেল নির্বাচন করুন",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "একটি মডেল নির্বাচন করুন",
"Select a pipeline": "একটি পাইপলাইন নির্বাচন করুন",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "মডেল নির্বাচন করুন",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "নির্বাচিত মডেল(গুলি) চিত্র ইনপুট সমর্থন করে না",
"Send": "পাঠান",
"Send a Message": "একটি মেসেজ পাঠান",
@@ -726,6 +728,7 @@
"Update and Copy Link": "আপডেট এবং লিংক কপি করুন",
"Update for the latest features and improvements.": "",
"Update password": "পাসওয়ার্ড আপডেট করুন",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "একটি GGUF মডেল আপলোড করুন",

View File

@@ -68,8 +68,8 @@
"Archived Chats": "Xats arxivats",
"are allowed - Activate this command by typing": "estan permesos - Activa aquesta comanda escrivint",
"Are you sure?": "Estàs segur?",
"Artifacts": "",
"Ask a question": "",
"Artifacts": "Artefactes",
"Ask a question": "Fer una pregunta",
"Attach file": "Adjuntar arxiu",
"Attention to detail": "Atenció al detall",
"Audio": "Àudio",
@@ -294,6 +294,7 @@
"Export Prompts": "Exportar les indicacions",
"Export Tools": "Exportar les eines",
"External Models": "Models externs",
"Failed to add file.": "",
"Failed to create API Key.": "No s'ha pogut crear la clau API.",
"Failed to read clipboard contents": "No s'ha pogut llegir el contingut del porta-retalls",
"Failed to update settings": "No s'han pogut actualitzar les preferències",
@@ -382,9 +383,9 @@
"Knowledge": "Coneixement",
"Knowledge created successfully.": "Coneixement creat correctament.",
"Knowledge deleted successfully.": "Coneixement eliminat correctament.",
"Knowledge reset successfully.": "",
"Knowledge reset successfully.": "Coneixement restablert correctament.",
"Knowledge updated successfully": "Coneixement actualitzat correctament.",
"Landing Page Mode": "",
"Landing Page Mode": "Mode de la pàgina d'entrada",
"Language": "Idioma",
"large language models, locally.": "models de llenguatge extensos, localment",
"Last Active": "Activitat recent",
@@ -449,9 +450,10 @@
"Name your model": "Posa un nom al teu model",
"New Chat": "Nou xat",
"New Password": "Nova contrasenya",
"No content found": "",
"No content to speak": "No hi ha contingut per parlar",
"No file selected": "No s'ha escollit cap fitxer",
"No HTML, CSS, or JavaScript content found.": "",
"No HTML, CSS, or JavaScript content found.": "No s'ha trobat contingut HTML, CSS o JavaScript.",
"No knowledge found": "No s'ha trobat Coneixement",
"No results found": "No s'han trobat resultats",
"No search query generated": "No s'ha generat cap consulta",
@@ -483,7 +485,7 @@
"Oops! There was an error in the previous response. Please try again or contact admin.": "Ui! Hi ha hagut un error en la resposta anterior. Torna a provar-ho o contacta amb un administrador",
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Ui! Estàs utilitzant un mètode no suportat (només frontend). Si us plau, serveix la WebUI des del backend.",
"Open file": "Obrir arxiu",
"Open in full screen": "",
"Open in full screen": "Obrir en pantalla complerta",
"Open new chat": "Obre un xat nou",
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "La versió d'Open WebUI (v{{OPEN_WEBUI_VERSION}}) és inferior a la versió requerida (v{{REQUIRED_VERSION}})",
"OpenAI": "OpenAI",
@@ -514,7 +516,7 @@
"Plain text (.txt)": "Text pla (.txt)",
"Playground": "Zona de jocs",
"Please carefully review the following warnings:": "Si us plau, revisa els següents avisos amb cura:",
"Please fill in all fields.": "",
"Please fill in all fields.": "Emplena tots els camps, si us plau.",
"Please select a reason": "Si us plau, selecciona una raó",
"Positive attitude": "Actitud positiva",
"Previous 30 days": "30 dies anteriors",
@@ -561,7 +563,7 @@
"Save & Update": "Desar i actualitzar",
"Save As Copy": "Desar com a còpia",
"Save Tag": "Desar l'etiqueta",
"Saved": "",
"Saved": "Desat",
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Desar els registres de xat directament a l'emmagatzematge del teu navegador ja no està suportat. Si us plau, descarregr i elimina els registres de xat fent clic al botó de sota. No et preocupis, pots tornar a importar fàcilment els teus registres de xat al backend a través de",
"Scroll to bottom when switching between branches": "Desplaçar a la part inferior quan es canviï de branca",
"Search": "Cercar",
@@ -589,6 +591,7 @@
"Seed": "Llavor",
"Select a base model": "Seleccionar un model base",
"Select a engine": "Seleccionar un motor",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Seleccionar una funció",
"Select a model": "Seleccionar un model",
"Select a pipeline": "Seleccionar una Pipeline",
@@ -599,7 +602,6 @@
"Select Knowledge": "Seleccionar coneixement",
"Select model": "Seleccionar un model",
"Select only one model to call": "Seleccionar només un model per trucar",
"Select/Add Files": "Seleccionar/Afegir arxius",
"Selected model(s) do not support image inputs": "El(s) model(s) seleccionats no admeten l'entrada d'imatges",
"Send": "Enviar",
"Send a Message": "Enviar un missatge",
@@ -634,11 +636,11 @@
"Show your support!": "Mostra el teu suport!",
"Showcased creativity": "Creativitat mostrada",
"Sign in": "Iniciar sessió",
"Sign in to {{WEBUI_NAME}}": "",
"Sign in to {{WEBUI_NAME}}": "Iniciar sessió a {{WEBUI_NAME}}",
"Sign Out": "Tancar sessió",
"Sign up": "Registrar-se",
"Sign up to {{WEBUI_NAME}}": "",
"Signing in to {{WEBUI_NAME}}": "",
"Sign up to {{WEBUI_NAME}}": "Registrar-se a {{WEBUI_NAME}}",
"Signing in to {{WEBUI_NAME}}": "Iniciant sessió a {{WEBUI_NAME}}",
"Source": "Font",
"Speech Playback Speed": "Velocitat de la parla",
"Speech recognition error: {{error}}": "Error de reconeixement de veu: {{error}}",
@@ -654,7 +656,7 @@
"Suggested": "Suggerit",
"Support": "Dona suport",
"Support this plugin:": "Dona suport a aquest complement:",
"Sync directory": "",
"Sync directory": "Sincronitzar directori",
"System": "Sistema",
"System Prompt": "Indicació del Sistema",
"Tags": "Etiquetes",
@@ -677,9 +679,9 @@
"This action cannot be undone. Do you wish to continue?": "Aquesta acció no es pot desfer. Vols continuar?",
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Això assegura que les teves converses valuoses queden desades de manera segura a la teva base de dades. Gràcies!",
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "Aquesta és una funció experimental, és possible que no funcioni com s'espera i està subjecta a canvis en qualsevol moment.",
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "",
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "Aquesta opció eliminarà tots els fitxers existents de la col·lecció i els substituirà per fitxers recentment penjats.",
"This will delete": "Això eliminarà",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Això restablirà la base de coneixement i sincronitzarà tots els fitxers. Vols continuar?",
"Thorough explanation": "Explicació en detall",
"Tika": "Tika",
"Tika Server URL required.": "La URL del servidor Tika és obligatòria.",
@@ -727,10 +729,11 @@
"Update and Copy Link": "Actualitzar i copiar l'enllaç",
"Update for the latest features and improvements.": "Actualitza per a les darreres característiques i millores.",
"Update password": "Actualitzar la contrasenya",
"Updated": "",
"Updated at": "Actualitzat",
"Upload": "Pujar",
"Upload a GGUF model": "Pujar un model GGUF",
"Upload directory": "",
"Upload directory": "Pujar directori",
"Upload files": "Pujar fitxers",
"Upload Files": "Pujar fitxers",
"Upload Pipeline": "Pujar una Pipeline",
@@ -754,7 +757,7 @@
"variable": "variable",
"variable to have them replaced with clipboard content.": "variable per tenir-les reemplaçades amb el contingut del porta-retalls.",
"Version": "Versió",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"Version {{selectedVersion}} of {{totalVersions}}": "Versió {{selectedVersion}} de {{totalVersions}}",
"Voice": "Veu",
"Warning": "Avís",
"Warning:": "Avís:",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Export prompts",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "",
"Failed to read clipboard contents": "Napakyas sa pagbasa sa sulod sa clipboard",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "",
"New Chat": "Bag-ong diskusyon",
"New Password": "Bag-ong Password",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Binhi",
"Select a base model": "",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Pagpili og modelo",
"Select a pipeline": "",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "Pagpili og modelo",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "",
"Send": "",
"Send a Message": "Magpadala ug mensahe",
@@ -726,6 +728,7 @@
"Update and Copy Link": "",
"Update for the latest features and improvements.": "",
"Update password": "I-update ang password",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Pag-upload ug modelo sa GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Prompts exportieren",
"Export Tools": "Werkzeuge exportieren",
"External Models": "Externe Modelle",
"Failed to add file.": "",
"Failed to create API Key.": "Fehler beim Erstellen des API-Schlüssels.",
"Failed to read clipboard contents": "Fehler beim Abruf der Zwischenablage",
"Failed to update settings": "Fehler beim Aktualisieren der Einstellungen",
@@ -450,6 +451,7 @@
"Name your model": "Benennen Sie Ihr Modell",
"New Chat": "Neue Unterhaltung",
"New Password": "Neues Passwort",
"No content found": "",
"No content to speak": "Kein Inhalt zum Vorlesen",
"No file selected": "Keine Datei ausgewählt",
"No HTML, CSS, or JavaScript content found.": "",
@@ -589,6 +591,7 @@
"Seed": "Seed",
"Select a base model": "Wählen Sie ein Basismodell",
"Select a engine": "Wählen Sie eine Engine",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Wählen Sie eine Funktion",
"Select a model": "Wählen Sie ein Modell",
"Select a pipeline": "Wählen Sie eine Pipeline",
@@ -599,7 +602,6 @@
"Select Knowledge": "",
"Select model": "Modell auswählen",
"Select only one model to call": "Wählen Sie nur ein Modell zum Anrufen aus",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Ihre ausgewählten Modelle unterstützen keine Bildeingaben",
"Send": "Senden",
"Send a Message": "Eine Nachricht senden",
@@ -727,6 +729,7 @@
"Update and Copy Link": "Aktualisieren und Link kopieren",
"Update for the latest features and improvements.": "",
"Update password": "Passwort aktualisieren",
"Updated": "",
"Updated at": "Aktualisiert am",
"Upload": "Hochladen",
"Upload a GGUF model": "GGUF-Model hochladen",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Export Promptos",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "",
"Failed to read clipboard contents": "Failed to read clipboard borks",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "",
"New Chat": "New Bark",
"New Password": "New Barkword",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -590,6 +592,7 @@
"Seed": "Seed very plant",
"Select a base model": "",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Select a model much choice",
"Select a pipeline": "",
@@ -600,7 +603,6 @@
"Select Knowledge": "",
"Select model": "Select model much choice",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "",
"Send": "",
"Send a Message": "Send a Message much message",
@@ -728,6 +730,7 @@
"Update and Copy Link": "",
"Update for the latest features and improvements.": "",
"Update password": "Update password much change",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Upload a GGUF model very upload",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "",
"Failed to read clipboard contents": "",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "",
"New Chat": "",
"New Password": "",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "",
"Select a base model": "",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "",
"Select a pipeline": "",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "",
"Send": "",
"Send a Message": "",
@@ -726,6 +728,7 @@
"Update and Copy Link": "",
"Update for the latest features and improvements.": "",
"Update password": "",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "",
"Failed to read clipboard contents": "",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "",
"New Chat": "",
"New Password": "",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "",
"Select a base model": "",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "",
"Select a pipeline": "",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "",
"Send": "",
"Send a Message": "",
@@ -726,6 +728,7 @@
"Update and Copy Link": "",
"Update for the latest features and improvements.": "",
"Update password": "",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "",

View File

@@ -1,14 +1,14 @@
{
"'s', 'm', 'h', 'd', 'w' or '-1' for no expiration.": "'s', 'm', 'h', 'd', 'w' o '-1' para evitar expiración.",
"(Beta)": "(Beta)",
"(e.g. `sh webui.sh --api --api-auth username_password`)": "",
"(e.g. `sh webui.sh --api --api-auth username_password`)": "(p.ej. `sh webui.sh --api --api-auth username_password`)",
"(e.g. `sh webui.sh --api`)": "(p.ej. `sh webui.sh --api`)",
"(latest)": "(latest)",
"{{ models }}": "{{ models }}",
"{{ owner }}: You cannot delete a base model": "{{ owner }}: No se puede eliminar un modelo base",
"{{user}}'s Chats": "{{user}}'s Chats",
"{{user}}'s Chats": "Chats de {{user}}",
"{{webUIName}} Backend Required": "{{webUIName}} Servidor Requerido",
"*Prompt node ID(s) are required for image generation": "",
"*Prompt node ID(s) are required for image generation": "Los ID de nodo son requeridos para la generación de imágenes",
"A new version (v{{LATEST_VERSION}}) is now available.": "",
"A task model is used when performing tasks such as generating titles for chats and web search queries": "Un modelo de tareas se utiliza cuando se realizan tareas como la generación de títulos para chats y consultas de búsqueda web",
"a user": "un usuario",
@@ -16,24 +16,24 @@
"Account": "Cuenta",
"Account Activation Pending": "Activación de cuenta pendiente",
"Accurate information": "Información precisa",
"Actions": "",
"Actions": "Acciones",
"Active Users": "Usuarios activos",
"Add": "Agregar",
"Add a model id": "Adición de un identificador de modelo",
"Add a short description about what this model does": "Agregue una breve descripción sobre lo que hace este modelo",
"Add a short title for this prompt": "Agregue un título corto para este Prompt",
"Add a tag": "Agregar una etiqueta",
"Add Content": "",
"Add content here": "",
"Add Content": "Agregar Contenido",
"Add content here": "Agrege contenido aquí",
"Add custom prompt": "Agregar un prompt personalizado",
"Add Docs": "Agregar Documentos",
"Add Files": "Agregar Archivos",
"Add Memory": "Agregar Memoria",
"Add message": "Agregar Prompt",
"Add message": "Agregar mensaje",
"Add Model": "Agregar Modelo",
"Add Tag": "",
"Add Tag": "Agregar etiqueta",
"Add Tags": "agregar etiquetas",
"Add text content": "",
"Add text content": "Añade contenido de texto",
"Add User": "Agregar Usuario",
"Adjusting these settings will apply changes universally to all users.": "Ajustar estas opciones aplicará los cambios universalmente a todos los usuarios.",
"admin": "admin",
@@ -48,9 +48,9 @@
"All Users": "Todos los Usuarios",
"Allow": "Permitir",
"Allow Chat Deletion": "Permitir Borrar Chats",
"Allow Chat Editing": "",
"Allow Chat Editing": "Permitir Editar Chat",
"Allow non-local voices": "Permitir voces no locales",
"Allow Temporary Chat": "",
"Allow Temporary Chat": "Permitir Chat Temporal",
"Allow User Location": "Permitir Ubicación del Usuario",
"Allow Voice Interruption in Call": "Permitir interrupción de voz en llamada",
"alphanumeric characters and hyphens": "caracteres alfanuméricos y guiones",
@@ -68,21 +68,21 @@
"Archived Chats": "Chats archivados",
"are allowed - Activate this command by typing": "están permitidos - Active este comando escribiendo",
"Are you sure?": "¿Está seguro?",
"Artifacts": "",
"Ask a question": "",
"Artifacts": "Artefactos",
"Ask a question": "Haz una pregunta",
"Attach file": "Adjuntar archivo",
"Attention to detail": "Detalle preciso",
"Audio": "Audio",
"August": "Agosto",
"Auto-playback response": "Respuesta de reproducción automática",
"Automatic1111": "",
"AUTOMATIC1111 Api Auth String": "",
"AUTOMATIC1111 Api Auth String": "Cadena de autenticación de API",
"AUTOMATIC1111 Base URL": "Dirección URL de AUTOMATIC1111",
"AUTOMATIC1111 Base URL is required.": "La dirección URL de AUTOMATIC1111 es requerida.",
"Available list": "",
"Available list": "Lista disponible",
"available!": "¡disponible!",
"Azure AI Speech": "",
"Azure Region": "",
"Azure Region": "Región de Azure",
"Back": "Volver",
"Bad Response": "Respuesta incorrecta",
"Banners": "Banners",
@@ -101,9 +101,9 @@
"Chat": "Chat",
"Chat Background Image": "Imágen de fondo del Chat",
"Chat Bubble UI": "Burbuja de chat UI",
"Chat Controls": "",
"Chat Controls": "Controles de chat",
"Chat direction": "Dirección del Chat",
"Chat Overview": "",
"Chat Overview": "Vista general del chat",
"Chats": "Chats",
"Check Again": "Verifica de nuevo",
"Check for updates": "Verificar actualizaciones",
@@ -121,7 +121,7 @@
"Click here to select a csv file.": "Presiona aquí para seleccionar un archivo csv.",
"Click here to select a py file.": "Presiona aquí para seleccionar un archivo py.",
"Click here to select documents.": "Presiona aquí para seleccionar documentos",
"Click here to upload a workflow.json file.": "",
"Click here to upload a workflow.json file.": "Presiona aquí para subir un archivo workflow.json.",
"click here.": "Presiona aquí.",
"Click on the user role button to change a user's role.": "Presiona en el botón de roles del usuario para cambiar su rol.",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "Permisos de escritura del portapapeles denegados. Por favor, comprueba las configuraciones de tu navegador para otorgar el acceso necesario.",
@@ -133,7 +133,7 @@
"ComfyUI Base URL": "ComfyUI Base URL",
"ComfyUI Base URL is required.": "ComfyUI Base URL es requerido.",
"ComfyUI Workflow": "",
"ComfyUI Workflow Nodes": "",
"ComfyUI Workflow Nodes": "Nodos para ComfyUI Workflow",
"Command": "Comando",
"Concurrent Requests": "Solicitudes simultáneas",
"Confirm": "Confirmar",
@@ -142,15 +142,15 @@
"Connections": "Conexiones",
"Contact Admin for WebUI Access": "Contacta el administrador para obtener acceso al WebUI",
"Content": "Contenido",
"Content Extraction": "",
"Content Extraction": "Extracción de contenido",
"Context Length": "Longitud del contexto",
"Continue Response": "Continuar Respuesta",
"Continue with {{provider}}": "Continuar con {{provider}}",
"Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "",
"Controls": "",
"Copied": "",
"Controls": "Controles",
"Copied": "Copiado",
"Copied shared chat URL to clipboard!": "¡URL de chat compartido copiado al portapapeles!",
"Copied to clipboard": "",
"Copied to clipboard": "Copiado al portapapeles",
"Copy": "Copiar",
"Copy last code block": "Copia el último bloque de código",
"Copy last response": "Copia la última respuesta",
@@ -158,7 +158,7 @@
"Copying to clipboard was successful!": "¡La copia al portapapeles se ha realizado correctamente!",
"Create a model": "Crear un modelo",
"Create Account": "Crear una cuenta",
"Create Knowledge": "",
"Create Knowledge": "Crear Conocimiento",
"Create new key": "Crear una nueva clave",
"Create new secret key": "Crear una nueva clave secreta",
"Created at": "Creado en",
@@ -174,8 +174,8 @@
"Database": "Base de datos",
"December": "Diciembre",
"Default": "Por defecto",
"Default (Open AI)": "",
"Default (SentenceTransformers)": "Por defecto (SentenceTransformers)",
"Default (Open AI)": "Predeterminado (Open AI)",
"Default (SentenceTransformers)": "Predeterminado (SentenceTransformers)",
"Default Model": "Modelo predeterminado",
"Default model updated": "El modelo por defecto ha sido actualizado",
"Default Prompt Suggestions": "Sugerencias de mensajes por defecto",
@@ -187,17 +187,17 @@
"Delete chat": "Borrar chat",
"Delete Chat": "Borrar Chat",
"Delete chat?": "Borrar el chat?",
"Delete Doc": "",
"Delete function?": "",
"Delete prompt?": "",
"Delete Doc": "Borrar Doc",
"Delete function?": "Borrar la función?",
"Delete prompt?": "Borrar el prompt?",
"delete this link": "Borrar este enlace",
"Delete tool?": "",
"Delete tool?": "Borrar la herramienta",
"Delete User": "Borrar Usuario",
"Deleted {{deleteModelTag}}": "Se borró {{deleteModelTag}}",
"Deleted {{name}}": "Eliminado {{nombre}}",
"Description": "Descripción",
"Didn't fully follow instructions": "No siguió las instrucciones",
"Disabled": "",
"Disabled": "Desactivado",
"Discover a function": "Descubre una función",
"Discover a model": "Descubrir un modelo",
"Discover a prompt": "Descubre un Prompt",
@@ -209,16 +209,16 @@
"Dismissible": "Desestimable",
"Display Emoji in Call": "Muestra Emoji en llamada",
"Display the username instead of You in the Chat": "Mostrar el nombre de usuario en lugar de Usted en el chat",
"Do not install functions from sources you do not fully trust.": "",
"Do not install tools from sources you do not fully trust.": "",
"Do not install functions from sources you do not fully trust.": "No instale funciones desde fuentes que no confíe totalmente.",
"Do not install tools from sources you do not fully trust.": "No instale herramientas desde fuentes que no confíe totalmente.",
"Document": "Documento",
"Documentation": "Documentación",
"Documents": "Documentos",
"does not make any external connections, and your data stays securely on your locally hosted server.": "no realiza ninguna conexión externa y sus datos permanecen seguros en su servidor alojado localmente.",
"Don't Allow": "No Permitir",
"Don't have an account?": "¿No tienes una cuenta?",
"don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "",
"don't install random functions from sources you don't trust.": "no instale funciones aleatorias desde fuentes que no confíe.",
"don't install random tools from sources you don't trust.": "no instale herramientas aleatorias desde fuentes que no confíe.",
"Don't like the style": "No te gusta el estilo?",
"Done": "Hecho",
"Download": "Descargar",
@@ -237,18 +237,18 @@
"Embedding Model Engine": "Motor de Modelo de Embedding",
"Embedding model set to \"{{embedding_model}}\"": "Modelo de Embedding configurado a \"{{embedding_model}}\"",
"Enable Community Sharing": "Habilitar el uso compartido de la comunidad",
"Enable Message Rating": "",
"Enable Message Rating": "Habilitar la calificación de los mensajes",
"Enable New Sign Ups": "Habilitar Nuevos Registros",
"Enable Web Search": "Habilitar la búsqueda web",
"Enable Web Search Query Generation": "",
"Enabled": "",
"Engine": "",
"Enable Web Search Query Generation": "Habilitar generación de consultas web",
"Enabled": "Activado",
"Engine": "Motor",
"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "Asegúrese de que su archivo CSV incluya 4 columnas en este orden: Nombre, Correo Electrónico, Contraseña, Rol.",
"Enter {{role}} message here": "Ingrese el mensaje {{role}} aquí",
"Enter a detail about yourself for your LLMs to recall": "Ingrese un detalle sobre usted para que sus LLMs recuerden",
"Enter api auth string (e.g. username:password)": "",
"Enter api auth string (e.g. username:password)": "Ingrese la cadena de autorización de api (p.ej., nombre:contraseña)",
"Enter Brave Search API Key": "Ingresa la clave de API de Brave Search",
"Enter CFG Scale (e.g. 7.0)": "",
"Enter CFG Scale (e.g. 7.0)": "Ingresa la escala de CFG (p.ej., 7.0)",
"Enter Chunk Overlap": "Ingresar superposición de fragmentos",
"Enter Chunk Size": "Ingrese el tamaño del fragmento",
"Enter Github Raw URL": "Ingresa la URL sin procesar de Github",
@@ -256,28 +256,28 @@
"Enter Google PSE Engine Id": "Introduzca el ID del motor PSE de Google",
"Enter Image Size (e.g. 512x512)": "Ingrese el tamaño de la imagen (p.ej. 512x512)",
"Enter language codes": "Ingrese códigos de idioma",
"Enter Model ID": "",
"Enter Model ID": "Ingresa el ID del modelo",
"Enter model tag (e.g. {{modelTag}})": "Ingrese la etiqueta del modelo (p.ej. {{modelTag}})",
"Enter Number of Steps (e.g. 50)": "Ingrese el número de pasos (p.ej., 50)",
"Enter Sampler (e.g. Euler a)": "",
"Enter Scheduler (e.g. Karras)": "",
"Enter Sampler (e.g. Euler a)": "Ingrese el sampler (p.ej., Euler a)",
"Enter Scheduler (e.g. Karras)": "Ingrese el planificador (p.ej., Karras)",
"Enter Score": "Ingrese la puntuación",
"Enter SearchApi API Key": "",
"Enter SearchApi Engine": "",
"Enter SearchApi API Key": "Ingrese la Clave API de SearchApi",
"Enter SearchApi Engine": "Ingrese el motor de SearchApi",
"Enter Searxng Query URL": "Introduzca la URL de consulta de Searxng",
"Enter Serper API Key": "Ingrese la clave API de Serper",
"Enter Serply API Key": "Ingrese la clave API de Serply",
"Enter Serpstack API Key": "Ingrese la clave API de Serpstack",
"Enter stop sequence": "Ingrese la secuencia de parada",
"Enter system prompt": "",
"Enter system prompt": "Ingrese el prompt del sistema",
"Enter Tavily API Key": "Ingrese la clave API de Tavily",
"Enter Tika Server URL": "",
"Enter Tika Server URL": "Ingrese la URL del servidor Tika",
"Enter Top K": "Ingrese el Top K",
"Enter URL (e.g. http://127.0.0.1:7860/)": "Ingrese la URL (p.ej., http://127.0.0.1:7860/)",
"Enter URL (e.g. http://localhost:11434)": "Ingrese la URL (p.ej., http://localhost:11434)",
"Enter Your Email": "Ingrese su correo electrónico",
"Enter Your Full Name": "Ingrese su nombre completo",
"Enter your message": "",
"Enter your message": "Ingrese su mensaje",
"Enter Your Password": "Ingrese su contraseña",
"Enter Your Role": "Ingrese su rol",
"Error": "Error",
@@ -294,22 +294,23 @@
"Export Prompts": "Exportar Prompts",
"Export Tools": "Exportar Herramientas",
"External Models": "Modelos Externos",
"Failed to create API Key.": "No se pudo crear la clave API.",
"Failed to add file.": "",
"Failed to create API Key.": "No se pudo crear la clave API.",
"Failed to read clipboard contents": "No se pudo leer el contenido del portapapeles",
"Failed to update settings": "Falla al actualizar los ajustes",
"Failed to upload file.": "",
"Failed to upload file.": "Falla al subir el archivo.",
"February": "Febrero",
"Feel free to add specific details": "Libre de agregar detalles específicos",
"File": "Archivo",
"File added successfully.": "",
"File content updated successfully.": "",
"File added successfully.": "Archivo agregado correctamente.",
"File content updated successfully.": "Contenido del archivo actualizado correctamente.",
"File Mode": "Modo de archivo",
"File not found.": "Archivo no encontrado.",
"File removed successfully.": "",
"File size should not exceed {{maxSize}} MB.": "",
"Files": "",
"Filter is now globally disabled": "",
"Filter is now globally enabled": "",
"File removed successfully.": "Archivo eliminado correctamente.",
"File size should not exceed {{maxSize}} MB.": "Tamaño del archivo no debe exceder {{maxSize}} MB.",
"Files": "Archivos",
"Filter is now globally disabled": "El filtro ahora está desactivado globalmente",
"Filter is now globally enabled": "El filtro ahora está habilitado globalmente",
"Filters": "Filtros",
"Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "Se detectó suplantación de huellas: No se pueden usar las iniciales como avatar. Por defecto se utiliza la imagen de perfil predeterminada.",
"Fluidly stream large external response chunks": "Transmita con fluidez grandes fragmentos de respuesta externa",
@@ -320,28 +321,28 @@
"Frequency Penalty": "Penalización de frecuencia",
"Function created successfully": "Función creada exitosamente",
"Function deleted successfully": "Función borrada exitosamente",
"Function Description (e.g. A filter to remove profanity from text)": "",
"Function ID (e.g. my_filter)": "",
"Function is now globally disabled": "",
"Function is now globally enabled": "",
"Function Name (e.g. My Filter)": "",
"Function Description (e.g. A filter to remove profanity from text)": "Descripción de la función (por ejemplo, un filtro para eliminar lo profano del texto)",
"Function ID (e.g. my_filter)": "ID de la función (por ejemplo, mi_filtro)",
"Function is now globally disabled": "La función ahora está desactivada globalmente",
"Function is now globally enabled": "La función está habilitada globalmente",
"Function Name (e.g. My Filter)": "Nombre de la función (por ejemplo, Mi filtro)",
"Function updated successfully": "Función actualizada exitosamente",
"Functions": "Funciones",
"Functions allow arbitrary code execution": "",
"Functions allow arbitrary code execution.": "",
"Functions allow arbitrary code execution": "Funciones habilitan la ejecución de código arbitrario",
"Functions allow arbitrary code execution.": "Funciones habilitan la ejecución de código arbitrario.",
"Functions imported successfully": "Funciones importadas exitosamente",
"General": "General",
"General Settings": "Opciones Generales",
"Generate Image": "Generar imagen",
"Generating search query": "Generación de consultas de búsqueda",
"Generation Info": "Información de Generación",
"Get up and running with": "",
"Global": "",
"Get up and running with": "Levanta y empieza con",
"Global": "Global",
"Good Response": "Buena Respuesta",
"Google PSE API Key": "Clave API de Google PSE",
"Google PSE Engine Id": "ID del motor PSE de Google",
"h:mm a": "h:mm a",
"Haptic Feedback": "",
"Haptic Feedback": "Retroalimentación háptica",
"has no conversations.": "no tiene conversaciones.",
"Hello, {{name}}": "Hola, {{name}}",
"Help": "Ayuda",
@@ -349,7 +350,7 @@
"Hide Model": "Esconder Modelo",
"How can I help you today?": "¿Cómo puedo ayudarte hoy?",
"Hybrid Search": "Búsqueda Híbrida",
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "",
"I acknowledge that I have read and I understand the implications of my action. I am aware of the risks associated with executing arbitrary code and I have verified the trustworthiness of the source.": "Aseguro que he leído y entiendo las implicaciones de mi acción. Estoy consciente de los riesgos asociados con la ejecución de código arbitrario y he verificado la confianza de la fuente.",
"Image Generation (Experimental)": "Generación de imágenes (experimental)",
"Image Generation Engine": "Motor de generación de imágenes",
"Image Settings": "Ajustes de la Imágen",
@@ -361,7 +362,7 @@
"Import Models": "Importar modelos",
"Import Prompts": "Importar Prompts",
"Import Tools": "Importar Herramientas",
"Include `--api-auth` flag when running stable-diffusion-webui": "",
"Include `--api-auth` flag when running stable-diffusion-webui": "Incluir el indicador `--api-auth` al ejecutar stable-diffusion-webui",
"Include `--api` flag when running stable-diffusion-webui": "Incluir el indicador `--api` al ejecutar stable-diffusion-webui",
"Info": "Información",
"Input commands": "Ingresar comandos",
@@ -380,17 +381,17 @@
"Keep Alive": "Mantener Vivo",
"Keyboard shortcuts": "Atajos de teclado",
"Knowledge": "Conocimiento",
"Knowledge created successfully.": "",
"Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "",
"Knowledge updated successfully": "",
"Landing Page Mode": "",
"Knowledge created successfully.": "Conocimiento creado exitosamente.",
"Knowledge deleted successfully.": "Conocimiento eliminado exitosamente.",
"Knowledge reset successfully.": "Conocimiento restablecido exitosamente.",
"Knowledge updated successfully": "Conocimiento actualizado exitosamente.",
"Landing Page Mode": "Modo de Página de Inicio",
"Language": "Lenguaje",
"large language models, locally.": "",
"large language models, locally.": "modelos de lenguaje grande, localmente",
"Last Active": "Última Actividad",
"Last Modified": "Modificado por última vez",
"Leave empty for unlimited": "",
"Leave empty to use the default prompt, or enter a custom prompt": "",
"Leave empty for unlimited": "Deje vacío para ilimitado",
"Leave empty to use the default prompt, or enter a custom prompt": "Deje vacío para usar el propmt predeterminado, o ingrese un propmt personalizado",
"Light": "Claro",
"Listening...": "Escuchando...",
"LLMs can make mistakes. Verify important information.": "Los LLM pueden cometer errores. Verifica la información importante.",
@@ -398,15 +399,15 @@
"LTR": "LTR",
"Made by OpenWebUI Community": "Hecho por la comunidad de OpenWebUI",
"Make sure to enclose them with": "Asegúrese de adjuntarlos con",
"Make sure to export a workflow.json file as API format from ComfyUI.": "",
"Make sure to export a workflow.json file as API format from ComfyUI.": "Asegúrese de exportar un archivo workflow.json en formato API desde ComfyUI.",
"Manage": "Gestionar",
"Manage Models": "Administrar Modelos",
"Manage Ollama Models": "Administrar Modelos Ollama",
"Manage Pipelines": "Administrar Pipelines",
"March": "Marzo",
"Max Tokens (num_predict)": "Máximo de fichas (num_predict)",
"Max Upload Count": "",
"Max Upload Size": "",
"Max Upload Count": "Cantidad máxima de cargas",
"Max Upload Size": "Tamaño máximo de Cargas",
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "Se pueden descargar un máximo de 3 modelos simultáneamente. Por favor, inténtelo de nuevo más tarde.",
"May": "Mayo",
"Memories accessible by LLMs will be shown here.": "Las memorias accesibles por los LLMs se mostrarán aquí.",
@@ -415,7 +416,7 @@
"Memory cleared successfully": "Memoria liberada correctamente",
"Memory deleted successfully": "Memoria borrada correctamente",
"Memory updated successfully": "Memoria actualizada correctamente",
"Merge Responses": "",
"Merge Responses": "Fusionar Respuestas",
"Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "Los mensajes que envíe después de crear su enlace no se compartirán. Los usuarios con el enlace podrán ver el chat compartido.",
"Min P": "",
"Minimum Score": "Puntuación mínima",
@@ -430,8 +431,8 @@
"Model {{modelId}} not found": "El modelo {{modelId}} no fue encontrado",
"Model {{modelName}} is not vision capable": "El modelo {{modelName}} no es capaz de ver",
"Model {{name}} is now {{status}}": "El modelo {{name}} ahora es {{status}}",
"Model {{name}} is now at the top": "",
"Model accepts image inputs": "",
"Model {{name}} is now at the top": "El modelo {{name}} está ahora en el tope",
"Model accepts image inputs": "El modelo acepta entradas de imagenes",
"Model created successfully!": "Modelo creado correctamente!",
"Model filesystem path detected. Model shortname is required for update, cannot continue.": "Se detectó la ruta del sistema de archivos del modelo. Se requiere el nombre corto del modelo para la actualización, no se puede continuar.",
"Model ID": "ID del modelo",
@@ -443,16 +444,17 @@
"Modelfile Content": "Contenido del Modelfile",
"Models": "Modelos",
"More": "Más",
"Move to Top": "",
"Move to Top": "Mueve al tope",
"Name": "Nombre",
"Name Tag": "Nombre de etiqueta",
"Name your model": "Asigne un nombre a su modelo",
"New Chat": "Nuevo Chat",
"New Password": "Nueva Contraseña",
"No content to speak": "No hay contenido para hablar",
"No content found": "",
"No content to speak": "No hay contenido para hablar",
"No file selected": "Ningún archivo fué seleccionado",
"No HTML, CSS, or JavaScript content found.": "",
"No knowledge found": "",
"No HTML, CSS, or JavaScript content found.": "No se encontró contenido HTML, CSS, o JavaScript.",
"No knowledge found": "No se encontró ningún conocimiento",
"No results found": "No se han encontrado resultados",
"No search query generated": "No se ha generado ninguna consulta de búsqueda",
"No source available": "No hay fuente disponible",
@@ -477,15 +479,15 @@
"On": "Activado",
"Only": "Solamente",
"Only alphanumeric characters and hyphens are allowed in the command string.": "Sólo se permiten caracteres alfanuméricos y guiones en la cadena de comando.",
"Only collections can be edited, create a new knowledge base to edit/add documents.": "",
"Only collections can be edited, create a new knowledge base to edit/add documents.": "Solo se pueden editar las colecciones, crear una nueva base de conocimientos para editar / añadir documentos",
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "¡Ups! ¡Agárrate fuerte! Tus archivos todavía están en el horno de procesamiento. Los estamos cocinando a la perfección. Tenga paciencia y le avisaremos una vez que estén listos.",
"Oops! Looks like the URL is invalid. Please double-check and try again.": "¡Ups! Parece que la URL no es válida. Vuelva a verificar e inténtelo nuevamente.",
"Oops! There was an error in the previous response. Please try again or contact admin.": "¡Oops! Hubo un error en la respuesta anterior. Intente de nuevo o póngase en contacto con el administrador.",
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "¡Ups! Estás utilizando un método no compatible (solo frontend). Por favor ejecute la WebUI desde el backend.",
"Open file": "",
"Open in full screen": "",
"Open file": "Abrir archivo",
"Open in full screen": "Abrir en pantalla completa",
"Open new chat": "Abrir nuevo chat",
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "",
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "La versión de Open WebUI (v{{OPEN_WEBUI_VERSION}}) es inferior a la versión requerida (v{{REQUIRED_VERSION}})",
"OpenAI": "OpenAI",
"OpenAI API": "OpenAI API",
"OpenAI API Config": "OpenAI API Config",
@@ -493,9 +495,9 @@
"OpenAI URL/Key required.": "URL/Clave de OpenAI es requerida.",
"or": "o",
"Other": "Otro",
"Output format": "",
"Overview": "",
"page": "",
"Output format": "Formato de salida",
"Overview": "Vista general",
"page": "página",
"Password": "Contraseña",
"PDF document (.pdf)": "PDF document (.pdf)",
"PDF Extract Images (OCR)": "Extraer imágenes de PDF (OCR)",
@@ -504,8 +506,8 @@
"Permission denied when accessing microphone": "Permiso denegado al acceder a la micrófono",
"Permission denied when accessing microphone: {{error}}": "Permiso denegado al acceder al micrófono: {{error}}",
"Personalization": "Personalización",
"Pin": "",
"Pinned": "",
"Pin": "Fijar",
"Pinned": "Fijado",
"Pipeline deleted successfully": "Pipeline borrada exitosamente",
"Pipeline downloaded successfully": "Pipeline descargada exitosamente",
"Pipelines": "Pipelines",
@@ -513,9 +515,9 @@
"Pipelines Valves": "Tuberías Válvulas",
"Plain text (.txt)": "Texto plano (.txt)",
"Playground": "Patio de juegos",
"Please carefully review the following warnings:": "",
"Please fill in all fields.": "",
"Please select a reason": "",
"Please carefully review the following warnings:": "Por favor revise con cuidado los siguientes avisos:",
"Please fill in all fields.": "Por favor llene todos los campos.",
"Please select a reason": "Por favor seleccione una razón",
"Positive attitude": "Actitud positiva",
"Previous 30 days": "Últimos 30 días",
"Previous 7 days": "Últimos 7 días",
@@ -548,76 +550,76 @@
"Reset Vector Storage": "Restablecer almacenamiento vectorial",
"Response AutoCopy to Clipboard": "Copiar respuesta automáticamente al portapapeles",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "Las notificaciones de respuesta no pueden activarse debido a que los permisos del sitio web han sido denegados. Por favor, visite las configuraciones de su navegador para otorgar el acceso necesario.",
"Response splitting": "",
"Response splitting": "División de respuestas",
"Role": "Rol",
"Rosé Pine": "Rosé Pine",
"Rosé Pine Dawn": "Rosé Pine Dawn",
"RTL": "RTL",
"Run": "",
"Run Llama 2, Code Llama, and other models. Customize and create your own.": "",
"Run": "Ejecutar",
"Run Llama 2, Code Llama, and other models. Customize and create your own.": "Correr Llama 2, Code Llama y otros modelos. Personalice y cree sus propios modelos.",
"Running": "Ejecutando",
"Save": "Guardar",
"Save & Create": "Guardar y Crear",
"Save & Update": "Guardar y Actualizar",
"Save As Copy": "",
"Save Tag": "",
"Saved": "",
"Save As Copy": "Guardar como copia",
"Save Tag": "Guardar etiqueta",
"Saved": "Guardado",
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "Ya no se admite guardar registros de chat directamente en el almacenamiento de su navegador. Tómese un momento para descargar y eliminar sus registros de chat haciendo clic en el botón a continuación. No te preocupes, puedes volver a importar fácilmente tus registros de chat al backend a través de",
"Scroll to bottom when switching between branches": "",
"Scroll to bottom when switching between branches": "Moverse a la parte inferior cuando se cambia entre ramas",
"Search": "Buscar",
"Search a model": "Buscar un modelo",
"Search Chats": "Chats de búsqueda",
"Search Collection": "",
"Search Collection": "Buscar Colección",
"Search Documents": "Buscar Documentos",
"Search Functions": "Funciones de Búsqueda",
"Search Knowledge": "",
"Search Models": "Modelos de búsqueda",
"Search Functions": "Buscar Funciones",
"Search Knowledge": "Buscar Conocimiento",
"Search Models": "Buscar Modelos",
"Search Prompts": "Buscar Prompts",
"Search Query Generation Prompt": "Búsqueda de consulta de generación de prompts",
"Search Result Count": "Recuento de resultados de búsqueda",
"Search Tools": "Búsqueda de herramientas",
"SearchApi API Key": "",
"SearchApi Engine": "",
"SearchApi API Key": "Clave API de SearchApi",
"SearchApi Engine": "Motor de SearchApi",
"Searched {{count}} sites_one": "Buscado {{count}} sites_one",
"Searched {{count}} sites_many": "Buscado {{count}} sites_many",
"Searched {{count}} sites_other": "Buscó {{count}} sites_other",
"Searching \"{{searchQuery}}\"": "Buscando \"{{searchQuery}}\"",
"Searching Knowledge for \"{{searchQuery}}\"": "",
"Searching Knowledge for \"{{searchQuery}}\"": "Buscando Conocimiento para \"{{searchQuery}}\"",
"Searxng Query URL": "Searxng URL de consulta",
"See readme.md for instructions": "Vea el readme.md para instrucciones",
"See what's new": "Ver las novedades",
"Seed": "Seed",
"Select a base model": "Seleccionar un modelo base",
"Select a engine": "Busca un motor",
"Select a function": "Busca una función",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Busca una función",
"Select a model": "Selecciona un modelo",
"Select a pipeline": "Selección de una Pipeline",
"Select a pipeline url": "Selección de una dirección URL de Pipeline",
"Select a tool": "Busca una herramienta",
"Select an Ollama instance": "Seleccione una instancia de Ollama",
"Select Engine": "",
"Select Knowledge": "",
"Select Engine": "Selecciona Motor",
"Select Knowledge": "Selecciona Conocimiento",
"Select model": "Selecciona un modelo",
"Select only one model to call": "Selecciona sólo un modelo para llamar",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Los modelos seleccionados no admiten entradas de imagen",
"Send": "Enviar",
"Send a Message": "Enviar un Mensaje",
"Send message": "Enviar Mensaje",
"Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "",
"Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "Envia `stream_options: { include_usage: true }` en la solicitud.\nLos proveedores admitidos devolverán información de uso del token en la respuesta cuando se establezca.",
"September": "Septiembre",
"Serper API Key": "Clave API de Serper",
"Serply API Key": "Clave API de Serply",
"Serpstack API Key": "Clave API de Serpstack",
"Server connection verified": "Conexión del servidor verificada",
"Set as default": "Establecer por defecto",
"Set CFG Scale": "",
"Set CFG Scale": "Establecer la escala CFG",
"Set Default Model": "Establecer modelo predeterminado",
"Set embedding model (e.g. {{model}})": "Establecer modelo de embedding (ej. {{model}})",
"Set Image Size": "Establecer tamaño de imagen",
"Set reranking model (e.g. {{model}})": "Establecer modelo de reranking (ej. {{model}})",
"Set Sampler": "",
"Set Scheduler": "",
"Set Sampler": "Establecer Sampler",
"Set Scheduler": "Establecer Programador",
"Set Steps": "Establecer Pasos",
"Set Task Model": "Establecer modelo de tarea",
"Set Voice": "Establecer la voz",
@@ -634,13 +636,13 @@
"Show your support!": "¡Muestra tu apoyo!",
"Showcased creativity": "Creatividad mostrada",
"Sign in": "Iniciar sesión",
"Sign in to {{WEBUI_NAME}}": "",
"Sign in to {{WEBUI_NAME}}": "Iniciar sesión en {{WEBUI_NAME}}",
"Sign Out": "Cerrar sesión",
"Sign up": "Crear una cuenta",
"Sign up to {{WEBUI_NAME}}": "",
"Signing in to {{WEBUI_NAME}}": "",
"Sign up to {{WEBUI_NAME}}": "Crear una cuenta en {{WEBUI_NAME}}",
"Signing in to {{WEBUI_NAME}}": "Iniciando sesión en {{WEBUI_NAME}}",
"Source": "Fuente",
"Speech Playback Speed": "",
"Speech Playback Speed": "Velocidad de reproducción de voz",
"Speech recognition error: {{error}}": "Error de reconocimiento de voz: {{error}}",
"Speech-to-Text Engine": "Motor de voz a texto",
"Stop Sequence": "Detener secuencia",
@@ -652,9 +654,9 @@
"Success": "Éxito",
"Successfully updated.": "Actualizado exitosamente.",
"Suggested": "Sugerido",
"Support": "",
"Support this plugin:": "",
"Sync directory": "",
"Support": "Soporte",
"Support this plugin:": "Brinda soporte a este plugin:",
"Sync directory": "Sincroniza directorio",
"System": "Sistema",
"System Prompt": "Prompt del sistema",
"Tags": "Etiquetas",
@@ -663,26 +665,26 @@
"Tell us more:": "Dinos más:",
"Temperature": "Temperatura",
"Template": "Plantilla",
"Temporary Chat": "",
"Temporary Chat": "Chat temporal",
"Text Completion": "Finalización de texto",
"Text-to-Speech Engine": "Motor de texto a voz",
"Tfs Z": "Tfs Z",
"Thanks for your feedback!": "¡Gracias por tu retroalimentación!",
"The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.": "",
"The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "",
"The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "",
"The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.": "Los desarrolladores de este plugin son apasionados voluntarios de la comunidad. Si encuentras este plugin útil, por favor considere contribuir a su desarrollo.",
"The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "El tamaño máximo del archivo en MB. Si el tamaño del archivo supera este límite, el archivo no se subirá.",
"The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "El número máximo de archivos que se pueden utilizar a la vez en chat. Si este límite es superado, los archivos no se subirán.",
"The score should be a value between 0.0 (0%) and 1.0 (100%).": "El puntaje debe ser un valor entre 0.0 (0%) y 1.0 (100%).",
"Theme": "Tema",
"Thinking...": "Pensando...",
"This action cannot be undone. Do you wish to continue?": "Esta acción no se puede deshacer. ¿Desea continuar?",
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Esto garantiza que sus valiosas conversaciones se guarden de forma segura en su base de datos en el backend. ¡Gracias!",
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "Esta es una característica experimental que puede no funcionar como se esperaba y está sujeto a cambios en cualquier momento.",
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "",
"This option will delete all existing files in the collection and replace them with newly uploaded files.": " Esta opción eliminará todos los archivos existentes en la colección y los reemplazará con nuevos archivos subidos.",
"This will delete": "Esto eliminará",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Esto reseteará la base de conocimientos y sincronizará todos los archivos. ¿Desea continuar?",
"Thorough explanation": "Explicación exhaustiva",
"Tika": "",
"Tika Server URL required.": "",
"Tika": "Tika",
"Tika Server URL required.": "URL del servidor de Tika",
"Tip: Update multiple variable slots consecutively by pressing the tab key in the chat input after each replacement.": "Consejo: Actualice múltiples variables consecutivamente presionando la tecla tab en la entrada del chat después de cada reemplazo.",
"Title": "Título",
"Title (e.g. Tell me a fun fact)": "Título (por ejemplo, cuéntame una curiosidad)",
@@ -692,9 +694,9 @@
"To access the available model names for downloading,": "Para acceder a los nombres de modelos disponibles para descargar,",
"To access the GGUF models available for downloading,": "Para acceder a los modelos GGUF disponibles para descargar,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Para acceder al interfaz de usuario web, por favor contacte al administrador. Los administradores pueden administrar los estados de los usuarios desde el panel de administración.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Para adjuntar la base de conocimientos aquí, agreguelas al área de trabajo \"Conocimiento\" primero.",
"to chat input.": "a la entrada del chat.",
"To select actions here, add them to the \"Functions\" workspace first.": "",
"To select actions here, add them to the \"Functions\" workspace first.": "Para seleccionar acciones aquí, agreguelas al área de trabajo \"Funciones\" primero.",
"To select filters here, add them to the \"Functions\" workspace first.": "Para seleccionar filtros aquí, agreguelos al área de trabajo \"Funciones\" primero.",
"To select toolkits here, add them to the \"Tools\" workspace first.": "Para seleccionar herramientas aquí, agreguelas al área de trabajo \"Herramientas\" primero.",
"Today": "Hoy",
@@ -705,13 +707,13 @@
"Tool deleted successfully": "Herramienta eliminada con éxito",
"Tool imported successfully": "Herramienta importada con éxito",
"Tool updated successfully": "Herramienta actualizada con éxito",
"Toolkit Description (e.g. A toolkit for performing various operations)": "",
"Toolkit ID (e.g. my_toolkit)": "",
"Toolkit Name (e.g. My ToolKit)": "",
"Toolkit Description (e.g. A toolkit for performing various operations)": "Descripción del Kit de herramientas (por ejemplo, una herramienta para realizar diversas operaciones)",
"Toolkit ID (e.g. my_toolkit)": "ID del Kit de Herramientas (por ejemplo, mi_herramienta)",
"Toolkit Name (e.g. My ToolKit)": "Nombre del Kit de Herramientas (por ejemplo, mi kit de herramientas)",
"Tools": "Herramientas",
"Tools are a function calling system with arbitrary code execution": "",
"Tools have a function calling system that allows arbitrary code execution": "",
"Tools have a function calling system that allows arbitrary code execution.": "",
"Tools are a function calling system with arbitrary code execution": "Las herramientas son un sistema de llamada de funciones con código arbitrario",
"Tools have a function calling system that allows arbitrary code execution": "Las herramientas tienen un sistema de llamadas de funciones que permite la ejecución de código arbitrario",
"Tools have a function calling system that allows arbitrary code execution.": "Las herramientas tienen un sistema de llamada de funciones que permite la ejecución de código arbitrario.",
"Top K": "Top K",
"Top P": "Top P",
"Trouble accessing Ollama?": "¿Problemas para acceder a Ollama?",
@@ -722,21 +724,22 @@
"Type Hugging Face Resolve (Download) URL": "Escriba la URL (Descarga) de Hugging Face Resolve",
"Uh-oh! There was an issue connecting to {{provider}}.": "¡Uh oh! Hubo un problema al conectarse a {{provider}}.",
"UI": "UI",
"Unpin": "",
"Unpin": "Desanclar",
"Update": "Actualizar",
"Update and Copy Link": "Actualizar y copiar enlace",
"Update for the latest features and improvements.": "",
"Update for the latest features and improvements.": "Actualize para las últimas características e mejoras.",
"Update password": "Actualizar contraseña",
"Updated": "",
"Updated at": "Actualizado en",
"Upload": "Subir",
"Upload a GGUF model": "Subir un modelo GGUF",
"Upload directory": "",
"Upload files": "",
"Upload directory": "Directorio de carga",
"Upload files": "Subir archivos",
"Upload Files": "Subir archivos",
"Upload Pipeline": "Subir Pipeline",
"Upload Progress": "Progreso de carga",
"URL Mode": "Modo de URL",
"Use '#' in the prompt input to load and include your knowledge.": "",
"Use '#' in the prompt input to load and include your knowledge.": "Utilize '#' en el prompt para cargar y incluir su conocimiento.",
"Use '#' in the prompt input to load and select your documents.": "Utilice '#' en el prompt para cargar y seleccionar sus documentos.",
"Use Gravatar": "Usar Gravatar",
"Use Initials": "Usar Iniciales",
@@ -754,10 +757,10 @@
"variable": "variable",
"variable to have them replaced with clipboard content.": "variable para reemplazarlos con el contenido del portapapeles.",
"Version": "Versión",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"Version {{selectedVersion}} of {{totalVersions}}": "Versión {{selectedVersion}} de {{totalVersions}}",
"Voice": "Voz",
"Warning": "Advertencia",
"Warning:": "",
"Warning:": "Advertencia:",
"Warning: If you update or change your embedding model, you will need to re-import all documents.": "Advertencia: Si actualiza o cambia su modelo de inserción, necesitará volver a importar todos los documentos.",
"Web": "Web",
"Web API": "API Web",
@@ -783,7 +786,7 @@
"You're a helpful assistant.": "Usted es un asistente útil.",
"You're now logged in.": "Usted ahora está conectado.",
"Your account status is currently pending activation.": "El estado de su cuenta actualmente se encuentra pendiente de activación.",
"Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "",
"Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Su contribución completa irá directamente a el desarrollador del plugin; Open WebUI no toma ningun porcentaje. Sin embargo, la plataforma de financiación elegida podría tener sus propias tarifas.",
"Youtube": "Youtube",
"Youtube Loader Settings": "Configuración del cargador de Youtube"
}

View File

@@ -294,6 +294,7 @@
"Export Prompts": "اکسپورت از پرامپت\u200cها",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "ایجاد کلید API با خطا مواجه شد.",
"Failed to read clipboard contents": "خواندن محتوای کلیپ بورد ناموفق بود",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "نام مدل خود را",
"New Chat": "گپ جدید",
"New Password": "رمز عبور جدید",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Seed",
"Select a base model": "انتخاب یک مدل پایه",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "انتخاب یک مدل",
"Select a pipeline": "انتخاب یک خط لوله",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "انتخاب یک مدل",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "مدل) های (انتخاب شده ورودیهای تصویر را پشتیبانی نمیکند",
"Send": "ارسال",
"Send a Message": "ارسال یک پیام",
@@ -726,6 +728,7 @@
"Update and Copy Link": "به روزرسانی و کپی لینک",
"Update for the latest features and improvements.": "",
"Update password": "به روزرسانی رمزعبور",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "آپلود یک مدل GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Vie kehotteet",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "API-avaimen luonti epäonnistui.",
"Failed to read clipboard contents": "Leikepöydän sisällön lukeminen epäonnistui",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "Mallin nimeäminen",
"New Chat": "Uusi keskustelu",
"New Password": "Uusi salasana",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Siemen",
"Select a base model": "Valitse perusmalli",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Valitse malli",
"Select a pipeline": "Valitse putki",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "Valitse malli",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Valitut mallit eivät tue kuvasyötteitä",
"Send": "Lähetä",
"Send a Message": "Lähetä viesti",
@@ -726,6 +728,7 @@
"Update and Copy Link": "Päivitä ja kopioi linkki",
"Update for the latest features and improvements.": "",
"Update password": "Päivitä salasana",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Lataa GGUF-malli",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Exporter les Prompts",
"Export Tools": "Outils d'exportation",
"External Models": "Modèles externes",
"Failed to add file.": "",
"Failed to create API Key.": "Échec de la création de la clé API.",
"Failed to read clipboard contents": "Échec de la lecture du contenu du presse-papiers",
"Failed to update settings": "Échec de la mise à jour des paramètres",
@@ -449,6 +450,7 @@
"Name your model": "Nommez votre modèle",
"New Chat": "Nouvelle conversation",
"New Password": "Nouveau mot de passe",
"No content found": "",
"No content to speak": "Rien à signaler",
"No file selected": "Aucun fichier sélectionné",
"No HTML, CSS, or JavaScript content found.": "",
@@ -589,6 +591,7 @@
"Seed": "Graine",
"Select a base model": "Sélectionnez un modèle de base",
"Select a engine": "Sélectionnez un moteur",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Sélectionnez une fonction",
"Select a model": "Sélectionnez un modèle",
"Select a pipeline": "Sélectionnez un pipeline",
@@ -599,7 +602,6 @@
"Select Knowledge": "",
"Select model": "Sélectionnez un modèle",
"Select only one model to call": "Sélectionnez seulement un modèle pour appeler",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Les modèle(s) sélectionné(s) ne prennent pas en charge les entrées d'images",
"Send": "Envoyer",
"Send a Message": "Envoyer un message",
@@ -727,6 +729,7 @@
"Update and Copy Link": "Mettre à jour et copier le lien",
"Update for the latest features and improvements.": "",
"Update password": "Mettre à jour le mot de passe",
"Updated": "",
"Updated at": "Mise à jour le",
"Upload": "Télécharger",
"Upload a GGUF model": "Téléverser un modèle GGUF",

View File

@@ -9,7 +9,7 @@
"{{user}}'s Chats": "Conversations de {{user}}",
"{{webUIName}} Backend Required": "Backend {{webUIName}} requis",
"*Prompt node ID(s) are required for image generation": "*Les ID de noeud du prompt sont nécessaires pour la génération dimages",
"A new version (v{{LATEST_VERSION}}) is now available.": "",
"A new version (v{{LATEST_VERSION}}) is now available.": "Une nouvelle version (v{{LATEST_VERSION}}) est disponible.",
"A task model is used when performing tasks such as generating titles for chats and web search queries": "Un modèle de tâche est utilisé lors de lexécution de tâches telles que la génération de titres pour les conversations et les requêtes de recherche sur le web.",
"a user": "un utilisateur",
"About": "À propos",
@@ -23,8 +23,8 @@
"Add a short description about what this model does": "Ajoutez une brève description de ce que fait ce modèle.",
"Add a short title for this prompt": "Ajoutez un bref titre pour cette prompt.",
"Add a tag": "Ajouter une étiquette",
"Add Content": "",
"Add content here": "",
"Add Content": "Ajouter du contenu",
"Add content here": "Ajoutez du contenu ici",
"Add custom prompt": "Ajouter une prompt personnalisée",
"Add Docs": "Ajouter de la documentation",
"Add Files": "Ajouter des fichiers",
@@ -33,7 +33,7 @@
"Add Model": "Ajouter un modèle",
"Add Tag": "Ajouter une étiquette",
"Add Tags": "Ajouter des étiquettes",
"Add text content": "",
"Add text content": "Ajouter du contenu texte",
"Add User": "Ajouter un utilisateur",
"Adjusting these settings will apply changes universally to all users.": "L'ajustement de ces paramètres appliquera universellement les changements à tous les utilisateurs.",
"admin": "administrateur",
@@ -68,8 +68,8 @@
"Archived Chats": "Conversations archivées",
"are allowed - Activate this command by typing": "sont autorisés - Activer cette commande en tapant",
"Are you sure?": "Êtes-vous certain ?",
"Artifacts": "",
"Ask a question": "",
"Artifacts": "Artéfacts",
"Ask a question": "Posez votre question",
"Attach file": "Joindre un document",
"Attention to detail": "Attention aux détails",
"Audio": "Audio",
@@ -79,10 +79,10 @@
"AUTOMATIC1111 Api Auth String": "AUTOMATIC1111 Chaîne d'authentification de l'API",
"AUTOMATIC1111 Base URL": "URL de base AUTOMATIC1111",
"AUTOMATIC1111 Base URL is required.": "L'URL de base {AUTOMATIC1111} est requise.",
"Available list": "",
"Available list": "Liste disponible",
"available!": "disponible !",
"Azure AI Speech": "",
"Azure Region": "",
"Azure AI Speech": "Azure AI Speech",
"Azure Region": "Région Azure",
"Back": "Retour en arrière",
"Bad Response": "Mauvaise réponse",
"Banners": "Bannières",
@@ -103,7 +103,7 @@
"Chat Bubble UI": "Bulles de chat",
"Chat Controls": "Contrôles du chat",
"Chat direction": "Direction du chat",
"Chat Overview": "",
"Chat Overview": "Aperçu du chat",
"Chats": "Conversations",
"Check Again": "Vérifiez à nouveau.",
"Check for updates": "Vérifier les mises à jour disponibles",
@@ -158,7 +158,7 @@
"Copying to clipboard was successful!": "La copie dans le presse-papiers a réussi !",
"Create a model": "Créer un modèle",
"Create Account": "Créer un compte",
"Create Knowledge": "",
"Create Knowledge": "Créer une connaissance",
"Create new key": "Créer une nouvelle clé",
"Create new secret key": "Créer une nouvelle clé secrète",
"Created at": "Créé à",
@@ -248,7 +248,7 @@
"Enter a detail about yourself for your LLMs to recall": "Saisissez un détail sur vous-même que vos LLMs pourront se rappeler",
"Enter api auth string (e.g. username:password)": "Entrez la chaîne d'authentification de l'API (par ex. nom d'utilisateur:mot de passe)",
"Enter Brave Search API Key": "Entrez la clé API Brave Search",
"Enter CFG Scale (e.g. 7.0)": "",
"Enter CFG Scale (e.g. 7.0)": "Entrez l'échelle CFG (par ex. 7.0)",
"Enter Chunk Overlap": "Entrez le chevauchement des chunks",
"Enter Chunk Size": "Entrez la taille des chunks",
"Enter Github Raw URL": "Entrez l'URL brute de GitHub",
@@ -259,8 +259,8 @@
"Enter Model ID": "Entrez l'ID du modèle",
"Enter model tag (e.g. {{modelTag}})": "Entrez l'étiquette du modèle (par ex. {{modelTag}})",
"Enter Number of Steps (e.g. 50)": "Entrez le nombre d'étapes (par ex. 50)",
"Enter Sampler (e.g. Euler a)": "",
"Enter Scheduler (e.g. Karras)": "",
"Enter Sampler (e.g. Euler a)": "Entrez le sampler (par ex. Euler a)",
"Enter Scheduler (e.g. Karras)": "Entrez le planificateur (par ex. Karras)",
"Enter Score": "Entrez votre score",
"Enter SearchApi API Key": "Entrez la clé API SearchApi",
"Enter SearchApi Engine": "Entrez le moteur de recherche SearchApi",
@@ -294,18 +294,19 @@
"Export Prompts": "Exporter des prompts",
"Export Tools": "Outils d'exportation",
"External Models": "Modèles externes",
"Failed to add file.": "",
"Failed to create API Key.": "Échec de la création de la clé API.",
"Failed to read clipboard contents": "Échec de la lecture du contenu du presse-papiers",
"Failed to update settings": "Échec de la mise à jour des paramètres",
"Failed to upload file.": "",
"Failed to upload file.": "Échec du téléchargement du fichier.",
"February": "Février",
"Feel free to add specific details": "N'hésitez pas à ajouter des détails spécifiques",
"File": "Fichier",
"File added successfully.": "",
"File content updated successfully.": "",
"File added successfully.": "Fichier ajouté avec succès.",
"File content updated successfully.": "Contenu du fichier mis à jour avec succès.",
"File Mode": "Mode fichier",
"File not found.": "Fichier introuvable.",
"File removed successfully.": "",
"File removed successfully.": "Fichier supprimé avec succès.",
"File size should not exceed {{maxSize}} MB.": "La taille du fichier ne doit pas dépasser {{maxSize}} Mo.",
"Files": "Fichiers",
"Filter is now globally disabled": "Le filtre est maintenant désactivé globalement",
@@ -379,12 +380,12 @@
"JWT Token": "Jeton JWT",
"Keep Alive": "Temps de maintien connecté",
"Keyboard shortcuts": "Raccourcis clavier",
"Knowledge": "Connaissance",
"Knowledge created successfully.": "",
"Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "",
"Knowledge updated successfully": "",
"Landing Page Mode": "",
"Knowledge": "Connaissances",
"Knowledge created successfully.": "Connaissance créée avec succès.",
"Knowledge deleted successfully.": "Connaissance supprimée avec succès.",
"Knowledge reset successfully.": "Connaissance réinitialisée avec succès.",
"Knowledge updated successfully": "Connaissance mise à jour avec succès",
"Landing Page Mode": "Mode de la page d'accueil",
"Language": "Langue",
"large language models, locally.": "grand modèle de langage, localement.",
"Last Active": "Dernière activité",
@@ -430,8 +431,8 @@
"Model {{modelId}} not found": "Modèle {{modelId}} introuvable",
"Model {{modelName}} is not vision capable": "Le modèle {{modelName}} n'a pas de capacités visuelles",
"Model {{name}} is now {{status}}": "Le modèle {{name}} est désormais {{status}}.",
"Model {{name}} is now at the top": "",
"Model accepts image inputs": "",
"Model {{name}} is now at the top": "Le modèle {{name}} est désormais en haut",
"Model accepts image inputs": "Le modèle accepte les images en entrée",
"Model created successfully!": "Le modèle a été créé avec succès !",
"Model filesystem path detected. Model shortname is required for update, cannot continue.": "Chemin du système de fichiers de modèle détecté. Le nom court du modèle est requis pour la mise à jour, l'opération ne peut pas être poursuivie.",
"Model ID": "ID du modèle",
@@ -443,16 +444,17 @@
"Modelfile Content": "Contenu du Fichier de Modèle",
"Models": "Modèles",
"More": "Plus de",
"Move to Top": "",
"Move to Top": "Déplacer en haut",
"Name": "Nom d'utilisateur",
"Name Tag": "Nom de l'étiquette",
"Name your model": "Nommez votre modèle",
"New Chat": "Nouvelle conversation",
"New Password": "Nouveau mot de passe",
"No content found": "",
"No content to speak": "Rien à signaler",
"No file selected": "Aucun fichier sélectionné",
"No HTML, CSS, or JavaScript content found.": "",
"No knowledge found": "",
"No HTML, CSS, or JavaScript content found.": "Aucun contenu HTML, CSS ou JavaScript trouvé.",
"No knowledge found": "Aucune connaissance trouvée",
"No results found": "Aucun résultat trouvé",
"No search query generated": "Aucune requête de recherche générée",
"No source available": "Aucune source n'est disponible",
@@ -477,13 +479,13 @@
"On": "Activé",
"Only": "Seulement",
"Only alphanumeric characters and hyphens are allowed in the command string.": "Seuls les caractères alphanumériques et les tirets sont autorisés dans la chaîne de commande.",
"Only collections can be edited, create a new knowledge base to edit/add documents.": "",
"Only collections can be edited, create a new knowledge base to edit/add documents.": "Seules les collections peuvent être modifiées, créez une nouvelle base de connaissance pour modifier/ajouter des documents.",
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "Oups ! Un instant ! Vos fichiers sont toujours en train d'être traités. Nous les perfectionnons pour vous. Veuillez patienter, nous vous informerons dès qu'ils seront prêts.",
"Oops! Looks like the URL is invalid. Please double-check and try again.": "Oups ! Il semble que l'URL soit invalide. Veuillez vérifier à nouveau et réessayer.",
"Oops! There was an error in the previous response. Please try again or contact admin.": "Oops ! Il y a eu une erreur dans la réponse précédente. Veuillez réessayer ou contacter l'administrateur.",
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "Oups\u00a0! Vous utilisez une méthode non prise en charge (frontend uniquement). Veuillez servir l'interface Web à partir du backend.",
"Open file": "",
"Open in full screen": "",
"Open file": "Ouvrir le fichier",
"Open in full screen": "Ouvrir en plein écran",
"Open new chat": "Ouvrir une nouvelle conversation",
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "La version Open WebUI (v{{OPEN_WEBUI_VERSION}}) est inférieure à la version requise (v{{REQUIRED_VERSION}})",
"OpenAI": "OpenAI",
@@ -493,9 +495,9 @@
"OpenAI URL/Key required.": "URL/Clé OpenAI requise.",
"or": "ou",
"Other": "Autre",
"Output format": "",
"Overview": "",
"page": "",
"Output format": "Format de sortie",
"Overview": "Aperçu",
"page": "page",
"Password": "Mot de passe",
"PDF document (.pdf)": "Document au format PDF (.pdf)",
"PDF Extract Images (OCR)": "Extraction d'images PDF (OCR)",
@@ -514,8 +516,8 @@
"Plain text (.txt)": "Texte simple (.txt)",
"Playground": "Playground",
"Please carefully review the following warnings:": "Veuillez lire attentivement les avertissements suivants :",
"Please fill in all fields.": "",
"Please select a reason": "",
"Please fill in all fields.": "Veuillez remplir tous les champs.",
"Please select a reason": "Veuillez sélectionner une raison",
"Positive attitude": "Attitude positive",
"Previous 30 days": "30 derniers jours",
"Previous 7 days": "7 derniers jours",
@@ -559,18 +561,18 @@
"Save": "Enregistrer",
"Save & Create": "Enregistrer & Créer",
"Save & Update": "Enregistrer & Mettre à jour",
"Save As Copy": "",
"Save As Copy": "Enregistrer comme copie",
"Save Tag": "Enregistrer l'étiquette",
"Saved": "",
"Saved": "Enregistré",
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "La sauvegarde des journaux de conversation directement dans le stockage de votre navigateur n'est plus prise en charge. Veuillez prendre un instant pour télécharger et supprimer vos journaux de conversation en cliquant sur le bouton ci-dessous. Ne vous inquiétez pas, vous pouvez facilement réimporter vos journaux de conversation dans le backend via",
"Scroll to bottom when switching between branches": "Défiler vers le bas lors du passage d'une branche à l'autre",
"Search": "Recherche",
"Search a model": "Rechercher un modèle",
"Search Chats": "Rechercher des conversations",
"Search Collection": "",
"Search Collection": "Rechercher une collection",
"Search Documents": "Rechercher des documents",
"Search Functions": "Rechercher des fonctions",
"Search Knowledge": "",
"Search Knowledge": "Rechercher des connaissances",
"Search Models": "Rechercher des modèles",
"Search Prompts": "Rechercher des prompts",
"Search Query Generation Prompt": "Génération d'interrogation de recherche",
@@ -589,6 +591,7 @@
"Seed": "Graine",
"Select a base model": "Sélectionnez un modèle de base",
"Select a engine": "Sélectionnez un moteur",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Sélectionnez une fonction",
"Select a model": "Sélectionnez un modèle",
"Select a pipeline": "Sélectionnez un pipeline",
@@ -596,10 +599,9 @@
"Select a tool": "Sélectionnez un outil",
"Select an Ollama instance": "Sélectionnez une instance Ollama",
"Select Engine": "Sélectionnez le moteur",
"Select Knowledge": "",
"Select Knowledge": "Sélectionnez une connaissance",
"Select model": "Sélectionnez un modèle",
"Select only one model to call": "Sélectionnez seulement un modèle pour appeler",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Les modèle(s) sélectionné(s) ne prennent pas en charge les entrées d'images",
"Send": "Envoyer",
"Send a Message": "Envoyer un message",
@@ -611,13 +613,13 @@
"Serpstack API Key": "Clé API Serpstack",
"Server connection verified": "Connexion au serveur vérifiée",
"Set as default": "Définir comme valeur par défaut",
"Set CFG Scale": "",
"Set CFG Scale": "Définir la CFG",
"Set Default Model": "Définir le modèle par défaut",
"Set embedding model (e.g. {{model}})": "Définir le modèle d'embedding (par ex. {{model}})",
"Set Image Size": "Définir la taille de l'image",
"Set reranking model (e.g. {{model}})": "Définir le modèle de ré-ranking (par ex. {{model}})",
"Set Sampler": "",
"Set Scheduler": "",
"Set Sampler": "Définir le sampler",
"Set Scheduler": "Définir le planificateur",
"Set Steps": "Définir le nombre d'étapes",
"Set Task Model": "Définir le modèle de tâche",
"Set Voice": "Choisir la voix",
@@ -634,17 +636,17 @@
"Show your support!": "Montre ton soutien !",
"Showcased creativity": "Créativité mise en avant",
"Sign in": "S'identifier",
"Sign in to {{WEBUI_NAME}}": "",
"Sign in to {{WEBUI_NAME}}": "Connectez-vous à {{WEBUI_NAME}}",
"Sign Out": "Déconnexion",
"Sign up": "Inscrivez-vous",
"Sign up to {{WEBUI_NAME}}": "",
"Signing in to {{WEBUI_NAME}}": "",
"Sign up to {{WEBUI_NAME}}": "Inscrivez-vous à {{WEBUI_NAME}}",
"Signing in to {{WEBUI_NAME}}": "Connexion à {{WEBUI_NAME}}",
"Source": "Source",
"Speech Playback Speed": "",
"Speech Playback Speed": "Vitesse de lecture de la parole",
"Speech recognition error: {{error}}": "Erreur de reconnaissance vocale\u00a0: {{error}}",
"Speech-to-Text Engine": "Moteur de reconnaissance vocale",
"Stop Sequence": "Séquence d'arrêt",
"Stream Chat Response": "",
"Stream Chat Response": "Streamer la réponse de la conversation",
"STT Model": "Modèle de Speech-to-Text",
"STT Settings": "Paramètres de Speech-to-Text",
"Submit": "Soumettre",
@@ -654,7 +656,7 @@
"Suggested": "Sugéré",
"Support": "Supporter",
"Support this plugin:": "Supporter ce module",
"Sync directory": "",
"Sync directory": "Synchroniser le répertoire",
"System": "Système",
"System Prompt": "Prompt du système",
"Tags": "Étiquettes",
@@ -677,9 +679,9 @@
"This action cannot be undone. Do you wish to continue?": "Cette action ne peut pas être annulée. Souhaitez-vous continuer ?",
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "Cela garantit que vos conversations précieuses soient sauvegardées en toute sécurité dans votre base de données backend. Merci !",
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "Il s'agit d'une fonctionnalité expérimentale, elle peut ne pas fonctionner comme prévu et est sujette à modification à tout moment.",
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "",
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "Cette option supprimera tous les fichiers existants dans la collection et les remplacera par les fichiers nouvellement téléchargés.",
"This will delete": "Cela supprimera",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "Cela réinitialisera la base de connaissances et synchronisera tous les fichiers. Souhaitez-vous continuer ?",
"Thorough explanation": "Explication approfondie",
"Tika": "Tika",
"Tika Server URL required.": "URL du serveur Tika requise.",
@@ -692,7 +694,7 @@
"To access the available model names for downloading,": "Pour accéder aux noms des modèles disponibles,",
"To access the GGUF models available for downloading,": "Pour accéder aux modèles GGUF disponibles,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "Pour accéder à l'interface Web, veuillez contacter l'administrateur. Les administrateurs peuvent gérer les statuts des utilisateurs depuis le panneau d'administration.",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "Pour attacher une base de connaissances ici, ajoutez-les d'abord à l'espace de travail « Connaissances ».",
"to chat input.": "Vers la zone de chat.",
"To select actions here, add them to the \"Functions\" workspace first.": "Pour sélectionner des actions ici, ajoutez-les d'abord à l'espace de travail « Fonctions ».",
"To select filters here, add them to the \"Functions\" workspace first.": "Pour sélectionner des filtres ici, ajoutez-les d'abord à l'espace de travail « Fonctions ». ",
@@ -725,18 +727,19 @@
"Unpin": "Désépingler",
"Update": "Mise à jour",
"Update and Copy Link": "Mettre à jour et copier le lien",
"Update for the latest features and improvements.": "",
"Update for the latest features and improvements.": "Mettez à jour pour bénéficier des dernières fonctionnalités et améliorations.",
"Update password": "Mettre à jour le mot de passe",
"Updated": "",
"Updated at": "Mise à jour le",
"Upload": "Télécharger",
"Upload a GGUF model": "Téléverser un modèle GGUF",
"Upload directory": "",
"Upload files": "",
"Upload directory": "Répertoire de téléchargement",
"Upload files": "Télécharger des fichiers",
"Upload Files": "Télécharger des fichiers",
"Upload Pipeline": "Pipeline de téléchargement",
"Upload Progress": "Progression de l'envoi",
"URL Mode": "Mode d'URL",
"Use '#' in the prompt input to load and include your knowledge.": "",
"Use '#' in the prompt input to load and include your knowledge.": "Utilisez '#' dans la zone de saisie du prompt pour charger et inclure vos connaissances.",
"Use '#' in the prompt input to load and select your documents.": "Utilisez '#' dans la zone de saisie du prompt pour charger et sélectionner vos documents.",
"Use Gravatar": "Utilisez Gravatar",
"Use Initials": "Utiliser les initiales",
@@ -754,7 +757,7 @@
"variable": "variable",
"variable to have them replaced with clipboard content.": "variable pour qu'elles soient remplacées par le contenu du presse-papiers.",
"Version": "version:",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"Version {{selectedVersion}} of {{totalVersions}}": "Version {{selectedVersion}} de {{totalVersions}}",
"Voice": "Voix",
"Warning": "Avertissement !",
"Warning:": "Avertissement :",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "ייצוא פקודות",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "יצירת מפתח API נכשלה.",
"Failed to read clipboard contents": "קריאת תוכן הלוח נכשלה",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "תן שם לדגם שלך",
"New Chat": "צ'אט חדש",
"New Password": "סיסמה חדשה",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -589,6 +591,7 @@
"Seed": "זרע",
"Select a base model": "בחירת מודל בסיס",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "בחר מודל",
"Select a pipeline": "בחר קו צינור",
@@ -599,7 +602,6 @@
"Select Knowledge": "",
"Select model": "בחר מודל",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "דגמים נבחרים אינם תומכים בקלט תמונה",
"Send": "שלח",
"Send a Message": "שלח הודעה",
@@ -727,6 +729,7 @@
"Update and Copy Link": "עדכן ושכפל קישור",
"Update for the latest features and improvements.": "",
"Update password": "עדכן סיסמה",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "העלה מודל GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "प्रॉम्प्ट निर्यात करें",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "एपीआई कुंजी बनाने में विफल.",
"Failed to read clipboard contents": "क्लिपबोर्ड सामग्री पढ़ने में विफल",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "अपने मॉडल को नाम दें",
"New Chat": "नई चैट",
"New Password": "नया पासवर्ड",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "सीड्\u200c",
"Select a base model": "एक आधार मॉडल का चयन करें",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "एक मॉडल चुनें",
"Select a pipeline": "एक पाइपलाइन का चयन करें",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "मॉडल चुनें",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "चयनित मॉडल छवि इनपुट का समर्थन नहीं करते हैं",
"Send": "भेज",
"Send a Message": "एक संदेश भेजो",
@@ -726,6 +728,7 @@
"Update and Copy Link": "अपडेट करें और लिंक कॉपी करें",
"Update for the latest features and improvements.": "",
"Update password": "पासवर्ड अपडेट करें",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "GGUF मॉडल अपलोड करें",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Izvoz prompta",
"Export Tools": "Izvoz alata",
"External Models": "Vanjski modeli",
"Failed to add file.": "",
"Failed to create API Key.": "Neuspješno stvaranje API ključa.",
"Failed to read clipboard contents": "Neuspješno čitanje sadržaja međuspremnika",
"Failed to update settings": "Greška kod ažuriranja postavki",
@@ -449,6 +450,7 @@
"Name your model": "Dodijelite naziv modelu",
"New Chat": "Novi razgovor",
"New Password": "Nova lozinka",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -589,6 +591,7 @@
"Seed": "Sjeme",
"Select a base model": "Odabir osnovnog modela",
"Select a engine": "Odaberite pogon",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Odaberite model",
"Select a pipeline": "Odabir kanala",
@@ -599,7 +602,6 @@
"Select Knowledge": "",
"Select model": "Odaberite model",
"Select only one model to call": "Odaberite samo jedan model za poziv",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Odabrani modeli ne podržavaju unose slika",
"Send": "Pošalji",
"Send a Message": "Pošaljite poruku",
@@ -727,6 +729,7 @@
"Update and Copy Link": "Ažuriraj i kopiraj vezu",
"Update for the latest features and improvements.": "",
"Update password": "Ažuriraj lozinku",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Učitaj GGUF model",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Perintah Ekspor",
"Export Tools": "Alat Ekspor",
"External Models": "Model Eksternal",
"Failed to add file.": "",
"Failed to create API Key.": "Gagal membuat API Key.",
"Failed to read clipboard contents": "Gagal membaca konten papan klip",
"Failed to update settings": "Gagal memperbarui pengaturan",
@@ -449,6 +450,7 @@
"Name your model": "Beri nama model Anda",
"New Chat": "Obrolan Baru",
"New Password": "Kata Sandi Baru",
"No content found": "",
"No content to speak": "Tidak ada konten untuk dibicarakan",
"No file selected": "Tidak ada file yang dipilih",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Benih",
"Select a base model": "Pilih model dasar",
"Select a engine": "Pilih mesin",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Memilih fungsi",
"Select a model": "Pilih model",
"Select a pipeline": "Pilih saluran pipa",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "Pilih model",
"Select only one model to call": "Pilih hanya satu model untuk dipanggil",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Model yang dipilih tidak mendukung input gambar",
"Send": "Kirim",
"Send a Message": "Kirim Pesan",
@@ -726,6 +728,7 @@
"Update and Copy Link": "Perbarui dan Salin Tautan",
"Update for the latest features and improvements.": "",
"Update password": "Perbarui kata sandi",
"Updated": "",
"Updated at": "Diperbarui di",
"Upload": "Unggah",
"Upload a GGUF model": "Unggah model GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Leideanna Easpórtála",
"Export Tools": "Uirlisí Easpór",
"External Models": "Samhlacha Seachtracha",
"Failed to add file.": "",
"Failed to create API Key.": "Theip ar an eochair API a chruthú.",
"Failed to read clipboard contents": "Theip ar ábhar gearrthaisce a lé",
"Failed to update settings": "Theip ar shocruithe a nuashonrú",
@@ -449,6 +450,7 @@
"Name your model": "Ainmnigh do mhúnla",
"New Chat": "Comhrá Nua",
"New Password": "Pasfhocal Nua",
"No content found": "",
"No content to speak": "Níl aon ábhar le labhairt",
"No file selected": "Níl aon chomhad roghnaithe",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Síol",
"Select a base model": "Roghnaigh bunmhúnla",
"Select a engine": "Roghnaigh inneall",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Roghnaigh feidhm",
"Select a model": "Roghnaigh samhail",
"Select a pipeline": "Roghnaigh píblíne",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "Roghnaigh samhail",
"Select only one model to call": "Roghnaigh ach samhail amháin le glaoch",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Ní thacaíonn samhail(í) roghnaithe le hionchur íomhá",
"Send": "Seol",
"Send a Message": "Seol Teachtaireacht",
@@ -726,6 +728,7 @@
"Update and Copy Link": "Nuashonraigh agus Cóipeáil Nasc",
"Update for the latest features and improvements.": "Nuashonrú le haghaidh na gnéithe agus na feabhsuithe is déanaí.",
"Update password": "Nuashonrú pasfhocal",
"Updated": "",
"Updated at": "Nuashonraithe ag",
"Upload": "Uaslódáil",
"Upload a GGUF model": "Uaslódáil samhail GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Esporta prompt",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "Impossibile creare la chiave API.",
"Failed to read clipboard contents": "Impossibile leggere il contenuto degli appunti",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "Assegna un nome al tuo modello",
"New Chat": "Nuova chat",
"New Password": "Nuova password",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -589,6 +591,7 @@
"Seed": "Seme",
"Select a base model": "Selezionare un modello di base",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Seleziona un modello",
"Select a pipeline": "Selezionare una tubazione",
@@ -599,7 +602,6 @@
"Select Knowledge": "",
"Select model": "Seleziona modello",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "I modelli selezionati non supportano l'input di immagini",
"Send": "Invia",
"Send a Message": "Invia un messaggio",
@@ -727,6 +729,7 @@
"Update and Copy Link": "Aggiorna e copia link",
"Update for the latest features and improvements.": "",
"Update password": "Aggiorna password",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Carica un modello GGUF",

View File

@@ -9,38 +9,38 @@
"{{user}}'s Chats": "{{user}} のチャット",
"{{webUIName}} Backend Required": "{{webUIName}} バックエンドが必要です",
"*Prompt node ID(s) are required for image generation": "",
"A new version (v{{LATEST_VERSION}}) is now available.": "",
"A new version (v{{LATEST_VERSION}}) is now available.": "新しいバージョンがReleaseされています。",
"A task model is used when performing tasks such as generating titles for chats and web search queries": "タスクモデルは、チャットやWeb検索クエリのタイトルの生成などのタスクを実行するときに使用されます",
"a user": "ユーザー",
"About": "概要",
"Account": "アカウント",
"Account Activation Pending": "",
"Account Activation Pending": "アカウント承認待ち",
"Accurate information": "情報の正確性",
"Actions": "",
"Active Users": "",
"Actions": "アクション",
"Active Users": "アクティブユーザー",
"Add": "追加",
"Add a model id": "モデル ID を追加する",
"Add a short description about what this model does": "このモデルの機能に関する簡単な説明を追加します",
"Add a short title for this prompt": "このプロンプトの短いタイトルを追加",
"Add a short title for this prompt": "このプロンプトへ名前を追加",
"Add a tag": "タグを追加",
"Add Content": "",
"Add content here": "",
"Add Content": "コンテンツを追加",
"Add content here": "ここへコンテンツを追加",
"Add custom prompt": "カスタムプロンプトを追加",
"Add Docs": "ドキュメントを追加",
"Add Files": "ファイルを追加",
"Add Memory": "メモリを追加",
"Add message": "メッセージを追加",
"Add Model": "モデルを追加",
"Add Tag": "",
"Add Tag": "タグを追加",
"Add Tags": "タグを追加",
"Add text content": "",
"Add text content": "コンテンツを追加",
"Add User": "ユーザーを追加",
"Adjusting these settings will apply changes universally to all users.": "これらの設定を調整すると、すべてのユーザーに普遍的に変更が適用されます。",
"Adjusting these settings will apply changes universally to all users.": "これらの設定を調整すると、すべてのユーザーに変更が適用されます。",
"admin": "管理者",
"Admin": "",
"Admin": "管理者",
"Admin Panel": "管理者パネル",
"Admin Settings": "管理者設定",
"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "",
"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "管理者は全てのツールにアクセス出来ます。ユーザーはワークスペースのモデル毎に割り当てて下さい。",
"Advanced Parameters": "詳細パラメーター",
"Advanced Params": "高度なパラメータ",
"all": "すべて",
@@ -48,11 +48,11 @@
"All Users": "すべてのユーザー",
"Allow": "許可",
"Allow Chat Deletion": "チャットの削除を許可",
"Allow Chat Editing": "",
"Allow non-local voices": "",
"Allow Temporary Chat": "",
"Allow User Location": "",
"Allow Voice Interruption in Call": "",
"Allow Chat Editing": "チャットの編集を許可",
"Allow non-local voices": "ローカル以外のボイスを許可",
"Allow Temporary Chat": "チャットの一時許可",
"Allow User Location": "ユーザーロケーションの許可",
"Allow Voice Interruption in Call": "音声の割り込みを許可",
"alphanumeric characters and hyphens": "英数字とハイフン",
"Already have an account?": "すでにアカウントをお持ちですか?",
"an assistant": "アシスタント",
@@ -69,41 +69,41 @@
"are allowed - Activate this command by typing": "が許可されています - 次のように入力してこのコマンドをアクティブ化します",
"Are you sure?": "よろしいですか?",
"Artifacts": "",
"Ask a question": "",
"Ask a question": "質問して下さい。",
"Attach file": "ファイルを添付する",
"Attention to detail": "詳細に注意する",
"Audio": "オーディオ",
"August": "8月",
"Auto-playback response": "応答の自動再生",
"Automatic1111": "",
"AUTOMATIC1111 Api Auth String": "",
"AUTOMATIC1111 Api Auth String": "AUTOMATIC1111のAuthを入力",
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 ベース URL",
"AUTOMATIC1111 Base URL is required.": "AUTOMATIC1111 ベース URL が必要です。",
"Available list": "",
"Available list": "利用可能リスト",
"available!": "利用可能!",
"Azure AI Speech": "",
"Azure Region": "",
"Azure AI Speech": "AzureAIスピーチ",
"Azure Region": "Azureリージョン",
"Back": "戻る",
"Bad Response": "応答が悪い",
"Banners": "バナー",
"Base Model (From)": "ベースモデル(From)",
"Batch Size (num_batch)": "",
"Batch Size (num_batch)": "バッチサイズ",
"before": "より前",
"Being lazy": "怠惰な",
"Brave Search API Key": "Brave Search APIキー",
"Bypass SSL verification for Websites": "SSL 検証をバイパスする",
"Call": "",
"Call": "コール",
"Call feature is not supported when using Web STT engine": "",
"Camera": "",
"Camera": "カメラ",
"Cancel": "キャンセル",
"Capabilities": "資格",
"Change Password": "パスワードを変更",
"Chat": "チャット",
"Chat Background Image": "",
"Chat Background Image": "チャットバックグラウンドイメージ",
"Chat Bubble UI": "チャットバブルUI",
"Chat Controls": "",
"Chat Controls": "チャットコントロール",
"Chat direction": "チャットの方向",
"Chat Overview": "",
"Chat Overview": "チャット概要",
"Chats": "チャット",
"Check Again": "再確認",
"Check for updates": "アップデートを確認",
@@ -113,44 +113,44 @@
"Chunk Params": "チャンクパラメーター",
"Chunk Size": "チャンクサイズ",
"Citation": "引用文",
"Clear memory": "",
"Clear memory": "メモリクリアー",
"Click here for help.": "ヘルプについてはここをクリックしてください。",
"Click here to": "ここをクリックして",
"Click here to download user import template file.": "",
"Click here to download user import template file.": "ユーザーテンプレートをインポートするにはここをクリック",
"Click here to select": "選択するにはここをクリックしてください",
"Click here to select a csv file.": "CSVファイルを選択するにはここをクリックしてください。",
"Click here to select a py file.": "",
"Click here to select a py file.": "Pythonスクリプトファイルを選択するにはここをクリック",
"Click here to select documents.": "ドキュメントを選択するにはここをクリックしてください。",
"Click here to upload a workflow.json file.": "",
"Click here to upload a workflow.json file.": "workflow.jsonファイルをアップロードするにはここをクリック。",
"click here.": "ここをクリックしてください。",
"Click on the user role button to change a user's role.": "ユーザーの役割を変更するには、ユーザー役割ボタンをクリックしてください。",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "クリップボードへの書き込み許可がありません。ブラウザ設定を確認し許可してください。",
"Clone": "クローン",
"Close": "閉じる",
"Code formatted successfully": "",
"Code formatted successfully": "コードフォーマット完了",
"Collection": "コレクション",
"ComfyUI": "ComfyUI",
"ComfyUI Base URL": "ComfyUIベースURL",
"ComfyUI Base URL is required.": "ComfyUIベースURLが必要です。",
"ComfyUI Workflow": "",
"ComfyUI Workflow Nodes": "",
"ComfyUI Workflow": "ComfyUIワークフロー",
"ComfyUI Workflow Nodes": "ComfyUIワークフローード",
"Command": "コマンド",
"Concurrent Requests": "コンカレント要求",
"Confirm": "",
"Confirm": "確認",
"Confirm Password": "パスワードを確認",
"Confirm your action": "",
"Connections": "接続",
"Contact Admin for WebUI Access": "",
"Contact Admin for WebUI Access": "WEBUIへの接続について管理者に問い合わせ下さい。",
"Content": "コンテンツ",
"Content Extraction": "",
"Context Length": "コンテキストの長さ",
"Continue Response": "続きの応答",
"Continue with {{provider}}": "",
"Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "",
"Controls": "",
"Copied": "",
"Copied shared chat URL to clipboard!": "共有チャットURLをクリップボードにコピーしました",
"Copied to clipboard": "",
"Controls": "コントロール",
"Copied": "コピー",
"Copied shared chat URL to clipboard!": "共有チャットURLをクリップボードにコピーしました!",
"Copied to clipboard": "クリップボードにコピーしました。",
"Copy": "コピー",
"Copy last code block": "最後のコードブロックをコピー",
"Copy last response": "最後の応答をコピー",
@@ -158,23 +158,23 @@
"Copying to clipboard was successful!": "クリップボードへのコピーが成功しました!",
"Create a model": "モデルを作成する",
"Create Account": "アカウントを作成",
"Create Knowledge": "",
"Create Knowledge": "RAG用データ作成",
"Create new key": "新しいキーを作成",
"Create new secret key": "新しいシークレットキーを作成",
"Created at": "作成日時",
"Created At": "作成日時",
"Created by": "",
"CSV Import": "",
"CSV Import": "CSVインポート",
"Current Model": "現在のモデル",
"Current Password": "現在のパスワード",
"Custom": "カスタム",
"Customize models for a specific purpose": "特定の目的に合わせてモデルをカスタマイズする",
"Dark": "ダーク",
"Dashboard": "",
"Dashboard": "ダッシュボード",
"Database": "データベース",
"December": "12月",
"Default": "デフォルト",
"Default (Open AI)": "",
"Default (Open AI)": "デフォルト(OpenAI)",
"Default (SentenceTransformers)": "デフォルト (SentenceTransformers)",
"Default Model": "デフォルトモデル",
"Default model updated": "デフォルトモデルが更新されました",
@@ -186,41 +186,41 @@
"Delete All Chats": "すべてのチャットを削除",
"Delete chat": "チャットを削除",
"Delete Chat": "チャットを削除",
"Delete chat?": "",
"Delete Doc": "",
"Delete function?": "",
"Delete prompt?": "",
"Delete chat?": "チャットを削除しますか?",
"Delete Doc": "ドキュメントを削除しますか?",
"Delete function?": "Functionを削除しますか",
"Delete prompt?": "プロンプトを削除しますか?",
"delete this link": "このリンクを削除します",
"Delete tool?": "",
"Delete tool?": "ツールを削除しますか?",
"Delete User": "ユーザーを削除",
"Deleted {{deleteModelTag}}": "{{deleteModelTag}} を削除しました",
"Deleted {{name}}": "{{name}}を削除しました",
"Description": "説明",
"Didn't fully follow instructions": "説明に沿って操作していませんでした",
"Disabled": "",
"Disabled": "無効",
"Discover a function": "",
"Discover a model": "モデルを検出する",
"Discover a prompt": "プロンプトを見つける",
"Discover a tool": "",
"Discover, download, and explore custom functions": "",
"Discover a prompt": "プロンプトを探す",
"Discover a tool": "ツールを探す",
"Discover, download, and explore custom functions": "カスタムFunctionを探しダウンロードする",
"Discover, download, and explore custom prompts": "カスタムプロンプトを見つけて、ダウンロードして、探索",
"Discover, download, and explore custom tools": "",
"Discover, download, and explore custom tools": "カスタムツールを探しダウンロードする",
"Discover, download, and explore model presets": "モデルプリセットを見つけて、ダウンロードして、探索",
"Dismissible": "",
"Display Emoji in Call": "",
"Display the username instead of You in the Chat": "チャットで「あなた」の代わりにユーザー名を表示",
"Do not install functions from sources you do not fully trust.": "",
"Do not install tools from sources you do not fully trust.": "",
"Do not install functions from sources you do not fully trust.": "信楽出来ないソースからFunctionをインストールしないでください。",
"Do not install tools from sources you do not fully trust.": "信頼出来ないソースからツールをインストールしないでください。",
"Document": "ドキュメント",
"Documentation": "",
"Documentation": "ドキュメント",
"Documents": "ドキュメント",
"does not make any external connections, and your data stays securely on your locally hosted server.": "外部接続を行わず、データはローカルでホストされているサーバー上に安全に保持されます。",
"Don't Allow": "許可しない",
"Don't have an account?": "アカウントをお持ちではありませんか?",
"don't install random functions from sources you don't trust.": "",
"don't install random tools from sources you don't trust.": "",
"don't install random functions from sources you don't trust.": "信頼出来ないソースからランダムFunctionをインストールしないでください。",
"don't install random tools from sources you don't trust.": "信頼出来ないソースからランダムツールをインストールしないでください。",
"Don't like the style": "デザインが好きでない",
"Done": "",
"Done": "完了",
"Download": "ダウンロードをキャンセルしました",
"Download canceled": "ダウンロードをキャンセルしました",
"Download Database": "データベースをダウンロード",
@@ -232,21 +232,21 @@
"Edit User": "ユーザーを編集",
"ElevenLabs": "",
"Email": "メールアドレス",
"Embedding Batch Size": "",
"Embedding Batch Size": "埋め込みモデルバッチサイズ",
"Embedding Model": "埋め込みモデル",
"Embedding Model Engine": "埋め込みモデルエンジン",
"Embedding model set to \"{{embedding_model}}\"": "埋め込みモデルを\"{{embedding_model}}\"に設定しました",
"Enable Community Sharing": "コミュニティ共有の有効化",
"Enable Message Rating": "",
"Enable Message Rating": "メッセージRatingの有効化",
"Enable New Sign Ups": "新規登録を有効化",
"Enable Web Search": "Web 検索を有効にする",
"Enable Web Search Query Generation": "",
"Enabled": "",
"Engine": "",
"Enable Web Search Query Generation": "WEBサーチQueryの有効化",
"Enabled": "有効",
"Engine": "エンジン",
"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "CSVファイルに4つの列が含まれていることを確認してください: Name, Email, Password, Role.",
"Enter {{role}} message here": "{{role}} メッセージをここに入力してください",
"Enter a detail about yourself for your LLMs to recall": "LLM が記憶するために、自分についての詳細を入力してください",
"Enter api auth string (e.g. username:password)": "",
"Enter api auth string (e.g. username:password)": "API AuthStringを入力(e.g Username:Password)",
"Enter Brave Search API Key": "Brave Search APIキーの入力",
"Enter CFG Scale (e.g. 7.0)": "",
"Enter Chunk Overlap": "チャンクオーバーラップを入力してください",
@@ -256,76 +256,76 @@
"Enter Google PSE Engine Id": "Google PSE エンジン ID を入力します。",
"Enter Image Size (e.g. 512x512)": "画像サイズを入力してください (例: 512x512)",
"Enter language codes": "言語コードを入力してください",
"Enter Model ID": "",
"Enter Model ID": "モデルIDを入力してください。",
"Enter model tag (e.g. {{modelTag}})": "モデルタグを入力してください (例: {{modelTag}})",
"Enter Number of Steps (e.g. 50)": "ステップ数を入力してください (例: 50)",
"Enter Sampler (e.g. Euler a)": "",
"Enter Scheduler (e.g. Karras)": "",
"Enter Sampler (e.g. Euler a)": "サンプラーを入力してください(e.g. Euler a)。",
"Enter Scheduler (e.g. Karras)": "スケジューラーを入力してください。(e.g. Karras)",
"Enter Score": "スコアを入力してください",
"Enter SearchApi API Key": "",
"Enter SearchApi Engine": "",
"Enter SearchApi API Key": "SearchApi API Keyを入力してください。",
"Enter SearchApi Engine": "SearchApi Engineを入力してください。",
"Enter Searxng Query URL": "SearxngクエリURLを入力",
"Enter Serper API Key": "Serper APIキーの入力",
"Enter Serply API Key": "",
"Enter Serply API Key": "Serply API Keyを入力してください。",
"Enter Serpstack API Key": "Serpstack APIキーの入力",
"Enter stop sequence": "ストップシーケンスを入力してください",
"Enter system prompt": "",
"Enter Tavily API Key": "",
"Enter Tika Server URL": "",
"Enter system prompt": "システムプロンプト入力",
"Enter Tavily API Key": "Tavily API Keyを入力してください。",
"Enter Tika Server URL": "Tika Server URLを入力してください。",
"Enter Top K": "トップ K を入力してください",
"Enter URL (e.g. http://127.0.0.1:7860/)": "URL を入力してください (例: http://127.0.0.1:7860/)",
"Enter URL (e.g. http://localhost:11434)": "URL を入力してください (例: http://localhost:11434)",
"Enter Your Email": "メールアドレスを入力してください",
"Enter Your Full Name": "フルネームを入力してください",
"Enter your message": "",
"Enter your message": "メッセージを入力してください。",
"Enter Your Password": "パスワードを入力してください",
"Enter Your Role": "ロールを入力してください",
"Error": "エラー",
"Experimental": "実験",
"Experimental": "実験",
"Export": "輸出",
"Export All Chats (All Users)": "すべてのチャットをエクスポート (すべてのユーザー)",
"Export chat (.json)": "",
"Export chat (.json)": "チャットをエクスポート(.json)",
"Export Chats": "チャットをエクスポート",
"Export Config to JSON File": "",
"Export Config to JSON File": "JSONファイルのエクスポートConfig",
"Export Documents Mapping": "ドキュメントマッピングをエクスポート",
"Export Functions": "",
"Export Functions": "Functionのエクスポート",
"Export LiteLLM config.yaml": "",
"Export Models": "モデルのエクスポート",
"Export Prompts": "プロンプトをエクスポート",
"Export Tools": "",
"External Models": "",
"Export Tools": "ツールのエクスポート",
"External Models": "外部モデル",
"Failed to create API Key.": "APIキーの作成に失敗しました。",
"Failed to read clipboard contents": "クリップボードの内容を読み取れませんでした",
"Failed to update settings": "",
"Failed to upload file.": "",
"Failed to update settings": "設定アップデート失敗",
"Failed to upload file.": "ファイルアップロード失敗",
"February": "2月",
"Feel free to add specific details": "詳細を追加してください",
"File": "",
"File added successfully.": "",
"File content updated successfully.": "",
"File": "ファイル",
"File added successfully.": "ファイル追加が成功しました。",
"File content updated successfully.": "ファイルコンテンツ追加が成功しました。",
"File Mode": "ファイルモード",
"File not found.": "ファイルが見つかりません。",
"File removed successfully.": "",
"File size should not exceed {{maxSize}} MB.": "",
"Files": "",
"Filter is now globally disabled": "",
"Filter is now globally enabled": "",
"Filters": "",
"File removed successfully.": "ファイル削除が成功しました。",
"File size should not exceed {{maxSize}} MB.": "ファイルサイズ最大値{{maxSize}} MB",
"Files": "ファイル",
"Filter is now globally disabled": "グローバルフィルタが無効です。",
"Filter is now globally enabled": "グローバルフィルタが有効です。",
"Filters": "フィルター",
"Fingerprint spoofing detected: Unable to use initials as avatar. Defaulting to default profile image.": "指紋のなりすましが検出されました: イニシャルをアバターとして使用できません。デフォルトのプロファイル画像にデフォルト設定されています。",
"Fluidly stream large external response chunks": "大規模な外部応答チャンクを流動的にストリーミングする",
"Focus chat input": "チャット入力をフォーカス",
"Followed instructions perfectly": "完全に指示に従った",
"Form": "",
"Form": "フォーム",
"Format your variables using square brackets like this:": "次のように角括弧を使用して変数をフォーマットします。",
"Frequency Penalty": "周波数ペナルティ",
"Function created successfully": "",
"Function deleted successfully": "",
"Function Description (e.g. A filter to remove profanity from text)": "",
"Frequency Penalty": "繰り返しペナルティ",
"Function created successfully": "Functonの作成が成功しました。",
"Function deleted successfully": "Functionの削除が成功しました。",
"Function Description (e.g. A filter to remove profanity from text)": "Function詳細",
"Function ID (e.g. my_filter)": "",
"Function is now globally disabled": "",
"Function is now globally enabled": "",
"Function is now globally disabled": "Functionはグローバルで無効です。",
"Function is now globally enabled": "Functionはグローバルで有効です。",
"Function Name (e.g. My Filter)": "",
"Function updated successfully": "",
"Function updated successfully": "Functionのアップデートが成功しました。",
"Functions": "",
"Functions allow arbitrary code execution": "",
"Functions allow arbitrary code execution.": "",
@@ -336,7 +336,7 @@
"Generating search query": "検索クエリの生成",
"Generation Info": "生成情報",
"Get up and running with": "",
"Global": "",
"Global": "グローバル",
"Good Response": "良い応答",
"Google PSE API Key": "Google PSE APIキー",
"Google PSE Engine Id": "Google PSE エンジン ID",
@@ -357,10 +357,10 @@
"Import Chats": "チャットをインポート",
"Import Config from JSON File": "",
"Import Documents Mapping": "ドキュメントマッピングをインポート",
"Import Functions": "",
"Import Functions": "Functionのインポート",
"Import Models": "モデルのインポート",
"Import Prompts": "プロンプトをインポート",
"Import Tools": "",
"Import Tools": "ツールのインポート",
"Include `--api-auth` flag when running stable-diffusion-webui": "",
"Include `--api` flag when running stable-diffusion-webui": "stable-diffusion-webuiを実行する際に`--api`フラグを含める",
"Info": "情報",
@@ -379,12 +379,12 @@
"JWT Token": "JWT トークン",
"Keep Alive": "キープアライブ",
"Keyboard shortcuts": "キーボードショートカット",
"Knowledge": "",
"Knowledge created successfully.": "",
"Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "",
"Knowledge updated successfully": "",
"Landing Page Mode": "",
"Knowledge": "RAGファイル",
"Knowledge created successfully.": "RAGファイル識別タグ作成完了",
"Knowledge deleted successfully.": "RAGファイル識別タグ削除完了",
"Knowledge reset successfully.": "RAGファイルリセット",
"Knowledge updated successfully": "RAGファイルアップデート完了",
"Landing Page Mode": "ランディングページモード",
"Language": "言語",
"large language models, locally.": "",
"Last Active": "最終アクティブ",
@@ -411,10 +411,10 @@
"May": "5月",
"Memories accessible by LLMs will be shown here.": "LLM がアクセスできるメモリはここに表示されます。",
"Memory": "メモリ",
"Memory added successfully": "",
"Memory cleared successfully": "",
"Memory deleted successfully": "",
"Memory updated successfully": "",
"Memory added successfully": "メモリに追加されました。",
"Memory cleared successfully": "メモリをクリアしました。",
"Memory deleted successfully": "メモリを削除しました。",
"Memory updated successfully": "メモリアップデート成功",
"Merge Responses": "",
"Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "リンクを作成した後、送信したメッセージは共有されません。URL を持つユーザーは共有チャットを閲覧できます。",
"Min P": "",
@@ -567,17 +567,17 @@
"Search": "検索",
"Search a model": "モデルを検索",
"Search Chats": "チャットの検索",
"Search Collection": "",
"Search Collection": "Collectionの検索",
"Search Documents": "ドキュメントを検索",
"Search Functions": "",
"Search Knowledge": "",
"Search Functions": "Functionの検索",
"Search Knowledge": "RAGファイルの検索",
"Search Models": "モデル検索",
"Search Prompts": "プロンプトを検索",
"Search Query Generation Prompt": "",
"Search Query Generation Prompt": "Query生成プロンプトの検索",
"Search Result Count": "検索結果数",
"Search Tools": "",
"SearchApi API Key": "",
"SearchApi Engine": "",
"Search Tools": "ツールの検索",
"SearchApi API Key": "SearchApiのAPIKey",
"SearchApi Engine": "SearchApiエンジン",
"Searched {{count}} sites_other": "{{count}} sites_other検索",
"Searching \"{{searchQuery}}\"": "",
"Searching Knowledge for \"{{searchQuery}}\"": "",
@@ -586,15 +586,15 @@
"See what's new": "新機能を見る",
"Seed": "シード",
"Select a base model": "基本モデルの選択",
"Select a engine": "",
"Select a function": "",
"Select a engine": "エンジンの選択",
"Select a function": "Functionの選択",
"Select a model": "モデルを選択",
"Select a pipeline": "パイプラインの選択",
"Select a pipeline url": "パイプラインの URL を選択する",
"Select a tool": "",
"Select a tool": "ツールの選択",
"Select an Ollama instance": "Ollama インスタンスを選択",
"Select Engine": "",
"Select Knowledge": "",
"Select Engine": "エンジンの選択",
"Select Knowledge": "RAGデータの選択",
"Select model": "モデルを選択",
"Select only one model to call": "",
"Select/Add Files": "",
@@ -659,7 +659,7 @@
"Tap to interrupt": "",
"Tavily API Key": "",
"Tell us more:": "もっと話してください:",
"Temperature": "温度",
"Temperature": "生成時予測幅(Tenperature)",
"Template": "テンプレート",
"Temporary Chat": "",
"Text Completion": "テキスト補完",
@@ -671,10 +671,10 @@
"The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "",
"The score should be a value between 0.0 (0%) and 1.0 (100%).": "スコアは0.0(0%)から1.0(100%)の間の値にしてください。",
"Theme": "テーマ",
"Thinking...": "",
"Thinking...": "思考中...",
"This action cannot be undone. Do you wish to continue?": "",
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "これは、貴重な会話がバックエンドデータベースに安全に保存されることを保証します。ありがとうございます!",
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "",
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "開発中の機能であり正常動作しない場合があります。",
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "",
"This will delete": "",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
@@ -713,9 +713,9 @@
"Top K": "トップ K",
"Top P": "トップ P",
"Trouble accessing Ollama?": "Ollama へのアクセスに問題がありますか?",
"TTS Model": "",
"TTS Model": "TTSモデル",
"TTS Settings": "TTS 設定",
"TTS Voice": "",
"TTS Voice": "TTSボイス",
"Type": "種類",
"Type Hugging Face Resolve (Download) URL": "Hugging Face Resolve (ダウンロード) URL を入力してください",
"Uh-oh! There was an issue connecting to {{provider}}.": "おっと! {{provider}} への接続に問題が発生しました。",
@@ -728,13 +728,13 @@
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "GGUF モデルをアップロード",
"Upload directory": "",
"Upload files": "",
"Upload directory": "アップロードディレクトリ",
"Upload files": "アップロードファイル",
"Upload Files": "ファイルのアップロード",
"Upload Pipeline": "",
"Upload Pipeline": "アップロードパイプライン",
"Upload Progress": "アップロードの進行状況",
"URL Mode": "URL モード",
"Use '#' in the prompt input to load and include your knowledge.": "",
"Use '#' in the prompt input to load and include your knowledge.": "#を入力するとRAGデータを参照することが出来ます。",
"Use '#' in the prompt input to load and select your documents.": "プロンプト入力で '#' を使用して、ドキュメントを読み込んで選択します。",
"Use Gravatar": "Gravatar を使用する",
"Use Initials": "初期値を使用する",
@@ -753,9 +753,9 @@
"variable to have them replaced with clipboard content.": "クリップボードの内容に置き換える変数。",
"Version": "バージョン",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"Voice": "",
"Voice": "ボイス",
"Warning": "警告",
"Warning:": "",
"Warning:": "警告",
"Warning: If you update or change your embedding model, you will need to re-import all documents.": "警告: 埋め込みモデルを更新または変更した場合は、すべてのドキュメントを再インポートする必要があります。",
"Web": "ウェブ",
"Web API": "",
@@ -775,13 +775,13 @@
"You": "あなた",
"You can only chat with a maximum of {{maxCount}} file(s) at a time.": "",
"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "",
"You cannot clone a base model": "基本モデルのクローン作成できない",
"You cannot clone a base model": "基本モデルのクローン作成できない",
"You have no archived conversations.": "これまでにアーカイブされた会話はありません。",
"You have shared this chat": "このチャットを共有しました",
"You're a helpful assistant.": "あなたは役に立つアシスタントです。",
"You're a helpful assistant.": "あなたは有能なアシスタントです。",
"You're now logged in.": "ログインしました。",
"Your account status is currently pending activation.": "",
"Your account status is currently pending activation.": "貴方のアカウント状態は現在登録認証待ちです。",
"Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "",
"Youtube": "YouTube",
"Youtube Loader Settings": "Youtubeローダー設定"
"Youtube Loader Settings": "Youtubeローダー設定(日本語はja)"
}

View File

@@ -294,6 +294,7 @@
"Export Prompts": "მოთხოვნების ექსპორტი",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "API ღილაკის შექმნა ვერ მოხერხდა.",
"Failed to read clipboard contents": "ბუფერში შიგთავსის წაკითხვა ვერ მოხერხდა",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "დაასახელეთ თქვენი მოდელი",
"New Chat": "ახალი მიმოწერა",
"New Password": "ახალი პაროლი",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "სიდი",
"Select a base model": "აირჩიეთ ბაზის მოდელი",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "მოდელის არჩევა",
"Select a pipeline": "აირჩიეთ მილსადენი",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "მოდელის არჩევა",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "შერჩეული მოდელი (ებ) ი არ უჭერს მხარს გამოსახულების შეყვანას",
"Send": "გაგზავნა",
"Send a Message": "შეტყობინების გაგზავნა",
@@ -726,6 +728,7 @@
"Update and Copy Link": "განახლება და ბმულის კოპირება",
"Update for the latest features and improvements.": "",
"Update password": "პაროლის განახლება",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "GGUF მოდელის ატვირთვა",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "프롬프트 내보내기",
"Export Tools": "도구 내보내기",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "API 키 생성에 실패했습니다.",
"Failed to read clipboard contents": "클립보드 내용을 읽는 데 실패하였습니다.",
"Failed to update settings": "설정 업데이트에 실패하였습니다.",
@@ -449,6 +450,7 @@
"Name your model": "모델 이름 지정",
"New Chat": "새 채팅",
"New Password": "새 비밀번호",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "시드",
"Select a base model": "기본 모델 선택",
"Select a engine": "엔진 선택",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "모델 선택",
"Select a pipeline": "파이프라인 선택",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "모델 선택",
"Select only one model to call": "콜을 위해서는 모델을 하나만 선택해야 합니다.",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "선택한 모델은 이미지 입력을 지원하지 않습니다.",
"Send": "보내기",
"Send a Message": "메시지 보내기",
@@ -726,6 +728,7 @@
"Update and Copy Link": "링크 업데이트 및 복사",
"Update for the latest features and improvements.": "",
"Update password": "비밀번호 업데이트",
"Updated": "",
"Updated at": "다음에 업데이트됨",
"Upload": "업로드",
"Upload a GGUF model": "GGUF 모델 업로드",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Eksportuoti užklausas",
"Export Tools": "Eksportuoti įrankius",
"External Models": "Išoriniai modeliai",
"Failed to add file.": "",
"Failed to create API Key.": "Nepavyko sukurti API rakto",
"Failed to read clipboard contents": "Nepavyko perskaityti kopijuoklės",
"Failed to update settings": "Nepavyko atnaujinti nustatymų",
@@ -449,6 +450,7 @@
"Name your model": "Pavadinkite savo modelį",
"New Chat": "Naujas pokalbis",
"New Password": "Naujas slaptažodis",
"No content found": "",
"No content to speak": "Nėra turinio kalbėjimui",
"No file selected": "Nėra pasirinktų dokumentų",
"No HTML, CSS, or JavaScript content found.": "",
@@ -590,6 +592,7 @@
"Seed": "Sėkla",
"Select a base model": "Pasirinkite bazinį modelį",
"Select a engine": "Pasirinkite variklį",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Pasirinkite funkciją",
"Select a model": "Pasirinkti modelį",
"Select a pipeline": "Pasirinkite procesą",
@@ -600,7 +603,6 @@
"Select Knowledge": "",
"Select model": "Pasirinkti modelį",
"Select only one model to call": "Pasirinkite vieną modelį",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Pasirinkti modeliai nepalaiko vaizdinių užklausų",
"Send": "Siųsti",
"Send a Message": "Siųsti žinutę",
@@ -728,6 +730,7 @@
"Update and Copy Link": "Atnaujinti ir kopijuoti nuorodą",
"Update for the latest features and improvements.": "",
"Update password": "Atnaujinti slaptažodį",
"Updated": "",
"Updated at": "Atnaujinta",
"Upload": "Atnaujinti",
"Upload a GGUF model": "Parsisiųsti GGUF modelį",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Eksport Gesaan",
"Export Tools": "Eksport Alat",
"External Models": "Model Luaran",
"Failed to add file.": "",
"Failed to create API Key.": "Gagal mencipta kekunci API",
"Failed to read clipboard contents": "Gagal membaca konten papan klip",
"Failed to update settings": "Gagal mengemaskini tetapan",
@@ -449,6 +450,7 @@
"Name your model": "Namakan Model Anda",
"New Chat": "Perbualan Baru",
"New Password": "Kata Laluan Baru",
"No content found": "",
"No content to speak": "Tiada kandungan untuk bercakap",
"No file selected": "Tiada fail dipilih",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Benih",
"Select a base model": "Pilih model asas",
"Select a engine": "Pilih enjin",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Pilih fungsi",
"Select a model": "Pilih model",
"Select a pipeline": "Pilih 'pipeline'",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "Pilih model",
"Select only one model to call": "Pilih hanya satu model untuk dipanggil",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Model dipilih tidak menyokong input imej",
"Send": "Hantar",
"Send a Message": "Hantar Pesanan",
@@ -726,6 +728,7 @@
"Update and Copy Link": "Kemaskini dan salin pautan",
"Update for the latest features and improvements.": "",
"Update password": "Kemaskini Kata Laluan",
"Updated": "",
"Updated at": "Dikemaskini pada",
"Upload": "Muatnaik",
"Upload a GGUF model": "Muatnaik model GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Eksporter prompts",
"Export Tools": "Eksporter verktøy",
"External Models": "Eksterne modeller",
"Failed to add file.": "",
"Failed to create API Key.": "Kunne ikke opprette API-nøkkel.",
"Failed to read clipboard contents": "Kunne ikke lese utklippstavleinnhold",
"Failed to update settings": "Kunne ikke oppdatere innstillinger",
@@ -449,6 +450,7 @@
"Name your model": "Gi modellen din et navn",
"New Chat": "Ny chat",
"New Password": "Nytt passord",
"No content found": "",
"No content to speak": "Mangler innhold for tale",
"No file selected": "Ingen fil valgt",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Seed",
"Select a base model": "Velg en grunnmodell",
"Select a engine": "Velg en motor",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Velg en funksjon",
"Select a model": "Velg en modell",
"Select a pipeline": "Velg en pipeline",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "Velg modell",
"Select only one model to call": "Velg kun én modell å kalle",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Valgte modell(er) støtter ikke bildeforslag",
"Send": "Send",
"Send a Message": "Send en melding",
@@ -726,6 +728,7 @@
"Update and Copy Link": "Oppdater og kopier lenke",
"Update for the latest features and improvements.": "",
"Update password": "Oppdater passord",
"Updated": "",
"Updated at": "Oppdatert",
"Upload": "Last opp",
"Upload a GGUF model": "Last opp en GGUF-modell",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Exporteer Prompts",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "Kan API Key niet aanmaken.",
"Failed to read clipboard contents": "Kan klembord inhoud niet lezen",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "Geef uw model een naam",
"New Chat": "Nieuwe Chat",
"New Password": "Nieuw Wachtwoord",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Seed",
"Select a base model": "Selecteer een basismodel",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Selecteer een model",
"Select a pipeline": "Selecteer een pijplijn",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "Selecteer een model",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Geselecteerde modellen ondersteunen geen beeldinvoer",
"Send": "Verzenden",
"Send a Message": "Stuur een Bericht",
@@ -726,6 +728,7 @@
"Update and Copy Link": "Update en Kopieer Link",
"Update for the latest features and improvements.": "",
"Update password": "Wijzig wachtwoord",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Upload een GGUF model",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "ਪ੍ਰੰਪਟ ਨਿਰਯਾਤ ਕਰੋ",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "API ਕੁੰਜੀ ਬਣਾਉਣ ਵਿੱਚ ਅਸਫਲ।",
"Failed to read clipboard contents": "ਕਲਿੱਪਬੋਰਡ ਸਮੱਗਰੀ ਪੜ੍ਹਣ ਵਿੱਚ ਅਸਫਲ",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "ਆਪਣੇ ਮਾਡਲ ਦਾ ਨਾਮ ਦੱਸੋ",
"New Chat": "ਨਵੀਂ ਗੱਲਬਾਤ",
"New Password": "ਨਵਾਂ ਪਾਸਵਰਡ",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "ਬੀਜ",
"Select a base model": "ਆਧਾਰ ਮਾਡਲ ਚੁਣੋ",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "ਇੱਕ ਮਾਡਲ ਚੁਣੋ",
"Select a pipeline": "ਪਾਈਪਲਾਈਨ ਚੁਣੋ",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "ਮਾਡਲ ਚੁਣੋ",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "ਚੁਣੇ ਗਏ ਮਾਡਲ(ਆਂ) ਚਿੱਤਰ ਇਨਪੁੱਟਾਂ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੇ",
"Send": "ਭੇਜੋ",
"Send a Message": "ਇੱਕ ਸੁਨੇਹਾ ਭੇਜੋ",
@@ -726,6 +728,7 @@
"Update and Copy Link": "ਅੱਪਡੇਟ ਕਰੋ ਅਤੇ ਲਿੰਕ ਕਾਪੀ ਕਰੋ",
"Update for the latest features and improvements.": "",
"Update password": "ਪਾਸਵਰਡ ਅੱਪਡੇਟ ਕਰੋ",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "ਇੱਕ GGUF ਮਾਡਲ ਅਪਲੋਡ ਕਰੋ",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Eksportuj prompty",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "Nie udało się utworzyć klucza API.",
"Failed to read clipboard contents": "Nie udało się odczytać zawartości schowka",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "Nazwij swój model",
"New Chat": "Nowy czat",
"New Password": "Nowe hasło",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -590,6 +592,7 @@
"Seed": "Seed",
"Select a base model": "Wybieranie modelu bazowego",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Wybierz model",
"Select a pipeline": "Wybieranie potoku",
@@ -600,7 +603,6 @@
"Select Knowledge": "",
"Select model": "Wybierz model",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Wybrane modele nie obsługują danych wejściowych obrazu",
"Send": "Wyślij",
"Send a Message": "Wyślij Wiadomość",
@@ -728,6 +730,7 @@
"Update and Copy Link": "Uaktualnij i skopiuj link",
"Update for the latest features and improvements.": "",
"Update password": "Aktualizacja hasła",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Prześlij model GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Exportar Prompts",
"Export Tools": "Exportar Ferramentas",
"External Models": "Modelos Externos",
"Failed to add file.": "",
"Failed to create API Key.": "Falha ao criar a Chave API.",
"Failed to read clipboard contents": "Falha ao ler o conteúdo da área de transferência",
"Failed to update settings": "Falha ao atualizar as configurações",
@@ -449,6 +450,7 @@
"Name your model": "Nomeie seu modelo",
"New Chat": "Novo Chat",
"New Password": "Nova Senha",
"No content found": "",
"No content to speak": "Sem conteúdo para falar",
"No file selected": "Nenhum arquivo selecionado",
"No HTML, CSS, or JavaScript content found.": "",
@@ -589,6 +591,7 @@
"Seed": "Seed",
"Select a base model": "Selecione um modelo base",
"Select a engine": "Selecione um motor",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Selecione uma função",
"Select a model": "Selecione um modelo",
"Select a pipeline": "Selecione um pipeline",
@@ -599,7 +602,6 @@
"Select Knowledge": "",
"Select model": "Selecionar modelo",
"Select only one model to call": "Selecione apenas um modelo para chamar",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Modelo(s) selecionado(s) não suportam entradas de imagem",
"Send": "Enviar",
"Send a Message": "Enviar uma Mensagem",
@@ -727,6 +729,7 @@
"Update and Copy Link": "Atualizar e Copiar Link",
"Update for the latest features and improvements.": "",
"Update password": "Atualizar senha",
"Updated": "",
"Updated at": "Atualizado em",
"Upload": "Fazer upload",
"Upload a GGUF model": "Fazer upload de um modelo GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Exportar Prompts",
"Export Tools": "",
"External Models": "Modelos Externos",
"Failed to add file.": "",
"Failed to create API Key.": "Falha ao criar a Chave da API.",
"Failed to read clipboard contents": "Falha ao ler o conteúdo da área de transferência",
"Failed to update settings": "Falha ao atualizar as definições",
@@ -449,6 +450,7 @@
"Name your model": "Atribua um nome ao seu modelo",
"New Chat": "Nova Conversa",
"New Password": "Nova Senha",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -589,6 +591,7 @@
"Seed": "Semente",
"Select a base model": "Selecione um modelo base",
"Select a engine": "Selecione um motor",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Selecione um modelo",
"Select a pipeline": "Selecione um pipeline",
@@ -599,7 +602,6 @@
"Select Knowledge": "",
"Select model": "Selecione o modelo",
"Select only one model to call": "Selecione apenas um modelo para a chamada",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "O(s) modelo(s) selecionado(s) não suporta(m) entradas de imagem",
"Send": "Enviar",
"Send a Message": "Enviar uma Mensagem",
@@ -727,6 +729,7 @@
"Update and Copy Link": "Atualizar e Copiar Link",
"Update for the latest features and improvements.": "",
"Update password": "Atualizar senha",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Carregar um modelo GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Exportă Prompturile",
"Export Tools": "Exportă Instrumentele",
"External Models": "Modele Externe",
"Failed to add file.": "",
"Failed to create API Key.": "Crearea cheii API a eșuat.",
"Failed to read clipboard contents": "Citirea conținutului clipboard-ului a eșuat",
"Failed to update settings": "Actualizarea setărilor a eșuat",
@@ -449,6 +450,7 @@
"Name your model": "Denumirea modelului",
"New Chat": "Conversație Nouă",
"New Password": "Parolă Nouă",
"No content found": "",
"No content to speak": "Nu există conținut de vorbit",
"No file selected": "Nu a fost selectat niciun fișier",
"No HTML, CSS, or JavaScript content found.": "",
@@ -589,6 +591,7 @@
"Seed": "Sămânță",
"Select a base model": "Selectează un model de bază",
"Select a engine": "Selectează un motor",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Selectează o funcție",
"Select a model": "Selectează un model",
"Select a pipeline": "Selectează o conductă",
@@ -599,7 +602,6 @@
"Select Knowledge": "",
"Select model": "Selectează model",
"Select only one model to call": "Selectează doar un singur model pentru apel",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Modelul(e) selectat(e) nu suportă intrări de imagine",
"Send": "Trimite",
"Send a Message": "Trimite un Mesaj",
@@ -727,6 +729,7 @@
"Update and Copy Link": "Actualizează și Copiază Link-ul",
"Update for the latest features and improvements.": "",
"Update password": "Actualizează parola",
"Updated": "",
"Updated at": "Actualizat la",
"Upload": "Încărcare",
"Upload a GGUF model": "Încarcă un model GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Экспортировать промпты",
"Export Tools": "Экспортировать инструменты",
"External Models": "Внешние модели",
"Failed to add file.": "",
"Failed to create API Key.": "Не удалось создать ключ API.",
"Failed to read clipboard contents": "Не удалось прочитать содержимое буфера обмена",
"Failed to update settings": "Не удалось обновить настройки",
@@ -449,6 +450,7 @@
"Name your model": "Присвойте модели имя",
"New Chat": "Новый чат",
"New Password": "Новый пароль",
"No content found": "",
"No content to speak": "Нечего говорить",
"No file selected": "Файлы не выбраны",
"No HTML, CSS, or JavaScript content found.": "",
@@ -590,6 +592,7 @@
"Seed": "Сид",
"Select a base model": "Выберите базовую модель",
"Select a engine": "Выберите движок",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Выберите функцию",
"Select a model": "Выберите модель",
"Select a pipeline": "Выберите конвейер",
@@ -600,7 +603,6 @@
"Select Knowledge": "",
"Select model": "Выберите модель",
"Select only one model to call": "Выберите только одну модель для вызова",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Выбранные модели не поддерживают ввод изображений",
"Send": "Отправить",
"Send a Message": "Отправить сообщение",
@@ -728,6 +730,7 @@
"Update and Copy Link": "Обновить и скопировать ссылку",
"Update for the latest features and improvements.": "Обновитесь для получения последних функций и улучшений.",
"Update password": "Обновить пароль",
"Updated": "",
"Updated at": "Обновлено",
"Upload": "Загрузить",
"Upload a GGUF model": "Загрузить модель GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Извези упите",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "Неуспешно стварање API кључа.",
"Failed to read clipboard contents": "Неуспешно читање садржаја оставе",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "Наведи свој модел",
"New Chat": "Ново ћаскање",
"New Password": "Нова лозинка",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -589,6 +591,7 @@
"Seed": "Семе",
"Select a base model": "Избор основног модела",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Изабери модел",
"Select a pipeline": "Избор цевовода",
@@ -599,7 +602,6 @@
"Select Knowledge": "",
"Select model": "Изабери модел",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Изабрани модели не подржавају уносе слика",
"Send": "Пошаљи",
"Send a Message": "Пошаљи поруку",
@@ -727,6 +729,7 @@
"Update and Copy Link": "Ажурирај и копирај везу",
"Update for the latest features and improvements.": "",
"Update password": "Ажурирај лозинку",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Отпреми GGUF модел",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Exportera instruktioner",
"Export Tools": "Exportera verktyg",
"External Models": "Externa modeller",
"Failed to add file.": "",
"Failed to create API Key.": "Misslyckades med att skapa API-nyckel.",
"Failed to read clipboard contents": "Misslyckades med att läsa urklippsinnehåll",
"Failed to update settings": "Misslyckades med att uppdatera inställningarna",
@@ -449,6 +450,7 @@
"Name your model": "Namnge din modell",
"New Chat": "Ny chatt",
"New Password": "Nytt lösenord",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Seed",
"Select a base model": "Välj en basmodell",
"Select a engine": "Välj en motor",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "Välj en modell",
"Select a pipeline": "Välj en rörledning",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "Välj en modell",
"Select only one model to call": "Välj endast en modell att ringa",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Valda modeller stöder inte bildinmatningar",
"Send": "Skicka",
"Send a Message": "Skicka ett meddelande",
@@ -726,6 +728,7 @@
"Update and Copy Link": "Uppdatera och kopiera länk",
"Update for the latest features and improvements.": "",
"Update password": "Uppdatera lösenord",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "Ladda upp en GGUF-modell",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "ส่งออกพรอมต์",
"Export Tools": "ส่งออกเครื่องมือ",
"External Models": "โมเดลภายนอก",
"Failed to add file.": "",
"Failed to create API Key.": "สร้างคีย์ API ล้มเหลว",
"Failed to read clipboard contents": "อ่านเนื้อหาคลิปบอร์ดล้มเหลว",
"Failed to update settings": "อัปเดตการตั้งค่าล้มเหลว",
@@ -449,6 +450,7 @@
"Name your model": "ตั้งชื่อโมเดลของคุณ",
"New Chat": "แชทใหม่",
"New Password": "รหัสผ่านใหม่",
"No content found": "",
"No content to speak": "ไม่มีเนื้อหาที่จะพูด",
"No file selected": "ไม่ได้เลือกไฟล์",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Seed",
"Select a base model": "เลือกโมเดลฐาน",
"Select a engine": "เลือกเอนจิน",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "เลือกฟังก์ชัน",
"Select a model": "เลือกโมเดล",
"Select a pipeline": "เลือกไปป์ไลน์",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "เลือกโมเดล",
"Select only one model to call": "เลือกเพียงโมเดลเดียวที่จะใช้",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "โมเดลที่เลือกไม่รองรับภาพ",
"Send": "ส่ง",
"Send a Message": "ส่งข้อความ",
@@ -726,6 +728,7 @@
"Update and Copy Link": "อัปเดตและคัดลอกลิงก์",
"Update for the latest features and improvements.": "",
"Update password": "อัปเดตรหัสผ่าน",
"Updated": "",
"Updated at": "อัปเดตเมื่อ",
"Upload": "อัปโหลด",
"Upload a GGUF model": "อัปโหลดโมเดล GGUF",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "",
"Export Tools": "",
"External Models": "",
"Failed to add file.": "",
"Failed to create API Key.": "",
"Failed to read clipboard contents": "",
"Failed to update settings": "",
@@ -449,6 +450,7 @@
"Name your model": "",
"New Chat": "",
"New Password": "",
"No content found": "",
"No content to speak": "",
"No file selected": "",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "",
"Select a base model": "",
"Select a engine": "",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "",
"Select a model": "",
"Select a pipeline": "",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "",
"Select only one model to call": "",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "",
"Send": "",
"Send a Message": "",
@@ -726,6 +728,7 @@
"Update and Copy Link": "",
"Update for the latest features and improvements.": "",
"Update password": "",
"Updated": "",
"Updated at": "",
"Upload": "",
"Upload a GGUF model": "",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Promptları Dışa Aktar",
"Export Tools": "Araçları Dışa Aktar",
"External Models": "Modelleri Dışa Aktar",
"Failed to add file.": "",
"Failed to create API Key.": "API Anahtarı oluşturulamadı.",
"Failed to read clipboard contents": "Pano içeriği okunamadı",
"Failed to update settings": "Ayarlar güncellenemedi",
@@ -449,6 +450,7 @@
"Name your model": "Modelinizi Adlandırın",
"New Chat": "Yeni Sohbet",
"New Password": "Yeni Parola",
"No content found": "",
"No content to speak": "Konuşacak içerik yok",
"No file selected": "Hiçbir dosya seçilmedi",
"No HTML, CSS, or JavaScript content found.": "",
@@ -588,6 +590,7 @@
"Seed": "Seed",
"Select a base model": "Bir temel model seç",
"Select a engine": "Bir motor seç",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Bir fonksiyon seç",
"Select a model": "Bir model seç",
"Select a pipeline": "Bir pipeline seç",
@@ -598,7 +601,6 @@
"Select Knowledge": "",
"Select model": "Model seç",
"Select only one model to call": "Arama için sadece bir model seç",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Seçilen model(ler) görüntü girişlerini desteklemiyor",
"Send": "Gönder",
"Send a Message": "Bir Mesaj Gönder",
@@ -726,6 +728,7 @@
"Update and Copy Link": "Güncelle ve Bağlantıyı Kopyala",
"Update for the latest features and improvements.": "",
"Update password": "Parolayı Güncelle",
"Updated": "",
"Updated at": "Şu tarihte güncellendi:",
"Upload": "Yükle",
"Upload a GGUF model": "Bir GGUF modeli yükle",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Експортувати промти",
"Export Tools": "Експортувати інструменти",
"External Models": "Зовнішні моделі",
"Failed to add file.": "",
"Failed to create API Key.": "Не вдалося створити API ключ.",
"Failed to read clipboard contents": "Не вдалося прочитати вміст буфера обміну",
"Failed to update settings": "Не вдалося оновити налаштування",
@@ -449,6 +450,7 @@
"Name your model": "Назвіть свою модель",
"New Chat": "Новий чат",
"New Password": "Новий пароль",
"No content found": "",
"No content to speak": "Нема чого говорити",
"No file selected": "Файл не обрано",
"No HTML, CSS, or JavaScript content found.": "",
@@ -590,6 +592,7 @@
"Seed": "Сід",
"Select a base model": "Обрати базову модель",
"Select a engine": "Оберіть рушій",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Оберіть функцію",
"Select a model": "Оберіть модель",
"Select a pipeline": "Оберіть конвеєр",
@@ -600,7 +603,6 @@
"Select Knowledge": "",
"Select model": "Обрати модель",
"Select only one model to call": "Оберіть лише одну модель для виклику",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Вибрані модель(і) не підтримують вхідні зображення",
"Send": "Надіслати",
"Send a Message": "Надіслати повідомлення",
@@ -728,6 +730,7 @@
"Update and Copy Link": "Оновлення та копіювання посилання",
"Update for the latest features and improvements.": "Оновіть програми для нових функцій та покращень.",
"Update password": "Оновити пароль",
"Updated": "",
"Updated at": "Оновлено на",
"Upload": "Завантажити",
"Upload a GGUF model": "Завантажити GGUF модель",

View File

@@ -294,6 +294,7 @@
"Export Prompts": "Tải các prompt về máy",
"Export Tools": "Tải Tools về máy",
"External Models": "Các model ngoài",
"Failed to add file.": "",
"Failed to create API Key.": "Lỗi khởi tạo API Key",
"Failed to read clipboard contents": "Không thể đọc nội dung clipboard",
"Failed to update settings": "Lỗi khi cập nhật các cài đặt",
@@ -449,6 +450,7 @@
"Name your model": "Tên model",
"New Chat": "Tạo chat mới",
"New Password": "Mật khẩu mới",
"No content found": "",
"No content to speak": "Không có nội dung để nói",
"No file selected": "Chưa có tệp nào được chọn",
"No HTML, CSS, or JavaScript content found.": "",
@@ -587,6 +589,7 @@
"Seed": "Seed",
"Select a base model": "Chọn một base model",
"Select a engine": "Chọn dịch vụ",
"Select a file to view or drag and drop a file to upload": "",
"Select a function": "Chọn function",
"Select a model": "Chọn mô hình",
"Select a pipeline": "Chọn một quy trình",
@@ -597,7 +600,6 @@
"Select Knowledge": "",
"Select model": "Chọn model",
"Select only one model to call": "Chọn model để gọi",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "Model được lựa chọn không hỗ trợ đầu vào là hình ảnh",
"Send": "Gửi",
"Send a Message": "Gửi yêu cầu",
@@ -725,6 +727,7 @@
"Update and Copy Link": "Cập nhật và sao chép link",
"Update for the latest features and improvements.": "",
"Update password": "Cập nhật mật khẩu",
"Updated": "",
"Updated at": "Cập nhật lúc",
"Upload": "",
"Upload a GGUF model": "Tải lên mô hình GGUF",

View File

@@ -68,8 +68,8 @@
"Archived Chats": "已归档对话",
"are allowed - Activate this command by typing": "允许 - 通过输入来激活这个命令",
"Are you sure?": "是否确定?",
"Artifacts": "",
"Ask a question": "",
"Artifacts": "Artifacts",
"Ask a question": "提问",
"Attach file": "添加文件",
"Attention to detail": "注重细节",
"Audio": "语音",
@@ -294,6 +294,7 @@
"Export Prompts": "导出提示词",
"Export Tools": "导出工具",
"External Models": "外部模型",
"Failed to add file.": "添加文件失败。",
"Failed to create API Key.": "无法创建 API 密钥。",
"Failed to read clipboard contents": "无法读取剪贴板内容",
"Failed to update settings": "无法更新设置",
@@ -384,7 +385,7 @@
"Knowledge deleted successfully.": "知识成功删除",
"Knowledge reset successfully.": "知识成功重置",
"Knowledge updated successfully": "知识成功更新",
"Landing Page Mode": "",
"Landing Page Mode": "默认主页样式",
"Language": "语言",
"large language models, locally.": "本地大语言模型",
"Last Active": "最后在线时间",
@@ -449,9 +450,10 @@
"Name your model": "为您的模型命名",
"New Chat": "新对话",
"New Password": "新密码",
"No content found": "未发现内容",
"No content to speak": "没有内容可朗读",
"No file selected": "未选中文件",
"No HTML, CSS, or JavaScript content found.": "",
"No HTML, CSS, or JavaScript content found.": "未找到 HTML、CSS 或 JavaScript 内容。",
"No knowledge found": "未找到知识",
"No results found": "未找到结果",
"No search query generated": "未生成搜索查询",
@@ -483,7 +485,7 @@
"Oops! There was an error in the previous response. Please try again or contact admin.": "糟糕!之前的回复出现了错误。请重试或联系管理员。",
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "糟糕!你正在使用不被支持的方法(仅前端)。请从后端提供 WebUI 服务。",
"Open file": "打开文件",
"Open in full screen": "",
"Open in full screen": "全屏打开",
"Open new chat": "打开新对话",
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "当前 Open WebUI 版本 (v{{OPEN_WEBUI_VERSION}}) 低于所需的版本 (v{{REQUIRED_VERSION}})",
"OpenAI": "OpenAI",
@@ -561,7 +563,7 @@
"Save & Update": "保存并更新",
"Save As Copy": "另存为副本",
"Save Tag": "保存标签",
"Saved": "",
"Saved": "已保存",
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "我们不再支持将聊天记录直接保存到浏览器的存储空间。请点击下面的按钮下载并删除您的聊天记录。别担心,您可以轻松地将聊天记录重新导入到后台。",
"Scroll to bottom when switching between branches": "在分支间切换时滚动到底部",
"Search": "搜索",
@@ -587,6 +589,7 @@
"Seed": "种子 (Seed)",
"Select a base model": "选择一个基础模型",
"Select a engine": "选择一个搜索引擎",
"Select a file to view or drag and drop a file to upload": "选择文件查看或拖放文件上传",
"Select a function": "选择一个函数",
"Select a model": "选择一个模型",
"Select a pipeline": "选择一个管道",
@@ -597,7 +600,6 @@
"Select Knowledge": "选择知识",
"Select model": "选择模型",
"Select only one model to call": "请仅选择一个模型来呼叫",
"Select/Add Files": "选择/添加 文件",
"Selected model(s) do not support image inputs": "已选择的模型不支持发送图像",
"Send": "发送",
"Send a Message": "输入消息",
@@ -632,11 +634,11 @@
"Show your support!": "表达你的支持!",
"Showcased creativity": "很有创意",
"Sign in": "登录",
"Sign in to {{WEBUI_NAME}}": "",
"Sign in to {{WEBUI_NAME}}": "登录 {{WEBUI_NAME}}",
"Sign Out": "登出",
"Sign up": "注册",
"Sign up to {{WEBUI_NAME}}": "",
"Signing in to {{WEBUI_NAME}}": "",
"Sign up to {{WEBUI_NAME}}": "注册 {{WEBUI_NAME}}",
"Signing in to {{WEBUI_NAME}}": "正在登录 {{WEBUI_NAME}}",
"Source": "来源",
"Speech Playback Speed": "语音播放速度",
"Speech recognition error: {{error}}": "语音识别错误:{{error}}",
@@ -677,7 +679,7 @@
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "这是一个实验功能,可能不会如预期那样工作,而且可能随时发生变化。",
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "此选项将会删除文件集中所有文件,并用新上传的文件替换。",
"This will delete": "这将删除",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "这将重置知识库并同步所有文件。确认继续吗?",
"Thorough explanation": "解释较为详细",
"Tika": "Tika",
"Tika Server URL required.": "请输入 Tika 服务器地址。",
@@ -725,6 +727,7 @@
"Update and Copy Link": "更新和复制链接",
"Update for the latest features and improvements.": "更新来获得最新功能与改进。",
"Update password": "更新密码",
"Updated": "已更新",
"Updated at": "更新于",
"Upload": "上传",
"Upload a GGUF model": "上传一个 GGUF 模型",
@@ -752,7 +755,7 @@
"variable": "变量",
"variable to have them replaced with clipboard content.": "变量将被剪贴板内容替换。",
"Version": "版本",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"Version {{selectedVersion}} of {{totalVersions}}": "版本 {{selectedVersion}}/{{totalVersions}}",
"Voice": "语音",
"Warning": "警告",
"Warning:": "警告:",

View File

@@ -8,14 +8,14 @@
"{{ owner }}: You cannot delete a base model": "{{ owner }}:您無法刪除基礎模型",
"{{user}}'s Chats": "{{user}} 的對話",
"{{webUIName}} Backend Required": "需要 {{webUIName}} 後端",
"*Prompt node ID(s) are required for image generation": "",
"A new version (v{{LATEST_VERSION}}) is now available.": "",
"*Prompt node ID(s) are required for image generation": "* 圖片生成需要提示詞節點 ID",
"A new version (v{{LATEST_VERSION}}) is now available.": "新版本 (v{{LATEST_VERSION}}) 現已推出。",
"A task model is used when performing tasks such as generating titles for chats and web search queries": "執行產生對話標題和網頁搜尋查詢等任務時會使用任務模型",
"a user": "一位使用者",
"About": "關於",
"Account": "帳號",
"Account Activation Pending": "帳號待啟用",
"Accurate information": "確資訊",
"Accurate information": "確資訊",
"Actions": "動作",
"Active Users": "活躍使用者",
"Add": "新增",
@@ -23,8 +23,8 @@
"Add a short description about what this model does": "新增這個模型的簡短描述",
"Add a short title for this prompt": "為這個提示詞新增一個簡短的標題",
"Add a tag": "新增標籤",
"Add Content": "",
"Add content here": "",
"Add Content": "新增內容",
"Add content here": "在此新增內容",
"Add custom prompt": "新增自訂提示詞",
"Add Docs": "新增文件",
"Add Files": "新增檔案",
@@ -33,14 +33,14 @@
"Add Model": "新增模型",
"Add Tag": "新增標籤",
"Add Tags": "新增標籤",
"Add text content": "",
"Add text content": "新增文字內容",
"Add User": "新增使用者",
"Adjusting these settings will apply changes universally to all users.": "調整這些設定將會全面套用到所有使用者。",
"Adjusting these settings will apply changes universally to all users.": "調整這些設定將會影響所有使用者。",
"admin": "管理員",
"Admin": "管理員",
"Admin Panel": "管理員控制台",
"Admin Settings": "管理員設定",
"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "管理員可以隨時使用所有工具;使用者需在工作區中為每個模型分配工具。",
"Admins have access to all tools at all times; users need tools assigned per model in the workspace.": "管理員可以隨時使用所有工具;使用者需在工作區中為每個模型分配工具。",
"Advanced Parameters": "進階參數",
"Advanced Params": "進階參數",
"all": "全部",
@@ -48,9 +48,9 @@
"All Users": "所有使用者",
"Allow": "允許",
"Allow Chat Deletion": "允許刪除對話紀錄",
"Allow Chat Editing": "",
"Allow Chat Editing": "允許編輯對話",
"Allow non-local voices": "允許非本機語音",
"Allow Temporary Chat": "",
"Allow Temporary Chat": "允許暫時對話",
"Allow User Location": "允許使用者位置",
"Allow Voice Interruption in Call": "允許在通話中打斷語音",
"alphanumeric characters and hyphens": "英文字母、數字和連字號",
@@ -66,23 +66,23 @@
"Archive": "封存",
"Archive All Chats": "封存所有對話紀錄",
"Archived Chats": "封存的對話紀錄",
"are allowed - Activate this command by typing": "已允許 - 輸入此命令啟用",
"are allowed - Activate this command by typing": "已允許 - 輸入此命令啟用",
"Are you sure?": "您確定嗎?",
"Artifacts": "",
"Ask a question": "",
"Artifacts": "成品",
"Ask a question": "提出問題",
"Attach file": "附加檔案",
"Attention to detail": "注重細節",
"Audio": "音訊",
"August": "8 月",
"Auto-playback response": "自動播放回應",
"Automatic1111": "",
"Automatic1111": "Automatic1111",
"AUTOMATIC1111 Api Auth String": "AUTOMATIC1111 API 驗證字串",
"AUTOMATIC1111 Base URL": "AUTOMATIC1111 基礎 URL",
"AUTOMATIC1111 Base URL is required.": "需要 AUTOMATIC1111 基礎 URL。",
"Available list": "",
"Available list": "可用清單",
"available!": "可用!",
"Azure AI Speech": "",
"Azure Region": "",
"Azure AI Speech": "Azure AI 語音",
"Azure Region": "Azure 區域",
"Back": "返回",
"Bad Response": "錯誤回應",
"Banners": "橫幅",
@@ -103,7 +103,7 @@
"Chat Bubble UI": "對話氣泡介面",
"Chat Controls": "對話控制項",
"Chat direction": "對話方向",
"Chat Overview": "",
"Chat Overview": "對話概覽",
"Chats": "對話",
"Check Again": "再次檢查",
"Check for updates": "檢查更新",
@@ -121,36 +121,36 @@
"Click here to select a csv file.": "點選這裡選擇 CSV 檔案。",
"Click here to select a py file.": "點選這裡選擇 Python 檔案。",
"Click here to select documents.": "點選這裡選擇文件。",
"Click here to upload a workflow.json file.": "",
"Click here to upload a workflow.json file.": "點選這裡上傳 workflow.json 檔案。",
"click here.": "點選這裡。",
"Click on the user role button to change a user's role.": "點選使用者角色按鈕變更使用者的角色。",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "剪貼簿寫入權限遭拒。請檢查您的瀏覽器設定,授予必要的存取權限。",
"Click on the user role button to change a user's role.": "點選使用者角色按鈕變更使用者的角色。",
"Clipboard write permission denied. Please check your browser settings to grant the necessary access.": "剪貼簿寫入權限遭拒。請檢查您的瀏覽器設定,授予必要的存取權限。",
"Clone": "複製",
"Close": "關閉",
"Code formatted successfully": "成功格式化程式碼",
"Code formatted successfully": "程式碼格式化成功",
"Collection": "收藏",
"ComfyUI": "ComfyUI",
"ComfyUI Base URL": "ComfyUI 基礎 URL",
"ComfyUI Base URL is required.": "需要 ComfyUI 基礎 URL。",
"ComfyUI Workflow": "",
"ComfyUI Workflow Nodes": "",
"ComfyUI Workflow": "ComfyUI 工作流程",
"ComfyUI Workflow Nodes": "ComfyUI 工作流程節點",
"Command": "命令",
"Concurrent Requests": "平行請求",
"Confirm": "確認",
"Confirm Password": "確認密碼",
"Confirm your action": "確認您的作",
"Confirm your action": "確認您的作",
"Connections": "連線",
"Contact Admin for WebUI Access": "請聯絡管理員以取得 WebUI 存取權限",
"Content": "內容",
"Content Extraction": "內容取",
"Content Extraction": "內容取",
"Context Length": "上下文長度",
"Continue Response": "繼續回應",
"Continue with {{provider}}": "使用 {{provider}} 繼續",
"Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "",
"Control how message text is split for TTS requests. 'Punctuation' splits into sentences, 'paragraphs' splits into paragraphs, and 'none' keeps the message as a single string.": "控制文字轉語音TTS請求中如何分割訊息文字。「標點符號」分割為句子「段落」分割為段落「無」則保持訊息為單一字串。",
"Controls": "控制項",
"Copied": "",
"Copied": "已複製",
"Copied shared chat URL to clipboard!": "已複製共用對話 URL 到剪貼簿!",
"Copied to clipboard": "",
"Copied to clipboard": "已複製到剪貼簿",
"Copy": "複製",
"Copy last code block": "複製最後一個程式碼區塊",
"Copy last response": "複製最後一個回應",
@@ -158,7 +158,7 @@
"Copying to clipboard was successful!": "成功複製到剪貼簿!",
"Create a model": "建立模型",
"Create Account": "建立帳號",
"Create Knowledge": "",
"Create Knowledge": "建立知識",
"Create new key": "建立新的金鑰",
"Create new secret key": "建立新的金鑰",
"Created at": "建立於",
@@ -174,8 +174,8 @@
"Database": "資料庫",
"December": "12 月",
"Default": "預設",
"Default (Open AI)": "",
"Default (SentenceTransformers)": "預設SentenceTransformers",
"Default (Open AI)": "預設 (OpenAI)",
"Default (SentenceTransformers)": "預設 (SentenceTransformers)",
"Default Model": "預設模型",
"Default model updated": "預設模型已更新",
"Default Prompt Suggestions": "預設提示詞建議",
@@ -237,18 +237,18 @@
"Embedding Model Engine": "嵌入模型引擎",
"Embedding model set to \"{{embedding_model}}\"": "嵌入模型已設定為 \"{{embedding_model}}\"",
"Enable Community Sharing": "啟用社群分享",
"Enable Message Rating": "",
"Enable Message Rating": "啟用訊息評分",
"Enable New Sign Ups": "允許新使用者註冊",
"Enable Web Search": "啟用網頁搜尋",
"Enable Web Search Query Generation": "",
"Enable Web Search Query Generation": "啟用網頁搜尋查詢生成",
"Enabled": "已啟用",
"Engine": "引擎",
"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "請確認您的 CSV 檔案包含以下 4 個欄位,並按照此順序排列:名、電子郵件、密碼、角色。",
"Ensure your CSV file includes 4 columns in this order: Name, Email, Password, Role.": "請確認您的 CSV 檔案包含以下 4 個欄位,並按照此順序排列:名、電子郵件、密碼、角色。",
"Enter {{role}} message here": "在此輸入 {{role}} 訊息",
"Enter a detail about yourself for your LLMs to recall": "輸入有關您的詳細資訊,讓您的大型語言模型可以回想起來",
"Enter api auth string (e.g. username:password)": "輸入 API 驗證字串例如username:password",
"Enter Brave Search API Key": "輸入 Brave 搜尋 API 金鑰",
"Enter CFG Scale (e.g. 7.0)": "",
"Enter CFG Scale (e.g. 7.0)": "輸入 CFG 比例例如7.0",
"Enter Chunk Overlap": "輸入區塊重疊",
"Enter Chunk Size": "輸入區塊大小",
"Enter Github Raw URL": "輸入 GitHub Raw URL",
@@ -256,14 +256,14 @@
"Enter Google PSE Engine Id": "輸入 Google PSE 引擎 ID",
"Enter Image Size (e.g. 512x512)": "輸入圖片大小例如512x512",
"Enter language codes": "輸入語言代碼",
"Enter Model ID": "",
"Enter Model ID": "輸入模型 ID",
"Enter model tag (e.g. {{modelTag}})": "輸入模型標籤(例如:{{modelTag}}",
"Enter Number of Steps (e.g. 50)": "輸入步驟數例如50",
"Enter Sampler (e.g. Euler a)": "",
"Enter Scheduler (e.g. Karras)": "",
"Enter Sampler (e.g. Euler a)": "輸入取樣器例如Euler a",
"Enter Scheduler (e.g. Karras)": "輸入排程器例如Karras",
"Enter Score": "輸入分數",
"Enter SearchApi API Key": "",
"Enter SearchApi Engine": "",
"Enter SearchApi API Key": "輸入 SearchApi API 金鑰",
"Enter SearchApi Engine": "輸入 SearchApi 引擎",
"Enter Searxng Query URL": "輸入 SearXNG 查詢 URL",
"Enter Serper API Key": "輸入 Serper API 金鑰",
"Enter Serply API Key": "輸入 Serply API 金鑰",
@@ -286,7 +286,7 @@
"Export All Chats (All Users)": "匯出所有對話紀錄(所有使用者)",
"Export chat (.json)": "匯出對話紀錄(.json",
"Export Chats": "匯出對話紀錄",
"Export Config to JSON File": "",
"Export Config to JSON File": "將設定匯出為 JSON 檔案",
"Export Documents Mapping": "匯出文件對應",
"Export Functions": "匯出函式",
"Export LiteLLM config.yaml": "匯出 LiteLLM config.yaml",
@@ -294,19 +294,20 @@
"Export Prompts": "匯出提示詞",
"Export Tools": "匯出工具",
"External Models": "外部模型",
"Failed to add file.": "無法新增檔案。",
"Failed to create API Key.": "無法建立 API 金鑰。",
"Failed to read clipboard contents": "無法讀取剪貼簿內容",
"Failed to update settings": "無法更新設定",
"Failed to upload file.": "",
"Failed to upload file.": "無法上傳檔案。",
"February": "2 月",
"Feel free to add specific details": "歡迎自由新增特定細節",
"File": "檔案",
"File added successfully.": "",
"File content updated successfully.": "",
"File added successfully.": "檔案新增成功。",
"File content updated successfully.": "檔案內容更新成功。",
"File Mode": "檔案模式",
"File not found.": "找不到檔案。",
"File removed successfully.": "",
"File size should not exceed {{maxSize}} MB.": "",
"File removed successfully.": "成功移除檔案。",
"File size should not exceed {{maxSize}} MB.": "檔案大小不應超過 {{maxSize}} MB。",
"Files": "檔案",
"Filter is now globally disabled": "篩選器現在已全域停用",
"Filter is now globally enabled": "篩選器現在已全域啟用",
@@ -341,7 +342,7 @@
"Google PSE API Key": "Google PSE API 金鑰",
"Google PSE Engine Id": "Google PSE 引擎 ID",
"h:mm a": "h:mm a",
"Haptic Feedback": "",
"Haptic Feedback": "觸覺回饋",
"has no conversations.": "沒有對話。",
"Hello, {{name}}": "您好,{{name}}",
"Help": "說明",
@@ -355,7 +356,7 @@
"Image Settings": "圖片設定",
"Images": "圖片",
"Import Chats": "匯入對話紀錄",
"Import Config from JSON File": "",
"Import Config from JSON File": "從 JSON 檔案匯入設定",
"Import Documents Mapping": "匯入文件對應",
"Import Functions": "匯入函式",
"Import Models": "匯入模型",
@@ -380,17 +381,17 @@
"Keep Alive": "保持連線",
"Keyboard shortcuts": "鍵盤快捷鍵",
"Knowledge": "知識",
"Knowledge created successfully.": "",
"Knowledge deleted successfully.": "",
"Knowledge reset successfully.": "",
"Knowledge updated successfully": "",
"Landing Page Mode": "",
"Knowledge created successfully.": "知識建立成功。",
"Knowledge deleted successfully.": "知識刪除成功。",
"Knowledge reset successfully.": "知識重設成功。",
"Knowledge updated successfully": "知識更新成功",
"Landing Page Mode": "首頁模式",
"Language": "語言",
"large language models, locally.": "在本機執行大型語言模型。",
"Last Active": "上次活動時間",
"Last Modified": "上次修改時間",
"Leave empty for unlimited": "",
"Leave empty to use the default prompt, or enter a custom prompt": "",
"Leave empty for unlimited": "留空表示無限制",
"Leave empty to use the default prompt, or enter a custom prompt": "留空使用預設提示詞,或輸入自訂提示詞",
"Light": "淺色",
"Listening...": "正在聆聽...",
"LLMs can make mistakes. Verify important information.": "大型語言模型可能會出錯。請驗證重要資訊。",
@@ -398,15 +399,15 @@
"LTR": "從左到右",
"Made by OpenWebUI Community": "由 OpenWebUI 社群製作",
"Make sure to enclose them with": "請務必將它們放在",
"Make sure to export a workflow.json file as API format from ComfyUI.": "",
"Make sure to export a workflow.json file as API format from ComfyUI.": "請確保從 ComfyUI 匯出 workflow.json 檔案為 API 格式。",
"Manage": "管理",
"Manage Models": "管理模型",
"Manage Ollama Models": "管理 Ollama 模型",
"Manage Pipelines": "管理管線",
"March": "3 月",
"Max Tokens (num_predict)": "最大 token 數num_predict",
"Max Upload Count": "",
"Max Upload Size": "",
"Max Upload Count": "最大上傳數量",
"Max Upload Size": "最大上傳大小",
"Maximum of 3 models can be downloaded simultaneously. Please try again later.": "最多可同時下載 3 個模型。請稍後再試。",
"May": "5 月",
"Memories accessible by LLMs will be shown here.": "可被大型語言模型存取的記憶將顯示在這裡。",
@@ -415,7 +416,7 @@
"Memory cleared successfully": "成功清除記憶",
"Memory deleted successfully": "成功刪除記憶",
"Memory updated successfully": "成功更新記憶",
"Merge Responses": "",
"Merge Responses": "合併回應",
"Messages you send after creating your link won't be shared. Users with the URL will be able to view the shared chat.": "建立連結後傳送的訊息不會被分享。擁有網址的使用者將能夠檢視分享的對話內容。",
"Min P": "最小 P 值",
"Minimum Score": "最低分數",
@@ -430,8 +431,8 @@
"Model {{modelId}} not found": "找不到模型 {{modelId}}",
"Model {{modelName}} is not vision capable": "模型 {{modelName}} 不具備視覺能力",
"Model {{name}} is now {{status}}": "模型 {{name}} 現在狀態為 {{status}}",
"Model {{name}} is now at the top": "",
"Model accepts image inputs": "",
"Model {{name}} is now at the top": "模型 {{name}} 現在位於頂端",
"Model accepts image inputs": "模型接受影像輸入",
"Model created successfully!": "成功建立模型!",
"Model filesystem path detected. Model shortname is required for update, cannot continue.": "偵測到模型檔案系統路徑。更新需要模型簡稱,因此無法繼續。",
"Model ID": "模型 ID",
@@ -443,26 +444,27 @@
"Modelfile Content": "模型檔案內容",
"Models": "模型",
"More": "更多",
"Move to Top": "",
"Move to Top": "移至頂端",
"Name": "名稱",
"Name Tag": "名稱標籤",
"Name your model": "為您的模型命名",
"New Chat": "新增對話",
"New Password": "新密碼",
"New Password": "新密碼",
"No content found": "找不到內容",
"No content to speak": "沒有要朗讀的內容",
"No file selected": "未選取檔案",
"No HTML, CSS, or JavaScript content found.": "",
"No knowledge found": "",
"No HTML, CSS, or JavaScript content found.": "找不到 HTML、CSS 或 JavaScript 內容。",
"No knowledge found": "找不到知識",
"No results found": "找不到任何結果",
"No search query generated": "未產生搜尋查詢",
"No source available": "沒有可用的來源",
"No valves to update": "沒有要更新的閥門",
"None": "無",
"Not factually correct": "與真實資訊不符",
"Not factually correct": "與事實不符",
"Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.": "注意:如果您設定了最低分數,則搜尋只會回傳分數大於或等於最低分數的文件。",
"Notifications": "通知",
"November": "11 月",
"num_gpu (Ollama)": "",
"num_gpu (Ollama)": "num_gpu (Ollama)",
"num_thread (Ollama)": "num_thread (Ollama)",
"OAuth ID": "OAuth ID",
"October": "10 月",
@@ -477,13 +479,13 @@
"On": "開啟",
"Only": "僅限",
"Only alphanumeric characters and hyphens are allowed in the command string.": "命令字串中只允許使用英文字母、數字和連字號。",
"Only collections can be edited, create a new knowledge base to edit/add documents.": "",
"Only collections can be edited, create a new knowledge base to edit/add documents.": "只能編輯集合,請建立新的知識以編輯或新增文件。",
"Oops! Hold tight! Your files are still in the processing oven. We're cooking them up to perfection. Please be patient and we'll let you know once they're ready.": "哎呀!請稍等!您的檔案仍在處理中。我們正在完善它們。請耐心等待,我們會在它們準備好時通知您。",
"Oops! Looks like the URL is invalid. Please double-check and try again.": "哎呀!這個 URL 似乎無效。請仔細檢查並再試一次。",
"Oops! There was an error in the previous response. Please try again or contact admin.": "哎呀!先前的回應發生錯誤。請重試或聯絡管理員。",
"Oops! You're using an unsupported method (frontend only). Please serve the WebUI from the backend.": "哎呀!您使用了不支援的方法(僅限前端)。請從後端提供 WebUI。",
"Open file": "",
"Open in full screen": "",
"Open file": "開啟檔案",
"Open in full screen": "全螢幕開啟",
"Open new chat": "開啟新的對話",
"Open WebUI version (v{{OPEN_WEBUI_VERSION}}) is lower than required version (v{{REQUIRED_VERSION}})": "Open WebUI 版本 (v{{OPEN_WEBUI_VERSION}}) 低於所需版本 (v{{REQUIRED_VERSION}})",
"OpenAI": "OpenAI",
@@ -493,9 +495,9 @@
"OpenAI URL/Key required.": "需要 OpenAI URL/金鑰。",
"or": "或",
"Other": "其他",
"Output format": "",
"Overview": "",
"page": "",
"Output format": "輸出格式",
"Overview": "概覽",
"page": "頁面",
"Password": "密碼",
"PDF document (.pdf)": "PDF 文件 (.pdf)",
"PDF Extract Images (OCR)": "PDF 影像擷取OCR 光學文字辨識)",
@@ -514,8 +516,8 @@
"Plain text (.txt)": "純文字 (.txt)",
"Playground": "遊樂場",
"Please carefully review the following warnings:": "請仔細閱讀以下警告:",
"Please fill in all fields.": "",
"Please select a reason": "",
"Please fill in all fields.": "請填寫所有欄位。",
"Please select a reason": "請選擇原因",
"Positive attitude": "積極的態度",
"Previous 30 days": "過去 30 天",
"Previous 7 days": "過去 7 天",
@@ -548,80 +550,80 @@
"Reset Vector Storage": "重設向量儲存空間",
"Response AutoCopy to Clipboard": "自動將回應複製到剪貼簿",
"Response notifications cannot be activated as the website permissions have been denied. Please visit your browser settings to grant the necessary access.": "無法啟用回應通知,因為網站權限已遭拒。請前往瀏覽器設定以授予必要存取權限。",
"Response splitting": "",
"Response splitting": "回應分割",
"Role": "角色",
"Rosé Pine": "玫瑰松",
"Rosé Pine Dawn": "黎明玫瑰松",
"RTL": "從右到左",
"Run": "",
"Run": "執行",
"Run Llama 2, Code Llama, and other models. Customize and create your own.": "執行 Llama 2、Code Llama 和其他模型。自訂並建立您自己的模型。",
"Running": "運作中",
"Save": "儲存",
"Save & Create": "儲存並建立",
"Save & Update": "儲存並更新",
"Save As Copy": "",
"Save As Copy": "另存為副本",
"Save Tag": "儲存標籤",
"Saved": "",
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "不再支援直接將對話錄儲存到您的瀏覽器儲存空間。請點選下方按鈕來下載並刪除您的對話錄。別擔心,您可以透過以下方式輕鬆地將對話錄重新匯入後端",
"Saved": "已儲存",
"Saving chat logs directly to your browser's storage is no longer supported. Please take a moment to download and delete your chat logs by clicking the button below. Don't worry, you can easily re-import your chat logs to the backend through": "不再支援直接將對話錄儲存到您的瀏覽器儲存空間。請點選下方按鈕來下載並刪除您的對話錄。別擔心,您可以透過以下方式輕鬆地將對話錄重新匯入後端",
"Scroll to bottom when switching between branches": "切換分支時捲動到底端",
"Search": "搜尋",
"Search a model": "搜尋模型",
"Search Chats": "搜尋對話",
"Search Collection": "",
"Search Collection": "搜尋集合",
"Search Documents": "搜尋文件",
"Search Functions": "搜尋函式",
"Search Knowledge": "",
"Search Knowledge": "搜尋知識庫",
"Search Models": "搜尋模型",
"Search Prompts": "搜尋提示詞",
"Search Query Generation Prompt": "搜尋查詢生成提示詞",
"Search Result Count": "搜尋結果數量",
"Search Tools": "搜尋工具",
"SearchApi API Key": "",
"SearchApi Engine": "",
"SearchApi API Key": "SearchApi API 金鑰",
"SearchApi Engine": "SearchApi 引擎",
"Searched {{count}} sites_one": "已搜尋 {{count}} 個網站",
"Searched {{count}} sites_other": "已搜尋 {{count}} 個網站",
"Searching \"{{searchQuery}}\"": "正在搜尋 \"{{searchQuery}}\"",
"Searching Knowledge for \"{{searchQuery}}\"": "",
"Searching Knowledge for \"{{searchQuery}}\"": "正在搜尋知識庫中的 \"{{searchQuery}}\"",
"Searxng Query URL": "Searxng 查詢 URL",
"See readme.md for instructions": "檢視 readme.md 以取得說明",
"See what's new": "查看新功能",
"Seed": "種子",
"Seed": "種子",
"Select a base model": "選擇基礎模型",
"Select a engine": "選擇引擎",
"Select a file to view or drag and drop a file to upload": "選擇檔案以檢視或拖放檔案以上傳",
"Select a function": "選擇函式",
"Select a model": "選擇模型",
"Select a pipeline": "選擇管線",
"Select a pipeline url": "選擇管線 URL",
"Select a tool": "選擇工具",
"Select an Ollama instance": "選擇 Ollama 執行個體",
"Select Engine": "",
"Select Knowledge": "",
"Select Engine": "選擇引擎",
"Select Knowledge": "選擇知識庫",
"Select model": "選擇模型",
"Select only one model to call": "僅選擇一個模型來呼叫",
"Select/Add Files": "",
"Selected model(s) do not support image inputs": "選取的模型不支援圖片輸入",
"Send": "傳送",
"Send a Message": "傳送訊息",
"Send message": "傳送訊息",
"Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "",
"Sends `stream_options: { include_usage: true }` in the request.\nSupported providers will return token usage information in the response when set.": "在請求中傳送 `stream_options: { include_usage: true }`。\n設定後支援的提供者將在回應中回傳權杖使用資訊。",
"September": "9 月",
"Serper API Key": "Serper API 金鑰",
"Serply API Key": "Serply API 金鑰",
"Serpstack API Key": "Serpstack API 金鑰",
"Server connection verified": "伺服器連線已驗證",
"Set as default": "設為預設",
"Set CFG Scale": "",
"Set CFG Scale": "設定 CFG 比例",
"Set Default Model": "設定預設模型",
"Set embedding model (e.g. {{model}})": "設定嵌入模型(例如:{{model}}",
"Set Image Size": "設定圖片大小",
"Set reranking model (e.g. {{model}})": "設定重新排序模型(例如:{{model}}",
"Set Sampler": "",
"Set Scheduler": "",
"Set Sampler": "設定取樣器",
"Set Scheduler": "設定排程器",
"Set Steps": "設定步數",
"Set Task Model": "設定任務模型",
"Set Voice": "設定語音",
"Settings": "設定",
"Settings saved successfully!": "設定已成功儲存",
"Settings saved successfully!": "設定已成功儲存",
"Share": "分享",
"Share Chat": "分享對話",
"Share to OpenWebUI Community": "分享到 OpenWebUI 社群",
@@ -630,20 +632,20 @@
"Show Admin Details in Account Pending Overlay": "在帳號待審覆蓋層中顯示管理員詳細資訊",
"Show Model": "顯示模型",
"Show shortcuts": "顯示快捷鍵",
"Show your support!": "表您的支持!",
"Show your support!": "表您的支持!",
"Showcased creativity": "展現創意",
"Sign in": "登入",
"Sign in to {{WEBUI_NAME}}": "",
"Sign in to {{WEBUI_NAME}}": "登入 {{WEBUI_NAME}}",
"Sign Out": "登出",
"Sign up": "註冊",
"Sign up to {{WEBUI_NAME}}": "",
"Signing in to {{WEBUI_NAME}}": "",
"Sign up to {{WEBUI_NAME}}": "註冊 {{WEBUI_NAME}}",
"Signing in to {{WEBUI_NAME}}": "正在登入 {{WEBUI_NAME}}",
"Source": "來源",
"Speech Playback Speed": "語音播放速度",
"Speech recognition error: {{error}}": "語音辨識錯誤:{{error}}",
"Speech-to-Text Engine": "語音轉文字 (STT) 引擎",
"Stop Sequence": "停止序列",
"Stream Chat Response": "",
"Stream Chat Response": "串流對話回應",
"STT Model": "語音轉文字 (STT) 模型",
"STT Settings": "語音轉文字 (STT) 設定",
"Submit": "提交",
@@ -653,7 +655,7 @@
"Suggested": "建議",
"Support": "支援",
"Support this plugin:": "支持這個外掛:",
"Sync directory": "",
"Sync directory": "同步目錄",
"System": "系統",
"System Prompt": "系統提示詞",
"Tags": "標籤",
@@ -662,23 +664,23 @@
"Tell us more:": "告訴我們更多:",
"Temperature": "溫度",
"Template": "範本",
"Temporary Chat": "",
"Temporary Chat": "臨時對話",
"Text Completion": "文字補全",
"Text-to-Speech Engine": "文字轉語音 (TTS) 引擎",
"Text-to-Speech Engine": "文字轉語音引擎",
"Tfs Z": "Tfs Z",
"Thanks for your feedback!": "感謝您的回饋!",
"The developers behind this plugin are passionate volunteers from the community. If you find this plugin helpful, please consider contributing to its development.": "這個外掛背後的開發者是來自社群的熱情志願者。如果您覺得這個外掛很有幫助,請考慮為其開發做出貢獻。",
"The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "",
"The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "",
"The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.": "檔案大小上限MB。如果檔案大小超過此限制檔案將不會被上傳。",
"The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.": "對話中一次可使用的最大檔案數量。如果檔案數量超過此限制,檔案將不會被上傳。",
"The score should be a value between 0.0 (0%) and 1.0 (100%).": "分數應該是介於 0.00%)和 1.0100%)之間的值。",
"Theme": "主題",
"Thinking...": "正在思考...",
"This action cannot be undone. Do you wish to continue?": "此操作無法復原。您確定要繼續進行嗎?",
"This ensures that your valuable conversations are securely saved to your backend database. Thank you!": "這確保您寶貴的對話會安全地儲存到您的後端資料庫。謝謝!",
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "這是一個實驗性功能,它可能無法預期運作,並且可能會隨時變更。",
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "",
"This is an experimental feature, it may not function as expected and is subject to change at any time.": "這是一個實驗性功能,它可能無法預期運作,並且可能會隨時變更。",
"This option will delete all existing files in the collection and replace them with newly uploaded files.": "此選項將刪除集合中的所有現有檔案,並用新上傳的檔案取代它們。",
"This will delete": "這將會刪除",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "",
"This will reset the knowledge base and sync all files. Do you wish to continue?": "這將重設知識庫並同步所有檔案。您確定要繼續嗎?",
"Thorough explanation": "詳細解釋",
"Tika": "Tika",
"Tika Server URL required.": "需要 Tika 伺服器 URL。",
@@ -691,7 +693,7 @@
"To access the available model names for downloading,": "若要存取可供下載的模型名稱,",
"To access the GGUF models available for downloading,": "若要存取可供下載的 GGUF 模型,",
"To access the WebUI, please reach out to the administrator. Admins can manage user statuses from the Admin Panel.": "若要存取 WebUI請聯絡管理員。管理員可以從管理面板管理使用者狀態。",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "",
"To attach knowledge base here, add them to the \"Knowledge\" workspace first.": "要在此處附加知識庫,請先將它們新增到「知識」工作區。",
"to chat input.": "到對話輸入。",
"To select actions here, add them to the \"Functions\" workspace first.": "若要在此選擇動作,請先將它們新增到「函式」工作區。",
"To select filters here, add them to the \"Functions\" workspace first.": "若要在此選擇篩選器,請先將它們新增到「函式」工作區。",
@@ -724,18 +726,19 @@
"Unpin": "取消釘選",
"Update": "更新",
"Update and Copy Link": "更新並複製連結",
"Update for the latest features and improvements.": "",
"Update for the latest features and improvements.": "更新以獲得最新功能和改進。",
"Update password": "更新密碼",
"Updated": "已更新",
"Updated at": "更新於",
"Upload": "上傳",
"Upload a GGUF model": "上傳 GGUF 模型",
"Upload directory": "",
"Upload files": "",
"Upload directory": "上傳目錄",
"Upload files": "上傳檔案",
"Upload Files": "上傳檔案",
"Upload Pipeline": "上傳管線",
"Upload Progress": "上傳進度",
"URL Mode": "URL 模式",
"Use '#' in the prompt input to load and include your knowledge.": "",
"Use '#' in the prompt input to load and include your knowledge.": "在提示詞輸入中使用 '#' 來載入並包含您的知識。",
"Use '#' in the prompt input to load and select your documents.": "在提示詞輸入中使用 '#' 來載入和選擇您的文件。",
"Use Gravatar": "使用 Gravatar",
"Use Initials": "使用姓名縮寫",
@@ -753,7 +756,7 @@
"variable": "變數",
"variable to have them replaced with clipboard content.": "變數,以便將其替換為剪貼簿內容。",
"Version": "版本",
"Version {{selectedVersion}} of {{totalVersions}}": "",
"Version {{selectedVersion}} of {{totalVersions}}": "第 {{selectedVersion}} 版,共 {{totalVersions}} 版",
"Voice": "語音",
"Warning": "警告",
"Warning:": "警告:",
@@ -765,16 +768,16 @@
"Web Search Engine": "網頁搜尋引擎",
"Webhook URL": "Webhook URL",
"WebUI Settings": "WebUI 設定",
"WebUI will make requests to": "WebUI 將會以下址發出請求",
"WebUI will make requests to": "WebUI 將會以下址發出請求",
"Whats New in": "新功能",
"Whisper (Local)": "Whisper",
"Whisper (Local)": "Whisper",
"Widescreen Mode": "寬螢幕模式",
"Workspace": "工作區",
"Write a prompt suggestion (e.g. Who are you?)": "撰寫提示詞建議(例如:你是誰?)",
"Write a summary in 50 words that summarizes [topic or keyword].": "用 50 字寫一篇總結 [主題或關鍵字] 的摘要。",
"Yesterday": "昨天",
"You": "您",
"You can only chat with a maximum of {{maxCount}} file(s) at a time.": "",
"You can only chat with a maximum of {{maxCount}} file(s) at a time.": "您一次最多只能與 {{maxCount}} 個檔案進行對話。",
"You can personalize your interactions with LLMs by adding memories through the 'Manage' button below, making them more helpful and tailored to you.": "您可以透過下方的「管理」按鈕新增記憶,將您與大型語言模型的互動個人化,讓它們更有幫助並更符合您的需求。",
"You cannot clone a base model": "您無法複製基礎模型",
"You have no archived conversations.": "您沒有已封存的對話。",

View File

@@ -67,22 +67,6 @@
: ''} transition"
href="/admin/settings">{$i18n.t('Settings')}</a
>
<!-- <a
class="min-w-fit rounded-lg p-1.5 px-3 {$page.url.pathname.includes('/workspace/documents')
? 'bg-gray-50 dark:bg-gray-850'
: ''} transition"
href="/workspace/documents"
>
{$i18n.t('Documents')}
</a>
<a
class="min-w-fit rounded-lg p-1.5 px-3 {$page.url.pathname.includes('/workspace/playground')
? 'bg-gray-50 dark:bg-gray-850'
: ''} transition"
href="/workspace/playground">{$i18n.t('Playground')}</a
> -->
</div>
</div>

View File

@@ -0,0 +1,22 @@
<script>
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
onMount(() => {
// Get the current URL search parameters
const params = new URLSearchParams(window.location.search);
// Check if 'v' parameter exists
if (params.has('v')) {
// Get the value of 'v' parameter
const videoId = params.get('v');
// Redirect to root with 'youtube' parameter
goto(`/?youtube=${encodeURIComponent(videoId)}`);
} else {
// Redirect to root if 'v' parameter doesn't exist
goto('/');
}
});
</script>