Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
e98cb452
Unverified
Commit
e98cb452
authored
May 06, 2024
by
Timothy Jaeryang Baek
Committed by
GitHub
May 06, 2024
Browse files
Merge pull request #2011 from cheahjs/feat/rag-citations
feat: show RAG query results as citations
parents
ba09fcd5
c84e0aa2
Changes
35
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
690 additions
and
469 deletions
+690
-469
backend/apps/rag/utils.py
backend/apps/rag/utils.py
+27
-22
backend/config.py
backend/config.py
+12
-10
backend/main.py
backend/main.py
+36
-3
src/lib/apis/streaming/index.ts
src/lib/apis/streaming/index.ts
+11
-0
src/lib/components/chat/Messages/CitationsModal.svelte
src/lib/components/chat/Messages/CitationsModal.svelte
+75
-0
src/lib/components/chat/Messages/ResponseMessage.svelte
src/lib/components/chat/Messages/ResponseMessage.svelte
+473
-420
src/lib/i18n/locales/ar-BH/translation.json
src/lib/i18n/locales/ar-BH/translation.json
+4
-1
src/lib/i18n/locales/bg-BG/translation.json
src/lib/i18n/locales/bg-BG/translation.json
+4
-1
src/lib/i18n/locales/bn-BD/translation.json
src/lib/i18n/locales/bn-BD/translation.json
+4
-1
src/lib/i18n/locales/ca-ES/translation.json
src/lib/i18n/locales/ca-ES/translation.json
+4
-1
src/lib/i18n/locales/de-DE/translation.json
src/lib/i18n/locales/de-DE/translation.json
+4
-1
src/lib/i18n/locales/dg-DG/translation.json
src/lib/i18n/locales/dg-DG/translation.json
+4
-1
src/lib/i18n/locales/en-GB/translation.json
src/lib/i18n/locales/en-GB/translation.json
+4
-1
src/lib/i18n/locales/en-US/translation.json
src/lib/i18n/locales/en-US/translation.json
+4
-1
src/lib/i18n/locales/es-ES/translation.json
src/lib/i18n/locales/es-ES/translation.json
+4
-1
src/lib/i18n/locales/fa-IR/translation.json
src/lib/i18n/locales/fa-IR/translation.json
+4
-1
src/lib/i18n/locales/fr-CA/translation.json
src/lib/i18n/locales/fr-CA/translation.json
+4
-1
src/lib/i18n/locales/fr-FR/translation.json
src/lib/i18n/locales/fr-FR/translation.json
+4
-1
src/lib/i18n/locales/it-IT/translation.json
src/lib/i18n/locales/it-IT/translation.json
+4
-1
src/lib/i18n/locales/ja-JP/translation.json
src/lib/i18n/locales/ja-JP/translation.json
+4
-1
No files found.
backend/apps/rag/utils.py
View file @
e98cb452
...
...
@@ -271,14 +271,14 @@ def rag_messages(
for
doc
in
docs
:
context
=
None
collection
=
doc
.
get
(
"collection_name"
)
if
collection
:
collection
=
[
collection
]
else
:
collection
=
doc
.
get
(
"collection_names"
,
[]
)
collection
_names
=
(
doc
[
"
collection
_names"
]
if
doc
[
"type"
]
=
=
"
collection
"
else
[
doc
[
"collection_name"
]]
)
collection
=
set
(
collection
).
difference
(
extracted_collections
)
if
not
collection
:
collection
_names
=
set
(
collection
_names
).
difference
(
extracted_collections
)
if
not
collection
_names
:
log
.
debug
(
f
"skipping
{
doc
}
as it has already been extracted"
)
continue
...
...
@@ -288,11 +288,7 @@ def rag_messages(
else
:
if
hybrid_search
:
context
=
query_collection_with_hybrid_search
(
collection_names
=
(
doc
[
"collection_names"
]
if
doc
[
"type"
]
==
"collection"
else
[
doc
[
"collection_name"
]]
),
collection_names
=
collection_names
,
query
=
query
,
embedding_function
=
embedding_function
,
k
=
k
,
...
...
@@ -301,11 +297,7 @@ def rag_messages(
)
else
:
context
=
query_collection
(
collection_names
=
(
doc
[
"collection_names"
]
if
doc
[
"type"
]
==
"collection"
else
[
doc
[
"collection_name"
]]
),
collection_names
=
collection_names
,
query
=
query
,
embedding_function
=
embedding_function
,
k
=
k
,
...
...
@@ -315,18 +307,31 @@ def rag_messages(
context
=
None
if
context
:
relevant_contexts
.
append
(
context
)
relevant_contexts
.
append
(
{
**
context
,
"source"
:
doc
}
)
extracted_collections
.
extend
(
collection
)
extracted_collections
.
extend
(
collection
_names
)
context_string
=
""
citations
=
[]
for
context
in
relevant_contexts
:
try
:
if
"documents"
in
context
:
items
=
[
item
for
item
in
context
[
"documents"
][
0
]
if
item
is
not
None
]
context_string
+=
"
\n\n
"
.
join
(
items
)
context_string
+=
"
\n\n
"
.
join
(
[
text
for
text
in
context
[
"documents"
][
0
]
if
text
is
not
None
]
)
if
"metadatas"
in
context
:
citations
.
append
(
{
"source"
:
context
[
"source"
],
"document"
:
context
[
"documents"
][
0
],
"metadata"
:
context
[
"metadatas"
][
0
],
}
)
except
Exception
as
e
:
log
.
exception
(
e
)
context_string
=
context_string
.
strip
()
ra_content
=
rag_template
(
...
...
@@ -355,7 +360,7 @@ def rag_messages(
messages
[
last_user_message_idx
]
=
new_user_message
return
messages
return
messages
,
citations
def
get_model_path
(
model
:
str
,
update_model
:
bool
=
False
):
...
...
backend/config.py
View file @
e98cb452
...
...
@@ -18,6 +18,18 @@ from secrets import token_bytes
from
constants
import
ERROR_MESSAGES
####################################
# Load .env file
####################################
try
:
from
dotenv
import
load_dotenv
,
find_dotenv
load_dotenv
(
find_dotenv
(
"../.env"
))
except
ImportError
:
print
(
"dotenv not installed, skipping..."
)
####################################
# LOGGING
####################################
...
...
@@ -59,16 +71,6 @@ for source in log_sources:
log
.
setLevel
(
SRC_LOG_LEVELS
[
"CONFIG"
])
####################################
# Load .env file
####################################
try
:
from
dotenv
import
load_dotenv
,
find_dotenv
load_dotenv
(
find_dotenv
(
"../.env"
))
except
ImportError
:
log
.
warning
(
"dotenv not installed, skipping..."
)
WEBUI_NAME
=
os
.
environ
.
get
(
"WEBUI_NAME"
,
"Open WebUI"
)
if
WEBUI_NAME
!=
"Open WebUI"
:
...
...
backend/main.py
View file @
e98cb452
...
...
@@ -15,7 +15,7 @@ from fastapi.middleware.wsgi import WSGIMiddleware
from
fastapi.middleware.cors
import
CORSMiddleware
from
starlette.exceptions
import
HTTPException
as
StarletteHTTPException
from
starlette.middleware.base
import
BaseHTTPMiddleware
from
starlette.responses
import
StreamingResponse
from
apps.ollama.main
import
app
as
ollama_app
from
apps.openai.main
import
app
as
openai_app
...
...
@@ -102,6 +102,8 @@ origins = ["*"]
class
RAGMiddleware
(
BaseHTTPMiddleware
):
async
def
dispatch
(
self
,
request
:
Request
,
call_next
):
return_citations
=
False
if
request
.
method
==
"POST"
and
(
"/api/chat"
in
request
.
url
.
path
or
"/chat/completions"
in
request
.
url
.
path
):
...
...
@@ -114,11 +116,15 @@ class RAGMiddleware(BaseHTTPMiddleware):
# Parse string to JSON
data
=
json
.
loads
(
body_str
)
if
body_str
else
{}
return_citations
=
data
.
get
(
"citations"
,
False
)
if
"citations"
in
data
:
del
data
[
"citations"
]
# Example: Add a new key-value pair or modify existing ones
# data["modified"] = True # Example modification
if
"docs"
in
data
:
data
=
{
**
data
}
data
[
"messages"
]
=
rag_messages
(
data
[
"messages"
]
,
citations
=
rag_messages
(
docs
=
data
[
"docs"
],
messages
=
data
[
"messages"
],
template
=
rag_app
.
state
.
RAG_TEMPLATE
,
...
...
@@ -130,7 +136,9 @@ class RAGMiddleware(BaseHTTPMiddleware):
)
del
data
[
"docs"
]
log
.
debug
(
f
"data['messages']:
{
data
[
'messages'
]
}
"
)
log
.
debug
(
f
"data['messages']:
{
data
[
'messages'
]
}
, citations:
{
citations
}
"
)
modified_body_bytes
=
json
.
dumps
(
data
).
encode
(
"utf-8"
)
...
...
@@ -148,11 +156,36 @@ class RAGMiddleware(BaseHTTPMiddleware):
]
response
=
await
call_next
(
request
)
if
return_citations
:
# Inject the citations into the response
if
isinstance
(
response
,
StreamingResponse
):
# If it's a streaming response, inject it as SSE event or NDJSON line
content_type
=
response
.
headers
.
get
(
"Content-Type"
)
if
"text/event-stream"
in
content_type
:
return
StreamingResponse
(
self
.
openai_stream_wrapper
(
response
.
body_iterator
,
citations
),
)
if
"application/x-ndjson"
in
content_type
:
return
StreamingResponse
(
self
.
ollama_stream_wrapper
(
response
.
body_iterator
,
citations
),
)
return
response
async
def
_receive
(
self
,
body
:
bytes
):
return
{
"type"
:
"http.request"
,
"body"
:
body
,
"more_body"
:
False
}
async
def
openai_stream_wrapper
(
self
,
original_generator
,
citations
):
yield
f
"data:
{
json
.
dumps
(
{
'citations'
:
citations
}
)
}
\n\n
"
async
for
data
in
original_generator
:
yield
data
async
def
ollama_stream_wrapper
(
self
,
original_generator
,
citations
):
yield
f
"
{
json
.
dumps
(
{
'citations'
:
citations
}
)
}
\n
"
async
for
data
in
original_generator
:
yield
data
app
.
add_middleware
(
RAGMiddleware
)
...
...
src/lib/apis/streaming/index.ts
View file @
e98cb452
...
...
@@ -4,6 +4,8 @@ import type { ParsedEvent } from 'eventsource-parser';
type
TextStreamUpdate
=
{
done
:
boolean
;
value
:
string
;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
citations
?:
any
;
};
// createOpenAITextStream takes a responseBody with a SSE response,
...
...
@@ -45,6 +47,11 @@ async function* openAIStreamToIterator(
const
parsedData
=
JSON
.
parse
(
data
);
console
.
log
(
parsedData
);
if
(
parsedData
.
citations
)
{
yield
{
done
:
false
,
value
:
''
,
citations
:
parsedData
.
citations
};
continue
;
}
yield
{
done
:
false
,
value
:
parsedData
.
choices
?.[
0
]?.
delta
?.
content
??
''
};
}
catch
(
e
)
{
console
.
error
(
'
Error extracting delta from SSE event:
'
,
e
);
...
...
@@ -62,6 +69,10 @@ async function* streamLargeDeltasAsRandomChunks(
yield
textStreamUpdate
;
return
;
}
if
(
textStreamUpdate
.
citations
)
{
yield
textStreamUpdate
;
continue
;
}
let
content
=
textStreamUpdate
.
value
;
if
(
content
.
length
<
5
)
{
yield
{
done
:
false
,
value
:
content
};
...
...
src/lib/components/chat/Messages/CitationsModal.svelte
0 → 100644
View file @
e98cb452
<script lang="ts">
import { getContext, onMount, tick } from 'svelte';
import Modal from '$lib/components/common/Modal.svelte';
const i18n = getContext('i18n');
export let show = false;
export let citation;
let mergedDocuments = [];
$: if (citation) {
mergedDocuments = citation.document?.map((c, i) => {
return {
source: citation.source,
document: c,
metadata: citation.metadata?.[i]
};
});
}
</script>
<Modal size="lg" bind:show>
<div>
<div class=" flex justify-between dark:text-gray-300 px-5 pt-4 pb-2">
<div class=" text-lg font-medium self-center capitalize">
{$i18n.t('Citation')}
</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 pb-5 md:space-x-4">
<div class="flex flex-col w-full dark:text-gray-200 overflow-y-scroll max-h-[22rem]">
{#each mergedDocuments as document, documentIdx}
<div class="flex flex-col w-full">
<div class="text-sm font-medium dark:text-gray-300">
{$i18n.t('Source')}
</div>
<div class="text-sm dark:text-gray-400">
{document.source?.name ?? $i18n.t('No source available')}
</div>
</div>
<div class="flex flex-col w-full">
<div class=" text-sm font-medium dark:text-gray-300">
{$i18n.t('Content')}
</div>
<pre class="text-sm dark:text-gray-400 whitespace-pre-line">
{document.document}
</pre>
</div>
{#if documentIdx !== mergedDocuments.length - 1}
<hr class=" dark:border-gray-850 my-3" />
{/if}
{/each}
</div>
</div>
</div>
</Modal>
src/lib/components/chat/Messages/ResponseMessage.svelte
View file @
e98cb452
...
...
@@ -32,6 +32,7 @@
import { WEBUI_BASE_URL } from '$lib/constants';
import Tooltip from '$lib/components/common/Tooltip.svelte';
import RateComment from './RateComment.svelte';
import CitationsModal from '$lib/components/chat/Messages/CitationsModal.svelte';
export let modelfiles = [];
export let message;
...
...
@@ -65,6 +66,9 @@
let showRateComment = false;
let showCitationModal = false;
let selectedCitation = null;
$: tokens = marked.lexer(sanitizeResponseContent(message.content));
const renderer = new marked.Renderer();
...
...
@@ -324,6 +328,8 @@
});
</script>
<CitationsModal bind:show={showCitationModal} citation={selectedCitation} />
{#key message.id}
<div class=" flex w-full message-{message.id}" id="message-{message.id}">
<ProfileImage
...
...
@@ -360,7 +366,6 @@
{/each}
</div>
{/if}
<div
class="prose chat-{message.role} w-full max-w-full dark:prose-invert prose-headings:my-0 prose-p:m-0 prose-p:-mb-6 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-img:my-0 prose-ul:-my-4 prose-ol:-my-4 prose-li:-my-3 prose-ul:-mb-6 prose-ol:-mb-8 prose-ol:p-0 prose-li:-mb-4 whitespace-pre-line"
>
...
...
@@ -441,436 +446,484 @@
{/each}
<!-- {@html marked(message.content.replaceAll('\\', '\\\\'))} -->
{/if}
</div>
{/if}
</div>
</div>
{#if message.done}
<div
class=" flex justify-start space-x-1 overflow-x-auto buttons text-gray-700 dark:text-gray-500"
>
{#if siblings.length > 1}
<div class="flex self-center min-w-fit">
<button
class="self-center dark:hover:text-white hover:text-black transition"
on:click={() => {
showPreviousMessage(message);
}}
>
<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="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z"
clip-rule="evenodd"
/>
</svg>
</button>
<div class="text-xs font-bold self-center min-w-fit dark:text-gray-100">
{siblings.indexOf(message.id) + 1} / {siblings.length}
</div>
<button
class="self-center dark:hover:text-white hover:text-black transition"
on:click={() => {
showNextMessage(message);
}}
>
<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="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
{/if}
<!-- if (message.citations) {
citations = message.citations.forEach((citation) => {
citation.document.forEach((document, index) => {
const metadata = citation.metadata?.[index];
const source = citation?.source?.name ?? metadata?.source ?? 'N/A';
citations[source] = citations[source] || {
source: citation.source,
document: [],
metadata: []
};
citations[source].document.push(document);
citations[source].metadata.push(metadata);
});
});
} -->
{#if !readOnly}
<Tooltip content={$i18n.t('Edit')} placement="bottom">
<button
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition"
on:click={() => {
editMessageHandler();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
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>
</Tooltip>
{/if}
{#if message.citations}
<hr class=" dark:border-gray-800" />
<div class="my-2.5 w-full flex overflow-x-auto gap-2 flex-wrap">
{#each message.citations.reduce((acc, citation) => {
citation.document.forEach((document, index) => {
const metadata = citation.metadata?.[index];
const id = metadata?.source ?? 'N/A';
const existingSource = acc.find((item) => item.id === id);
if (existingSource) {
existingSource.document.push(document);
existingSource.metadata.push(metadata);
} else {
acc.push( { id: id, source: citation?.source, document: [document], metadata: metadata ? [metadata] : [] } );
}
});
return acc;
}, []) as citation, idx}
<div class="flex gap-1 text-xs font-semibold">
<div>
[{idx + 1}]
</div>
<Tooltip content={$i18n.t('Copy')} placement="bottom">
<button
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition copy-response-button"
on:click={() => {
copyToClipboard(message.content);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.666 3.888A2.25 2.25 0 0013.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 01-.75.75H9a.75.75 0 01-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 01-2.25 2.25H6.75A2.25 2.25 0 014.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 011.927-.184"
/>
</svg>
</button>
</Tooltip>
{#if !readOnly}
<Tooltip content={$i18n.t('Good Response')} placement="bottom">
<button
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded {message?.annotation
?.rating === 1
? 'bg-gray-100 dark:bg-gray-800'
: ''} dark:hover:text-white hover:text-black transition"
on:click={() => {
rateMessage(message.id, 1);
showRateComment = true;
window.setTimeout(() => {
document
.getElementById(`message-feedback-${message.id}`)
?.scrollIntoView();
}, 0);
}}
>
<svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="w-4 h-4"
xmlns="http://www.w3.org/2000/svg"
><path
d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"
/></svg
>
</button>
</Tooltip>
<Tooltip content={$i18n.t('Bad Response')} placement="bottom">
<button
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded {message?.annotation
?.rating === -1
? 'bg-gray-100 dark:bg-gray-800'
: ''} dark:hover:text-white hover:text-black transition"
on:click={() => {
rateMessage(message.id, -1);
showRateComment = true;
window.setTimeout(() => {
document
.getElementById(`message-feedback-${message.id}`)
?.scrollIntoView();
}, 0);
}}
>
<svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="w-4 h-4"
xmlns="http://www.w3.org/2000/svg"
><path
d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17"
/></svg
>
</button>
</Tooltip>
{/if}
<button
class="dark:text-gray-500 underline"
on:click={() => {
showCitationModal = true;
selectedCitation = citation;
}}
>
{citation.source.name}
</button>
</div>
{/each}
</div>
{/if}
<Tooltip content={$i18n.t('Read Aloud')} placement="bottom">
<button
id="speak-button-{message.id}"
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition"
on:click={() => {
if (!loadingSpeech) {
toggleSpeakMessage(message);
}
}}
>
{#if loadingSpeech}
<svg
class=" w-4 h-4"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
><style>
.spinner_S1WN {
animation: spinner_MGfb 0.8s linear infinite;
animation-delay: -0.8s;
}
.spinner_Km9P {
animation-delay: -0.65s;
}
.spinner_JApP {
animation-delay: -0.5s;
}
@keyframes spinner_MGfb {
93.75%,
100% {
opacity: 0.2;
}
}
</style><circle class="spinner_S1WN" cx="4" cy="12" r="3" /><circle
class="spinner_S1WN spinner_Km9P"
cx="12"
cy="12"
r="3"
/><circle
class="spinner_S1WN spinner_JApP"
cx="20"
cy="12"
r="3"
/></svg
>
{:else if speaking}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M17.25 9.75 19.5 12m0 0 2.25 2.25M19.5 12l2.25-2.25M19.5 12l-2.25 2.25m-10.5-6 4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.009 9.009 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z"
/>
</svg>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19.114 5.636a9 9 0 010 12.728M16.463 8.288a5.25 5.25 0 010 7.424M6.75 8.25l4.72-4.72a.75.75 0 011.28.53v15.88a.75.75 0 01-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.01 9.01 0 012.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75z"
/>
</svg>
{/if}
</button>
</Tooltip>
{#if $config.images && !readOnly}
<Tooltip content="Generate Image" placement="bottom">
<button
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition"
on:click={() => {
if (!generatingImage) {
generateImage(message);
}
}}
>
{#if generatingImage}
<svg
class=" w-4 h-4"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
><style>
.spinner_S1WN {
animation: spinner_MGfb 0.8s linear infinite;
animation-delay: -0.8s;
}
.spinner_Km9P {
animation-delay: -0.65s;
}
.spinner_JApP {
animation-delay: -0.5s;
}
@keyframes spinner_MGfb {
93.75%,
100% {
opacity: 0.2;
}
}
</style><circle class="spinner_S1WN" cx="4" cy="12" r="3" /><circle
class="spinner_S1WN spinner_Km9P"
cx="12"
cy="12"
r="3"
/><circle
class="spinner_S1WN spinner_JApP"
cx="20"
cy="12"
r="3"
/></svg
>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z"
/>
</svg>
{/if}
</button>
</Tooltip>
{/if}
{#if message.done}
<div
class=" flex justify-start space-x-1 overflow-x-auto buttons text-gray-700 dark:text-gray-500"
>
{#if siblings.length > 1}
<div class="flex self-center min-w-fit">
<button
class="self-center dark:hover:text-white hover:text-black transition"
on:click={() => {
showPreviousMessage(message);
}}
>
<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="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z"
clip-rule="evenodd"
/>
</svg>
</button>
<div class="text-xs font-bold self-center min-w-fit dark:text-gray-100">
{siblings.indexOf(message.id) + 1} / {siblings.length}
</div>
{#if message.info}
<Tooltip content={$i18n.t('Generation Info')} placement="bottom">
<button
class=" {isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition whitespace-pre-wrap"
on:click={() => {
console.log(message);
}}
id="info-{message.id}"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"
/>
</svg>
</button>
</Tooltip>
{/if}
<button
class="self-center dark:hover:text-white hover:text-black transition"
on:click={() => {
showNextMessage(message);
}}
>
<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="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
{/if}
{#if isLastMessage && !readOnly}
<Tooltip content={$i18n.t('Continue Response')} placement="bottom">
<button
type="button"
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition regenerate-response-button"
on:click={() => {
continueGeneration();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.91 11.672a.375.375 0 0 1 0 .656l-5.603 3.113a.375.375 0 0 1-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112Z"
/>
</svg>
</button>
</Tooltip>
<Tooltip content={$i18n.t('Regenerate')} placement="bottom">
<button
type="button"
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition regenerate-response-button"
on:click={regenerateResponse}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99"
/>
</svg>
</button>
</Tooltip>
{/if}
</div>
{/if}
{#if !readOnly}
<Tooltip content={$i18n.t('Edit')} placement="bottom">
<button
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition"
on:click={() => {
editMessageHandler();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
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>
</Tooltip>
{/if}
{#if showRateComment}
<RateComment
messageId={message.id}
bind:show={showRateComment}
bind:message
on:submit={() => {
updateChatMessages();
}}
<Tooltip content={$i18n.t('Copy')} placement="bottom">
<button
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition copy-response-button"
on:click={() => {
copyToClipboard(message.content);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.666 3.888A2.25 2.25 0 0013.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 01-.75.75H9a.75.75 0 01-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 01-2.25 2.25H6.75A2.25 2.25 0 014.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 011.927-.184"
/>
</svg>
</button>
</Tooltip>
{#if !readOnly}
<Tooltip content={$i18n.t('Good Response')} placement="bottom">
<button
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded {message?.annotation?.rating ===
1
? 'bg-gray-100 dark:bg-gray-800'
: ''} dark:hover:text-white hover:text-black transition"
on:click={() => {
rateMessage(message.id, 1);
showRateComment = true;
window.setTimeout(() => {
document.getElementById(`message-feedback-${message.id}`)?.scrollIntoView();
}, 0);
}}
>
<svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="w-4 h-4"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"
/>
</svg>
</button>
</Tooltip>
<Tooltip content={$i18n.t('Bad Response')} placement="bottom">
<button
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded {message?.annotation?.rating ===
-1
? 'bg-gray-100 dark:bg-gray-800'
: ''} dark:hover:text-white hover:text-black transition"
on:click={() => {
rateMessage(message.id, -1);
showRateComment = true;
window.setTimeout(() => {
document.getElementById(`message-feedback-${message.id}`)?.scrollIntoView();
}, 0);
}}
>
<svg
stroke="currentColor"
fill="none"
stroke-width="2"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="w-4 h-4"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17"
/>
</svg>
</button>
</Tooltip>
{/if}
<Tooltip content={$i18n.t('Read Aloud')} placement="bottom">
<button
id="speak-button-{message.id}"
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition"
on:click={() => {
if (!loadingSpeech) {
toggleSpeakMessage(message);
}
}}
>
{#if loadingSpeech}
<svg
class=" w-4 h-4"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<style>
.spinner_S1WN {
animation: spinner_MGfb 0.8s linear infinite;
animation-delay: -0.8s;
}
.spinner_Km9P {
animation-delay: -0.65s;
}
.spinner_JApP {
animation-delay: -0.5s;
}
@keyframes spinner_MGfb {
93.75%,
100% {
opacity: 0.2;
}
}
</style>
<circle class="spinner_S1WN" cx="4" cy="12" r="3" />
<circle class="spinner_S1WN spinner_Km9P" cx="12" cy="12" r="3" />
<circle class="spinner_S1WN spinner_JApP" cx="20" cy="12" r="3" />
</svg>
{:else if speaking}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M17.25 9.75 19.5 12m0 0 2.25 2.25M19.5 12l2.25-2.25M19.5 12l-2.25 2.25m-10.5-6 4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.009 9.009 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z"
/>
</svg>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19.114 5.636a9 9 0 010 12.728M16.463 8.288a5.25 5.25 0 010 7.424M6.75 8.25l4.72-4.72a.75.75 0 011.28.53v15.88a.75.75 0 01-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.01 9.01 0 012.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75z"
/>
</svg>
{/if}
</div>
</button>
</Tooltip>
{#if $config.images && !readOnly}
<Tooltip content="Generate Image" placement="bottom">
<button
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition"
on:click={() => {
if (!generatingImage) {
generateImage(message);
}
}}
>
{#if generatingImage}
<svg
class=" w-4 h-4"
fill="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<style>
.spinner_S1WN {
animation: spinner_MGfb 0.8s linear infinite;
animation-delay: -0.8s;
}
.spinner_Km9P {
animation-delay: -0.65s;
}
.spinner_JApP {
animation-delay: -0.5s;
}
@keyframes spinner_MGfb {
93.75%,
100% {
opacity: 0.2;
}
}
</style>
<circle class="spinner_S1WN" cx="4" cy="12" r="3" />
<circle class="spinner_S1WN spinner_Km9P" cx="12" cy="12" r="3" />
<circle class="spinner_S1WN spinner_JApP" cx="20" cy="12" r="3" />
</svg>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z"
/>
</svg>
{/if}
</button>
</Tooltip>
{/if}
{#if message.info}
<Tooltip content={$i18n.t('Generation Info')} placement="bottom">
<button
class=" {isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition whitespace-pre-wrap"
on:click={() => {
console.log(message);
}}
id="info-{message.id}"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"
/>
</svg>
</button>
</Tooltip>
{/if}
{#if isLastMessage && !readOnly}
<Tooltip content={$i18n.t('Continue Response')} placement="bottom">
<button
type="button"
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition regenerate-response-button"
on:click={() => {
continueGeneration();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.91 11.672a.375.375 0 0 1 0 .656l-5.603 3.113a.375.375 0 0 1-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112Z"
/>
</svg>
</button>
</Tooltip>
<Tooltip content={$i18n.t('Regenerate')} placement="bottom">
<button
type="button"
class="{isLastMessage
? 'visible'
: 'invisible group-hover:visible'} p-1 rounded dark:hover:text-white hover:text-black transition regenerate-response-button"
on:click={regenerateResponse}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99"
/>
</svg>
</button>
</Tooltip>
{/if}
</div>
</div>
{/if}
{#if showRateComment}
<RateComment
messageId={message.id}
bind:show={showRateComment}
bind:message
on:submit={() => {
updateChatMessages();
}}
/>
{/if}
{/if}
</div>
</div>
...
...
src/lib/i18n/locales/ar-BH/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"Chunk تداخل"
,
"Chunk Params"
:
"Chunk المتغيرات"
,
"Chunk Size"
:
"Chunk حجم"
,
"Citation"
:
""
,
"Click here for help."
:
"أضغط هنا للمساعدة"
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"انقر هنا للتحقق من ملفات الموديلات الأخرى."
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"دردشة جديدة"
,
"New Password"
:
"كلمة المرور الجديدة"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
"ليس صحيحا من حيث الواقع"
,
"Not sure what to add?"
:
"لست متأكدا ما يجب إضافته؟"
,
"Not sure what to write? Switch to"
:
"لست متأكدا ماذا أكتب؟ التبديل إلى"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"تسجيل الخروج"
,
"Sign up"
:
"تسجيل"
,
"Signing in"
:
"جاري الدخول"
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"خطأ في التعرف على الكلام: {{error}}"
,
"Speech-to-Text Engine"
:
"محرك تحويل الكلام إلى نص"
,
"SpeechRecognition API is not supported in this browser."
:
"API SpeechRecognition غير مدعومة في هذا المتصفح."
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"مساعدك المفيد هنا"
,
"You're now logged in."
:
"لقد قمت الآن بتسجيل الدخول."
,
"Youtube"
:
"Youtube"
}
}
\ No newline at end of file
src/lib/i18n/locales/bg-BG/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"Chunk Overlap"
,
"Chunk Params"
:
"Chunk Params"
,
"Chunk Size"
:
"Chunk Size"
,
"Citation"
:
""
,
"Click here for help."
:
"Натиснете тук за помощ."
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"Натиснете тук за проверка на други моделфайлове."
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"Нов чат"
,
"New Password"
:
"Нова парола"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
"Не сте сигурни, какво да добавите?"
,
"Not sure what to write? Switch to"
:
"Не сте сигурни, какво да напишете? Превключете към"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"Изход"
,
"Sign up"
:
"Регистрация"
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"Speech recognition error: {{error}}"
,
"Speech-to-Text Engine"
:
"Speech-to-Text Engine"
,
"SpeechRecognition API is not supported in this browser."
:
"SpeechRecognition API is not supported in this browser."
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"Вие сте полезен асистент."
,
"You're now logged in."
:
"Сега, вие влязохте в системата."
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/bn-BD/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"চাঙ্ক ওভারল্যাপ"
,
"Chunk Params"
:
"চাঙ্ক প্যারামিটার্স"
,
"Chunk Size"
:
"চাঙ্ক সাইজ"
,
"Citation"
:
""
,
"Click here for help."
:
"সাহায্যের জন্য এখানে ক্লিক করুন"
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"অন্যান্য মডেলফাইল চেক করার জন্য এখানে ক্লিক করুন"
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"নতুন চ্যাট"
,
"New Password"
:
"নতুন পাসওয়ার্ড"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
"কী যুক্ত করতে হবে নিশ্চিত না?"
,
"Not sure what to write? Switch to"
:
"কী লিখতে হবে নিশ্চিত না? পরিবর্তন করুন:"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"সাইন আউট"
,
"Sign up"
:
"সাইন আপ"
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"স্পিচ রিকগনিশনে সমস্যা: {{error}}"
,
"Speech-to-Text Engine"
:
"স্পিচ-টু-টেক্সট ইঞ্জিন"
,
"SpeechRecognition API is not supported in this browser."
:
"এই ব্রাউজার স্পিচরিকগনিশন এপিআই সাপোর্ট করে না।"
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"আপনি একজন উপকারী এসিস্ট্যান্ট"
,
"You're now logged in."
:
"আপনি এখন লগইন করা অবস্থায় আছেন"
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/ca-ES/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"Solapament de Blocs"
,
"Chunk Params"
:
"Paràmetres de Blocs"
,
"Chunk Size"
:
"Mida del Bloc"
,
"Citation"
:
""
,
"Click here for help."
:
"Fes clic aquí per ajuda."
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"Fes clic aquí per comprovar altres fitxers de model."
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"Xat Nou"
,
"New Password"
:
"Nova Contrasenya"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
"No estàs segur del que afegir?"
,
"Not sure what to write? Switch to"
:
"No estàs segur del que escriure? Canvia a"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"Tanca sessió"
,
"Sign up"
:
"Registra't"
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"Error de reconeixement de veu: {{error}}"
,
"Speech-to-Text Engine"
:
"Motor de Veu a Text"
,
"SpeechRecognition API is not supported in this browser."
:
"L'API de Reconèixer Veu no és compatible amb aquest navegador."
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"Ets un assistent útil."
,
"You're now logged in."
:
"Ara estàs connectat."
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/de-DE/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"Chunk Overlap"
,
"Chunk Params"
:
"Chunk Parameter"
,
"Chunk Size"
:
"Chunk Size"
,
"Citation"
:
""
,
"Click here for help."
:
"Klicke hier für Hilfe."
,
"Click here to"
:
"Klicke hier, um"
,
"Click here to check other modelfiles."
:
"Klicke hier, um andere Modelfiles zu überprüfen."
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"Neuer Chat"
,
"New Password"
:
"Neues Passwort"
,
"No results found"
:
"Keine Ergebnisse gefunden"
,
"No source available"
:
""
,
"Not factually correct"
:
"Nicht sachlich korrekt."
,
"Not sure what to add?"
:
"Nicht sicher, was hinzugefügt werden soll?"
,
"Not sure what to write? Switch to"
:
"Nicht sicher, was Du schreiben sollst? Wechsel zu"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"Abmelden"
,
"Sign up"
:
"Registrieren"
,
"Signing in"
:
"Anmeldung"
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"Spracherkennungsfehler: {{error}}"
,
"Speech-to-Text Engine"
:
"Sprache-zu-Text-Engine"
,
"SpeechRecognition API is not supported in this browser."
:
"Die Spracherkennungs-API wird in diesem Browser nicht unterstützt."
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"Du bist ein hilfreicher Assistent."
,
"You're now logged in."
:
"Du bist nun eingeloggt."
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/dg-DG/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"Chunk Overlap"
,
"Chunk Params"
:
"Chunk Params"
,
"Chunk Size"
:
"Chunk Size"
,
"Citation"
:
""
,
"Click here for help."
:
"Click for help. Much assist."
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"Click to check other modelfiles."
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"New Bark"
,
"New Password"
:
"New Barkword"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
"Not sure what to add?"
,
"Not sure what to write? Switch to"
:
"Not sure what to write? Switch to"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"Sign Out much logout"
,
"Sign up"
:
"Sign up much join"
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"Speech recognition error: {{error}} so error"
,
"Speech-to-Text Engine"
:
"Speech-to-Text Engine much speak"
,
"SpeechRecognition API is not supported in this browser."
:
"SpeechRecognition API is not supported in this browser. Much sad."
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"You're a helpful assistant. Much helpful."
,
"You're now logged in."
:
"You're now logged in. Much logged."
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/en-GB/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
""
,
"Chunk Params"
:
""
,
"Chunk Size"
:
""
,
"Citation"
:
""
,
"Click here for help."
:
""
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
""
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
""
,
"New Password"
:
""
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
""
,
"Not sure what to write? Switch to"
:
""
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
""
,
"Sign up"
:
""
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
""
,
"Speech-to-Text Engine"
:
""
,
"SpeechRecognition API is not supported in this browser."
:
""
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
""
,
"You're now logged in."
:
""
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/en-US/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
""
,
"Chunk Params"
:
""
,
"Chunk Size"
:
""
,
"Citation"
:
""
,
"Click here for help."
:
""
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
""
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
""
,
"New Password"
:
""
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
""
,
"Not sure what to write? Switch to"
:
""
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
""
,
"Sign up"
:
""
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
""
,
"Speech-to-Text Engine"
:
""
,
"SpeechRecognition API is not supported in this browser."
:
""
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
""
,
"You're now logged in."
:
""
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/es-ES/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"Superposición de fragmentos"
,
"Chunk Params"
:
"Parámetros de fragmentos"
,
"Chunk Size"
:
"Tamaño de fragmentos"
,
"Citation"
:
""
,
"Click here for help."
:
"Presiona aquí para obtener ayuda."
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"Presiona aquí para consultar otros modelfiles."
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"Nuevo Chat"
,
"New Password"
:
"Nueva Contraseña"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
"¿No sabes qué añadir?"
,
"Not sure what to write? Switch to"
:
"¿No sabes qué escribir? Cambia a"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"Cerrar sesión"
,
"Sign up"
:
"Crear una cuenta"
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"Error de reconocimiento de voz: {{error}}"
,
"Speech-to-Text Engine"
:
"Motor de voz a texto"
,
"SpeechRecognition API is not supported in this browser."
:
"La API SpeechRecognition no es compatible con este navegador."
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"Eres un asistente útil."
,
"You're now logged in."
:
"Has iniciado sesión."
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/fa-IR/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"همپوشانی تکه"
,
"Chunk Params"
:
"پارامترهای تکه"
,
"Chunk Size"
:
"اندازه تکه"
,
"Citation"
:
""
,
"Click here for help."
:
"برای کمک اینجا را کلیک کنید."
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"برای بررسی سایر فایل
\u
200cهای مدل اینجا را کلیک کنید."
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"گپ جدید"
,
"New Password"
:
"رمز عبور جدید"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
"مطمئن نیستید چه چیزی را اضافه کنید؟"
,
"Not sure what to write? Switch to"
:
"مطمئن نیستید چه بنویسید؟ تغییر به"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"خروج"
,
"Sign up"
:
"ثبت نام"
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"خطای تشخیص گفتار: {{error}}"
,
"Speech-to-Text Engine"
:
"موتور گفتار به متن"
,
"SpeechRecognition API is not supported in this browser."
:
"API تشخیص گفتار در این مرورگر پشتیبانی نمی شود."
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"تو یک دستیار سودمند هستی."
,
"You're now logged in."
:
"شما اکنون وارد شده
\u
200cاید."
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/fr-CA/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"Chevauchement de bloc"
,
"Chunk Params"
:
"Paramètres de bloc"
,
"Chunk Size"
:
"Taille de bloc"
,
"Citation"
:
""
,
"Click here for help."
:
"Cliquez ici pour de l'aide."
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"Cliquez ici pour vérifier d'autres fichiers de modèle."
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"Nouvelle discussion"
,
"New Password"
:
"Nouveau mot de passe"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
"Pas sûr de quoi ajouter ?"
,
"Not sure what to write? Switch to"
:
"Pas sûr de quoi écrire ? Changez pour"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"Se déconnecter"
,
"Sign up"
:
"S'inscrire"
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"Erreur de reconnaissance vocale : {{error}}"
,
"Speech-to-Text Engine"
:
"Moteur reconnaissance vocale"
,
"SpeechRecognition API is not supported in this browser."
:
"L'API SpeechRecognition n'est pas prise en charge dans ce navigateur."
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"Vous êtes un assistant utile"
,
"You're now logged in."
:
"Vous êtes maintenant connecté."
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/fr-FR/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"Chevauchement de bloc"
,
"Chunk Params"
:
"Paramètres de bloc"
,
"Chunk Size"
:
"Taille de bloc"
,
"Citation"
:
""
,
"Click here for help."
:
"Cliquez ici pour de l'aide."
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"Cliquez ici pour vérifier d'autres fichiers de modèle."
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"Nouveau chat"
,
"New Password"
:
"Nouveau mot de passe"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
"Vous ne savez pas quoi ajouter ?"
,
"Not sure what to write? Switch to"
:
"Vous ne savez pas quoi écrire ? Basculer vers"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"Se déconnecter"
,
"Sign up"
:
"S'inscrire"
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"Erreur de reconnaissance vocale : {{error}}"
,
"Speech-to-Text Engine"
:
"Moteur de reconnaissance vocale"
,
"SpeechRecognition API is not supported in this browser."
:
"L'API SpeechRecognition n'est pas prise en charge dans ce navigateur."
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"Vous êtes un assistant utile"
,
"You're now logged in."
:
"Vous êtes maintenant connecté."
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/it-IT/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"Sovrapposizione chunk"
,
"Chunk Params"
:
"Parametri chunk"
,
"Chunk Size"
:
"Dimensione chunk"
,
"Citation"
:
""
,
"Click here for help."
:
"Clicca qui per aiuto."
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"Clicca qui per controllare altri file modello."
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"Nuova chat"
,
"New Password"
:
"Nuova password"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
"Non sei sicuro di cosa aggiungere?"
,
"Not sure what to write? Switch to"
:
"Non sei sicuro di cosa scrivere? Passa a"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"Esci"
,
"Sign up"
:
"Registrati"
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"Errore di riconoscimento vocale: {{error}}"
,
"Speech-to-Text Engine"
:
"Motore da voce a testo"
,
"SpeechRecognition API is not supported in this browser."
:
"L'API SpeechRecognition non è supportata in questo browser."
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"Sei un assistente utile."
,
"You're now logged in."
:
"Ora hai effettuato l'accesso."
,
"Youtube"
:
""
}
}
\ No newline at end of file
src/lib/i18n/locales/ja-JP/translation.json
View file @
e98cb452
...
...
@@ -73,6 +73,7 @@
"Chunk Overlap"
:
"チャンクオーバーラップ"
,
"Chunk Params"
:
"チャンクパラメーター"
,
"Chunk Size"
:
"チャンクサイズ"
,
"Citation"
:
""
,
"Click here for help."
:
"ヘルプについてはここをクリックしてください。"
,
"Click here to"
:
""
,
"Click here to check other modelfiles."
:
"他のモデルファイルを確認するにはここをクリックしてください。"
,
...
...
@@ -270,6 +271,7 @@
"New Chat"
:
"新しいチャット"
,
"New Password"
:
"新しいパスワード"
,
"No results found"
:
""
,
"No source available"
:
""
,
"Not factually correct"
:
""
,
"Not sure what to add?"
:
"何を追加すればよいかわからない?"
,
"Not sure what to write? Switch to"
:
"何を書けばよいかわからない? 次に切り替える"
,
...
...
@@ -385,6 +387,7 @@
"Sign Out"
:
"サインアウト"
,
"Sign up"
:
"サインアップ"
,
"Signing in"
:
""
,
"Source"
:
""
,
"Speech recognition error: {{error}}"
:
"音声認識エラー: {{error}}"
,
"Speech-to-Text Engine"
:
"音声テキスト変換エンジン"
,
"SpeechRecognition API is not supported in this browser."
:
"このブラウザでは SpeechRecognition API がサポートされていません。"
,
...
...
@@ -463,4 +466,4 @@
"You're a helpful assistant."
:
"あなたは役に立つアシスタントです。"
,
"You're now logged in."
:
"ログインしました。"
,
"Youtube"
:
""
}
}
\ No newline at end of file
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment