Jelajahi Sumber

Merge pull request #2011 from cheahjs/feat/rag-citations

feat: show RAG query results as citations
Timothy Jaeryang Baek 1 tahun lalu
induk
melakukan
e98cb45238
35 mengubah file dengan 772 tambahan dan 488 penghapusan
  1. 27 22
      backend/apps/rag/utils.py
  2. 12 10
      backend/config.py
  3. 36 3
      backend/main.py
  4. 11 0
      src/lib/apis/streaming/index.ts
  5. 75 0
      src/lib/components/chat/Messages/CitationsModal.svelte
  6. 473 420
      src/lib/components/chat/Messages/ResponseMessage.svelte
  7. 4 1
      src/lib/i18n/locales/ar-BH/translation.json
  8. 4 1
      src/lib/i18n/locales/bg-BG/translation.json
  9. 4 1
      src/lib/i18n/locales/bn-BD/translation.json
  10. 4 1
      src/lib/i18n/locales/ca-ES/translation.json
  11. 4 1
      src/lib/i18n/locales/de-DE/translation.json
  12. 4 1
      src/lib/i18n/locales/dg-DG/translation.json
  13. 4 1
      src/lib/i18n/locales/en-GB/translation.json
  14. 4 1
      src/lib/i18n/locales/en-US/translation.json
  15. 4 1
      src/lib/i18n/locales/es-ES/translation.json
  16. 4 1
      src/lib/i18n/locales/fa-IR/translation.json
  17. 4 1
      src/lib/i18n/locales/fr-CA/translation.json
  18. 4 1
      src/lib/i18n/locales/fr-FR/translation.json
  19. 4 1
      src/lib/i18n/locales/it-IT/translation.json
  20. 4 1
      src/lib/i18n/locales/ja-JP/translation.json
  21. 4 1
      src/lib/i18n/locales/ka-GE/translation.json
  22. 4 1
      src/lib/i18n/locales/ko-KR/translation.json
  23. 4 1
      src/lib/i18n/locales/nl-NL/translation.json
  24. 4 1
      src/lib/i18n/locales/pl-PL/translation.json
  25. 4 1
      src/lib/i18n/locales/pt-BR/translation.json
  26. 4 1
      src/lib/i18n/locales/pt-PT/translation.json
  27. 4 1
      src/lib/i18n/locales/ru-RU/translation.json
  28. 4 1
      src/lib/i18n/locales/sv-SE/translation.json
  29. 4 1
      src/lib/i18n/locales/tr-TR/translation.json
  30. 4 1
      src/lib/i18n/locales/uk-UA/translation.json
  31. 4 1
      src/lib/i18n/locales/vi-VN/translation.json
  32. 4 1
      src/lib/i18n/locales/zh-CN/translation.json
  33. 4 1
      src/lib/i18n/locales/zh-TW/translation.json
  34. 15 3
      src/routes/(app)/+page.svelte
  35. 15 3
      src/routes/(app)/c/[id]/+page.svelte

+ 27 - 22
backend/apps/rag/utils.py

@@ -271,14 +271,14 @@ def rag_messages(
     for doc in docs:
     for doc in docs:
         context = None
         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")
             log.debug(f"skipping {doc} as it has already been extracted")
             continue
             continue
 
 
@@ -288,11 +288,7 @@ def rag_messages(
             else:
             else:
                 if hybrid_search:
                 if hybrid_search:
                     context = query_collection_with_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,
                         query=query,
                         embedding_function=embedding_function,
                         embedding_function=embedding_function,
                         k=k,
                         k=k,
@@ -301,11 +297,7 @@ def rag_messages(
                     )
                     )
                 else:
                 else:
                     context = query_collection(
                     context = query_collection(
-                        collection_names=(
-                            doc["collection_names"]
-                            if doc["type"] == "collection"
-                            else [doc["collection_name"]]
-                        ),
+                        collection_names=collection_names,
                         query=query,
                         query=query,
                         embedding_function=embedding_function,
                         embedding_function=embedding_function,
                         k=k,
                         k=k,
@@ -315,18 +307,31 @@ def rag_messages(
             context = None
             context = None
 
 
         if context:
         if context:
-            relevant_contexts.append(context)
+            relevant_contexts.append({**context, "source": doc})
 
 
-        extracted_collections.extend(collection)
+        extracted_collections.extend(collection_names)
 
 
     context_string = ""
     context_string = ""
+
+    citations = []
     for context in relevant_contexts:
     for context in relevant_contexts:
         try:
         try:
             if "documents" in context:
             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:
         except Exception as e:
             log.exception(e)
             log.exception(e)
+
     context_string = context_string.strip()
     context_string = context_string.strip()
 
 
     ra_content = rag_template(
     ra_content = rag_template(
@@ -355,7 +360,7 @@ def rag_messages(
 
 
     messages[last_user_message_idx] = new_user_message
     messages[last_user_message_idx] = new_user_message
 
 
-    return messages
+    return messages, citations
 
 
 
 
 def get_model_path(model: str, update_model: bool = False):
 def get_model_path(model: str, update_model: bool = False):

+ 12 - 10
backend/config.py

@@ -18,6 +18,18 @@ from secrets import token_bytes
 from constants import ERROR_MESSAGES
 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
 # LOGGING
 ####################################
 ####################################
@@ -59,16 +71,6 @@ for source in log_sources:
 
 
 log.setLevel(SRC_LOG_LEVELS["CONFIG"])
 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")
 WEBUI_NAME = os.environ.get("WEBUI_NAME", "Open WebUI")
 if WEBUI_NAME != "Open WebUI":
 if WEBUI_NAME != "Open WebUI":

+ 36 - 3
backend/main.py

@@ -15,7 +15,7 @@ from fastapi.middleware.wsgi import WSGIMiddleware
 from fastapi.middleware.cors import CORSMiddleware
 from fastapi.middleware.cors import CORSMiddleware
 from starlette.exceptions import HTTPException as StarletteHTTPException
 from starlette.exceptions import HTTPException as StarletteHTTPException
 from starlette.middleware.base import BaseHTTPMiddleware
 from starlette.middleware.base import BaseHTTPMiddleware
-
+from starlette.responses import StreamingResponse
 
 
 from apps.ollama.main import app as ollama_app
 from apps.ollama.main import app as ollama_app
 from apps.openai.main import app as openai_app
 from apps.openai.main import app as openai_app
@@ -102,6 +102,8 @@ origins = ["*"]
 
 
 class RAGMiddleware(BaseHTTPMiddleware):
 class RAGMiddleware(BaseHTTPMiddleware):
     async def dispatch(self, request: Request, call_next):
     async def dispatch(self, request: Request, call_next):
+        return_citations = False
+
         if request.method == "POST" and (
         if request.method == "POST" and (
             "/api/chat" in request.url.path or "/chat/completions" in request.url.path
             "/api/chat" in request.url.path or "/chat/completions" in request.url.path
         ):
         ):
@@ -114,11 +116,15 @@ class RAGMiddleware(BaseHTTPMiddleware):
             # Parse string to JSON
             # Parse string to JSON
             data = json.loads(body_str) if body_str else {}
             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
             # Example: Add a new key-value pair or modify existing ones
             # data["modified"] = True  # Example modification
             # data["modified"] = True  # Example modification
             if "docs" in data:
             if "docs" in data:
                 data = {**data}
                 data = {**data}
-                data["messages"] = rag_messages(
+                data["messages"], citations = rag_messages(
                     docs=data["docs"],
                     docs=data["docs"],
                     messages=data["messages"],
                     messages=data["messages"],
                     template=rag_app.state.RAG_TEMPLATE,
                     template=rag_app.state.RAG_TEMPLATE,
@@ -130,7 +136,9 @@ class RAGMiddleware(BaseHTTPMiddleware):
                 )
                 )
                 del data["docs"]
                 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")
             modified_body_bytes = json.dumps(data).encode("utf-8")
 
 
@@ -148,11 +156,36 @@ class RAGMiddleware(BaseHTTPMiddleware):
             ]
             ]
 
 
         response = await call_next(request)
         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
         return response
 
 
     async def _receive(self, body: bytes):
     async def _receive(self, body: bytes):
         return {"type": "http.request", "body": body, "more_body": False}
         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)
 app.add_middleware(RAGMiddleware)
 
 

+ 11 - 0
src/lib/apis/streaming/index.ts

@@ -4,6 +4,8 @@ import type { ParsedEvent } from 'eventsource-parser';
 type TextStreamUpdate = {
 type TextStreamUpdate = {
 	done: boolean;
 	done: boolean;
 	value: string;
 	value: string;
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
+	citations?: any;
 };
 };
 
 
 // createOpenAITextStream takes a responseBody with a SSE response,
 // createOpenAITextStream takes a responseBody with a SSE response,
@@ -45,6 +47,11 @@ async function* openAIStreamToIterator(
 			const parsedData = JSON.parse(data);
 			const parsedData = JSON.parse(data);
 			console.log(parsedData);
 			console.log(parsedData);
 
 
+			if (parsedData.citations) {
+				yield { done: false, value: '', citations: parsedData.citations };
+				continue;
+			}
+
 			yield { done: false, value: parsedData.choices?.[0]?.delta?.content ?? '' };
 			yield { done: false, value: parsedData.choices?.[0]?.delta?.content ?? '' };
 		} catch (e) {
 		} catch (e) {
 			console.error('Error extracting delta from SSE event:', e);
 			console.error('Error extracting delta from SSE event:', e);
@@ -62,6 +69,10 @@ async function* streamLargeDeltasAsRandomChunks(
 			yield textStreamUpdate;
 			yield textStreamUpdate;
 			return;
 			return;
 		}
 		}
+		if (textStreamUpdate.citations) {
+			yield textStreamUpdate;
+			continue;
+		}
 		let content = textStreamUpdate.value;
 		let content = textStreamUpdate.value;
 		if (content.length < 5) {
 		if (content.length < 5) {
 			yield { done: false, value: content };
 			yield { done: false, value: content };

+ 75 - 0
src/lib/components/chat/Messages/CitationsModal.svelte

@@ -0,0 +1,75 @@
+<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>

+ 473 - 420
src/lib/components/chat/Messages/ResponseMessage.svelte

@@ -32,6 +32,7 @@
 	import { WEBUI_BASE_URL } from '$lib/constants';
 	import { WEBUI_BASE_URL } from '$lib/constants';
 	import Tooltip from '$lib/components/common/Tooltip.svelte';
 	import Tooltip from '$lib/components/common/Tooltip.svelte';
 	import RateComment from './RateComment.svelte';
 	import RateComment from './RateComment.svelte';
+	import CitationsModal from '$lib/components/chat/Messages/CitationsModal.svelte';
 
 
 	export let modelfiles = [];
 	export let modelfiles = [];
 	export let message;
 	export let message;
@@ -65,6 +66,9 @@
 
 
 	let showRateComment = false;
 	let showRateComment = false;
 
 
+	let showCitationModal = false;
+	let selectedCitation = null;
+
 	$: tokens = marked.lexer(sanitizeResponseContent(message.content));
 	$: tokens = marked.lexer(sanitizeResponseContent(message.content));
 
 
 	const renderer = new marked.Renderer();
 	const renderer = new marked.Renderer();
@@ -324,6 +328,8 @@
 	});
 	});
 </script>
 </script>
 
 
+<CitationsModal bind:show={showCitationModal} citation={selectedCitation} />
+
 {#key message.id}
 {#key message.id}
 	<div class=" flex w-full message-{message.id}" id="message-{message.id}">
 	<div class=" flex w-full message-{message.id}" id="message-{message.id}">
 		<ProfileImage
 		<ProfileImage
@@ -360,7 +366,6 @@
 						{/each}
 						{/each}
 					</div>
 					</div>
 				{/if}
 				{/if}
-
 				<div
 				<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"
 					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}
 									{/each}
 									<!-- {@html marked(message.content.replaceAll('\\', '\\\\'))} -->
 									<!-- {@html marked(message.content.replaceAll('\\', '\\\\'))} -->
 								{/if}
 								{/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}
 								{/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}
 						{/if}
 					</div>
 					</div>
-				</div>
+				{/if}
+
+				{#if showRateComment}
+					<RateComment
+						messageId={message.id}
+						bind:show={showRateComment}
+						bind:message
+						on:submit={() => {
+							updateChatMessages();
+						}}
+					/>
+				{/if}
 			{/if}
 			{/if}
 		</div>
 		</div>
 	</div>
 	</div>

+ 4 - 1
src/lib/i18n/locales/ar-BH/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chunk تداخل",
 	"Chunk Overlap": "Chunk تداخل",
 	"Chunk Params": "Chunk المتغيرات",
 	"Chunk Params": "Chunk المتغيرات",
 	"Chunk Size": "Chunk حجم",
 	"Chunk Size": "Chunk حجم",
+	"Citation": "",
 	"Click here for help.": "أضغط هنا للمساعدة",
 	"Click here for help.": "أضغط هنا للمساعدة",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "انقر هنا للتحقق من ملفات الموديلات الأخرى.",
 	"Click here to check other modelfiles.": "انقر هنا للتحقق من ملفات الموديلات الأخرى.",
@@ -270,6 +271,7 @@
 	"New Chat": "دردشة جديدة",
 	"New Chat": "دردشة جديدة",
 	"New Password": "كلمة المرور الجديدة",
 	"New Password": "كلمة المرور الجديدة",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "ليس صحيحا من حيث الواقع",
 	"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": "تسجيل الخروج",
 	"Sign up": "تسجيل",
 	"Sign up": "تسجيل",
 	"Signing in": "جاري الدخول",
 	"Signing in": "جاري الدخول",
+	"Source": "",
 	"Speech recognition error: {{error}}": "خطأ في التعرف على الكلام: {{error}}",
 	"Speech recognition error: {{error}}": "خطأ في التعرف على الكلام: {{error}}",
 	"Speech-to-Text Engine": "محرك تحويل الكلام إلى نص",
 	"Speech-to-Text Engine": "محرك تحويل الكلام إلى نص",
 	"SpeechRecognition API is not supported in this browser.": "API SpeechRecognition غير مدعومة في هذا المتصفح.",
 	"SpeechRecognition API is not supported in this browser.": "API SpeechRecognition غير مدعومة في هذا المتصفح.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "مساعدك المفيد هنا",
 	"You're a helpful assistant.": "مساعدك المفيد هنا",
 	"You're now logged in.": "لقد قمت الآن بتسجيل الدخول.",
 	"You're now logged in.": "لقد قمت الآن بتسجيل الدخول.",
 	"Youtube": "Youtube"
 	"Youtube": "Youtube"
-}
+}

+ 4 - 1
src/lib/i18n/locales/bg-BG/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Params": "Chunk Params",
 	"Chunk Params": "Chunk Params",
 	"Chunk Size": "Chunk Size",
 	"Chunk Size": "Chunk Size",
+	"Citation": "",
 	"Click here for help.": "Натиснете тук за помощ.",
 	"Click here for help.": "Натиснете тук за помощ.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Натиснете тук за проверка на други моделфайлове.",
 	"Click here to check other modelfiles.": "Натиснете тук за проверка на други моделфайлове.",
@@ -270,6 +271,7 @@
 	"New Chat": "Нов чат",
 	"New Chat": "Нов чат",
 	"New Password": "Нова парола",
 	"New Password": "Нова парола",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "Изход",
 	"Sign up": "Регистрация",
 	"Sign up": "Регистрация",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Speech recognition error: {{error}}",
 	"Speech recognition error: {{error}}": "Speech recognition error: {{error}}",
 	"Speech-to-Text Engine": "Speech-to-Text Engine",
 	"Speech-to-Text Engine": "Speech-to-Text Engine",
 	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API is not supported in this browser.",
 	"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 a helpful assistant.": "Вие сте полезен асистент.",
 	"You're now logged in.": "Сега, вие влязохте в системата.",
 	"You're now logged in.": "Сега, вие влязохте в системата.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/bn-BD/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "চাঙ্ক ওভারল্যাপ",
 	"Chunk Overlap": "চাঙ্ক ওভারল্যাপ",
 	"Chunk Params": "চাঙ্ক প্যারামিটার্স",
 	"Chunk Params": "চাঙ্ক প্যারামিটার্স",
 	"Chunk Size": "চাঙ্ক সাইজ",
 	"Chunk Size": "চাঙ্ক সাইজ",
+	"Citation": "",
 	"Click here for help.": "সাহায্যের জন্য এখানে ক্লিক করুন",
 	"Click here for help.": "সাহায্যের জন্য এখানে ক্লিক করুন",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "অন্যান্য মডেলফাইল চেক করার জন্য এখানে ক্লিক করুন",
 	"Click here to check other modelfiles.": "অন্যান্য মডেলফাইল চেক করার জন্য এখানে ক্লিক করুন",
@@ -270,6 +271,7 @@
 	"New Chat": "নতুন চ্যাট",
 	"New Chat": "নতুন চ্যাট",
 	"New Password": "নতুন পাসওয়ার্ড",
 	"New Password": "নতুন পাসওয়ার্ড",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "সাইন আউট",
 	"Sign up": "সাইন আপ",
 	"Sign up": "সাইন আপ",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "স্পিচ রিকগনিশনে সমস্যা: {{error}}",
 	"Speech recognition error: {{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 a helpful assistant.": "আপনি একজন উপকারী এসিস্ট্যান্ট",
 	"You're now logged in.": "আপনি এখন লগইন করা অবস্থায় আছেন",
 	"You're now logged in.": "আপনি এখন লগইন করা অবস্থায় আছেন",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/ca-ES/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Solapament de Blocs",
 	"Chunk Overlap": "Solapament de Blocs",
 	"Chunk Params": "Paràmetres de Blocs",
 	"Chunk Params": "Paràmetres de Blocs",
 	"Chunk Size": "Mida del Bloc",
 	"Chunk Size": "Mida del Bloc",
+	"Citation": "",
 	"Click here for help.": "Fes clic aquí per ajuda.",
 	"Click here for help.": "Fes clic aquí per ajuda.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Fes clic aquí per comprovar altres fitxers de model.",
 	"Click here to check other modelfiles.": "Fes clic aquí per comprovar altres fitxers de model.",
@@ -270,6 +271,7 @@
 	"New Chat": "Xat Nou",
 	"New Chat": "Xat Nou",
 	"New Password": "Nova Contrasenya",
 	"New Password": "Nova Contrasenya",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "No estàs segur del que afegir?",
 	"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",
 	"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 Out": "Tanca sessió",
 	"Sign up": "Registra't",
 	"Sign up": "Registra't",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Error de reconeixement de veu: {{error}}",
 	"Speech recognition error: {{error}}": "Error de reconeixement de veu: {{error}}",
 	"Speech-to-Text Engine": "Motor de Veu a Text",
 	"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.",
 	"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 a helpful assistant.": "Ets un assistent útil.",
 	"You're now logged in.": "Ara estàs connectat.",
 	"You're now logged in.": "Ara estàs connectat.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/de-DE/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Params": "Chunk Parameter",
 	"Chunk Params": "Chunk Parameter",
 	"Chunk Size": "Chunk Size",
 	"Chunk Size": "Chunk Size",
+	"Citation": "",
 	"Click here for help.": "Klicke hier für Hilfe.",
 	"Click here for help.": "Klicke hier für Hilfe.",
 	"Click here to": "Klicke hier, um",
 	"Click here to": "Klicke hier, um",
 	"Click here to check other modelfiles.": "Klicke hier, um andere Modelfiles zu überprüfen.",
 	"Click here to check other modelfiles.": "Klicke hier, um andere Modelfiles zu überprüfen.",
@@ -270,6 +271,7 @@
 	"New Chat": "Neuer Chat",
 	"New Chat": "Neuer Chat",
 	"New Password": "Neues Passwort",
 	"New Password": "Neues Passwort",
 	"No results found": "Keine Ergebnisse gefunden",
 	"No results found": "Keine Ergebnisse gefunden",
+	"No source available": "",
 	"Not factually correct": "Nicht sachlich korrekt.",
 	"Not factually correct": "Nicht sachlich korrekt.",
 	"Not sure what to add?": "Nicht sicher, was hinzugefügt werden soll?",
 	"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",
 	"Not sure what to write? Switch to": "Nicht sicher, was Du schreiben sollst? Wechsel zu",
@@ -385,6 +387,7 @@
 	"Sign Out": "Abmelden",
 	"Sign Out": "Abmelden",
 	"Sign up": "Registrieren",
 	"Sign up": "Registrieren",
 	"Signing in": "Anmeldung",
 	"Signing in": "Anmeldung",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Spracherkennungsfehler: {{error}}",
 	"Speech recognition error: {{error}}": "Spracherkennungsfehler: {{error}}",
 	"Speech-to-Text Engine": "Sprache-zu-Text-Engine",
 	"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.",
 	"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 a helpful assistant.": "Du bist ein hilfreicher Assistent.",
 	"You're now logged in.": "Du bist nun eingeloggt.",
 	"You're now logged in.": "Du bist nun eingeloggt.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/dg-DG/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Params": "Chunk Params",
 	"Chunk Params": "Chunk Params",
 	"Chunk Size": "Chunk Size",
 	"Chunk Size": "Chunk Size",
+	"Citation": "",
 	"Click here for help.": "Click for help. Much assist.",
 	"Click here for help.": "Click for help. Much assist.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Click to check other modelfiles.",
 	"Click here to check other modelfiles.": "Click to check other modelfiles.",
@@ -270,6 +271,7 @@
 	"New Chat": "New Bark",
 	"New Chat": "New Bark",
 	"New Password": "New Barkword",
 	"New Password": "New Barkword",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "Not sure what to add?",
 	"Not sure what to add?": "Not sure what to add?",
 	"Not sure what to write? Switch to": "Not sure what to write? Switch to",
 	"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 Out": "Sign Out much logout",
 	"Sign up": "Sign up much join",
 	"Sign up": "Sign up much join",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Speech recognition error: {{error}} so error",
 	"Speech recognition error: {{error}}": "Speech recognition error: {{error}} so error",
 	"Speech-to-Text Engine": "Speech-to-Text Engine much speak",
 	"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.",
 	"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 a helpful assistant.": "You're a helpful assistant. Much helpful.",
 	"You're now logged in.": "You're now logged in. Much logged.",
 	"You're now logged in.": "You're now logged in. Much logged.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/en-GB/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "",
 	"Chunk Overlap": "",
 	"Chunk Params": "",
 	"Chunk Params": "",
 	"Chunk Size": "",
 	"Chunk Size": "",
+	"Citation": "",
 	"Click here for help.": "",
 	"Click here for help.": "",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "",
 	"Click here to check other modelfiles.": "",
@@ -270,6 +271,7 @@
 	"New Chat": "",
 	"New Chat": "",
 	"New Password": "",
 	"New Password": "",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "",
 	"Sign up": "",
 	"Sign up": "",
 	"Signing in": "",
 	"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 a helpful assistant.": "",
 	"You're now logged in.": "",
 	"You're now logged in.": "",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/en-US/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "",
 	"Chunk Overlap": "",
 	"Chunk Params": "",
 	"Chunk Params": "",
 	"Chunk Size": "",
 	"Chunk Size": "",
+	"Citation": "",
 	"Click here for help.": "",
 	"Click here for help.": "",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "",
 	"Click here to check other modelfiles.": "",
@@ -270,6 +271,7 @@
 	"New Chat": "",
 	"New Chat": "",
 	"New Password": "",
 	"New Password": "",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "",
 	"Sign up": "",
 	"Sign up": "",
 	"Signing in": "",
 	"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 a helpful assistant.": "",
 	"You're now logged in.": "",
 	"You're now logged in.": "",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/es-ES/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Superposición de fragmentos",
 	"Chunk Overlap": "Superposición de fragmentos",
 	"Chunk Params": "Parámetros de fragmentos",
 	"Chunk Params": "Parámetros de fragmentos",
 	"Chunk Size": "Tamaño de fragmentos",
 	"Chunk Size": "Tamaño de fragmentos",
+	"Citation": "",
 	"Click here for help.": "Presiona aquí para obtener ayuda.",
 	"Click here for help.": "Presiona aquí para obtener ayuda.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Presiona aquí para consultar otros modelfiles.",
 	"Click here to check other modelfiles.": "Presiona aquí para consultar otros modelfiles.",
@@ -270,6 +271,7 @@
 	"New Chat": "Nuevo Chat",
 	"New Chat": "Nuevo Chat",
 	"New Password": "Nueva Contraseña",
 	"New Password": "Nueva Contraseña",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "¿No sabes qué añadir?",
 	"Not sure what to add?": "¿No sabes qué añadir?",
 	"Not sure what to write? Switch to": "¿No sabes qué escribir? Cambia a",
 	"Not sure what to write? Switch to": "¿No sabes qué escribir? Cambia a",
@@ -385,6 +387,7 @@
 	"Sign Out": "Cerrar sesión",
 	"Sign Out": "Cerrar sesión",
 	"Sign up": "Crear una cuenta",
 	"Sign up": "Crear una cuenta",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Error de reconocimiento de voz: {{error}}",
 	"Speech recognition error: {{error}}": "Error de reconocimiento de voz: {{error}}",
 	"Speech-to-Text Engine": "Motor de voz a texto",
 	"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.",
 	"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 a helpful assistant.": "Eres un asistente útil.",
 	"You're now logged in.": "Has iniciado sesión.",
 	"You're now logged in.": "Has iniciado sesión.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/fa-IR/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "همپوشانی تکه",
 	"Chunk Overlap": "همپوشانی تکه",
 	"Chunk Params": "پارامترهای تکه",
 	"Chunk Params": "پارامترهای تکه",
 	"Chunk Size": "اندازه تکه",
 	"Chunk Size": "اندازه تکه",
+	"Citation": "",
 	"Click here for help.": "برای کمک اینجا را کلیک کنید.",
 	"Click here for help.": "برای کمک اینجا را کلیک کنید.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "برای بررسی سایر فایل\u200cهای مدل اینجا را کلیک کنید.",
 	"Click here to check other modelfiles.": "برای بررسی سایر فایل\u200cهای مدل اینجا را کلیک کنید.",
@@ -270,6 +271,7 @@
 	"New Chat": "گپ جدید",
 	"New Chat": "گپ جدید",
 	"New Password": "رمز عبور جدید",
 	"New Password": "رمز عبور جدید",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "خروج",
 	"Sign up": "ثبت نام",
 	"Sign up": "ثبت نام",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "خطای تشخیص گفتار: {{error}}",
 	"Speech recognition error: {{error}}": "خطای تشخیص گفتار: {{error}}",
 	"Speech-to-Text Engine": "موتور گفتار به متن",
 	"Speech-to-Text Engine": "موتور گفتار به متن",
 	"SpeechRecognition API is not supported in this browser.": "API تشخیص گفتار در این مرورگر پشتیبانی نمی شود.",
 	"SpeechRecognition API is not supported in this browser.": "API تشخیص گفتار در این مرورگر پشتیبانی نمی شود.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "تو یک دستیار سودمند هستی.",
 	"You're a helpful assistant.": "تو یک دستیار سودمند هستی.",
 	"You're now logged in.": "شما اکنون وارد شده\u200cاید.",
 	"You're now logged in.": "شما اکنون وارد شده\u200cاید.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/fr-CA/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chevauchement de bloc",
 	"Chunk Overlap": "Chevauchement de bloc",
 	"Chunk Params": "Paramètres de bloc",
 	"Chunk Params": "Paramètres de bloc",
 	"Chunk Size": "Taille de bloc",
 	"Chunk Size": "Taille de bloc",
+	"Citation": "",
 	"Click here for help.": "Cliquez ici pour de l'aide.",
 	"Click here for help.": "Cliquez ici pour de l'aide.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Cliquez ici pour vérifier d'autres fichiers de modèle.",
 	"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 Chat": "Nouvelle discussion",
 	"New Password": "Nouveau mot de passe",
 	"New Password": "Nouveau mot de passe",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "Pas sûr de quoi ajouter ?",
 	"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",
 	"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 Out": "Se déconnecter",
 	"Sign up": "S'inscrire",
 	"Sign up": "S'inscrire",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Erreur de reconnaissance vocale : {{error}}",
 	"Speech recognition error: {{error}}": "Erreur de reconnaissance vocale : {{error}}",
 	"Speech-to-Text Engine": "Moteur reconnaissance vocale",
 	"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.",
 	"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 a helpful assistant.": "Vous êtes un assistant utile",
 	"You're now logged in.": "Vous êtes maintenant connecté.",
 	"You're now logged in.": "Vous êtes maintenant connecté.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/fr-FR/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chevauchement de bloc",
 	"Chunk Overlap": "Chevauchement de bloc",
 	"Chunk Params": "Paramètres de bloc",
 	"Chunk Params": "Paramètres de bloc",
 	"Chunk Size": "Taille de bloc",
 	"Chunk Size": "Taille de bloc",
+	"Citation": "",
 	"Click here for help.": "Cliquez ici pour de l'aide.",
 	"Click here for help.": "Cliquez ici pour de l'aide.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Cliquez ici pour vérifier d'autres fichiers de modèle.",
 	"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 Chat": "Nouveau chat",
 	"New Password": "Nouveau mot de passe",
 	"New Password": "Nouveau mot de passe",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "Vous ne savez pas quoi ajouter ?",
 	"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",
 	"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 Out": "Se déconnecter",
 	"Sign up": "S'inscrire",
 	"Sign up": "S'inscrire",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Erreur de reconnaissance vocale : {{error}}",
 	"Speech recognition error: {{error}}": "Erreur de reconnaissance vocale : {{error}}",
 	"Speech-to-Text Engine": "Moteur de reconnaissance vocale",
 	"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.",
 	"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 a helpful assistant.": "Vous êtes un assistant utile",
 	"You're now logged in.": "Vous êtes maintenant connecté.",
 	"You're now logged in.": "Vous êtes maintenant connecté.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/it-IT/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Sovrapposizione chunk",
 	"Chunk Overlap": "Sovrapposizione chunk",
 	"Chunk Params": "Parametri chunk",
 	"Chunk Params": "Parametri chunk",
 	"Chunk Size": "Dimensione chunk",
 	"Chunk Size": "Dimensione chunk",
+	"Citation": "",
 	"Click here for help.": "Clicca qui per aiuto.",
 	"Click here for help.": "Clicca qui per aiuto.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Clicca qui per controllare altri file modello.",
 	"Click here to check other modelfiles.": "Clicca qui per controllare altri file modello.",
@@ -270,6 +271,7 @@
 	"New Chat": "Nuova chat",
 	"New Chat": "Nuova chat",
 	"New Password": "Nuova password",
 	"New Password": "Nuova password",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "Non sei sicuro di cosa aggiungere?",
 	"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",
 	"Not sure what to write? Switch to": "Non sei sicuro di cosa scrivere? Passa a",
@@ -385,6 +387,7 @@
 	"Sign Out": "Esci",
 	"Sign Out": "Esci",
 	"Sign up": "Registrati",
 	"Sign up": "Registrati",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Errore di riconoscimento vocale: {{error}}",
 	"Speech recognition error: {{error}}": "Errore di riconoscimento vocale: {{error}}",
 	"Speech-to-Text Engine": "Motore da voce a testo",
 	"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.",
 	"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 a helpful assistant.": "Sei un assistente utile.",
 	"You're now logged in.": "Ora hai effettuato l'accesso.",
 	"You're now logged in.": "Ora hai effettuato l'accesso.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/ja-JP/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "チャンクオーバーラップ",
 	"Chunk Overlap": "チャンクオーバーラップ",
 	"Chunk Params": "チャンクパラメーター",
 	"Chunk Params": "チャンクパラメーター",
 	"Chunk Size": "チャンクサイズ",
 	"Chunk Size": "チャンクサイズ",
+	"Citation": "",
 	"Click here for help.": "ヘルプについてはここをクリックしてください。",
 	"Click here for help.": "ヘルプについてはここをクリックしてください。",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "他のモデルファイルを確認するにはここをクリックしてください。",
 	"Click here to check other modelfiles.": "他のモデルファイルを確認するにはここをクリックしてください。",
@@ -270,6 +271,7 @@
 	"New Chat": "新しいチャット",
 	"New Chat": "新しいチャット",
 	"New Password": "新しいパスワード",
 	"New Password": "新しいパスワード",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "サインアウト",
 	"Sign up": "サインアップ",
 	"Sign up": "サインアップ",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "音声認識エラー: {{error}}",
 	"Speech recognition error: {{error}}": "音声認識エラー: {{error}}",
 	"Speech-to-Text Engine": "音声テキスト変換エンジン",
 	"Speech-to-Text Engine": "音声テキスト変換エンジン",
 	"SpeechRecognition API is not supported in this browser.": "このブラウザでは SpeechRecognition API がサポートされていません。",
 	"SpeechRecognition API is not supported in this browser.": "このブラウザでは SpeechRecognition API がサポートされていません。",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "あなたは役に立つアシスタントです。",
 	"You're a helpful assistant.": "あなたは役に立つアシスタントです。",
 	"You're now logged in.": "ログインしました。",
 	"You're now logged in.": "ログインしました。",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/ka-GE/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "გადახურვა ფრაგმენტულია",
 	"Chunk Overlap": "გადახურვა ფრაგმენტულია",
 	"Chunk Params": "გადახურვის პარამეტრები",
 	"Chunk Params": "გადახურვის პარამეტრები",
 	"Chunk Size": "გადახურვის ზომა",
 	"Chunk Size": "გადახურვის ზომა",
+	"Citation": "",
 	"Click here for help.": "დახმარებისთვის, დააკლიკე აქ",
 	"Click here for help.": "დახმარებისთვის, დააკლიკე აქ",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "სხვა მოდელური ფაილების სანახავად, დააკლიკე აქ",
 	"Click here to check other modelfiles.": "სხვა მოდელური ფაილების სანახავად, დააკლიკე აქ",
@@ -270,6 +271,7 @@
 	"New Chat": "ახალი მიმოწერა",
 	"New Chat": "ახალი მიმოწერა",
 	"New Password": "ახალი პაროლი",
 	"New Password": "ახალი პაროლი",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "გასვლა",
 	"Sign up": "რეგისტრაცია",
 	"Sign up": "რეგისტრაცია",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "მეტყველების ამოცნობის შეცდომა: {{error}}",
 	"Speech recognition error: {{error}}": "მეტყველების ამოცნობის შეცდომა: {{error}}",
 	"Speech-to-Text Engine": "ხმოვან-ტექსტური ძრავი",
 	"Speech-to-Text Engine": "ხმოვან-ტექსტური ძრავი",
 	"SpeechRecognition API is not supported in this browser.": "მეტყველების ამოცნობის API არ არის მხარდაჭერილი ამ ბრაუზერში.",
 	"SpeechRecognition API is not supported in this browser.": "მეტყველების ამოცნობის API არ არის მხარდაჭერილი ამ ბრაუზერში.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "თქვენ სასარგებლო ასისტენტი ხართ.",
 	"You're a helpful assistant.": "თქვენ სასარგებლო ასისტენტი ხართ.",
 	"You're now logged in.": "თქვენ შესული ხართ.",
 	"You're now logged in.": "თქვენ შესული ხართ.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/ko-KR/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Params": "Chunk Params",
 	"Chunk Params": "Chunk Params",
 	"Chunk Size": "Chunk Size",
 	"Chunk Size": "Chunk Size",
+	"Citation": "",
 	"Click here for help.": "도움말을 보려면 여기를 클릭하세요.",
 	"Click here for help.": "도움말을 보려면 여기를 클릭하세요.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "다른 모델파일을 확인하려면 여기를 클릭하세요.",
 	"Click here to check other modelfiles.": "다른 모델파일을 확인하려면 여기를 클릭하세요.",
@@ -270,6 +271,7 @@
 	"New Chat": "새 채팅",
 	"New Chat": "새 채팅",
 	"New Password": "새 비밀번호",
 	"New Password": "새 비밀번호",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "로그아웃",
 	"Sign up": "가입",
 	"Sign up": "가입",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "음성 인식 오류: {{error}}",
 	"Speech recognition error: {{error}}": "음성 인식 오류: {{error}}",
 	"Speech-to-Text Engine": "음성-텍스트 엔진",
 	"Speech-to-Text Engine": "음성-텍스트 엔진",
 	"SpeechRecognition API is not supported in this browser.": "이 브라우저에서는 SpeechRecognition API를 지원하지 않습니다.",
 	"SpeechRecognition API is not supported in this browser.": "이 브라우저에서는 SpeechRecognition API를 지원하지 않습니다.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "당신은 유용한 어시스턴트입니다.",
 	"You're a helpful assistant.": "당신은 유용한 어시스턴트입니다.",
 	"You're now logged in.": "로그인되었습니다.",
 	"You're now logged in.": "로그인되었습니다.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/nl-NL/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Params": "Chunk Params",
 	"Chunk Params": "Chunk Params",
 	"Chunk Size": "Chunk Grootte",
 	"Chunk Size": "Chunk Grootte",
+	"Citation": "",
 	"Click here for help.": "Klik hier voor help.",
 	"Click here for help.": "Klik hier voor help.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Klik hier om andere modelfiles te controleren.",
 	"Click here to check other modelfiles.": "Klik hier om andere modelfiles te controleren.",
@@ -270,6 +271,7 @@
 	"New Chat": "Nieuwe Chat",
 	"New Chat": "Nieuwe Chat",
 	"New Password": "Nieuw Wachtwoord",
 	"New Password": "Nieuw Wachtwoord",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "Niet zeker wat toe te voegen?",
 	"Not sure what to add?": "Niet zeker wat toe te voegen?",
 	"Not sure what to write? Switch to": "Niet zeker wat te schrijven? Schakel over naar",
 	"Not sure what to write? Switch to": "Niet zeker wat te schrijven? Schakel over naar",
@@ -385,6 +387,7 @@
 	"Sign Out": "Uitloggen",
 	"Sign Out": "Uitloggen",
 	"Sign up": "Registreren",
 	"Sign up": "Registreren",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Spraakherkenning fout: {{error}}",
 	"Speech recognition error: {{error}}": "Spraakherkenning fout: {{error}}",
 	"Speech-to-Text Engine": "Spraak-naar-tekst Engine",
 	"Speech-to-Text Engine": "Spraak-naar-tekst Engine",
 	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API wordt niet ondersteund in deze browser.",
 	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API wordt niet ondersteund in deze browser.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "Jij bent een behulpzame assistent.",
 	"You're a helpful assistant.": "Jij bent een behulpzame assistent.",
 	"You're now logged in.": "Je bent nu ingelogd.",
 	"You're now logged in.": "Je bent nu ingelogd.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/pl-PL/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Zachodzenie bloku",
 	"Chunk Overlap": "Zachodzenie bloku",
 	"Chunk Params": "Parametry bloku",
 	"Chunk Params": "Parametry bloku",
 	"Chunk Size": "Rozmiar bloku",
 	"Chunk Size": "Rozmiar bloku",
+	"Citation": "",
 	"Click here for help.": "Kliknij tutaj, aby uzyskać pomoc.",
 	"Click here for help.": "Kliknij tutaj, aby uzyskać pomoc.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Kliknij tutaj, aby sprawdzić inne pliki modelowe.",
 	"Click here to check other modelfiles.": "Kliknij tutaj, aby sprawdzić inne pliki modelowe.",
@@ -270,6 +271,7 @@
 	"New Chat": "Nowy czat",
 	"New Chat": "Nowy czat",
 	"New Password": "Nowe hasło",
 	"New Password": "Nowe hasło",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "Nie wiesz, co dodać?",
 	"Not sure what to add?": "Nie wiesz, co dodać?",
 	"Not sure what to write? Switch to": "Nie wiesz, co napisać? Przełącz się na",
 	"Not sure what to write? Switch to": "Nie wiesz, co napisać? Przełącz się na",
@@ -385,6 +387,7 @@
 	"Sign Out": "Wyloguj się",
 	"Sign Out": "Wyloguj się",
 	"Sign up": "Zarejestruj się",
 	"Sign up": "Zarejestruj się",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Błąd rozpoznawania mowy: {{error}}",
 	"Speech recognition error: {{error}}": "Błąd rozpoznawania mowy: {{error}}",
 	"Speech-to-Text Engine": "Silnik mowy na tekst",
 	"Speech-to-Text Engine": "Silnik mowy na tekst",
 	"SpeechRecognition API is not supported in this browser.": "API Rozpoznawania Mowy nie jest obsługiwane w tej przeglądarce.",
 	"SpeechRecognition API is not supported in this browser.": "API Rozpoznawania Mowy nie jest obsługiwane w tej przeglądarce.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "Jesteś pomocnym asystentem.",
 	"You're a helpful assistant.": "Jesteś pomocnym asystentem.",
 	"You're now logged in.": "Jesteś teraz zalogowany.",
 	"You're now logged in.": "Jesteś teraz zalogowany.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/pt-BR/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Sobreposição de Fragmento",
 	"Chunk Overlap": "Sobreposição de Fragmento",
 	"Chunk Params": "Parâmetros de Fragmento",
 	"Chunk Params": "Parâmetros de Fragmento",
 	"Chunk Size": "Tamanho do Fragmento",
 	"Chunk Size": "Tamanho do Fragmento",
+	"Citation": "",
 	"Click here for help.": "Clique aqui para obter ajuda.",
 	"Click here for help.": "Clique aqui para obter ajuda.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Clique aqui para verificar outros arquivos de modelo.",
 	"Click here to check other modelfiles.": "Clique aqui para verificar outros arquivos de modelo.",
@@ -270,6 +271,7 @@
 	"New Chat": "Novo Bate-papo",
 	"New Chat": "Novo Bate-papo",
 	"New Password": "Nova Senha",
 	"New Password": "Nova Senha",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "Não tem certeza do que adicionar?",
 	"Not sure what to add?": "Não tem certeza do que adicionar?",
 	"Not sure what to write? Switch to": "Não tem certeza do que escrever? Mude para",
 	"Not sure what to write? Switch to": "Não tem certeza do que escrever? Mude para",
@@ -385,6 +387,7 @@
 	"Sign Out": "Sair",
 	"Sign Out": "Sair",
 	"Sign up": "Inscrever-se",
 	"Sign up": "Inscrever-se",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Erro de reconhecimento de fala: {{error}}",
 	"Speech recognition error: {{error}}": "Erro de reconhecimento de fala: {{error}}",
 	"Speech-to-Text Engine": "Mecanismo de Fala para Texto",
 	"Speech-to-Text Engine": "Mecanismo de Fala para Texto",
 	"SpeechRecognition API is not supported in this browser.": "A API SpeechRecognition não é suportada neste navegador.",
 	"SpeechRecognition API is not supported in this browser.": "A API SpeechRecognition não é suportada neste navegador.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "Você é um assistente útil.",
 	"You're a helpful assistant.": "Você é um assistente útil.",
 	"You're now logged in.": "Você está conectado agora.",
 	"You're now logged in.": "Você está conectado agora.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/pt-PT/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Sobreposição de Fragmento",
 	"Chunk Overlap": "Sobreposição de Fragmento",
 	"Chunk Params": "Parâmetros de Fragmento",
 	"Chunk Params": "Parâmetros de Fragmento",
 	"Chunk Size": "Tamanho do Fragmento",
 	"Chunk Size": "Tamanho do Fragmento",
+	"Citation": "",
 	"Click here for help.": "Clique aqui para obter ajuda.",
 	"Click here for help.": "Clique aqui para obter ajuda.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Clique aqui para verificar outros arquivos de modelo.",
 	"Click here to check other modelfiles.": "Clique aqui para verificar outros arquivos de modelo.",
@@ -270,6 +271,7 @@
 	"New Chat": "Novo Bate-papo",
 	"New Chat": "Novo Bate-papo",
 	"New Password": "Nova Senha",
 	"New Password": "Nova Senha",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "Não tem certeza do que adicionar?",
 	"Not sure what to add?": "Não tem certeza do que adicionar?",
 	"Not sure what to write? Switch to": "Não tem certeza do que escrever? Mude para",
 	"Not sure what to write? Switch to": "Não tem certeza do que escrever? Mude para",
@@ -385,6 +387,7 @@
 	"Sign Out": "Sair",
 	"Sign Out": "Sair",
 	"Sign up": "Inscrever-se",
 	"Sign up": "Inscrever-se",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Erro de reconhecimento de fala: {{error}}",
 	"Speech recognition error: {{error}}": "Erro de reconhecimento de fala: {{error}}",
 	"Speech-to-Text Engine": "Mecanismo de Fala para Texto",
 	"Speech-to-Text Engine": "Mecanismo de Fala para Texto",
 	"SpeechRecognition API is not supported in this browser.": "A API SpeechRecognition não é suportada neste navegador.",
 	"SpeechRecognition API is not supported in this browser.": "A API SpeechRecognition não é suportada neste navegador.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "Você é um assistente útil.",
 	"You're a helpful assistant.": "Você é um assistente útil.",
 	"You're now logged in.": "Você está conectado agora.",
 	"You're now logged in.": "Você está conectado agora.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/ru-RU/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Перекрытие фрагментов",
 	"Chunk Overlap": "Перекрытие фрагментов",
 	"Chunk Params": "Параметры фрагментов",
 	"Chunk Params": "Параметры фрагментов",
 	"Chunk Size": "Размер фрагмента",
 	"Chunk Size": "Размер фрагмента",
+	"Citation": "",
 	"Click here for help.": "Нажмите здесь для помощь.",
 	"Click here for help.": "Нажмите здесь для помощь.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Нажмите тут чтобы проверить другие файлы моделей.",
 	"Click here to check other modelfiles.": "Нажмите тут чтобы проверить другие файлы моделей.",
@@ -270,6 +271,7 @@
 	"New Chat": "Новый чат",
 	"New Chat": "Новый чат",
 	"New Password": "Новый пароль",
 	"New Password": "Новый пароль",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "Выход",
 	"Sign up": "зарегистрировать",
 	"Sign up": "зарегистрировать",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Ошибка распознавания речи: {{error}}",
 	"Speech recognition error: {{error}}": "Ошибка распознавания речи: {{error}}",
 	"Speech-to-Text Engine": "Система распознавания речи",
 	"Speech-to-Text Engine": "Система распознавания речи",
 	"SpeechRecognition API is not supported in this browser.": "API распознавания речи не поддерживается в этом браузере.",
 	"SpeechRecognition API is not supported in this browser.": "API распознавания речи не поддерживается в этом браузере.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "Вы полезный ассистент.",
 	"You're a helpful assistant.": "Вы полезный ассистент.",
 	"You're now logged in.": "Вы вошли в систему.",
 	"You're now logged in.": "Вы вошли в систему.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/sv-SE/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Överlappning",
 	"Chunk Overlap": "Överlappning",
 	"Chunk Params": "Chunk-parametrar",
 	"Chunk Params": "Chunk-parametrar",
 	"Chunk Size": "Chunk-storlek",
 	"Chunk Size": "Chunk-storlek",
+	"Citation": "",
 	"Click here for help.": "Klicka här för hjälp.",
 	"Click here for help.": "Klicka här för hjälp.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Klicka här för att kontrollera andra modelfiler.",
 	"Click here to check other modelfiles.": "Klicka här för att kontrollera andra modelfiler.",
@@ -270,6 +271,7 @@
 	"New Chat": "Ny chatt",
 	"New Chat": "Ny chatt",
 	"New Password": "Nytt lösenord",
 	"New Password": "Nytt lösenord",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"Not factually correct": "",
 	"Not sure what to add?": "Inte säker på vad du ska lägga till?",
 	"Not sure what to add?": "Inte säker på vad du ska lägga till?",
 	"Not sure what to write? Switch to": "Inte säker på vad du ska skriva? Växla till",
 	"Not sure what to write? Switch to": "Inte säker på vad du ska skriva? Växla till",
@@ -385,6 +387,7 @@
 	"Sign Out": "Logga ut",
 	"Sign Out": "Logga ut",
 	"Sign up": "Registrera dig",
 	"Sign up": "Registrera dig",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Fel vid taligenkänning: {{error}}",
 	"Speech recognition error: {{error}}": "Fel vid taligenkänning: {{error}}",
 	"Speech-to-Text Engine": "Tal-till-text-motor",
 	"Speech-to-Text Engine": "Tal-till-text-motor",
 	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API stöds inte i denna webbläsare.",
 	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API stöds inte i denna webbläsare.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "Du är en hjälpsam assistent.",
 	"You're a helpful assistant.": "Du är en hjälpsam assistent.",
 	"You're now logged in.": "Du är nu inloggad.",
 	"You're now logged in.": "Du är nu inloggad.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/tr-TR/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chunk Çakışması",
 	"Chunk Overlap": "Chunk Çakışması",
 	"Chunk Params": "Chunk Parametreleri",
 	"Chunk Params": "Chunk Parametreleri",
 	"Chunk Size": "Chunk Boyutu",
 	"Chunk Size": "Chunk Boyutu",
+	"Citation": "",
 	"Click here for help.": "Yardım için buraya tıklayın.",
 	"Click here for help.": "Yardım için buraya tıklayın.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Diğer model dosyalarını kontrol etmek için buraya tıklayın.",
 	"Click here to check other modelfiles.": "Diğer model dosyalarını kontrol etmek için buraya tıklayın.",
@@ -270,6 +271,7 @@
 	"New Chat": "Yeni Sohbet",
 	"New Chat": "Yeni Sohbet",
 	"New Password": "Yeni Parola",
 	"New Password": "Yeni Parola",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "Gerçeklere göre doğru değil",
 	"Not factually correct": "Gerçeklere göre doğru değil",
 	"Not sure what to add?": "Ne ekleyeceğinizden emin değil misiniz?",
 	"Not sure what to add?": "Ne ekleyeceğinizden emin değil misiniz?",
 	"Not sure what to write? Switch to": "Ne yazacağınızdan emin değil misiniz? Şuraya geçin",
 	"Not sure what to write? Switch to": "Ne yazacağınızdan emin değil misiniz? Şuraya geçin",
@@ -385,6 +387,7 @@
 	"Sign Out": "Çıkış Yap",
 	"Sign Out": "Çıkış Yap",
 	"Sign up": "Kaydol",
 	"Sign up": "Kaydol",
 	"Signing in": "Oturum açma",
 	"Signing in": "Oturum açma",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Konuşma tanıma hatası: {{error}}",
 	"Speech recognition error: {{error}}": "Konuşma tanıma hatası: {{error}}",
 	"Speech-to-Text Engine": "Konuşmadan Metne Motoru",
 	"Speech-to-Text Engine": "Konuşmadan Metne Motoru",
 	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API bu tarayıcıda desteklenmiyor.",
 	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API bu tarayıcıda desteklenmiyor.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "Sen yardımcı bir asistansın.",
 	"You're a helpful assistant.": "Sen yardımcı bir asistansın.",
 	"You're now logged in.": "Şimdi oturum açtınız.",
 	"You're now logged in.": "Şimdi oturum açtınız.",
 	"Youtube": "Youtube"
 	"Youtube": "Youtube"
-}
+}

+ 4 - 1
src/lib/i18n/locales/uk-UA/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Перекриття фрагментів",
 	"Chunk Overlap": "Перекриття фрагментів",
 	"Chunk Params": "Параметри фрагментів",
 	"Chunk Params": "Параметри фрагментів",
 	"Chunk Size": "Розмір фрагменту",
 	"Chunk Size": "Розмір фрагменту",
+	"Citation": "",
 	"Click here for help.": "Клацніть тут, щоб отримати допомогу.",
 	"Click here for help.": "Клацніть тут, щоб отримати допомогу.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Клацніть тут, щоб перевірити інші файли моделей.",
 	"Click here to check other modelfiles.": "Клацніть тут, щоб перевірити інші файли моделей.",
@@ -270,6 +271,7 @@
 	"New Chat": "Новий чат",
 	"New Chat": "Новий чат",
 	"New Password": "Новий пароль",
 	"New Password": "Новий пароль",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "Вийти",
 	"Sign up": "Зареєструватися",
 	"Sign up": "Зареєструватися",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Помилка розпізнавання мови: {{error}}",
 	"Speech recognition error: {{error}}": "Помилка розпізнавання мови: {{error}}",
 	"Speech-to-Text Engine": "Система розпізнавання мови",
 	"Speech-to-Text Engine": "Система розпізнавання мови",
 	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API не підтримується в цьому браузері.",
 	"SpeechRecognition API is not supported in this browser.": "SpeechRecognition API не підтримується в цьому браузері.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "Ви корисний асистент.",
 	"You're a helpful assistant.": "Ви корисний асистент.",
 	"You're now logged in.": "Ви увійшли в систему.",
 	"You're now logged in.": "Ви увійшли в систему.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/vi-VN/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chồng lấn (overlap)",
 	"Chunk Overlap": "Chồng lấn (overlap)",
 	"Chunk Params": "Cài đặt số lượng ký tự cho khối ký tự (chunk)",
 	"Chunk Params": "Cài đặt số lượng ký tự cho khối ký tự (chunk)",
 	"Chunk Size": "Kích thước khối (size)",
 	"Chunk Size": "Kích thước khối (size)",
+	"Citation": "",
 	"Click here for help.": "Bấm vào đây để được trợ giúp.",
 	"Click here for help.": "Bấm vào đây để được trợ giúp.",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "Bấm vào đây để kiểm tra các tệp mô tả mô hình (modelfiles) khác.",
 	"Click here to check other modelfiles.": "Bấm vào đây để kiểm tra các tệp mô tả mô hình (modelfiles) khác.",
@@ -270,6 +271,7 @@
 	"New Chat": "Tạo cuộc trò chuyện mới",
 	"New Chat": "Tạo cuộc trò chuyện mới",
 	"New Password": "Mật khẩu mới",
 	"New Password": "Mật khẩu mới",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "Không chính xác so với thực tế",
 	"Not factually correct": "Không chính xác so với thực tế",
 	"Not sure what to add?": "Không chắc phải thêm gì?",
 	"Not sure what to add?": "Không chắc phải thêm gì?",
 	"Not sure what to write? Switch to": "Không chắc phải viết gì? Chuyển sang",
 	"Not sure what to write? Switch to": "Không chắc phải viết gì? Chuyển sang",
@@ -385,6 +387,7 @@
 	"Sign Out": "Đăng xuất",
 	"Sign Out": "Đăng xuất",
 	"Sign up": "Đăng ký",
 	"Sign up": "Đăng ký",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "Lỗi nhận dạng giọng nói: {{error}}",
 	"Speech recognition error: {{error}}": "Lỗi nhận dạng giọng nói: {{error}}",
 	"Speech-to-Text Engine": "Công cụ Nhận dạng Giọng nói",
 	"Speech-to-Text Engine": "Công cụ Nhận dạng Giọng nói",
 	"SpeechRecognition API is not supported in this browser.": "Trình duyệt này không hỗ trợ API Nhận dạng Giọng nói.",
 	"SpeechRecognition API is not supported in this browser.": "Trình duyệt này không hỗ trợ API Nhận dạng Giọng nói.",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "Bạn là một trợ lý hữu ích.",
 	"You're a helpful assistant.": "Bạn là một trợ lý hữu ích.",
 	"You're now logged in.": "Bạn đã đăng nhập.",
 	"You're now logged in.": "Bạn đã đăng nhập.",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/zh-CN/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "块重叠(Chunk Overlap)",
 	"Chunk Overlap": "块重叠(Chunk Overlap)",
 	"Chunk Params": "块参数(Chunk Params)",
 	"Chunk Params": "块参数(Chunk Params)",
 	"Chunk Size": "块大小(Chunk Size)",
 	"Chunk Size": "块大小(Chunk Size)",
+	"Citation": "",
 	"Click here for help.": "点击这里获取帮助。",
 	"Click here for help.": "点击这里获取帮助。",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "点击这里检查其他模型文件。",
 	"Click here to check other modelfiles.": "点击这里检查其他模型文件。",
@@ -270,6 +271,7 @@
 	"New Chat": "新聊天",
 	"New Chat": "新聊天",
 	"New Password": "新密码",
 	"New Password": "新密码",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "登出",
 	"Sign up": "注册",
 	"Sign up": "注册",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "语音识别错误:{{error}}",
 	"Speech recognition error: {{error}}": "语音识别错误:{{error}}",
 	"Speech-to-Text Engine": "语音转文字引擎",
 	"Speech-to-Text Engine": "语音转文字引擎",
 	"SpeechRecognition API is not supported in this browser.": "此浏览器不支持SpeechRecognition API。",
 	"SpeechRecognition API is not supported in this browser.": "此浏览器不支持SpeechRecognition API。",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "你是一个有帮助的助手。",
 	"You're a helpful assistant.": "你是一个有帮助的助手。",
 	"You're now logged in.": "已登录。",
 	"You're now logged in.": "已登录。",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 4 - 1
src/lib/i18n/locales/zh-TW/translation.json

@@ -73,6 +73,7 @@
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Overlap": "Chunk Overlap",
 	"Chunk Params": "Chunk 參數",
 	"Chunk Params": "Chunk 參數",
 	"Chunk Size": "Chunk 大小",
 	"Chunk Size": "Chunk 大小",
+	"Citation": "",
 	"Click here for help.": "點擊這裡尋找幫助。",
 	"Click here for help.": "點擊這裡尋找幫助。",
 	"Click here to": "",
 	"Click here to": "",
 	"Click here to check other modelfiles.": "點擊這裡檢查其他 Modelfiles。",
 	"Click here to check other modelfiles.": "點擊這裡檢查其他 Modelfiles。",
@@ -270,6 +271,7 @@
 	"New Chat": "新增聊天",
 	"New Chat": "新增聊天",
 	"New Password": "新密碼",
 	"New Password": "新密碼",
 	"No results found": "",
 	"No results found": "",
+	"No source available": "",
 	"Not factually correct": "",
 	"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": "登出",
 	"Sign up": "註冊",
 	"Sign up": "註冊",
 	"Signing in": "",
 	"Signing in": "",
+	"Source": "",
 	"Speech recognition error: {{error}}": "語音識別錯誤: {{error}}",
 	"Speech recognition error: {{error}}": "語音識別錯誤: {{error}}",
 	"Speech-to-Text Engine": "語音轉文字引擎",
 	"Speech-to-Text Engine": "語音轉文字引擎",
 	"SpeechRecognition API is not supported in this browser.": "此瀏覽器不支持 SpeechRecognition API。",
 	"SpeechRecognition API is not supported in this browser.": "此瀏覽器不支持 SpeechRecognition API。",
@@ -463,4 +466,4 @@
 	"You're a helpful assistant.": "你是一位善於協助他人的助手。",
 	"You're a helpful assistant.": "你是一位善於協助他人的助手。",
 	"You're now logged in.": "已登入。",
 	"You're now logged in.": "已登入。",
 	"Youtube": ""
 	"Youtube": ""
-}
+}

+ 15 - 3
src/routes/(app)/+page.svelte

@@ -366,7 +366,8 @@
 			},
 			},
 			format: $settings.requestFormat ?? undefined,
 			format: $settings.requestFormat ?? undefined,
 			keep_alive: $settings.keepAlive ?? undefined,
 			keep_alive: $settings.keepAlive ?? undefined,
-			docs: docs.length > 0 ? docs : undefined
+			docs: docs.length > 0 ? docs : undefined,
+			citations: docs.length > 0
 		});
 		});
 
 
 		if (res && res.ok) {
 		if (res && res.ok) {
@@ -401,6 +402,11 @@
 							console.log(line);
 							console.log(line);
 							let data = JSON.parse(line);
 							let data = JSON.parse(line);
 
 
+							if ('citations' in data) {
+								responseMessage.citations = data.citations;
+								continue;
+							}
+
 							if ('detail' in data) {
 							if ('detail' in data) {
 								throw data;
 								throw data;
 							}
 							}
@@ -598,7 +604,8 @@
 				num_ctx: $settings?.options?.num_ctx ?? undefined,
 				num_ctx: $settings?.options?.num_ctx ?? undefined,
 				frequency_penalty: $settings?.options?.repeat_penalty ?? undefined,
 				frequency_penalty: $settings?.options?.repeat_penalty ?? undefined,
 				max_tokens: $settings?.options?.num_predict ?? undefined,
 				max_tokens: $settings?.options?.num_predict ?? undefined,
-				docs: docs.length > 0 ? docs : undefined
+				docs: docs.length > 0 ? docs : undefined,
+				citations: docs.length > 0
 			},
 			},
 			model?.source?.toLowerCase() === 'litellm'
 			model?.source?.toLowerCase() === 'litellm'
 				? `${LITELLM_API_BASE_URL}/v1`
 				? `${LITELLM_API_BASE_URL}/v1`
@@ -614,7 +621,7 @@
 			const textStream = await createOpenAITextStream(res.body, $settings.splitLargeChunks);
 			const textStream = await createOpenAITextStream(res.body, $settings.splitLargeChunks);
 
 
 			for await (const update of textStream) {
 			for await (const update of textStream) {
-				const { value, done } = update;
+				const { value, done, citations } = update;
 				if (done || stopResponseFlag || _chatId !== $chatId) {
 				if (done || stopResponseFlag || _chatId !== $chatId) {
 					responseMessage.done = true;
 					responseMessage.done = true;
 					messages = messages;
 					messages = messages;
@@ -626,6 +633,11 @@
 					break;
 					break;
 				}
 				}
 
 
+				if (citations) {
+					responseMessage.citations = citations;
+					continue;
+				}
+
 				if (responseMessage.content == '' && value == '\n') {
 				if (responseMessage.content == '' && value == '\n') {
 					continue;
 					continue;
 				} else {
 				} else {

+ 15 - 3
src/routes/(app)/c/[id]/+page.svelte

@@ -378,7 +378,8 @@
 			},
 			},
 			format: $settings.requestFormat ?? undefined,
 			format: $settings.requestFormat ?? undefined,
 			keep_alive: $settings.keepAlive ?? undefined,
 			keep_alive: $settings.keepAlive ?? undefined,
-			docs: docs.length > 0 ? docs : undefined
+			docs: docs.length > 0 ? docs : undefined,
+			citations: docs.length > 0
 		});
 		});
 
 
 		if (res && res.ok) {
 		if (res && res.ok) {
@@ -413,6 +414,11 @@
 							console.log(line);
 							console.log(line);
 							let data = JSON.parse(line);
 							let data = JSON.parse(line);
 
 
+							if ('citations' in data) {
+								responseMessage.citations = data.citations;
+								continue;
+							}
+
 							if ('detail' in data) {
 							if ('detail' in data) {
 								throw data;
 								throw data;
 							}
 							}
@@ -610,7 +616,8 @@
 				num_ctx: $settings?.options?.num_ctx ?? undefined,
 				num_ctx: $settings?.options?.num_ctx ?? undefined,
 				frequency_penalty: $settings?.options?.repeat_penalty ?? undefined,
 				frequency_penalty: $settings?.options?.repeat_penalty ?? undefined,
 				max_tokens: $settings?.options?.num_predict ?? undefined,
 				max_tokens: $settings?.options?.num_predict ?? undefined,
-				docs: docs.length > 0 ? docs : undefined
+				docs: docs.length > 0 ? docs : undefined,
+				citations: docs.length > 0
 			},
 			},
 			model?.source?.toLowerCase() === 'litellm'
 			model?.source?.toLowerCase() === 'litellm'
 				? `${LITELLM_API_BASE_URL}/v1`
 				? `${LITELLM_API_BASE_URL}/v1`
@@ -626,7 +633,7 @@
 			const textStream = await createOpenAITextStream(res.body, $settings.splitLargeChunks);
 			const textStream = await createOpenAITextStream(res.body, $settings.splitLargeChunks);
 
 
 			for await (const update of textStream) {
 			for await (const update of textStream) {
-				const { value, done } = update;
+				const { value, done, citations } = update;
 				if (done || stopResponseFlag || _chatId !== $chatId) {
 				if (done || stopResponseFlag || _chatId !== $chatId) {
 					responseMessage.done = true;
 					responseMessage.done = true;
 					messages = messages;
 					messages = messages;
@@ -638,6 +645,11 @@
 					break;
 					break;
 				}
 				}
 
 
+				if (citations) {
+					responseMessage.citations = citations;
+					continue;
+				}
+
 				if (responseMessage.content == '' && value == '\n') {
 				if (responseMessage.content == '' && value == '\n') {
 					continue;
 					continue;
 				} else {
 				} else {